From 0cae2cb32a1b1160e6b9fcbf39644f6bfb248b68 Mon Sep 17 00:00:00 2001 From: Alexander Petrov Date: Mon, 17 Aug 2026 23:01:14 +0300 Subject: [PATCH] =?UTF-8?q?QuickSave:=20=D0=BD=D0=BE=D1=81=D0=B8=D1=82?= =?UTF-8?q?=D0=B5=D0=BB=D1=8C=20=E2=80=94=20=D1=84=D0=B0=D0=B9=D0=BB,=20?= =?UTF-8?q?=D0=B0=20=D0=BD=D0=B5=20EMM-=D1=81=D1=82=D1=80=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D1=86=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Пересмотр по вопросу пользователя. Первая редакция плана рекомендовала 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 --- applications/PoP/docs/quicksave_plan.md | 68 +++++++++++++++++-------- applications/PoP/roomtest/TASKS_OPEN.md | 10 ++-- 2 files changed, 55 insertions(+), 23 deletions(-) diff --git a/applications/PoP/docs/quicksave_plan.md b/applications/PoP/docs/quicksave_plan.md index 650bce3..c459d5c 100644 --- a/applications/PoP/docs/quicksave_plan.md +++ b/applications/PoP/docs/quicksave_plan.md @@ -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`) через ``, флаги `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 заново, загрузить — и оказаться там же. Именно +этого сценария сейчас нет ничем, и ради него задача и делается. --- diff --git a/applications/PoP/roomtest/TASKS_OPEN.md b/applications/PoP/roomtest/TASKS_OPEN.md index 4896f96..bfbf4fe 100644 --- a/applications/PoP/roomtest/TASKS_OPEN.md +++ b/applications/PoP/roomtest/TASKS_OPEN.md @@ -888,9 +888,13 @@ F6/F9). Значит повторяем не букву, а устройств и главное — **дабл-буфер**: перерисовать после загрузки надо ОБЕ страницы, иначе старая картинка мигнёт через кадр. -Размер снимка ≈ 1,9 КБ, поэтому основной носитель — **EMM-страница** -(мгновенно, без DSS и его лимита манипуляторов), файл — опциональный -шаг QS6. +Носитель — **файл** (`QUICKSAVE.SAV`, ≈1,9 КБ), EMM-страница отвергнута: +она не переживает рестарт программы, а именно рестарт — тот случай, ради +которого QuickSave и нужен (сцену каскада на 13/23 воспроизводит только +`ESC` → запуск заново). Мгновенный EMM-слот остаётся необязательным QS6. + +**Критерий приёмки:** сохранить, выйти по `ESC`, запустить roomtest заново, +загрузить — и оказаться там же. ### L1-SPEED. Игра идёт быстрее оригинала (найдено 2026-08-01)