Files
Sprinter-SDCC/applications/PoP/docs/menu_settings_plan.md
T
snark13 f4b4852d51 QuickSave F6/F9 в roomtest; bank_load_file/bank_save_file/gfx_w0_page_prepare; sprinter-cc: авто n_banks
roomtest:
- QuickSave/QuickLoad (F6/F9): снапшот 'POPQ' v3 в POP.SAV/POP.BAK на HDD,
  транзакционная запись (POP.NEW -> rename, откат при ошибке), XOR-контрольная
  сумма payload'а; сериализация всех игровых переменных через W0-примитивы
  pop_qs_*; pop_qsave_process() на границе кадра вне Char-окон
- pop_qsave_restore_room(): полная перезагрузка комнаты после загрузки
  (карта/края/швы, сброс bake-кэша, перерисовка обеих страниц, инвалидация
  кэшей спрайтов и HP)
- сериализаторы в pop_map/pop_loose_mob/pop_trob/pop_guard_ai
  (+ восстановление инвариантов: mobs_live, trob_drawn, redraw)
- immortal-чит 2 уровня: уровень 2 поглощает только малый урон Kid'а

libc/libbgi:
- bank_load_file()/bank_save_file() — резидентное файловое I/O в банк,
  без правила W3 (путь читается до переключения страницы)
- gfx_w0_page_prepare(page) — подготовка W0-окна (IRQ/NMI-стабы) одной
  функцией; atlas_load.c и roomtest переведены на новые примитивы;
  ручные ISR-стабы удалены

sprinter-cc / сборка:
- --bank N=FILE.c: автогенерация n_banks (_n_banks_auto.c), ручные
  const n_banks удалены из тестов
- roomtest/app.mk: ресурсы через stamp-файлы (.resource-stamps/) — один
  запуск упаковщика на группу вместо N под -B; HDD_PACK_ARGS
2026-08-22 11:53:10 +03:00

14 KiB
Raw Blame History

Pause menu и Settings для Sprinter PoP

Статус: согласованный план, код не начат (2026-08-21).

Связанные документы:

  • full_game_plan.md — автомат состояний, title, demo, cutscenes и ending;
  • quicksave_plan.md — состав и восстановление снимка.

1. Решения

  • Программа работает только с HDD; настройки, QuickSave и Hall of Fame всегда могут быть постоянными файлами.
  • Основной pause menu обязательно содержит QuickSave и QuickLoad.
  • QuickSave имеет один слот POP.SAV; предыдущая корректная запись хранится как POP.BAK.
  • Первая версия имеет один профиль VANILLA. Под этим именем пока понимается текущее поведение roomtest, включая уже встроенные исправления.
  • Дизайн файла и API предусматривает будущий ENHANCED, но аудит и переключение fixes сейчас не выполняются.
  • Уровень 15/copy protection отсутствует.
  • Моды, levelsets и меню Mods отложены.

2. Что есть в SDLPoP

src/menu.c содержит:

  • Resume, QuickSave, QuickLoad, Restart Level, Settings, Restart Game, Quit;
  • General, Gameplay, Visuals, Mods, Controls;
  • toggle/number/key controls, пояснения, scroll и confirmation dialogs;
  • большой список fixes/enhancements и custom level options.

На Sprinter не переносятся SDL-специфичные параметры: fullscreen, hardware acceleration, scaling, aspect ratio, rumble. UI берёт структуру SDLPoP, но набор настроек соответствует платформе.

3. Pause menu первой версии

RESUME
QUICKSAVE
QUICKLOAD
RESTART LEVEL
SETTINGS
RESTART GAME
QUIT

Поведение:

  • Esc в PLAYING открывает меню; повторный Esc или Resume возвращает игру;
  • игра, логический таймер и звуковой насос ставятся на паузу согласованно;
  • QuickSave/QuickLoad только взводят запрос, фактическая операция идёт на безопасной границе кадра;
  • QuickLoad disabled/показывает NO QUICKLOAD, если нет валидных SAV/BAK;
  • Restart Level и Restart Game требуют подтверждения;
  • Quit требует подтверждения и закрывает файлы/каналы штатным путём;
  • меню недоступно в demo, cutscene, time-expired и ending;
  • отдельная debug-комбинация немедленного выхода может остаться только в отладочной сборке.

4. Settings первой версии

GENERAL
  Sound                 ON / OFF
  Show Sprinter screen  ON / OFF
  Restore defaults...

GAMEPLAY
  Speed                 NORMAL / FAST / FASTEST
  Gameplay profile      VANILLA
  Cheats                ON / OFF

CONTROLS
  Show key bindings

BACK

Gameplay profile: VANILLA показывается read-only: место в модели уже есть, но пользователь не может выбрать ещё не реализованный ENHANCED.

Отладочные параметры ROOMNAV, border profiling, stop-frame и переключение double buffering не являются пользовательскими Settings. Они остаются compile-time/debug функциями и скрываются из release UI.

5. Модель настроек

Игровой код не должен читать UI-структуры. Единственный runtime-контракт:

typedef enum {
    POP_PROFILE_VANILLA = 0,
    POP_PROFILE_ENHANCED = 1
} pop_gameplay_profile_t;

typedef struct {
    uint8_t sound_enabled;
    uint8_t speed_mode;
    uint8_t gameplay_profile;
    uint8_t cheats_enabled;
    uint8_t show_build_info;
    uint16_t enhancement_flags;
} pop_settings_t;

В первой версии загрузчик принимает только POP_PROFILE_VANILLA. Значение ENHANCED из более нового/ручного файла заменяется на VANILLA с диагностикой, а не включает частично реализованный режим.

Будущий профиль задаёт маску возможностей централизованно:

VANILLA  -> текущий согласованный набор
ENHANCED -> будущий рекомендуемый набор fixes
CUSTOM   -> только если позже действительно понадобится

До отдельного аудита существующие fix_exit_door, feather guard behavior, jump grab и sound priorities не переключаются и считаются частью текущего VANILLA.

6. Файл POP.CFG

Бинарный, компактный, версионированный формат:

+0  "PCFG"          magic, 4 Б
+4  format_version  1 Б
+5  payload_size    2 Б
+7  payload         фиксированные поля little-endian
..  checksum        2 Б

Требования:

  • путь рядом с exe/в выделенном каталоге игры на HDD;
  • неизвестная версия, неверная длина или checksum -> defaults;
  • неизвестные будущие хвостовые поля можно пропустить по payload_size;
  • запись только после Apply/выхода из Settings, не на каждый шаг курсора;
  • ошибка записи не завершает игру: показать сообщение и оставить runtime значения;
  • Restore defaults меняет RAM только после подтверждения и затем сохраняет.

CFG не содержит состояние уровня, QuickSave или Hall of Fame.

7. QuickSave / QuickLoad в меню

Детальный состав снимка и порядок восстановления — в quicksave_plan.md. Здесь фиксируется UI и файловая транзакция.

Один слот и backup

Файлы:

POP.SAV   текущий слот
POP.BAK   предыдущий валидный слот
POP.NEW   временный файл во время записи

Безопасная запись:

  1. записать полный снимок в POP.NEW;
  2. закрыть файл;
  3. повторно открыть/прочитать заголовок и checksum;
  4. старый валидный POP.SAV перенести/скопировать в POP.BAK;
  5. POP.NEW сделать новым POP.SAV;
  6. при любой ошибке сохранить прежний POP.SAV.

Точную последовательность rename/copy выбрать после характеризации DSS. Если атомарный rename не гарантирован, использовать copy + fsync/close и никогда не удалять единственную валидную копию до проверки новой.

Загрузка

  1. проверить POP.SAV;
  2. если он отсутствует/повреждён/несовместим — проверить POP.BAK;
  3. при валидном BAK показать LOAD BACKUP?;
  4. несовместимая версия — INCOMPATIBLE SAVE, без частичной загрузки;
  5. после успеха закрыть menu, перерисовать обе страницы, перезапустить звук.

Сообщения

Минимальный набор:

QUICKSAVED
QUICKLOADED
NO QUICKLOAD
SAVE ERROR
INCOMPATIBLE SAVE
LOAD BACKUP?

Сообщение показывается UI-слоем, но операция завершается до возврата в игровой кадр.

8. Restart Level / Restart Game

Restart Level:

  • использует существующий штатный reset текущего уровня;
  • не перечитывает CFG;
  • не меняет POP.SAV;
  • сбрасывает состояние, которое сбрасывает текущая реализация roomtest.

Restart Game:

  • подтверждение;
  • завершить текущий gameplay session;
  • освободить level/atlas/temporary EMM;
  • создать новую игру с уровня 1 и новым глобальным таймером;
  • настройки оставить;
  • QuickSave не удалять.

9. Controls

Первая версия только показывает активную раскладку. Переназначение клавиш откладывается: raw PS/2 канал имеет особенности Shift и расширенных кодов, поэтому generic key-binding UI требует отдельного проекта.

Экран должен перечислить минимум:

  • движение и Shift/action;
  • Esc/menu;
  • F6/F9 QuickSave/QuickLoad;
  • Ctrl+S sound;
  • P speed;
  • доступные cheats, только если они включены.

10. UI renderer и ввод

Меню использует общую с title текстовую подсистему:

  • фиксированный bitmap font без _gfx_font_buf на 2 КБ в W2;
  • фон/рамка и выделенная строка;
  • вертикальная навигация, left/right для значения, Enter, Esc;
  • edge-triggered клавиши поверх существующего kbd_raw;
  • двойная буферизация либо один заранее сохранённый фон menu;
  • строки и холодный код — в отдельном банке, постоянное состояние — в W2.

Первый UI может быть визуально простым. Критично отсутствие потери клавиш, предсказуемая пауза и отсутствие повреждения игрового back buffer.

11. Диалоги

Общий диалог подтверждения:

RESTART LEVEL?
RESTART GAME?
QUIT GAME?
RESTORE DEFAULTS?
LOAD BACKUP?

YES / NO

Диалог не выполняет действие напрямую: он возвращает решение автомату меню, который формирует команду приложению. Так UI не зависит от gameplay-модулей.

12. Будущий ENHANCED

Не реализуется сейчас, но дизайн обязан позволять:

  • добавить второй профиль без смены всего UI;
  • хранить enhancement_flags в CFG;
  • отличать технические исправления порта (всегда включены) от изменений оригинальной механики;
  • провести аудит уже встроенных исправлений;
  • покрыть каждый переключаемый fix host/MAME тестом;
  • при необходимости добавить Advanced screen, не раздувая основной menu.

До этого момента нельзя рассыпать проверки if (enhanced) по горячему коду. Сначала составляется реестр и выбирается минимальная битовая модель.

13. Этапы реализации

этап результат критерий приёмки
MS0 определить команды app/menu и структуру settings UI не вызывает gameplay internals напрямую
MS1 проверить запись/rename/copy на HDD DSS crash/power-loss сценарий не теряет обе копии save
MS2 POP.CFG: defaults, load, validate, save повреждённый CFG безопасно даёт defaults
MS3 QuickSave hotkeys + POP.SAV/BAK полный критерий quicksave_plan.md
MS4 минимальный pause menu все семь пунктов доступны и корректно паузят игру
MS5 General/Gameplay Settings значения применяются и переживают рестарт
MS6 dialogs + backup recovery подтверждения и fallback на POP.BAK
MS7 Controls help полная актуальная раскладка на экране
MS8 интеграция с title/build info CFG применяется до первого экрана

QuickSave (MS1/MS3) можно реализовать раньше визуального menu: сначала F6/F9 и сообщения, затем подключить те же команды к пунктам UI.

14. Тесты

  • Host: CFG round-trip, defaults, bad magic/version/size/checksum.
  • Host: menu navigation, disabled items, confirmations, команды приложению.
  • Host: SAV invalid -> BAK valid; оба invalid -> NO QUICKLOAD.
  • MAME: F6, изменение сцены, F9; затем рестарт программы и повторный F9.
  • MAME: прервать запись/испортить SAV — BAK остаётся загружаемым.
  • MAME: pause на бое/падении, Resume не меняет состояние и таймер.
  • MAME: Settings сохраняются после полного выхода и запуска с HDD.
  • Проверка лимита 8 DSS handles на каждом error path.
  • make size-check; menu/text строки не должны съесть резидентный бюджет.

15. Не входит в план

  • Mods и выбор levelset;
  • уровень 15/copy protection;
  • несколько save slots;
  • replay/recording;
  • key rebinding;
  • SDL visual/controller options;
  • фактическая реализация ENHANCED и individual fix switches.