ZX Forum
#04
19 ноября 1997 |
|
Технология спрайтов - часть 8: печать спрайтов (координаты заданы в знакоместах).
ПЕЧАТЬ СПРАЙТОВ (КООРДИНАТЫ ЗАДАНЫ В ЗНАКОМЕСТАХ) Теперь мы с Вами рассмотрим простейшие процедуры для печати спрайтов. Вся их простота сос- тоит в том, что координаты печа- ти задаются в знакоместах. Это самые быстрые и в то же время не такие уж и нужные процедуры, но мы должны их рассмотреть, пос- кольку они дают основу для всех процедур печати спрайтов. Рассмотрим основную структу- ру данной процедуры. Из чего она должна состоять: давайте посмот- рим на данные, которые у нас имеются к этому моменту: это длина и высота спрайта, его ад- рес в блоке и координаты печати. Первым делом нам надо получить адрес в экране, который бы соот- ветствовал нашим координатам пе- чати, а вычислить нам ее помо- жет простенькая програмка: 140. ------------------------------------- 3(C) 1994 А.А.Иванов (ZX-Ревю N3 1994) ------------------------------------- ADR LD A,L AND 7 RRCA RRCA RRCA ADD A,H LD H,L LD L,A LD A,H AND #18 OR #40 LD H,A RET 2 Теперь абсолютно все данные у нас есть и нам не остается ниче- го, кроме как напечатать спрайт на экране. У нас есть еще нес- колько данных - это длина и вы- сота спрайта. Вы не задумыва- лись над тем, какое из этих чи- сел важнее? Сейчас самый момент об этом подумать, поскольку от этого зависит скорость работы Вашей процедуры. Если Вы взгля- нете на данную ранее схему хра- нения спрайта, то без труда смо- жете ответить на этот вопрос. Итак, главной здесь является вы- сота спрайта, при помощи ее мы и организуем первый цикл печати. Теперь настал момент дать всю процедуру полностью. 140. SETSPR LD HL,(COORD) ;Заносим в HL координаты печати. CALL ADR ;Вычисляем адрес в экране. LD DE,(ADRSPR) ;В DE заносим адрес данных спрайта. LD A,(LENHGT+1);В регистр A заносим высоту спрайта. LD B,A ;В регистре B высота спрайта в пик- ;селях. SETSPR1 PUSH HL ;Сохраняем адрес в экране. LD A,(LENHGT) ;В регистр A заносим длину спрайта. LD C,A ;В регистре C длина спрайта в знако- ;местах. SETSPR2 LD A,(DE) ;Берем байт маски/спрайта. IZM AND (HL) ;Накладываем по AND/OR на байт экра- ;на. Это зависит от того, что мы пе- ;чатаем - маску или спрайт. LD (HL),A ;Переписываем экран. INC DE ;Переходим к следующему байту маски - ;спрайта INC HL ;Переходим к соседнему знакоместу эк- ;рана. DEC C ;Уменьшаем длину спрайта. JR NZ,SETSPR2 ;Если длина не равна 0, продолжаем ;печатать в длину. POP HL ;Восстанавливаем адрес в экране. CALL DOWN ;Переходим к следующей пиксельной ли- ;нии снизу. DJNZ SETSPR1 ;Если высота не равна 0, продолжаем ;печатать. RET ---------------------------------------- 3(C) 1995 Старков Павел (ZX-Ревю N4 1995) ---------------------------------------- DOWN INC H LD A,H AND #07 RET NZ LD A,L ADD A,#20 LD L,A RET C LD A,H SUB #08 LD H,A RET 2 Теперь давайте попробуем на- печатать на экране спрайт с мас- кой из игры 3D BATMAN. Посмотри- те, как будет выглядеть данная программа: 140. PRINSPR LD HL,(COORD) ;Берем координаты печати. CALL ADR ;Вычисляем адрес в экране. PUSH HL ;Сохраняем. LD DE,(ADRSPR);В DE адрес спрайта в памяти. CALL SETSPR ;Накладываем маску. POP HL ;Восстанавливаем адрес в экране. LD A,#B6 ;Изменяем команду AND (HL) на OR (HL). LD (IZM),A CALL SETSPR ;Печатаем спрайт. LD A,#A6 ;Восстанавливаем команду AND (HL). LD (IZM),A RET SETSPR LD A,(LENHGT+1) LD B,A SETSPR1 PUSH HL LD A,(LENHGT) LD C,A SETSPR2 LD A,(DE) IZM AND (HL) LD (HL),A INC DE INC HL DEC C JR NZ,SETSPR2 POP HL CALL DOWN DJNZ SETSPR1 RET 2 Как видно из этой программы, мы спрайт печатали как бы 2 ра- за, что работает не совсем быс- тро и говорит не в пользу подоб- ному формату хранения. Теперь давайте напечатаем спрайт к программе ELEFANT-1: 140.PRINTSPR LD HL,(COORD) CALL ADR LD DE,SPRDATA LD B,HGT SETSPR1 PUSH HL LD C,LEN SETSPR2 LD A,(DE) ;Берем байт маски. AND (HL) ;Объединяем его с байтом экрана. INC DE ;Переходим к байту спрайта. EX DE,HL ;Временно меняем HL и DE местами, так ;как OR (DE) нет. OR (HL) ;Печатаем байт спрайта. EX DE,HL ;Восстанавливаем DE. LD (HL),A ;Перерисовываем экран. INC DE INC HL DEC C JR NZ,SETSPR2 POP HL CALL DOWN DJNZ SETSPR1 RET 2 Это самая быстрая из всех приведенных до этого процедур печати и наиболее эффективная. Хочу заострить Ваше внимание на следующем моменте - поскольку байт маски и байт спрайта чере- дуются между собой, то длина спрайта может составлять не 3 знакоместа, а 6 (здесь 6 может появиться, если программа, со- здающая спрайты, не учитывает этот момент), тогда Вам следует перед занесением длины в регистр C уменьшить ее в два раза коман- дой SRL A. Особенностью дан- ной программы является то, что спрайт на экране появляется плавно, поскольку при печати спрайта предыдущими (особенно первой) программами, если спрайт довольно велик, можно увидеть мерцание экрана. Ну, а теперь нам осталось на- печатать спрайт из программы JACK THE NIPPER-2. Здесь тоже стоит обратить Ваше внимание на то, что в заголовке длина может указываться неправильно: может быть указана общая длина маски и спрайта, и вам придется C так же разделить на 2, как и в предыду- щей процедуре: 140. PRINTSPR LD HL,(COORD) CALL ADR LD DE,(ADRSPR) LD A,(LENHGT+1) LD B,A SETSPR1 PUSH HL LD A,(LENHGT) LD C,A SETSPR2 LD A,(DE) ;Печатаем линию маски. AND (HL) LD (HL),A INC DE INC HL DEC C JR NZ,SETSPR2 POP HL ;Восстанавливаем адрес в экране. PUSH HL ;Вновь сохраняем его. LD A,(LENHGT) LD C,A SETSPR3 LD A,(DE) ;Печатаем линию спрайта. OR (HL) LD (HL),A INC DE INC HL DEC C JR NZ,SETSPR3 POP HL CALL DOWN DJNZ SETSPR1 RET 2 Я не стал давать подробные комментарии к этой процедуре, она практически дублирует вто- рую и отличается от нее лишь расположением структурных эле- ментов. Предыдущие спрайты мы печата- ли без атрибутов; чтобы напеча- тать атрибуты спрайтов, надо до- бавить к этим процедурам еще од- ну небольшую. Для второй проце- дуры ее надо оформить в виде подпрограммы и вызывать через CALL в конце головной программы. Для печати атрибутов спрайта нам нужен адрес в экране, кото- рый мы получили после вызова подпрограммы ADR, для этого HL надо сохранить дважды, а не один раз, как в предыдущих вариантах. Для первой процедуры перед вызо- вом печати атрибутов восстано- вите адрес в экране, а первую строку с меткой SETATTR в прог- рамме печати атрибутов уберите. Ну, а теперь сама процедура: 140.SETATTR POP HL ;Восстанавливаем адрес в экране. ---------------------------------------- 3(C) 1994 В.В.Патрахин (ZX-Ревю N6 1994) ---------------------------------------- LD A,H ;Переводим адрес в экране в адрес в ;атрибутах. RRCA RRCA RRCA AND #03 OR #58 LD H,A ---------------------------------------- LD A,(LENHGT+1) LD B,A ;В регистре B высота в пикселях. LD A,#04 SRL B ;Делим на 2. JR NC,R1 ;Если нацело, переход. LD (IZM),A ;В А код команды INC B, заносим его в ;переменную. R1 SRL B ;Делим на #04. JR NC,R2 LD (IZM),A R2 SRL B ;На #08. JR NC,IZM LD (IZM),A IZM NOP ;Если где-либо делилось не нацело, ;здесь будет команда INC B. SETATTR1 PUSH HL ;Сохраняем адрес в экране. LD A,(LENHGT) LD C,A ;Длина спрайта (для JACK THE NIPPER-2 ;надо после этой команды добавить SRL ;C, тоже и для ELEFANT-1). SETATTR2 LD A,(DE) ;Переносим атрибуты в экран. LD (HL),A INC DE INC HL DEC C JR NZ,SETATTR2 POP HL PUSH DE LD DE,#0020 ADD HL,DE POP DE DJNZ SETATTR1 RET 2 Для спрайтов в формате ELE- FANT-1 и JACK NIPPER-2 длину также стоит разделить на 2 (ес- ли, конечно, Вам пришлось ее де- лить при печати спрайтов). Многие могут заметить стран- ную конструкцию в том месте, где мы делили высоту спрайта на 8. Я вынужден пояснить эту ситуацию. Если Ваш спрайт в высоту кратен знакоместу (делится нацело на 8), то эту конструкцию можно за- менить на три команды SRL B; но вот в том случае, если спрайт в высоту не кратен знакоместу, мо- гут возникнуть спорные ситуации: ПРИМЕР: высота составила 9 пикселей. При делении на два, мы получим 4, на 4 - 2, на 8 - 1, но ведь спрайт в атрибутах зани- мает 2 знакоместа (9 линия нахо- дится в следующем знакоместе), и окрашены атрибутами будут только первые 8 линий. Вот для этого и нужна подобная конструкция. Ну, вот мы с Вами и напечата- ли все основные форматы спрай- тов в знакоместах и нам стоит перейти к печати спрайтов по пикселям.
Другие статьи номера:
Похожие статьи:
В этот день... 21 ноября