8bbc6b4d07
Пункт 1 плана стражей. play_seq был прибит к Киду, поэтому страж стоял на захардкоженном кадре 166. Теперь как в оригинале: интерпретатор работает с АКТИВНЫМ персонажем Char, а вокруг стоят loadkid/savekid и loadshad/saveshad (порт seg006:809..825). Почему копия, а не указатель: так в оригинале, и на Z80 это быстрее — горячий цикл обращается к глобалу абсолютной адресацией, а 16-байтовое копирование платится один раз на переключение персонажа, тогда как указатель дал бы индексную адресацию в каждом обращении. Сопутствующее: - kid_t и pop_char_t слиты в один pop_char_t (pop_char.h): в оригинале char_type один на всех, и без этого общий интерпретатор невозможен. Kid получил поля room/charid/sword/alive — они и так нужны боёвке; - load_frame выбирает таблицу кадров по Char.charid (у стража своя, frame_tbl_guard с индексом frame + add_frame − 149, seg006:0293); - cur_frame разведён на два кэша: страж тикает ПОСЛЕ Кида, и без этого kid_draw брал бы кадр стража. savekid/saveshad раскладывают кадр по своему персонажу; - kid_set_seq пишет ИМЕННО Kid (его зовут pop_ctrl/pop_map вне окна Char, иначе loadkid затёр бы), для окна Char добавлен pop_char_set_seq — порт seqtbl_offset_char; - в pop_map 9 голых play_seq() заменены на pop_kid_play() (load+play+save); - страж входит в комнату через seq_77_guard_stand_inactive (seg002:0208), а не через прибитый кадр. Проверено в MAME: Kid бегает и упирается в стену как прежде, в комнате 12 плиты проваливаются со щебнем (правка задела 9 вызовов play_seq в физике), страж в комнате 3 рисуется в той же позе, но теперь curr_seq=0x19A9 и charid=2 — кадр получен прокруткой последовательности, а не константой. Бюджет (комната 3, 150 кадров): 380 292..381 282 тактов против 370 140..371 160 до правки, то есть +10 150 (+2.7 %). Основное — не копии Char, а то, что страж теперь реально крутит интерпретатор каждый кадр, а раньше стоял замороженным. 0.887 кадра, запас 48 718. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
27 lines
1.6 KiB
C
27 lines
1.6 KiB
C
/*
|
|
* guards.c — ЛОГИКА стража, собирается в БАНК (--bank 1=guards.c, окно W3).
|
|
*
|
|
* Правила банка (проверено пробником tests/w3bankgfx):
|
|
* - состояние держим в W1/W2 (pop_guard.c): статики банка линкуются в
|
|
* страницу банка и снаружи не читаются;
|
|
* - звать можно W1/W2-код (pop_map, pop_kid, pop_geom, libc, примитивы
|
|
* libbgi) — скобка _bgi_begin/_bgi_end возвращает страницу БАНКА;
|
|
* - звать НЕЛЬЗЯ резидент W3 (pop_bg) — ни напрямую, ни транзитивно:
|
|
* пока исполняется банк, резидентной страницы в адресном пространстве
|
|
* нет. Поэтому фон/окклюзию за стража рисует главный цикл.
|
|
*
|
|
* Сейчас — каркас: тик есть, ИИ и боёвка (порт seg005 control_guard*,
|
|
* seg004 fight/collision) добавляются сюда.
|
|
*/
|
|
#include "pop_guard.h"
|
|
#include "pop_kid.h"
|
|
|
|
void pop_guard_tick(void) __banked
|
|
{
|
|
if (Guard.charid == 0) return; /* стража в комнате нет */
|
|
/* Анимация: та же seqtbl, что у Кида, но своя таблица кадров —
|
|
* выбирается по Char.charid внутри load_frame (seg006:0293). */
|
|
pop_guard_play();
|
|
/* TODO: порт control_guard/fight (seg005/seg004) — состояние в Guard. */
|
|
}
|