NagyD / SDLPoP

An open-source port of Prince of Persia, based on the disassembly of the DOS version.
GNU General Public License v3.0
1.1k stars 140 forks source link

Out of bounds x-coordinate in x_bump #307

Closed dstarosta closed 1 year ago

dstarosta commented 1 year ago

In the linked code line the very first value of the "x_bump" array is -12. It is out of the byte range and gets converted to 244. Even if the "x_bump" variable is declared as "short", "Char.x" is still an unsigned byte.

"y_land" has a similar problem with the -8 value but has the type of "short" in the "data.h" file.

https://github.com/NagyD/SDLPoP/blob/bf97796df594688fae6f7b68fbcd57f20a7beb13/src/data.h#L513

Is this a bug in the assembly code?

NagyD commented 1 year ago

x_bump[] comes from here: https://github.com/jmechner/Prince-of-Persia-Apple-II/blob/master/01%20POP%20Source/Source/TABLES.S#L142-L154 I don't even know if the first value is ever used, because that represents the column off-screen to the left by 5 tiles. I might have seen the kid wrap around when he backed off screen to the left (during a sword fight).

y_land[] comes from here: https://github.com/jmechner/Prince-of-Persia-Apple-II/blob/master/01%20POP%20Source/Source/TABLES.S#L178-L185

The y coordinate is a bit tricky. It's not fully unsigned, because it's treated as signed here: https://github.com/NagyD/SDLPoP/blob/7aeacd83167ab407272ab539ed5190fffc1d80f7/src/seg002.c#L428-L433

While at it, this part casts y_land to unsigned: https://github.com/NagyD/SDLPoP/blob/7aeacd83167ab407272ab539ed5190fffc1d80f7/src/seg005.c#L42-L43 I added the cast to make it possible to jump through the wall on level 7. (Trick 41) Details: https://forum.princed.org/viewtopic.php?p=15042#p15042

dstarosta commented 1 year ago

Thanks for the explanation.

The negative x_bump value presented an issue if you want the guard to follow you from another room because it causes the can_guard_see_kid function to look at a tile in a different room. It is not a problem in the original game because guards do not follow you from far.