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:
@@ -442,7 +442,7 @@ static void land(void)
|
||||
if (deadly || take_hp(1)) { /* 3+ этажа или последнее HP */
|
||||
take_hp(100);
|
||||
kid_set_seq(SEQ_22_CRUSHED);
|
||||
play_seq();
|
||||
pop_kid_play();
|
||||
determine_col();
|
||||
pop_kid_dead = 1;
|
||||
return;
|
||||
@@ -451,7 +451,7 @@ static void land(void)
|
||||
}
|
||||
Kid.fall_x = Kid.fall_y = 0;
|
||||
kid_set_seq(seq);
|
||||
play_seq();
|
||||
pop_kid_play();
|
||||
determine_col();
|
||||
}
|
||||
|
||||
@@ -465,7 +465,7 @@ static void start_fall(void)
|
||||
else if (frame == 44) seq = SEQ_21_FALL_RUNJUMP;
|
||||
else seq = SEQ_7_FALL; /* frame 9 + stand/step/crouch */
|
||||
kid_set_seq(seq);
|
||||
play_seq();
|
||||
pop_kid_play();
|
||||
determine_col();
|
||||
/* Проверки «упал в стену» — ТОЛЬКО пока персонаж В комнате (curr_row<=2).
|
||||
* Ниже нижнего ряда (curr_row=3 после inc — падение сквозь дыру loose)
|
||||
@@ -531,7 +531,7 @@ static void check_grab(void)
|
||||
Kid.y = (uint8_t)pop_y_land[Kid.curr_row + 1];
|
||||
Kid.fall_y = 0;
|
||||
kid_set_seq(SEQ_15_GRAB_LEDGE_MIDAIR);
|
||||
play_seq();
|
||||
pop_kid_play();
|
||||
determine_col();
|
||||
grab_timer = 12; /* (TODO: sound grab) */
|
||||
}
|
||||
@@ -886,7 +886,7 @@ static void bumped_fall(void)
|
||||
Kid.fall_x = 0;
|
||||
} else {
|
||||
kid_set_seq(SEQ_45_BUMPFALL); /* (TODO: bumped_sound) */
|
||||
play_seq();
|
||||
pop_kid_play();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -920,7 +920,7 @@ static void bumped_floor(void)
|
||||
kid_set_seq(SEQ_46_HARDBUMP);
|
||||
else
|
||||
kid_set_seq(SEQ_47_BUMP); /* (TODO: bumped_sound) */
|
||||
play_seq();
|
||||
pop_kid_play();
|
||||
}
|
||||
|
||||
/* check_bumped (seg004): если передний край ЗАШЁЛ за грань стены — выровнять
|
||||
@@ -1157,14 +1157,14 @@ static void fell_on_your_head(void)
|
||||
pop_kid_hurt = 1; /* hitp_delta<0 → draw_hurt_splash */
|
||||
if (take_hp(1)) {
|
||||
kid_set_seq(SEQ_22_CRUSHED);
|
||||
play_seq();
|
||||
pop_kid_play();
|
||||
determine_col();
|
||||
pop_kid_dead = 1;
|
||||
} else if (frame != FRAME_109_CROUCH) {
|
||||
if (get_tile_behind_char() == TILE_EMPTY)
|
||||
Kid.x = (uint8_t)char_dx_forward(-2);
|
||||
kid_set_seq(SEQ_52_LOOSE_FELL_ON_KID);
|
||||
play_seq();
|
||||
pop_kid_play();
|
||||
determine_col();
|
||||
}
|
||||
}
|
||||
@@ -1430,7 +1430,7 @@ static void spiked(uint8_t tilepos)
|
||||
Kid.fall_y = 0;
|
||||
take_hp(100); /* (TODO: sound_48_spiked) */
|
||||
kid_set_seq(SEQ_51_SPIKED);
|
||||
play_seq();
|
||||
pop_kid_play();
|
||||
determine_col();
|
||||
pop_kid_dead = 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user