PoP roomtest: интерпретатор последовательностей стал общим (Char) — стражи
Пункт 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>
This commit is contained in:
@@ -11,20 +11,10 @@
|
||||
#define POP_KID_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "pop_char.h"
|
||||
|
||||
/* Состояние персонажа (подмножество char_type, types.h). */
|
||||
typedef struct {
|
||||
uint8_t frame;
|
||||
uint8_t x, y;
|
||||
int8_t direction; /* -1 влево, 0 вправо */
|
||||
int8_t curr_col, curr_row;
|
||||
uint8_t action;
|
||||
int8_t fall_x, fall_y;
|
||||
uint8_t repeat;
|
||||
uint16_t curr_seq; /* адрес в seqtbl (база SEQTBL_BASE) */
|
||||
} kid_t;
|
||||
|
||||
extern kid_t Kid;
|
||||
/* Состояние персонажа — общий тип для Кида, стража и Char (pop_char.h). */
|
||||
extern pop_char_t Kid;
|
||||
|
||||
/* Флаг сотрясения (seg006 knock): +1 = KNOCK_UP (ряд выше), -1 = KNOCK_DOWN
|
||||
* (свой ряд). Ставит play_seq, читает/сбрасывает pop_check_knock. */
|
||||
@@ -63,7 +53,22 @@ void kid_tick(void);
|
||||
|
||||
/* play_seq напрямую (для pop_map start_fall — переход в fall-seq в тот же
|
||||
* physics-шаг, как оригинал). */
|
||||
void play_seq(void);
|
||||
void play_seq(void); /* работает с Char — см. pop_kid_play ниже */
|
||||
|
||||
/* Активный персонаж (порт Char, seg006) и его загрузка/выгрузка.
|
||||
* Интерпретатор последовательностей общий для Kid и стража: у них общая
|
||||
* seqtbl, но РАЗНЫЕ таблицы кадров (load_frame выбирает по Char.charid). */
|
||||
extern pop_char_t Char;
|
||||
void pop_loadkid(void);
|
||||
void pop_savekid(void);
|
||||
void pop_loadshad(void);
|
||||
void pop_saveshad(void);
|
||||
|
||||
/* Прокрутить последовательность персонажа целиком (load + play_seq +
|
||||
* save). Звать вместо голого play_seq. */
|
||||
void pop_char_set_seq(uint8_t seq_id); /* seq активного персонажа */
|
||||
void pop_kid_play(void);
|
||||
void pop_guard_play(void);
|
||||
|
||||
/* Поля текущего кадра kid_frames[Kid.frame] (pop_map, без дублирования
|
||||
* таблицы во втором TU). */
|
||||
|
||||
Reference in New Issue
Block a user