Category: Баги

30
Апр
2024

Внезапные грабли

Графика в текущем проекте (Dave) выводится с помощью AZBK, а точнее с помощью одной из графических фич AZBK — блиттера. Суть «азбучного» блиттера состоит в том, что ему можно давать пакет команд, который он читает себе в буфер и потом выполняет уже самостоятельно, не отнимая процессорного времени.

Читать далее

16
Апр
2024

Призраки и Блиттер

Наконец-то я победил эти «хвосты» при скроллинге! Можно делать игру дальше!

При больших сдвигах рулона среднего экранного слоя (где бродят Зомби) промелькивали объекты, которые должны были уже быть стерты. И борьба с ними заняла у меня три дня…

Пока я использовал блиттер в атоматическом режиме (он при этом сам стартует при каждом прерывании по вектору 100) — все было почти хорошо. Точнее, в эмуляторе было вооще все хорошо, а вот на реальном железе при глобальном скроллинге экрана иногда наблюдалось какое-то дергание экрана.  Этим, конечно же, было поручено заняться Тэду из будущего. При этом возникал вопросы о скоростном построении экрана из множества тайлов — ведь количество команд, которые можно скормить блиттеру за раз, ограничено.  А это значит, что лабиринт будет заполняться порциями, каждыя из которых будет выводиться при очередном прерывании по вектору 100 («кадровое»). С появлением в AZBK режима ручного запуска блиттера, эта проблема ушла — выдаем блиттеру пакет за пакетом и запускаем все это сами, не ожидая милостей от вектора 100. Заодно появилась возможность сбрасывать блиттеру фоновые задачи, типа «удали старые спрайты со скрытого экрана, а мы в это время посчитаем куда какому монстру сделать шаг». И вывод на экран стало возможно делать тогда, когда хочется, а не ожидая очередного «кадрового» прерывания. Вот тут и был подвох.

Как только я добавил Зомби, шагающих туда-сюда, потребовалось их еще и скроллить вместе с фоном, когда Дейв инициирует движение окна. При этом, когда скроллинг (вертикальный или горизонтальный) докручивался до максимума и надо было уже переключать окно, вдруг могли промелькнуть какие-то дополнительные фигуры Зомби, там, где их никак быть не могло. Я предположил, что это спрайты, которые не успели стереться, а это место экранной страницы было вытащено скроллингом на видимую область экрана.  Стало ясно, что эти вещи надо тоже теперь синхронизировать вручную — сдвиг рулонов и переключение видимой области экрана. Но когда пакет команд блиттеру ушел, то о том, что блиттер его обработал, можно судить только по биту 15 в регистре 177270. Т.е. надо ждать, когда этот бит сбросится в 0 и потом можно переключать  рулоны.

А рулоны двигаются совсем в другом месте — в подпрограмме перемещения слоев в зависимости от деятельности Дейва. Блиттер работает сам по себе где-то в фоне, а вот регистры скроллинга изменяют изображение сразу. Значит, нам в этой подпрограмме нельзя изменять сами регистры, нужно просто вычислять новые значения, чтобы применить их потом, сразу кучей, после того, как блиттер закончит стирать/выводить спрайты и все будет готово к отображению нового кадра. Причем желательно  это сделать как раз в момент обратного хода луча, чтобы было незаметно.

В итоге, я завел несколько переменных, содержащих копии регистров управления слоями экрана и движок теперь изменяет не сами регистры, а эти переменные. А перенос значений из этих переменных в сами регистры происходит в тот момент, когда все готово и блиттер завершил обработку команд.

Вот тогда призраки и были изгнаны и «дрожь земли» пропала!

Да, еще я напоролся на небольшие грабли: если пакет команд маленький, то блиттер так шустро его выполняет, что бит 15 (признак работы блиттера) и установиться не успевает. И это приводило к бесконечным ожиданиям «когда ты там начнешь команды обрабатывать??» и зависаниям.

13
Апр
2024

Призрачные Зомби

Переделал движок анимации монстров. В анимации Зомби каждая фаза движения стоит на экране 8 кадров, напрашивалось решение выводить на экран только один из этих спрайтов, первый. А потом 7 кадров пусть он себе стоит, не надо выводить его заново. Что и было реализовано. Получен, конечно, большой выигрыш в скорости обработки монстров. Но можно еще ускорить, если сдвинуть начальные фазы монстров так, чтобы они обновляли свои ключевые спрайты не одновременно.

Не обошлось без подводных камней: пакет команд в блиттер уходит сразу после получения «кадрового» прерывания, а вот изменения начального адреса отображения слоя видеопамяти — в процессе обработки скроллинга движком. В итоге иногда на экране мелькают призраки Зомби, которые не успели стереться. Идеи борьбы с этими «хвостами» у меня есть, завтра попробую реализовать.

Монстров на одном уровне в Дейве прямо толпы — количество их достигает 60 штук. Конечно, не все они видны и в реальной игре Дейва быстро сожрут при большом столпотворении, но все равно есть что оптимизировать…

23
Мар
2024

Если где-то закрывается дверь, значит это кому-нибудь не нужно!

Итак, чтобы было понятно в чем суть, объясню как устроен вывод лабиринта в Дейве (моем). Хранится он, конечно, в виде кодов объектов, но его ведь надо вывести на экран. Причем экран в Дейве скроллится во все стороны с произвольным смещением, значит надо или постоянно дорисовывать невидимые части и вдвигать их в видимое окно, или вывести сразу весь лабиринт тайлами и только двигать по нему окно отображения. Во втором случае рисовать больше ничего не надо, только смещай окно да и все. Как угодно можно смещать.

Тут начинаются (как обычно) ограничения.

  1. В контроллере AZBK можно вывести на экран любую область его памяти, просто указав «экран начинается с такой-то страницы».
  2. В контроллере AZBK максимальная длина строки для экранного отображения — 512 байт. Для используего в Дейве видеорежима (256х192,  256 цветов) это байт на точку. Значит, рисовать «полотно» можно только кусками 512х512, а не каким-то там гигантским холстом.
  3. Скроллинг окна есть аппаратный, как горизонтальный так и вертикальный. Это прекрасно. Но он сворачивает окно в кольцо. Т.е., если мы двигаем окно влево, то справа вылезает начало этого же самого окна. Хорошие новости — размер окна может быть 512х512, а видимая часть у нас 256х192. Значит, мы можем протянуть 256 «новых» точек рулоном из невидимой части. Но после этого все равно в окно вползет левый край этого же, пусть и большого, окна.

Каким же образом двигаться по большому холсту? Можно в невидимой части дорисовывать новую обстановку. Но Макс (MaxiolLtd) предложил идею покруче: «У нас же море памяти! Можно сделать кучу страниц и оперировать ими!».

Т.е. мы делаем две страницы 512х512 таким образом, что вторая страница ПОВТОРЯЕТ половину первой. И тогда, когда горизонтальным скроллом мы втянем влево эти правые 256 точек, мы может сбросить счетчик рулона на ноль, а начало экрана для отображения переключить уже на вторую страницу 512х512. Ведь у нас эти два куска по 256 точек полностью совпадают. И таким макаром двигать можно бесконечно — половину вкручиваем, перключаемся на следующую страницу. Расход памяти дикий, олды бьются в истерике «это не наш метод», ну да и пофиг, развлекаемся 🙂

Коряво нарисую как выглядит «мегаэкран» в моем ремейке Дейва:

Специально сдвинул квадратики, чтобы они не затерли границы друг друга. В целом, понятно, как это выглядит — по вертикали тоже надо продублировать половины (много половин, много, да).

Скролл заработал весело, но чуть позже стало понятно, что везде есть подводные камни — если на пересекающихся частях нужно что-то изменить (открыли дверь, к примеру), то ведь и скопировать теперь надо эти изменения на ВСЕ пересекающиеся части. Итого может быть от 1 до 4 копий одного места.

Вот тут и начались развлечения с дверями. Дело в том, что эти виртуальные видеостраницы 512х512 тоже состоят из страниц, которые имеют фиксированный размер 10000(8) байт. Блиттер, конечно, лихо рисует на них, ему только адреса подкидывай. 24-битные. Но надо еще и все «соседские отношения» помнить — кто на ком стоял. Причем, размеры у лабиринтов у всех разные, окошек 512х512 может быть разное количество и по вертикали и по горизонтали. Поэтому двери у меня два или три дня появлялись непонятно где (неверно считались смещения на соседних страницах), потом вроде открываешь дверь, идешь от нее, а она у тебя за спиной закрывается! Страница включилась с неоткрытым вариантом. Ну и все в таком духе.

Записал видеоролик, залил в ютуб и потом там заметил, что на 1:31 там мелькает снова закрытая дверь! Начал думать как это снова могло произойти и понял, что не учел того, что дверь имеет размеры 2х3 тайла и при этом может стоять на границе аж четырех страниц! Т.е. левая часть в одном окне, правая часть в другом, а нижняя половина еще черт знает где.

Но сегодня я их добил! Теперь можно в эти шкафы что-то и поставить. Ролик исправлять уже не стал, пусть останется для истории:

 

24
Янв
2024

The Goonies 1v7

  • исправлена работа с «битым» портом джойстика
  • добавлена обработка второй кнопки джойстика — работает как дополнительная кнопка «Вверх/Прыжок»
08
Янв
2024

Goonies, new fix

Игроки нашли еще один баг — при приземлении из прыжка «наискосок» иногда Балбес проваливался сквозь пол. Дело было в одновременном обнаружении и стены в полете и пола, но первой срабатывала обработка обнаружения стены, хотя пора было уже приземляться на пол. Исправлено.

07
Янв
2024

Goonies, new fix

Образ обновлен:

  • исправлено задание управление от джойстика (блокировка дребезга кнопок)
  • исправлены ошибки при ударах с ускорителем

 

30
Дек
2023

Первый фикс Goonies :)

Manwe Sands нашел ошибку — в MKDOS загрузка не работала как надо. Исправлено. По старой ссылке доступна исправленная версия.

Manwe — спасибо! Всех  с наступающим!

 

25
Дек
2023

Еще немного, еще чуть-чуть…

Исправил кучу багов:

  • исправлен тот самый противный баг с помиранием во время удара
  • исправлен глюк с Призраком на границе экрана
  • растущая стена переставала расти, если Балбес успевал перейти в соседнее окно
  • донастроен артефакт Часы
  • обнаружено единственное на всю игру место, где можно залезть по канату, который кончается на верхней границе окна, теперь это работает

Добавлено:

  • демо и заставка теперь прерывается и с помощью джойстика
  • поддержка MKDOS