Skip to content

Commit

Permalink
When backing offscreen (to the left) from the first guard on level 7,…
Browse files Browse the repository at this point in the history
… simulate the glitch from DOS PoP, which causes the prince to fall through the floor. (#229)
  • Loading branch information
NagyD committed Dec 31, 2020
1 parent e3b3032 commit 58f3fdd
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 2 deletions.
1 change: 1 addition & 0 deletions doc/ChangeLog.txt
Expand Up @@ -596,3 +596,4 @@ DONE: Added a new cheat key: Ctrl+B: Go back to the room where the prince is. (U
FIXED: Fixed the length of feather fall in fast-forward mode.
FIXED: Prevent torches from being randomly colored when an older replay is loaded.
FIXED: If the prince is fighting a guard, and the player does a quickload to a state where the prince is near the mouse, the prince would draw the sword.
DONE: When backing offscreen (to the left) from the first guard on level 7, simulate the glitch from DOS PoP, which causes the prince to fall through the floor.
26 changes: 24 additions & 2 deletions src/seg006.c
Expand Up @@ -714,13 +714,19 @@ const byte tile_mod_tbl[256] = {

// seg006:03F0
int __pascal far get_tile_div_mod(int xpos) {
// Determine tile column (xh) and the position within the tile (xl) from xpos.

// xpos might be negative if the kid is far off left.
// In this case, the array index overflows.
/* if (xpos < 0 || xpos >= 256) {
if (xpos < 0 || xpos >= 256) {
printf("get_tile_div_mod(): xpos = %d\n", xpos);
}*/
}

// DOS PoP does this:
// obj_xl = tile_mod_tbl[xpos];
// return tile_div_tbl[xpos];

// xpos uses a coordinate system in which the left edge of the screen is 58, and each tile is 14 units wide.
int x = xpos - 58;
int xl = x % 14;
int xh = x / 14;
Expand All @@ -730,6 +736,22 @@ int __pascal far get_tile_div_mod(int xpos) {
// Modulo returns a negative number if x is negative, but we want 0 <= xl < 14.
xl += 14;
}

if (xpos < 0) {
// In this case DOS PoP reads the bytes directly before tile_div_tbl[] and tile_mod_tbl[] in the memory.
// Here we simulate these reads.
// Before tile_mod_tbl[] is tile_div_tbl[], and before tile_div_tbl[] are the following bytes:
static const byte bogus[] = {0x02, 0x00, 0x41, 0x00, 0x80, 0x00, 0xBF, 0xFF, 0x01, 0x01, 0xFF, 0xC4, 0xFF, 0x03, 0x00, 0x42, 0x00, 0x81, 0x00, 0xC0, 0x00, 0xF8, 0xFF, 0x37, 0x00, 0x76, 0x00, 0xB5, 0x00, 0xF4, 0x00};
if (COUNT(bogus) + xpos >= 0) {
xh = bogus[COUNT(bogus) + xpos]; // simulating tile_div_tbl[xpos]
xl = tile_div_tbl[COUNT(tile_div_tbl) + xpos]; // simulating tile_mod_tbl[xpos]
} else {
printf("xpos = %d (< %d) out of range for simulation of index overflow!\n", xpos, -COUNT(bogus));
}
}

// TODO: Do the same for xpos >= 256.

obj_xl = xl;
return xh;
}
Expand Down

0 comments on commit 58f3fdd

Please sign in to comment.