Page 1 of 1

Another graphical glitch

Posted: April 28th, 2021, 8:05 pm
by dmitrys
This issue is reproducible easily with the "draw_sword_anywhere" branch. But it can happen at specific pixels when you jump and grab the ledge right before the chomper.

The problem seems to happen in the function linked below. If the "if" statement that checks for fall is false, it re-renders tiles above and below kid. And sometimes the "char_col_right" points to the chomper. The "set_redraw2" function messes an open chomper up.

https://github.com/NagyD/SDLPoP/blob/90 ... 003.c#L468

I created a simple fix that tracks if you are falling and skips rendering of chomper tiles. But I am wondering if there is a more elegant fix that David usually finds.


Re: Another graphical glitch

Posted: April 29th, 2021, 4:36 am
by atrueprincefanfrom18
I've seen it before in the normal SDLPoP package too. Check this at 1:24 timestamp.

Re: Another graphical glitch

Posted: April 29th, 2021, 10:05 pm
by dmitrys
It looks from your video that the bug can also happen when prince is dropping down to a row that has a chomper.

Edit: It is definitely reproducible as well.


Re: Another graphical glitch

Posted: May 1st, 2021, 7:44 pm
by David
It also happens when you hang below the chomper like this:
floor-chomper.PNG
floor-chomper.PNG (3.15 KiB) Viewed 2111 times
I have also seen it in Run, Prince! Run! (level 3):
floor-chomper_run_prince_run.png
floor-chomper_run_prince_run.png (4.26 KiB) Viewed 2111 times

Re: Another graphical glitch

Posted: May 1st, 2021, 8:15 pm
by dmitrys
Yes, the "redraw_at_char2" function is also responsible for hanging. This is the fix I came up with.

Edit: "get_tile" function cannot be used because changing "curr_tile2" causes a bug when falling down into another room.

Code: Select all

// redraws all tiles except chompers when falling/hanging
// next to a chomper to avoid artifacts under the chomper
void set_redraw_at_char2(short tilepos, byte frames) {
	int tile;
	if (curr_room > 0) {
		tile = curr_room_tiles[tilepos] & 0x1F;
	} else {
		tile = custom->level_edge_hit_tile;
	}
	if (tile != tiles_18_chomper) {
		set_redraw2(tilepos, frames);
	}
}

// seg003:0645
void __pascal far redraw_at_char2() {
	short char_action;
	short char_frame;
	void __pascal (* redraw_func)(short, byte);
	char_action = Char.action;
	char_frame = Char.frame;
	redraw_func = &set_redraw_at_char2;
	// frames 78..80: grab
	if (char_frame < frame_78_jumphang || char_frame >= frame_80_jumphang) {
		// frames 135..149: climb up
		if (char_frame >= frame_137_climbing_3 && char_frame < frame_145_climbing_11) {
			redraw_func = &set_redraw_floor_overlay;
		} else {
			// frames 102..106: fall
			if (char_action != actions_2_hang_climb && char_action != actions_3_in_midair &&
					char_action != actions_4_in_freefall && char_action != actions_6_hang_straight &&
					(char_action != actions_5_bumped || char_frame < frame_102_start_fall_1 || char_frame > frame_106_fall)) {
				return;
			}
		}
	}
	for (tile_col = char_col_right; tile_col >= char_col_left; --tile_col) {
		if (char_action != 2) {
			redraw_func(get_tilepos(tile_col, char_bottom_row), 1);
		}
		if (char_top_row != char_bottom_row) {
			redraw_func(get_tilepos(tile_col, char_top_row), 1);
		}
	}
}