Фикс переворота: отсев тайлов по fore-окну — в ЛОГИЧЕСКИХ координатах

Симптом (нашёл пользователь, ур. 9): в перевёрнутом виде Кид рисуется ПЕРЕД
передней колонной — передние грани его больше не перекрывают.

Причина: окно fore-клипа задаётся прямоугольником уже перевёрнутого спрайта,
то есть в ЭКРАННЫХ координатах, а весь отсев «задевает ли ТАЙЛ окно» считает
позицию тайла из его РЯДА (63*row + …) — величину логическую, от переворота
не зависящую.  Сравнивались разные системы координат, и выбрасывались ровно
те тайлы, что должны лечь поверх персонажа.

Заведена вторая пара границ того же окна — pop_t_fclip_ly0/ly1 (логические,
ставятся в pop_fore_set_clip).  По ней теперь идут ВСЕ отсевы по тайлам:
tile_in_fclip, грубый отсев в pop_blit_b, wp_vis, wpp_fill и отсев кладки в
pop_wall_b, а также выбор диапазона рядов в pop_fore_over_char.  Экранная
пара осталась там, где режется сам блит (он работает с уже перевёрнутым
прямоугольником).

Проверено в MAME: колонна снова перекрывает перевёрнутого Кида.
tests-host 6/6.
This commit is contained in:
2026-08-12 22:39:55 +03:00
parent 755190674c
commit c4dd2c7a87
3 changed files with 35 additions and 11 deletions
+14 -9
View File
@@ -297,13 +297,15 @@ static void wall_rnd_palace(int row, int col)
}
}
/* Прямоугольник [x, x+w) x [ytop, ybot] (ЭКРАННЫЕ) задевает окно fore-клипа?
* Клипа нет — задевает всегда. */
/* Прямоугольник [x, x+w) x [ytop, ybot] задевает окно fore-клипа? Клипа
* нет — задевает всегда. Координаты сюда приходят посчитанными ИЗ РЯДА
* (63*row + …), то есть логические — значит и рамка нужна логическая
* (pop_tile.h, пара fclip_l*): переворот применяется позже, при блите. */
static uint8_t wp_vis(int x, int w, int ytop, int ybot)
{
if (!pop_t_fclip_on) return 1;
return (uint8_t)(x < pop_t_fclip_x1 && x + w > pop_t_fclip_x0 &&
ytop < pop_t_fclip_y1 && ybot >= pop_t_fclip_y0);
ytop < pop_t_fclip_ly1 && ybot >= pop_t_fclip_ly0);
}
/* Декаль кладки: ybot — БЕЗ POP_YOFF (как ждёт pop_wall_b), w/h — реальный
@@ -331,9 +333,9 @@ static void wpp_fill(int x, int ytop, int w, int h, uint8_t colour)
int x2 = x + w - 1, y2 = ytop + h - 1;
if (pop_t_fclip_on) {
if (x < pop_t_fclip_x0) x = pop_t_fclip_x0;
if (ytop < pop_t_fclip_y0) ytop = pop_t_fclip_y0;
if (ytop < pop_t_fclip_ly0) ytop = pop_t_fclip_ly0;
if (x2 >= pop_t_fclip_x1) x2 = pop_t_fclip_x1 - 1;
if (y2 >= pop_t_fclip_y1) y2 = pop_t_fclip_y1 - 1;
if (y2 >= pop_t_fclip_ly1) y2 = pop_t_fclip_ly1 - 1; /* клип ДО переворота */
}
if (pop_t_clip_top && ytop < pop_t_clip_top) ytop = pop_t_clip_top;
if (x < 0) x = 0;
@@ -374,7 +376,7 @@ static void wall_pattern_palace(int row, int col, int which_part)
if (pop_t_fclip_on) {
int x0 = xh * 8;
if (x0 >= pop_t_fclip_x1 || x0 + 32 <= pop_t_fclip_x0 ||
dmy - 59 >= pop_t_fclip_y1 || dby + 1 <= pop_t_fclip_y0)
dmy - 59 >= pop_t_fclip_ly1 || dby + 1 <= pop_t_fclip_ly0)
return;
}
/* Цвета лежат по рядам 0..2; полоса у потолка (row −1) — это ряд 2
@@ -620,8 +622,10 @@ static uint8_t tile_in_fclip(int row, int col)
if (!pop_t_fclip_on) return 1;
x0 = POP_COL_XH[col] * 8;
y0 = POP_YOFF + 63 * row;
/* По ЛОГИЧЕСКОЙ рамке: y0 тайла считается из его ряда и переворотом не
* меняется (см. pop_tile.h про пару fclip_l*). */
return (uint8_t)(x0 < pop_t_fclip_x1 && x0 + 40 > pop_t_fclip_x0 &&
y0 - 8 < pop_t_fclip_y1 && y0 + 70 > pop_t_fclip_y0);
y0 - 8 < pop_t_fclip_ly1 && y0 + 70 > pop_t_fclip_ly0);
}
static void fore_tile(int row, int col) /* передний слой одного тайла */
@@ -891,8 +895,9 @@ void pop_fore_over_char(const pop_char_t *ch, int obj_x, int obj_y,
* достаточно сравнить с границами полос.
* 63r > y0 POP_YOFF 70 и 63r < y1 POP_YOFF + 8 */
{
int a = pop_t_fclip_y0 - POP_YOFF - 70;
int b = pop_t_fclip_y1 - POP_YOFF + 8;
/* Ряды — величина ЛОГИЧЕСКАЯ, поэтому по логической рамке. */
int a = pop_t_fclip_ly0 - POP_YOFF - 70;
int b = pop_t_fclip_ly1 - POP_YOFF + 8;
lo = a < 0 ? 0 : (a < 63 ? 1 : 2);
hi = b > 126 ? 2 : (b > 63 ? 1 : 0);
if (a < 126 && b > 0 && lo <= hi) {