morozov
16.07.2021, 08:47
Привет!
С полгода назад поначитался форма и других интернетов, и на ностальгической новогодней волне решил попробовать дизассемблировать River Raid (https://github.com/morozov/river-raid-disasm). В отличие от автора подобного проекта о The Great Escape (https://github.com/dpt/The-Great-Escape), полную документацию со всеми картинками я вряд ли когда-то осилю. И в отличие от Batty (https://zx-pk.ru/threads/31932-dizassemblirovanie-igry-batty) ни на какую другую ретро-платформу портировать тоже не планирую, т.к. не умею.
Хотел довести проект до такого состояния, когда достаточно подробно смогу понимать логику движка, и переписать игру на чём-нибудь типа Ebiten (https://ebiten.org/). С одной стороны, можно было бы играть без эмулятора на всём, что движется; с другой, можно было бы устранить клешинг. Уж больно он противный в этой игре.
Пытаясь описывать логику отрисовки уровней, понял, что описанине словами будет недостаточно понятно, и стал прототипировать отрисовку на PHP (https://github.com/morozov/river-raid-php). Сравнивал с картами с maps.speccy.cz (https://maps.speccy.cz/map.php?id=RiverRaid&sort=4&part=18&ath=): не считая мостов (руки не дошли), вроде похоже и без клешинга!
Что сделано:
Файл ассемблера, который собирается с любого стартового адреса (значит Skookit всё расставил правильно).
Описаны все спрайты.
Описаны данные и логика построения уровней.
Описана логика выбора управления и начального уровня, переключения между игроками, некоторые структуры данных.
Мелкие исправления в инструкциях. Без нех некоторые переходы и метки указывали на один байт раньше, код работал на удачу и не переносился.
Мелкие исправления в спрайтах. У самолёта в одной из позиций по-прежнему отгрызен кусок левого крыла.
Более-менее интересное из того, что узнал по коду:
Логику второго игрока явно дописывали в последнюю очередь задней левой ногой. Куча дублирования кода, который по-хорошему нужно было бы обобщить.
Логика отрисовки островов и берегов сильно продублирована, хотя она абсолютно одинаковая. Может писали на каком-то высокоуровневом языке, и это компилятор так скомпилировал?
Данные об уровнях хранятся крайне неэкономно. Подробностей сейчас не вспомню.
Цвет корабля и цвет второго игрока (голубой) задаётся в одном и том же месте.
В коде есть несколько указателей, которые нигде не используются
Все спрайты продублированы в четырёх позициях со смещением в два пикселя, чтобы проще было отрисовывать, но истребители летят с такой скоростью, что используются только один или два спрайта.
За 10.000 очков дают бонусную жизнь. Сколько ни играл, не замечал (или не набирал столько).
Определение столкновения с объектом происходит прямо по данным на экране. Т.е. если поставить игру на паузу, нарисовать что-нибудь на экране с помощью POKE, в это что-то можно врезаться. Это приводит к багу, что если заправляться и стрельнуть в заправку, иногда можно себя взорвать (а точнее, врезаться во взрыв), хотя в основном такого не происходит.
По адресу #8561 есть экран с выбором управления, который нигде не выводится (см. ниже).
Счёт хранится прямо в виде ASCII-символов, и вся арифметика (например, добавление очков) выполняется вручную над символами, прямо как в школе столбиком.
Когда танк подъезжает к берегу, то на каждом шаге его координату нужно увеличить или уменьшить в зависимости от того, на каком он берегу. Так вот сначала она всегда увеличивается, а потом, если танк на правом берегу, уменьшается на вдвое большее значение. Может на низком уровне оно так и принято, но выглядит диковато.
По ходу работы предложил улучшение (https://github.com/skoolkid/skoolkit/issues/112) в Skoolkit, чтобы в снапшоте, который он делает из образа ленты, можно было инициализировать системные переменные. Наверное в этом плане River Raid – исключение, раз никому до меня такое раньше не требовалось.
Что не сделано? Куча всего. Более-менее подробно описана логика полёта снаряда танка на берегу, но поведение всех других объектов не описано. У многих меток временные названия типа "something", а добрая треть так и не названы.
В последние несколько попыток продолжить разбор натыкался на то, что не понимаю, что дальше делать. От этого весь запал иссяк. Решил оставить наработки здесь – вдруг кто-то захочет продолжить или хотя бы подскажет, куда дальше копать.
Спасибо за внимание.
Ссылки:
Репозиторий с разбором: https://github.com/morozov/river-raid-disasm
Репозиторий с отрисованными уровнями: https://github.com/morozov/river-raid-php
Неиспользуемый экран выбора управления:
75829
С полгода назад поначитался форма и других интернетов, и на ностальгической новогодней волне решил попробовать дизассемблировать River Raid (https://github.com/morozov/river-raid-disasm). В отличие от автора подобного проекта о The Great Escape (https://github.com/dpt/The-Great-Escape), полную документацию со всеми картинками я вряд ли когда-то осилю. И в отличие от Batty (https://zx-pk.ru/threads/31932-dizassemblirovanie-igry-batty) ни на какую другую ретро-платформу портировать тоже не планирую, т.к. не умею.
Хотел довести проект до такого состояния, когда достаточно подробно смогу понимать логику движка, и переписать игру на чём-нибудь типа Ebiten (https://ebiten.org/). С одной стороны, можно было бы играть без эмулятора на всём, что движется; с другой, можно было бы устранить клешинг. Уж больно он противный в этой игре.
Пытаясь описывать логику отрисовки уровней, понял, что описанине словами будет недостаточно понятно, и стал прототипировать отрисовку на PHP (https://github.com/morozov/river-raid-php). Сравнивал с картами с maps.speccy.cz (https://maps.speccy.cz/map.php?id=RiverRaid&sort=4&part=18&ath=): не считая мостов (руки не дошли), вроде похоже и без клешинга!
Что сделано:
Файл ассемблера, который собирается с любого стартового адреса (значит Skookit всё расставил правильно).
Описаны все спрайты.
Описаны данные и логика построения уровней.
Описана логика выбора управления и начального уровня, переключения между игроками, некоторые структуры данных.
Мелкие исправления в инструкциях. Без нех некоторые переходы и метки указывали на один байт раньше, код работал на удачу и не переносился.
Мелкие исправления в спрайтах. У самолёта в одной из позиций по-прежнему отгрызен кусок левого крыла.
Более-менее интересное из того, что узнал по коду:
Логику второго игрока явно дописывали в последнюю очередь задней левой ногой. Куча дублирования кода, который по-хорошему нужно было бы обобщить.
Логика отрисовки островов и берегов сильно продублирована, хотя она абсолютно одинаковая. Может писали на каком-то высокоуровневом языке, и это компилятор так скомпилировал?
Данные об уровнях хранятся крайне неэкономно. Подробностей сейчас не вспомню.
Цвет корабля и цвет второго игрока (голубой) задаётся в одном и том же месте.
В коде есть несколько указателей, которые нигде не используются
Все спрайты продублированы в четырёх позициях со смещением в два пикселя, чтобы проще было отрисовывать, но истребители летят с такой скоростью, что используются только один или два спрайта.
За 10.000 очков дают бонусную жизнь. Сколько ни играл, не замечал (или не набирал столько).
Определение столкновения с объектом происходит прямо по данным на экране. Т.е. если поставить игру на паузу, нарисовать что-нибудь на экране с помощью POKE, в это что-то можно врезаться. Это приводит к багу, что если заправляться и стрельнуть в заправку, иногда можно себя взорвать (а точнее, врезаться во взрыв), хотя в основном такого не происходит.
По адресу #8561 есть экран с выбором управления, который нигде не выводится (см. ниже).
Счёт хранится прямо в виде ASCII-символов, и вся арифметика (например, добавление очков) выполняется вручную над символами, прямо как в школе столбиком.
Когда танк подъезжает к берегу, то на каждом шаге его координату нужно увеличить или уменьшить в зависимости от того, на каком он берегу. Так вот сначала она всегда увеличивается, а потом, если танк на правом берегу, уменьшается на вдвое большее значение. Может на низком уровне оно так и принято, но выглядит диковато.
По ходу работы предложил улучшение (https://github.com/skoolkid/skoolkit/issues/112) в Skoolkit, чтобы в снапшоте, который он делает из образа ленты, можно было инициализировать системные переменные. Наверное в этом плане River Raid – исключение, раз никому до меня такое раньше не требовалось.
Что не сделано? Куча всего. Более-менее подробно описана логика полёта снаряда танка на берегу, но поведение всех других объектов не описано. У многих меток временные названия типа "something", а добрая треть так и не названы.
В последние несколько попыток продолжить разбор натыкался на то, что не понимаю, что дальше делать. От этого весь запал иссяк. Решил оставить наработки здесь – вдруг кто-то захочет продолжить или хотя бы подскажет, куда дальше копать.
Спасибо за внимание.
Ссылки:
Репозиторий с разбором: https://github.com/morozov/river-raid-disasm
Репозиторий с отрисованными уровнями: https://github.com/morozov/river-raid-php
Неиспользуемый экран выбора управления:
75829