QuickSave: носитель — файл, а не EMM-страница
Пересмотр по вопросу пользователя. Первая редакция плана рекомендовала EMM-страницу — ошибка: взвешивала скорость и недооценивала главный сценарий. EMM-страница не переживает рестарт программы, а именно рестарт — тот случай, ради которого QuickSave и нужен: сцену каскада плит на 13/23 воспроизводит ТОЛЬКО ESC → запуск заново (perf_l13_room23.md §1). Снимок в ОЗУ там не помогает вовсе. Доводы за EMM при перепроверке оказались слабыми: лимит манипуляторов DSS ни при чём (один файл, гард _fd_guard и так стоит), а экономия на пути к файлу — одна строка. Разница в скорости некритична: 1,9 КБ на HDD не заметны на фоне полной перерисовки комнаты при загрузке. Добавлен шаг QS0 — проверить, что D: вообще пишется из-под MAME: если образ только на чтение, это меняет весь план, поэтому идёт первым. Критерий приёмки задачи: сохранить, выйти, запустить заново, загрузить — и оказаться там же. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -180,27 +180,49 @@ SDLPoP, сохраняются.
|
||||
|
||||
---
|
||||
|
||||
## 4. Куда писать снимок: EMM-страница, а не файл
|
||||
## 4. Куда писать снимок: файл, а не EMM-страница
|
||||
|
||||
Рекомендация: **основной путь — EMM-страница, файл опционален.**
|
||||
Рекомендация: **основной путь — файл `QUICKSAVE.SAV`; EMM-страница —
|
||||
необязательный второй слот.**
|
||||
|
||||
Мотивы:
|
||||
> Пересмотрено 2026-08-17 по вопросу пользователя «почему EMM, а не файл».
|
||||
> Первая редакция плана рекомендовала EMM — это была ошибка: она взвешивала
|
||||
> скорость и недооценивала главный сценарий использования. Разбор оставлен
|
||||
> целиком, потому что довод переносится и на другие «положить в память
|
||||
> вместо диска» решения.
|
||||
|
||||
- снимок 1,9 КБ, страница 16 КБ — влезает целиком, с запасом на рост;
|
||||
- свободно 215 страниц / 3440 КБ на старте ([[sprinter_emm_budget]]) — одна
|
||||
страница не заметна;
|
||||
- сохранение/загрузка становятся **мгновенными** (копия через W0), без
|
||||
обращения к DSS и без риска упереться в лимит манипуляторов;
|
||||
- не нужен путь к файлу и права на запись; на дискете запись ещё и медленная.
|
||||
**Решающий довод: EMM-страница не переживает рестарт программы,** а именно
|
||||
рестарт — тот случай, ради которого QuickSave и нужен. Пример из этого же
|
||||
проекта: сцену каскада плит на 13/23 воспроизводит ТОЛЬКО `ESC` → запуск
|
||||
заново ([`perf_l13_room23.md`](perf_l13_room23.md) §1, где перечислено,
|
||||
почему не годятся ни возврат в комнату, ни рестарт уровня, ни запись
|
||||
состояния отладчиком). Тем более снимок в ОЗУ не переживает перезапуск
|
||||
MAME, обязательный после каждой пересборки образа.
|
||||
|
||||
Цена: снимок не переживает выход из программы. Для отладочного инструмента
|
||||
(а QuickSave у нас в первую очередь именно он — быстро вернуться к месту
|
||||
бага) это ровно то, что нужно.
|
||||
| сценарий | EMM | файл |
|
||||
|---|---|---|
|
||||
| «переиграть это место ещё раз» | работает, мгновенно | работает, на HDD быстро |
|
||||
| «вернуться к багу после рестарта» | **не работает** | **работает** |
|
||||
|
||||
Файловый вариант (`QUICKSAVE.SAV` рядом с exe) делается тем же
|
||||
сериализатором и добавляется вторым шагом, если понадобится переживать
|
||||
рестарт. Общий обход состояния писать сразу так, чтобы «куда» было
|
||||
параметром — как у SDLPoP через `process_func`.
|
||||
Второй сценарий не закрывается ничем другим; первый закрывается обоими, и
|
||||
разница в скорости там некритична — 1,9 КБ на HDD ([[mame_hdd_test_disk]] —
|
||||
быстрый путь против дискеты) не заметны на фоне полной перерисовки комнаты,
|
||||
которая при загрузке делается в любом случае и стоит дороже.
|
||||
|
||||
Доводы за EMM, которые при перепроверке оказались слабыми: лимит
|
||||
манипуляторов DSS ни при чём (открываем и закрываем ровно один файл, гард
|
||||
`_fd_guard` в libc и так стоит), а «не нужен путь и права» — экономия одной
|
||||
строки.
|
||||
|
||||
Что остаётся за EMM: мгновенный слот для «переиграть» без обращения к диску.
|
||||
Делается тем же сериализатором и добавляется, если понадобится. Поэтому
|
||||
обход состояния писать сразу так, чтобы «куда» было параметром — как у
|
||||
SDLPoP через `process_func`.
|
||||
|
||||
**Проверить ДО кодинга:** пишется ли `test_hdd.chd` из-под MAME. Если образ
|
||||
только на чтение, файловый путь упрётся в это на первом же шаге и порядок
|
||||
работ придётся менять. Проверка дешёвая — записать пробный файл на `D:` из
|
||||
roomtest.
|
||||
|
||||
---
|
||||
|
||||
@@ -261,14 +283,20 @@ static void qs_walk(qs_io_t io) /* io = запись или чтение */
|
||||
| шаг | что | критерий готовности |
|
||||
|---|---|---|
|
||||
| **QS1** | Аксессоры/сериализаторы для `static`-состояния банковых модулей: `pop_trob.c` (`room_modif`, `room_seen`, `trobs`, `trob_seed`), `pop_room.c` (`mobs_live`), страница уровня (чтение `fg`) | хост-тест `tests-host/t_qsave.c`: обход туда-обратно на синтетическом состоянии даёт байт-в-байт исходное |
|
||||
| **QS2** | Ядро: `qs_walk` + запись/чтение в EMM-страницу, магия и версия, отказ при несовпадении | сохранение и загрузка **в той же комнате, без движения** — картинка и состояние не изменились |
|
||||
| **QS0** | Проверить, что `D:` пишется из-под MAME (пробный файл из roomtest) | файл создался и читается обратно после рестарта программы |
|
||||
| **QS2** | Ядро: `qs_walk` + запись/чтение файла `QUICKSAVE.SAV`, магия и версия, отказ при несовпадении | сохранение и загрузка **в той же комнате, без движения** — картинка и состояние не изменились |
|
||||
| **QS3** | Восстановление отрисовки (§6), включая обе страницы дабл-буфера | загрузка после перехода в другую комнату; нет мерцания через кадр |
|
||||
| **QS4** | Клавиши **F6/F9** (или свободные из `pop_cheat.h`) через `<kbd_raw.h>`, флаги `need_quick_save/load`, обработка **между кадрами** | загрузка посреди боя/падения не ломает `play_seq` |
|
||||
| **QS5** | Загрузка с **другого уровня** (перезагрузка уровня и атласов) | сохранить на ур. 2, уйти на ур. 12, загрузить — тайлсет и стражи верные |
|
||||
| **QS6** | Опционально: файл `QUICKSAVE.SAV` тем же сериализатором | снимок переживает рестарт программы |
|
||||
| **QS6** | Опционально: второй слот в EMM-странице тем же сериализатором | мгновенное «переиграть» без обращения к диску |
|
||||
|
||||
Порядок не переставлять: QS3 без QS2 нечего проверять, а QS5 обязан идти
|
||||
после QS3 — иначе смена тайлсета замаскирует ошибки восстановления.
|
||||
Порядок не переставлять: QS0 первым (он может изменить весь план), QS3 без
|
||||
QS2 нечего проверять, а QS5 обязан идти после QS3 — иначе смена тайлсета
|
||||
замаскирует ошибки восстановления.
|
||||
|
||||
**Главный критерий приёмки всей задачи:** сохранить состояние, выйти по
|
||||
`ESC`, запустить roomtest заново, загрузить — и оказаться там же. Именно
|
||||
этого сценария сейчас нет ничем, и ради него задача и делается.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -888,9 +888,13 @@ F6/F9). Значит повторяем не букву, а устройств
|
||||
и главное — **дабл-буфер**: перерисовать после загрузки надо ОБЕ страницы,
|
||||
иначе старая картинка мигнёт через кадр.
|
||||
|
||||
Размер снимка ≈ 1,9 КБ, поэтому основной носитель — **EMM-страница**
|
||||
(мгновенно, без DSS и его лимита манипуляторов), файл — опциональный
|
||||
шаг QS6.
|
||||
Носитель — **файл** (`QUICKSAVE.SAV`, ≈1,9 КБ), EMM-страница отвергнута:
|
||||
она не переживает рестарт программы, а именно рестарт — тот случай, ради
|
||||
которого QuickSave и нужен (сцену каскада на 13/23 воспроизводит только
|
||||
`ESC` → запуск заново). Мгновенный EMM-слот остаётся необязательным QS6.
|
||||
|
||||
**Критерий приёмки:** сохранить, выйти по `ESC`, запустить roomtest заново,
|
||||
загрузить — и оказаться там же.
|
||||
|
||||
### <a id="l1-speed"></a>L1-SPEED. Игра идёт быстрее оригинала (найдено 2026-08-01)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user