| Разработка и ромхакинг > Ромхакинг и программирование |
| Sega MD VDP: Что оно такое и с чем его едят |
| << < (3/3) |
| vladikcomper:
--- Цитата: Segaman от 26 Июль 2011, 09:19:15 ---а на гофере дма шрифт жует :D --- Конец цитаты --- Ты про Соник 3 в 1? Где именно шрифты жуются? --- Цитата: Ti_ от 26 Июль 2011, 15:22:13 ---А как мне кажется должно работать и move.l d7,(a0) , то есть условие что содержимое должно находится в ram или в регистре. (баг то по логике происходит, потому что если что-то типа move.l #$12345678,(a0) , а команда эта и число 12345678, это находится в ром, и из ром же должна передача пойти,только с другого адреса) --- Конец цитаты --- Не уверен, что-то мне подсказывает, что если бы можно было адресовать из регистров, они бы обязательно про это упомянули. Но опять же, ничего конкретно сказать не могу, так как не представляю из-за чего такие ограничения берутся. Хотя можно будет попробовать, а так же ради интереса посмотреть, что будет, если нарушить все условия. |
| Segaman:
--- Цитата: vladikcomper от 27 Июль 2011, 23:00:32 ---Ты про Соник 3 в 1? Где именно шрифты жуются? --- Конец цитаты --- в твоей заставке с авторами сборника |
| Ti_:
--- Цитата: Segaman от 26 Июль 2011, 09:19:15 ---а на гофере дма шрифт жует :D --- Конец цитаты --- а дюна на гофере нормально работает? там сделали проверку если на переходах с 4F000 на 51000 и т.п. данные оказываются , то переносятся 2-умя кусками через dma. <_< |
| Nemesis_c:
нормально, только со звуком проблемы. |
| Segaman:
--- Цитата: Nemesis_c от 09 Август 2011, 00:08:46 ---нормально, только со звуком проблемы. --- Конец цитаты --- я играл, все чудесно. звук в меру жеванный. большой разницы от оригинала нет. имхо, играется чюдесно ^_^ |
| Segaman:
до меня доперло, чем основано неперекрашивание нескольких пикселей в начале при смене цвета во время отрисовки картинки. мне кажется всему виной обработка процедур в момент возникновения прерывания. дело в том что каждая команда занимает определенное колличество циклов. а так, как прерывание происходит во время исполнения какой либо команды, проц сначала доделывает операцию, а потом только сбрасывается на прерывание, что занимает некоторое время и является причиной недоперекрашивания. все гениальное просто :D и тут уж никуда не деться |
| vladikcomper:
--- Цитата: Segaman от 29 Ноябрь 2011, 18:21:02 ---до меня доперло, чем основано неперекрашивание нескольких пикселей в начале при смене цвета во время отрисовки картинки. мне кажется всему виной обработка процедур в момент возникновения прерывания. дело в том что каждая команда занимает определенное колличество циклов. а так, как прерывание происходит во время исполнения какой либо команды, проц сначала доделывает операцию, а потом только сбрасывается на прерывание, что занимает некоторое время и является причиной недоперекрашивания. все гениальное просто :D и тут уж никуда не деться --- Конец цитаты --- HBlank, согласно внутренним счетчикам VDP, занимает столько времени, сколько нужно на отрисовку 2 пикслелей на экране. Согласно документации, это эквивалентно 36 циклам M68K. (Я это называю по памяти, так что могу немного наврать в цифрах). Насчет "процессор сначала заканчивает обработку инструкции, а потом переключается на прерывание" - я тоже так думаю, хотя это только моя догадка, так как я не сильно разбираюсь в механизме обработки прерывания. Если оно так, действительно пара циклов может теряться. Однако крайне мало инструкций процессора занимают больше 10 циклов, и думаю, большая редкость застать длинную инструкцию в самом начале ее выполнения. В то же время, обработка самого прерывания тоже должна занять пару циклов процессора. Нужно сохранить в стеке значение PC (Program Counter - оффсет текущей инструкции), на котором произошло прерывание, а также значение SR (Status Register). Кстати, именно из-за того, что в стеке настраивается состояние SR, для возврата из прерывания нужна специальная инструкция RTE, а не обычный RTS. Но вряд ли может случиться так, что все эти операции по времени займут больше, чем само прерывание. Вот тот эффект про который ты говоришь, ты заметил в Канслвании. Но видел ли ты его когда-нибудь в Сониках? Я не видел, если только мельком в Соник 3 (в AIZ 2). Где-то на первой странице этого топика я высказывал мысль, что дело в медленном коде. Думаю, так и есть. Код прерывания не оптимален, понатыкан всякими бранчами, отнимающими время процессора, а может сам перенос цветов в CRAM сделан медленно (например, если перебрасывать по 2 байта, да еще и в цикле, потери времени будут огромны). Ну а если код еще написан на Си... Вобщем, из-за всего этого палитра не успевает переброситься вовремя, и уже начинается отображение новой строки с еще старой палитрой. |
| Segaman:
в сонике 3 просто спрайты с волнами на воде. изза них ничего и не видно. поправь меня если не прав. воще чтоб моск не парить не легче ли замутить DME переброс палитры? так и быстрее. вдруг успеет? ^_^ |
| vladikcomper:
--- Цитата: Segaman от 30 Ноябрь 2011, 19:09:36 ---в сонике 3 просто спрайты с волнами на воде. изза них ничего и не видно. поправь меня если не прав. --- Конец цитаты --- Спрайты в виде волн в Гидросити. И причем здесь мерцание пикселей? Мерцают спрайты. Зато посмотри как интересно проходит линия воды в Angel Island Zone: Я про этот уровень как раз и говорил. Здесь палитра меняется выборчно и в течении нескольких строк. Создается такой приятный эффект объемности. И только здесь, в AIZ2, в некоторых местах можно увидеть мерцающие пиксели, но они проходят через всю линию. --- Цитата --- воще чтоб моск не парить не легче ли замутить DME переброс палитры? так и быстрее. вдруг успеет? --- Конец цитаты --- Тоже задумывался, почему в Сониках перенос палитры во время прерывания не через DMA (насчет других игр не знаю). Думаю, дожна быть причина, Юджи Нака же крайне умный и умелый программист. Хотя, надо будет как-нибудь на досуге попробовать, заодно и проверить, как оно ведет себя на реальном железе. |
| Ti_:
--- Цитата: vladikcomper от 30 Ноябрь 2011, 22:36:33 ---Тоже задумывался, почему в Сониках перенос палитры во время прерывания не через DMA (насчет других игр не знаю). --- Конец цитаты --- Если малое количество данных нужно отослать, без дма быстрее. На само его включение больше уйдет времени, это раз. Второе - во время отображения скорость одинаковая. |
| Segaman:
нуда. так можно отправить сначал одну палитру, потом другую. а период между ними поставить воще не вопрос :) кстати в комикс зон творят с этим чюдеса. взять последнюю 5 и 6 страницы. вода там очень хитрая. |
| Segaman:
вопрос знающим людям. ситуация такая. пишу свою игру на сега. написал свой движ отображения спрайтов и столкнулся с такой проблемой. не могу согласовать приоритеты между спрайтами. почему то 0й показывает последним. и еще не много не впетрю, как приоритет контролируется между слоями, если он в спрайте имеет всего один бит. |
| Ti_:
--- Цитата: Segaman от 15 Декабрь 2011, 10:40:21 ---почему то 0й показывает последним. --- Конец цитаты --- Так сделано значит, счет с 1 по 79 , а 80-ый (0-ой) последний. Смотри debug-vdp sprites. Приоритет если 1 значит точно всегда сверху спрайт. Если 0 - то, видимо еще зависит от того какой приоритет в тайлах в фоне. |
| vladikcomper:
--- Цитата: Segaman от 15 Декабрь 2011, 10:40:21 ---вопрос знающим людям. ситуация такая. пишу свою игру на сега. написал свой движ отображения спрайтов и столкнулся с такой проблемой. не могу согласовать приоритеты между спрайтами. почему то 0й показывает последним. и еще не много не впетрю, как приоритет контролируется между слоями, если он в спрайте имеет всего один бит. --- Конец цитаты --- С нулевым спрайтом все логично - вначале VPD отображает его, потом он перекрывается следующим по списку тайлом, и так далее, что в итоге оказывается последним. Флаг приоритета используется, чтобы поместить спрайт поверх всех планов, удобно для того, чтобы сделать HUD, например. Без флага приоритета спрайт отображается поверх планов А и Б, и его могут перекрыть только тайлы планов А и Б с высоким приритетом. Вот как контроллер приоритетов VDP распределяет слои (приритеты даю по возврастанию): 1) Фоновый цвет 2) План Б с низким приоритетом 3) План А с низким приоритетом 4) Спрайты с низким приоритетом 5) План Б с высоким приоритетом 6) План А с высоким приоритетом 7) Спрайты с высоким приоритетом Низкий приоритет - это когда у спрайта или тайла на плане бит приоритета равен 0, высокий - 1. |
| Segaman:
спасибо большое, проблема разрешилась ^_^ |
| Segaman:
опять проблема. с горизонтальным прерыванием. хочу затемнить нижнюю часть экрана, а вместо этого максимум получается мерцание по 2 половинкам экрана. т.е. сначала сверху светло, снизу темно, а на след кадре уже вверху темно, внизу светло из 2 часов попыток ничего путного невышло. узнал только что если записать 8A20 то горизонтальное прерывание будет происходить всегда через каждые 32 строки ($20) пробовал и это использовать, всеравно ничего не выщло :'( может я чтото упустил? |
| vladikcomper:
Горизонтальные прерывания - вещь очень прихотливая, тут если не уследить за какой-то малейшей деталью или не учесть мелочь - все пойдет комом. --- Цитата ---узнал только что если записать 8A20 то горизонтальное прерывание будет происходить всегда через каждые 32 строки ($20) --- Конец цитаты --- Все верно, регистр VDP $0A задает интервал в строках, через который нужно совершать горизонтальное прерывание. В VDP есть внутренний счечик горизонтальных линий, который уменьшается на единицу с каждой отрисованной линией, и когда он достигает нуля, случается горизонтальное прерывание (если включено), а в счетчик загружается значение регистра $0A. Помимо этого, счетчик автоматически обновляется на линии 0 (начало кадра) и на линиях 225-261 (период VBlank'а). Последнее означает, что во время VBlank'а горизонтальные прерывания случатся не должны. Важно отметить, что счетчик *не* обновляется как только в регистр $0A записывается новое значение. Он обновляется только при вышеописанных условиях. И это логично, иначе счетчик линий потерял бы привязку к началу рисования кадра. Поскольку кадр состоит из 224 линий, если задать счетчику значение меньшее, чем 112, горизонтальное прерывание случится больше одного раза. Segaman, если у тебя оно случается по нескольку раз за кадр, это может объяснить мерцание, а может, это какой-нибудь баг в коде. Если ты хочешь сделать прерывание только в одном месте, нужно позаботиться о том, чтобы после первого вызова, код прерывания в пределах одного кадра больше не выполнялся. Для этого можно сделать флаг в памяти и включать его в процедуре прерывания. И выходить из кода прерывания, если флаг включен. Потом, можно сбрасывать флаг в процедуре вертикального прерывания, чтобы к новому кадру он снова был чист. Также в коде горизонтального прерывания можно задавать регистру VDP $0A значение $DF, так, прерывание гарантированно случится не более двух раз (при следующем прерывании в счечик будет загружено значение $DF - 223 линии). |
| Segaman:
--- Цитата: vladikcomper от 14 Февраль 2012, 20:00:17 ---Горизонтальные прерывания - вещь очень прихотливая, тут если не уследить за какой-то малейшей деталью или не учесть мелочь - все пойдет комом. --- Конец цитаты --- это я уже уяснил. спасибо за хелп. чтоб я без вас делал ^_^ |
| Навигация |
| Главная страница сообщений |
| Предыдущая страница |