Как написать игру для ZX Spectrum на ассемблере



         

Вывод изображения из «теневого» экрана - часть 2


ORG 60000 ; Адрес «теневого» (или виртуального) экрана = #8000 V_OFFS EQU #40 ;старший байт смещения адреса ; «теневого» экрана относительно ; начального адреса физического экрана LD A,69 LD (23693),A XOR A CALL 8859 CALL 3435 LD A,2 CALL 5633 ;здесь необходима только для правильного ; вывода атрибутов основного экрана ; Инициализация переменных MAIN LD A,2 LD (X_LAMP),A LD HL,0 LD (X_LAND),HL CALL FRAME ;рамка вокруг окна MAIN1 CALL CLS_V ;очистка «теневого» экрана ; Формирование игрового поля в «теневом» экране CALL LAND ;вывод заднего плана (дома) CALL LINE1 ;рисование дальнего тротуара CALL PUTCAR ;автомобиль CALL LINE2 ;ближний тротуар CALL LAMPS ;фонари ; ---------------- CALL PUTVRT ;вывод окна виртуального экрана ; на физический CALL 8020 ;проверка нажатия клавиши Break

RET NC ;выход из программы, если нажата LD HL,(X_LAND) ;изменение координаты автомобиля INC HL LD (X_LAND),HL LD DE,200 ;если пройдено расстояние AND A ; меньше 200 знакомест, SBC HL,DE JR NZ,MAIN1 ; то движение продолжается LD BC,100 ;иначе - пауза 2 сек. CALL 7997 JR MAIN ; и переход к началу пути ; Рисование горизонтальных линий белого цвета, изображающих тротуары LINE1 LD L,#40 LD H,#4A+V_OFFS JR LINE3 LINE2 LD L,#60 LD H,#4C+V_OFFS LINE3 PUSH HL ;адрес экрана здесь не рассчитывется, ; а задается в явном числовом виде LD D,H LD E,L INC DE LD (HL),255 ;сплошная линия (если изменить число, ; получится пунктирная) LD BC,31 LDIR ;проводим линию POP HL LD A,H ;расчет адреса атрибутов SUB V_OFFS AND #18 RRCA RRCA RRCA ADD A,#58+V_OFFS LD H,A LD D,H LD E,L INC DE LD (HL),7 ;INK 7, PAPER 0 LD BC,31 LDIR RET ; Вывод автомобиля в виртуальный экран PUTCAR LD BC,#90E ;координаты фиксированы (B = 9, C = 14) LD HL,SPR7 ;маска LD A,SPRAND ;по принципу AND CALL PTBL LD HL,SPR6 ;автомобиль LD A,SPROR ;по принципу OR JP PTBL ; Рисование в виртуальном экране дорожных фонарей LAMPS LD HL,X_LAMP LD C,(HL) ;горизонтальная координата самого левого ; на экране фонаря LD B,7 ;вертикальная координата фиксирована PUSH HL LAMPS1 LD HL,SPR9 ;маска LD A,SPRAND CALL PTBL LD HL,SPR8 ;фонарь LD A,SPROR CALL PTBL LD A,20 ;следующий через 20 знакомест ADD A,C LD C,A CP 28 JR C,LAMPS1 ;закончить вывод? POP HL DEC (HL) ;уменьшение координаты на 2 DEC (HL) RET P ;выход, если начальная координата ; не отрицательна LD (HL),18 ;иначе задаем начальную координату RET X_LAMP DEFB 0 ; Подпрограмма очистки виртуального экрана CLS_V LD H,#40+V_OFFS LD L,0 LD D,H LD E,L INC DE LD (HL),0 LD BC,6144 LDIR ; Атрибуты LD (HL),1 ;INK 1, PAPER 0 LD BC,767 LDIR RET ; Формирование изображения здания, скомбинированного из нескольких ; спрайтов (адрес соответствующего блока данных в паре HL) PUT_B LD A,(HL) ;количество блоков в доме INC HL PUT_B1 PUSH AF PUSH BC LD A,(HL) ;горизонтальная координата блока INC HL ADD A,C CP 2 ;проверка выхода за пределы окна JR C,PUT_B3 CP 29 JR NC,PUT_B3 LD C,A LD A,(HL) ;вертикальная координата блока INC HL ADD A,B ;проверка выхода за пределы окна JP M,PUT_B4 LD B,A LD E,(HL) ;адрес спрайта, изображающего блок INC HL LD D,(HL) INC HL PUSH HL EX DE,HL LD A,SPRPUT CALL PTBL ;выводим спрайт в «теневой» экран POP HL PUT_B2 POP BC POP AF DEC A JR NZ,PUT_B1 ;следующий блок RET PUT_B3 INC HL ;обход, если блок выходит за пределы окна PUT_B4 INC HL INC HL JR PUT_B2 ; Вывод помещающейся в окно части пейзажа X_LAND DEFW 0 ;координата автомобиля на трассе LAND LD HL,D_LAND ;блок данных, описывающих ; местоположение и внешний вид домов LAND1 LD BC,(X_LAND) LD E,(HL) ;горизонтальная координата дома на трассе INC HL LD D,(HL) INC HL LD A,D OR E RET Z ;0 - маркер конца блока данных LD A,(HL) ;протяженность дома в знакоместах INC HL PUSH HL PUSH DE EX DE,HL ;вычисляем координату дальнего конца дома ADD A,L LD L,A LD A,H ADC A,0 LD H,A INC HL AND A SBC HL,BC ;сравниваем с текущим положением ; автомобиля POP DE JR C,LAND3 ;если дом выходит за левый край окна LD HL,28 ADD HL,BC SBC HL,DE JR C,LAND3 ;если дом выходит за правый край окна EX DE,HL SBC HL,BC ;вычисление экранной координаты дома LD C,L POP HL LD B,(HL) ;вертикальная экранная координата дома INC HL LD E,(HL) ;адрес блока данных, описывающих дом INC HL LD D,(HL) PUSH HL EX DE,HL CALL PUT_B ;вывод изображения дома в «теневой» экран POP HL LAND2 INC HL JR LAND1 ;следующий дом LAND3 POP HL ;обход, если изображение дома не ; попадает в окно экрана INC HL INC HL JR LAND2 ; ВНИМАНИЕ! В процедуре PTBL есть изменения! PTBL SPRPUT EQU 0 SPROR EQU #B6 SPRAND EQU #A6 SPRXOR EQU #AE PUSH HL LD (MODE),A LD A,(HL) INC HL PUSH HL LD L,A LD H,0 LD E,L LD D,H ADD HL,HL ADD HL,DE POP DE ADD HL,DE EX DE,HL PTBL1 PUSH AF PUSH BC LD A,(HL) INC HL PUSH HL ADD A,B CP 24 JR NC,PTBL4 PUSH DE CALL 3742 POP DE ; +++ Добавление +++ LD A,V_OFFS ADD A,H LD H,A ; +++ EX (SP),HL LD A,(HL) EX (SP),HL ADD A,C CP 32 JR NC,PTBL4 ADD A,L LD L,A LD B,8 PUSH HL PTBL2 LD A,(DE) MODE NOP LD (HL),A INC DE INC H DJNZ PTBL2 POP BC LD A,B AND #18 SRA A SRA A SRA A ; +++ Изменение: вместо ADD A,#58 +++ ADD A,#58+V_OFFS ; +++ LD B,A POP HL INC HL LD A,(HL) DEC HL LD (BC),A PTBL3 POP BC POP AF INC HL INC HL DEC A JR NZ,PTBL1 POP HL RET PTBL4 LD HL,8 ADD HL,DE EX DE,HL POP HL JR PTBL3 ; Вывод окна «теневого» экрана на физический PUTVRT LD A,8 ;отступ сверху (в пикселях) LD B,12*8 ;высота окна (в пикселях) PUT_V1 PUSH AF PUSH BC LD C,4*8 ;отступ слева (в пикселях) CALL 8880 ;адрес физического экрана LD D,H ;сохраняем в DE LD E,L LD A,V_OFFS ADD A,H ;в HL - соответствующий адрес LD H,A ; «теневого» экрана LD BC,24 ;ширина окна - 24 знакоместа LDIR POP BC POP AF INC A ;следующий ряд пикселей DJNZ PUT_V1 ; Перенос атрибутов LD DE,#5824 ;адрес верхнего левого угла окна LD L,E ; в области атрибутов LD A,D ADD A,V_OFFS ;вычисляем соответствующий адрес LD H,A ; в «теневом» экране LD B,12 PUT_V2 PUSH BC LD BC,24 LDIR ;переносим 24 байта (по ширине окна) LD BC,8 ;переходим к следующей ADD HL,BC ; строке экрана (32-24 = 8) EX DE,HL ADD HL,BC EX DE,HL POP BC DJNZ PUT_V2 RET ; Рисование рамки вокруг окна ; (подпрограммы LABS1 и PRINT описаны в предыдущем разделе) FRAME LD IX,DFRAME ;Данные для построения рамки




Содержание  Назад  Вперед