Сегодня была куча работы, и завтра тоже будет. Но из принципа исправил пару глюков в принце, хоть понемногу но продвигаться надо 🙂
Исправил глюк с отображением количества жизней при входе в лабиринт (не сразу выводилось верное значение) и немного поправил фехтование (принц смещался на байт вперед при неудачной атаке, а должен оставаться на месте).
Два дня правил звуки, расставил вызовы событий, в которых временно вручную указывал канал для воспроизведения (левый/центр/правый). Все звучало. И вот пришло время все-таки написать процедуру автоматического определения канала для звука. И тут мне в голову пришло, что все данные у меня уже есть — в любой точке вызова звука всегда известен адрес в экране того объекта, который издает звук. Просто надо передать его подпрограмме добавления нового звука в очередь, а та сама вычислит в какой канал этот звук разместить. Пришлось снова пройтись по всем исходникам и поменять при вызове звука номер канала на адрес в экране. И, конечно, добавить вычисление канала в саму подпрограмму добавления звука в очередь. И все зазвучало!
Когда я добавил звуки поднимающихся и опускающихся решеток, то сразу заметил, что как-то много звуков стало. Решил посмотреть, как в оригинале все это звучит. И выяснилось, что в оригинале звук опускающейся решетки слышен только тогда, когда она видна. А вот поднимающуюся решетку слышно всегда и везде. Но есть один момент — решетка в третьем лабиринте (кто знает, тот поймет) все-таки тоже везде слышна при опускании. Реализовал все это дело и сразу стало гораздо тише. Сегодня исправил кучу звуков и сделал новые. Теперь мне прям нравится как все звучит, даже заигрался в принца )) Не совсем нравятся шипы, но может еще исправлю. И совсем не нравятся звуки качающегося пола. Как выяснилось, в оригинале сделано вообще хитро — если прыгать на одном и том же месте, то каждый раз качающийся пол издает разные звуки:
Мне пока не удалось получить такие звуки для AY. Тем более как-то их перемешивать. Завтра помучаю этот вопрос.
Alexander «Sandro» Tishin подсказал, что в первом лабиринте существует скрытый способ пройти мимо стражника без меча. Оказалось, что у меня этот вариант был невозможен — отсутствовала одна падающая плита. Поставил плиту, теперь все стало возможно.
Вот такие особенности вдруг выясняются. Раньше на них и внимания не обращал никогда.
Добавил звуки фехтования. Вроде бы получилось неплохо. На записи цвиркание какое-то попадается, но в самой игре таких звуков не было, видимо приколы оцифровки с эмулятора.
Сегодня сделал новый звуковой движок: очереди выкинуты, сделаны три вида приоритетов. Важные звуки могут прерывать любые звуки (пила должна всегда быть слышна), средней важности могут быть заглушены важными (пила заглушает решетку, но решетка глушит шаги). И он заработал! Теперь надо делать звуки более похожими и соблюдать стерео при выводе звуков, чтобы правая решетка звучала справа и т.д.
Идея с очередями звуков оказалась перебором. На самом деле очереди только мешали. Звуки становились в очередь, доигрывались целиком и это как раз оказалось лишним. Три фрезы, стоящие рядом, наглядно показали, что каждый звук должен прозвучать вовремя, а не когда закончится предыдущий.
Сегодня сделал часть движка, ответственного за звуки. Он принимает «заказы» на проигрывание звуков событий в определенном канале (левом, правом, среднем), ставит их в три независимые очереди и потом играет их по таймеру. Накатал небольшую программу проверки, которая сыпала события, движок успешно все переварил. Вылез один хитрый баг, из-за которого именно звук встающего скелета не воспроизводился в правом канале. Как всегда, после исправления удивился как вообще что-то игралось))
Вчерась ехал в поезде, прямо в поезде накатал менеджер звуков на AY, который раскодирует звуки afx-формата и выводит их в требуемые каналы. По приезду набрал — работает. Теперь ему можно подкидывать события типа «выдать звук упавшей плиты слева» и он его поставит в очередь и выведет слева, одновременно играя другие звуки в других каналах. В оригинальном принце на PC никаких стерео-эффектов нет, вроде бы. Почему? Посмотрим, как это будет звучать в самой игре) Должно быть интересно.
Звуки получаются очень маленькие по размерам данных — 20 байт, 70. Решил декодер в «psg» пока не делать, сделал сразу проигрыватель afx, тем более что регистр микшера все равно на лету приходится конфигурить.
Итак, занялся вплотную звуками. Как сделать звуки? Как обычно: записать с микрофона удары молотком по рельсу на фоне отбойного молотка, в лучших традициях ранних Депешей. Но вот незадача — нужны звуки на AY, в виде всяких там периодов и частот шума. Поискал софт для создания звуков, нашел несколько редакторов. Но мои синусоиды, нарисованные в стиле импрессионизма, никаких вменяемых звуков не выдавали. Пришлось смотреть как сделаны другие «сэмплы», звучащие круто. Математический смысл вроде понятен. Но вот как взять и нарисовать звук «железных челюстей, с грохотом смыкающихся, с низкочастотным ударом и металлический звоном»? Фиг его знает. Но я в итоге нарисовал:
Ок, звучание меня устроило. Вроде бы очень даже похоже и на удар и на звон такой с легким эхом:
Что с этим делать дальше? Редактор позволяет выгрузить звук в нескольких форматах: afx и двух вариантах текстового формата. В доке есть описание формата afx:
Формат одиночного эффекта, расширение .afx
Каждое прерывание кодируется последовательностью байт, их количество может изменяться в зависимости от изменений значений тона/шума/громкости в текущем прерывании. Сначала идёт информационный байт:
bit0..3 Громкость
bit4 Запрещение T
bit5 Изменение T
bit6 Изменение N
bit7 Запрещение N
Если установлен bit5, далее следуют два байта со значением тона; если установлен bit6 - байт со значением шума; если установлены оба этих бита - сначала идёт значение тона, потом шума; если не установлен ни один - сразу идёт следующий информационный байт.
Конец эффекта помечается последовательностью байт #D0,#20. Плеер должен определять её до вывода в регистры (сравнением значения шума на = #20). В редакторе за признак конца эффекта считается последнее ненулевое значение громкости, вне зависимости от остальных параметров.
Как я уже знал из различных док, примеров и ценных советов гуру, самый быстрый способ выводить звук на AY — писать в его регистры уже готовые данные, не вычисляя ничего на ходу. Иначе говоря, мне нужно было преобразовать мой AFX в PSG-формат. Порылся на просторах интернета — конвертера не обнаружил. Придется самому. Берем блокнот и декодируем:
-- 000
EF Инф байт 1110 1111
Громкость F (17)
bit 4=0 разрешено Т
bit 5=1 далее значит два байта со значением тона
bit 6=1 и еще байт шума
bit 7=1 запрещение шума
88 байт тона 210
0B байт тона 13
17 байт шума 27
-- 001
EE Инф байт 1110 1110
Громкость E (16)
bit 4=0 разрешено Т
bit 5=1 далее значит два байта со значением тона
bit 6=1 и еще байт шума
bit 7=1 запрещение шума
83 байт тона 203
0C байт тона 14
10 байт шума 20
Вколачиваю полученные значения в таблицу в исходник тестового «плеера», накиданного за 5 минут, которые просто хватает данные из этой таблицы и пишет в регистры 4,5,6,7,10 AY. Компилирую, запускаю — какое-то хрипение. Ну, особо никто и не надеялся, как всегда какой-то косяк. Ага, перепутал биты в канале управления регистра C. Исправляем, запускаем:
Оуууууееее!!
Теперь, правда, надо создать все другие звуки принца… А там, помимо бряцания и клацания, есть весьма непростые, типа перерубаемого принца, воплей падения и прочих звуков органического происхождения. Будем, значит, сочинять ))
Ну, и конвертер написать придется, а то на бумажке конвертить не очень интересно ))
Потребовалось некоторое время отвлечься на работу, бывает! Сегодня снова занялся принцем. Наконец-то исправил старейший баг с обрезанием рук принца при выходе их в верхний экран. Теперь принц висит на стене как положено:
Раньше же руки ему в этом случае обрезались по самую голову. Я уже как-то пытался исправить этот глюк но не нашел места, в котором бы вообще проверялась верхняя граница спрайта, т.к. писал это еще Женя. И сегодня я все-таки понял почему. Я не мог найти такого места, потому что нигде она и не проверялась. Если попадался вывод в элемент верхнего окна, то принц тупо не накладывался на этот элемент вообще, потому никаких запчастей выше уровня кирпича и не могло быть.
Исправил глюк, возникший после переделки вывода падающих плит (в сотый раз уже).
Заметил, что в принца уже можно играть как вполне в рабочую игру ))
Свежие комментарии