roomtest: фикс провала сквозь пол при беге с кромки (порт start_fall/in_wall)

Тап-бег с кромки [1,3] вправо -> Kid проваливался в стену col2/3 ->
респавн, вместо посадки на [2,4].  Сверено с SDLPoP seg006:

- start_fall: frame 9 -> seq_7_fall (был ошибочно seq_19 как у 13);
  frame 13 -> seq_19 (лишний dx(1)).  + хвост seg006:1099: тайл ПЕРЕД
  персонажем — стена -> Char.x = char_dx_forward(-1);
- in_wall переписан аутентично (seg006:1292): выталкивает ВПЕРЁД из стены
  (delta+4) на соседний тайл, а не назад вглубь (наш старый через
  dist_from_wall_forward давал отрицательный сдвиг -> Kid уходил в стену
  col2 -> проваливался).  distance_to_edge_weight + 6-delta/+4.

Проверено в MAME (пользователь): бег с кромки [1,3] -> посадка на [2,4].

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-18 21:23:09 +03:00
parent 237f780e0e
commit 36a5a5e194
+31 -19
View File
@@ -225,21 +225,21 @@ static int dist_from_wall_forward(uint8_t tiletype, int8_t tcol)
return wall_dl[type] + coll_left - cx;
}
/* Выровнять передний край РОВНО к грани стены, если он зашёл за неё (bumped:
* Char.x += dist; char_dx_forward отражает знак для обоих направлений).
* Стена ищется под персонажем, иначе перед ним. */
/* in_wall (seg006:1292): персонаж оказался ВНУТРИ стены (тайл под ним =
* стена) — вытолкнуть. Аутентично SDLPoP: если он глубоко (delta>=8) ИЛИ
* перед ним тоже стена — двигаем НАЗАД к грани (6-delta), иначе ВПЕРЁД из
* стены на соседний тайл (delta+4). Вызывать ТОЛЬКО когда
* get_tile_at_char()==стена (проверяет вызывающий). */
static void in_wall(void)
{
uint8_t t; int8_t tcol; int d;
t = get_tile_at_char(); tcol = Kid.curr_col;
if (!wall_type(t)) { t = get_tile_infrontof_char(); tcol = g_infrontx; }
if (!wall_type(t)) return;
d = dist_from_wall_forward(t, tcol);
if (d < 0) {
Kid.x = (uint8_t)char_dx_forward((int8_t)d); /* край -> грань */
determine_col();
get_tile_at_char();
}
int d = distance_to_edge_weight();
if (d >= 8 || get_tile_infrontof_char() == TILE_WALL)
d = 6 - d;
else
d += 4;
Kid.x = (uint8_t)char_dx_forward((int8_t)d);
determine_col();
get_tile_at_char();
}
/* ---- Падение ------------------------------------------------------- */
@@ -264,17 +264,29 @@ static void land(void)
static void start_fall(void)
{
uint8_t frame = Kid.frame, seq;
uint8_t frame = Kid.frame, seq, tile;
inc_curr_row();
if (frame == 9 || frame == 13) seq = SEQ_19_FALL; /* падение из бега */
else if (frame == 26) seq = SEQ_18_FALL_STANDJUMP;
else if (frame == 44) seq = SEQ_21_FALL_RUNJUMP;
else seq = SEQ_7_FALL; /* stand/step/crouch */
/* seg006:1044 start_fall: frame 9 -> seq_7, 13 -> seq_19 (лишний dx(1)) */
if (frame == 13) seq = SEQ_19_FALL;
else if (frame == 26) seq = SEQ_18_FALL_STANDJUMP;
else if (frame == 44) seq = SEQ_21_FALL_RUNJUMP;
else seq = SEQ_7_FALL; /* frame 9 + stand/step/crouch */
kid_set_seq(seq);
play_seq();
determine_col();
if (get_tile_at_char() == TILE_WALL)
if (get_tile_at_char() == TILE_WALL) {
in_wall();
return;
}
/* Хвост seg006:1099: тайл ПЕРЕД персонажем — стена → отодвинуть на 1
* назад (иначе передний край зайдёт в грань). (seq_104 для frame 44 с
* малым зазором не портирован — в этом тесте не встречается.) */
tile = get_tile_infrontof_char();
if (tile == TILE_WALL) {
if (frame != 44 || distance_to_edge_weight() >= 6)
Kid.x = (uint8_t)char_dx_forward(-1);
determine_col();
}
}
/* ---- Зацеп (seg006 can_grab/check_grab) --------------------------- *