I investigated the cause of the overflow bug, using SDLPoP with the help of a debugger.
The test case is the level 12 skip.
When jumping to the new room to the left, the x/y coordinates of the kid are initially:
x = 53, y =199
After the room transition, this becomes:
x = 193, y = 199
Then, in redraw_screen(), exit_room_timer is set to 2.
As a result, for the next two frames, exit_room() prematurely exits while counting down exit_room_timer. (The room cannot change again during this time).
The next few frames, the x/y coordinates are:
x = 190, y = 211 (at this point, the y threshold for leaving the room downwards is reached, but leave_room() is never called)
x = 189, y = 244
x = 189, y = 244 (the same because the kid has grabbed the ledge down below)
At this point, leave_room() is called again.
Then the relevant code is this:
Code: Select all
if (action != actions_5_bumped &&
action != actions_4_in_freefall &&
action != actions_3_in_midair &&
(sbyte)chary < 10 && (sbyte)chary > -16
) {
leave_dir = 2; // up
} else if (chary >= 211) {
leave_dir = 3; // down
} ...
Because y = 244, the cast (sbyte)chary resolves to -12. As a result of this the leave_dir is set to 2 (up) instead of 3 (down).
This explains why the kid is moved to the room above.
Then, in goto_other_room(), Char.y += 189 occurs.
The new y value is 177. ((244 + 189) % 256)