From f47d79ded8e79a72798645f22eafb9463d26fb72 Mon Sep 17 00:00:00 2001 From: Alexander Petrov Date: Wed, 19 Aug 2026 16:42:54 +0300 Subject: [PATCH] =?UTF-8?q?guard=5Fover=5Fkid=20=E2=80=94=20=D1=82=D0=BE?= =?UTF-8?q?=D0=BB=D1=8C=D0=BA=D0=BE=20=D0=BA=D0=BE=D0=B3=D0=B4=D0=B0=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=B3=D0=BE-=D1=82=D0=BE=20=D1=80=D0=B8=D1=81?= =?UTF-8?q?=D1=83=D0=B5=D0=BC:=20=D0=BC=D0=B8=D0=BD=D1=83=D1=81=2014=20118?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Разложил остаток цианной фазы (44 007 на трёх вызовах): pop_loose_mob_draw 978 гейт mobs_live работает guard_over_kid 14 424 трамплин в банк 8 + два objtile_at_char pop_char_skip_mask 28 605 трамплин в банк 4 + два cd_quiet guard_over_kid отвечает на вопрос «кто рисуется поверх кого», а он не имеет смысла, когда не рисуется никто. Перенёс вызов ПОСЛЕ pop_char_skip_mask и сделал условным: при skip == 3 оба слота тихие, и порядок не нужен. Перестановка безопасна: обе функции только читают, и читают разное — skip_mask снимок cd_sig, guard_over_kid габариты pop_cd прошлого кадра. Замер 11/15, лёгкая позиция: циан 55 257 -> 41 280, работа кадра 456 780 -> 442 662. Проверено в MAME: статика чистая, в бою (Кид сближается и бьёт стража) персонажи перекрываются правильно, порядок не сломался. Co-Authored-By: Claude Opus 5 --- applications/PoP/roomtest/roomtest.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/applications/PoP/roomtest/roomtest.c b/applications/PoP/roomtest/roomtest.c index 9451eaf..c6812fc 100644 --- a/applications/PoP/roomtest/roomtest.c +++ b/applications/PoP/roomtest/roomtest.c @@ -641,18 +641,26 @@ int main(void) * так окно задней стены и передняя грань пола оказывались на плите. */ pop_dbg_m10(); /* ЗАМЕР: check_mirror сделан */ pop_loose_mob_draw(); + pop_dbg_m11(); /* ЗАМЕР: pop_loose_mob_draw сделан */ { /* Кто позже — тот поверх; порядок задаёт обход тайлов, а не роль * персонажа (см. guard_over_kid). Отрисовка одна на всех Char * (pop_cdraw.c), различает их только слот. */ - uint8_t g_after = guard_over_kid(); /* Пересчёт после тика: слот, за который heal не платили, мог * всё-таки сдвинуться — тогда бит снимется, а прошлый кадр * сотрёт сам pop_char_draw (страховка cd_heal). */ + uint8_t g_after; skip = pop_char_skip_mask(); + pop_dbg_m12(); /* ЗАМЕР: skip_mask сделан */ + /* Порядок «кто поверх кого» нужен, только если кого-то РИСУЕМ. + * При skip == 3 оба слота тихие, рисовать некого — а вызов стоит + * трамплина в банк 8 и двух objtile_at_char, 14 424 такта + * (замер 11/15, 2026-08-19). Перестановка безопасна: обе + * функции только читают, и читают разное — skip_mask снимок + * cd_sig, guard_over_kid габариты pop_cd прошлого кадра. */ + g_after = (skip == 3) ? 0 : guard_over_kid(); if (!g_after && !(skip & 2)) { pop_char_draw(POP_CH_OPP); pop_char_fore(POP_CH_OPP); } PROF(6); /* кадр Кида (тот же циан) */ if (!(skip & 1)) pop_char_draw(POP_CH_KID); /* спрайт + брызги + клинок */ - pop_dbg_m11(); /* ЗАМЕР: Кид нарисован */ #if DBG_KIDOBJ /* ВРЕМЕННО: трасса для сверки с SDLPoP кадр в кадр. Место — то * же, что у оригинала (конец add_kid_to_objtable), и ВНЕ skip: @@ -673,7 +681,6 @@ int main(void) /* ПЕРЕДНИЙ СЛОЙ по пометкам — последним в кадре, как foretable у * оригинала (draw_tables, seg008:1373). Пометки ставят сами * объекты вокруг себя (pop_redraw.h). */ - pop_dbg_m12(); /* ЗАМЕР: соперник + mob поверх сделаны */ pop_fore_needed(); pop_hp_draw(); /* полоса HP — только при изменении */ PROF(6); /* fore поверх Kid + борта */