From 0bb6d640647761ecd86eab6d1984dfb96b2e3a30 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Sat, 1 Apr 2006 12:47:09 +0000 Subject: A lot of code in sword1/router.cpp and sword2/router.cpp is virtually identical -- unified the two files in many places (but a lot more could be done, feel free to pick up and continue this work) svn-id: r21526 --- engines/sword1/object.h | 4 +- engines/sword1/router.cpp | 2387 ++++++++++++++++++++------------------------- engines/sword1/router.h | 132 ++- engines/sword2/router.cpp | 131 +-- engines/sword2/router.h | 16 +- 5 files changed, 1198 insertions(+), 1472 deletions(-) diff --git a/engines/sword1/object.h b/engines/sword1/object.h index 3d2cde4a6d..61727e7abc 100644 --- a/engines/sword1/object.h +++ b/engines/sword1/object.h @@ -20,8 +20,8 @@ * */ -#ifndef BSOBJECT_H -#define BSOBJECT_H +#ifndef SWORD1_OBJECT_H +#define SWORD1_OBJECT_H #include "common/scummsys.h" diff --git a/engines/sword1/router.cpp b/engines/sword1/router.cpp index 57e72880f7..8b263758fb 100644 --- a/engines/sword1/router.cpp +++ b/engines/sword1/router.cpp @@ -73,51 +73,54 @@ namespace Sword1 { Router::Router(ObjectMan *pObjMan, ResMan *pResMan) { _objMan = pObjMan; _resMan = pResMan; - nnodes = nbars = 0; + _nNodes = _nBars = 0; _playerTargetX = _playerTargetY = _playerTargetDir = _playerTargetStance = 0; - diagonalx = diagonaly = 0; + _diagonalx = _diagonaly = 0; } /* * CODE */ -int32 Router::routeFinder(int32 id, Object *megaObject, int32 x, int32 y, int32 dir) -{ -/**************************************************************************** - * RouteFinder.C polygon router with modular walks - * 21 august 94 - * 3 november 94 - * RouteFinder creates a list of modules that enables HardWalk to create - * an animation list. - * - * RouteFinder currently works by scanning grid data and coming up with a ROUTE - * as a series of way points(nodes), the smoothest eight directional PATH - * through these nodes is then found, this information is made available to - * HardWalk for a WALK to be created to fit the PATH. - * - * 30 november 94 return values modified - * - * return 0 = failed to find a route - * - * 1 = found a route - * - * 2 = mega already at target - * - ****************************************************************************/ - - int32 routeFlag = 0; - int32 solidFlag = 0; +int32 Router::routeFinder(int32 id, Object *megaObject, int32 x, int32 y, int32 dir) { + /********************************************************************* + * RouteFinder.C polygon router with modular walks + * 21 august 94 + * 3 november 94 + * routeFinder creates a list of modules that enables HardWalk to + * create an animation list. + * + * routeFinder currently works by scanning grid data and coming up + * with a ROUTE as a series of way points(nodes), the smoothest eight + * directional PATH through these nodes is then found, this + * information is made available to HardWalk for a WALK to be created + * to fit the PATH. + * + * 30 november 94 return values modified + * + * return 0 = failed to find a route + * + * 1 = found a route + * + * 2 = mega already at target + * + *********************************************************************/ + + int32 routeFlag = 0; + int32 solidFlag = 0; + WalkData *walkAnim; megaId = id; LoadWalkResources(megaObject, x, y, dir); - framesPerStep = nWalkFrames/2; - framesPerChar = nWalkFrames * NO_DIRECTIONS; + walkAnim = megaObject->o_route; + + _framesPerStep = _nWalkFrames/2; + _framesPerChar = _nWalkFrames * NO_DIRECTIONS; // offset pointers added Oct 30 95 JPS - standFrames = framesPerChar; + standFrames = _framesPerChar; turnFramesLeft = standFrames; turnFramesRight = standFrames; walkFramesLeft = 0; @@ -127,17 +130,15 @@ int32 Router::routeFinder(int32 id, Object *megaObject, int32 x, int32 y, int32 if (megaId == GEORGE) { - turnFramesLeft = 3 * framesPerChar + NO_DIRECTIONS + 2 * SLOW_IN + 4 * SLOW_OUT; - turnFramesRight = 3 * framesPerChar + NO_DIRECTIONS + 2 * SLOW_IN + 4 * SLOW_OUT + NO_DIRECTIONS; - walkFramesLeft = framesPerChar + NO_DIRECTIONS; - walkFramesRight = 2 * framesPerChar + NO_DIRECTIONS; - slowInFrames = 3 * framesPerChar + NO_DIRECTIONS; - slowOutFrames = 3 * framesPerChar + NO_DIRECTIONS + 2 * SLOW_IN; - } - else if (megaId == NICO) - { - turnFramesLeft = framesPerChar + NO_DIRECTIONS; - turnFramesRight = framesPerChar + 2 * NO_DIRECTIONS; + turnFramesLeft = 3 * _framesPerChar + NO_DIRECTIONS + 2 * SLOW_IN + 4 * SLOW_OUT; + turnFramesRight = 3 * _framesPerChar + NO_DIRECTIONS + 2 * SLOW_IN + 4 * SLOW_OUT + NO_DIRECTIONS; + walkFramesLeft = _framesPerChar + NO_DIRECTIONS; + walkFramesRight = 2 * _framesPerChar + NO_DIRECTIONS; + slowInFrames = 3 * _framesPerChar + NO_DIRECTIONS; + slowOutFrames = 3 * _framesPerChar + NO_DIRECTIONS + 2 * SLOW_IN; + } else if (megaId == NICO) { + turnFramesLeft = _framesPerChar + NO_DIRECTIONS; + turnFramesRight = _framesPerChar + 2 * NO_DIRECTIONS; walkFramesLeft = 0; walkFramesRight = 0; slowInFrames = 0; @@ -148,199 +149,214 @@ int32 Router::routeFinder(int32 id, Object *megaObject, int32 x, int32 y, int32 // All route data now loaded start finding a route // ************************************************************************** // ************************************************************************** -// Check if we can get a route through the floor changed 12 Oct95 JPS +// check if we can get a route through the floor changed 12 Oct95 JPS // ************************************************************************** - routeFlag = GetRoute(); + routeFlag = getRoute(); + + switch (routeFlag) { + case 2: + // special case for zero length route + + // if target direction specified as any + if (_targetDir > 7) + _targetDir = _startDir; + + // just a turn on the spot is required set an end module for + // the route let the animator deal with it + // modularPath is normally set by extractRoute + + _modularPath[0].dir = _startDir; + _modularPath[0].num = 0; + _modularPath[0].x = _startX; + _modularPath[0].y = _startY; + _modularPath[1].dir = _targetDir; + _modularPath[1].num = 0; + _modularPath[1].x = _startX; + _modularPath[1].y = _startY; + _modularPath[2].dir = 9; + _modularPath[2].num = ROUTE_END_FLAG; + + slidyWalkAnimator(walkAnim); + routeFlag = 2; + break; + case 1: + // A normal route. Convert the route to an exact path + smoothestPath(); + + // The Route had waypoints and direction options + + // The Path is an exact set of lines in 8 directions that + // reach the target. + + // The path is in module format, but steps taken in each + // direction are not accurate - if (routeFlag == 2) //special case for zero length route - { - if (targetDir >7)// if target direction specified as any - { - targetDir = startDir; - } - // just a turn on the spot is required set an end module for the route let the animator deal with it - // modularPath is normally set by ExtractRoute - modularPath[0].dir = startDir; - modularPath[0].num = 0; - modularPath[0].x = startX; - modularPath[0].y = startY; - modularPath[1].dir = targetDir; - modularPath[1].num = 0; - modularPath[1].x = startX; - modularPath[1].y = startY; - modularPath[2].dir = 9; - modularPath[2].num = ROUTE_END_FLAG; - - SlidyWalkAnimator(megaObject->o_route); - routeFlag = 2; - } - else if (routeFlag == 1) // a normal route - { - SmoothestPath();//Converts the route to an exact path - // The Route had waypoints and direction options - // The Path is an exact set of lines in 8 directions that reach the target. - // The path is in module format, but steps taken in each direction are not accurate // if target dir = 8 then the walk isn't linked to an anim so - // we can create a route without sliding and miss the exact target - if (targetDir == NO_DIRECTIONS) - { - SolidPath(); - solidFlag = SolidWalkAnimator(megaObject->o_route); + // we can create a route without sliding and miss the exact + // target + + if (_targetDir == NO_DIRECTIONS) { + // can end facing ANY direction (ie. exact end + // position not vital) - so use SOLID walk to + // avoid sliding to exact position + + solidPath(); + solidFlag = solidWalkAnimator(walkAnim); } - if (!solidFlag) - { - SlidyPath(); - SlidyWalkAnimator(megaObject->o_route); + if (!solidFlag) { + // if we failed to create a SOLID route, do a SLIDY + // one instead + + slidyPath(); + slidyWalkAnimator(walkAnim); } + + break; + default: + // Route didn't reach target so assume point was off the floor + // routeFlag = 0; + break; } - else // Route didn't reach target so assume point was off the floor - { -// routeFlag = 0; - } + return routeFlag; // send back null route } -// **************************************************************************** -// * GET A ROUTE -// **************************************************************************** - -int32 Router::GetRoute() -{ - /**************************************************************************** - * GetRoute.C extract a path from walk grid - * 12 october 94 - * - * GetRoute currently works by scanning grid data and coming up with a ROUTE - * as a series of way points(nodes). - * static _routeData route[O_ROUTE_SIZE]; - * - * return 0 = failed to find a route - * - * 1 = found a route - * - * 2 = mega already at target - * - * 3 = failed to find a route because target was on a line - * - ****************************************************************************/ - int32 routeGot = 0; - int32 level; - int32 changed; - - if ((startX == targetX) && (startY == targetY)) +int32 Router::getRoute() { + /********************************************************************* + * GetRoute.C extract a path from walk grid + * 12 october 94 + * + * GetRoute currently works by scanning grid data and coming up with + * a ROUTE as a series of way points(nodes). + * + * static routeData _route[O_ROUTE_SIZE]; + * + * return 0 = failed to find a route + * + * 1 = found a route + * + * 2 = mega already at target + * + * 3 = failed to find a route because target was on a line + * + *********************************************************************/ + + int32 routeGot = 0; + + if (_startX == _targetX && _startY == _targetY) routeGot = 2; + else { + // 'else' added by JEL (23jan96) otherwise 'routeGot' affected + // even when already set to '2' above - causing some 'turns' + // to walk downwards on the spot + + // returns 3 if target on a line ( +- 1 pixel ) + routeGot = checkTarget(_targetX, _targetY); + } - else // 'else' added by JEL (23jan96) otherwise 'routeGot' affected even when already set to '2' above - causing some 'turns' to walk downwards on the spot - routeGot = CheckTarget(targetX,targetY);// returns 3 if target on a line ( +- 1 pixel ) + if (routeGot == 0) { + // still looking for a route check if target is within a pixel + // of a line + // scan through the nodes linking each node to its nearest + // neighbour until no more nodes change - if (routeGot == 0) //still looking for a route check if target is within a pixel of a line - { - // scan through the nodes linking each node to its nearest neighbour until no more nodes change - // This is the routine that finds a route using Scan() - level = 1; - do - { - changed = Scan(level); - level =level + 1; - } - while (changed == 1); + // This is the routine that finds a route using scan() + + int32 level = 1; + + while (scan(level)) + level++; // Check to see if the route reached the target - if (node[nnodes].dist < 9999) - { + + if (_node[_nNodes].dist < 9999) { + // it did so extract the route as nodes and the + // directions to go between each node + routeGot = 1; - ExtractRoute(); // it did so extract the route as nodes and the directions to go between each node - // route.X,route.Y and route.Dir now hold all the route infomation with the target dir or route continuation + extractRoute(); + + // route.X,route.Y and route.Dir now hold all the + // route infomation with the target dir or route + // continuation } } return routeGot; } -// **************************************************************************** -// * THE SLIDY PATH ROUTINES -// **************************************************************************** - -int32 Router::SmoothestPath() -{ -/* - * This is the second big part of the route finder and the the only bit that tries to be clever - * (the other bits are clever). - * This part of the autorouter creates a list of modules from a set of lines running across the screen - * The task is complicated by two things; - * Firstly in chosing a route through the maze of nodes the routine tries to minimise the amount of each - * individual turn avoiding 90 degree and greater turns (where possible) and reduces the total nuber of - * turns (subject to two 45 degree turns being better than one 90 degree turn). - * Secondly when walking in a given direction the number of steps required to reach the end of that run - * is not calculated accurately. This is because I was unable to derive a function to relate number of - * steps taken between two points to the shrunken step size - * - */ - int32 p; - int32 dirS; - int32 dirD; - int32 dS; - int32 dD; - int32 dSS; - int32 dSD; - int32 dDS; - int32 dDD; - int32 i; - int32 steps; - int32 option; - int32 options; +// THE SLIDY PATH ROUTINES + +int32 Router::smoothestPath() { + // This is the second big part of the route finder and the the only + // bit that tries to be clever (the other bits are clever). + // + // This part of the autorouter creates a list of modules from a set of + // lines running across the screen. The task is complicated by two + // things: + // + // Firstly in choosing a route through the maze of nodes the routine + // tries to minimise the amount of each individual turn avoiding 90 + // degree and greater turns (where possible) and reduces the total + // number of turns (subject to two 45 degree turns being better than + // one 90 degree turn). + // + // Secondly when walking in a given direction the number of steps + // required to reach the end of that run is not calculated accurately. + // This is because I was unable to derive a function to relate number + // of steps taken between two points to the shrunken step size + + int i; + int32 steps = 0; int32 lastDir; - int32 nextDirS; - int32 nextDirD; int32 tempturns[4]; int32 turns[4]; - int32 turntable[NO_DIRECTIONS] = { 0, 1, 3, 5, 7, 5, 3, 1 }; - -// targetDir;// no warnings + const int32 turntable[NO_DIRECTIONS] = { 0, 1, 3, 5, 7, 5, 3, 1 }; // route.X route.Y and route.Dir start at far end - smoothPath[0].x = startX; - smoothPath[0].y = startY; - smoothPath[0].dir = startDir; - smoothPath[0].num = 0; - p = 0; - lastDir = startDir; + + _smoothPath[0].x = _startX; + _smoothPath[0].y = _startY; + _smoothPath[0].dir = _startDir; + _smoothPath[0].num = 0; + + lastDir = _startDir; + // for each section of the route - do - { - dirS = route[p].dirS; - dirD = route[p].dirD; - nextDirS = route[p+1].dirS; - nextDirD = route[p+1].dirD; - - // Check directions into and out of a pair of nodes - // going in - dS = dirS - lastDir; - if ( dS < 0) + + for (int p = 0; p < _routeLength; p++) { + int32 dirS = _route[p].dirS; + int32 dirD = _route[p].dirD; + int32 nextDirS = _route[p + 1].dirS; + int32 nextDirD = _route[p + 1].dirD; + + // Check directions into and out of a pair of nodes going in + int32 dS = dirS - lastDir; + if (dS < 0) dS = dS + NO_DIRECTIONS; - dD = dirD - lastDir; - if ( dD < 0) + int32 dD = dirD - lastDir; + if (dD < 0) dD = dD + NO_DIRECTIONS; // coming out - dSS = dirS - nextDirS; - if ( dSS < 0) + int32 dSS = dirS - nextDirS; + if (dSS < 0) dSS = dSS + NO_DIRECTIONS; - dDD = dirD - nextDirD; - if ( dDD < 0) + int32 dDD = dirD - nextDirD; + if (dDD < 0) dDD = dDD + NO_DIRECTIONS; - dSD = dirS - nextDirD; - if ( dSD < 0) + int32 dSD = dirS - nextDirD; + if (dSD < 0) dSD = dSD + NO_DIRECTIONS; - dDS = dirD - nextDirS; - if ( dDS < 0) + int32 dDS = dirD - nextDirS; + if (dDS < 0) dDS = dDS + NO_DIRECTIONS; // Determine the amount of turning involved in each possible path @@ -350,14 +366,14 @@ int32 Router::SmoothestPath() dDD = turntable[dDD]; dSD = turntable[dSD]; dDS = turntable[dDS]; + // get the best path out ie assume next section uses best direction if (dSD < dSS) dSS = dSD; if (dDS < dDD) dDD = dDS; - // Rate each option. Split routes look crap so weight against - // them + // Rate each option. Split routes look crap so weight against them tempturns[0] = dS + dSS + 3; turns[0] = 0; tempturns[1] = dS + dDD; @@ -367,7 +383,7 @@ int32 Router::SmoothestPath() tempturns[3] = dD + dDD + 3; turns[3] = 3; - // set up turns as a sorted array of the turn values + // set up turns as a sorted array of the turn values for (i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (tempturns[j] > tempturns[j + 1]) { @@ -377,291 +393,256 @@ int32 Router::SmoothestPath() } } - // best option matched in order of the priority we would like to see on the screen - // but each option must be checked to see if it can be walked + // best option matched in order of the priority we would like + // to see on the screen but each option must be checked to see + // if it can be walked - options = NewCheck(1, route[p].x, route[p].y, route[p + 1].x, route[p + 1].y); + int32 options = newCheck(1, _route[p].x, _route[p].y, _route[p + 1].x, _route[p + 1].y); + + assert(options); - if (options == 0) - { - /*Tdebug("BestTurns fail %d %d %d %d",route[p].x, route[p].y, route[p + 1].x, route[p + 1].y); - Tdebug("BestTurns fail %d %d %d %d",turns[0],turns[1],turns[2],options); - Go_dos("BestTurns failed");*/ - error("BestTurns failed"); - } i = 0; steps = 0; - do - { - option = 1 << turns[i]; - if (option & options) - steps = SmoothCheck(turns[i],p,dirS,dirD); - i = i + 1; - } - while ((steps == 0) && (i < 4)); - if (steps == 0) - { - /*Tdebug("BestTurns failed %d %d %d %d",route[p].x, route[p].y, route[p + 1].x, route[p + 1].y); - Tdebug("BestTurns failed %d %d %d %d",turns[0],turns[1],turns[2],options); - Go_dos("BestTurns failed");*/ - error("BestTurns failed"); - } - // route.X route.Y route.dir and bestTurns start at far end - p = p + 1; + do { + int32 opt = 1 << turns[i]; + if (options & opt) + steps = smoothCheck(turns[i], p, dirS, dirD); + i++; + } while (steps == 0 && i < 4); + assert(steps); + // route.X route.Y route.dir and bestTurns start at far end } - while (p < (routeLength)); - // best turns will end heading as near as possible to target dir rest is down to anim for now - smoothPath[steps].dir = 9; - smoothPath[steps].num = ROUTE_END_FLAG; - return 1; -} - + // best turns will end heading as near as possible to target dir rest + // is down to anim for now + _smoothPath[steps].dir = 9; + _smoothPath[steps].num = ROUTE_END_FLAG; + return 1; +} -int32 Router::SmoothCheck(int32 best, int32 p, int32 dirS, int32 dirD) -/**************************************************************************** - * Slip sliding away - * This path checker checks to see if a walk that exactly follows the path - * would be valid. This should be inherently true for atleast one of the turn - * options. - * No longer checks the data it only creates the smoothPath array JPS - ****************************************************************************/ -{ - static int32 k; - int32 tempK; - int32 x; - int32 y; - int32 x2; - int32 y2; - int32 dx; - int32 dy; - int32 dsx; - int32 dsy; - int32 ddx; - int32 ddy; - int32 dirX; - int32 dirY; - int32 ss0; - int32 ss1; - int32 ss2; - int32 sd0; - int32 sd1; - int32 sd2; +int32 Router::smoothCheck(int32 best, int32 p, int32 dirS, int32 dirD) { + /********************************************************************* + * Slip sliding away + * This path checker checks to see if a walk that exactly follows the + * path would be valid. This should be inherently true for atleast one + * of the turn options. + * No longer checks the data it only creates the smoothPath array JPS + *********************************************************************/ + + // FIXME: Using 'static' vars in a method is evil -- they should almost + // always be turned into member variables instead. + static int32 k; + int32 dsx, dsy; + int32 ddx, ddy; + int32 ss0, ss1, ss2; + int32 sd0, sd1, sd2; if (p == 0) - { k = 1; - } - tempK = 0; - x = route[p].x; - y = route[p].y; - x2 = route[p + 1].x; - y2 = route[p + 1].y; - dx = x2 - x; - dy = y2 - y; - dirX = 1; - dirY = 1; - if (dx < 0) - { - dx = -dx; + + int32 x = _route[p].x; + int32 y = _route[p].y; + int32 x2 = _route[p + 1].x; + int32 y2 = _route[p + 1].y; + int32 ldx = x2 - x; + int32 ldy = y2 - y; + int32 dirX = 1; + int32 dirY = 1; + + if (ldx < 0) { + ldx = -ldx; dirX = -1; } - if (dy < 0) - { - dy = -dy; + if (ldy < 0) { + ldy = -ldy; dirY = -1; } -// set up sd0-ss2 to reflect possible movement in each direction - if ((dirS == 0) || (dirS == 4))// vert and diag - { - ddx = dx; - ddy = (dx*diagonaly)/diagonalx; - dsy = dy - ddy; + // set up sd0-ss2 to reflect possible movement in each direction + + if (dirS == 0 || dirS == 4) { // vert and diag + ddx = ldx; + ddy = (ldx * _diagonaly) / _diagonalx; + dsy = ldy - ddy; ddx = ddx * dirX; ddy = ddy * dirY; dsy = dsy * dirY; dsx = 0; - sd0 = (ddx + modX[dirD]/2)/ modX[dirD]; - ss0 = (dsy + modY[dirS]/2) / modY[dirS]; - sd1 = sd0/2; - ss1 = ss0/2; + sd0 = (ddx + _modX[dirD] / 2) / _modX[dirD]; + ss0 = (dsy + _modY[dirS] / 2) / _modY[dirS]; + sd1 = sd0 / 2; + ss1 = ss0 / 2; sd2 = sd0 - sd1; ss2 = ss0 - ss1; - } - else - { - ddy = dy; - ddx = (dy*diagonalx)/diagonaly; - dsx = dx - ddx; + } else { + ddy = ldy; + ddx = (ldy * _diagonalx) / _diagonaly; + dsx = ldx - ddx; ddy = ddy * dirY; ddx = ddx * dirX; dsx = dsx * dirX; dsy = 0; - sd0 = (ddy + modY[dirD]/2)/ modY[dirD]; - ss0 = (dsx + modX[dirS]/2)/ modX[dirS]; - sd1 = sd0/2; - ss1 = ss0/2; + sd0 = (ddy + _modY[dirD] / 2) / _modY[dirD]; + ss0 = (dsx + _modX[dirS] / 2) / _modX[dirS]; + sd1 = sd0 / 2; + ss1 = ss0 / 2; sd2 = sd0 - sd1; ss2 = ss0 - ss1; } - if (best == 0) //halfsquare, diagonal, halfsquare - { - smoothPath[k].x = x+dsx/2; - smoothPath[k].y = y+dsy/2; - smoothPath[k].dir = dirS; - smoothPath[k].num = ss1; - k = k + 1; - smoothPath[k].x = x+dsx/2+ddx; - smoothPath[k].y = y+dsy/2+ddy; - smoothPath[k].dir = dirD; - smoothPath[k].num = sd0; - k = k + 1; - smoothPath[k].x = x+dsx+ddx; - smoothPath[k].y = y+dsy+ddy; - smoothPath[k].dir = dirS; - smoothPath[k].num = ss2; - k = k + 1; - tempK = k; - } - else if (best == 1) //square, diagonal - { - smoothPath[k].x = x+dsx; - smoothPath[k].y = y+dsy; - smoothPath[k].dir = dirS; - smoothPath[k].num = ss0; - k = k + 1; - smoothPath[k].x = x2; - smoothPath[k].y = y2; - smoothPath[k].dir = dirD; - smoothPath[k].num = sd0; - k = k + 1; - tempK = k; - } - else if (best == 2) //diagonal square - { - smoothPath[k].x = x+ddx; - smoothPath[k].y = y+ddy; - smoothPath[k].dir = dirD; - smoothPath[k].num = sd0; - k = k + 1; - smoothPath[k].x = x2; - smoothPath[k].y = y2; - smoothPath[k].dir = dirS; - smoothPath[k].num = ss0; - k = k + 1; - tempK = k; - } - else //halfdiagonal, square, halfdiagonal - { - smoothPath[k].x = x+ddx/2; - smoothPath[k].y = y+ddy/2; - smoothPath[k].dir = dirD; - smoothPath[k].num = sd1; - k = k + 1; - smoothPath[k].x = x+dsx+ddx/2; - smoothPath[k].y = y+dsy+ddy/2; - smoothPath[k].dir = dirS; - smoothPath[k].num = ss0; - k = k + 1; - smoothPath[k].x = x2; - smoothPath[k].y = y2; - smoothPath[k].dir = dirD; - smoothPath[k].num = sd2; - k = k + 1; - tempK = k; - } - - return tempK; + switch (best) { + case 0: // halfsquare, diagonal, halfsquare + _smoothPath[k].x = x + dsx / 2; + _smoothPath[k].y = y + dsy / 2; + _smoothPath[k].dir = dirS; + _smoothPath[k].num = ss1; + k++; + + _smoothPath[k].x = x + dsx / 2 + ddx; + _smoothPath[k].y = y + dsy / 2 + ddy; + _smoothPath[k].dir = dirD; + _smoothPath[k].num = sd0; + k++; + + _smoothPath[k].x = x + dsx + ddx; + _smoothPath[k].y = y + dsy + ddy; + _smoothPath[k].dir = dirS; + _smoothPath[k].num = ss2; + k++; + + break; + case 1: // square, diagonal + _smoothPath[k].x = x + dsx; + _smoothPath[k].y = y + dsy; + _smoothPath[k].dir = dirS; + _smoothPath[k].num = ss0; + k++; + + _smoothPath[k].x = x2; + _smoothPath[k].y = y2; + _smoothPath[k].dir = dirD; + _smoothPath[k].num = sd0; + k++; + + break; + case 2: // diagonal square + _smoothPath[k].x = x + ddx; + _smoothPath[k].y = y + ddy; + _smoothPath[k].dir = dirD; + _smoothPath[k].num = sd0; + k++; + + _smoothPath[k].x = x2; + _smoothPath[k].y = y2; + _smoothPath[k].dir = dirS; + _smoothPath[k].num = ss0; + k++; + + break; + default: // halfdiagonal, square, halfdiagonal + _smoothPath[k].x = x + ddx / 2; + _smoothPath[k].y = y + ddy / 2; + _smoothPath[k].dir = dirD; + _smoothPath[k].num = sd1; + k++; + + _smoothPath[k].x = x + dsx + ddx / 2; + _smoothPath[k].y = y + dsy + ddy / 2; + _smoothPath[k].dir = dirS; + _smoothPath[k].num = ss0; + k++; + + _smoothPath[k].x = x2; + _smoothPath[k].y = y2; + _smoothPath[k].dir = dirD; + _smoothPath[k].num = sd2; + k++; + + break; + } + + return k; } -int32 Router::SlidyPath() -{ -/**************************************************************************** - * SlidyPath creates a path based on part steps with no sliding to get - * as near as possible to the target without any sliding this routine is - * currently unused, but is intended for use when just clicking about. - * - * produce a module list from the line data - * - ****************************************************************************/ - int32 smooth; - int32 slidy; - int32 scale; - int32 stepX; - int32 stepY; - int32 deltaX; - int32 deltaY; +void Router::slidyPath() { + /********************************************************************* + * slidyPath creates a path based on part steps with no sliding to get + * as near as possible to the target without any sliding this routine + * is intended for use when just clicking about. + * + * produce a module list from the line data + *********************************************************************/ + + int32 smooth = 1; + int32 slidy = 1; // strip out the short sections - slidy = 1; - smooth = 1; - modularPath[0].x = smoothPath[0].x; - modularPath[0].y = smoothPath[0].y; - modularPath[0].dir = smoothPath[0].dir; - modularPath[0].num = 0; - while (smoothPath[smooth].num < ROUTE_END_FLAG) - { - scale = scaleA * smoothPath[smooth].y + scaleB; - deltaX = smoothPath[smooth].x - modularPath[slidy-1].x; - deltaY = smoothPath[smooth].y - modularPath[slidy-1].y; - stepX = modX[smoothPath[smooth].dir]; - stepY = modY[smoothPath[smooth].dir]; - stepX = stepX * scale; - stepY = stepY * scale; - stepX = stepX >> 19;// quarter a step minimum - stepY = stepY >> 19; - if ((ABS(deltaX)>=ABS(stepX)) && (ABS(deltaY)>=ABS(stepY))) - { - modularPath[slidy].x = smoothPath[smooth].x; - modularPath[slidy].y = smoothPath[smooth].y; - modularPath[slidy].dir = smoothPath[smooth].dir; - modularPath[slidy].num = 1; - slidy += 1; + _modularPath[0].x = _smoothPath[0].x; + _modularPath[0].y = _smoothPath[0].y; + _modularPath[0].dir = _smoothPath[0].dir; + _modularPath[0].num = 0; + + while (_smoothPath[smooth].num < ROUTE_END_FLAG) { + int32 scale = _scaleA * _smoothPath[smooth].y + _scaleB; + int32 deltaX = _smoothPath[smooth].x - _modularPath[slidy - 1].x; + int32 deltaY = _smoothPath[smooth].y - _modularPath[slidy - 1].y; + // quarter a step minimum + int32 stepX = (scale * _modX[_smoothPath[smooth].dir]) >> 19; + int32 stepY = (scale * _modY[_smoothPath[smooth].dir]) >> 19; + + if (ABS(deltaX) >= ABS(stepX) && ABS(deltaY) >= ABS(stepY)) { + _modularPath[slidy].x = _smoothPath[smooth].x; + _modularPath[slidy].y = _smoothPath[smooth].y; + _modularPath[slidy].dir = _smoothPath[smooth].dir; + _modularPath[slidy].num = 1; + slidy++; } - smooth += 1; + smooth++; } - // in case the last bit had no steps - if (slidy > 1) - { - modularPath[slidy-1].x = smoothPath[smooth-1].x; - modularPath[slidy-1].y = smoothPath[smooth-1].y; + + // in case the last bit had no steps + + if (slidy > 1) { + _modularPath[slidy - 1].x = _smoothPath[smooth - 1].x; + _modularPath[slidy - 1].y = _smoothPath[smooth - 1].y; } + // set up the end of the walk - modularPath[slidy].x = smoothPath[smooth-1].x; - modularPath[slidy].y = smoothPath[smooth-1].y; - modularPath[slidy].dir = targetDir; - modularPath[slidy].num = 0; - slidy += 1; - modularPath[slidy].x = smoothPath[smooth-1].x; - modularPath[slidy].y = smoothPath[smooth-1].y; - modularPath[slidy].dir = 9; - modularPath[slidy].num = ROUTE_END_FLAG; - return 1; -} + _modularPath[slidy].x = _smoothPath[smooth - 1].x; + _modularPath[slidy].y = _smoothPath[smooth - 1].y; + _modularPath[slidy].dir = _targetDir; + _modularPath[slidy].num = 0; + slidy++; -void Router::SlidyWalkAnimator(WalkData *walkAnim) -/**************************************************************************** - * Skidding every where HardWalk creates an animation that exactly fits the - * smoothPath and uses foot slipping to fit whole steps into the route - * Parameters: georgeg,mouseg - * Returns: rout - * - * produce a module list from the line data - * - ****************************************************************************/ -{ + _modularPath[slidy].x = _smoothPath[smooth - 1].x; + _modularPath[slidy].y = _smoothPath[smooth - 1].y; + _modularPath[slidy].dir = 9; + _modularPath[slidy].num = ROUTE_END_FLAG; +} +void Router::slidyWalkAnimator(WalkData *walkAnim) { + /********************************************************************* + * Skidding every where HardWalk creates an animation that exactly + * fits the smoothPath and uses foot slipping to fit whole steps into + * the route + * + * Parameters: georgeg, mouseg + * Returns: rout + * + * produce a module list from the line data + *********************************************************************/ + + // FIXME: Using 'static' vars in a method is evil -- they should almost + // always be turned into member variables instead. static int32 left = 0; int32 p; int32 lastDir; @@ -690,14 +671,14 @@ void Router::SlidyWalkAnimator(WalkData *walkAnim) // start at the begining for a change p = 0; - lastDir = modularPath[0].dir; - currentDir = modularPath[1].dir; + lastDir = _modularPath[0].dir; + currentDir = _modularPath[1].dir; + if (currentDir == NO_DIRECTIONS) - { currentDir = lastDir; - } - moduleX = startX; - moduleY = startY; + + moduleX = _startX; + moduleY = _startY; module16X = moduleX << 16; module16Y = moduleY << 16; stepCount = 0; @@ -707,7 +688,7 @@ void Router::SlidyWalkAnimator(WalkData *walkAnim) // START THE WALK WITH THE FIRST STANDFRAME THIS MAY CAUSE A DELAY // BUT IT STOPS THE PLAYER MOVING FOR COLLISIONS ARE DETECTED //**************************************************************************** - module = framesPerChar + lastDir; + module = _framesPerChar + lastDir; walkAnim[stepCount].frame = module; walkAnim[stepCount].step = 0; walkAnim[stepCount].dir = lastDir; @@ -739,9 +720,7 @@ void Router::SlidyWalkAnimator(WalkData *walkAnim) if ( turnDir < 0) // new frames for turn frames 29oct95jps { module = turnFramesLeft + lastDir; - } - else - { + } else { module = turnFramesRight + lastDir; } walkAnim[stepCount].frame = module; @@ -761,9 +740,7 @@ void Router::SlidyWalkAnimator(WalkData *walkAnim) if ( lastDir < 0) lastDir += NO_DIRECTIONS; module = turnFramesLeft + lastDir; - } - else - { + } else { if ( lastDir > 7) lastDir -= NO_DIRECTIONS; module = turnFramesRight + lastDir; @@ -787,16 +764,15 @@ void Router::SlidyWalkAnimator(WalkData *walkAnim) //**************************************************************************** if (left == 0) - left = framesPerStep; + left = _framesPerStep; else left = 0; lastCount = stepCount; lastDir = 99;// this ensures that we don't put in turn frames for the start currentDir = 99;// this ensures that we don't put in turn frames for the start - do - { - while (modularPath[p].num == 0) + do { + while (_modularPath[p].num == 0) { p = p + 1; if (currentDir != 99) @@ -804,20 +780,19 @@ void Router::SlidyWalkAnimator(WalkData *walkAnim) lastDir = currentDir; lastCount = stepCount; } - //calculate average amount to lose in each step on the way to the next node - currentDir = modularPath[p].dir; + //calculate average amount to lose in each step on the way to the next _node + currentDir = _modularPath[p].dir; if (currentDir < NO_DIRECTIONS) { - module = currentDir * framesPerStep * 2 + left; + module = currentDir * _framesPerStep * 2 + left; if (left == 0) - left = framesPerStep; + left = _framesPerStep; else left = 0; - moduleEnd = module + framesPerStep; + moduleEnd = module + _framesPerStep; step = 0; - scale = (scaleA * moduleY + scaleB); - do - { + scale = (_scaleA * moduleY + _scaleB); + do { module16X += _dx[module]*scale; module16Y += _dy[module]*scale; moduleX = module16X >> 16; @@ -830,76 +805,69 @@ void Router::SlidyWalkAnimator(WalkData *walkAnim) stepCount += 1; step += 1; module += 1; - } - while ( module < moduleEnd) ; - stepX = modX[modularPath[p].dir]; - stepY = modY[modularPath[p].dir]; - errorX = modularPath[p].x - moduleX; + } while ( module < moduleEnd) ; + stepX = _modX[_modularPath[p].dir]; + stepY = _modY[_modularPath[p].dir]; + errorX = _modularPath[p].x - moduleX; errorX = errorX * stepX; - errorY = modularPath[p].y - moduleY; + errorY = _modularPath[p].y - moduleY; errorY = errorY * stepY; if ((errorX < 0) || (errorY < 0)) { - modularPath[p].num = 0; // the end of the path + _modularPath[p].num = 0; // the end of the path // okay those last steps took us past our target but do we want to scoot or moonwalk frames = stepCount - lastCount; - errorX = modularPath[p].x - walkAnim[stepCount-1].x; - errorY = modularPath[p].y - walkAnim[stepCount-1].y; + errorX = _modularPath[p].x - walkAnim[stepCount-1].x; + errorY = _modularPath[p].y - walkAnim[stepCount-1].y; - if (frames > framesPerStep) + if (frames > _framesPerStep) { - lastErrorX = modularPath[p].x - walkAnim[stepCount-7].x; - lastErrorY = modularPath[p].y - walkAnim[stepCount-7].y; + lastErrorX = _modularPath[p].x - walkAnim[stepCount-7].x; + lastErrorY = _modularPath[p].y - walkAnim[stepCount-7].y; if (stepX==0) { if (3*ABS(lastErrorY) < ABS(errorY)) //the last stop was closest { - stepCount -= framesPerStep; + stepCount -= _framesPerStep; if (left == 0) - left = framesPerStep; + left = _framesPerStep; else - left = 0; + left = 0; } - } - else - { + } else { if (3*ABS(lastErrorX) < ABS(errorX)) //the last stop was closest { - stepCount -= framesPerStep; + stepCount -= _framesPerStep; if (left == 0) - left = framesPerStep; + left = _framesPerStep; else - left = 0; + left = 0; } } } - errorX = modularPath[p].x - walkAnim[stepCount-1].x; - errorY = modularPath[p].y - walkAnim[stepCount-1].y; + errorX = _modularPath[p].x - walkAnim[stepCount-1].x; + errorY = _modularPath[p].y - walkAnim[stepCount-1].y; // okay we've reached the end but we still have an error if (errorX != 0) { frameCount = 0; frames = stepCount - lastCount; - do - { + do { frameCount += 1; walkAnim[lastCount + frameCount - 1].x += errorX*frameCount/frames; - } - while (frameCount 7) lastRealDir -= NO_DIRECTIONS; module = turnFramesRight + lastRealDir; @@ -1038,8 +998,7 @@ void Router::SlidyWalkAnimator(WalkData *walkAnim) } module = standFrames + lastRealDir; walkAnim[stepCount-1].frame = module; - } - else // just stand at the end + } else // just stand at the end { module = standFrames + lastRealDir; walkAnim[stepCount].frame = module; @@ -1063,16 +1022,16 @@ void Router::SlidyWalkAnimator(WalkData *walkAnim) // * THE SOLID PATH ROUTINES // **************************************************************************** -int32 Router::SolidPath() -{ -/**************************************************************************** - * SolidPath creates a path based on whole steps with no sliding to get - * as near as possible to the target without any sliding this routine is - * currently unused, but is intended for use when just clicking about. - * - * produce a module list from the line data - * - ****************************************************************************/ +void Router::solidPath() { + /********************************************************************* + * SolidPath creates a path based on whole steps with no sliding to + * get as near as possible to the target without any sliding this + * routine is currently unused, but is intended for use when just + * clicking about. + * + * produce a module list from the line data + *********************************************************************/ + int32 smooth; int32 solid; int32 scale; @@ -1082,66 +1041,66 @@ int32 Router::SolidPath() int32 deltaY; // strip out the short sections + solid = 1; smooth = 1; - modularPath[0].x = smoothPath[0].x; - modularPath[0].y = smoothPath[0].y; - modularPath[0].dir = smoothPath[0].dir; - modularPath[0].num = 0; - - do - { - scale = scaleA * smoothPath[smooth].y + scaleB; - deltaX = smoothPath[smooth].x - modularPath[solid-1].x; - deltaY = smoothPath[smooth].y - modularPath[solid-1].y; - stepX = modX[smoothPath[smooth].dir]; - stepY = modY[smoothPath[smooth].dir]; + _modularPath[0].x = _smoothPath[0].x; + _modularPath[0].y = _smoothPath[0].y; + _modularPath[0].dir = _smoothPath[0].dir; + _modularPath[0].num = 0; + + do { + scale = _scaleA * _smoothPath[smooth].y + _scaleB; + deltaX = _smoothPath[smooth].x - _modularPath[solid - 1].x; + deltaY = _smoothPath[smooth].y - _modularPath[solid - 1].y; + stepX = _modX[_smoothPath[smooth].dir]; + stepY = _modY[_smoothPath[smooth].dir]; stepX = stepX * scale; stepY = stepY * scale; stepX = stepX >> 16; stepY = stepY >> 16; - if ((ABS(deltaX)>=ABS(stepX)) && (ABS(deltaY)>=ABS(stepY))) - { - modularPath[solid].x = smoothPath[smooth].x; - modularPath[solid].y = smoothPath[smooth].y; - modularPath[solid].dir = smoothPath[smooth].dir; - modularPath[solid].num = 1; - solid += 1; + + if (ABS(deltaX) >= ABS(stepX) && ABS(deltaY) >= ABS(stepY)) { + _modularPath[solid].x = _smoothPath[smooth].x; + _modularPath[solid].y = _smoothPath[smooth].y; + _modularPath[solid].dir = _smoothPath[smooth].dir; + _modularPath[solid].num = 1; + solid++; } - smooth += 1; - } - while (smoothPath[smooth].num < ROUTE_END_FLAG); - // in case the last bit had no steps - if (solid == 1) //there were no paths so put in a dummy end - { + + smooth++; + } while (_smoothPath[smooth].num < ROUTE_END_FLAG); + + // in case the last bit had no steps + + if (solid == 1) { + // there were no paths so put in a dummy end solid = 2; - modularPath[1].dir = smoothPath[0].dir; - modularPath[1].num = 0; + _modularPath[1].dir = _smoothPath[0].dir; + _modularPath[1].num = 0; } - modularPath[solid-1].x = smoothPath[smooth-1].x; - modularPath[solid-1].y = smoothPath[smooth-1].y; - // set up the end of the walk - modularPath[solid].x = smoothPath[smooth-1].x; - modularPath[solid].y = smoothPath[smooth-1].y; - modularPath[solid].dir = 9; - modularPath[solid].num = ROUTE_END_FLAG; - return 1; + _modularPath[solid - 1].x = _smoothPath[smooth - 1].x; + _modularPath[solid - 1].y = _smoothPath[smooth - 1].y; + + // set up the end of the walk + _modularPath[solid].x = _smoothPath[smooth - 1].x; + _modularPath[solid].y = _smoothPath[smooth - 1].y; + _modularPath[solid].dir = 9; + _modularPath[solid].num = ROUTE_END_FLAG; } -int32 Router::SolidWalkAnimator(WalkData *walkAnim) -{ -/**************************************************************************** - * SolidWalk creates an animation based on whole steps with no sliding to get - * as near as possible to the target without any sliding this routine is - * is intended for use when just clicking about. - * - * produce a module list from the line data - * - * returns 0 if solid route not found - ****************************************************************************/ - int32 p; - int32 i; +int32 Router::solidWalkAnimator(WalkData *walkAnim) { + /********************************************************************* + * SolidWalk creates an animation based on whole steps with no sliding + * to get as near as possible to the target without any sliding. This + * routine is is intended for use when just clicking about. + * + * produce a module list from the line data + * + * returns 0 if solid route not found + *********************************************************************/ + int32 left; int32 lastDir; int32 currentDir; @@ -1162,12 +1121,11 @@ int32 Router::SolidWalkAnimator(WalkData *walkAnim) int32 frame; // start at the begining for a change - lastDir = modularPath[0].dir; - p = 1; - currentDir = modularPath[1].dir; - module = framesPerChar + lastDir; - moduleX = startX; - moduleY = startY; + lastDir = _modularPath[0].dir; + currentDir = _modularPath[1].dir; + module = _framesPerChar + lastDir; + moduleX = _startX; + moduleY = _startY; module16X = moduleX << 16; module16Y = moduleY << 16; slowStart = 0; @@ -1209,9 +1167,7 @@ int32 Router::SolidWalkAnimator(WalkData *walkAnim) if ( turnDir < 0) // new frames for turn frames 29oct95jps { module = turnFramesLeft + lastDir; - } - else - { + } else { module = turnFramesRight + lastDir; } walkAnim[stepCount].frame = module; @@ -1231,9 +1187,7 @@ int32 Router::SolidWalkAnimator(WalkData *walkAnim) if ( lastDir < 0) lastDir += NO_DIRECTIONS; module = turnFramesLeft + lastDir; - } - else - { + } else { if ( lastDir > 7) lastDir -= NO_DIRECTIONS; module = turnFramesRight + lastDir; @@ -1255,12 +1209,9 @@ int32 Router::SolidWalkAnimator(WalkData *walkAnim) //**************************************************************************** // do start frames if its george and left or right - if (megaId == GEORGE) - { - if (modularPath[1].num > 0) - { - if (currentDir == 2) // only for george - { + if (megaId == GEORGE) { + if (_modularPath[1].num > 0) { + if (currentDir == 2) { // only for george slowStart = 1; walkAnim[stepCount].frame = 296; walkAnim[stepCount].step = 0; @@ -1280,9 +1231,7 @@ int32 Router::SolidWalkAnimator(WalkData *walkAnim) walkAnim[stepCount].x = moduleX; walkAnim[stepCount].y = moduleY; stepCount += 1; - } - else if (currentDir == 6) // only for george - { + } else if (currentDir == 6) { // only for george slowStart = 1; walkAnim[stepCount].frame = 299; walkAnim[stepCount].step = 0; @@ -1311,7 +1260,7 @@ int32 Router::SolidWalkAnimator(WalkData *walkAnim) //**************************************************************************** if (currentDir > 4) - left = framesPerStep; + left = _framesPerStep; else left = 0; @@ -1319,24 +1268,22 @@ int32 Router::SolidWalkAnimator(WalkData *walkAnim) lastDir = 99;// this ensures that we don't put in turn frames for the start currentDir = 99;// this ensures that we don't put in turn frames for the start - do - { - while (modularPath[p].num > 0) - { - currentDir = modularPath[p].dir; - if (currentDir< NO_DIRECTIONS) - { + int32 p; - module = currentDir * framesPerStep * 2 + left; + for (p = 1; _modularPath[p].dir < NO_DIRECTIONS; ++p) { + while (_modularPath[p].num > 0) { + currentDir = _modularPath[p].dir; + if (currentDir < NO_DIRECTIONS) { + + module = currentDir * _framesPerStep * 2 + left; if (left == 0) - left = framesPerStep; + left = _framesPerStep; else left = 0; - moduleEnd = module + framesPerStep; + moduleEnd = module + _framesPerStep; step = 0; - scale = (scaleA * moduleY + scaleB); - do - { + scale = (_scaleA * moduleY + _scaleB); + do { module16X += _dx[module]*scale; module16Y += _dy[module]*scale; moduleX = module16X >> 16; @@ -1349,18 +1296,16 @@ int32 Router::SolidWalkAnimator(WalkData *walkAnim) stepCount += 1; module += 1; step += 1; - } - while ( module < moduleEnd) ; - errorX = modularPath[p].x - moduleX; - errorX = errorX * modX[modularPath[p].dir]; - errorY = modularPath[p].y - moduleY; - errorY = errorY * modY[modularPath[p].dir]; - if ((errorX < 0) || (errorY < 0)) - { - modularPath[p].num = 0; - stepCount -= framesPerStep; + } while ( module < moduleEnd) ; + errorX = _modularPath[p].x - moduleX; + errorX = errorX * _modX[_modularPath[p].dir]; + errorY = _modularPath[p].y - moduleY; + errorY = errorY * _modY[_modularPath[p].dir]; + if ((errorX < 0) || (errorY < 0)) { + _modularPath[p].num = 0; + stepCount -= _framesPerStep; if (left == 0) - left = framesPerStep; + left = _framesPerStep; else left = 0; // Okay this is the end of a section @@ -1368,44 +1313,35 @@ int32 Router::SolidWalkAnimator(WalkData *walkAnim) moduleY = walkAnim[stepCount-1].y; module16X = moduleX << 16; module16Y = moduleY << 16; - modularPath[p].x =moduleX; - modularPath[p].y =moduleY; + _modularPath[p].x =moduleX; + _modularPath[p].y =moduleY; // Now is the time to put in the turn frames for the last turn - if ((stepCount - lastCount) < framesPerStep)// no step taken - { + if ((stepCount - lastCount) < _framesPerStep) { // no step taken currentDir = 99;// this ensures that we don't put in turn frames for this walk or the next - if (slowStart == 1)// clean up if a slow in but no walk - { + if (slowStart == 1) { // clean up if a slow in but no walk stepCount -= 3; lastCount -= 3; slowStart = 0; } } // check each turn condition in turn - if (((lastDir != 99) && (currentDir != 99)) && (megaId == GEORGE)) // only for george - { + if (((lastDir != 99) && (currentDir != 99)) && (megaId == GEORGE)) { // only for george lastDir = currentDir - lastDir;//1 and -7 going right -1 and 7 going left - if (((lastDir == -1) || (lastDir == 7)) || ((lastDir == -2) || (lastDir == 6))) - { + if (((lastDir == -1) || (lastDir == 7)) || ((lastDir == -2) || (lastDir == 6))) { // turn at the end of the last walk - frame = lastCount - framesPerStep; - do - { + frame = lastCount - _framesPerStep; + do { walkAnim[frame].frame += 104;//turning left frame += 1; - } - while (frame < lastCount ); + } while (frame < lastCount ); } - if (((lastDir == 1) || (lastDir == -7)) || ((lastDir == 2) || (lastDir == -6))) - { + if (((lastDir == 1) || (lastDir == -7)) || ((lastDir == 2) || (lastDir == -6))) { // turn at the end of the current walk - frame = lastCount - framesPerStep; - do - { + frame = lastCount - _framesPerStep; + do { walkAnim[frame].frame += 200; //was 60 now 116 frame += 1; - } - while (frame < lastCount ); + } while (frame < lastCount ); } } // all turns checked @@ -1413,45 +1349,35 @@ int32 Router::SolidWalkAnimator(WalkData *walkAnim) } } } - p = p + 1; lastDir = currentDir; slowStart = 0; //can only be valid first time round } - while (modularPath[p].dir < NO_DIRECTIONS); //**************************************************************************** // SOLID // THE SLOW OUT //**************************************************************************** - if ((currentDir == 2) && (megaId == GEORGE)) // only for george - { + if ((currentDir == 2) && (megaId == GEORGE)) { // only for george // place stop frames here // slowdown at the end of the last walk - frame = lastCount - framesPerStep; - if (walkAnim[frame].frame == 24) - { - do - { + frame = lastCount - _framesPerStep; + if (walkAnim[frame].frame == 24) { + do { walkAnim[frame].frame += 278;//stopping right frame += 1; - } - while (frame < lastCount ); + } while (frame < lastCount ); walkAnim[stepCount].frame = 308; walkAnim[stepCount].step = 7; walkAnim[stepCount].dir = currentDir; walkAnim[stepCount].x = moduleX; walkAnim[stepCount].y = moduleY; stepCount += 1; - } - else if (walkAnim[frame].frame == 30) - { - do - { + } else if (walkAnim[frame].frame == 30) { + do { walkAnim[frame].frame += 279;//stopping right frame += 1; - } - while (frame < lastCount ); + } while (frame < lastCount ); walkAnim[stepCount].frame = 315; walkAnim[stepCount].step = 7; walkAnim[stepCount].dir = currentDir; @@ -1459,35 +1385,26 @@ int32 Router::SolidWalkAnimator(WalkData *walkAnim) walkAnim[stepCount].y = moduleY; stepCount += 1; } - } - else if ((currentDir == 6) && (megaId == GEORGE)) // only for george - { + } else if ((currentDir == 6) && (megaId == GEORGE)) { // only for george // place stop frames here // slowdown at the end of the last walk - frame = lastCount - framesPerStep; - if (walkAnim[frame].frame == 72) - { - do - { + frame = lastCount - _framesPerStep; + if (walkAnim[frame].frame == 72) { + do { walkAnim[frame].frame += 244;//stopping left frame += 1; - } - while (frame < lastCount ); + } while (frame < lastCount ); walkAnim[stepCount].frame = 322; walkAnim[stepCount].step = 7; walkAnim[stepCount].dir = currentDir; walkAnim[stepCount].x = moduleX; walkAnim[stepCount].y = moduleY; stepCount += 1; - } - else if (walkAnim[frame].frame == 78) - { - do - { + } else if (walkAnim[frame].frame == 78) { + do { walkAnim[frame].frame += 245;//stopping left frame += 1; - } - while (frame < lastCount ); + } while (frame < lastCount ); walkAnim[stepCount].frame = 329; walkAnim[stepCount].step = 7; walkAnim[stepCount].dir = currentDir; @@ -1496,10 +1413,10 @@ int32 Router::SolidWalkAnimator(WalkData *walkAnim) stepCount += 1; } } - module = framesPerChar + modularPath[p-1].dir; + module = _framesPerChar + _modularPath[p-1].dir; walkAnim[stepCount].frame = module; walkAnim[stepCount].step = 0; - walkAnim[stepCount].dir = modularPath[p-1].dir; + walkAnim[stepCount].dir = _modularPath[p-1].dir; walkAnim[stepCount].x = moduleX; walkAnim[stepCount].y = moduleY; stepCount += 1; @@ -1515,26 +1432,20 @@ int32 Router::SolidWalkAnimator(WalkData *walkAnim) // NO END TURNS //**************************************************************************** -// Tdebug("RouteFinder RouteSize is %d", stepCount); -// now check the route - i = 0; - do - { - if (!Check(modularPath[i].x, modularPath[i].y, modularPath[i+1].x, modularPath[i+1].y)) - p=0; - i += 1; - } - while (i node[i].dist) - { - x2 = node[k].x; - y2 = node[k].y; - - if (ABS(x2-x1)>(4.5*ABS(y2-y1))) - { - distance = (8*ABS(x2-x1)+18*ABS(y2-y1))/(54*8)+1; - } +bool Router::scan(int32 level) { + /********************************************************************* + * Called successively from routeFinder until no more changes take + * place in the grid array, ie he best path has been found + * + * Scans through every point in the node array and checks if there is + * a route between each point and if this route gives a new route. + * + * This routine could probably halve its processing time if it doubled + * up on the checks after each route check + * + *********************************************************************/ + + int32 x1, y1, x2, y2; + int32 distance; + bool changed = false; + + // For all the nodes that have new values and a distance less than + // enddist, ie dont check for new routes from a point we checked + // before or from a point that is already further away than the best + // route so far. + + for (int i = 0; i < _nNodes; i++) { + if (_node[i].dist < _node[_nNodes].dist && _node[i].level == level) { + x1 = _node[i].x; + y1 = _node[i].y; + + for (int j = _nNodes; j > 0; j--) { + if (_node[j].dist > _node[i].dist) { + x2 = _node[j].x; + y2 = _node[j].y; + + if (ABS(x2 - x1) > 4.5 * ABS(y2 - y1)) + distance = (8 * ABS(x2 - x1) + 18 * ABS(y2 - y1)) / (54 * 8) + 1; else - { - distance = (6*ABS(x2-x1)+36*ABS(y2-y1))/(36*14)+1; - } - - if ((distance + node[i].dist < node[nnodes].dist) && (distance + node[i].dist < node[k].dist)) - { - if (NewCheck(0, x1,y1,x2,y2)) - { - node[k].level = level + 1; - node[k].dist = distance + node[i].dist; - node[k].prev = i; - changed = 1; + distance = (6 * ABS(x2 - x1) + 36 * ABS(y2 - y1)) / (36 * 14) + 1; + + if (distance + _node[i].dist < _node[_nNodes].dist && distance + _node[i].dist < _node[j].dist) { + if (newCheck(0, x1, y1, x2, y2)) { + _node[j].level = level + 1; + _node[j].dist = distance + _node[i].dist; + _node[j].prev = i; + changed = true; } } } - k-=1; } - while (k > 0); } - i=i+1; } - while (i < nnodes); + return changed; } -int32 Router::NewCheck(int32 status, int32 x1 , int32 y1 , int32 x2 ,int32 y2) -/****************************************************************************** - * NewCheck routine checks if the route between two points can be achieved - * without crossing any of the bars in the Bars array. - * - * NewCheck differs from check in that that 4 route options are considered - * corresponding to actual walked routes. - * - * Note distance doesnt take account of shrinking ??? - * - * Note Bars array must be properly calculated ie min max dx dy co - *****************************************************************************/ -{ - int32 dx; - int32 dy; - int32 dlx; - int32 dly; - int32 dirX; - int32 dirY; - int32 step1; - int32 step2; - int32 step3; - int32 steps; - int32 options; +int32 Router::newCheck(int32 status, int32 x1 , int32 y1 , int32 x2 ,int32 y2) { + /********************************************************************* + * newCheck routine checks if the route between two points can be + * achieved without crossing any of the bars in the Bars array. + * + * newCheck differs from check in that that 4 route options are + * considered corresponding to actual walked routes. + * + * Note distance doesnt take account of shrinking ??? + * + * Note Bars array must be properly calculated ie min max dx dy co + *********************************************************************/ + + int32 ldx; + int32 ldy; + int32 dlx; + int32 dly; + int32 dirX; + int32 dirY; + int32 step1; + int32 step2; + int32 step3; + int32 steps; + int32 options; steps = 0; options = 0; - dx = x2 - x1; - dy = y2 - y1; + ldx = x2 - x1; + ldy = y2 - y1; dirX = 1; dirY = 1; - if (dx < 0) - { - dx = -dx; + + if (ldx < 0) { + ldx = -ldx; dirX = -1; } - if (dy < 0) - { - dy = -dy; + if (ldy < 0) { + ldy = -ldy; dirY = -1; } - //make the route options - if ((diagonaly * dx) > (diagonalx * dy)) // dir = 1,2 or 2,3 or 5,6 or 6,7 - { - dly = dy; - dlx = (dy*diagonalx)/diagonaly; - dx = dx - dlx; + // make the route options + + if (_diagonaly * ldx > _diagonalx * ldy) { + // dir = 1,2 or 2,3 or 5,6 or 6,7 + + dly = ldy; + dlx = (ldy * _diagonalx) / _diagonaly; + ldx = ldx - dlx; dlx = dlx * dirX; dly = dly * dirY; - dx = dx * dirX; - dy = 0; - - //options are - //square, diagonal a code 1 route - step1 = Check(x1, y1, x1+dx, y1); - if (step1 != 0) - { - step2 = Check(x1+dx, y1, x2, y2); - if (step2 != 0) - { - steps = step1 + step2; // yes - options = options + 2; + ldx = ldx * dirX; + ldy = 0; + + // options are square, diagonal a code 1 route + step1 = check(x1, y1, x1 + ldx, y1); + if (step1 != 0) { + step2 = check(x1 + ldx, y1, x2, y2); + if (step2 != 0) { + steps = step1 + step2; + options |= 2; } } - //diagonal, square a code 2 route - if ((steps == 0) || (status == 1)) - { - step1 = Check(x1, y1, x1+dlx,y1+dly); - if (step1 != 0) - { - step2 = Check(x1+dlx, y2, x2, y2); - if (step2 != 0) - { - steps = step1 + step2; // yes - options = options + 4; + + // diagonal, square a code 2 route + if (steps == 0 || status == 1) { + step1 = check(x1, y1, x1 + dlx, y1 + dly); + if (step1 != 0) { + step2 = check(x1 + dlx, y2, x2, y2); + if (step2 != 0) { + steps = step1 + step2; + options |= 4; } } } - //halfsquare, diagonal, halfsquare a code 0 route - if ((steps == 0) || (status == 1)) - { - step1 = Check(x1, y1, x1+dx/2, y1); - if (step1 != 0) - { - step2 = Check(x1+dx/2, y1, x1+dx/2+dlx, y2); - if (step2 != 0) - { - step3 = Check(x1+dx/2+dlx, y2, x2, y2); - if (step3 != 0) - { - steps = step1 + step2 + step3; // yes - options = options + 1; + + // halfsquare, diagonal, halfsquare a code 0 route + if (steps == 0 || status == 1) { + step1 = check(x1, y1, x1 + ldx / 2, y1); + if (step1 != 0) { + step2 = check(x1 + ldx / 2, y1, x1 + ldx / 2 + dlx, y2); + if (step2 != 0) { + step3 = check(x1 + ldx / 2 + dlx, y2, x2, y2); + if (step3 != 0) { + steps = step1 + step2 + step3; + options |= 1; } } } } - //halfdiagonal, square, halfdiagonal a code 3 route - if ((steps == 0) || (status == 1)) - { - step1 = Check(x1, y1, x1+dlx/2, y1+dly/2); - if (step1 != 0) - { - step2 = Check(x1+dlx/2, y1+dly/2, x1+dx+dlx/2, y1+dly/2); - if (step2 != 0) - { - step3 = Check(x1+dx+dlx/2, y1+dly/2, x2, y2); - if (step3 != 0) - { - steps = step1 + step2 + step3; // yes - options = options + 8; + + // halfdiagonal, square, halfdiagonal a code 3 route + if (steps == 0 || status == 1) { + step1 = check(x1, y1, x1 + dlx / 2, y1 + dly / 2); + if (step1 != 0) { + step2 = check(x1 + dlx / 2, y1 + dly / 2, x1 + ldx + dlx / 2, y1 + dly / 2); + if (step2 != 0) { + step3 = check(x1 + ldx + dlx / 2, y1 + dly / 2, x2, y2); + if (step3 != 0) { + steps = step1 + step2 + step3; + options |= 8; } } } } - } - else // dir = 7,0 or 0,1 or 3,4 or 4,5 - { - dlx = dx; - dly = (dx*diagonaly)/diagonalx; - dy = dy - dly; + } else { + // dir = 7,0 or 0,1 or 3,4 or 4,5 + + dlx = ldx; + dly = (ldx * _diagonaly) / _diagonalx; + ldy = ldy - dly; dlx = dlx * dirX; dly = dly * dirY; - dy = dy * dirY; - dx = 0; - - //options are - //square, diagonal a code 1 route - step1 = Check(x1 ,y1 ,x1 ,y1+dy ); - if (step1 != 0) - { - step2 = Check(x1 ,y1+dy ,x2,y2); - if (step2 != 0) - { - steps = step1 + step2; // yes - options = options + 2; + ldy = ldy * dirY; + ldx = 0; + + // options are square, diagonal a code 1 route + step1 = check(x1 ,y1, x1, y1 + ldy); + if (step1 != 0) { + step2 = check(x1, y1 + ldy, x2, y2); + if (step2 != 0) { + steps = step1 + step2; + options |= 2; } } - //diagonal, square a code 2 route - if ((steps == 0) || (status == 1)) - { - step1 = Check(x1, y1, x2, y1+dly); - if (step1 != 0) - { - step2 = Check(x2, y1+dly, x2, y2); - if (step2 != 0) - { - steps = step1 + step2; // yes - options = options + 4; + + // diagonal, square a code 2 route + if (steps == 0 || status == 1) { + step1 = check(x1, y1, x2, y1 + dly); + if (step1 != 0) { + step2 = check(x2, y1 + dly, x2, y2); + if (step2 != 0) { + steps = step1 + step2; + options |= 4; } } } - //halfsquare, diagonal, halfsquare a code 0 route - if ((steps == 0) || (status == 1)) - { - step1 = Check(x1, y1, x1, y1+dy/2); - if (step1 != 0) - { - step2 = Check(x1, y1+dy/2, x2, y1+dy/2+dly); - if (step2 != 0) - { - step3 = Check(x2, y1+dy/2+dly, x2, y2); - if (step3 != 0) - { - steps = step1 + step2 + step3; // yes - options = options + 1; + + // halfsquare, diagonal, halfsquare a code 0 route + if (steps == 0 || status == 1) { + step1 = check(x1, y1, x1, y1 + ldy / 2); + if (step1 != 0) { + step2 = check(x1, y1 + ldy / 2, x2, y1 + ldy / 2 + dly); + if (step2 != 0) { + step3 = check(x2, y1 + ldy / 2 + dly, x2, y2); + if (step3 != 0) { + steps = step1 + step2 + step3; + options |= 1; } } } } - //halfdiagonal, square, halfdiagonal a code 3 route - if ((steps == 0) || (status == 1)) - { - step1 = Check(x1, y1, x1+dlx/2, y1+dly/2); - if (step1 != 0) - { - step2 = Check(x1+dlx/2, y1+dly/2, x1+dlx/2, y1+dy+dly/2); - if (step2 != 0) - { - step3 = Check(x1+dlx/2, y1+dy+dly/2, x2, y2); - if (step3 != 0) - { - steps = step1 + step2 + step3; // yes - options = options + 8; + + // halfdiagonal, square, halfdiagonal a code 3 route + if (steps == 0 || status == 1) { + step1 = check(x1, y1, x1 + dlx / 2, y1 + dly / 2); + if (step1 != 0) { + step2 = check(x1 + dlx / 2, y1 + dly / 2, x1 + dlx / 2, y1 + ldy + dly / 2); + if (step2 != 0) { + step3 = check(x1 + dlx / 2, y1 + ldy + dly / 2, x2, y2); + if (step3 != 0) { + steps = step1 + step2 + step3; + options |= 8; } } } } } + if (status == 0) - { status = steps; - } else - { status = options; - } + return status; } @@ -1819,296 +1692,186 @@ int32 Router::NewCheck(int32 status, int32 x1 , int32 y1 , int32 x2 ,int32 y2) // * CHECK ROUTINES // **************************************************************************** -int32 Router::Check(int32 x1 , int32 y1 , int32 x2 ,int32 y2) -{ -//call the fastest line check for the given line -//returns 1 if line didn't cross any bars - int32 steps; +bool Router::check(int32 x1, int32 y1, int32 x2, int32 y2) { + // call the fastest line check for the given line + // returns true if line didn't cross any bars - if ((x1 == x2) && (y1 == y2)) - { - steps = 1; - } - else if (x1 == x2) - { - steps = VertCheck(x1, y1, y2); - } - else if (y1 == y2) - { - steps = HorizCheck(x1, y1, x2); - } - else - { - steps = LineCheck(x1, y1, x2, y2); - } - return steps; + if (x1 == x2 && y1 == y2) + return true; -} + if (x1 == x2) + return vertCheck(x1, y1, y2); + if (y1 == y2) + return horizCheck(x1, y1, x2); -int32 Router::LineCheck(int32 x1 , int32 y1 , int32 x2 ,int32 y2) -{ - int32 dirx; - int32 diry; - int32 co; - int32 slope; - int32 i; - int32 xc; - int32 yc; - int32 xmin; - int32 ymin; - int32 xmax; - int32 ymax; - int32 linesCrossed = 1; - - - if (x1 > x2) - { - xmin = x2; - xmax = x1; - } - else - { - xmin = x1; - xmax = x2; - } - if (y1 > y2) - { - ymin = y2; - ymax = y1; - } - else - { - ymin = y1; - ymax = y2; - } - //line set to go one step in chosen direction - //so ignore if it hits anything - dirx = x2 - x1; - diry = y2 - y1; - co = (y1 *dirx)- (x1*diry); //new line equation - - i = 0; - do - { - // this is the inner inner loop - if ((xmax >= bars[i].xmin) && ( xmin <= bars[i].xmax)) //skip if not on module - { - if ((ymax >= bars[i].ymin) && ( ymin <= bars[i].ymax)) //skip if not on module - { - // okay its a valid line calculate an intersept - // wow but all this arithmatic we must have loads of time - slope = (bars[i].dx * diry) - (bars[i].dy *dirx);// slope it he slope between the two lines - if (slope != 0)//assuming parallel lines don't cross - { - //calculate x intercept and check its on both lines - xc = ((bars[i].co * dirx) - (co * bars[i].dx)) / slope; - - if ((xc >= xmin-1) && (xc <= xmax+1)) //skip if not on module - { - if ((xc >= bars[i].xmin-1) && (xc <= bars[i].xmax+1)) //skip if not on line - { - - yc = ((bars[i].co * diry) - (co * bars[i].dy)) / slope; + return lineCheck(x1, y1, x2, y2); +} - if ((yc >= ymin-1) && (yc <= ymax+1)) //skip if not on module - { - if ((yc >= bars[i].ymin-1) && (yc <= bars[i].ymax+1)) //skip if not on line - { - linesCrossed = 0; - } +bool Router::lineCheck(int32 x1, int32 y1, int32 x2, int32 y2) { + bool linesCrossed = true; + + int32 xmin = MIN(x1, x2); + int32 xmax = MAX(x1, x2); + int32 ymin = MIN(y1, y2); + int32 ymax = MAX(y1, y2); + + // Line set to go one step in chosen direction so ignore if it hits + // anything + + int32 dirx = x2 - x1; + int32 diry = y2 - y1; + + int32 co = (y1 * dirx) - (x1 * diry); // new line equation + + for (int i = 0; i < _nBars && linesCrossed; i++) { + // skip if not on module + if (xmax >= _bars[i].xmin && xmin <= _bars[i].xmax && ymax >= _bars[i].ymin && ymin <= _bars[i].ymax) { + // Okay, it's a valid line. Calculate an intercept. Wow + // but all this arithmetic we must have loads of time + + // slope it he slope between the two lines + int32 slope = (_bars[i].dx * diry) - (_bars[i].dy *dirx); + // assuming parallel lines don't cross + if (slope != 0) { + // calculate x intercept and check its on both + // lines + int32 xc = ((_bars[i].co * dirx) - (co * _bars[i].dx)) / slope; + + // skip if not on module + if (xc >= xmin - 1 && xc <= xmax + 1) { + // skip if not on line + if (xc >= _bars[i].xmin - 1 && xc <= _bars[i].xmax + 1) { + int32 yc = ((_bars[i].co * diry) - (co * _bars[i].dy)) / slope; + + // skip if not on module + if (yc >= ymin - 1 && yc <= ymax + 1) { + // skip if not on line + if (yc >= _bars[i].ymin - 1 && yc <= _bars[i].ymax + 1) { + linesCrossed = false; } } } } } } - i = i + 1; } - while ((i < nbars) && linesCrossed); return linesCrossed; } -int32 Router::HorizCheck(int32 x1 , int32 y , int32 x2) -{ - int32 dy; - int32 i; - int32 xc; - int32 xmin; - int32 xmax; - int32 linesCrossed = 1; - - if (x1 > x2) - { - xmin = x2; - xmax = x1; - } - else - { - xmin = x1; - xmax = x2; - } - //line set to go one step in chosen direction - //so ignore if it hits anything - - i = 0; - do - { - // this is the inner inner loop - if ((xmax >= bars[i].xmin) && ( xmin <= bars[i].xmax)) //skip if not on module - { - if ((y >= bars[i].ymin) && ( y <= bars[i].ymax)) //skip if not on module - { - // okay its a valid line calculate an intersept - // wow but all this arithmatic we must have loads of time - if (bars[i].dy == 0) - { - linesCrossed = 0; - } - else - { - dy = y-bars[i].y1; - xc = bars[i].x1 + (bars[i].dx * dy)/bars[i].dy; - if ((xc >= xmin-1) && (xc <= xmax+1)) //skip if not on module - { - linesCrossed = 0; - } - } +bool Router::horizCheck(int32 x1, int32 y, int32 x2) { + bool linesCrossed = true; + + int32 xmin = MIN(x1, x2); + int32 xmax = MAX(x1, x2); + + // line set to go one step in chosen direction so ignore if it hits + // anything + + for (int i = 0; i < _nBars && linesCrossed; i++) { + // skip if not on module + if (xmax >= _bars[i].xmin && xmin <= _bars[i].xmax && y >= _bars[i].ymin && y <= _bars[i].ymax) { + // Okay, it's a valid line calculate an intercept. Wow + // but all this arithmetic we must have loads of time + + if (_bars[i].dy == 0) + linesCrossed = false; + else { + int32 ldy = y - _bars[i].y1; + int32 xc = _bars[i].x1 + (_bars[i].dx * ldy) / _bars[i].dy; + // skip if not on module + if (xc >= xmin - 1 && xc <= xmax + 1) + linesCrossed = false; } } - i = i + 1; } - while ((i < nbars) && linesCrossed); return linesCrossed; } +bool Router::vertCheck(int32 x, int32 y1, int32 y2) { + bool linesCrossed = true; -int32 Router::VertCheck(int32 x, int32 y1, int32 y2) -{ - int32 dx; - int32 i; - int32 yc; - int32 ymin; - int32 ymax; - int32 linesCrossed = 1; - - if (y1 > y2) - { - ymin = y2; - ymax = y1; - } - else - { - ymin = y1; - ymax = y2; - } - //line set to go one step in chosen direction - //so ignore if it hits anything - i = 0; - do // this is the inner inner loop - { - if ((x >= bars[i].xmin) && ( x <= bars[i].xmax)) //overlapping - { - if ((ymax >= bars[i].ymin) && ( ymin <= bars[i].ymax)) //skip if not on module - { - // okay its a valid line calculate an intersept - // wow but all this arithmatic we must have loads of time - if (bars[i].dx == 0)//both lines vertical and overlap in x and y so they cross - { - linesCrossed = 0; - } - else - { - dx = x-bars[i].x1; - yc = bars[i].y1 + (bars[i].dy * dx)/bars[i].dx; - if ((yc >= ymin-1) && (yc <= ymax+1)) //the intersept overlaps - { - linesCrossed = 0; - } - } + int32 ymin = MIN(y1, y2); + int32 ymax = MAX(y1, y2); + + // Line set to go one step in chosen direction so ignore if it hits + // anything + + for (int i = 0; i < _nBars && linesCrossed; i++) { + // skip if not on module + if (x >= _bars[i].xmin && x <= _bars[i].xmax && ymax >= _bars[i].ymin && ymin <= _bars[i].ymax) { + // Okay, it's a valid line calculate an intercept. Wow + // but all this arithmetic we must have loads of time + + // both lines vertical and overlap in x and y so they + // cross + + if (_bars[i].dx == 0) + linesCrossed = false; + else { + int32 ldx = x - _bars[i].x1; + int32 yc = _bars[i].y1 + (_bars[i].dy * ldx) / _bars[i].dx; + // the intercept overlaps + if (yc >= ymin - 1 && yc <= ymax + 1) + linesCrossed = false; } } - i = i + 1; } - while ((i < nbars) && linesCrossed); return linesCrossed; } -int32 Router::CheckTarget(int32 x , int32 y) -{ - int32 dx; - int32 dy; - int32 i; - int32 xc; - int32 yc; - int32 xmin; - int32 xmax; - int32 ymin; - int32 ymax; - int32 onLine = 0; - - xmin = x - 1; - xmax = x + 1; - ymin = y - 1; - ymax = y + 1; +int32 Router::checkTarget(int32 x, int32 y) { + int32 onLine = 0; + + int32 xmin = x - 1; + int32 xmax = x + 1; + int32 ymin = y - 1; + int32 ymax = y + 1; // check if point +- 1 is on the line - //so ignore if it hits anything + // so ignore if it hits anything - i = 0; - do - { + for (int i = 0; i < _nBars && onLine == 0; i++) { + // overlapping line + if (xmax >= _bars[i].xmin && xmin <= _bars[i].xmax && ymax >= _bars[i].ymin && ymin <= _bars[i].ymax) { + int32 xc, yc; - // this is the inner inner loop + // okay this line overlaps the target calculate an y intercept for x - if ((xmax >= bars[i].xmin) && ( xmin <= bars[i].xmax)) //overlapping line - { - if ((ymax >= bars[i].ymin) && ( ymin <= bars[i].ymax)) //overlapping line - { - - // okay this line overlaps the target calculate an y intersept for x - - if (bars[i].dx == 0)// vertical line so we know it overlaps y - { - yc = 0; - } - else - { - dx = x-bars[i].x1; - yc = bars[i].y1 + (bars[i].dy * dx)/bars[i].dx; - } + // vertical line so we know it overlaps y + if (_bars[i].dx == 0) + yc = 0; + else { + int ldx = x - _bars[i].x1; + yc = _bars[i].y1 + (_bars[i].dy * ldx) / _bars[i].dx; + } - if ((yc >= ymin) && (yc <= ymax)) //overlapping point for y - { - onLine = 3;// target on a line so drop out - //Tdebug("RouteFail due to target on a line %d %d",x,y); + // overlapping point for y + if (yc >= ymin && yc <= ymax) { + // target on a line so drop out + onLine = 3; + debug(5, "RouteFail due to target on a line %d %d", x, y); + } else { + // vertical line so we know it overlaps y + if (_bars[i].dy == 0) + xc = 0; + else { + int32 ldy = y - _bars[i].y1; + xc = _bars[i].x1 + (_bars[i].dx * ldy) / _bars[i].dy; } - else - { - if (bars[i].dy == 0)// vertical line so we know it overlaps y - { - xc = 0; - } - else - { - dy = y-bars[i].y1; - xc = bars[i].x1 + (bars[i].dx * dy)/bars[i].dy; - } - if ((xc >= xmin) && (xc <= xmax)) //skip if not on module - { - onLine = 3;// target on a line so drop out - //Tdebug("RouteFail due to target on a line %d %d",x,y); - } + // skip if not on module + if (xc >= xmin && xc <= xmax) { + // target on a line so drop out + onLine = 3; + debug(5, "RouteFail due to target on a line %d %d", x, y); } } } - i = i + 1; } - while ((i < nbars) && (onLine == 0)); return onLine; } @@ -2145,56 +1908,54 @@ int32 Router::LoadWalkResources(Object *megaObject, int32 x, int32 y, int32 dir) fPolygrid = (uint8*)_resMan->openFetchRes(walkGridResourceId); - fPolygrid += sizeof(Header); - memcpy(&floorHeader,fPolygrid,sizeof(WalkGridHeader)); - fPolygrid += sizeof(WalkGridHeader); - nbars = FROM_LE_32(floorHeader.numBars); + fPolygrid += sizeof(Header); + memcpy(&floorHeader,fPolygrid,sizeof(WalkGridHeader)); + fPolygrid += sizeof(WalkGridHeader); + _nBars = FROM_LE_32(floorHeader.numBars); - if (nbars >= O_GRID_SIZE) + if (_nBars >= O_GRID_SIZE) { #ifdef DEBUG //check for id > number in file, - error("RouteFinder Error too many bars %d", nbars); + error("RouteFinder Error too many _bars %d", _nBars); #endif - nbars = 0; + _nBars = 0; } - nnodes = FROM_LE_32(floorHeader.numNodes)+1; //array starts at 0 begins at a start node has nnodes nodes and a target node + _nNodes = FROM_LE_32(floorHeader.numNodes)+1; //array starts at 0 begins at a start _node has nnodes nodes and a target _node - if (nnodes >= O_GRID_SIZE) + if (_nNodes >= O_GRID_SIZE) { #ifdef DEBUG //check for id > number in file, - error("RouteFinder Error too many nodes %d", nnodes); + error("RouteFinder Error too many nodes %d", _nNodes); #endif - nnodes = 0; - } - - /*memmove(&bars[0],fPolygrid,nbars*sizeof(BarData)); - fPolygrid += nbars*sizeof(BarData);//move pointer to start of node data*/ - for (cnt = 0; cnt < nbars; cnt++) { - bars[cnt].x1 = READ_LE_UINT16(fPolygrid); fPolygrid += 2; - bars[cnt].y1 = READ_LE_UINT16(fPolygrid); fPolygrid += 2; - bars[cnt].x2 = READ_LE_UINT16(fPolygrid); fPolygrid += 2; - bars[cnt].y2 = READ_LE_UINT16(fPolygrid); fPolygrid += 2; - bars[cnt].xmin = READ_LE_UINT16(fPolygrid); fPolygrid += 2; - bars[cnt].ymin = READ_LE_UINT16(fPolygrid); fPolygrid += 2; - bars[cnt].xmax = READ_LE_UINT16(fPolygrid); fPolygrid += 2; - bars[cnt].ymax = READ_LE_UINT16(fPolygrid); fPolygrid += 2; - bars[cnt].dx = READ_LE_UINT16(fPolygrid); fPolygrid += 2; - bars[cnt].dy = READ_LE_UINT16(fPolygrid); fPolygrid += 2; - bars[cnt].co = READ_LE_UINT32(fPolygrid); fPolygrid += 4; - } - - /*j = 1;// leave node 0 for start node - do - { - memmove(&node[j].x,fPolygrid,2*sizeof(int16)); + _nNodes = 0; + } + + /*memmove(&_bars[0],fPolygrid,_nBars*sizeof(BarData)); + fPolygrid += _nBars*sizeof(BarData);//move pointer to start of _node data*/ + for (cnt = 0; cnt < _nBars; cnt++) { + _bars[cnt].x1 = READ_LE_UINT16(fPolygrid); fPolygrid += 2; + _bars[cnt].y1 = READ_LE_UINT16(fPolygrid); fPolygrid += 2; + _bars[cnt].x2 = READ_LE_UINT16(fPolygrid); fPolygrid += 2; + _bars[cnt].y2 = READ_LE_UINT16(fPolygrid); fPolygrid += 2; + _bars[cnt].xmin = READ_LE_UINT16(fPolygrid); fPolygrid += 2; + _bars[cnt].ymin = READ_LE_UINT16(fPolygrid); fPolygrid += 2; + _bars[cnt].xmax = READ_LE_UINT16(fPolygrid); fPolygrid += 2; + _bars[cnt].ymax = READ_LE_UINT16(fPolygrid); fPolygrid += 2; + _bars[cnt].dx = READ_LE_UINT16(fPolygrid); fPolygrid += 2; + _bars[cnt].dy = READ_LE_UINT16(fPolygrid); fPolygrid += 2; + _bars[cnt].co = READ_LE_UINT32(fPolygrid); fPolygrid += 4; + } + + /*j = 1;// leave _node 0 for start _node + do { + memmove(&_node[j].x,fPolygrid,2*sizeof(int16)); fPolygrid += 2*sizeof(int16); j ++; - } - while (j < nnodes);//array starts at 0*/ - for (cnt = 1; cnt < nnodes; cnt++) { - node[cnt].x = READ_LE_UINT16(fPolygrid); fPolygrid += 2; - node[cnt].y = READ_LE_UINT16(fPolygrid); fPolygrid += 2; + } while (j < _nNodes);//array starts at 0*/ + for (cnt = 1; cnt < _nNodes; cnt++) { + _node[cnt].x = READ_LE_UINT16(fPolygrid); fPolygrid += 2; + _node[cnt].y = READ_LE_UINT16(fPolygrid); fPolygrid += 2; } //ResUnlock(walkGridResourceId); // mouse wiggle @@ -2206,80 +1967,78 @@ int32 Router::LoadWalkResources(Object *megaObject, int32 x, int32 y, int32 dir) // copy the mega structure into the local variables for use in all subroutines - startX = megaObject->o_xcoord; - startY = megaObject->o_ycoord; - startDir = megaObject->o_dir; - targetX = x; - targetY= y; - targetDir = dir; + _startX = megaObject->o_xcoord; + _startY = megaObject->o_ycoord; + _startDir = megaObject->o_dir; + _targetX = x; + _targetY= y; + _targetDir = dir; - scaleA = megaObject->o_scale_a; - scaleB = megaObject->o_scale_b; + _scaleA = megaObject->o_scale_a; + _scaleB = megaObject->o_scale_b; //ResOpen(megaObject->o_mega_resource); // mouse wiggle //fMegaWalkData = ResLock(megaObject->o_mega_resource); // mouse wiggle fMegaWalkData = (uint8*)_resMan->openFetchRes(megaObject->o_mega_resource); - nWalkFrames = fMegaWalkData[0]; - nTurnFrames = fMegaWalkData[1]; - fMegaWalkData += 2; + _nWalkFrames = fMegaWalkData[0]; + _nTurnFrames = fMegaWalkData[1]; + fMegaWalkData += 2; - for (cnt = 0; cnt < NO_DIRECTIONS * (nWalkFrames + 1 + nTurnFrames); cnt++) { + for (cnt = 0; cnt < NO_DIRECTIONS * (_nWalkFrames + 1 + _nTurnFrames); cnt++) { _dx[cnt] = (int32)READ_LE_UINT32(fMegaWalkData); fMegaWalkData += 4; } - for (cnt = 0; cnt < NO_DIRECTIONS * (nWalkFrames + 1 + nTurnFrames); cnt++) { + for (cnt = 0; cnt < NO_DIRECTIONS * (_nWalkFrames + 1 + _nTurnFrames); cnt++) { _dy[cnt] = (int32)READ_LE_UINT32(fMegaWalkData); fMegaWalkData += 4; } - /*memmove(&_dx[0],fMegaWalkData,NO_DIRECTIONS*(nWalkFrames+1+nTurnFrames)*sizeof(int32)); - fMegaWalkData += NO_DIRECTIONS*(nWalkFrames+1+nTurnFrames)*sizeof(int32); - memmove(&_dy[0],fMegaWalkData,NO_DIRECTIONS*(nWalkFrames+1+nTurnFrames)*sizeof(int32)); - fMegaWalkData += NO_DIRECTIONS*(nWalkFrames+1+nTurnFrames)*sizeof(int32);*/ + /*memmove(&_dx[0],fMegaWalkData,NO_DIRECTIONS*(_nWalkFrames+1+_nTurnFrames)*sizeof(int32)); + fMegaWalkData += NO_DIRECTIONS*(_nWalkFrames+1+_nTurnFrames)*sizeof(int32); + memmove(&_dy[0],fMegaWalkData,NO_DIRECTIONS*(_nWalkFrames+1+_nTurnFrames)*sizeof(int32)); + fMegaWalkData += NO_DIRECTIONS*(_nWalkFrames+1+_nTurnFrames)*sizeof(int32);*/ for (cntu = 0; cntu < NO_DIRECTIONS; cntu++) { - modX[cntu] = (int32)READ_LE_UINT32(fMegaWalkData); + _modX[cntu] = (int32)READ_LE_UINT32(fMegaWalkData); fMegaWalkData += 4; } for (cntu = 0; cntu < NO_DIRECTIONS; cntu++) { - modY[cntu] = (int32)READ_LE_UINT32(fMegaWalkData); + _modY[cntu] = (int32)READ_LE_UINT32(fMegaWalkData); fMegaWalkData += 4; } - /*memmove(&modX[0],fMegaWalkData,NO_DIRECTIONS*sizeof(int32)); - fMegaWalkData += NO_DIRECTIONS*sizeof(int32); - memmove(&modY[0],fMegaWalkData,NO_DIRECTIONS*sizeof(int32)); - fMegaWalkData += NO_DIRECTIONS*sizeof(int32);*/ + /*memmove(&_modX[0],fMegaWalkData,NO_DIRECTIONS*sizeof(int32)); + fMegaWalkData += NO_DIRECTIONS*sizeof(int32); + memmove(&_modY[0],fMegaWalkData,NO_DIRECTIONS*sizeof(int32)); + fMegaWalkData += NO_DIRECTIONS*sizeof(int32);*/ //ResUnlock(megaObject->o_mega_resource); // mouse wiggle //ResClose(megaObject->o_mega_resource); // mouse wiggle _resMan->resClose(megaObject->o_mega_resource); - diagonalx = modX[3] ;//36 - diagonaly = modY[3] ;//8 + _diagonalx = _modX[3] ;//36 + _diagonaly = _modY[3] ;//8 // mega data ready -// finish setting grid by putting mega node at begining -// and target node at end and reset current values - node[0].x = startX; - node[0].y = startY; - node[0].level = 1; - node[0].prev = 0; - node[0].dist = 0; +// finish setting grid by putting mega _node at begining +// and target _node at end and reset current values + _node[0].x = _startX; + _node[0].y = _startY; + _node[0].level = 1; + _node[0].prev = 0; + _node[0].dist = 0; i=1; - do - { - node[i].level = 0; - node[i].prev = 0; - node[i].dist = 9999; + do { + _node[i].level = 0; + _node[i].prev = 0; + _node[i].dist = 9999; i=i+1; - } - while (i < nnodes); - node[nnodes].x = targetX; - node[nnodes].y = targetY; - node[nnodes].level = 0; - node[nnodes].prev = 0; - node[nnodes].dist = 9999; + } while (i < _nNodes); + _node[_nNodes].x = _targetX; + _node[_nNodes].y = _targetY; + _node[_nNodes].level = 0; + _node[_nNodes].prev = 0; + _node[_nNodes].dist = 9999; return 1; } @@ -2288,103 +2047,105 @@ int32 Router::LoadWalkResources(Object *megaObject, int32 x, int32 y, int32 dir) // * THE ROUTE EXTRACTOR // **************************************************************************** -void Router::ExtractRoute() -/**************************************************************************** - * ExtractRoute gets route from the node data after a full scan, route is - * written with just the basic way points and direction options for heading - * to the next point. - ****************************************************************************/ -{ - int32 prev; - int32 prevx; - int32 prevy; - int32 last; - int32 point; +void Router::extractRoute() { + /********************************************************************* + * extractRoute gets route from the node data after a full scan, route + * is written with just the basic way points and direction options for + * heading to the next point. + *********************************************************************/ + + int32 prev; + int32 prevx; + int32 prevy; + int32 last; + int32 point; + int32 dirx; + int32 diry; + int32 dir; + int32 ldx; + int32 ldy; int32 p; - int32 dirx; - int32 diry; - int32 dir; - int32 dx; - int32 dy; - - // extract the route from the node data - prev = nnodes; + // extract the route from the _node data + prev = _nNodes; last = prev; point = O_ROUTE_SIZE - 1; - route[point].x = node[last].x; - route[point].y = node[last].y; - do - { - point = point - 1; - prev = node[last].prev; - prevx = node[prev].x; - prevy = node[prev].y; - route[point].x = prevx; - route[point].y = prevy; + _route[point].x = _node[last].x; + _route[point].y = _node[last].y; + + do { + point--; + prev = _node[last].prev; + prevx = _node[prev].x; + prevy = _node[prev].y; + _route[point].x = prevx; + _route[point].y = prevy; last = prev; - } - while (prev > 0); + } while (prev > 0); // now shuffle route down in the buffer - routeLength = 0; - do - { - route[routeLength].x = route[point].x; - route[routeLength].y = route[point].y; - point = point + 1; - routeLength = routeLength + 1; - } - while (point < O_ROUTE_SIZE); - routeLength = routeLength - 1; + _routeLength = 0; + + do { + _route[_routeLength].x = _route[point].x; + _route[_routeLength].y = _route[point].y; + point++; + _routeLength++; + } while (point < O_ROUTE_SIZE); + + _routeLength--; // okay the route exists as a series point now put in some directions - p = 0; - do - { - dx = route[p+1].x - route[p].x; - dy = route[p+1].y - route[p].y; + for (p = 0; p < _routeLength; ++p) { + ldx = _route[p + 1].x - _route[p].x; + ldy = _route[p + 1].y - _route[p].y; dirx = 1; diry = 1; - if (dx < 0) - { - dx = -dx; + + if (ldx < 0) { + ldx = -ldx; dirx = -1; } - if (dy < 0) - { - dy = -dy; + + if (ldy < 0) { + ldy = -ldy; diry = -1; } - if ((diagonaly * dx) > (diagonalx * dy)) // dir = 1,2 or 2,3 or 5,6 or 6,7 - { - dir = 4 - 2 * dirx; // 2 or 6 - route[p].dirS = dir; - dir = dir + diry * dirx; // 1,3,5 or 7 - route[p].dirD = dir; - } - else // dir = 7,0 or 0,1 or 3,4 or 4,5 - { - dir = 2 + 2 * diry; // 0 or 4 - route[p].dirS = dir; - dir = 4 - 2 * dirx; // 2 or 6 - dir = dir + diry * dirx; // 1,3,5 or 7 - route[p].dirD = dir; + if (_diagonaly * ldx > _diagonalx * ldy) { + // dir = 1,2 or 2,3 or 5,6 or 6,7 + + // 2 or 6 + dir = 4 - 2 * dirx; + _route[p].dirS = dir; + + // 1, 3, 5 or 7 + dir = dir + diry * dirx; + _route[p].dirD = dir; + } else { + // dir = 7,0 or 0,1 or 3,4 or 4,5 + + // 0 or 4 + dir = 2 + 2 * diry; + _route[p].dirS = dir; + + // 2 or 6 + dir = 4 - 2 * dirx; + + // 1, 3, 5 or 7 + dir = dir + diry * dirx; + _route[p].dirD = dir; } - p = p + 1; } - while (p < (routeLength)); + // set the last dir to continue previous route unless specified - if (targetDir == NO_DIRECTIONS) - { - route[p].dirS = route[p-1].dirS; - route[p].dirD = route[p-1].dirD; - } - else - { - route[p].dirS = targetDir; - route[p].dirD = targetDir; + if (_targetDir == NO_DIRECTIONS) { + // ANY direction + _route[p].dirS = _route[p - 1].dirS; + _route[p].dirD = _route[p - 1].dirD; + } else { + _route[p].dirS = _targetDir; + _route[p].dirD = _targetDir; } return; } diff --git a/engines/sword1/router.h b/engines/sword1/router.h index ca660d1b8f..b20a70a481 100644 --- a/engines/sword1/router.h +++ b/engines/sword1/router.h @@ -20,40 +20,37 @@ * */ -#ifndef BSROUTER_H -#define BSROUTER_H +#ifndef SWORD1_ROUTER_H +#define SWORD1_ROUTER_H -#include "common/scummsys.h" #include "sword1/object.h" namespace Sword1 { -#define O_GRID_SIZE 200 - #if !defined(__GNUC__) #pragma START_PACK_STRUCTS #endif struct BarData { - int16 x1; - int16 y1; - int16 x2; - int16 y2; - int16 xmin; - int16 ymin; - int16 xmax; - int16 ymax; - int16 dx; // x2 - x1 - int16 dy; // y2 - y1 - int32 co; // co = (y1 *dx)- (x1*dy) from an equation for a line y*dx = x*dy + co + int16 x1; + int16 y1; + int16 x2; + int16 y2; + int16 xmin; + int16 ymin; + int16 xmax; + int16 ymax; + int16 dx; // x2 - x1 + int16 dy; // y2 - y1 + int32 co; // co = (y1*dx) - (x1*dy) from an equation for a line y*dx = x*dy + co } GCC_PACK; struct NodeData { - int16 x; - int16 y; - int16 level; - int16 prev; - int16 dist; + int16 x; + int16 y; + int16 level; + int16 prev; + int16 dist; } GCC_PACK; #if !defined(__GNUC__) @@ -68,23 +65,25 @@ struct FloorData { }; struct RouteData { - int32 x; - int32 y; - int32 dirS; - int32 dirD; + int32 x; + int32 y; + int32 dirS; + int32 dirD; }; struct PathData { - int32 x; - int32 y; - int32 dir; - int32 num; + int32 x; + int32 y; + int32 dir; + int32 num; }; -#define ROUTE_END_FLAG 255 -#define NO_DIRECTIONS 8 #define MAX_FRAMES_PER_CYCLE 16 +#define NO_DIRECTIONS 8 #define MAX_FRAMES_PER_CHAR (MAX_FRAMES_PER_CYCLE * NO_DIRECTIONS) +#define ROUTE_END_FLAG 255 + +#define O_GRID_SIZE 200 #define O_ROUTE_SIZE 50 class ObjectMan; @@ -100,9 +99,12 @@ public: void setPlayerTarget(int32 x, int32 y, int32 dir, int32 stance); // these should be private but are read by Screen for debugging: - BarData bars[O_GRID_SIZE]; - NodeData node[O_GRID_SIZE]; - int32 nbars, nnodes; + BarData _bars[O_GRID_SIZE]; + NodeData _node[O_GRID_SIZE]; + + int32 _nBars; + int32 _nNodes; + private: // when the player collides with another mega, we'll receive a ReRouteRequest here. // that's why we need to remember the player's target coordinates @@ -111,61 +113,55 @@ private: ObjectMan *_objMan; ResMan *_resMan; - /*uint8 _nWalkFrames, _nTurnFrames; - int32 _dx[NO_DIRECTIONS + MAX_FRAMES_PER_CHAR]; - int32 _dy[NO_DIRECTIONS + MAX_FRAMES_PER_CHAR]; - int32 _modX[NO_DIRECTIONS]; - int32 _modY[NO_DIRECTIONS]; - int32 _diagonalx, _diagonaly;*/ + int32 _startX, _startY, _startDir; + int32 _targetX, _targetY, _targetDir; + int32 _scaleA, _scaleB; - int32 startX, startY, startDir; - int32 targetX, targetY, targetDir; - int32 scaleA, scaleB; int32 megaId; /*RouteData _route[O_ROUTE_SIZE]; //int32 _routeLength; PathData _smoothPath[O_ROUTE_SIZE]; PathData _modularPath[O_ROUTE_SIZE];*/ - RouteData route[O_ROUTE_SIZE]; - PathData smoothPath[O_ROUTE_SIZE]; - PathData modularPath[O_ROUTE_SIZE]; - int32 routeLength; + RouteData _route[O_ROUTE_SIZE]; + PathData _smoothPath[O_ROUTE_SIZE]; + PathData _modularPath[O_ROUTE_SIZE]; + int32 _routeLength; - int32 framesPerStep, framesPerChar; - uint8 nWalkFrames, nTurnFrames; + int32 _framesPerStep, _framesPerChar; + uint8 _nWalkFrames, _nTurnFrames; int32 _dx[NO_DIRECTIONS + MAX_FRAMES_PER_CHAR]; int32 _dy[NO_DIRECTIONS + MAX_FRAMES_PER_CHAR]; - int32 modX[NO_DIRECTIONS]; - int32 modY[NO_DIRECTIONS]; - int32 diagonalx, diagonaly; + int32 _modX[NO_DIRECTIONS]; + int32 _modY[NO_DIRECTIONS]; + int32 _diagonalx, _diagonaly; int32 standFrames; int32 turnFramesLeft, turnFramesRight; int32 walkFramesLeft, walkFramesRight; // left/right walking turn int32 slowInFrames, slowOutFrames; - int32 LoadWalkResources(Object *mega, int32 x, int32 y, int32 targetDir); - int32 GetRoute(void); - int32 CheckTarget(int32 x, int32 y); + int32 LoadWalkResources(Object *mega, int32 x, int32 y, int32 dir); + int32 getRoute(void); + int32 checkTarget(int32 x, int32 y); - int32 Scan(int32 level); - int32 NewCheck(int32 status, int32 x1, int32 x2, int32 y1, int32 y2); - int32 Check(int32 x1, int32 y1, int32 x2, int32 y2); - int32 HorizCheck(int32 x1, int32 y, int32 x2); - int32 VertCheck(int32 x, int32 y1, int32 y2); - int32 LineCheck(int32 x1, int32 y1, int32 x2, int32 y2); + bool scan(int32 level); + int32 newCheck(int32 status, int32 x1, int32 x2, int32 y1, int32 y2); + bool check(int32 x1, int32 y1, int32 x2, int32 y2); + bool horizCheck(int32 x1, int32 y, int32 x2); + bool vertCheck(int32 x, int32 y1, int32 y2); + bool lineCheck(int32 x1, int32 y1, int32 x2, int32 y2); - void ExtractRoute(); + void extractRoute(); - int32 SlidyPath(); - void SlidyWalkAnimator(WalkData *walkAnim); + void slidyPath(); + void slidyWalkAnimator(WalkData *walkAnim); - int32 SmoothestPath(); - int32 SmoothCheck(int32 best, int32 p, int32 dirS, int32 dirD); + int32 smoothestPath(); + int32 smoothCheck(int32 best, int32 p, int32 dirS, int32 dirD); - int32 SolidPath(); - int32 SolidWalkAnimator(WalkData *walkAnim); + void solidPath(); + int32 solidWalkAnimator(WalkData *walkAnim); }; } // End of namespace Sword1 diff --git a/engines/sword2/router.cpp b/engines/sword2/router.cpp index 3976bdb179..e26f736a5f 100644 --- a/engines/sword2/router.cpp +++ b/engines/sword2/router.cpp @@ -19,6 +19,19 @@ * $Id$ */ +#include "common/stdafx.h" +#include "common/stream.h" + +#include "sword2/sword2.h" +#include "sword2/defs.h" +#include "sword2/header.h" +#include "sword2/logic.h" +#include "sword2/resman.h" +#include "sword2/router.h" +#include "sword2/screen.h" + +namespace Sword2 { + // --------------------------------------------------------------------------- // ROUTER.CPP by James // @@ -75,19 +88,6 @@ * ****************************************************************************/ -#include "common/stdafx.h" -#include "common/stream.h" - -#include "sword2/sword2.h" -#include "sword2/defs.h" -#include "sword2/header.h" -#include "sword2/logic.h" -#include "sword2/resman.h" -#include "sword2/router.h" -#include "sword2/screen.h" - -namespace Sword2 { - //---------------------------------------------------------- // (4) WALK-GRID FILES //---------------------------------------------------------- @@ -220,18 +220,18 @@ int32 Router::routeFinder(byte *ob_mega, byte *ob_walkdata, int32 x, int32 y, in // modularPath is normally set by extractRoute _modularPath[0].dir = _startDir; - _modularPath[0].num = 0; - _modularPath[0].x = _startX; - _modularPath[0].y = _startY; + _modularPath[0].num = 0; + _modularPath[0].x = _startX; + _modularPath[0].y = _startY; _modularPath[1].dir = _targetDir; - _modularPath[1].num = 0; - _modularPath[1].x = _startX; - _modularPath[1].y = _startY; - _modularPath[2].dir = 9; - _modularPath[2].num = ROUTE_END_FLAG; + _modularPath[1].num = 0; + _modularPath[1].x = _startX; + _modularPath[1].y = _startY; + _modularPath[2].dir = 9; + _modularPath[2].num = ROUTE_END_FLAG; slidyWalkAnimator(walkAnim); - routeFlag = 2; + routeFlag = 2; break; case 1: // A normal route. Convert the route to an exact path @@ -369,7 +369,7 @@ int32 Router::smoothestPath() { int32 lastDir; int32 tempturns[4]; int32 turns[4]; - int32 turntable[NO_DIRECTIONS] = { 0, 1, 3, 5, 7, 5, 3, 1 }; + const int32 turntable[NO_DIRECTIONS] = { 0, 1, 3, 5, 7, 5, 3, 1 }; // route.X route.Y and route.Dir start at far end @@ -414,9 +414,7 @@ int32 Router::smoothestPath() { if (dDS < 0) dDS = dDS + NO_DIRECTIONS; - // Determine the amount of turning involved in each possible - // path - + // Determine the amount of turning involved in each possible path dS = turntable[dS]; dD = turntable[dD]; dSS = turntable[dSS]; @@ -424,17 +422,13 @@ int32 Router::smoothestPath() { dSD = turntable[dSD]; dDS = turntable[dDS]; - // get the best path out ie assume next section uses best - // direction - + // get the best path out ie assume next section uses best direction if (dSD < dSS) dSS = dSD; - if (dDS < dDD) dDD = dDS; - // Rate each option. Split routes look crap so weight against - // them + // Rate each option. Split routes look crap so weight against them tempturns[0] = dS + dSS + 3; turns[0] = 0; tempturns[1] = dS + dDD; @@ -445,7 +439,6 @@ int32 Router::smoothestPath() { turns[3] = 3; // set up turns as a sorted array of the turn values - for (i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (tempturns[j] > tempturns[j + 1]) { @@ -495,6 +488,8 @@ int32 Router::smoothCheck(int32 best, int32 p, int32 dirS, int32 dirD) { * No longer checks the data it only creates the smoothPath array JPS *********************************************************************/ + // FIXME: Using 'static' vars in a method is evil -- they should almost + // always be turned into member variables instead. static int32 k; int32 dsx, dsy; int32 ddx, ddy; @@ -687,7 +682,6 @@ void Router::slidyPath() { _modularPath[slidy].y = _smoothPath[smooth - 1].y; _modularPath[slidy].dir = 9; _modularPath[slidy].num = ROUTE_END_FLAG; - slidy++; } // SLOW IN @@ -727,7 +721,7 @@ void Router::earlySlowOut(byte *ob_mega, byte *ob_walkdata) { debug(5, "_firstSlowOutFrame = %d", _firstSlowOutFrame); debug(5, "********************************"); - walk_pc = obMega.getWalkPc(); + walk_pc = obMega.getWalkPc(); walkAnim = getRouteMem(); @@ -805,7 +799,7 @@ void Router::addSlowOutFrames(WalkData *walkAnim) { // if the mega did actually walk, we overwrite the last step (half a // cycle) with slow-out frames + add any necessary stationary frames - if (_walkData.usingSlowOutFrames && _lastCount >= _framesPerStep) { + if (_walkData.usingSlowOutFrames && _lastCount >= _framesPerStep) { // place stop frames here // slowdown at the end of the last walk @@ -857,6 +851,8 @@ void Router::slidyWalkAnimator(WalkData *walkAnim) { * produce a module list from the line data *********************************************************************/ + // FIXME: Using 'static' vars in a method is evil -- they should almost + // always be turned into member variables instead. static int32 left = 0; int32 p; int32 lastDir; @@ -1069,9 +1065,9 @@ void Router::slidyWalkAnimator(WalkData *walkAnim) { // closest _stepCount -= _framesPerStep; if (left == 0) - left = _framesPerStep; + left = _framesPerStep; else - left = 0; + left = 0; } } else { if (3 * ABS(lastErrorX) < ABS(errorX)) { @@ -1079,9 +1075,9 @@ void Router::slidyWalkAnimator(WalkData *walkAnim) { // closest _stepCount -= _framesPerStep; if (left == 0) - left = _framesPerStep; + left = _framesPerStep; else - left = 0; + left = 0; } } } @@ -1294,7 +1290,7 @@ void Router::slidyWalkAnimator(WalkData *walkAnim) { // THE SOLID PATH ROUTINES -int32 Router::solidPath() { +void Router::solidPath() { /********************************************************************* * SolidPath creates a path based on whole steps with no sliding to * get as near as possible to the target without any sliding this @@ -1335,7 +1331,7 @@ int32 Router::solidPath() { if (ABS(deltaX) >= ABS(stepX) && ABS(deltaY) >= ABS(stepY)) { _modularPath[solid].x = _smoothPath[smooth].x; _modularPath[solid].y = _smoothPath[smooth].y; - _modularPath[solid].dir = _smoothPath[smooth].dir; + _modularPath[solid].dir = _smoothPath[smooth].dir; _modularPath[solid].num = 1; solid++; } @@ -1360,8 +1356,6 @@ int32 Router::solidPath() { _modularPath[solid].y = _smoothPath[smooth - 1].y; _modularPath[solid].dir = 9; _modularPath[solid].num = ROUTE_END_FLAG; - - return 1; } int32 Router::solidWalkAnimator(WalkData *walkAnim) { @@ -1504,9 +1498,9 @@ int32 Router::solidWalkAnimator(WalkData *walkAnim) { // this ensures that we don't put in turn frames for the start _currentDir = 99; - int32 p = 1; + int32 p; - do { + for (p = 1; _modularPath[p].dir < NO_DIRECTIONS; ++p) { while (_modularPath[p].num > 0) { _currentDir = _modularPath[p].dir; if (_currentDir < NO_DIRECTIONS) { @@ -1618,12 +1612,11 @@ int32 Router::solidWalkAnimator(WalkData *walkAnim) { } } } - p++; lastDir = _currentDir; // can only be valid first time round slowStart = false; - } while (_modularPath[p].dir < NO_DIRECTIONS); + } // THE SLOW OUT @@ -1658,13 +1651,10 @@ int32 Router::solidWalkAnimator(WalkData *walkAnim) { debug(5, "routeFinder RouteSize is %d", _stepCount); // now check the route - int i = 0; - - do { + for (int i = 0; i < p - 1; ++i) { if (!check(_modularPath[i].x, _modularPath[i].y, _modularPath[i + 1].x, _modularPath[i + 1].y)) p = 0; - i++; - } while (i < p - 1); + } if (p != 0) { _targetDir = _modularPath[p - 1].dir; @@ -1698,7 +1688,7 @@ bool Router::scan(int32 level) { int32 distance; bool changed = false; - // For all the nodes that have new values and a distance less than + // For all the nodes that have new values and a distance less than // enddist, ie dont check for new routes from a point we checked // before or from a point that is already further away than the best // route so far. @@ -1789,8 +1779,7 @@ int32 Router::newCheck(int32 status, int32 x1, int32 y1, int32 x2, int32 y2) { ldx = ldx * dirX; ldy = 0; - // options are square, diagonal a code 1 route - + // options are square, diagonal a code 1 route step1 = check(x1, y1, x1 + ldx, y1); if (step1 != 0) { step2 = check(x1 + ldx, y1, x2, y2); @@ -1801,7 +1790,6 @@ int32 Router::newCheck(int32 status, int32 x1, int32 y1, int32 x2, int32 y2) { } // diagonal, square a code 2 route - if (steps == 0 || status == 1) { step1 = check(x1, y1, x1 + dlx, y1 + dly); if (step1 != 0) { @@ -1814,7 +1802,6 @@ int32 Router::newCheck(int32 status, int32 x1, int32 y1, int32 x2, int32 y2) { } // halfsquare, diagonal, halfsquare a code 0 route - if (steps == 0 || status == 1) { step1 = check(x1, y1, x1 + ldx / 2, y1); if (step1 != 0) { @@ -1829,8 +1816,7 @@ int32 Router::newCheck(int32 status, int32 x1, int32 y1, int32 x2, int32 y2) { } } - //halfdiagonal, square, halfdiagonal a code 3 route - + // halfdiagonal, square, halfdiagonal a code 3 route if (steps == 0 || status == 1) { step1 = check(x1, y1, x1 + dlx / 2, y1 + dly / 2); if (step1 != 0) { @@ -1855,8 +1841,7 @@ int32 Router::newCheck(int32 status, int32 x1, int32 y1, int32 x2, int32 y2) { ldy = ldy * dirY; ldx = 0; - // options are square, diagonal a code 1 route - + // options are square, diagonal a code 1 route step1 = check(x1 ,y1, x1, y1 + ldy); if (step1 != 0) { step2 = check(x1, y1 + ldy, x2, y2); @@ -1867,7 +1852,6 @@ int32 Router::newCheck(int32 status, int32 x1, int32 y1, int32 x2, int32 y2) { } // diagonal, square a code 2 route - if (steps == 0 || status == 1) { step1 = check(x1, y1, x2, y1 + dly); if (step1 != 0) { @@ -1880,7 +1864,6 @@ int32 Router::newCheck(int32 status, int32 x1, int32 y1, int32 x2, int32 y2) { } // halfsquare, diagonal, halfsquare a code 0 route - if (steps == 0 || status == 1) { step1 = check(x1, y1, x1, y1 + ldy / 2); if (step1 != 0) { @@ -1896,7 +1879,6 @@ int32 Router::newCheck(int32 status, int32 x1, int32 y1, int32 x2, int32 y2) { } // halfdiagonal, square, halfdiagonal a code 3 route - if (steps == 0 || status == 1) { step1 = check(x1, y1, x1 + dlx / 2, y1 + dly / 2); if (step1 != 0) { @@ -2069,8 +2051,7 @@ int32 Router::checkTarget(int32 x, int32 y) { if (xmax >= _bars[i].xmin && xmin <= _bars[i].xmax && ymax >= _bars[i].ymin && ymin <= _bars[i].ymax) { int32 xc, yc; - // okay this line overlaps the target calculate - // an y intercept for x + // okay this line overlaps the target calculate an y intercept for x // vertical line so we know it overlaps y if (_bars[i].dx == 0) @@ -2227,14 +2208,14 @@ void Router::extractRoute() { int32 prevy; int32 last; int32 point; - int32 p; int32 dirx; int32 diry; int32 dir; int32 ldx; int32 ldy; + int32 p; - // extract the route from the node data + // extract the route from the node data prev = _nNodes; last = prev; @@ -2253,7 +2234,6 @@ void Router::extractRoute() { } while (prev > 0); // now shuffle route down in the buffer - _routeLength = 0; do { @@ -2266,10 +2246,7 @@ void Router::extractRoute() { _routeLength--; // okay the route exists as a series point now put in some directions - - p = 0; - - do { + for (p = 0; p < _routeLength; ++p) { ldx = _route[p + 1].x - _route[p].x; ldy = _route[p + 1].y - _route[p].y; dirx = 1; @@ -2309,12 +2286,10 @@ void Router::extractRoute() { dir = dir + diry * dirx; _route[p].dirD = dir; } - p++; - } while (p < _routeLength); + } // set the last dir to continue previous route unless specified - - if (_targetDir == 8) { + if (_targetDir == NO_DIRECTIONS) { // ANY direction _route[p].dirS = _route[p - 1].dirS; _route[p].dirD = _route[p - 1].dirD; diff --git a/engines/sword2/router.h b/engines/sword2/router.h index 3b2fabf3fd..f2f87403c7 100644 --- a/engines/sword2/router.h +++ b/engines/sword2/router.h @@ -53,8 +53,7 @@ struct BarData { int16 ymax; int16 dx; // x2 - x1 int16 dy; // y2 - y1 - int32 co; // co = (y1 * dx) - (x1 * dy) from an equation for a - // line y * dx = x * dy + co + int32 co; // co = (y1*dx) - (x1*dy) from an equation for a line y*dx = x*dy + co }; struct NodeData { @@ -113,14 +112,9 @@ private: int32 _nBars; int32 _nNodes; - int32 _startX; - int32 _startY; - int32 _startDir; - int32 _targetX; - int32 _targetY; - int32 _targetDir; - int32 _scaleA; - int32 _scaleB; + int32 _startX, _startY, _startDir; + int32 _targetX, _targetY, _targetDir; + int32 _scaleA, _scaleB; RouteData _route[O_ROUTE_SIZE]; PathData _smoothPath[O_ROUTE_SIZE]; @@ -189,7 +183,7 @@ private: void slidyWalkAnimator(WalkData *walkAnim); #ifndef FORCE_SLIDY - int32 solidPath(); + void solidPath(); int32 solidWalkAnimator(WalkData *walkAnim); #endif -- cgit v1.2.3