Files
Sprinter-SDCC/applications/PoP/roomtest/tests-host/t_wall.c
T
Александр Петров dc8b2b7115 Приёмка ур. 2–3: сквозь стену, клин в шве, бар под плитой, глухой страж
Четыре разбора с прогонов пользователя; три бага закрыты, четвёртый
(BUG-SPIKE-1, пики) заведён с замером и гипотезой.

BUG-JUMPWALL-1 (Critical) — недолетевший прыжок проходил СКВОЗЬ стену.
check_collisions держал флаги перекрытия ОДНОГО ряда, а оригинал
(seg004:0004) — трёх, и move_coll_to_prev (seg004:00DF) берёт «прошлые»
флаги из нужного.  Наш prev=3 («уже перекрывал») подавлял бамп ровно на
кадре смены ряда, а в падении ряд меняется почти каждый кадр — переход 0→1
на стене приходился как раз на него.  Порт трёх рядов дословно.
Воспроизведено и закрыто на харнессе (новый набор t_wall: свип по 20
стартовым X, 4 давали проход сквозь кладку); 1723 трассы t_phys НЕ
изменились — правка поведение-сохраняющая.  Живьём подтвердил пользователь.

BUG-GUARD-DEAF-1 (Major) — is_guard_notice не взводился НИГДЕ, поэтому
неактивный страж не оборачивался на Кида за спиной никогда.  Портированы
все пять мест оригинала: опкод SOUND в play_seq (звуки 0..2), bumped_sound,
мягкое/среднее приземление, обрушенная плита, щелчок кнопки.  Ждёт
игровой проверки боем в комнате 11 уровня 2.

BUG-SEAM-WEDGE-1 — клин кладки в пустом (2,0).  Сосед угла снизу-слева
лежит в комнате по диагонали (room_BL); мы безусловно считали его стеной,
оригинал (load_rowbelow, seg008:368) — только когда такой комнаты нет.
Ряд «снизу» стал 11-байтным: [10] = тайл (0,9) диагональной комнаты.

BUG-LOOSE-3 — чёрный бар под упавшей плитой-потолком.  pop_ceil_bake_empty
стирал полосу и восстанавливал только два тайла ряда −1, а в полосу лезет
графика соседа слева и верхушки ряда 0.  Теперь перерисовываются ряды −1 и
0, колонки col−1..col+1.  Проверено попиксельной сверкой с эталонной
перерисовкой: 0 различий.

Плюс карта связности комнат уровней 1–3 (TASKS.md): на ур. 2 недостижимых
нет, на ур. 3 это 23 и 24 — те же односторонние ссылки, что дали 13/18/24
на уровне 1, только комнаты полностью пустые.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 21:29:37 +03:00

96 lines
4.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* t_wall.c — удар о стену В ВОЗДУХЕ (BUG-JUMPWALL-1).
*
* Наблюдение с приёмки уровня 3 (комната 14): Кид прыгает, не долетает и
* вместо удара о кладку с последующим сползанием ВДОЛЬ неё пролетает
* сквозь стену «по свободной траектории». Класс отказа шире одной
* комнаты, поэтому проверяем его отдельным набором, а не сценарием в
* t_phys: там характеризация (трасса == эталон), здесь — утверждение о
* поведении («сквозь кладку нельзя»), которое не должно молча
* переснашиваться вместе с эталонами.
*
* Оригинал: bumped_fall (seg004:04E4) на ударе гасит `Char.fall_x`, то есть
* горизонтальный снос обнуляется и дальше Кид падает вертикально. Кто
* решает, что удар был, — check_collisions (seg004:0004) + check_bumped.
*
* Проверка — свипом по стартовому X, а не одним прыжком: исход зависит от
* фазы, и «с одной X работает» ничего не доказывает (ровно так и вышло с
* первым сценарием — из центра плиты стена держит).
*/
#include "tcheck.h"
#include "scene.h"
#include "stubs.h"
#include "pop_kid.h"
#include "pop_map.h"
#define E 0
#define F 1
#define W 20
/* Комната 14 уровня 3 с одной правкой: шахте колонок 6–7 подложено дно
* (ряд 2), потому что соседних комнат у сцены нет, а в игре Кид улетает
* вниз в комнату 13. Остальное — как в данных: площадка (0,8), провал
* (0,6)/(0,7), СТЕНА в колонке 5 рядов 1–2, площадка (0,5) за ней. */
static const uint8_t room14[30] = {
F, F, F, E, E, F, E, E, F, E,
W, W, W, E, E, W, E, E, W, E,
W, W, W, F, F, W, F, F, W, W,
};
/* Плита (0,8) по X: колонка 8 — это [177, 191), плюс шов с пустой (0,9). */
#define X_LO 177
#define X_HI 196
/* Прыгнуть влево со стартовой X. Возврат — код исхода:
* 'L' — долетел до площадки (0,5) и стоит на ней (ряд 0) — законно;
* '.' — не долетел и упал на дно шахты колонок 6–7 — тоже законно;
* цифра — колонка, в которой Кид оказался ЛЕВЕЕ стены, то есть прошёл
* сквозь кладку колонки 5 (это и есть баг). */
static char jump_left_from(uint8_t x)
{
sc_room(room14, 14);
sc_kid_at_x(8, 0, x, -1 /* лицом влево */);
sc_trace_clear();
/* Клавиши держим только на сам прыжок: если удерживать их всю сцену,
* Кид, ДОЛЕТЕВШИЙ до (0,5), тут же прыгает с неё второй раз — и исход
* говорит уже не о стене, а о втором прыжке. */
sc_run(SC_L | SC_U, 6);
sc_run(0, 34);
if (!sc_len) return '?';
{
int8_t col = sc_trace[sc_len - 1].col;
int8_t row = sc_trace[sc_len - 1].row;
if (row == 0) return 'L'; /* остался на верхнем ряду */
if (col >= 6) return '.'; /* сполз вдоль стены в шахту */
return (char)('0' + (col < 0 ? 0 : col));
}
}
static void put(char c)
{
if (tc_result.logn < TC_LOGSZ) tc_result.log[tc_result.logn++] = (uint8_t)c;
}
static void puts_(const char *s) { while (*s) put(*s++); }
TC_TEST(wall_stops_undershot_jump)
{
uint8_t x, bad = 0;
/* Карта исходов по всей ширине плиты: 'L' — долетел до (0,5), '.' —
* сполз вдоль стены в шахту, цифра — просочился сквозь кладку. */
puts_("x=177..196: ");
for (x = X_LO; x <= X_HI; x++) {
char r = jump_left_from(x);
put(r);
if (r != 'L' && r != '.') bad++;
}
put('\n');
TC_EQ(bad, 0);
}
int main(void)
{
sc_init();
TC_RUN(wall_stops_undershot_jump);
return 0;
}