applications/PoP/roomtest: fore-слой поверх Kid (передние тайлы)
Порт SDLPoP seg003 redraw_at_char + seg008 set_char_collision: после kid_draw передний слой (fore_id = foretable-кусок) тайлов ФУТПРИНТА спрайта Kid перерисовывается ПОВЕРХ него — то, что по изометрии перед персонажем (передние грани колонн/ворот/большой колонны/щебня). Стены и факелы имеют fore_id=0 → остаются сзади (в статическом фоне). - pop_bg: pop_fore_over_kid(obj_x,obj_y,w,h,dir) — считает футпринт (char_x_left/right, col_from_x, y_to_row_mod4) рядов top..bottom × колонок left..right (≤2×2=4 тайла) и рисует fore_id каждого в GFX_BANK_SPRITE (видео-ОЗУ; kid_heal восстановит из теневого фона, fore в нём запечён pop_room_draw). - pop_kid: kid_fp_obj_x/y/width/height — метрики последнего кадра (obj_x ЛОГИЧЕСКАЯ, до ×8/7) для футпринта. - roomtest: вызов pop_fore_over_kid после kid_draw. Проверено в MAME: Kid, идя влево мимо колонны под навесом (row1 col3), корректно уходит ЗА её переднюю грань (скрывается) и выходит с другой стороны; задние колонны/факелы остаются сзади. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -392,3 +392,54 @@ void pop_room_draw(uint8_t room_num,
|
||||
draw_tile(row, col);
|
||||
gfx_set_bank(GFX_BANK_NORMAL);
|
||||
}
|
||||
|
||||
/* ---- fore-over-Kid (порт seg003 redraw_at_char + seg008 set_char_collision) --
|
||||
* Передний слой (fore_id = foretable-кусок) тайлов ФУТПРИНТА спрайта Kid
|
||||
* — рядов top..bottom × колонок left..right (<= 2×2 = 4 тайла) — рисуется
|
||||
* ПОВЕРХ Kid: то, что по изометрии перед ним (передние грани колонн/ворот/
|
||||
* большой колонны/щебня). Стены и факелы имеют fore_id=0 → остаются сзади.
|
||||
* Рисуем в GFX_BANK_SPRITE (видео-ОЗУ, 0xFF прозрачен); kid_heal восстановит
|
||||
* из теневого фона (fore в нём уже запечён pop_room_draw). obj_x — ЛОГИЧЕСКАЯ
|
||||
* X кадра Kid (до ×8/7), obj_y — низ спрайта, w/h — размер, dir — направление. */
|
||||
static int8_t col_from_x(int xpos) /* get_tile_div_mod: колонка (58/14) */
|
||||
{
|
||||
int x = xpos - 58;
|
||||
int xh = x / 14;
|
||||
if (x % 14 < 0) xh--; /* округление вниз для отрицательных */
|
||||
return (int8_t)xh;
|
||||
}
|
||||
|
||||
static int8_t y_to_row(int y) /* y_to_row_mod4 (TILE_SIZEY=63) */
|
||||
{
|
||||
return (int8_t)((y + 60) / 63 % 4 - 1);
|
||||
}
|
||||
|
||||
static void fore_tile(int row, int col) /* fore одного тайла, если fore_id≠0 */
|
||||
{
|
||||
uint8_t code = tile_code(row, col);
|
||||
const piece *t = &tile_table[code];
|
||||
if (t->fore_id) {
|
||||
int x = COL_XH[col] * 8;
|
||||
int dmy = 63 * row + 62;
|
||||
fore_b(t->fore_id, t->fore_x * 8 + x, t->fore_y + dmy);
|
||||
}
|
||||
}
|
||||
|
||||
void pop_fore_over_kid(int obj_x, int obj_y, uint16_t w, uint16_t h, int8_t dir)
|
||||
{
|
||||
int wh = (int)((w + 1) >> 1); /* char_width_half */
|
||||
int xl = obj_x / 2 + 58; /* char_x_left (58-база) */
|
||||
int xr;
|
||||
int8_t cL, cR, rT, rB, r, c;
|
||||
if (dir >= 0) xl -= wh; /* лицом вправо: левый край внутрь */
|
||||
xr = xl + wh;
|
||||
cL = col_from_x(xl); if (cL < 0) cL = 0; else if (cL > 9) cL = 9;
|
||||
cR = col_from_x(xr); if (cR < 0) cR = 0; else if (cR > 9) cR = 9;
|
||||
rB = y_to_row(obj_y); if (rB < 0) rB = 0; else if (rB > 2) rB = 2;
|
||||
rT = y_to_row(obj_y - (int)h + 1); if (rT < 0) rT = 0; else if (rT > 2) rT = 2;
|
||||
gfx_set_bank(GFX_BANK_SPRITE); /* видео-ОЗУ, heal восстановит */
|
||||
for (r = rT; r <= rB; r++)
|
||||
for (c = cL; c <= cR; c++)
|
||||
fore_tile(r, c);
|
||||
gfx_set_bank(GFX_BANK_NORMAL);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user