
Короче скормил нейронке исходники игры с задачей выйти на 50+ фпс, удалось не везде, но играется в разы лучше чем оригинал. Проверилось на фсеуксе, нестопии, месене - работает, на пунес виснет после выбор персонажа, разбирать почему - лень. У кого есть возможность, потестируйте пожалуйста на флешкарике и реальной консоли и напишите результат.
--
v09 - рекомендованная версия, но если прямо не запускается или вас очень сильно парит еę размер то см. ниже
v10 - размер с 640кб до 384кб уменьшен, но может быть небольшой откат в фпс 1-2 и какие-то баги (тесты особо не проводились). Оставляю оба рома на выбор.
Ниже более подробное описание составленное нейронкой.
# Contra Force [v09] — MMC3 accelerated preview
Задача проекта — уменьшить тормоза, сохранив уровни, графику и основные игровые механики. Ускорение получено изменениями кода игры, без разгона процессора в эмуляторе.
По записям прохождений средняя скорость во время игры выросла с **37,17 FPS у оригинала до 53,80 FPS у v09**. Катсцены, меню и паузы из расчęта исключены. Стабильные 60 FPS во всей игре пока не достигнуты.
## Что сделано от начала проекта до v09
### 1. Восстановлена сборка оригинальной игры
За основу взято дизассемблирование из проекта [NES-Games-Disassembly](https://github.com/cyneprepou4uk/NES-Games-Disassembly). Сначала исходники собраны в ROM, побайтово совпадающий с оригиналом.
Затем на тяжęлых сценах измерены расходы процессора: обработка объектов, столкновения, подготовка фона, сборка спрайтов и переключение банков памяти.
### 2. Ускорены повторные обращения к карте и сборка спрайтов
Добавлен кеш метатайлов — небольших блоков карты, к которым игра постоянно обращается при движении и проверках столкновений.
Для спрайтов последовательно проверялись кеширование готовых данных и относительных координат частей объекта. Эти эксперименты дали первые сокращения времени обработки и помогли определить следующие узкие места.
### 3. Перестроена организация игрового кадра
Это основной архитектурный этап проекта.
Расчęт игровой логики и подготовка спрайтов перенесены из длинного обработчика видеопрерывания в основной цикл процессора. Короткое видеопрерывание выводит только полностью подготовленный кадр.
Вместе с кадром фиксируются параметры прокрутки, графические банки и данные растровых прерываний. Убраны лишние копирования: готовые спрайты передаются через DMA напрямую, а команды фона читаются из подготовленного буфера.
### 4. Исправлены ошибки ранних ускоренных сборок
В версиях v02–v06 исправлены обнаруженные при тестировании регрессии:
- дрожание фона;
- чęрный экран и зависания при паузе, катсценах и переходах;
- повреждение нижней панели при вертикальной прокрутке;
- задержки разрушения объектов и оставшиеся изображения на фоне;
- скачки изображения при переходах на крылья самолęтов;
- неправильное поведение ракет и стрельбы;
- повреждение фона в сцене с вертолęтом.
Устранено смешивание данных разных кадров и сокращена работа, которую нужно успеть выполнить во время вертикального гашения.
Генератор случайных чисел также переработан, чтобы убрать зависимость случайных событий от изменившегося времени выполнения. Поэтому отдельные случайные ситуации могут отличаться от оригинала.
### 5. Добавлен заранее подготовленный вывод спрайтов
В v07 появился компилятор спрайтовых поз: **630 часто используемых шаблонов** преобразуются при сборке ROM в готовые процедуры вывода.
Это сокращает повторный разбор графических данных во время игры. Для остальных случаев сохраняется исходный обработчик.
### 6. Ускорены столкновения и служебная работа с объектами
В v08 переработан обход целей при проверках столкновений с сохранением их порядка и масок попаданий.
Также ускорены очистка таблицы спрайтов и расчęты камеры: повторяющиеся операции выполняются один раз за игровое обновление.
### 7. Дополнительные сокращения в v09
В текущую версию вошли:
- более раннее отсеивание неподходящих целей при столкновениях;
- копирование только необходимой части команд фона;
- прямое сохранение параметров готового кадра;
- повторное использование рассчитанной скорости объектов;
- сокращęнное переключение банков памяти во время игры.
Экспериментальные изменения, показавшие повреждение изображения или расхождения состояния, в v09 не включены.
## Сравнение с оригиналом
Измеряются **завершęнные игровые обновления**, а не только опросы управления. «Худшая секунда» — самое медленное полностью игровое окно из 60 видеокадров.
| Уровень | Оригинал: среднее | v09: среднее | Оригинал: худшая секунда | v09: худшая секунда |
|---|---:|---:|---:|---:|
| 1 | 42,44 | **58,71** | 30,05 | **45,07** |
| 2 | 40,80 | **56,67** | 30,05 | **42,07** |
| 3 | 36,57 | **50,23** | 23,04 | **32,05** |
| 4 | 34,51 | **53,85** | 29,05 | **39,06** |
| 5 | 32,82 | **48,74** | 30,05 | **38,06** |
| **Общее среднее** | **37,17** | **53,80** | — | — |
Это разные человеческие прохождения: маршрут, оружие, смерти и случайные события различаются. Таблица описывает результаты этих записей; всю разницу нельзя приписывать исключительно оптимизации.
Отдельно v08 и v09 сравнивались на одинаковых входах в пяти контрольных сценах — по 600 игровых обновлений. В этих тестах v09 дала дополнительное ускорение, а все 838 сравниваемых байтов состояния совпали на каждом обновлении.
Полная запись v09 воспроизведена в FCEUX 2.6.6: **65 596 видеокадров без расхождений записанных lag-флагов**.
## Что ещę тормозит
Тяжęлые сцены остаются. В выбранном пятисекундном отрезке третий босс даęт около **34,46 FPS**, бой с вертолęтом пятого уровня — **41,87 FPS**.
Около **27% игровых секундных окон** прохождения v09 остаются ниже 50 FPS. Работа над стабильными 50+ продолжается.
## Требования и запуск
Сборка использует стандартный **MMC3, mapper 4**:
- 512 КиБ PRG-ROM;
- 128 КиБ CHR-ROM;
- 8 КиБ PRG-RAM.
Для картриджа нужна MMC3-плата с соответствующей памятью. Оригинальная плата Contra Force — TLROM без рабочей RAM, поэтому немодифицированная плата оригинального картриджа для этой сборки не подходит. [Данные оригинального картриджа](https://nescartdb.com/profile/view/1152/contra-force).
Проверки проводились в FCEUX 2.6.6 без overclock. Проверка на реальной NES пока не проведена.