Menu

#7140 SCI: QFG3 - Incorrect Keyboard Movement

open
nobody
None
5
2016-05-28
2016-05-27
Omer Mor
No

ScummVM version:
ScummVM 1.9.0git1868-gd35cdf5 (May 19 2016 09:14:40)
Features compiled in: TAINTED Vorbis FLAC MP3 RGB zLib MPEG2 FluidSynth Theora AAC FreeType2 JPEG PNG

Details:
In QFG3 (anthology version, English, no patches), room 750, when standing in the middle of the upper bridge, moving the character via the keyboard behaves incorrectly:
Pressing the LEFT key moves the hero to the right.

In SSCI, the LEFT key moves the hero to the left, as expected.

Attaching save games for ScummVM and SSCI.

Plaftorm: Windows 10

3 Attachments

Discussion

  • Omer Mor

    Omer Mor - 2016-05-27

    Maybe this could help:
    When enabling Pathfinding debugflag, we get this output upon pressing the LEFT key:

    [avoidpath] Pathfinding input:
    Start point: (218, 27)
    End point: (-31782, 27)
    Optimization level: 0
    Polygons:
    3: (262, 189) (272, 175) (265, 159) (235, 159) (221, 156) (201, 161) (191, 172) (128, 169) (38, 170) (64, 160) (137, 86) (127, 77) (135, 70) (164, 67) (184, 66) (204, 69) (224, 78) (228, 76) (187, 56) (133, 66) (116, 80) (128, 84) (57, 156) (32, 164) (21, 154) (48, 141) (33, 131) (57, 126) (0, 120) (0, 189) (262, 189);
    3: (319, 88) (306, 85) (310, 74) (292, 70) (270, 69) (246, 78) (298, 78) (304, 81) (291, 90) (319, 90) (319, 88);
    3: (319, 32) (282, 26) (204, 27) (183, 19) (135, 1) (130, 9) (202, 30) (284, 30) (319, 43) (319, 32);

    Returning path:
    (218, 27) (284, 30);


    The same problem also occurs when standing in the middle of the bottom plane (with the grass) and pressing the RIGHT key (the hero goes left):

    [avoidpath] Pathfinding input:
    Start point: (127, 179)
    End point: (10793, 179)
    Optimization level: 0
    Polygons:
    3: (262, 189) (272, 175) (265, 159) (235, 159) (221, 156) (201, 161) (191, 172) (128, 169) (38, 170) (64, 160) (137, 86) (127, 77) (135, 70) (164, 67) (184, 66) (204, 69) (224, 78) (228, 76) (187, 56) (133, 66) (116, 80) (128, 84) (57, 156) (32, 164) (21, 154) (48, 141) (33, 131) (57, 126) (0, 120) (0, 189) (262, 189);
    3: (319, 88) (306, 85) (310, 74) (292, 70) (270, 69) (246, 78) (298, 78) (304, 81) (291, 90) (319, 90) (319, 88);
    3: (319, 32) (282, 26) (204, 27) (183, 19) (135, 1) (130, 9) (202, 30) (284, 30) (319, 43) (319, 32);

    Returning path:
    (127, 179) (0, 179);

     
  • Omer Mor

    Omer Mor - 2016-05-27

    I have a suspicion the problem has to with polygons of type POLY_CONTAINED_ACCESS (3).

    I managed to reproduce this behavior also in room 380, when pressing LEFT (hero goes upper-left):

    [avoidpath] Pathfinding input:
    Start point: (204, 135)
    End point: (-10462, 135)
    Optimization level: 0
    Polygons:
    3: (0, 92) (85, 92) (81, 103) (60, 109) (70, 115) (70, 136) (140, 179) (177, 184) (251, 184) (293, 152) (232, 110) (141, 96) (133, 87) (178, 80) (178, 76) (227, 76) (263, 69) (287, 71) (319, 53) (319, 1) (0, 1) (0, 92);

    Returning path:
    (204, 135) (146, 97) (141, 96) (0, 1);

     
  • Omer Mor

    Omer Mor - 2016-05-27

    I found that fixup_end_point() changes the endpoint from (-31782, 27) to (284, 30) which flips the direction from the hero's left to the hero's right side (the hero is at (233, 30)).

    After this change it's clear why the pathfinding algorithm finds a path that moves the hero to the right.
    Still need to figure what goes wrong in fixup_end_point().

     

    Last edit: Omer Mor 2016-05-27
  • Omer Mor

    Omer Mor - 2016-05-27

    Further analysis:

    I've got this backtrace:

        scummvm.exe!Common::Point::sqrDist(const Common::Point & p) Line 64 C++
        scummvm.exe!Sci::PathfindingState::findNearPoint(const Common::Point & p, Sci::Polygon * polygon, Common::Point * ret) Line 796 C++
        scummvm.exe!Sci::fixup_end_point(Sci::PathfindingState * s, const Common::Point & end) Line 1032    C++
        scummvm.exe!Sci::convert_polygon_set(Sci::EngineState * s, Sci::reg_t poly_list, Common::Point start, Common::Point end, int width, int height, int opt) Line 1234  C++
    

    The end point is very far the to west (-31,782). // explain why
    fixup_end_point() tries to fix it to the closest point in the containing POLY_CONTAINED_ACCESS polygon. It does that in PathfindingState::findNearPoint() by iterating on the polygon's points and calculating comparing distances via Point::sqrDist().
    The problem is that Point::sqrDist() only supports distance in each axis up to 4,096 (0x1000), When the distance is longer, it returns a constant 0xFFFFFF.
    As a consequence, the iteration in PathfindingState::findNearPoint() always calculates the same sqrDist from the end point, so the point it chooses is not the one with the minimal distance, but the ones that it happened to compare first with.

    I don't know why Point::sqrDist() has these limits, but I'll try to find out.

     
  • Omer Mor

    Omer Mor - 2016-05-28

    Following a discussion with waltervn, here's what we concluded:
    1. Calling kAvoidPath due to keyboard event should not result in real pathfinding: it is called with optimizing level of 0, which means it should simply return a direct path until an obstacle is hit. This means fixup_end_point probaly should not be called in this case. Assuming this is correct - then this is the root cause of the bug.
    2. Point::sqrDist() is capping the distance, and it's hard to tell why. This function goes back to the initial scummvm commit by Ludvig Strigeus from 2001. However since it's not the root cause - its not clear whether it should be fixed.

     
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.