- Fixed the pathfinding issue for LSL5 room 640, where Patti walks off-screen (we still need a proper way of detecting this, though...)
- Made warnings where invalid pointers are dereferenced more precise svn-id: r45257
This commit is contained in:
parent
c0f6657797
commit
a88aa2f45f
3 changed files with 23 additions and 18 deletions
|
@ -261,7 +261,7 @@ struct PathfindingState {
|
||||||
static Common::Point read_point(SegManager *segMan, reg_t list, int offset) {
|
static Common::Point read_point(SegManager *segMan, reg_t list, int offset) {
|
||||||
SegmentRef list_r = segMan->dereference(list);
|
SegmentRef list_r = segMan->dereference(list);
|
||||||
if (!list_r.isValid()) {
|
if (!list_r.isValid()) {
|
||||||
warning("Attempt to dereference invalid pointer %04x:%04x", PRINT_REG(list));
|
warning("read_point(): Attempt to dereference invalid pointer %04x:%04x", PRINT_REG(list));
|
||||||
}
|
}
|
||||||
Common::Point point;
|
Common::Point point;
|
||||||
|
|
||||||
|
@ -854,7 +854,6 @@ static VertexList *visible_vertices(PathfindingState *s, Vertex *vertex_cur) {
|
||||||
return visVerts;
|
return visVerts;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
static bool point_on_screen_border(const Common::Point &p) {
|
static bool point_on_screen_border(const Common::Point &p) {
|
||||||
// Determines if a point lies on the screen border
|
// Determines if a point lies on the screen border
|
||||||
// Parameters: (const Common::Point &) p: The point
|
// Parameters: (const Common::Point &) p: The point
|
||||||
|
@ -862,7 +861,6 @@ static bool point_on_screen_border(const Common::Point &p) {
|
||||||
// FIXME get dimensions from somewhere?
|
// FIXME get dimensions from somewhere?
|
||||||
return (p.x == 0) || (p.x == 319) || (p.y == 0) || (p.y == 189);
|
return (p.x == 0) || (p.x == 319) || (p.y == 0) || (p.y == 189);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static bool edge_on_screen_border(const Common::Point &p, const Common::Point &q) {
|
static bool edge_on_screen_border(const Common::Point &p, const Common::Point &q) {
|
||||||
// Determines if an edge lies on the screen border
|
// Determines if an edge lies on the screen border
|
||||||
|
@ -1498,7 +1496,7 @@ static int intersecting_polygons(PathfindingState *s) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dijkstra(PathfindingState *s) {
|
static void dijkstra(PathfindingState *s, bool avoidScreenEdge) {
|
||||||
// Computes a shortest path from vertex_start to vertex_end. The caller can
|
// Computes a shortest path from vertex_start to vertex_end. The caller can
|
||||||
// construct the resulting path by following the path_prev links from
|
// construct the resulting path by following the path_prev links from
|
||||||
// vertex_end back to vertex_start. If no path exists vertex_end->path_prev
|
// vertex_end back to vertex_start. If no path exists vertex_end->path_prev
|
||||||
|
@ -1558,13 +1556,12 @@ static void dijkstra(PathfindingState *s) {
|
||||||
uint32 new_dist;
|
uint32 new_dist;
|
||||||
Vertex *vertex = *it;
|
Vertex *vertex = *it;
|
||||||
|
|
||||||
// Early pathfinding-enabled games exclude edges on screen borders.
|
if (avoidScreenEdge) {
|
||||||
// FIXME: Enable this selectively for those games that need it.
|
// Avoid plotting path along screen edge
|
||||||
#if 0
|
if ((vertex != s->vertex_end) && point_on_screen_border(vertex->v))
|
||||||
// Avoid plotting path along screen edge
|
continue;
|
||||||
if ((vertex != s->vertex_end) && point_on_screen_border(vertex->v))
|
}
|
||||||
continue;
|
|
||||||
#endif
|
|
||||||
new_dist = vertex_min->dist + (uint32)sqrt((float)vertex_min->v.sqrDist(vertex->v));
|
new_dist = vertex_min->dist + (uint32)sqrt((float)vertex_min->v.sqrDist(vertex->v));
|
||||||
if (new_dist < vertex->dist) {
|
if (new_dist < vertex->dist) {
|
||||||
vertex->dist = new_dist;
|
vertex->dist = new_dist;
|
||||||
|
@ -1715,7 +1712,16 @@ reg_t kAvoidPath(EngineState *s, int argc, reg_t *argv) {
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
dijkstra(p);
|
// Early pathfinding-enabled games exclude edges on screen borders.
|
||||||
|
// FIXME: Enable this selectively for those games that need it.
|
||||||
|
bool avoidScreenEdge = false;
|
||||||
|
|
||||||
|
// This is certainly needed for LSL5 room 640, otherwise Patti walks off-screen
|
||||||
|
// and reenters through the wall
|
||||||
|
if (s->_gameName == "lsl5" && s->currentRoomNumber() == 640)
|
||||||
|
avoidScreenEdge = true;
|
||||||
|
|
||||||
|
dijkstra(p, avoidScreenEdge);
|
||||||
|
|
||||||
output = output_path(p, s);
|
output = output_path(p, s);
|
||||||
delete p;
|
delete p;
|
||||||
|
|
|
@ -877,7 +877,7 @@ SegmentRef SegManager::dereference(reg_t pointer) {
|
||||||
|
|
||||||
if (!pointer.segment || (pointer.segment >= _heap.size()) || !_heap[pointer.segment]) {
|
if (!pointer.segment || (pointer.segment >= _heap.size()) || !_heap[pointer.segment]) {
|
||||||
// This occurs in KQ5CD when interacting with certain objects
|
// This occurs in KQ5CD when interacting with certain objects
|
||||||
warning("Attempt to dereference invalid pointer %04x:%04x", PRINT_REG(pointer));
|
warning("SegManager::dereference(): Attempt to dereference invalid pointer %04x:%04x", PRINT_REG(pointer));
|
||||||
return ret; /* Invalid */
|
return ret; /* Invalid */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1158,12 +1158,11 @@ size_t SegManager::strlen(reg_t str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Common::String SegManager::getString(reg_t pointer, int entries)
|
Common::String SegManager::getString(reg_t pointer, int entries) {
|
||||||
{
|
|
||||||
Common::String ret;
|
Common::String ret;
|
||||||
SegmentRef src_r = dereference(pointer);
|
SegmentRef src_r = dereference(pointer);
|
||||||
if (!src_r.isValid()) {
|
if (!src_r.isValid()) {
|
||||||
warning("Attempt to dereference invalid pointer %04x:%04x", PRINT_REG(pointer));
|
warning("SegManager::getString(): Attempt to dereference invalid pointer %04x:%04x", PRINT_REG(pointer));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if (entries > src_r.maxSize) {
|
if (entries > src_r.maxSize) {
|
||||||
|
|
|
@ -222,7 +222,7 @@ bool Script::isValidOffset(uint16 offset) const {
|
||||||
|
|
||||||
SegmentRef Script::dereference(reg_t pointer) {
|
SegmentRef Script::dereference(reg_t pointer) {
|
||||||
if (pointer.offset > _bufSize) {
|
if (pointer.offset > _bufSize) {
|
||||||
warning("Attempt to dereference invalid pointer %04x:%04x into script segment (script size=%d)",
|
warning("Script::dereference(): Attempt to dereference invalid pointer %04x:%04x into script segment (script size=%d)",
|
||||||
PRINT_REG(pointer), (uint)_bufSize);
|
PRINT_REG(pointer), (uint)_bufSize);
|
||||||
return SegmentRef();
|
return SegmentRef();
|
||||||
}
|
}
|
||||||
|
@ -299,7 +299,7 @@ SegmentRef SystemStrings::dereference(reg_t pointer) {
|
||||||
ret.raw = (byte *)(_strings[pointer.offset]._value);
|
ret.raw = (byte *)(_strings[pointer.offset]._value);
|
||||||
else {
|
else {
|
||||||
// This occurs in KQ5CD when interacting with certain objects
|
// This occurs in KQ5CD when interacting with certain objects
|
||||||
warning("Attempt to dereference invalid pointer %04x:%04x", PRINT_REG(pointer));
|
warning("SystemStrings::dereference(): Attempt to dereference invalid pointer %04x:%04x", PRINT_REG(pointer));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue