Фикс переворота: отсев тайлов по 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:
@@ -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)
|
static uint8_t wp_vis(int x, int w, int ytop, int ybot)
|
||||||
{
|
{
|
||||||
if (!pop_t_fclip_on) return 1;
|
if (!pop_t_fclip_on) return 1;
|
||||||
return (uint8_t)(x < pop_t_fclip_x1 && x + w > pop_t_fclip_x0 &&
|
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 — реальный
|
/* Декаль кладки: 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;
|
int x2 = x + w - 1, y2 = ytop + h - 1;
|
||||||
if (pop_t_fclip_on) {
|
if (pop_t_fclip_on) {
|
||||||
if (x < pop_t_fclip_x0) x = pop_t_fclip_x0;
|
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 (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 (pop_t_clip_top && ytop < pop_t_clip_top) ytop = pop_t_clip_top;
|
||||||
if (x < 0) x = 0;
|
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) {
|
if (pop_t_fclip_on) {
|
||||||
int x0 = xh * 8;
|
int x0 = xh * 8;
|
||||||
if (x0 >= pop_t_fclip_x1 || x0 + 32 <= pop_t_fclip_x0 ||
|
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;
|
return;
|
||||||
}
|
}
|
||||||
/* Цвета лежат по рядам 0..2; полоса у потолка (row −1) — это ряд 2
|
/* Цвета лежат по рядам 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;
|
if (!pop_t_fclip_on) return 1;
|
||||||
x0 = POP_COL_XH[col] * 8;
|
x0 = POP_COL_XH[col] * 8;
|
||||||
y0 = POP_YOFF + 63 * row;
|
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 &&
|
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) /* передний слой одного тайла */
|
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 */
|
* 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);
|
lo = a < 0 ? 0 : (a < 63 ? 1 : 2);
|
||||||
hi = b > 126 ? 2 : (b > 63 ? 1 : 0);
|
hi = b > 126 ? 2 : (b > 63 ? 1 : 0);
|
||||||
if (a < 126 && b > 0 && lo <= hi) {
|
if (a < 126 && b > 0 && lo <= hi) {
|
||||||
|
|||||||
@@ -34,6 +34,14 @@ pop_rnd_t pop_t_seed;
|
|||||||
|
|
||||||
int pop_t_clip_top;
|
int pop_t_clip_top;
|
||||||
int pop_t_fclip_x0, pop_t_fclip_y0, pop_t_fclip_x1, pop_t_fclip_y1;
|
int pop_t_fclip_x0, pop_t_fclip_y0, pop_t_fclip_x1, pop_t_fclip_y1;
|
||||||
|
/* ТО ЖЕ ОКНО В ЛОГИЧЕСКИХ (неперевёрнутых) координатах. Экранная пара нужна
|
||||||
|
* для клипа самого блита — он режет уже перевёрнутый прямоугольник; а вот
|
||||||
|
* ОТСЕВ ТАЙЛОВ идёт по позиции тайла в комнате (63*row + …), и она от
|
||||||
|
* переворота не зависит. Пока пара была одна, при pop_upside отсев сравнивал
|
||||||
|
* логический y тайла с зеркальным окном и выбрасывал именно те тайлы, что
|
||||||
|
* должны лечь ПОВЕРХ персонажа: передняя грань колонны переставала рисоваться
|
||||||
|
* и Кид оказывался перед ней (найдено пользователем на уровне 9). */
|
||||||
|
int pop_t_fclip_ly0, pop_t_fclip_ly1;
|
||||||
uint8_t pop_t_fclip_on;
|
uint8_t pop_t_fclip_on;
|
||||||
uint8_t pop_t_bake_rest;
|
uint8_t pop_t_bake_rest;
|
||||||
|
|
||||||
@@ -332,8 +340,8 @@ void pop_blit_b(atlas_t *a, uint8_t idx, int x, int ybottom)
|
|||||||
* atlas_image, ни за map/unmap. */
|
* atlas_image, ни за map/unmap. */
|
||||||
if (pop_t_fclip_on &&
|
if (pop_t_fclip_on &&
|
||||||
(x >= pop_t_fclip_x1 || x + 64 <= pop_t_fclip_x0 ||
|
(x >= pop_t_fclip_x1 || x + 64 <= pop_t_fclip_x0 ||
|
||||||
ybottom + POP_YOFF + 1 <= pop_t_fclip_y0 ||
|
ybottom + POP_YOFF + 1 <= pop_t_fclip_ly0 ||
|
||||||
ybottom + POP_YOFF - 64 >= pop_t_fclip_y1))
|
ybottom + POP_YOFF - 64 >= pop_t_fclip_ly1))
|
||||||
return;
|
return;
|
||||||
img = (const uint8_t *)atlas_image(a, idx);
|
img = (const uint8_t *)atlas_image(a, idx);
|
||||||
gfx_w0_map(a->page);
|
gfx_w0_map(a->page);
|
||||||
@@ -476,6 +484,12 @@ void pop_fore_set_clip(int x, int y, int w, int h)
|
|||||||
{
|
{
|
||||||
pop_t_fclip_x0 = x; pop_t_fclip_y0 = y;
|
pop_t_fclip_x0 = x; pop_t_fclip_y0 = y;
|
||||||
pop_t_fclip_x1 = x + w; pop_t_fclip_y1 = y + h;
|
pop_t_fclip_x1 = x + w; pop_t_fclip_y1 = y + h;
|
||||||
|
if (pop_upside) { /* вернуть окно в неперевёрнутый вид */
|
||||||
|
pop_t_fclip_ly0 = 2 * POP_YOFF + POP_PLAYFIELD_H - (y + h);
|
||||||
|
pop_t_fclip_ly1 = 2 * POP_YOFF + POP_PLAYFIELD_H - y;
|
||||||
|
} else {
|
||||||
|
pop_t_fclip_ly0 = y; pop_t_fclip_ly1 = y + h;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ряд 0 комнаты СНИЗУ (fg-коды) — нужен draw_tile_topright/floorright, когда
|
/* Ряд 0 комнаты СНИЗУ (fg-коды) — нужен draw_tile_topright/floorright, когда
|
||||||
|
|||||||
@@ -70,6 +70,11 @@ extern int pop_t_clip_top;
|
|||||||
* кадра при бюджете 430 000. С окном большинство кусков отсекается целиком,
|
* кадра при бюджете 430 000. С окном большинство кусков отсекается целиком,
|
||||||
* остальные режутся до пересечения. */
|
* остальные режутся до пересечения. */
|
||||||
extern int pop_t_fclip_x0, pop_t_fclip_y0, pop_t_fclip_x1, pop_t_fclip_y1;
|
extern int pop_t_fclip_x0, pop_t_fclip_y0, pop_t_fclip_x1, pop_t_fclip_y1;
|
||||||
|
/* Та же рамка в ЛОГИЧЕСКИХ координатах (без переворота). Всё, что решает
|
||||||
|
* «задевает ли ТАЙЛ окно», обязано сравнивать по ней: позиция тайла в
|
||||||
|
* комнате от переворота не зависит. Экранная пара — только для клипа
|
||||||
|
* блита, который режет уже перевёрнутый прямоугольник. */
|
||||||
|
extern int pop_t_fclip_ly0, pop_t_fclip_ly1;
|
||||||
extern uint8_t pop_t_fclip_on;
|
extern uint8_t pop_t_fclip_on;
|
||||||
|
|
||||||
/* ---- Таблица тайлов (piece, seg008.c:27) ---------------------------- */
|
/* ---- Таблица тайлов (piece, seg008.c:27) ---------------------------- */
|
||||||
|
|||||||
Reference in New Issue
Block a user