3 битплана
ьу Alone Coder
Придумал хитрый алгоритм, который на стандартном экране может
вывести 3 битплана с любыми сдвигами друг относительно друга (с
шагом в 2 пикселя).
По идее надо мегабайт памяти под это дело, но можно ограничиться
128K. Имеем карты битпланов в страницах (или в одной странице) и
4 разных горизонтальных сдвига графики в разных страницах. Карт
каждого битплана тоже нужно 4, чтобы обеспечить любой сдвиг по
вертикали.
Сначала просматривается верхний битплан, и на его основе в стеке
строится последовательность вызовов для его вывода. Кроме того,
строится биткарта, описывающая, что закрыто передним планом, а
что нет. Потом средний, таблица корректируется (знакоместа,
которые закрыты верхним, не обрабатываются). Потом нижний
(знакоместа, которые закрыты верхним и средним, не
обрабатываются). Потом по стеку вызываются процедуры вывода в
порядке нижний, средний, верхний. Проблема в том, что вывод
должен идти исключительно в 0-й экран (т.к. графика в
страницах). А при этом будет видно процесс обновления, даже если
в каждой строке обрабатывать все 3 битплана.
Непрозрачные знакоместа (всегда 768) в обработке занимают 113
тактов + в выводе 201 такт.
Прозрачные знакоместа (порядка 100, есть только в верхних
битпланах по периметру объектов) = 110 + 345.
Все остальные знакоместа - неиспользуемые (прозрачные или
neрeкрытыe вышeлeжащими битпланами) = 67 (на верхнем битnланe
60) + 24.
Итого примерно 240000 + 46000 + 129000 = 415000 тактов (8 fps на
нетурбо).
Для сравнения, LDIR трёх экранов (без наложения вообще) занял бы
387000 тактов.
middlelayerloop:
ld a,(de) ;занято в биткартe? 0/#ff
and (hl) ;прозрачное в битnланe?
jnz middlelayerused:
push af ;#0054
push af ;#0054
dec l
dec l
inc e
jp nz,middlelayerloop
middlelayernextline:
inc d
ld a,d
ср `конец_биткарты
jnc middlelayerloop
ret
middlelayerused:
ld b,a
dec l
ld с,(hl)
dec l
push ьс
ср `maskedgfx
jnc middlelayermasked
хог a
ld (de),a ;занято в биткартe
ld a,`A1
push af ;#ххЧЧ
inc e
jp nz,middlelayerloop
jp middlelayernextline
middlelayermasked:
ld ьс,A2
push ьс
inc e
jp nz,middlelayerloop
jp middlelayernextline
#0054:
рор af
inc e
ret nz
jp slice
A1:
рор hl
dup 8
ld a,(hl)
inc l
ld (de),a
inc d
edup
org $-1
ld d,b
inc e
ret nz
jp slice
A2:
рор hl
dup 8
ld a,(de)
and (hl)
inc l
хог (hl)
inc l
ld (de),a
inc d
edup
org $-1
ld d,b
inc e
ret nz
slice:
ld a,d
add a,8
ld d,a
ld b,a
ср #58
ret с
QUIT:
Можно добавить отдельные ветки для чисто чёрных и чисто белых
знакомест (выигрыш 88 тактов на выводе каждого, но проигрыш 14
тактов на каждый из 768+~100 проходов middlelayerused).
Хорошее ускорение - знакоместа 8(X)х16(Y), но тогда надо 8 карт
для каждого битплана, а не 4.
Разные реализации для игр и демо. В демо можно рассчитать время
рисования каждого кадра и как-то победить луч за счёт этого. В
играх этого сделать нельзя. Кроме того, нужны спрайты, и под них
надо выделить целый слой. Причём графика всех сдвигов спрайтов
должна быть в одной и той же странице (4K графики, включая
маску). И спрайты не могут накладываться друг на друга. Можно
сделать теневой экран, на нём проиграть 70000 тактов (но
выиграть 40000 тактов прозрачных знакомест в слое спрайтов) и
12K нижней памяти (LD:PUSH, хитро отсортированных, чтобы
сделать теневой экран, на нём проиграть 70000 тактов (но
выиграть 40000 тактов прозрачных знакомест в слое спрайтов) и
12K нижней памяти (LD:PUSH, хитро отсортированных, чтобы
выводить туда по inc h) - можно занять 0-й экран этим кодом. Или
90000 тактов и 7K (POP:PUSH). Зато экран будет обновляться
целиком, и можно спрайты накладывать, поверх них надписи и т.n.
Но будет ли игра зрелищной в ч/б? Скорее всего, нет. Надо цвет
на точку. Но там, наверно, надо рисовать не знакоместами, а
длинными непрерывными вертикальными линиями. В цвете на точку
теоретическое минимальное время (1/2 рор de:ld (hl),e/d:inc h *
24576) ~ 400000 тактов (8 fps в турбо). Причём это в случае
графики НЕ в странице. А если из страницы через чанковый буфер
(максимальный размер 224*128), то лишних 160768 тактов. Опять
делать чeрeсстрочно? (до 224*192). Чeрeсстрочно - не для игр.
В Livingstone 2 и других играх на том же движке было примерно 5
fps, познакоместно, в цвете.
Как перешагивать #3dxx, которая глючит на пентагонах со старой
прошивкой? Можно заполнять как обычно
(...,#Зсхх,#3dxx,#3exx,...), потом данные оттуда вывести на
экран внешней выводилкой.
Other articles: