ACNews
#52
16 сентября 2008 |
|
Графика - Три битплана.
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,...), потом данные оттуда вывести на экран внешней выводилкой.
Другие статьи номера:
Похожие статьи:
В этот день... 21 ноября