новое слово в демомакинге :)
приветствую всех, считающих себя кодерами - крутыми и так себе! сегодня я попытаюсь вас удивить :)
современный кодинг (на спектруме, of coz) в основном основан на чанковых движках. и это правильно - ибо иначе очень сложно реализовать многие вещи. объяснять подробнее не буду - все было высказано уже весьма давно. тем более, выбор уже сделан...
чанки бывают разные. вопреки распространенному мнению всяких гопников, разбирающихся в коде, как я в китайской кулинарии, чанки - это не только квадратики 4х4 :) грубо говоря, чанки - это такая технология, при которой экран заполняется блоками, имеющими одинаковый размер; обычно изображение строится не сразу на экран, а в буфер; мы имеем произвольный доступ к любому элементу изображения, независимо от других (в отличие от нашего планарного экрана); и обычно мы рисуем картинку в большем количестве цветов, чем имеет наш zx (15, не забыли?) так как ликбез полных чайников не входит в мои планы, то на этом сумбурном описании я этот вопрос закрываю - кому надо, могут найти информацию в других изданиях (deja vu, demo or die, buzz, etc)
так вот - чанки бывают разные. на спеке в основном юзаются размером 4х4 (двух видов - пиксельные [refresh, dogma, inbetween] и мультиколорные [eye ache 1/2, rage, stellar contour]), так как это оптимальное соотношение между разрешением и объемом экрана. разновидности 8х8, как чисто атрибутные [любые демы годов 95-97], так и пиксельно-атрибутные [emergency, 63bit3, smile_4k], из-за низкого разрешения сильно проигрывают, так как сделать что-то нормальное в 32х24 почти нереально. о, забыл сказать - говоря о коде, я имею в виду 3d - ибо это наиболее сложное (следовательно и интересное) приложение кодерских способностей.
все это было опробовано очень давно (97й год), и многим уже набило оскомину. неужели нет никакой альтернативы?
а выход есть - и тоже давно известен. помните такие вещи higher state / 3sc, over the top / enigma, matricks / baze? ну да -я говорю о чанках 2х2.
многие кодеры, которые давно уже не новички, сейчас недоверчиво усмехаются. да-да, на первый взгляд пользы от такого размера чанок мало, так как экран увеличивается аж в 4 раза по сравнению с 4х4 (а, следовательно, и кадр будет строиться в 4 раза дольше) да и в память такой экран затолкать не так-то и просто. а использование крохотных окошек - далеко не выход. да еще фишка - в чанках 2х2 мы имеем всего 5 цветов, что ужасно мало для реализации освещения в 3d-частях (и phong, и gourado, и даже flat смотрятся просто ужасно). в довершение ко всему еще и c2p тормознее, так как приходится больше читать и меньше писать (по сравнению с 4х4, опять же).
но! я не стал бы просто так тратить ваше время (а заодно и свое, которое мне намного дороже :), если бы не реализовал чанки 2х2 в нашей деме, которую мы, к сожалению, не смогли привести на cafe'02, да и сейчас не можем никак довести до конца : ((( вот об этом я вам сейчас и расскажу...
наиболее просто решить проблему нехватки 5ти цветов. само собой дизеринг. кто не в курсе - в каком-то deja vu была хорошая статья про это. кстати, о птичках. сравнительно недавно в psychoz#11c была опубликована статья dark/x-trade о дизеринге в чанках 2х2. несмотря на все мое уважение к данному человеку, код дизеринга там ужасно слабый. еще в 2000м году мы на пару с baze/3sc придумали правильную
рутину c2p для чанок 2х2, а в своей интре matricks он как раз и применил дизеринг в 16 цветов (правда, c2p там его персональная более тормозная). код c2p такой:
sp - chunk screen de - 1st line on spectrum screen (#401f) bc - 2nd line on spectrum screen (#4120) pop hl ld a,(hl) pop hl ld l,(hl) ld h,a ldd ld a,(hl) ld (bc),a итого: 10+7+10+7+4+16+7+7= 68tct
[напомню, что у dark'а два знакоместа отрисовываются за 90+94 такта, то есть 92 такта в среднем]
вся хитрость в использовании команды ldd. небольшая особенность - картинка рисуется перевернутой по горизонтали, так как sp растет вверх, а bc и de уменьшаются. чанки вида %---xxxx0. для дизеринга прийдется ставить таблицы графики в разные банки и работать на одном экране. объяснять подробно не буду, так как это все равно уже пройденный этап :) кому все-таки интересно и непонятно пишите мне, объясню.
как видите, такая скорость вполне нормальна - весь экран отрисовывается примерно за 3 фрейма. но проблема слишком большого экрана остается -поэтому это неполноценное решение.
экспериментируя с разными движками и фильтрами, мне пришла в голову великолепная мысль :) а что если мы будем обсчитывать экран не полностью, а лишь частично а оставшуюся часть заполнять программно, скажем, через линейную интерполяцию? тогда можно будет не использовать тормозной фильтр (a la sair00s) для скрытия дефектов движка -то есть получаем выгоду и в скорости, и в объеме экрана. есть некоторая па-
раллель с амижным режимом ham8 (насколько я понял), где цвет группы пикселов зависит от узлового и последние демы работают в разрешении вовсе не 640х480 или 320х240, а намного меньше. так как я не амижник (совсем), то может быть сейчас сказал огромную глупость - но это неважно :) речь идет о спектруме.
что я подразумеваю под линейной интерполяцией? я обсчитываю не каждый чанк экрана, а через один по горизонтали - а пропущенные получаю как среднее между двумя уже известными. типа так:
так делают обычно: !c0! c1! c2! c3! c4! c5! c6! c7! c8! а так делаю я: !c0!--!c2!--!c4!--!c6!--!c8! (c0+c2)/2 (c4+c6)/2
в результате картинка получает некоторую смазанность, которая лично меня устраивает :) все равно выдавать сразу чанковый экран немного рисковано, ибо из-за низкого разрешения и упрощенных шейдеров картинка часто получается, так сказать, страшноватая :) в последних демах sair00s примерно так же интерполирует два экрана - я же обошелся одним.
если интерполяцию проводить отдельной операцией, то никакой выгоды в скорости мы не получим, так как дело это не слишком стремительное (достаем из памяти два числа, складываем, по таблице достаем результат и заносим его в память - тактов 40 на один чанк уйдет). поэтому я извратился и совместил интерполяцию с c2p:
sp - chunk screen de - spectrum screen h - previous chunk pop bc ld a,(bc) ld l,a ld a,(hl) ld (de),a inc h inc d ldi dec d ld h,b итого: 10+7+4+7+7+4+4+16+4+4= 67tct
мдаааа :) попытаюсь объяснить доступно.
для того, чтобы отрисовать знакоместо, (8х2 пиксела) нам надо учитывать 3 чанка:
! ! ! ! -- c0 -- c1 ! -- c2 -- c3 ! ! ! ! ^ ^ ^
у нас есть 16 таблиц (так как чанк в предыдущем знакоместе может быть любого цвета), и адрес графики высчитывается так (для второго знакоместа):
c1*#0100 + c2*#0010 + c3
чанки вида %110хххх0, те #e0-#fe. в конце сектора находится таблица младших адресов графики, то есть с адресов #e0e0, #e2e0, etc. в самих же 32 секторах находится графика.
нестыковка вышла - так как графика и таблица умножения расположены в одних и тех же адресах, то происходит их наползание друг на друга. я обошел это, выкинув два цвета :) то есть у меня не 16 реальных цветов, а 14. но так как удобнее работать в шестнадцати цветах, поэтому я просто совместил 0 и 1, 14 и 15 цвета (в таблице "умножения" выставлены одинаковые значения). можно вообще-то сделать и честные 16 цветов, но только за счет замедления c2p -поэтому я выбрал такой выход.
дизеринг у меня сделан при помощи двух банок с разной чанковой графикой - для четных строк и для нечетных. все это жрет много памяти, да еще и работает на одном экране :)
что же нам все это дает? мы имеем следующее - по сравнению с чанками 4х4 размер экрана увеличился в два раза (а не в четыре), экран полностью отстраивается примерно за три фрейма, нам не нужен дополнительный фильтр, качество картинки на порядок лучше (еще бы, ведь чанк уменьшился в 4 раза). то есть мы проигрываем в скорости, но выигрываем в качестве. на таком движке вполне возможно что-то делать, что мы и попытались доказать в своей деме.
в приложении к журналу вы найдете исходники генерилки чанковой графики и c2p в текстовом формате, но к сожалению для многих, с синтаксисом storm'а :) а также небольшую демонстрацию движка.
respect to all spectrum's coders and adventurer's readers!!!
(c) triebkraft
я, конечно, слегка стормозил со своей статьей (а заодно и с демой : ( ), и чтоб хоть как-нить скомпенсировать этот негативный момент, предлагаю вашему вниманию оптимизированный вариант c2p-рутины с интерполяцией. написал его jtn//4d, комментариев не будет :) принцип работы такой же, да и вообще - надо головой больше думать.
pop hl ;10 l,(hl) ;7 ld a,h ;4 exa ;4 ld h,a ;4 ldd ;16 ld a,(hl) ;7 ld (bc),a ;7 ;=59t!!!!!!!!!!!