mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-28 04:34:50 +00:00
Cleaned up the walking code.
PathVertex replaced by Common::Point. Do not update the path sprites if not in the debugging mode. svn-id: r45598
This commit is contained in:
parent
c1cc230e4b
commit
170918afab
@ -961,11 +961,12 @@ void Game::walkHero(int x, int y, SightDirection dir) {
|
|||||||
|
|
||||||
// Compute the shortest and obliqued path.
|
// Compute the shortest and obliqued path.
|
||||||
WalkingMap::Path shortestPath, obliquePath;
|
WalkingMap::Path shortestPath, obliquePath;
|
||||||
_walkingMap.findShortestPath(oldHero.x, oldHero.y, _hero.x, _hero.y, &shortestPath);
|
_walkingMap.findShortestPath(oldHero, _hero, &shortestPath);
|
||||||
_walkingMap.obliquePath(shortestPath, &obliquePath);
|
_walkingMap.obliquePath(shortestPath, &obliquePath);
|
||||||
|
if (_vm->_showWalkingMap) {
|
||||||
redrawWalkingPath(kWalkingShortestPathOverlay, kWalkingShortestPathOverlayColour, shortestPath);
|
redrawWalkingPath(kWalkingShortestPathOverlay, kWalkingShortestPathOverlayColour, shortestPath);
|
||||||
redrawWalkingPath(kWalkingObliquePathOverlay, kWalkingObliquePathOverlayColour, obliquePath);
|
redrawWalkingPath(kWalkingObliquePathOverlay, kWalkingObliquePathOverlayColour, obliquePath);
|
||||||
|
}
|
||||||
|
|
||||||
Movement movement = kStopRight;
|
Movement movement = kStopRight;
|
||||||
switch (dir) {
|
switch (dir) {
|
||||||
|
@ -182,33 +182,34 @@ Common::Point WalkingMap::findNearestWalkable(int startX, int startY, Common::Re
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We don't use Common::Point due to using static initialization.
|
||||||
int WalkingMap::kDirections[][2] = { {0, -1}, {0, +1}, {-1, 0}, {+1, 0} };
|
int WalkingMap::kDirections[][2] = { {0, -1}, {0, +1}, {-1, 0}, {+1, 0} };
|
||||||
|
|
||||||
bool WalkingMap::findShortestPath(int x1, int y1, int x2, int y2, WalkingMap::Path *path) const {
|
bool WalkingMap::findShortestPath(Common::Point p1, Common::Point p2, Path *path) const {
|
||||||
// Round the positions to map squares.
|
// Round the positions to map squares.
|
||||||
x1 /= _deltaX;
|
p1.x /= _deltaX;
|
||||||
x2 /= _deltaX;
|
p2.x /= _deltaX;
|
||||||
y1 /= _deltaY;
|
p1.y /= _deltaY;
|
||||||
y2 /= _deltaY;
|
p2.y /= _deltaY;
|
||||||
|
|
||||||
// Allocate buffers for breadth-first search. The buffer of points for
|
// Allocate buffers for breadth-first search. The buffer of points for
|
||||||
// exploration should be large enough.
|
// exploration should be large enough.
|
||||||
int8 *cameFrom = new int8[_mapWidth * _mapHeight];
|
int8 *cameFrom = new int8[_mapWidth * _mapHeight];
|
||||||
const int bufSize = 4 * _realHeight;
|
const int bufSize = 4 * _realHeight;
|
||||||
PathVertex *toSearch = new PathVertex[bufSize];
|
Common::Point *toSearch = new Common::Point[bufSize];
|
||||||
|
|
||||||
// Insert the starting point as a single seed.
|
// Insert the starting point as a single seed.
|
||||||
int toRead = 0, toWrite = 0;
|
int toRead = 0, toWrite = 0;
|
||||||
memset(cameFrom, -1, _mapWidth * _mapHeight); // -1 = not found yet
|
memset(cameFrom, -1, _mapWidth * _mapHeight); // -1 = not found yet
|
||||||
cameFrom[y1 * _mapWidth + x1] = 0;
|
cameFrom[p1.y * _mapWidth + p1.x] = 0;
|
||||||
toSearch[toWrite++] = PathVertex(x1, y1);
|
toSearch[toWrite++] = p1;
|
||||||
|
|
||||||
// Search until we empty the whole buffer (not found) or find the
|
// Search until we empty the whole buffer (not found) or find the
|
||||||
// destination point.
|
// destination point.
|
||||||
while (toRead != toWrite) {
|
while (toRead != toWrite) {
|
||||||
const PathVertex &here = toSearch[toRead];
|
const Common::Point &here = toSearch[toRead];
|
||||||
const int from = cameFrom[here.y * _mapWidth + here.x];
|
const int from = cameFrom[here.y * _mapWidth + here.x];
|
||||||
if (here.x == x2 && here.y == y2) {
|
if (here == p2) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Look into all 4 directions in a particular order depending
|
// Look into all 4 directions in a particular order depending
|
||||||
@ -217,17 +218,16 @@ bool WalkingMap::findShortestPath(int x1, int y1, int x2, int y2, WalkingMap::Pa
|
|||||||
// with the smallest number of turns is preferred.
|
// with the smallest number of turns is preferred.
|
||||||
for (int addDir = 0; addDir < 4; ++addDir) {
|
for (int addDir = 0; addDir < 4; ++addDir) {
|
||||||
const int probeDirection = (from + addDir) % 4;
|
const int probeDirection = (from + addDir) % 4;
|
||||||
const int x = here.x + kDirections[probeDirection][0];
|
const Common::Point p(here.x + kDirections[probeDirection][0], here.y + kDirections[probeDirection][1]);
|
||||||
const int y = here.y + kDirections[probeDirection][1];
|
if (p.x < 0 || p.x >= _mapWidth || p.y < 0 || p.y >= _mapHeight) {
|
||||||
if (x < 0 || x >= _mapWidth || y < 0 || y >= _mapHeight) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// If this point is walkable and we haven't seen it
|
// If this point is walkable and we haven't seen it
|
||||||
// yet, record how we have reached it and insert it
|
// yet, record how we have reached it and insert it
|
||||||
// into the round buffer for exploration.
|
// into the round buffer for exploration.
|
||||||
if (getPixel(x, y) && cameFrom[y * _mapWidth + x] == -1) {
|
if (getPixel(p.x, p.y) && cameFrom[p.y * _mapWidth + p.x] == -1) {
|
||||||
cameFrom[y * _mapWidth + x] = probeDirection;
|
cameFrom[p.y * _mapWidth + p.x] = probeDirection;
|
||||||
toSearch[toWrite++] = PathVertex(x, y);
|
toSearch[toWrite++] = p;
|
||||||
toWrite %= bufSize;
|
toWrite %= bufSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -245,19 +245,19 @@ bool WalkingMap::findShortestPath(int x1, int y1, int x2, int y2, WalkingMap::Pa
|
|||||||
path->clear();
|
path->clear();
|
||||||
int length = 0;
|
int length = 0;
|
||||||
for (int pass = 0; pass < 2; ++pass) {
|
for (int pass = 0; pass < 2; ++pass) {
|
||||||
int x = x2, y = y2;
|
Common::Point p = p2;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
++index;
|
++index;
|
||||||
if (pass == 1) {
|
if (pass == 1) {
|
||||||
(*path)[length - index] = PathVertex(x, y);
|
(*path)[length - index] = p;
|
||||||
}
|
}
|
||||||
if (x == x1 && y == y1) {
|
if (p == p1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
const int from = cameFrom[y * _mapWidth + x];
|
const int from = cameFrom[p.y * _mapWidth + p.x];
|
||||||
x -= kDirections[from][0];
|
p.x -= kDirections[from][0];
|
||||||
y -= kDirections[from][1];
|
p.y -= kDirections[from][1];
|
||||||
}
|
}
|
||||||
if (pass == 0) {
|
if (pass == 0) {
|
||||||
length = index;
|
length = index;
|
||||||
@ -312,8 +312,8 @@ void WalkingMap::obliquePath(const WalkingMap::Path& path, WalkingMap::Path *obl
|
|||||||
// first edge (going from the 1st vertex to the 2nd one) as is, move
|
// first edge (going from the 1st vertex to the 2nd one) as is, move
|
||||||
// the index to the 2nd vertex, and continue.
|
// the index to the 2nd vertex, and continue.
|
||||||
for (uint head = 2; head < obliquedPath->size(); ++head) {
|
for (uint head = 2; head < obliquedPath->size(); ++head) {
|
||||||
const PathVertex &v1 = (*obliquedPath)[head-2];
|
const Common::Point &v1 = (*obliquedPath)[head-2];
|
||||||
const PathVertex &v3 = (*obliquedPath)[head];
|
const Common::Point &v3 = (*obliquedPath)[head];
|
||||||
const int steps = MAX(abs(v3.x - v1.x), abs(v3.y - v1.y));
|
const int steps = MAX(abs(v3.x - v1.x), abs(v3.y - v1.y));
|
||||||
bool allPointsOk = true;
|
bool allPointsOk = true;
|
||||||
// Testing only points between (i.e., without the end-points) is OK.
|
// Testing only points between (i.e., without the end-points) is OK.
|
||||||
@ -337,8 +337,8 @@ Sprite *WalkingMap::newOverlayFromPath(const WalkingMap::Path &path, byte colour
|
|||||||
memset(wlk, 255, _realWidth * _realHeight);
|
memset(wlk, 255, _realWidth * _realHeight);
|
||||||
|
|
||||||
for (uint segment = 1; segment < path.size(); ++segment) {
|
for (uint segment = 1; segment < path.size(); ++segment) {
|
||||||
const PathVertex &v1 = path[segment-1];
|
const Common::Point &v1 = path[segment-1];
|
||||||
const PathVertex &v2 = path[segment];
|
const Common::Point &v2 = path[segment];
|
||||||
const int steps = MAX(abs(v2.x - v1.x), abs(v2.y - v1.y));
|
const int steps = MAX(abs(v2.x - v1.x), abs(v2.y - v1.y));
|
||||||
// Draw only points in the interval [v1, v2). These half-open
|
// Draw only points in the interval [v1, v2). These half-open
|
||||||
// half-closed intervals connect all the way to the last point.
|
// half-closed intervals connect all the way to the last point.
|
||||||
@ -351,7 +351,7 @@ Sprite *WalkingMap::newOverlayFromPath(const WalkingMap::Path &path, byte colour
|
|||||||
// Draw the last point. This works also when the path has no segment,
|
// Draw the last point. This works also when the path has no segment,
|
||||||
// but just one point.
|
// but just one point.
|
||||||
if (path.size() > 0) {
|
if (path.size() > 0) {
|
||||||
const PathVertex &vLast = path[path.size()-1];
|
const Common::Point &vLast = path[path.size()-1];
|
||||||
drawOverlayRectangle(vLast.x, vLast.y, colour, wlk);
|
drawOverlayRectangle(vLast.x, vLast.y, colour, wlk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,12 +33,6 @@ namespace Draci {
|
|||||||
|
|
||||||
class Sprite;
|
class Sprite;
|
||||||
|
|
||||||
struct PathVertex {
|
|
||||||
PathVertex() {}
|
|
||||||
PathVertex(int xx, int yy) : x(xx), y(yy) {}
|
|
||||||
int x, y;
|
|
||||||
};
|
|
||||||
|
|
||||||
class WalkingMap {
|
class WalkingMap {
|
||||||
public:
|
public:
|
||||||
WalkingMap() : _realWidth(0), _realHeight(0), _deltaX(1), _deltaY(1),
|
WalkingMap() : _realWidth(0), _realHeight(0), _deltaX(1), _deltaY(1),
|
||||||
@ -52,8 +46,8 @@ public:
|
|||||||
Sprite *newOverlayFromMap(byte colour) const;
|
Sprite *newOverlayFromMap(byte colour) const;
|
||||||
Common::Point findNearestWalkable(int x, int y, Common::Rect searchRect) const;
|
Common::Point findNearestWalkable(int x, int y, Common::Rect searchRect) const;
|
||||||
|
|
||||||
typedef Common::Array<PathVertex> Path;
|
typedef Common::Array<Common::Point> Path;
|
||||||
bool findShortestPath(int x1, int y1, int x2, int y2, Path *path) const;
|
bool findShortestPath(Common::Point p1, Common::Point p2, Path *path) const;
|
||||||
void obliquePath(const Path& path, Path *obliquedPath) const;
|
void obliquePath(const Path& path, Path *obliquedPath) const;
|
||||||
Sprite *newOverlayFromPath(const Path &path, byte colour) const;
|
Sprite *newOverlayFromPath(const Path &path, byte colour) const;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user