Статус-строка: LEVEL N и лейбл QS/QL до дисковой операции

* pop_status_level() — порт show_level (seg008:25A8): «LEVEL N» на старте
  уровня.  Демо-уровень 0 и номера от 14 молчат, тринадцатый показывается
  двенадцатым, бесшовный переход 12->13 пропускается и гасит флаг за собой.
  Первое сообщение с ПАРАМЕТРОМ: строка собирается вручную (dec2, без
  printf и без деления), номер хранится снимком st_arg — иначе вторая
  страница дабл-буфера нарисовала бы другое число.
* pop_status_show_now() — печать немедленно, в ВИДИМУЮ страницу.
  QuickSave/QuickLoad заявляют лейбл ПЕРВЫМ действием, до mem_alloc/ESTEX:
  запись снимка занимает доли секунды, и раньше игрок видел сначала
  необъяснённый фриз, а надпись — уже после него.  Отказ переписывает
  строку на NO QUICKSAVE/NO QUICKLOAD обычной заявкой.
  Расхождение с оригиналом (он печатает по результату) — impl_diff.md.

Проверено в MAME: watchpoint ловит заявку внутри pop_status_show_now,
step_out возвращает в pop_qsave_process — и QUICKSAVE уже на экране, диск
ещё не тронут.  Бюджет прежний: _CODE 23981, куча 266 Б.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-25 14:13:48 +03:00
parent 47a4b084c4
commit 5756101d29
6 changed files with 130 additions and 19 deletions
+26
View File
@@ -577,3 +577,29 @@ seg008.c:1600). XOR идёт по 24-битному RGB того, что УЖЕ
кайма станет резать глаз — вариантов два: запечь второй набор под светлый
фон (ещё 32 страницы EMM) или считать эту кайму прозрачной (силуэт станет
на пиксель уже). Оба хуже нынешнего; трогать только по факту жалобы.
## QuickSave/QuickLoad: лейбл печатается ДО дисковой операции, а не после
**Как в оригинале.** SDLPoP печатает `QUICKSAVE` / `NO QUICKSAVE` (и пару
для загрузки) уже ПО РЕЗУЛЬТАТУ операции — `process_quicksave` (seg000:497)
сначала делает save/load, потом зовёт `display_text_bottom` и ставит
`text_time_total = 24`. На PC это незаметно: файл пишется мгновенно.
**У нас.** `pop_qsave_process` заявляет строку ПЕРВЫМ действием, ещё до
`mem_alloc_pages`/ESTEX, через `pop_status_show_now()` — та печатает её
немедленно в ВИДИМУЮ страницу, не дожидаясь конца кадра. Отказ уже потом
переписывает строку на `NO QUICKSAVE`/`NO QUICKLOAD` обычной заявкой.
**Зачем.** Запись снимка на диск занимает доли секунды, и всё это время
игра стоит. При порядке оригинала игрок видел сначала необъяснённый фриз,
и только по его окончании — надпись, объясняющую то, что уже прошло.
Решение пользователя, 2026-08-25.
**Чем платим.** Строка успевает мигнуть даже там, где операция потом не
удалась: сначала `QUICKSAVE`, следом `NO QUICKSAVE`. На практике отказ —
редкость (нет места/диска), и «заявка → отказ» читается не хуже.
**Что проверять при регрессе.** Что после неудачной операции на экране
остаётся именно `NO QUICKSAVE`/`NO QUICKLOAD`, а не первая строка: отказ
идёт обычной заявкой и печатается кадровым проходом, то есть на кадр позже.
+13 -8
View File
@@ -139,18 +139,23 @@ display_text_bottom: draw_rect(чёрным) + show_text(halign_center, valign_b
## 4. Что из этого касается нашего порта
Реализовано:
Реализовано (`pop_status.c`, таймер 24 тика как у оригинала):
* `GAME PAUSED`в строке HP, без таймера (`pop_menu.c`).
* `GAME PAUSED` — без таймера, рисует само меню (`pop_menu.c`);
* `QUICKSAVE` / `NO QUICKSAVE`, `QUICKLOAD` / `NO QUICKLOAD` — заявка стоит
в `pop_qsave_process`, то есть в единственном месте, где известно, что
именно делали. Лейбл печатается ДО дисковой операции — осознанное
расхождение, см. `impl_diff.md`;
* `SOUND ON` / `SOUND OFF` — Ctrl+S;
* `LEVEL %d` — порт `show_level()` целиком: демо-уровень 0 и номера от 14
молчат, тринадцатый показывается двенадцатым, бесшовный переход 12→13
пропускается и гасит флаг за собой.
Есть у нас, но сообщение пока НЕ печатается (показывается иначе или не
показывается вовсе):
Пока НЕ печатается:
* `LEVEL %d` и вся группа времени — таймер уже есть (`pop_timer.c`), текста нет;
* `QUICKSAVE`/`QUICKLOAD` — у нас вместо строки экран-уведомление (`ui_notice`);
* `SOUND ON/OFF` — у нас индикатор в отладочной полосе, а не текст;
* вся группа времени — таймер есть (`pop_timer.c`), текста нет;
* `Press Button to Continue` — у нас авто-респавн по таймеру/стрелке вверх;
* номера комнат (`C`/Shift+`C`) — у нас палочки в отладочной полосе.
* номера комнат (`C`/Shift+`C`) — у нас отдельная отладочная строка.
Нам не нужно: copy protection (уровень 15 исключён из порта — см.
`full_game_plan.md`), joystick-режимы, replay, скриншоты.