From 5ef084eca467a0e4a779129e4fce946aad234e41 Mon Sep 17 00:00:00 2001 From: Alexander Petrov Date: Sat, 18 Jul 2026 21:43:43 +0300 Subject: [PATCH] =?UTF-8?q?docs:=20loose=5Ffloors=5Fplan=20=E2=80=94=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BD=D0=BA=D1=80=D0=B5=D1=82=D0=B8=D0=BA=D0=B0=20?= =?UTF-8?q?SDLPoP=20+=20=D0=BF=D0=BE=D0=B4=D1=85=D0=BE=D0=B4=20=D0=B8?= =?UTF-8?q?=D0=BD=D1=82=D0=B5=D0=B3=D1=80=D0=B0=D1=86=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Дополнен точными данными из SDLPoP (сверено): кадровые таблицы loose_fram_left/right/bottom, get_loose_frame, y_loose_land, delay=11; триггеры с call-sites (check_press->make_loose_fall при стоянии на 11, frame79-сверху; do_knock на жёстком приземлении; animate каждый кадр); tile_is_floor(11)=1. Плюс подход интеграции в наш движок: общая мутабельная копия комнаты pop_map<->pop_bg + per-page запекание пустоты после падения; тонкое место — перерисовка динамического тайла в дабл-буфере. Co-Authored-By: Claude Opus 4.8 --- applications/PoP/docs/loose_floors_plan.md | 47 ++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/applications/PoP/docs/loose_floors_plan.md b/applications/PoP/docs/loose_floors_plan.md index 799080c..5ab72fa 100644 --- a/applications/PoP/docs/loose_floors_plan.md +++ b/applications/PoP/docs/loose_floors_plan.md @@ -89,6 +89,53 @@ - L4: mob (падающий кусок → debris снизу). - L5: урон Киду от падающего куска. +## Конкретика из SDLPoP (сверено 2026-07-18, готово к реализации) + +Таблицы (seg008.c), индекс = `get_loose_frame(modif)`: +- `loose_fram_left[] = {41,69,41,70,70,41,41,41,70,70,70,0}` +- `loose_fram_right[] = {42,71,42,72,72,42,42,42,72,72,72,0}` +- `loose_fram_bottom[]= {43,73,43,74,74,43,43,43,74,74,74,0}` +- `get_loose_frame(m)`: если `(m&0x80)` (или delay>11) → `m&=0x7F; if(m>10) return 1;` → `return m;` +- `y_loose_land[] = {2,65,128,191,254}` (mob), `loose_floor_delay = 11`. + +Триггеры (call-sites): +- **make_loose_fall(modifier=1)** — из `check_press()` (seg006): когда Kid + СТОИТ на тайле (FRAME_NEEDS_FLOOR, action < hang_climb / turn / bumped) и + `get_tile_at_char()==11`; ИЛИ `frame==79` (прыжок вверх) и + `get_tile_above_char()==11` (пробой сверху). `tile_is_floor(11)==1` — + Kid стоит на loose (start_fall НЕ зовётся). Тело: + `if(!(tile&0x20) && (sbyte)modif<=0){ modif=modifier; add_trob(type0); }` +- **do_knock(row)** — на ЖЁСТКОМ приземлении (SEQ_KNOCK_DOWN→check_knock, + seg003): по всем колонкам ряда `if(tile==11) loose_make_shake()` + (`if(modif==0){ modif=0x80; add_trob(type1); }`). +- **animate_loose** (каждый кадр, seg007:816): `++modif`; если `&0x80` + (тряска): `if(modif>=0x84){modif=0; trob=-1;}`; иначе (отсчёт): + `if(modif>=11){ remove_loose(tile→0); trob=-1; add_mob(); } else shake`. + +## Интеграция в наш движок (roomtest) — подход + +Наш движок ПЕКЁТ комнату один раз (двойной буфер: своя ОЗУ-копия на +страницу). Loose требует динамики + общего состояния pop_map↔pop_bg: +1. **Общая МУТАБЕЛЬНАЯ копия комнаты**: roomtest.c держит `uint8_t + room_fg[30]` (копия room1_fg) и передаёт ОДИН указатель и в + `pop_room_draw`, и в `pop_map_set` → мутации loose видны обоим. + (Сейчас g_fg — `const`; сделать неконстантным.) +2. **Состояние**: `uint8_t pop_loose_modif[30]` (0 / 0x80.. / 1..11). +3. **Модель** (pop_map): `check_press()` в `pop_phys_tick` (make_loose_fall + при стоянии на 11), `animate` каждый кадр. +4. **Перерисовка** (pop_bg, на back-странице каждый кадр): + - тряска/отсчёт (код всё ещё 11): `gfx_heal(tile rect)` (вернуть + печёный фон) + нарисовать loose-кадр (left/right/bottom по + get_loose_frame) банком SPRITE; + - падение (11→0): mutate `g_fg[pos]=0` + «запечь пустоту» на ОБЕИХ + страницах (bake-счётчик 2: чёрный bar + draw_tile empty банком NORMAL + на текущей странице 2 кадра подряд) → дальше heal показывает пусто. +5. **L4 mob**: падающий кусок → debris(14) снизу (y_loose_land); пока + отложено — упавший loose = пусто. **L5** урон — позже. + +Риск: перерисовка динамического тайла в двойном буфере (per-page heal + +bake) — единственное тонкое место; остальное — прямой порт логики выше. + ## Связанные Триггеры завязаны на физику Kid ([[pop_hang_state]] check_press/check_grab,