Sword disappears at the edge of the room when turned left

Open-source port of PoP that runs natively on Windows, Linux, etc.
Post Reply
dmitry_s
Developer
Developer
Posts: 148
Joined: July 27th, 2021, 7:22 am

Sword disappears at the edge of the room when turned left

Post by dmitry_s »

See the attachment. It happens at specific coordinates when guard or kid are turned left. If you enable the fix that keeps guards from disappearing you are going to see the sword in the next room. There is a gap between the guard's hand and the sword. It happens at certain positions with kid as well when in combat.

I think the issue is with the sword table values but I am not exactly sure how to fix it correctly to avoid side effects. This is a workaround that I put with a few coordinates I identified. It puts the sword 1 pixel to the left of where it should be but it still looks much better than the gap (see the second attachment).

Code: Select all

void fix_disappearing_sword_obj_x() {
    // custom logic - prevent sword from disappearing at specific positions
    // when the character is facing left near the edge of the room
    if (Char.charid == charid_0_kid && Char.direction == dir_FF_left && obj_x == 19) {
    	--obj_x;
    } else if (Char.charid == charid_0_kid && Char.direction == dir_FF_left && obj_x == 3) {
    	--obj_x;
    // need to test it with skeletons
    } else if (Char.charid == charid_2_guard && Char.direction == dir_FF_left && ABS(obj_x) == 4) {
    	--obj_x;
    }
}

// seg006:1798
void __pascal far add_sword_to_objtable() {
	short frame;
	short sword_frame;
	frame = Char.frame;
	if ((frame >= frame_229_found_sword && frame < 238) || // found sword + put sword away
		Char.sword != sword_0_sheathed ||
		(Char.charid == charid_2_guard && Char.alive < 0)
	) {
		sword_frame = cur_frame.sword & 0x3F;
		if (sword_frame) {
			obj_id = sword_tbl[sword_frame].id;
			if (obj_id != 0xFF) {
				obj_x = calc_screen_x_coord(obj_x);
				fix_disappearing_sword_obj_x(); // the fix function
				obj_dx_forward(sword_tbl[sword_frame].x);
				obj_y += sword_tbl[sword_frame].y;
				obj_chtab = id_chtab_0_sword;
				add_objtable(3); // sword
			}
		}
	}
}
Attachments
screenshot_000.png
screenshot_000.png (7.67 KiB) Viewed 841 times
screenshot_001.png
screenshot_001.png (7.83 KiB) Viewed 841 times
David
The Prince of Persia
The Prince of Persia
Posts: 2848
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: Sword disappears at the edge of the room when turned left

Post by David »

I can't reproduce the guard's exact position.

But I know of another graphical glitch related to x-position of sprites.
At the end of level 12, when I do a run-jump towards the next room, the prince is temporarily shifted to the left.

See this replay:
level_12_xpos_glitch.p1r
(3.82 KiB) Downloaded 44 times
I can fix that bug if I replace the x_to_xh_and_xl() function with this:

Code: Select all

void __pascal far x_to_xh_and_xl(int xpos, sbyte *xh_addr, sbyte *xl_addr) {
	*xh_addr = xpos >> 3;
	*xl_addr = xpos & 7;
}
This function is called from add_objtable(), which is called from add_sword_to_objtable().

You could check if this fixes the sword glitch as well.


The original code of that function is quite complicated, and works incorrectly if xpos is negative and divisible by 8.
That's when the glitch appears.

xh and xl should be calculated so that: xh*8+xl == xpos
But when the glitch appears, this is true instead: xh*8+xl == xpos-8

This strange division of xpos into xh (x high) and xl (x low) was inherited from the Apple II version.
There each pixel is one bit, and drawing needs the byte address and the bit offset to be separated.
dmitry_s
Developer
Developer
Posts: 148
Joined: July 27th, 2021, 7:22 am

Re: Sword disappears at the edge of the room when turned left

Post by dmitry_s »

Yes, that code fixes the glitches. It sounds like it is safe to use that code. Thanks.
David
The Prince of Persia
The Prince of Persia
Posts: 2848
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: Sword disappears at the edge of the room when turned left

Post by David »

dmitry_s wrote: August 7th, 2021, 8:19 pm Yes, that code fixes the glitches. It sounds like it is safe to use that code. Thanks.
Done: https://github.com/NagyD/SDLPoP/commit/ ... 9ddb063be7
Post Reply