Вспомним, с чего все начиналось
С прокрутки каждой строки командами RL(HL) + DEC L
Для двух одинаковых строк очевидный способ RL(HL) + LDD
Казалось бы, улучшать здесь нечего, однако...
В последних изысканиях получил интересный побочный результат
Cамая быстрая полная прокрутка двух совпадающих строк
получается с применением недокументированных команд
...итого 957 тактов (912 сама прокрутка) на ДВЕ растровые строкиКод:Вход: hl = ^массив 128 байт подрисовка ix = ^конец нечетной строки sp = ^конец четной = ix-256 rl (hl) правый бит inc l rl d,(ix-1) | rl e,(ix-2) | push de | всего 16 раз ... rl d,(ix-31) rl e,(ix-32) push de inc ixh переход на 2 строки ниже ld sp,ix inc ixh
Кроме того, данный способ заметно меньше страдает
от задержек медленной памяти фирменных машин
Аналогично делается переброска фона одинарными строками
из теневого буфера с одновременной его прокруткой
(ix = ^буфер с подрисовкой, sp = ^экран)
Один большой недостаток - направление только справа налево
Прихожу без разрешения, сею смерть и разрушение...
957 * 80= 76560
на 160 строк целый фрейм - многовато - надо же еще и обьекты стирать рисовать
С уважением,
Jerri / Red Triangle.
Мало ли кому пригодится... может быть даже мне
Я пока балуюсь автогенерацией процедур кусочной прокрутки
По первым грубым прикидкам даже самый примитивный вариант получается быстрее
Прихожу без разрешения, сею смерть и разрушение...
Просчитал кусочную попиксельную прокрутку пикового экрана
Получилось около 21000 тактов, считая строчные переходы
Но без учета предварительной подготовки (о ней потом)
Сначала излагаю сам принцип
Формат хранения ландшафта теперь не важен
лишь бы вовремя получать новый столбец подрисовки
Каждая символьная строка крутится динамически создаваемой процедурой
которая вызывается в кадре 4 раза (а всего в том же виде - 32 раза)
Установка регистров
а также сдвигом байта подрисовки устанавливается исходный бит переносаКод:Один раз на весь экран: B = правый обрыв (или левая стенка шахты) A'= not B (противоположная стенка) (C использовать нельзя, его испортит LDD) В начале строки: HL = адрес начального (правого) байта первой строки DE = адрес начального (правого) байта второй строки A = L = E
Сама процедура-скроллер состоит из следующих стандартных фрагментов
...ну и возврат по команде retКод:чистая вода и сплошная земля просто пропускаются: пропуск одного знакоместа (8 тактов) dec l dec e пропуск двух знакомест (12 тактов) dec l dec l ld e,l пропуск трех и более знакомест (15 тактов) sub N ld l,a ld e,a (внимание - N не всегда равно кол-ву пропускаемых) (корректируется поcледнее значение аккумулятора) правый обрыв или левая стенка шахты (22 такта) ld (hl),b ex de,hl ld (hl),b ex de,hl левый обрыв или правая стенка шахты (22 такта) exa ld (hl),a ld (de),a exa (указатель остался там же, нужен явный пропуск) (условно) правый склон (31 такт) sla (hl) ldd (условно) левый склон (31 такт) sli (hl) ldd эти два куска нужны только сразу после длинного пропуска из-за испорченного вычитанием прошлого переноса во всех остальных случаях используется rl (hl) ldd
Хочу заметить, что и вызывать оную процедуру тоже лучше всего через ret
потому что она будет постоянно "отползать" в младшие адреса каждые 8 кадров
по мере того как будут распакованы и добавлены в подрисовку следующие тайлы
Так что лучше просто корректировать адреса, раз и навсегда уложенные в скрипт,
временно адресуемый указателем стека (там же сортировку спрайтов удобно)
Конечно, "отползать" вечно процедура не может - не хватит памяти
на одну знакоместную строку может потребоваться до 128 байт
а каждые 8 кадров возможен еще прирост (а строк 20 штук)
Что делать? Сдвигать обратно каждый такой кусок слишком долго
Проще всего буфер закольцевать и разбить на две части командой ret
Скрипт получится примерно вот такой:
Подготовка тоже (даже вся сразу) должна жрать гораздо меньшеКод:^установка на первую строку ^скроллер1 голова ^скроллер1 хвост ^переход растровых строк ^скроллер1 голова ^скроллер1 хвост ^переход растровых строк ^скроллер1 голова ^скроллер1 хвост ^переход растровых строк ^скроллер1 голова ^скроллер1 хвост ^переход тайловой строки ^скроллер2 голова ^скроллер2 хвост ^переход растровых строк ... ... ... ^скроллер20 хвост ^переход растровых строк ^скроллер20 голова ^скроллер20 хвост ^завершение
Но если нужно, то размазать задачу по 8 кадрам довольно просто
Например 5 кадров дописываем головы ровно по 4 скроллера
Потом два кадра отмеряем хвосты на обрезку по 10 каждый
Восьмой кадр соответственно корректируем адреса и возвраты
С такой прокруткой мины наверно выгодно делать чистыми спрайтами
кроме разве что тросов, которые лучше в ландшафт засунуть
благо их мало (прокрутка пустого места не так страшна)
а вычистить столбик прямо на экране несложно
См. скриншот в аттаче
Светлыми точками помечены прокручиваемые тайлы
желтые - sla/sli, белые - rl, зеленые - ld
(черные остались с прошлого варианта)
P.S. Однако ветку давно пора перекидывать в "Программирование"![]()
Последний раз редактировалось Lethargeek; 06.12.2009 в 11:45.
Прихожу без разрешения, сею смерть и разрушение...
Бакграунд это еще не все
1.Спрайты как кидать?
2.скорость 1 или 2 пикселя за фрейм?
С уважением,
Jerri / Red Triangle.
Да хоть обычной ксоркой (ею же потом и стирать)
Хотя можно хитрее (например ксорить не сам спрайт, а разницу сдвига)
Только нужно ли - мина (или пушка) всяко хавает меньше 500 тактов
Мин таких на простом экране не больше 16 (на сложных и того меньше)
Плюс лодка, выстрелы, логика, то да се... где-то на 40000+ свободных тактов
Один, конечно (то есть вдвое плавнее оригинала при той же скорости)
Прихожу без разрешения, сею смерть и разрушение...
Разобрался, вник.
Здорово!Особенно если действительно 21000 тактов, не просчитался ли? Вот тут например:
надо бы в начале: ld a,l
В любом случае замечательно!
Оно по идее так и должно быстро скроллироваться. Т.к. в отличии от печатания тайлами, здесь не надо загружать адрес экрана и адрес тайла.
И в концепцию луча тоже хорошо укладывается:
1) затираем спрайты в знаколинии
2) скроллируем знаколинию
3) печатаем спрайты в знаколинии
Еще большой плюс - это то, что можно делать ландшафт любой красоты, а не только ограниченным набором тайлов. Да что тут говорить, это же готовый fantastic dizzy с плавным скроллом! А то тот прикол с хранением графики в 4 копиях, конечно, никуда не годился.
Там может слегка набежать только за счет строчных переходов
Возможно будут нужны задержки, чтоб луч не опередить
(c оценкой по длине процедуры скроллера)
Не надо - A в начале строки устанавливается и нигде не портится
Только нужно при дописывании головы последний N корректировать
а главное, все легко пихается в тот же скрипт
Сомневаюсь, у нас все-таки картинка достаточно специфическая, много сплошных квадратов
Разве что разбить на два кадра и окно урезать...
Ну для оставшихся-то немногих спрайтов еще как годится (уже в 8 копиях)
Но про них потом напишу, времени пока мало![]()
Прихожу без разрешения, сею смерть и разрушение...
1. Атрибуты где будут сдвигаться?
2. момент с уходом тайла за экран как решается?
С уважением,
Jerri / Red Triangle.
Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)