PoP roomtest: блеск лежащего меча, клинок в руке, вспышка фона
Три расхождения с оригиналом на сцене подъёма меча (комната 15): 1. Лежащий меч не блестел. Порт animate_sword (seg007:0425) + start_anim_sword (seg007:087C): при входе в комнату тайлу даётся случайная фаза (prandom & 0x1F), каждый кадр счётчик вниз, на 0 — новый период 0x28..0x67. Кадр блеска рисуется РОВНО на modif==1 ((modif==1)+10 в draw_tile), т.е. одиночная вспышка раз в 40..103 тика. Перерисовка тайла — по смене видимого кадра, схемой кнопки (текущая страница сразу, вторая через rest-цикл). 2. В кадрах «нашёл меч» клинка не было видно. Порт add_sword_to_objtable (seg006:1798): клинок — ОТДЕЛЬНЫЙ спрайт chtab_0 поверх Kid со смещением из sword_tbl. Смещения в ЭКРАННЫХ пикселях (оригинал применяет их после calc_screen_x_coord), поэтому берём уже масштабированный obj_x. Из таблицы взяты только строки 35..42 (кадры 229..236) — бой не портирован. Новый атлас sword.atl (8 спрайтов, 1.6 КБ) + палитра chtab_0 в слотах 0x80..0x8F. Прямоугольник heal расширяется объединением с клинком, иначе он оставлял след за габаритом Kid. 3. Не было вспышки фона. do_flash = set_bg_attr(0, color) — оригинал подменяет НУЛЕВУЮ запись палитры, вспыхивает всё чёрное поле экрана; proc_get_object ставит flash_color=14, flash_time=8. У нас gfx_pal_set на обе страницы. ВАЖНО: вызов gfx_pal_set(0,0,0,0,0) пятью литералами ломает SDCC 4.5 (эмитит невалидный `ld hl, a`) — обёрнуто в функцию с параметрами. Попутно: TROBS_MAX 24 -> 30 (как в оригинале) + при входе в комнату из списка выбрасываются «декоративные» trob ДРУГИХ комнат (факелы/зелья/ меч анимируются только в отрисованной). Без этого отладочный обход всех 24 комнат забивал список, и новые анимации молча не заводились. Проверено в MAME: блеск (брейк на редрое тайла срабатывает), клинок в руке виден, фон вспыхивает жёлтым. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -89,8 +89,19 @@ static uint8_t room_label_redraw;
|
||||
#define OVR_MAX 8
|
||||
static uint8_t ovr_room[OVR_MAX], ovr_pos[OVR_MAX], ovr_tile[OVR_MAX], ovr_cnt;
|
||||
|
||||
/* Поднятый предмет (меч): tilepos и счётчик «запечь пол» по страницам. */
|
||||
static uint8_t item_pos, item_bake;
|
||||
/* Поднятый предмет (меч): tilepos и счётчик «запечь пол» по страницам.
|
||||
* flash_on — вспышка фона активна (нулевая запись палитры подменена). */
|
||||
static uint8_t item_pos, item_bake, flash_on;
|
||||
|
||||
/* Подмена НУЛЕВОЙ записи палитры на обеих страницах (do_flash/set_bg_attr).
|
||||
* Через функцию с параметрами, а не пятью литералами в месте вызова: на
|
||||
* gfx_pal_set(0,0,0,0,0) SDCC 4.5 выдаёт невалидный `ld hl, a`
|
||||
* (см. .sprinter-cc-roomtest/roomtest.asm) и ассемблер падает. */
|
||||
static void flash_bg(uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
gfx_pal_set(0, 0, r, g, b);
|
||||
gfx_pal_set(1, 0, r, g, b);
|
||||
}
|
||||
|
||||
static void add_tile_override(uint8_t room, uint8_t pos, uint8_t tile)
|
||||
{
|
||||
@@ -191,6 +202,7 @@ int main(void)
|
||||
puts("pop_bg_load failed");
|
||||
return 1;
|
||||
}
|
||||
pop_sword_load(); /* меч в руке (без него кадры 229+ без клинка) */
|
||||
if (pop_kid_load(28) != 0) { /* ВСЕ страницы: бег+стоп+разворот+присед+прыжок */
|
||||
puts("kid atlas load failed");
|
||||
return 1;
|
||||
@@ -386,12 +398,27 @@ int main(void)
|
||||
item_pos = (uint8_t)(pop_item_taken - 1);
|
||||
item_bake = 2; /* запечь на ОБЕИХ страницах */
|
||||
add_tile_override(cur_room, item_pos, TILE_FLOOR);
|
||||
pop_add_trob(cur_room, item_pos, -1); /* меч убран — блеска больше нет */
|
||||
pop_item_taken = 0;
|
||||
}
|
||||
if (item_bake) { /* стереть спрайт меча из фона страницы */
|
||||
pop_floor_bake(item_pos / 10, item_pos % 10);
|
||||
item_bake--;
|
||||
}
|
||||
if (pop_flash_time) {
|
||||
/* do_flash (seg001:0908) = set_bg_attr(0, color): оригинал подменяет
|
||||
* НУЛЕВУЮ запись палитры — вспыхивает всё чёрное поле экрана.
|
||||
* У нас то же самое, но правим обе страницы (у каждой своя
|
||||
* палитра). color_14_brightyellow = VGA 14. */
|
||||
if (!flash_on) {
|
||||
flash_bg(255, 255, 85); /* color_14_brightyellow */
|
||||
flash_on = 1;
|
||||
}
|
||||
if (--pop_flash_time == 0) {
|
||||
flash_bg(0, 0, 0); /* вернуть чёрный фон */
|
||||
flash_on = 0;
|
||||
}
|
||||
}
|
||||
io_border = 4; /* зеленый */
|
||||
update_kid_render_dx(); /* straddle: смещение спрайта, если kid_room≠cur_room */
|
||||
kid_draw(); /* нарисовать новый кадр (детект выхода за поле) */
|
||||
|
||||
Reference in New Issue
Block a user