L1-START + L1-EXIT: старт по данным уровня и выход через дверь уровня
L1-START. Старт и оба рестарта (смерть, выпадение из уровня) сведены в pop_start_level() — порт start_level + do_startpos + set_start_pos (seg003). Комната/тайл/направление берутся из pop_level_start_*, направление инвертируется (~start_dir), поза входа — из tbl_entry_pose: у уровня 1 это падение внутрь (seq_7_fall) плюс нажатие кнопки room5(0,2), то самое, что захлопывает решётку за спиной. Жёсткие START_ROOM/COL/ROW убраны. Проверено в MAME: старт даёт room 1, col 0, падение на row 1 — как по данным. L1-EXIT. Ветка двери уровня из up_pressed + go_up_leveldoor (seg005:0482/ 0574): тайлы и геометрия — pop_leveldoor_enter() в pop_map, последовательность seq_70 — в pop_ctrl. Опкод 0xF1 END_LEVEL в play_seq инкрементит pop_next_level (порт next_level), главный цикл по нему перезапускает уровень — ровно та точка, куда levels_plan §2.2 подключит загрузку уровня 2. Открытость двери проверяется по modifier >= 42 (ветка fix_exit_door), а не по ванильному leveldoor_open: иначе можно войти в ещё ползущую створку. Отдельно стоило разбора: go_up_leveldoor сначала писал Char.x/Char.direction, и оба присваивания молча терялись — окно Char вокруг диспетчера возвращает назад только curr_seq и sword (pop_savekid_state). Направление оставалось «вправо», а все DX в seq_70 отрицательные, поэтому Кид уходил ИЗ проёма влево (поймано стоп-кадром). Геометрию персонажа в этом порте меняет pop_map, пишет в Kid — как pop_down_action и pop_jump_up_seq. Известный остаток — BUG-DOOR-CLIP в bug_list.md: нет обрезки силуэта правым косяком проёма (недопортирован obj_clip_right в clip_char); нужен вариант колоночного блита с ограничением ширины. ROOMNAV пока оставлен включённым — он нужен, чтобы попадать в комнату 9 для этой работы. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -23,6 +23,13 @@ pop_char_t Kid;
|
||||
* в play_seq, потребляется pop_check_knock (pop_map) — трясёт loose-полы. */
|
||||
int8_t knock;
|
||||
|
||||
/* Порт глобала next_level: seqtbl-команда END_LEVEL инкрементит его в конце
|
||||
* seq_70 (подъём по лестнице за дверью уровня), а главный цикл сравнивает с
|
||||
* текущим уровнем и грузит следующий. Счётчик, а не флаг — ровно как в
|
||||
* оригинале, чтобы читы «следующий/предыдущий уровень» (levels_plan.md §4)
|
||||
* легли сюда же без переделки. */
|
||||
uint8_t pop_next_level;
|
||||
|
||||
|
||||
/* ---- Атласы Kid (прямая адресация image>>3) ------------------------ */
|
||||
#define KID_MAXPAGES 28
|
||||
@@ -418,7 +425,12 @@ void play_seq(void)
|
||||
case 0xF2: /* SOUND — потребить 1 байт */
|
||||
Char.curr_seq++;
|
||||
break;
|
||||
case 0xF1: /* END_LEVEL */
|
||||
case 0xF1: /* END_LEVEL: seq_70 доиграл — уровень пройден.
|
||||
* В оригинале это `++next_level`, а главный цикл
|
||||
* (play_level_2, seg003:0386) выходит, когда next_level
|
||||
* разошёлся с current_level. У нас так же: счётчик, а
|
||||
* решение — снаружи (roomtest.c). */
|
||||
pop_next_level++;
|
||||
break;
|
||||
case 0xF3: /* GET_ITEM: аргумент 1 — применить эффект предмета
|
||||
* (порт play_seq -> proc_get_object, seg006) */
|
||||
|
||||
Reference in New Issue
Block a user