Files
Sprinter-SDCC/applications/SprPoP/docs/keys_plan.md
T
snark13 659071838d SprPoP: KEYS-D, KEYS-R и KEYS-F12 — на доску отложенного
Три остатка плана keys_plan.md записаны в TASKS_OPEN.md с полным разбором,
чтобы не выводить его заново.

KEYS-D (осмотр соседних комнат) — главное, что стоит помнить: у SDLPoP это
три строки, потому что там drawn_room влияет ТОЛЬКО на отрисовку, а физика
ходит через get_tile(room, col, row) с явной комнатой.  У нас наоборот —
карта коллизий грузится для ОТРИСОВАННОЙ комнаты: room_fg, lcol_fg,
rcol_fg, above_fg, below_fg это ОДИН комплект на программу.  Уведи cur_room
к соседу, не трогая kid_room, и Кид считает столкновения по чужим тайлам.
Задел под расхождение уже стоит (kid_room отдельной переменной,
update_kid_render_dx со сдвигом ±140), но enter_room_side пишет обе разом —
это незакрытая часть S3 straddle.

Записаны оба пути с ценой: честный (правка ядра, дни) и смотровой режим с
остановкой игры (150-250 байт, часы) — плюс что главный риск не в
отрисовке, а в возврате.

KEYS-R (воскрешение) — четыре места, которые обязаны знать про окно
неуязвимости, со ссылками на seg-код.

KEYS-F12 (скриншот) — «возможно, когда-то», по пометке пользователя.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-27 15:38:22 +03:00

12 KiB
Raw Blame History

План: перевод управления на раскладку keys.txt

Состояние на 2026-08-27. Фазы A и B сделаны (коммит 76f02e7), фаза C — три чита из четырёх (f8e96c0). Отложены и записаны на доску TASKS_OPEN.md: KEYS-R (воскрешение), KEYS-D (осмотр соседних комнат), KEYS-F12 (скриншот). Итоговая раскладка, включая наши сверхштатные клавиши, — в keys.txt.

Целевая раскладка — keys.txt, она же раскладка SDLPoP. Здесь разобрано, что у нас уже есть, что стоит не на той клавише и каких функций нет вовсе, плюс порядок работ. Кода этот документ не меняет.

1. Принципы

Раскладка — не самоцель. Часть строк keys.txt — это функции SDLPoP, которых у нас нет вообще (воскрешение, замедленное падение, осмотр соседних комнат). Поэтому работа делится на две разные по цене части: переназначить клавишу (минуты) и реализовать функцию (от часа до дня). Смешивать их в одной фазе нельзя — иначе простые переименования застрянут за сложным.

Механику сверять с SDLPoP. Для каждой новой функции — сначала найти её в assets/orig/SDLPoP/src/, потом писать (правило проекта, memory pop_check_sdlpop_first). Особенно для читов: Shift+S/Shift+T — это не «прибавить HP», а конкретные add_life/set_health_life.

Кромка против удержания. Игровые клавиши (стрелки, Shift) читаются как удержание — это held-state, ради которого и заводился <kbd_raw.h>. Все служебные и читерские — как НОВОЕ нажатие (edge), иначе одно касание сработает столько раз, сколько кадров клавиша была внизу. В коде уже есть оба образца: read_user_control() для первого, intro_skip_requested() и hof_* для второго.

Где живёт обработчик. Служебный слой — pop_frame_ui() в sprpop_cold.c (банк 8), читы — pop_cheat.h + вызовы из главного цикла. После переноса pop_config/pop_hof в банк 10 в банке 9 свободно 4436 байт, в банке 8 — 1786; новые обработчики лучше класть в 8-й или 10-й, а не в 9-й.

Ctrl-комбинации уже поддержаны: Ctrl+S/Ctrl+M проверяют KBD_LCTRL || KBD_RCTRL вместе с буквой (sprpop_cold.c:518). Тот же приём годится для Ctrl+A, Ctrl+R, Ctrl+V, Ctrl+Q, Ctrl+B.

2. Что есть сейчас

Движение и бой — совпадает, кроме диагоналей

keys.txt у нас статус
Left / Right / Up / Down стрелки, read_input() есть
Down+Left/Right — прыжок на месте комбинация стрелок есть
Shift — поднять предмет KBD_LSHIFT/KBD_RSHIFT есть
Shift+Left/Right — осторожный шаг комбинация есть
Up+Left / Up+Right — прыжок в сторону комбинация есть
Home / Page Up — то же самое НЕТ: читаются только стрелки
Up на бегу — прыжок с разбега есть
Shift в падении — зацеп есть
Бой: Left/Right/Shift/Up есть
Бой: Down — убрать меч проверить отдельно

Служебные

keys.txt у нас статус
Esc — пауза/меню KBD_MENU = 0x76 есть
Backspace — меню НЕТ (в оригинале это основная клавиша меню, Esc — дублёр)
Space — показать остаток времени НЕТ (Space занят только в меню и вводе имени)
Ctrl+A — рестарт уровня только пунктом меню НЕТ клавиши
Ctrl+R — вернуться в заставку НЕТ
Ctrl+S — звук вкл/выкл Ctrl+S есть, совпадает
Ctrl+M — музыка вкл/выкл Ctrl+M есть, совпадает
Ctrl+V — версия pop_build_info_show() есть, зовётся на старте НЕТ клавиши
Ctrl+Q / F10 — выход F10 в двух местах половина (см. §3)
F6 / F9 — quicksave/load совпадает есть
F12 — скриншот помечено опциональным, не делаем

Читы

keys.txt у нас статус
Shift+L — следующий уровень совпадает есть
K — убить стража совпадает есть
[ / ] — сдвинуть Кида на пиксель совпадает есть
+ / — минута времени у нас это F7/F8, а +/ заняты обходом комнат конфликт, см. §3
Shift+I — перевернуть экран у нас это U переназначить
R — воскресить Кида НЕТ функции
Shift+W — замедленное падение НЕТ функции
Shift+S — вернуть одну единицу HP НЕТ функции
Shift+T — добавить HP НЕТ функции
T — показывать таймер НЕТ функции

Осмотр комнат — нет целиком

H / J / U / N (соседняя комната слева/справа/сверху/снизу) и Ctrl+B (вернуться к Кида) не реализованы. У нас есть отладочный обход комнат по номеру (+/, ROOMNAV в sprpop.c) — это другое: он ТЕЛЕПОРТИРУЕТ Кида, а H/J/U/N только смотрят, не двигая его.

Наше сверх keys.txt

I — бессмертие, P — режим скорости, 1/2 — стоп-кадр, +/ — обход комнат. Всё это отладочное и в оригинале отсутствует; выбросить или оставить — решение пользователя (§6).

3. Конфликты, которые надо решить до кодинга

К1. +/: время или комнаты. keys.txt отдаёт их под ±минуту, у нас на них обход комнат, а время висит на F7/F8. В pop_cheat.h это записано как осознанный выбор («Numpad +/- уже принадлежат ROOMNAV»). Варианты: вернуть +/ времени и увести ROOMNAV на другие клавиши; оставить как есть и разойтись с keys.txt; либо развести по контексту (ROOMNAV — только в отладочной сборке). Развилка требует решения.

К2. U занят. Сейчас U — переворот экрана, а keys.txt хочет U под «посмотреть комнату сверху», переворот — на Shift+I. Разрешается само, если делать К5 и К7 одной фазой.

К3. S без Ctrl. Звук у нас требует Ctrl, и это правильно, но keys.txt хочет ещё и Shift+S (вернуть HP). Проверка обязана различать Ctrl+S, Shift+S и голое S, иначе они будут срабатывать вместе. То же для T: T (таймер) против Shift+T (добавить HP).

К4. Два выхода. F10 живёт в pop_frame_ui() (только в игре) и, с коммита 808c2a5, в kbd_idle() (везде). Дублирование безвредное, но лишнее: проверку в pop_frame_ui стоит убрать, оставив одну точку. Заодно повесить туда же Ctrl+Q.

4. Порядок работ

Фаза A — переназначения, функции уже есть. Дёшево и не трогает логику.

  • Shift+I вместо U для переворота экрана (К2).
  • Backspace как основная клавиша меню, Esc оставить дублёром.
  • Ctrl+V на существующий pop_build_info_show().
  • Ctrl+Q рядом с F10, убрать дубль F10 из pop_frame_ui (К4).
  • Ctrl+A на существующий путь POP_MENU_RESTART_LEVEL.
  • Решение по К1 и правка +//F7/F8.

Фаза B — мелкие новые функции.

  • Space — показать остаток времени. Механика есть (pop_timer, статус- строка); нужен показ на несколько секунд, как text_time_total оригинала.
  • T — постоянный показ таймера (минуты:секунды) в статус-строке.
  • Ctrl+R — возврат в заставку. Автомат это умеет (POP_APP_EV_RESTART_INTRO), нужен только вход с клавиши.

Фаза C — читы, требующие правки игровой логики. Каждый — сверка с SDLPoP до кодинга.

  • Shift+S / Shift+T — HP: аналоги малого и большого красного зелья.
  • R — воскрешение Кида: сложнее прочих, поднимает мёртвого персонажа и должен согласоваться с уже существующим гейтом «мёртв» (memory pop_level_restart_scope).
  • Shift+W — замедленное падение.

Фаза D — осмотр соседних комнат (H/J/U/N + Ctrl+B). Самое крупное: нужен показ комнаты, в которой Кида нет, с возвратом. У нас уже разобрана модель kid_room ≠ drawn_room (memory pop_seam_room_model, room_model_plan.md) — это её прямое применение, и именно поэтому фаза идёт последней.

Фаза E — F12 скриншот. Помечен опциональным; предлагаю не делать вовсе: файл на 80 КБ и запись на диск посреди кадра.

5. Открытые вопросы

  1. К1 — кому отдать +/: времени (как keys.txt) или обходу комнат?
  2. Что делать с нашими сверхштатными клавишами (I бессмертие, P скорость, 1/2 стоп-кадр): оставить как есть, увести под отладочную сборку или выбросить?
  3. Нужны ли Home/Page Up как дублёры диагональных прыжков — на IBM-клавиатуре Sprinter они есть, но комбинация Up+Left уже работает.
  4. Фазы C и D — делать ли их вообще: это читы и отладочный осмотр, к прохождению игры отношения не имеющие.