cb995bf0fc
Симптом (пользователь, 2026-09-02): на подъёме Кида шёл нескончаемый свист клинка, хотя меча у него нет. ОПОЗНАНИЕ. Звук снят с живой машины, а не угадан: snd_curr == 11 (sound_11_sword_moving). Заодно проверено, что тракт исправен — указатели насоса (pg 2, ptr 0x2B80, left 512) сошлись с записью 11 в SND/snd.idx (страница 2, off 0x2880, длина 1280, конец 0x2D80) байт в байт. То есть играл честно заявленный эффект из своих данных, и виновата была ЗАЯВКА, а не звук. ПРИЧИНА. Хвост check_hurting был портирован не до конца. В оригинале (seg002:1039..1044) звук 11 стоит В КОНЦЕ функции, после ОБЕИХ веток, и защищён тремя вещами: ранним выходом по dir_56_none, кадром 154 и условием Opp.action != actions_99_hurt. У нас он стоял ВНУТРИ ветки «не парировано», до присвоения Opp.action = 99_hurt, без проверки на попадание и — главное — без гарда по dir_56_none, который автор SDLPoP подписал прямым текстом: «Fix looping sword moving sound». Направление dir_56_none означает «персонаж выключен» (clear_char), махать ему нечем. Наш движок эту константу знает и применяет в pop_guard_tick — в check_hurting она просто не доехала. ТОНКОСТЬ ПОРТА: хвост оригинала ПЕРЕЧИТЫВАЕТ Char.frame и Opp.frame у персонажей, а не берёт снимки начала функции. Ветка парирования только что записала Opp.frame, а play_seq в ней — Char.frame; на кэшированных cf/of условие дало бы неверный ответ. Живая проверка в MAME пользователем: корректно. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018T2k4VZrSyERwk6H97Sfi1