Падающие плиты: передний слой по пометкам, честные спрайты, замер кадра
Слой fore переведён на пометки ОБЪЕКТОВ вместо окна вокруг персонажа — порт set_redraw_fore/redraw_frames_fore (seg007:0550, seg008:214): pop_set_redraw_fore + pop_fore_needed + pop_fore_tile_b, пометки ставит падающий кусок вокруг себя (draw_mob, seg007:1147). Ключевая правка: пометки соседа считаются в ПРОХОДЕ ОТРИСОВКИ, а не в тике. Стояли в цикле тика — то есть по позиции ДО mob_tick_one, а кусок рисовался уже по новой; пока он летит внутри ряда, тайлы совпадают, но в кадр пересечения границы пометка указывала на прежний тайл и колонна кусок не перекрывала. Ровно один кадр, как и наблюдалось. Спрайты падающего куска: obj_id = 10 (add_mob_to_objtable, seg007:1170), части берутся по этому индексу — 70/74/72, а не 41/43/42 (плита В ПОКОЕ). Отсюда была «цельная ровная плита» вместо двух половин со сдвигом. Убрана подпорка «перерисовать соседний тайл поверх куска»: тащила на плиту чужой узор и окно и стоила по полной отрисовке тайла на кусок за кадр. Коридор heal сужен по высоте 32 -> 24 (реальный след спрайта 16 px). gfx_set_bank вынесен из потайлового цикла в обрамление прохода. Выяснено и зафиксировано: clip.right = 40 в add_mob_to_objtable — МЁРТВЫЕ данные. set_clip_rect вызывается под chtab_flip_clip[chtab_id], а для окружения флаг равен нулю — оригинал падающие куски не клипует вовсе. Портировать нечего; две попытки это сделать были ошибочны. Замер кадра (маркеры m1..m4, оставлены временно для проверки правок): покой 196 614 тактов (15,2 % кадра при периоде 1 290 000), во время падения гряды среднее 222 667, пик 1 428 990 — то есть 111 % кадра, шесть кадров подряд за пределом. Логика неизменна (88 020), растут фон (до 887 376) и спрайты (до 660 792). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
#include "pop_tile.h" /* общие листья слоя фона (резидент): блит, тайлы, таблица */
|
||||
#include "_pop_draw.h" /* pop_onscreen_cols / pop_heal_fast */
|
||||
#include "pop_state.h"
|
||||
#include "pop_redraw.h" /* пометки тайлов: сосед падающего куска (draw_mob) */
|
||||
#include "pop_geom.h"
|
||||
#include "pop_level.h" /* pop_doorlink2 — состояние нажатия кнопки */
|
||||
#include "pop_kid.h" /* Kid.curr_col/curr_row — порядок оверлеев */
|
||||
@@ -1165,6 +1166,30 @@ static void mob_tick_one(mob_t *m, uint8_t pg)
|
||||
*
|
||||
* Порядок «кусок против Кида» здесь ни при чём — его решает defer выше, и там
|
||||
* действует обычное правило. */
|
||||
/* Пометки СОСЕДА СПРАВА — порт draw_mob (seg007:1147). Оригинал каждый
|
||||
* кадр помечает тайл col+1 в ряду куска сразу двумя пометками:
|
||||
*
|
||||
* set_redraw2(tilepos, 1); // фон соседа — рисуется ДО куска
|
||||
* set_redraw_fore(tilepos, 1); // его передние части — ПОСЛЕ куска
|
||||
*
|
||||
* и повторяет их для второго ряда, если кусок висит на границе (ypos-18).
|
||||
* Так правая часть куска (спрайт 72 лежит в столбце col+1) прячется за
|
||||
* передней гранью соседнего пола, а передние части чужого тайла — колонна,
|
||||
* например, — ложатся поверх куска.
|
||||
*
|
||||
* Здесь была подпорка: целый соседний тайл рисовался ПОВЕРХ куска прямо в
|
||||
* mob_render. Она тащила на плиту чужой узор и окно и стоила по полной
|
||||
* отрисовке тайла на кусок за кадр (MOB-CLIP-RIGHT). */
|
||||
static void mob_mark_neighbour(const mob_t *m)
|
||||
{
|
||||
int8_t r = pop_y_to_row((int16_t)m->y);
|
||||
int8_t rt = pop_y_to_row((int16_t)(m->y - 18));
|
||||
int8_t c = (int8_t)(m->col + 1);
|
||||
if (c > 9) return;
|
||||
if (r >= 0 && r <= 2) pop_set_redraw_fore((uint8_t)(r * 10 + c));
|
||||
if (rt != r && rt >= 0 && rt <= 2) pop_set_redraw_fore((uint8_t)(rt * 10 + c));
|
||||
}
|
||||
|
||||
static void mob_draw_pass(uint8_t pg, uint8_t want_defer)
|
||||
{
|
||||
uint8_t order[MOB_MAX], n = 0, i, j;
|
||||
@@ -1177,7 +1202,18 @@ static void mob_draw_pass(uint8_t pg, uint8_t want_defer)
|
||||
order[j] = i;
|
||||
n++;
|
||||
}
|
||||
for (i = 0; i < n; i++) mob_render(&mobs[order[i]], pg);
|
||||
for (i = 0; i < n; i++) {
|
||||
/* Пометки соседа ставятся ЗДЕСЬ, а не в тике: у оригинала draw_mob
|
||||
* (seg007:1147) считает ряд от той же координаты, по которой кусок
|
||||
* рисуется. Стояли они в цикле тика — то есть по позиции ДО
|
||||
* mob_tick_one, а рисовался кусок уже по новой. Пока он летит
|
||||
* внутри ряда, старый и новый тайл совпадают и разницы не видно; но
|
||||
* в кадр пересечения границы пометка указывала на прежний тайл, и
|
||||
* передняя часть колонны кусок не перекрывала — ровно ОДИН кадр,
|
||||
* как и наблюдалось (прогон 2026-08-13, комната 23, колонка 8). */
|
||||
mob_mark_neighbour(&mobs[order[i]]);
|
||||
mob_render(&mobs[order[i]], pg);
|
||||
}
|
||||
}
|
||||
|
||||
void pop_loose_mob_tick(void) __banked
|
||||
|
||||
Reference in New Issue
Block a user