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

320 lines
14 KiB
Markdown
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.
# Pause menu и Settings для Sprinter PoP
Статус: **согласованный план, код не начат** (2026-08-21).
Связанные документы:
- [`full_game_plan.md`](full_game_plan.md) — автомат состояний, title,
demo, cutscenes и ending;
- [`quicksave_plan.md`](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 первой версии
```text
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 первой версии
```text
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-контракт:
```c
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 с диагностикой,
а не включает частично реализованный режим.
Будущий профиль задаёт маску возможностей централизованно:
```text
VANILLA -> текущий согласованный набор
ENHANCED -> будущий рекомендуемый набор fixes
CUSTOM -> только если позже действительно понадобится
```
До отдельного аудита существующие `fix_exit_door`, feather guard behavior,
jump grab и sound priorities не переключаются и считаются частью текущего
VANILLA.
## 6. Файл POP.CFG
Бинарный, компактный, версионированный формат:
```text
+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`](quicksave_plan.md). Здесь фиксируется UI и файловая
транзакция.
### Один слот и backup
Файлы:
```text
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, перерисовать обе страницы, перезапустить звук.
### Сообщения
Минимальный набор:
```text
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. Диалоги
Общий диалог подтверждения:
```text
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.