Кодерам ---------------------------------------- Размышления о 3D ------------------ Николай Дворник /KilleRam/ В этой короткой статье я хочу рассказать о моей идее на счет создания универсального 3D движка на SPECCY для написания игр соответствующего направле- ния. Как мне кажется, наиболее удачно 3D реализовано в следующих программах: DOOM Ьу Digital Reality, Awaken Ьу Rage, Wolf 3D Ьу AlCo/i8, Stellar Game Ьу Brain- wave. Реализации, конечно, отличные, но до Delta Force'а и до Medal of Honor не тянут:). Я в смысле реализации полного ландшафта, а не тупого беганья по лаби- ринту (Awaken не в рамках стиля). Я предлагаю создать на SPECCY редак- тор на котором можно будет писать прак- тически любой 3d ActiOn. А точнее, чисто редактить зоны (подгружаем текстуры, создаем плоскости-обЪекты и "разрисо- вываем" их текстурами). Первое с чего я хочу начать - это таблица высот. Эта таблица хранит данные о высоте (z-координате), на которой бу- дет впечатываться тот или иной снимок (см. ниже). Длина этой таблицы 255 байт, при чем уровень 0 принадлежит плоскости ХУ, а квантование уровней идет в соот- ветствии с наименьшей высотой плоскости (см. ниже). ПРИМЕР: 1байт: уровень наинизшего снимка (ХУ) 2байт: уровень более высшего ... 192байт: уровень наивысшего снимка,час- тый случай которого - небо. Снимок - ортогональная, горизонтальная проекция уровня высоты. Формат снимка таков: Размер снимка (16х16 бит) 1линия массива снимка соответствует у=0 и хранит данные о впечатываемых плоскос- тях (см. ниже), минимальная ширина плос- кости 4pix (см. ниже). Например: Х | 0 | 4 | 8 | 12 | 16 | 20 | 24 | ---+---+----+----+----+----+----+----+ N | 1 | 2 | 3 | 4 | 1 | 3 | 4 | Это соответствует такому представлению: Х +-----------------------------------> | +---------------------------------+ | |1234134 и т.д до Х(мах)/4 | | | | | | | | | | | | | | | | | | | | +---------------------------------+ УС И так для каждой линии до У (мах) Хочу сказать, что максимальное количест- во плоскостей 111, а максимальный номер, роспознаваемый программой 255, при этом коды от 0 до 31 - управляющие (например, оповещают программу о впечатывании спрайта вместо плоскости и т.д.) Коды от 32 до 143 говорят программе о том, что плоскость с соответствующим номером впе- чатывается параллельно оси Х, а если ко- ды находятся в пределах от 144 до 255, то параллельно оси У. То есть, плоскость с номером 32 соот- ветествует плоскости с номером 144. Код 31 соответствует пустоте (ничего не впе- чатывается). Плоскость - массив содержа- щий данные о впечатываемых текстурах и их цвете. Максимальное количество текстур 222 (коды от 0 до 31 - управляю- щие). Размер текстуры 8x4pix, чтобы удо- бнее было разрисовывать. Пример формата 1байт - длина (ширина) 2байт - высота 3 |- размер в байтах 4/ далее идет Sбайт - номер текстуры ббайт - цвет и т.д. В памяти все хранится по порядку. В процессе подготовки ландшафта он пол- ностью преобразуется в координатную фор- му (над ней легче производить преобразо- вания), а потом в соответствии с полу- ченными координатами впечатываются текс- туры. - - - Свои мышления по-поводу этой идеи шлите либо в редакцию, либо мне лично по адресу: ул.Суворова 22, г.Енакиево-19, Донецкая обл., Украина, 86486 * * * Простой вывод спрайта ----------------------- Денис Токарчук /DWT/ Не знаю, возможно в каких-то источни- ках и было написано о подобном приеме вывода спрайта, но до него я дошел путем экспериментов. Как известно, спрайт в памяти компь- ютера расположен последовательно - строчка за строчкой. Однако спектрумов- ский экран имеет свои особенности, о ко- торых все прекрасно знают. Следователь- но, сложность вывода спрайта на спектру- мовский экран состоит в пересчете следу- ющей линии по оси У в экранной памяти. Существует множество способов выводить спрайт на экран - от "грубовысчитывае- мых" (но универсальных) до табличных и стековых. Я же предлагаю некий гибрид таблично-стековой выводилки спрайта. Конструкция такой программых чрезвы- чайно проста. Допустим, где-то в памяти с адреса TABL находится таблица примерно следующего вида: #4000, #4100, #4200, #4300 . . . #4020, #4120, #4220, и т.д. То есть адреса каждой последующей линии экрана в памяти. А по адресу SPR_V на- ходится программа непосредственно вывода спрайта: SPR_V LD (STACK),SP LD HL,адрес спрайта LD SP,TABL DUP высота в пикселях РОР DE DUP ширина в знакоместах LDI EDUP EDUP LD SP,0 STACK EQU $-2 RET Надеюсь, что комментарии к этому лис- тингу излишни, так как все ясно: поме- щаем в регистр DE из стека (который на- ходится у нас на таблице адресов экрана) значение текущей линии экрана, затем командами LDI перекидываем одну линию спрайта на экран (HL)->(DE), потом "сни- маем" со стека следующую линию, и так до конца. Элементарно, не правда ли?.. Однако по скорости выполнения эта конструкция (я ее называю РОР DE-LDI) не является самой оптимальной, хотя тоже довольно шустрая. Например, спрайт в 10х20 знакомест она выводит примерно за 27250 тактов. По-моему, неплохо. Другой вопрос - как бы ее сгенерить, чтобы довольно увесистый кусок кода не хранить эдаким балластом в программе. Прежде всего, необходимо сгенериро- вать таблицу адресов экрана (названную нами TABL), что довольно-таки просто. А затем нехитрой программкой создать собс- твенно выводилку. Ну а вот и пример: TABL EQU #6000 ;адрес, куда раз- ;мещать таблицу ;адресов экрана SPR_V EQU #8000 ;адрес, где будет ;находиться прог- ;рамма вывода сп- ;айта ADR_SCR EQU #4000 ;адрес экрана,ку- ;да печатать спр- ;айт SPR_НТ EQU 64 ;высота спрайта в ;пикселях SPR_WT EQU 8 ;ширина спрайта в ;знакоместах ORG #6200 ;формируем таблицу адресов экрана: МАКТАВ LD DE,TABL PUSH DE LD HL,ADR_SCR LD В,SPR_НТ МТ1 LD А,L LD (DE),А INC DE LD А,Н LD (DE),А INC DE INC Н LD А,Н AND 7 JR NZ,МТ2 LD А,L ADD А,#20 LD L,А JR С,МТ2 LD А,Н SUB 8 LD Н,А МТ2 DJNZ МТ1 ;а вот и сама генерилка программы вывода ;спрайта: МАКЕ_SV ;---------------------- LD HL,SPR_V ;Записываем по LD (HL),#ED ;адресу SPR_V ко- INC HL ;манду LD (..),SP LD (HL),#73 ;Адрес, куда SP INC HL,HL,HL ;запишется - вы- ;ясним позже ;---------------------- LD (HL),#31 ;Записываем по INC HL ;следующему адре- РОР DE ;су LD SP,TABL, LD (HL),Е ;то есть помещаем INC HL ;стек на адрес LD (HL),D ;таблицы адресов INC HL ; ;---------------------- LD С,SPR_НТ MSV0 LD (HL),#D1 ;по следующему ;адресу помещаем ;РОР DE INC HL ;---------------------- LD В,SPR_WT ;Записываем LDI MSV1 LD (HL),#ED ;SPR_WT раз (то INC HL ;есть ширина сп- LD (HL),#А0 ;райта определяе- INC HL ;тся количеством DJNZ MSV1 ;LDI) ;---------------------- DEC С ;Повторяем всю JR NZ,MSV0 ;конструкцию (РОР ;DE-LDI) SPR_НТ ;раз LD (HL),#31 ;Записываем в по- ;следующий адрес ;LD SP,.. INC HL ;И сохраняем сле- LD (SPR_V+2),HL ;дующий адрес ;в начало програ- ;ммы (куда сохра- ;нять стек) INC HL,HL LD (HL),#С9 ;Ну и в конце - ;RET RET После генерации программы вывода спрайта, можно ее запустить, не забыв перед CALL SPR_V записать в HL адрес спрайта. Вот и все что я хотел сказать:) - - -