Fade: пересчёт палитры в пять раз дешевле, шестнадцать ступеней

Затемнение длилось около восьми секунд вместо заказанных двух. Причин
две, и обе измерены в MAME.

Первая: пересчёт палитры звался на КАЖДОМ кадре — сто с лишним раз за
fade, хотя ступеней всего восемь. Теперь пересчёт идёт только при смене
ступени, остальное время цикл просто ждёт луча.

Вторая: сам пересчёт стоил 2,44 млн тактов — почти шесть кадров.
Разложение показало, что заливка палитры через BIOS тут ни при чём
(136 тысяч на восемь вызовов). Съедали два цикла на C: 768 умножений
uint16 на канал и побайтовое копирование снимка из страницы шрифта.
Умножения заменены таблицей яркости на стеке (256 сложений, без единого
умножения), копирование — memcpy, то есть LDIR. Итог: 487 тысяч тактов,
в пять раз меньше.

Освободившийся запас потрачен на плавность: ступеней теперь шестнадцать
вместо восьми. Длительность fade считает POP_FADE_FRAMES — из 106 кадров
(2,13 с оригинала) вычитается то, что съедает сам пересчёт.

Host-тесты: 15 наборов. Проверено в MAME: заставка проходит цепочку
кадров штатно.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-26 10:14:55 +03:00
parent 0db4f94707
commit 5ede8b9045
5 changed files with 119 additions and 50 deletions
+17 -2
View File
@@ -899,10 +899,25 @@ load_intro у оригинала и так начинается с ожидан
тика, 128 тиков = 2,13 с; сцена перед уровнем 2 занимает с ними около семи
секунд. Наши четыре ступени укладывались в восемь сотых секунды, и сцена
выходила втрое короче. Теперь `INTRO_FADE = POP_T60(128)`, а ступеней в
`pop_ui_palette_dim` восемь вместо четырёх (7/8, 3/4, 5/8, 1/2, 3/8, 1/4,
1/8, 0 — каждая парой сдвигов, без умножения): на четырёх растянутых
`pop_ui_palette_dim` шестнадцать вместо четырёх: на четырёх растянутых
ступенях затемнение выглядело бы скачками.
**Цена ступени** (замеры в MAME 2026-08-26, такты 21 МГц; кадр 430 000):
| версия | такты | что изменилось |
|--------|-------|----------------|
| исходная | 2 440 000 | снимок копировался побайтовым циклом на C |
| + таблица яркости на стеке | 1 250 000 | 768 умножений uint16 заменены 256 сложениями |
| + memcpy для снимка | 487 000 | LDIR вместо цикла — главный выигрыш |
Из оставшихся 487 тысяч 136 тысяч — заливка палитры через BIOS (8 вызовов
`gfx_pal_load` по 17 000). Дальше можно было бы хранить готовые таблицы
яркости файлом, но при 1,2 мс на построение это уже незаметно.
ВАЖНО: ступень пересчитывается только когда она СМЕНИЛАСЬ. Наивный цикл
«ступень на каждый кадр» звал пересчёт сто раз и растягивал fade до
десяти с лишним секунд.
**Чего пока нет.** Финальный `won` (56): 115 с, 1,2 МБ, 78 страниц EMM —
в `POP_MUS_PAGES` (20) он не помещается даже теоретически. Ему нужен
КОЛЬЦЕВОЙ стриминг: держать в памяти несколько страниц и дочитывать в те,