MEGA65 / mega65-rom-public

MEGA65 ROM public issue reporting
4 stars 0 forks source link

MOVSPR ... TO ... sometimes overshoots its target #127

Open dansanderson opened 4 months ago

dansanderson commented 4 months ago

MOVSPR <sprite>,<origin-x>,<origin-y> TO <dest-x>,<dest-y>,<speed>

sets the sprite to the origin location, then calculates a velocity (xmo and ymo) that cause it to arrive at the destination location at the requested speed per frame. This velocity is applied to the sprite coordinates once per frame in an IRQ routine. When the sprite arrives, its speed is set to 0.

Specifically, for each frame, a new position is calculated based on the velocity, and this position is compared to the target. If the new position overshoots the target in the direction of the velocity—calculated based on the sign of the velocity for each axis—it is considered "at" the target. The speed is set to 0 and the actual position is set to the target position, even if the calculated position overshot.

This algorithm (or at least the implementation) fails to detect arrival at the target in some edge cases, causing the sprite to continue moving at the given angle and speed beyond the target, typically wrapping around the screen. Depending on the values, it may or may not eventually arrive at the destination after wrapping.

I believe I noticed this behavior before this change https://github.com/MEGA65/mega65-rom/commit/69f2bda300f62dcff6a41d8b440ca94930968572 which revises some of the target detection logic. I can't tell if it happens more often with the new logic, but I don't believe it is directly caused by the change.

One example discovered using the new hires sprite support: MOVSPR 0,100,100 TO 600,375,1 xmo=$00e0, ymo=$007b, xtg=$0258, ytg=$0177.

Please add more examples to this ticket as they are discovered.

johnwayner commented 4 months ago

I'm not really sure this is useful, but this one fails seemingly randomly: MOVSPR 0,150,150 TO 200,255,4 (for speed 1 to 4 -- more than that and it doesn't seem to work ever)