DRAW-CHAR: отрисовка одна на всех Char; разгрузка банка 2 (90.4% -> 72.9%)
DRAW-CHAR. Отрисовка персонажа сведена к одному набору функций над Char — как физика после GUARD-PHYS. В оригинале add_kid_to_objtable (seg008:22F0) и add_guard_to_objtable (seg008:2324) имеют идентичное тело и различаются окном (loadkid/loadshad), набором спрайтов и типом объекта, а redraw_at_char/redraw_at_char2 гейтов по charid не имеют вовсе. pop_gdraw.c -> pop_cdraw.c: pop_char_draw/heal/fore(who), слот POP_CH_KID / POP_CH_OPP; состояние слотов pop_cd[] в _DATA — читается из любого банка без трамплина. Проход окклюзии тоже один (pop_fore_over_char), pop_fore_over_kid больше нет. Починилось само (расхождения, которые и были ценой дублирования): у соперника не было clip_char; у Кида не было клипа полем 192 и ветки брызг «мёртв/падение»; char_width_half СТРАЖА считался по спрайту КИДА. Замер: _CODE 24 881 -> 20 524 (куча 2023 -> 6333), BANK2 -265, итого -3.2 КБ. Проверено пользователем в MAME; циан-полоса профиля подросла — оптимизация заведена отдельной задачей DRAW-COST. MEM-BANK2, шаг 1: общие «листья» слоя фона в РЕЗИДЕНТ (pop_tile.c/.h). Ограничение платформы: писучие данные банка лежат в _DATA и видны всем, а const-таблицы — в странице банка, из другого банка их не прочитать; трамплин же выбирается объявлением, то есть __banked на листе бьёт и по горячим вызывающим (654 такта). W1 замаплено всегда — оттуда обе половины зовут листья прямым call и читают таблицы напрямую. MEM-BANK2, шаг 2: дедуп внутри банка. wall_pattern 808 -> 394 и wall_rnd 786 -> 654: четыре ветки по виду стены отличались только набором кусков и числами в одной серии prandom — сведены к таблицам WP_PARTS и WR_RULE, порядок вызовов prandom сохранён дословно. Заодно: kid_seq_off больше не static const в kid_data.h (230 Б мёртвой копии в каждом из 9 модулей) — генератор pop_extract_kid_data.py отдаёт макро-инициализатор, массив определяет один pop_kid.c. Итог: BANK2 14 815 -> 11 942 (72.9 %, свободно 4442 Б), _CODE 22 556, куча 4301 Б. tests-host зелёные (65/39/53/1723/1); в MAME комната 1 совпала с дорефакторным снимком попиксельно (0 из 227 520), комната 3 — та же раскладка кладки. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# roomtest — ЗАКРЫТЫЕ задачи (архив досок, обновлено 2026-08-07)
|
||||
# roomtest — ЗАКРЫТЫЕ задачи (архив досок, обновлено 2026-08-08)
|
||||
|
||||
Сделанное — с протоколами замеров, граблями и причинами решений. Файл
|
||||
существует не ради истории: половина записей ниже — это ЧИСЛА (сколько тактов
|
||||
@@ -232,6 +232,95 @@ BUG-1 (провал на row 1 при переходе через открыты
|
||||
|
||||
## Отрисовка и память
|
||||
|
||||
<a id="draw-char"></a>
|
||||
### DRAW-CHAR. Отрисовка — ОДНА на всех Char — **СДЕЛАНО И ПРОВЕРЕНО 2026-08-08**
|
||||
|
||||
> **Итог.** Отрисовка персонажа сведена к одному набору функций над `Char`
|
||||
> (`pop_cdraw.c`, банк 4) — как физика после GUARD-PHYS. Было два
|
||||
> независимых куска кода: `kid_draw`/`kid_heal`/`kid_draw_splash`/
|
||||
> `kid_fore_clip*` в резиденте W1 и `pop_guard_draw`/`pop_guard_heal` в
|
||||
> банке 4, каждый со своей математикой кадра, своими heal-прямоугольниками
|
||||
> и своим проходом окклюзии (`pop_fore_over_kid` / `pop_fore_over_char`).
|
||||
>
|
||||
> **Основание в оригинале** (сверено перед кодингом): `add_kid_to_objtable`
|
||||
> (seg008:22F0) и `add_guard_to_objtable` (seg008:2324) имеют ИДЕНТИЧНОЕ
|
||||
> тело и различаются окном (`loadkid`/`loadshad`), набором спрайтов и типом
|
||||
> объекта; `redraw_at_char` / `redraw_at_char2` (seg003:0576/0645) гейтов по
|
||||
> `charid` не имеют вовсе — единственная ветка по персонажу там это
|
||||
> объединение с ПРОШЛЫМ футпринтом у Кида (пометки перерисовки, у нас их
|
||||
> нет). `draw_hurt_splash` (seg006:2003) разводит Кида и остальных ровно
|
||||
> двумя числами: chtab/image и подъём `((charid == kid) << 2) + 11`.
|
||||
|
||||
**Что теперь одно на всех.**
|
||||
|
||||
| Было (два места) | Стало |
|
||||
|---|---|
|
||||
| `kid_draw` / `pop_guard_draw` | `pop_char_draw(who)` |
|
||||
| `kid_heal` / `pop_guard_heal` | `pop_char_heal(who)` |
|
||||
| `kid_draw_splash` / ветка брызг внутри `pop_guard_draw` | `cd_splash` (порт целиком, все три ветки кадров) |
|
||||
| `kid_fore_clip` + `kid_fore_clip_restore` / хвост `pop_guard_draw` | `pop_char_fore(who)` |
|
||||
| `pop_fore_over_kid` / `pop_fore_over_char` | `pop_fore_over_char(ch, …)` |
|
||||
| `kid_fp_*()` / `pop_guard_fp_width()` | `pop_cd[slot]` (структура в `_DATA`, читается из любого банка без трамплина) |
|
||||
| `pop_kid_set_render_dx` | `pop_char_set_render_dx(who, dx)` |
|
||||
|
||||
Слот (`POP_CH_KID` / `POP_CH_OPP`) выбирает ровно то, что различается в
|
||||
оригинале: окно `Char`, набор атласов и кадр (`kidp`+`kid_frame` /
|
||||
`gp`+`pop_gframe`), heal-прямоугольники по страницам дабл-буфера.
|
||||
|
||||
**Что при этом ПОЧИНИЛОСЬ (расхождения, которые и были ценой дублирования).**
|
||||
|
||||
1. **`clip_char` у соперника не было вовсе** — теперь общий (в оригинале он
|
||||
в обоих `add_*_to_objtable`).
|
||||
2. **Клип полем 192 у Кида не было** (`reset_obj_clip`: `obj_clip_bottom =
|
||||
192`): его спрайт рисовался на полосе HP, а следы за него подчищала
|
||||
полоса `pop_room_clip_borders` по флагу `pop_clip_sprite`. Теперь
|
||||
персонаж режется полем, как в оригинале, и `border_dirty` остался только
|
||||
у падающей плиты.
|
||||
3. **У Кида не было ветки брызг «мёртв / падение 106..110»** (`obj_y += 4`)
|
||||
— была только у соперника.
|
||||
4. **`char_width_half` СТРАЖА считался по спрайту КИДА**: `set_char_collision`
|
||||
и `check_spike_below` (`pop_map.c`) читали `kid_fp_width()` безусловно, а
|
||||
`pop_guard_fp_width()` использовался только для порядка отрисовки.
|
||||
Теперь метрики берутся по `charid` активного персонажа (`CD_ACT`).
|
||||
5. **Расширение перебора тайлов окном спрайта** (клинок и брызги уходят за
|
||||
габарит кадра) было только у соперника — теперь общее. Заодно оно
|
||||
перестало быть четырьмя лишними аргументами: окно fore-клипа уже лежит в
|
||||
`pop_bg.c`, и проход читает его сам.
|
||||
|
||||
**Цена / выигрыш (ALLOCS=3000, замер до и после):**
|
||||
|
||||
```
|
||||
было стало дельта
|
||||
_CODE (W1) 24 881 20 524 −4 357 ← куча 2 023 → 6 333 Б (+4 310)
|
||||
BANK2 pop_bg 15 310 15 045 − 265 ← свободно 1 074 → 1 339 Б
|
||||
BANK3 pop_map 8 608 8 713 + 105 (CD_ACT — индекс по charid)
|
||||
BANK4 pop_cdraw 4 625 5 905 +1 280 (сюда переехала отрисовка Кида)
|
||||
итого −3 237
|
||||
```
|
||||
|
||||
То есть слияние двух копий дало ~3.2 КБ, но **главный выигрыш не в банке 2,
|
||||
а в резиденте**: отрисовка Кида уехала из W1 в банк, и куча выросла втрое
|
||||
(2 023 → 6 333 Б). Банку 2 при этом досталось всего +265 Б свободного
|
||||
места — **под [L3-CHOMP](TASKS_OPEN.md#l3-chomp) этого мало**, разгрузку
|
||||
`pop_bg` придётся делать отдельно (свободные номера банков — 7+).
|
||||
|
||||
**Проверено:** `tests-host` — все 5 наборов зелёные, трассы физики не
|
||||
изменились (`[phys] ok: 1723`, тот же эталон; `[char] ok: 65`). В MAME
|
||||
(свежий образ, полный рестарт): уровень 1 — комната 1 (Кид, кладка,
|
||||
факелы, окклюзия колонны), падение на нижний ярус, комната 3 — страж своего
|
||||
цвета с клинком и своей полосой HP, бой и смерть Кида. Артефактов
|
||||
отрисовки и мусора на полосе HP нет.
|
||||
|
||||
**Приёмка пользователем пройдена 2026-08-08.** Прогон вживую: отрисовка
|
||||
персонажей, окклюзия и бой — без регрессий.
|
||||
|
||||
Единственное наблюдение — **циан-полоса профиля (спрайты + fore) выросла**:
|
||||
проход над Кидом теперь расширяется окном спрайта, как раньше только у
|
||||
соперника, то есть перебирает на колонку-другую больше. Решение
|
||||
пользователя: **в пределах допустимого, оптимизация — ОТДЕЛЬНОЙ задачей**
|
||||
([DRAW-COST](TASKS_OPEN.md#draw-cost)).
|
||||
|
||||
|
||||
<a id="clip-1"></a>
|
||||
### CLIP-1. Аудит блитов: где клип не нужен — **СДЕЛАНО 2026-08-01**
|
||||
|
||||
|
||||
Reference in New Issue
Block a user