PoP roomtest: отрисовка стража в резидент W3 + fore-окклюзия + off-by-one спрайта
Разгрузка W1/W2 перед ИИ стражей (вариант 2 из двух обсуждённых). 1. pop_guard.c разделён по окнам: состояние/логика (Guard, HP, enter, kill, load_frame) остаются в W1/W2 — их обязан видеть банк guards.c; ОТРИСОВКА уехала в новый pop_gdraw.c, собираемый как --w3 (резидент). Правило границы: резидент = только то, что рисует и зовётся исключительно из главного цикла. Кадр стража стал глобальным (pop_gframe): заполняет логика, читает резидент. 2. Страж не окклюдировался передними гранями тайлов — рисовался поверх столба. В оригинале любой Char это запись midtable, а foretable рисуется после всех midtable (draw_tile_fore, seg008:690), т.е. столб перекрывает всех одинаково. Футпринт персонажа выделен из pop_fore_over_kid в char_footprint(), поверх него добавлен pop_fore_over_char() — слой fore + полоса потолка, без оверлеев поз виса/полёта/подъёма (у стража их нет; появятся — портируем redraw_at_char2 общим кодом, а не догадками). 3. Упаковщик стража: тот же off-by-one, что уже ловили у Kid. load_chtab_from_file(id_chtab_5_guard, 750) даёт images[0] = res751, а рисование индексирует images[frame.image] — значит image=N это res(751+N), а не res(750+N). Из-за сдвига frame_166_stand_inactive рисовался как res767 (выпад) вместо res768 (стойка). Проверено в MAME: страж в комнатах 3 и 21 стоит в правильной позе; окклюзия подтверждена патчем Guard.x в живой сессии — при заходе за столб спрайт корректно срезается его передней гранью. Память: _CODE 26 149 -> 25 703, куча W2 805 -> 1245 Б, резидент W3 11 656 -> 12 819 (свободно 3565 Б), банк 1 236/16384 Б. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -7,9 +7,9 @@
|
||||
* линкуются В СТРАНИЦУ БАНКА и снаружи не читаются, поэтому банк —
|
||||
* только код;
|
||||
* - ЛОГИКА (ИИ, боёвка) — в guards.c, собираемом как --bank 1=guards.c;
|
||||
* - ОТРИСОВКА стража — из W1/W2 (рядом с kid_draw): из банка примитивы
|
||||
* libbgi звать можно, но резидент W3 (pop_bg) — нельзя, поэтому слой
|
||||
* фона/окклюзии за стража делает главный цикл.
|
||||
* - ОТРИСОВКА стража — в pop_gdraw.c, РЕЗИДЕНТЕ W3 (--w3): её зовёт
|
||||
* только главный цикл, а из банка резидент недостижим. Так код
|
||||
* отрисовки не занимает дефицитные W1/W2 (куча).
|
||||
*
|
||||
* Поля char_type — как в оригинале (types.h:302), чтобы порт seg005/seg006
|
||||
* ложился один в один.
|
||||
@@ -18,6 +18,7 @@
|
||||
#define POP_GUARD_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "kid_data.h" /* kframe */
|
||||
|
||||
/* charids (types.h:320) — нужны хотя бы для «скелет не убивается читом». */
|
||||
#define CHARID_0_KID 0
|
||||
@@ -45,6 +46,11 @@ extern pop_char_t Guard; /* страж ТЕКУЩЕЙ комнаты
|
||||
extern uint8_t guardhp_curr, guardhp_max;
|
||||
extern int8_t guardhp_delta; /* <0 = в этом кадре отняли HP */
|
||||
|
||||
/* Текущий кадр стража (порт cur_frame для Char): заполняет логика в W1/W2,
|
||||
* читает отрисовка в резиденте W3. image == 255 — рисовать нечего. */
|
||||
extern kframe pop_gframe;
|
||||
void pop_guard_load_frame(void);
|
||||
|
||||
/* Есть ли живой страж в отрисованной комнате (для главного цикла). */
|
||||
uint8_t pop_guard_present(void);
|
||||
|
||||
@@ -58,9 +64,8 @@ void pop_guard_free(void);
|
||||
void pop_guard_enter(uint8_t room);
|
||||
|
||||
/* Нарисовать текущий кадр стража на back-странице (банк GFX_BANK_SPRITE,
|
||||
* как kid_draw) и стереть прошлый (heal). Звать из главного цикла рядом
|
||||
* с kid_draw: рисовать из БАНКА нельзя только резидентом W3, а тут мы в
|
||||
* W1/W2. */
|
||||
* как kid_draw) и стереть прошлый (heal). Реализация — pop_gdraw.c
|
||||
* (резидент W3), поэтому звать ТОЛЬКО из главного цикла, не из банка. */
|
||||
void pop_guard_heal(void);
|
||||
void pop_guard_draw(void);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user