Плиты нижнего ряда пропадали без кадров падения: draw_mob рисует и соседей
Уровень 11 комната 14: плита ряда 2 уходит в комнату снизу на первом же move_loose (спавн y=191 при границе ряда 188), а у нас кусок в чужой комнате не рисовался вовсе — плита исчезала мгновенно. Оригинал (seg007:13E5) рисует его ещё три кадра, выглядывающим из нижней кромки (+192), и симметрично из комнаты сверху (−189). У куска появилась экранная координата draw_y; по ней идут отрисовка, heal, порядок относительно Кида, пометки соседа и оверлей, отбор в проходе — по ней же, а не по комнате. Ссылки вверх/вниз кэшируются. Цена (13/23): зелёная 419 562 -> 427 242, работа 880 272 -> 888 984. Первый вариант стоил втрое дороже (445 248) из-за безусловной пометки по прошлой нарисованной позиции — у куска из соседней комнаты она в 192 пикселях, и объединение растягивалось на весь экран; гейт вернул 18 000. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -3238,3 +3238,69 @@ MAME на резидентном `pop_dbg_trap`; сборщик — `collect_kid
|
||||
`pop_cd[].fpw`. Подозрение на паддинг кадров в атласе
|
||||
(`png_strip_padding_tradeoff`) либо на мой пересчёт переднего края мимо
|
||||
боевого `char_x_forward_edge`. Проверять отдельно.
|
||||
|
||||
---
|
||||
|
||||
<a id="mob-neighbour-room"></a>
|
||||
## MOB-NEIGHBOUR-ROOM. Плиты нижнего ряда пропадали без кадров падения
|
||||
|
||||
**Наблюдение (пользователь, 2026-08-18).** Уровень 11, комната 14: Кид бежит
|
||||
по ряду проваливающихся плит, они трясутся и «падают сразу полностью
|
||||
пропадая, а должен быть промежуточный кадр». Догадка пользователя — «для
|
||||
плит на 2-ом ряду мы рисуем только тряску» — оказалась верной по симптому и
|
||||
почти верной по причине.
|
||||
|
||||
**Корень.** Порт `draw_mob` (seg007:13E5) был неполным. У оригинала кусок
|
||||
рисуется НЕ ТОЛЬКО в своей комнате:
|
||||
|
||||
```c
|
||||
if (curmob.room == drawn_room) { if (curmob.y >= 210) return; }
|
||||
else if (curmob.room == room_B) { if (ABS((sbyte)ypos) >= 18) return; curmob.y += 192; }
|
||||
else if (curmob.room == room_A) { if (curmob.y < 174) return; ypos = curmob.y - 189; }
|
||||
else return;
|
||||
```
|
||||
|
||||
У нас на этом месте стояло `if (!mt_here) return;` — «чужая комната: считаем,
|
||||
но не рисуем».
|
||||
|
||||
Почему страдал ИМЕННО ряд 2: кусок спавнится на `y_loose_land[row+1]`, для
|
||||
ряда 2 это **191**, а граница ряда `y_something[3]` — **188**. То есть на
|
||||
ПЕРВОМ же `move_loose` он уходит в комнату снизу и у нас переставал
|
||||
рисоваться мгновенно. Ряды 0 и 1 летят внутри комнаты, поэтому там всё было
|
||||
видно. Промежуточных кадров ровно три — пока `|y| < 18`.
|
||||
|
||||
**Фикс.** У куска появилась отдельная ЭКРАННАЯ координата `draw_y` (своя
|
||||
комната / +192 из комнаты снизу / −189 из комнаты сверху, `MOB_Y_NONE` =
|
||||
не рисуется). По ней идут отрисовка, `prev_y`/heal, порядок относительно
|
||||
Кида, пометки соседа и оверлей; отбор в проходе отрисовки — по `draw_y`, а не
|
||||
по комнате. Ссылки вверх/вниз кэшируются (иначе `pop_room_link` мапил бы W0
|
||||
каждый кадр).
|
||||
|
||||
Вторым заходом пришлось поправить `mob_overlay_neighbour`: ряд там уже считался
|
||||
по `draw_y`, а габарит спрайта и вызов `pop_mob_overlay_tile` остались по `y` —
|
||||
для куска из соседней комнаты это расходится на 192, и пересечение с габаритом
|
||||
тайла считалось заведомо неверно (порядок переднего слоя).
|
||||
|
||||
**Цена — и урок про то, ЧТО именно дорого.** Замер 13/23:
|
||||
|
||||
| секция | до | первый вариант | после гейта |
|
||||
|---|---:|---:|---:|
|
||||
| работа | 880 272 | 898 578 | **888 984** |
|
||||
| зелёная | 419 562 | 445 248 | **427 242** |
|
||||
| циан | 380 202 | 379 818 | 378 864 |
|
||||
|
||||
Первый вариант метил «фон трогали» по ПРОШЛОЙ нарисованной позиции
|
||||
безусловно. У куска, видимого из соседней комнаты, она отличается от `y` на
|
||||
192 — объединение прямоугольников растягивалось почти на весь экран и тянуло
|
||||
за собой лишние перерисовки. Гейт `m->room != pop_t_room` вернул 18 000 из
|
||||
26 000.
|
||||
|
||||
Я сперва списал рост на клипованный блит (кусок у кромки по определению
|
||||
клипуется, а клипованный путь дороже: 14 088 против 10 422) — замер это
|
||||
опроверг: дело было в пометке. Остаток +7 680 в зелёной (+1,8 %) —
|
||||
собственно отрисовка трёх кадров на плиту; зелёная остаётся ниже растрового
|
||||
кадра 430 000.
|
||||
|
||||
Host-тесты 5106 проверок без расхождений (`pop_room.c` они не линкуют —
|
||||
проверка визуальная, в MAME: уровень 11 комната 14, отделившаяся плита видна
|
||||
три кадра).
|
||||
|
||||
Reference in New Issue
Block a user