JHGuitarFreak / UQM-MegaMod

A fork of The Ur-Quan Masters + HD-mod that remasters the HD graphics with a veritable smorgasbord of extra features, options, QoL improvements, and much more...
https://uqm-mods.sourceforge.net
GNU General Public License v2.0
80 stars 22 forks source link

Kruzenshtern's Bugs: Starmap cursor is slightly off after Ur-Quan hypnotized encounter. #37

Closed Serosis closed 4 years ago

Serosis commented 4 years ago

A gentleperson named Kruzenshtern got in touch with me and sent me a lovely list of bugs that I'm entering in here so they can be tracked proper.

This is their fifth bug, verbatim:

Right after conversation described in bug #36, a new oddity appears. Actually it appears on several points, but this is most comfortable for testing.

Steps to reproduce:

⦁ Know that Umgah are zombies (GAME_STATE (KNOW_UMGAH_ZOMBIES, 1)) ⦁ Go to Beta Orionis I without Taalo Shield ⦁ Talk to Talking Pet ⦁ Get hypnotized ⦁ Zap to Ur-Quan conversation ⦁ Leave Ur-Quan conversation ⦁ Get spit out to HyperSpace ⦁ DO NOT MOVE ⦁ Open StarMap ⦁ DO NOT MOVE CURSOR ⦁ Set Maximum zoom-in image

StarMap cursor position is off

As far as I tested, this is not an issue in a original game, but exists in UQM 0.7.0 and MegaMod 0.8.0.84. This comes from recalculating DISP to universe. In pstarmap.c function StarMap(void) called. It stores SIS position to POINT universe variable. If not autopilot, universe value get tossed to POINT cursorLoc, which is shared between all functions in pstamap.c. Then cursor gets drawn by calling DrawCursor (UNIVERSE_TO_DISPX (cursorLoc.x), UNIVERSE_TO_DISPY(cursorLoc.y)). At that point cursor has been drawn correctly, but SIS Title didn’t get updated. Almost right after drawning, UpdateCursorInfo (UNICODE *prevbuf) from pstarmap.c is called. It defines a new point - POINT pt: pt.x = UNIVERSE_TO_DISPX (cursorLoc.x); pt.y = UNIVERSE_TO_DISPY (cursorLoc.y); After several checks related to cursor pointing on star or Quasispace portal, if nothing found, cursorLoc gets recalculated from pt:

        else
    {   // No star found. Reset the coordinates to the cursor's location
        cursorLoc.x = DISP_TO_UNIVERSEX (pt.x);
        if (cursorLoc.x < 0)
            cursorLoc.x = 0;
        else if (cursorLoc.x > MAX_X_UNIVERSE)
            cursorLoc.x = MAX_X_UNIVERSE;
        cursorLoc.y = DISP_TO_UNIVERSEY (pt.y);
        if (cursorLoc.y < 0)
            cursorLoc.y = 0;
        else if (cursorLoc.y > MAX_Y_UNIVERSE)
            cursorLoc.y = MAX_Y_UNIVERSE;
    }

At that point cursorLoc gets new slightly different value, which is drawn at SIS Title (DrawHyperCoords (cursorLoc);). And because this variable is shared, if we zoom in - DrawCursor (UNIVERSE_TO_DISPX(cursorLoc.x), UNIVERSE_TO_DISPY (cursorLoc.y)) will redraw cursor in wrong position. image

Recreation in HD mode (coords are 528.7:489.1 – slightly off)

image

Recreation of bug scenario in original game. Cursor points correctly

image

Maximum zoom of previous screeshot scene

Possible solution

Since it is an error check for values (as I understand it), I added a dummy POINT to UpdateCursorInfo (UNICODE *prevbuf) function, and if it’s values are off, then cursorLoc gets redefined. But probably math for DISP_TO_UNIVERSE functions needs to be checked.

        else
    {   // No star found. Reset the coordinates to the cursor's location
        change.x = DISP_TO_UNIVERSEX (pt.x);
        if (change.x < 0)
            cursorLoc.x = 0;
        else if (change.x > MAX_X_UNIVERSE)
            cursorLoc.x = MAX_X_UNIVERSE;
        change.y = DISP_TO_UNIVERSEY (pt.y);
        if (change.y < 0)
            cursorLoc.y = 0;
        else if (change.y > MAX_Y_UNIVERSE)
            cursorLoc.y = MAX_Y_UNIVERSE;
    }

image

StarMap cursor after fix

Kruzen commented 4 years ago

I recently found that cursor misslocation actually happens almost everywhere in HyperSpace, unless recalculation gets the same result, which is rare, or cursor is pointing on the star. Same reason, same solution. Bug itself is not tied to described Ur-Quan encounter.