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:
@@ -14,17 +14,61 @@ odd-pixel арифметика `char_x`, подстановка тайла на
|
||||
починена кодом ещё в июле, список просто отстал — чем именно закрыта каждая,
|
||||
расписано в [`bug_closed.md`](bug_closed.md)).
|
||||
|
||||
**Открытых багов сейчас нет** — только две незакрытые оптимизации и
|
||||
незаконченная ревизия комнат:
|
||||
|
||||
| ID | что | тип |
|
||||
|----|-----|-----|
|
||||
| [BUG-DOOR-CLIP](#bug-door-clip) | Кид не обрезается правым косяком двери уровня | Medium |
|
||||
| [T-1](#t-1) | пики перерисовываются безусловно | оптимизация |
|
||||
| [T-2](#t-2) | Кид перерисовывается в покое | оптимизация |
|
||||
| [обход 24 комнат](#обход-всех-24-комнат-уровня-1) | таблица заполнена на 5 строк из 24 | ревизия |
|
||||
|
||||
Это НЕ значит «багов нет» — значит, что известные найдены и закрыты, а
|
||||
следующая порция придёт из обхода 24 комнат и сквозного прохождения (L1-PASS).
|
||||
---
|
||||
|
||||
<a id="bug-door-clip"></a>
|
||||
## BUG-DOOR-CLIP. Подъём по лестнице двери уровня: нет обрезки по правому косяку — **Medium**
|
||||
|
||||
**Симптом (2026-08-01, найден пользователем сразу после L1-EXIT):** при
|
||||
подъёме по лестнице за дверью уровня (seq_70, кадры 224..228) силуэт Кида
|
||||
вылезает ПРАВЕЕ правого косяка проёма — должен уходить за него. По ВЫСОТЕ
|
||||
обрезка корректна.
|
||||
|
||||
**Причина — недопортированная половина `clip_char`** (seg006:1231). Для
|
||||
кадров двери уровня оригинал ставит ДВА клипа, а мы портировали только
|
||||
первый:
|
||||
|
||||
```c
|
||||
if (frame >= frame_224_exit_stairs_8 && frame < 229) {
|
||||
obj_clip_top = leveldoor_ybottom + 1; // ЕСТЬ (pop_clip_char_top)
|
||||
obj_clip_right = leveldoor_right; // НЕТ
|
||||
}
|
||||
```
|
||||
|
||||
`leveldoor_right = (draw_xh << 3) + 48` считается в `draw_leveldoor`
|
||||
(seg008:1D29) от колонки ЛЕВОЙ половины двери; для palace-уровней (+8,
|
||||
`tbl_level_type`) — на уровне 1 не применяется.
|
||||
|
||||
Обратить внимание: комментарий в SDLPoP говорит «frames 217..228», а КОД
|
||||
проверяет `>= frame_224_exit_stairs_8`, то есть **224..228**. Портировать по
|
||||
коду.
|
||||
|
||||
**Чего не хватает в движке:** обрезки СПРАВА у колоночного блита.
|
||||
`gfx_blit_cols_part` (libbgi) умеет только обрезку сверху (`skip`/`rows`) плюс
|
||||
клип по краю ЭКРАНА (`w = _bgi_maxx + 1 - x`). Для column-major спрайта
|
||||
обрезка справа — это ровно уменьшение `w`, то есть внутри ядра она уже есть,
|
||||
не хватает способа задать её снаружи.
|
||||
|
||||
**План (не начат):**
|
||||
1. libbgi: тело `gfx_blit_cols_part` вынести в вариант с ограничением
|
||||
ширины (напр. `gfx_blit_cols_part_w(..., uint8_t maxw)`), а нынешнюю
|
||||
функцию оставить тонкой обёрткой — тем же приёмом, каким `gfx_blit_cols`
|
||||
уже обёрнут вокруг `gfx_blit_cols_part`. Флип тут не мешает: в кадрах
|
||||
двери направление всегда dir_FF_left, то есть flip=0.
|
||||
2. PoP: `pop_clip_char_top` дополнить правым клипом (или завести
|
||||
`pop_clip_char_right`), считать `leveldoor_right` от колонки двери.
|
||||
3. `make size-check` (трогаем libbgi) + проверка стоп-кадром в MAME:
|
||||
поймать кадр 224..228 клавишей `1` и сверить кромку.
|
||||
|
||||
**Пока не починено, дефект косметический** — вход на следующий уровень
|
||||
работает.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user