[Scummvm-git-logs] scummvm branch-2-9 -> 6ebb6a963ce09125e1556096766eba0a211f0fd7
antoniou79
noreply at scummvm.org
Thu Feb 6 11:48:45 UTC 2025
This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
9ba3b8867f BLADERUNNER: Initialize color in SliceRenderer::drawShadowPolygon()
1346b3ac61 BLADERUNNER: Fix duplicate vertices in merged polygons
6ebb6a963c BLADERUNNER: Fix 2x scaling for non-interactive demo
Commit: 9ba3b8867f1742c05941aeb9d7dc6e28c67b806d
https://github.com/scummvm/scummvm/commit/9ba3b8867f1742c05941aeb9d7dc6e28c67b806d
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2025-02-06T13:46:08+02:00
Commit Message:
BLADERUNNER: Initialize color in SliceRenderer::drawShadowPolygon()
Prevents compiler warning for potential uninitialized use of color
This would happen if getPixel() dealt with a Surface whose bytePerPixel would be a value other than 1, 2 or 4. So highly unlikely.
Changed paths:
engines/bladerunner/slice_renderer.cpp
diff --git a/engines/bladerunner/slice_renderer.cpp b/engines/bladerunner/slice_renderer.cpp
index 87331edde9f..19014a30c20 100644
--- a/engines/bladerunner/slice_renderer.cpp
+++ b/engines/bladerunner/slice_renderer.cpp
@@ -732,7 +732,7 @@ void SliceRenderer::drawShadowPolygon(int transparency, Graphics::Surface &surfa
if (z >= zMin) {
int index = (x & 3) + ((y & 3) << 2);
if (transparency - ditheringFactor[index] <= 0) {
- uint32 color;
+ uint32 color = 0;
uint8 r, g, b;
getPixel(surface, pixel, color);
surface.format.colorToRGB(color, r, g, b);
Commit: 1346b3ac61ff5b480bde7fbe78018086cb5b73c8
https://github.com/scummvm/scummvm/commit/1346b3ac61ff5b480bde7fbe78018086cb5b73c8
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2025-02-06T13:46:29+02:00
Commit Message:
BLADERUNNER: Fix duplicate vertices in merged polygons
Some merged polygons for obstacles would get duplicate vertices
This could result in bad pathfinding and actors being stuck while walking to their destinations.
A soft lock could occur, for example in RC02, with Runciter walking to his desk to get
the camera disc, if he started at a point like -15.78f, -1238.894287f, 108432.14f
(ie. Actor_Set_At_XYZ(kActorRunciter, -15.78f, -1238.894287f, 108432.14f, Actor_Query_Facing_1024(kActorRunciter));)
Same could happen to the player's actor, but in Runciter's case from the above example,
the player loses control until Runciter gets the disc and gives it to McCoy, but since
Runctiter never reaches the waypoint to get the disc, the game is soft locked.
This will not automatically fix a scene's obstacles loaded from an old saved game.
For those cases, the player will have to exit the scene and re-enter for the obstacles
to be properly recalculated.
Changed paths:
engines/bladerunner/obstacles.cpp
diff --git a/engines/bladerunner/obstacles.cpp b/engines/bladerunner/obstacles.cpp
index e4a2c8528fe..7dd17b41ad4 100644
--- a/engines/bladerunner/obstacles.cpp
+++ b/engines/bladerunner/obstacles.cpp
@@ -112,7 +112,7 @@ bool Obstacles::linePolygonIntersection(LineSegment lineA, VertexType lineAType,
float nearestIntersectionDistance = 0.0f;
for (int i = 0; i != polyB->verticeCount; ++i) {
- LineSegment lineB;
+ LineSegment lineB; // An edge of the secondary polygon
lineB.start = polyB->vertices[i];
lineB.end = polyB->vertices[(i+1) % polyB->verticeCount];
@@ -121,20 +121,32 @@ bool Obstacles::linePolygonIntersection(LineSegment lineA, VertexType lineAType,
Vector2 newIntersectionPoint;
if (lineLineIntersection(lineA, lineB, &newIntersectionPoint)) {
+ // NOTE: An edge type (eg lineAType) is set by its start point vertex type.
+ // The end point of the edge is the next vertex of the polygon going clock-wise.
if ((lineAType == TOP_RIGHT && lineBType == TOP_LEFT)
|| (lineAType == BOTTOM_RIGHT && lineBType == TOP_RIGHT)
|| (lineAType == BOTTOM_LEFT && lineBType == BOTTOM_RIGHT)
|| (lineAType == TOP_LEFT && lineBType == BOTTOM_LEFT)
) {
+ // NOTE: pathLengthSinceLastIntersection is part of pathfinding fix 2
if ( (pathLengthSinceLastIntersection > 2)
- || ( (!(WITHIN_TOLERANCE(lineB.end.x, intersectionPoint->x) && WITHIN_TOLERANCE(lineB.end.y, intersectionPoint->y)))
- && (newIntersectionPoint != *intersectionPoint) )) {
+ || ( (!(WITHIN_TOLERANCE(lineB.end.x, newIntersectionPoint.x) && WITHIN_TOLERANCE(lineB.end.y, newIntersectionPoint.y)))
+ && (newIntersectionPoint != *intersectionPoint) )) {
float newIntersectionDistance = getLength(lineA.start.x, lineA.start.y, newIntersectionPoint.x, newIntersectionPoint.y);
+ // NOTE: We only want the *nearest* intersection point to the start of the line A
+ // We don't want the intersection point to be the end point of the line B (from secondary polygon),
+ // because in that case, switching to Polygon B (to make it primary) we'd get an "edge"
+ // from the intersection point to the end point of the line B (which was a vertex of Polygon B)
+ // which would result to an edge with the same start and end point, and thus duplicate vertices in the merged polygon.
+ //
+ // We do keep 0 length segments here from lineA start to the intersection point
+ // (which can happen when the polygons touch edges or corners)
+ // but those will be handled in the calling function.
if (!hasIntersection || newIntersectionDistance < nearestIntersectionDistance) {
hasIntersection = true;
nearestIntersectionDistance = newIntersectionDistance;
*intersectionPoint = newIntersectionPoint;
- *intersectionIndex = i;
+ *intersectionIndex = i; // the index of the vertex for the start of the lineB edge (of Polygon B which will become primary)
}
}
}
@@ -146,10 +158,10 @@ bool Obstacles::linePolygonIntersection(LineSegment lineA, VertexType lineAType,
/*
* Polygons vertices are defined in clock-wise order
- * starting at the top-most, right-most corner.
+ * starting at the top-most, left-most corner (eg. here B0).
*
- * When merging two polygons, we start at the top-most, right-most vertex.
- * The polygon with this vertex starts is the primary polygon.
+ * When merging two polygons, we start at the top-most, left-most vertex.
+ * The polygon with this vertex starts as the primary polygon.
* We follow the edges until we find an intersection with the secondary polygon,
* in which case we switch primary and secondary and continue following the new edges.
*
@@ -202,6 +214,9 @@ bool Obstacles::mergePolygons(Polygon &polyA, Polygon &polyB) {
polyLine.end = polyPrimary->vertices[(vertIndex + 1) % polyPrimary->verticeCount];
// TODO(madmoose): How does this work when adding a new intersection point?
+ // The intersection point "inherits" the vertex type of the now-primary
+ // (which was "secondary" before the intersection swap) polygon's vertex,
+ // which was the start of the edge that intersected with the former-primary (now secondary) polygon.
polyPrimaryType = polyPrimary->vertexType[vertIndex];
if (flagAddVertexToVertexList) {
@@ -225,7 +240,19 @@ bool Obstacles::mergePolygons(Polygon &polyA, Polygon &polyB) {
if (linePolygonIntersection(polyLine, polyPrimaryType, polySecondary, &intersectionPoint, &polySecondaryIntersectionIndex, pathLengthSinceLastIntersection)) {
if (WITHIN_TOLERANCE(intersectionPoint.x, polyLine.start.x) && WITHIN_TOLERANCE(intersectionPoint.y, polyLine.start.y)) {
+ // The start of the edge of the primary polygon is (very close to) the intersection point.
+ // This eg. does occur in RC02 (Set 16, Scene 79, chapter 1) (intersection point (x: -16.000000, y: 108303.968750))
+
+ // The code here ensures we keep the intersection point in the merged polygon (polyMerged)
+ // but *remove* the vertex that was the start of the edge (belonging to the primary polygon)
+ // However, unless the intersection point is exactly the same as the start of the line segment from the primary polygon,
+ // (which seems to practically be the case)
+ // this can *potentially* lead to slanted (so not strictly vertical or horizontal) lines in the merged polygon.
+ // TODO: Is there a case where we end up with slanted edges in the merged polygon?
flagAddVertexToVertexList = false;
+ // TODO: We don't check here for polyMerged.verticeCount > 0 before decrementing it,
+ // and this practically seems to not be an issue, but shouldn't we include this check just to be safe?
+ //
// TODO(madmoose): How would this work?
--(polyMerged.verticeCount);
} else {
@@ -451,6 +478,7 @@ bool Obstacles::findNextWaypoint(const Vector3 &from, const Vector3 &to, Vector3
}
if (--recursionLevel > 1) {
+ // NOTE: Basically this allows at most 1 level of recursion
return false;
}
@@ -801,7 +829,7 @@ bool Obstacles::findFarthestAvailablePathVertex(Vector2 *path, int pathSize, Vec
}
int polygonVertexType = polygon->vertexType[polygonVertexIdx];
- if ((polygonVertexType == TOP_LEFT && intersection.y < path[pathVertexIdx].y)
+ if ((polygonVertexType == TOP_LEFT && intersection.y < path[pathVertexIdx].y)
|| (polygonVertexType == TOP_RIGHT && intersection.x > path[pathVertexIdx].x)
|| (polygonVertexType == BOTTOM_RIGHT && intersection.y > path[pathVertexIdx].y)
|| (polygonVertexType == BOTTOM_LEFT && intersection.x < path[pathVertexIdx].x)
@@ -929,6 +957,7 @@ void Obstacles::load(SaveFileReadStream &f) {
_pathSize = f.readInt();
}
+// This is used when debugger is set to draw obstacles
void Obstacles::draw() {
float y = _vm->_playerActor->getY();
@@ -956,7 +985,7 @@ void Obstacles::draw() {
}
}
- // draw actor's box
+ // draw actor's box - only for the player (McCoy)
{
Vector3 playerPos = _vm->_playerActor->getXYZ();
Vector3 p0 = _vm->_view->calculateScreenPosition(playerPos + Vector3(-12.0f, 0.0f, -12.0f));
Commit: 6ebb6a963ce09125e1556096766eba0a211f0fd7
https://github.com/scummvm/scummvm/commit/6ebb6a963ce09125e1556096766eba0a211f0fd7
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2025-02-06T13:46:39+02:00
Commit Message:
BLADERUNNER: Fix 2x scaling for non-interactive demo
Fixes bug https://bugs.scummvm.org/ticket/15713
Changed paths:
engines/bladerunner/outtake.cpp
diff --git a/engines/bladerunner/outtake.cpp b/engines/bladerunner/outtake.cpp
index 989e99c3334..92893afa5d1 100644
--- a/engines/bladerunner/outtake.cpp
+++ b/engines/bladerunner/outtake.cpp
@@ -72,13 +72,21 @@ void OuttakePlayer::play(const Common::String &name, bool noLocalization, int co
VQAPlayer vqaPlayer(_vm, &_surfaceVideo, resNameNoVQASuffix + ".VQA"); // in original game _surfaceFront is used here, but for proper subtitles rendering we need separate surface
+ vqaPlayer.open();
+
+ // NOTE: The VQAPlayer::open():
+ // - calls VQAPlayer::close(), and that calls VQADecoder::close(), at its start to cleanup any previous state.
+ // - later it calls _decoder.loadStream() which also calls VQADecoder::close().
+ // Since VQADecoder::close() cleans up (deletes) the VQPTable,
+ // we need to do the allocation for it and loading of its values here, *after* vqaPlayer.open().
+ // The parsing of the VQP files is needed for the case of the non-interactive Blade Runner demo
+ // and the support of other old VQA files that have accompanying VQP files (eg. for demo reels for other Westwood games)
if (container == -2) {
// container value: -2 indicates potential existence of VQP file
if (!vqaPlayer.loadVQPTable(resNameNoVQASuffix + ".VQP")) {
debug("Unable to load VQP table");
}
}
- vqaPlayer.open();
_vm->_vqaIsPlaying = true;
_vm->_vqaStopIsRequested = false;
More information about the Scummvm-git-logs
mailing list