JetPac на пару с Cookie ненавистного местными 83 года ржет над вами со своими 16к.
Вид для печати
JetPac на пару с Cookie ненавистного местными 83 года ржет над вами со своими 16к.
Если хранить буфер экрана линейно
то оптимальный вариант строения буфера таков
FEDC BA98 7654 3210
***X XXXX YYYY YYYY
преимущества
переход влево dec h 4t
переход вправо inc h 4t
переход вверх dec l 4t
переход вниз inc l 4t
буфер хоть и занимает собой 8К
но в 64 байтной щелке вполне можно хранить спрайты и таблицы
так же таблицы можно хранить и "вертикально"
то есть в L закидываем номер таблицы
а в H число пропускаемое через таблицу
из недостатков
если читать буфер стеком
то выводить нужно столбцами
что сечется с лучом заметней
если рисовать стеком а читать просто линейно
то проблем уже нет
- - - Добавлено - - -
кто сказал?
Да, хороший вариант. Надо только после смещения вправо, возврат по Х организовать и сместиться по Y, для разный ширины спрайта. Пока оптимально по тикам, что-то не соображу как.
Бросать можно и через
, где адреса заранее рассчитаны. Получается чуть более 80тыс. тактов на весь экран. Теоретически, если нужен весь экран, то эту процедуру можно кинуть в нулевую страницу и подключить по cpu0. Хотя этой возможности подключать в cpu0 (ram0) лет 20 уже, предполагаю, что всё равно это специфично.Код:POP HL
LD (#4000),HL
POP HL
LD (#4002),HL
Ещё бы в такой буфер быстро кидать
, то весь экран в 67тыс. тактов укладывается и не используется дополнительный буфер. Можно и без cpu0 обходиться.Код:D SP,экран
LD HL,NN ;два байта графики, здесь будет подставляться спрайт
PUSH HL
LD HL,NN
PUSH HL
можно и нужно по возможности двигаться змейкой
inc h inc h inc h inc h inc l
dec h dec h dec h dec h inc l
inc h inc h inc h inc h inc l
dec h dec h dec h dec h inc l
или
inc l inc l inc l inc h
dec l dec l dec l inc h
inc l inc l inc l inc h
dec l dec l dec l inc h
- - - Добавлено - - -
в условиях демосцены или жесткого извращения и если мы пишем под 128
и если мы не боимся медленной памяти и пишим под пентагон и ложим на фирменные машины
а может мы просто захотели рисовать мультиколор
опять же
мы можем организовать чуть более удобно и такой буфер для 128 строк
ld hl,nn push hl занимает 4 байта на 2 байта экранной области
тоесть делаем так
включаем теневой экран навсегда
в итоге у нас появляется место по $4000-7FFF под маневры
далее раскидываем развернутую процедуру в виде
можно 127 строкКод:org $4000
l1 ld sp,C0xx ;3
dup 16
ld hl,nnnn ;3
push hl ;1
edup
jp l2 ;3
org $4100
l2 ld sp,C1xx
dup 16
ld hl,nnnn
push hl
edup
jp l3
...
org $BF00
l128 ld sp,xxxx
dup 16
ld hl,nnnn
push hl
edup
jp end
и выровнять более удобно
чтоб nnnn приходилось на кратный адрес $хх00
и в принципе если хотим ЕЩЕ БЫСТРЕЕ
то можем убрать ld sp,xxxx
а поставить Jp по образу и подобию строения спековского экрана
ТОГДА мы выиграем 1К тактов
но не сможем рисовать линейно сверху в низ
чтоб не сектись с лучом
тогда 128 строк улетят в экран за 44298 тактов
при этом у нас остается свободное переключаемое окно С000-FFFF
графику можно хранить между каждой строкой
по 186 байт на строку свободно
таблицу вектора прерываний нужно будет ложить в каждой банке (кроме тех что всегда по адресам 4000-BFFF)
так же как и обработчик
(как вариант можно пожертвовать пару строк и положить вектор и обработчик в более надежном месте)
на время рисования в буфере
видео память отключаем из адресного пространства проца вообще
так же в странице с видеопамятью у нас еще свободно 9К памяти
так же чтоб жестко не извращатся переключением страниц кодом находящимся в переключаемой странице (гемор же)
можно переместить некоторые процедуры
переключалки страниц рамы
переменные
в те 186 байтные щелки что есть в 32К процедуре перекидывания буфера в видеопамять
в итоге перемещение по вертикали
у нас остается достаточно быстрое inc h dec h
но по горизонтали
уже нужно извращаться
так у нас чередуются 2 байта данных и 2 байта кода
- - - Добавлено - - -
по адресам 4B00-BFFF вполне найдется 29К памяти
чтоб поместить 24К процедуру
и без cpu0 которого ниукогонет...
но опять же это или в условиях 128К
или при большом извращении
Кстати, да. Про змейку подумал, а увидев наглядно пример, понял, что можно спрайты тоже змейкой хранить.
Для буфера и вывода сразу
LD HL,NN
PUSH HL
можно тоже схему применять
ld (hl),N - inc l - inc l - inc l - ld (hl),N - inc l - ld (hl),N
, что тоже быстро.
Только scroll такого буфера будет медленнее, но в общем случае на дистанции будет неплохо на первый взгляд. Хотя такты надо будет посчитать.
Спасибо всем за советы.
И, ещё, один вопрос. Где-то проскакивала тема с библиотеками, по типу процедур. Понимаю, что задачи у всех разные и решения тоже специфичны. Но готовые процедуры облегчают процесс, хотя бы "заточенные" под какой-либо конкретный случай, тем более SJAsm позволяет подключать модули (или как их там правильно). Нет ли каких наработок по этому поводу, структурированных сайтов, где оптимизировать и сохранять могут сами участники? Или в этом смысла нет?
П.С.: После dec l dec l dec l inc h, только что прочитал. Нужно время, чтобы переосмыслить полностью.
близко нет
все в перемешку
есть некоторые сайтеке
которые содержат большой набор процедур для матана
просто для z80
не факт что оптимизированные и оптимальные...
может чего то я не знаю
и за пару лет все изменилось?
вангую что воз и ныне там
- - - Добавлено - - -
про хранение "змейкой" и для общего развития
прочитай эту статью
https://zxpress.ru/article.php?id=8659
тоже иногда можно применять
- - - Добавлено - - -
смысл таков
забываем про десятичные цифры при размышлении
и переходим на шестнадцатеричные и двоичные
осмысляем выравнивание по кратным адресам и как этим пользоватсо
ну и таблицы с любым количеством переменных в любой форме и в любом направлении
представляем память спека как квадрат 256х256 с координатами H и L...
а не как "с 32768 на резинке у нас быстра память"...
итд...
и будет вам счастие
- - - Добавлено - - -
В качестве авторитетного примера приведу вот эту поделку alone coder-а
https://jpegshare.net/images/3c/ea/3...02156e4b32.png
(вертикальные столбцы это младшие 256 байт)
где видно что видео буфер лежит "вертикально" а в образовавшихся щелях понапихано еще :)
в моем представлении
$0000 верхний левый угол
$FFFF нижний правый
а тут все повернуто на 90 градусов :)
да и термины типа нижняя\верхняя память не люблю
пушо как по мне вверху должен быть и так естественней адрес 0
а называют совершенно на оборот...
а не проще бегло просмотреть готовые BattleCity (на вирте их штук 10) ?
Может и проще, только от чужой мнемоники голова идёт кругом, т.к. нет опыта ни в ассемблере, ни в оптимизации кода на нём. Да и про вопросы о таких способах вывода графики, как я уже выше писал, в этой игре мало имеет значения, т.к. там не нужен будет буфер и т.п. Это всё для полной картины понимания, чтобы нюансы потом не всплывали, камнями. Да и работу с экраном нужно осмыслить с разных сторон.
Да, интересный метод. В голове проскакивала мысль об управление битами при смещении, а здесь более подробно метод описан, 26 тактов на байт, без стека. А со стеком
и змейкой - 36 тактов на два байта, т.е. 18 тактов на один. Итого 576 тактов на квадратный спрайт-фон из 4-х выровненных знакомест, без подготовки.Код:pop bc ;10
ld (hl),b ;7
inc l ;4
ld (hl),c ;7
set/res N,l;8
pop bc ;10
ld (hl),c ;7
dec l ;4
ld (hl),b ;7
set/res N,l ;8
Я не так давно загорелся подобной идеей, помог сайт http://zxpress.ru/article.php?id=5437, там много полезных статей, в которых описано то, что я только недавно узнал про спек.
Имхо делай 128 версию, мороки меньше, когда разберёшься со страницами памяти, особенно со сменными видеостраницами, всё пойдёт и тормозов станет меньше.
Я себе придумал челендж, написать программу в которой можно написать программу)) То-есть потратил неделю на написание своего "компилятора", старая версия которого тут выложена.
Листинг последней версии Tank 1990(немного оптимизированный по занимаемой памяти)
Скрытый текст
Код:ORG 32768
LD A,7
LD (23693),A ;ATTR_P
LD HL,(23670)
LD (RND_VAL),HL
CALL MAIN_CYCLE
RET
;-------------------
LEVELS EQU #C000
LEVEL_ADDR DEFW 0
;-------------------
T_COORD DEFW 0
T_OLD_COORD DEFW 0
T_SPR_ADR DEFW 0
T_SPR_W DEFB 0
T_SPR_H DEFB 0
T_DIRECT DEFB 0 ;Направление игрока
T_ACTIVE DEFB 0
T_LIVES DEFB 0
T_POWER DEFB 0
T_VISIBLE DEFB 0
T_BLINK_TIMER DEFB 0
T_PROTECT_TIMER DEFB 0
T_SLIP_TIMER DEFB 0
T_COL_SHOT DEFB 0
T_SH_TIMER DEFB 0
T_FASE DEFB 0
;-------------------
T_SH_COORD EQU 0
T_SH_OLD_COORD EQU 2
T_SH_DIRECT EQU 4
T_SH_ACTIVE EQU 5
T_SH_SPEED EQU 6
T_SH_LEN EQU 7
T_SHOT DEFS 14 ;Массив патронов игрока
;-------------------
E_COORD EQU 0 ;Координаты врага
E_OLD_COORD EQU 2 ;Координаты врага
E_SPR_H EQU 4 ;Высота текущего спрайта врага
E_SPR_W EQU 5 ;Ширина текущего спрайта врага
E_SPR_ADR EQU 6 ;Адрес текущего спрайта врага
E_DIRECT EQU 8 ;Направление врага
E_HP EQU 9 ;Существует ли враг
E_SH_COORD EQU 10
E_SH_OLD_COORD EQU 12
E_SH_DIRECT EQU 14
E_SH_ACTIVE EQU 15
E_BONUSED EQU 16
E_VISIBLE EQU 17
E_BLINK_TIMER EQU 18
E_TYPE EQU 19
E_SPRITE_ADDR EQU 20
E_FASE EQU 22
E_COUNT EQU 3
ENEMY_LEN EQU 23 ;Размер в байтах одного врага
ENEMY DEFS 69 ;Массив врагов
L_ECOUNT DEFB 0,0,0,0
STAGE_NUM DEFB 0
SCORE DEFW 0
HI_SCORE DEFW 200
;-------------------
B_COORD DEFW 0
B_OLD_COORD DEFW 0
B_ACTIVE DEFB 0
B_INDEX DEFB 0
B_VISIBLE DEFB 0
B_BLINK_TIMER DEFB 0
STOP_TIMER DEFB 0
SPAWN_POS DEFB 0
ENEMY_COUNT DEFB 0
BASE_DAMAGED DEFB 0
BONUS_COUNTER DEFB 0
IS_ICE DEFB 0
IS_KEMPSTON DEFB 0
DEFICULT DEFB 0
BLINK_TIME EQU 3
L_END_TIMER DEFB 0 ;Таймер задержки по окончании
;--------------------------
W_COORD DEFW 0
W_SPRADR DEFW 0
W_SPRW DEFB 0
W_SPRH DEFB 0
U_PRESSED DEFB 0
D_PRESSED DEFB 0
L_PRESSED DEFB 0
R_PRESSED DEFB 0
F_PRESSED DEFB 0
U_PORT DEFB #FB ;Порты полурядов с клавишами управления
D_PORT DEFB #FD ;меняются при редефайне
L_PORT DEFB #FD
R_PORT DEFB #FD
F_PORT DEFB #BF
;--------------------------
SELECT_T_SPRITE
LD A,(T_POWER)
LD HL,T1
CP 0
JR Z,STS_END
LD HL,T2
CP 1
JR Z,STS_END
LD HL,T3
CP 2
JR Z,STS_END
LD HL,T4
STS_END LD DE,T_SPRITE_1
CALL FILL_SPRITE
RET
;--------------------------
SELECT_E_SPRITE
LD A,(IX+E_TYPE)
LD HL,E1
CP 0
JR Z,SES_END
LD HL,E2
CP 1
JR Z,SES_END
LD HL,E3
CP 2
JR Z,SES_END
LD HL,E4
SES_END LD E,(IX+E_SPRITE_ADDR)
LD D,(IX+E_SPRITE_ADDR+1)
CALL FILL_SPRITE
RET
;--------------------------
REDEFINE_KEYS
LD DE,TXT_LEFT
LD HL,#0A10
CALL PRINT
CALL WAIT_UNPRESSED_KEY ;Ждём отпускания клавиш
;Клавиша влево
CALL WAIT_PRESS_KEY
LD A,(HL)
LD (L_PORT),A
LD A,(DE)
LD (L_BIT+1),A
CALL WAIT_UNPRESSED_KEY ;Ждём отпускания клавиш
LD DE,TXT_RIGHT
LD HL,#0A10
CALL PRINT
;Клавиша вправо
CALL WAIT_PRESS_KEY
LD A,(HL)
LD (R_PORT),A
LD A,(DE)
LD (R_BIT+1),A
CALL WAIT_UNPRESSED_KEY
LD DE,TXT_UP
LD HL,#0A10
CALL PRINT
;Клавиша вверх
CALL WAIT_PRESS_KEY
LD A,(HL)
LD (U_PORT),A
LD A,(DE)
LD (U_BIT+1),A
CALL WAIT_UNPRESSED_KEY
LD DE,TXT_DOWN
LD HL,#0A10
CALL PRINT
;Клавиша вниз
CALL WAIT_PRESS_KEY
LD A,(HL)
LD (D_PORT),A
LD A,(DE)
LD (D_BIT+1),A
CALL WAIT_UNPRESSED_KEY
LD DE,TXT_FIRE
LD HL,#0A10
CALL PRINT
;Клавиша огонь
CALL WAIT_PRESS_KEY
LD A,(HL)
LD (F_PORT),A
LD A,(DE)
LD (F_BIT+1),A
CALL WAIT_UNPRESSED_KEY
LD DE,MENU_2
LD HL,#0610
CALL PRINT
RET
TXT_LEFT DEFM "PRESS LEFT KEY "
DEFB 0
TXT_RIGHT DEFM "PRESS RIGHT KEY"
DEFB 0
TXT_UP DEFM "PRESS UP KEY "
DEFB 0
TXT_DOWN DEFM "PRESS DOWN KEY "
DEFB 0
TXT_FIRE DEFM "PRESS FIRE KEY "
DEFB 0
;--------------------------
IS_KEY
LD HL,KEY_PORTS
LD B,8 ;8 полурядов
IK_NP LD A,(HL)
IN A,(254)
AND 31
XOR 31
RET NZ ;Какая-то клавиша нажата
INC HL
DJNZ IK_NP
RET ;Не нажата ни одна клавиша
;--------------------------
WAIT_UNPRESSED_KEY
LD HL,KEY_PORTS
LD B,8 ;8 полурядов
WKP_NP LD A,(HL)
IN A,(254)
AND 31
CP 31
JR NZ,WAIT_UNPRESSED_KEY ;Клавиша нажата.
INC HL
DJNZ WKP_NP
RET ;Не нажата ни одна клавиша
;--------------------------
WAIT_PRESS_KEY
LD HL,KEY_PORTS
LD B,8 ;8 полурядов
DK_NP LD A,(HL)
IN A,(254)
PUSH AF
LD A,#FE
CP (HL)
JR NZ,WAKP_0
POP AF
OR 1 ;CAPS SHIFT - НЕ ИСПОЛЬЗУЕМ
JR WAKP_1
WAKP_0 POP AF
WAKP_1
LD C,5 ;5 бит
LD DE,BIT_HALFCODE
NEXT_BIT RRA
RET NC ;Клавиша нажата. В (HL) порт, в (DE) полукод
INC DE
DEC C
JR NZ,NEXT_BIT
INC HL
DJNZ DK_NP
JR WAIT_PRESS_KEY ;Пока клавиша не будет нажата
BIT_0 EQU #47 ;Полукоды команды от BIT 0,A до BIT 4,A
BIT_1 EQU #4F
BIT_2 EQU #57
BIT_3 EQU #5F
BIT_4 EQU #67
KEY_PORTS DEFB #7F,#BF,#DF,#EF,#F7,#FB,#FD,#FE ;Все 8 полурядов клавиатуры
BIT_HALFCODE DEFB #47,#4F,#57,#5F,#67
;--------------------------
CALL ADR
PRNT_1 PUSH DE
PUSH HL
LD A,H ;рассчитываем адрес атрибутов соответствующего знакоместа
AND #18
RRCA
RRCA
RRCA
ADD A,#58
LD H,A
LD A,(COLOR)
LD (HL),A
LD A,(DE) ;Считали очередной символ
LD L,A
LD H,0
ADD HL,HL
ADD HL,HL
ADD HL,HL
LD DE,(23606)
ADD HL,DE ;Получим адрес символа
POP DE
PUSH DE
LD B,8
PRNT_0 LD A,(HL)
SRL A
OR (HL) ;Утолщим символ
LD (DE),A ;Поместим на экран
INC HL
INC D
DJNZ PRNT_0
POP HL
POP DE
INC HL
INC DE
LD A,(DE)
AND A
RET Z ;Выходим, если символ с кодом 0
JR PRNT_1
COLOR DEFB 0
;--------------------------
START_MELODY
DI
LD HL,MELODY
NOTE LD D,(HL)
INC HL
LD E,(HL)
INC HL
LD A,E
OR D
JR Z,END_MELODY
PUSH HL
CALL TWOTON
POP HL
JR NOTE
END_MELODY
EI
RET
MELODY
DEFB 226,225
DEFB 201,0
DEFB 190,0
DEFB 226,225
DEFB 201,227
DEFB 190,225
DEFB 190,191
DEFB 169,0
DEFB 150,0
DEFB 190,189
DEFB 169,191
DEFB 150,189
DEFB 169,170
DEFB 150,0
DEFB 142,0
DEFB 169,170
DEFB 150,170
DEFB 142,170
DEFB 142,143
DEFB 126,144
DEFB 113,143
DEFB 142,125
DEFB 126,124
DEFB 113,125
DEFB 113,114
DEFB 113,0
DEFB 113,0
DEFB 113,114
DEFB 113,115
DEFB 113,115
DEFB 113,114
DEFB 0,0
;------------------------------
TWOTON
LD BC,5000 ;длительность звучания
LD A,(23624)
AND #38
RRA
RRA
RRA
LD H,D
LD L,E
TWOTN1 INC H
DEC H
JR Z,TWOTN2
DEC H ;задержка для получения первого тона
JR NZ,TWOTN2
XOR 16
OUT (254),A ;извлечение первого звука
LD H,D ;восстановление значения задержки для первого тона
TWOTN2 INC H
DEC H
JR Z,TWOTN22
DEC L ;задержка для получения второго тона
JR NZ,TWOTN22
XOR 16
OUT (254),A ;извлечение второго звука
LD L,E ;восстановление значения задержки для второго голоса
TWOTN22 PUSH AF
LD A,B ;проверка окончания звучания
OR C
JR Z,TWOTN3
POP AF
DEC BC
JR TWOTN1
TWOTN3 POP AF
RET
;-------------------
INTERR PUSH AF ;сохраняем используемые
PUSH BC ; в прерывании регистры
PUSH HL
INTER1 LD A,(REPEAT)
AND A
; Если эффект прозвучал нужное количество раз, завершаем обработку прерывания
JR NZ,NO_EXITI
LD (BLOCKED),A
JR EXITI
NO_EXITI
LD HL,(CURADR) ;определяем текущий адрес в блоке данных
LD B,(HL) ;высота звука
INC B
DEC B
; Если встретился маркер конца блока данных, переходим к следующему повторению
JR Z,EXITI0
INC HL
LD C,(HL) ;длительность звука
INC HL
LD (CURADR),HL ;запоминаем текущий адрес
CALL BEEP ;извлекаем звук
EXITI
POP HL ;восстанавливаем регистры
POP BC
POP AF
JP 56 ;переходим к стандартному обработчику прерываний
; Переход к началу эффекта - повторение
EXITI0 LD HL,(ADREFF) ;восстанавливаем начальный
LD (CURADR),HL ; адрес блока данных
LD HL,REPEAT
DEC (HL) ;уменьшаем счетчик повторений
JR INTER1
REPEAT DEFB 0 ;количество повторений эффекта
ADREFF DEFW 0 ;начальный адрес блока данных эффекта
CURADR DEFW 0 ;текущий адрес в блоке данных
BLOCKED DEFB 0
; Извлечение звука
BEEP LD A,(23624)
SRL A
SRL A
SRL A
AND 7
BEEP1 XOR 16
OUT (254),A
PUSH BC
DELAY DJNZ DELAY
POP BC
DEC C
JR NZ,BEEP1
RET
;-------------------------
ON_SILENCE
XOR A
JR ON_EFF
ON_SHOT_SOUND
LD A,(BLOCKED)
CP 0
RET NZ ;Пока играет другой звук
LD HL,EFF1
LD A,1
JR ON_EFF
ON_CRASH_SOUND
LD A,(BLOCKED)
CP 0
RET NZ ;Пока играет другой звук
LD A,1
LD (BLOCKED),A
LD HL,EFF2
LD A,2
JR ON_EFF
ON_ADD_LIVE_SOUND
LD A,(BLOCKED)
CP 0
RET NZ ;Пока играет другой звук
LD A,1
LD (BLOCKED),A
LD HL,EFF3
LD A,1
JR ON_EFF
ON_BONUS_SOUND
LD A,(BLOCKED)
CP 0
RET NZ ;Пока играет другой звук
LD A,1
LD (BLOCKED),A
LD HL,EFF4
LD A,2
JR ON_EFF
ON_CLANG_SOUND
LD A,(BLOCKED)
CP 0
RET NZ ;Пока играет другой звук
LD A,1
LD (BLOCKED),A
LD HL,EFF5
LD A,1
JR ON_EFF
ON_EFF LD (ADREFF),HL
LD (CURADR),HL
LD (REPEAT),A
RET
EFF1 DEFB 50,12,100,6,150,4,200,2,250,2
DEFB 0
EFF2 DEFB 50,2,100,2,25,2,46,2,215,2
DEFB 0
EFF3 DEFB 60,6,60,6,60,6,60,6,60,6
DEFB 80,6,80,6,80,6,80,6,80,6
DEFB 100,6,100,6,100,6,100,6,100,6
DEFB 120,6,120,6,120,6,120,6,120,6
DEFB 100,6,100,6,100,6,100,6,100,6
DEFB 60,6,60,6,60,6,60,6,60,6
DEFB 70,6,70,6,70,6,70,6,70,6
DEFB 0
EFF4 DEFB 250,4,200,4,150,4,100,4,50,4
DEFB 0
EFF5 DEFB 80,4,70,4,60,5,50,5
DEFB 0
;-------------------
IMON
CALL SET_VIDEO5
LD A,195 ;код команды JP
LD (49087),A
LD HL,INTERR ;адрес процедуры обработки прерываний
LD (49088),HL
LD HL,48640 ;формируем таблицу векторов прерываний
LD DE,48641
LD BC,256
LD (HL),191 ;на адрес 16705
LD A,H
LDIR
DI
LD I,A ;загружаем регистр вектора прерываний
IM 2 ;включаем 2-й режим
EI
RET
;---------------------------
FIRST_INIT
;Обнулим очки
LD HL,0
LD (SCORE),HL
;Начальные 4 жизни
LD A,4
LD (T_LIVES),A
;Начало уровней
LD HL,LEVELS
LD (LEVEL_ADDR),HL
XOR A
LD (BASE_DAMAGED),A ;База цела
LD (T_PROTECT_TIMER),A ;Каску уберём
LD (T_POWER),A ;Звёзды сбросим
LD (STAGE_NUM),A ;Сбросим номер уровеня
LD A,1
LD (T_COL_SHOT),A ;1 патрон
;Оба патрона неактивны
LD IX,T_SHOT
LD (IX+T_SH_ACTIVE),0
LD IX,T_SHOT+T_SH_LEN
LD (IX+T_SH_ACTIVE),0
LD DE,ENEMY_LEN
LD IX,ENEMY
;Раздадим врагам адреса рабочих спрайтов
LD HL,E_SPRITE_1
LD (IX+E_SPRITE_ADDR),L
LD (IX+E_SPRITE_ADDR+1),H
ADD IX,DE
LD HL,E_SPRITE_2
LD (IX+E_SPRITE_ADDR),L
LD (IX+E_SPRITE_ADDR+1),H
ADD IX,DE
LD HL,E_SPRITE_3
LD (IX+E_SPRITE_ADDR),L
LD (IX+E_SPRITE_ADDR+1),H
RET
;----------------------------
MAIN_CYCLE
CALL ON_SILENCE
CALL IMON
CALL FIRST_SCREEN
CALL FIRST_INIT
M_C0
;Кончились ли уровни
LD HL,(LEVEL_ADDR)
LD A,H
OR L
CP 0
JR NZ,M_C1
CALL VIN_SCREEN
JR MAIN_CYCLE
M_C1
CALL INIT_LEVEL
M_CGC CALL GAME_CYCLE
;Проигрыш ли
LD A,(T_LIVES)
CP 0
JR NZ,M_C2
LD A,(T_ACTIVE)
CP 0
JR NZ,M_C2
CALL DEC_L_TIMER
JR NZ,M_CGC
CALL GAME_OVER_SCREEN
JR MAIN_CYCLE
M_C2
;Взорвана ли база
LD A,(BASE_DAMAGED)
CP 0
JR Z,M_C21
CALL DEC_L_TIMER
JR NZ,M_CGC
CALL GAME_OVER_SCREEN
JR MAIN_CYCLE
M_C21
;Очищен ли уровень
LD A,(ENEMY_COUNT)
CP 0
JR NZ,M_C3
LD IX,ENEMY
LD DE,ENEMY_LEN
LD A,(IX+E_HP)
CP 0
JR NZ,M_C3
ADD IX,DE
LD A,(IX+E_HP)
CP 0
JR NZ,M_C3
ADD IX,DE
LD A,(IX+E_HP)
CP 0
JR NZ,M_C3
CALL DEC_L_TIMER
JR NZ,M_CGC
CALL ENDLEVEL_SCREEN
JR M_C0
M_C3
JR M_CGC
DEC_L_TIMER
LD A,(L_END_TIMER)
OR A
RET Z
DEC A
LD (L_END_TIMER),A
OR A
RET
;----------------------------
GAME_CYCLE
CALL PRINT_FON
CALL INIT_PLAYER
CALL INIT_EMPTY_ENEMY
CALL KEY_TEST
CALL T_ACTION
CALL E_ACTION
CALL T_SHOT_MOVE
CALL E_SHOT_MOVE
CALL PRINT_ENEMYS
CALL PRINT_PLAYER
CALL PRINT_T_SHOT
CALL PRINT_E_SHOT
CALL PRINT_BONUS
CALL PRINT_LIVES
CALL SWAP_SCREEN
RET
;--------------------------
SCROLL_SCREEN
LD A,(IX)
LD HL,SCROL_COLOR
CP 1
JR Z,SS0
LD HL,SCROL_DEF
SS0 LD (S8B_CF+1),HL
INC IX
LD A,(IX)
LD (SSCOL+1),A
INC IX
LD A,(IX)
LD (SSBCNT+1),A
INC IX
LD A,(IX)
LD (SSSCNT+1),A
INC IX
LD B,(IX)
INC IX
SS1 PUSH BC
LD L,23
SSCOL LD H,0
CALL ADR
SSBCNT LD B,0
SS2 PUSH BC
LD C,8
SS3 RLC (IX)
JR NC,SS5
PUSH HL
LD DE,SPR_C1
LD B,8
SS4 LD A,(DE)
LD (HL),A
INC H
INC DE
DJNZ SS4
POP HL
SS5 INC HL
DEC C
JR NZ,SS3
INC IX
POP BC
DJNZ SS2
LD B,8
CALL SCRU_8B
POP BC
DJNZ SS1
SSSCNT LD B,0
CALL SCRU_8B
RET
;---------------------------
SCRU_8B PUSH BC
S8B_CF CALL 0
CALL SCROLL_UP
POP BC
DJNZ SCRU_8B
RET
;---------------------------
SCROL_COLOR
LD A,(#D800)
LD HL,#D801
LD DE,#D800
LD BC,735
LDIR
LD (#DADF),A
RET
SCROL_DEF
RET
;---------------------------
GAME_OVER_SCREEN
CALL SET_VIDEO5
LD A,%00000010
LD B,0
CALL CLS
LD A,6
LD (COL),A
LD A,6
LD (ROW),A
LD A,20
LD (WDT),A
LD A,18
LD (HGT),A
LD DE,#DAE1
LD HL,#DAE0
LD (HL),0
LD BC,31
LDIR
LD IX,GAME_OVER_TEXT
CALL SCROLL_SCREEN
CALL WAIT_PRESS_KEY
RET
;---------------------------
VIN_SCREEN
CALL SET_VIDEO5
LD A,%00000000
LD B,0
CALL CLS
LD HL,#D800
LD BC,736
V_S0 PUSH HL
PUSH BC
CALL RND_255
AND 71
POP BC
POP HL
LD (HL),A
INC HL
DEC BC
LD A,B
OR C
JR NZ,V_S0
LD A,8
LD (COL),A
LD A,6
LD (ROW),A
LD A,15
LD (WDT),A
LD A,18
LD (HGT),A
LD IX,VIN_TEXT
CALL SCROLL_SCREEN
V_S7 CALL SCROL_COLOR
CALL IS_KEY
CP 0
JR Z,V_S7
RET
;---------------------------
FIRST_SCREEN
CALL SET_VIDEO5
LD A,%00000010
LD B,0
CALL CLS
LD A,7
LD (COL),A
LD A,3
LD (ROW),A
LD A,18
LD (WDT),A
LD A,21
LD (HGT),A
LD DE,#DAE1
LD HL,#DAE0
LD (HL),0
LD BC,31
LDIR
LD IX,FIRST_TEXT
CALL SCROLL_SCREEN
LD A,7
LD (COLOR),A
LD DE,MENU_1
LD HL,#060E
CALL PRINT
LD DE,MENU_2
LD HL,#0610
CALL PRINT
LD DE,MENU_3
LD HL,#0612
CALL PRINT
LD DE,MENU_4
LD HL,#0614
CALL PRINT
F_WKP LD DE,T_OFF
LD HL,#1312
LD A,(IS_KEMPSTON)
CP 0
JR Z,KEMP
LD DE,T_ON
KEMP CALL PRINT
F_DEF LD DE,TDEF_1
LD HL,#1514
LD A,(DEFICULT)
CP 0
JR Z,DEFI
LD DE,TDEF_2
CP 1
JR Z,DEFI
LD DE,TDEF_3
DEFI CALL PRINT
CALL WAIT_PRESS_KEY
LD A,(HL)
CP #F7 ;Сравниваем с полурядом 1...5
JR NZ,F_WKP
LD A,(DE)
CP BIT_0 ;Клавиша 1
RET Z
PUSH AF
CP BIT_1 ;Клавиша 2
CALL Z,REDEFINE_KEYS
POP AF
PUSH AF
CP BIT_2 ;Клавиша 3
CALL Z,CHANGE_KAMPSTON
POP AF
CP BIT_3 ;Клавиша 4
CALL Z,INC_DEFIC
JR F_WKP
MENU_1 DEFM "1 - START DESTRUCTION"
DEFB 0
MENU_2 DEFM "2 - REDEFINE KEYS "
DEFB 0
MENU_3 DEFM "3 - KEMPSTON"
DEFB 0
MENU_4 DEFM "4 - DIFFICULTY"
DEFB 0
T_OFF DEFM "OFF"
DEFB 0
T_ON DEFM "ON "
DEFB 0
TDEF_1 DEFM "EASY "
DEFB 0
TDEF_2 DEFM "NORMAL"
DEFB 0
TDEF_3 DEFM "HARD "
DEFB 0
;---------------------------
ENDLEVEL_SCREEN
CALL SET_VIDEO5
LD A,%00000111
LD B,0
CALL CLS
LD A,2
LD (COLOR),A
LD HL,(HI_SCORE)
LD DE,(SCORE)
AND A
SBC HL,DE
JR NC,NO_HISCORE
LD (HI_SCORE),DE
NO_HISCORE
LD DE,ELS_1
LD HL,#0800
CALL PRINT
LD DE,ELS_3
LD HL,#0304
CALL PRINT
LD A,7
LD (COLOR),A
LD DE,ELS_2
LD HL,#0C02
CALL PRINT
LD DE,ELS_4
LD HL,#0808
CALL PRINT
LD DE,ELS_4
LD HL,#080B
CALL PRINT
LD DE,ELS_4
LD HL,#080E
CALL PRINT
LD DE,ELS_4
LD HL,#0811
CALL PRINT
LD DE,ELS_5
LD HL,#0C13
CALL PRINT
LD DE,ELS_6
LD HL,#0614
CALL PRINT
LD HL,ENEMY1_UP1
LD (W_SPRADR),HL
LD A,2
LD (W_SPRW),A
LD A,16
LD (W_SPRH),A
LD A,MOD_OR
LD (MODE),A
LD HL,#7840
LD (W_COORD),HL
LD HL,E1
LD DE,E_SPRITE_1
CALL FILL_SPRITE
CALL PRINT_SPRITE
LD HL,#7858
LD (W_COORD),HL
LD HL,E2
LD DE,E_SPRITE_1
CALL FILL_SPRITE
CALL PRINT_SPRITE
LD HL,#7870
LD (W_COORD),HL
LD HL,E3
LD DE,E_SPRITE_1
CALL FILL_SPRITE
CALL PRINT_SPRITE
LD HL,#7888
LD (W_COORD),HL
LD HL,E4
LD DE,E_SPRITE_1
CALL FILL_SPRITE
CALL PRINT_SPRITE
LD A,2
CALL 5633 ;вывод на основной экран
LD A,17
RST 16
XOR A
RST 16
LD A,16
RST 16
LD A,6
RST 16
LD DE,PTS_HISCORE
LD BC,3
CALL 8252 ;управляющие коды
LD BC,(HI_SCORE)
CALL 6683
LD BC,0
CALL 6683
LD BC,0
CALL 6683
LD DE,PTS_SCORE
LD BC,3
CALL 8252 ;управляющие коды
LD BC,(SCORE)
PUSH BC
CALL 6683
POP BC
LD A,B
OR C
JR Z,SCORE_NODBL
LD BC,0
CALL 6683
LD BC,0
CALL 6683
SCORE_NODBL
LD A,16
RST 16
LD A,7
RST 16
LD DE,PTS_LVLNUM
LD BC,3
CALL 8252 ;управляющие коды
LD BC,(STAGE_NUM)
LD B,0
CALL 6683
LD HL,L_ECOUNT
LD (CNT_ADR),HL
LD HL,PTS_11
LD (PTS_1ADR),HL
LD HL,PTS_12
LD (PTS_2ADR),HL
LD DE,1
CALL PRINT_PTS
LD HL,L_ECOUNT+1
LD (CNT_ADR),HL
LD HL,PTS_21
LD (PTS_1ADR),HL
LD HL,PTS_22
LD (PTS_2ADR),HL
LD DE,2
CALL PRINT_PTS
LD HL,L_ECOUNT+2
LD (CNT_ADR),HL
LD HL,PTS_31
LD (PTS_1ADR),HL
LD HL,PTS_32
LD (PTS_2ADR),HL
LD DE,3
CALL PRINT_PTS
LD HL,L_ECOUNT+3
LD (CNT_ADR),HL
LD HL,PTS_41
LD (PTS_1ADR),HL
LD HL,PTS_42
LD (PTS_2ADR),HL
LD DE,4
CALL PRINT_PTS
LD A,22
RST 16
LD A,20
RST 16
LD A,12
RST 16
LD A,0
LD HL,L_ECOUNT
ADD A,(HL)
INC HL
ADD A,(HL)
INC HL
ADD A,(HL)
INC HL
ADD A,(HL)
LD C,A
LD B,0
CALL 6683
CALL ON_BONUS_SOUND
LD BC,100
CALL 7997
RET
ELS_1 DEFM "HI-SCORE"
DEFB 0
ELS_2 DEFM "STAGE"
DEFB 0
ELS_3 DEFM "1-PLAYER"
DEFB 0
ELS_4 DEFM "PTS"
DEFB 0
ELS_5 DEFM "________"
DEFB 0
ELS_6 DEFM "TOTAL"
DEFB 0
;--------------------------
PRINT_PTS
LD HL,(CNT_ADR)
LD A,(HL)
INC A
LD (BCNT1+1),A
LD (BCNT2+1),A
LD HL,0
BCNT1 LD B,0
ES_C1 PUSH BC
PUSH DE
PUSH HL
PUSH HL
PUSH BC
LD DE,(PTS_2ADR)
LD BC,3
CALL 8252 ;выводим управляющие коды
POP BC
BCNT2 LD A,0
SUB B
LD C,A
LD B,0
CALL 6683
LD DE,(PTS_1ADR)
LD BC,3
CALL 8252 ;выводим управляющие коды
POP BC
PUSH BC
CALL 6683
POP BC
LD A,B
OR C
JR Z,NODBL
LD BC,0
CALL 6683
LD BC,0
CALL 6683
NODBL
CALL ON_CLANG_SOUND
LD BC,10
CALL 7997
POP HL
POP DE
POP BC
ADD HL,DE
DJNZ ES_C1
RET
CNT_ADR DEFW 0
PTS_1ADR DEFW 0
PTS_2ADR DEFW 0
PTS_11 DEFB 22,8,3
PTS_12 DEFB 22,8,12
PTS_21 DEFB 22,11,3
PTS_22 DEFB 22,11,12
PTS_31 DEFB 22,14,3
PTS_32 DEFB 22,14,12
PTS_41 DEFB 22,17,3
PTS_42 DEFB 22,17,12
PTS_HISCORE DEFB 22,0,19
PTS_SCORE DEFB 22,6,5
PTS_LVLNUM DEFB 22,2,18
;--------------------------
GAME_OVER_TEXT
DEFB 0,4,3,48,11
DEFB %00011100,%11001000,%10111100
DEFB %00100001,%00101000,%10100000
DEFB %00101101,%11101101,%10111100
DEFB %00100101,%00101010,%10100000
DEFB %00011001,%00101000,%10111100
DEFB %00000000,%00000000,%00000000
DEFB %00011001,%00010111,%10111000
DEFB %00100101,%00010100,%00100100
DEFB %00100101,%00010111,%10111000
DEFB %00100100,%10100100,%00100100
DEFB %00011000,%01000111,%10100100
VIN_TEXT
DEFB 1,8,2,48,11
DEFB %10001001,%10010010
DEFB %01010010,%01010010
DEFB %00100010,%01010010
DEFB %00100010,%01010010
DEFB %00100001,%10001100
DEFB %00000000,%00000000
DEFB %10001011,%10100010
DEFB %10001001,%00110010
DEFB %10101001,%00101010
DEFB %11011001,%00100110
DEFB %10001011,%10100010
FIRST_TEXT
DEFB 0,4,3,80,10
DEFB %00011100,%11001001,%01001000
DEFB %00001001,%00101101,%01110000
DEFB %00001001,%11101011,%01001000
DEFB %00001001,%00101001,%01001000
DEFB %00000000,%00000000,%00000000
DEFB %00000101,%11101111,%01111000
DEFB %00001101,%00101001,%01001000
DEFB %00010101,%11101111,%01001000
DEFB %00000100,%00100001,%01001000
DEFB %00000101,%11101111,%01111000
;---------------------------
CHANGE_KAMPSTON
LD A,(IS_KEMPSTON)
XOR 1
LD (IS_KEMPSTON),A
CALL WAIT_UNPRESSED_KEY
RET
;---------------------------
INC_DEFIC
LD A,(DEFICULT)
INC A
CP 3
JR NZ,CH_D1
LD A,0
CH_D1 LD (DEFICULT),A
CALL WAIT_UNPRESSED_KEY
RET
;---------------------------
SCROLL_UP
LD HL,(ROW)
CALL ADR
LD A,(HGT)
LD B,A
SLA B
SLA B
SLA B
DEC B
SCR_U1 PUSH HL
PUSH BC
PUSH HL
POP DE
CALL DOWN
LD A,(WDT)
LD C,A
LD B,0
LDIR
POP BC
POP HL
CALL DOWN
DJNZ SCR_U1
PUSH HL
POP DE
INC DE
LD (HL),0
LD A,(WDT)
DEC A
RET Z
LD C,A
LD B,0
LDIR
RET
ROW DEFB 0
COL DEFB 0
HGT DEFB 0
WDT DEFB 0
;---------------
PRINT_LIVES
LD L,15
LD H,27
CALL ADR
LD DE,MINI
LD B,8
P_LI1 LD A,(DE)
LD (HL),A
INC DE
INC H
DJNZ P_LI1
LD HL,(T_LIVES)
LD H,0
DEC L
SLA L
SLA L
SLA L
LD DE,15744
ADD HL,DE
EX DE,HL
LD L,15
LD H,28
CALL ADR
LD B,8
P_LI2 LD A,(DE)
LD (HL),A
INC DE
INC H
DJNZ P_LI2
RET
;---------------
PRINT_MINI
PUSH IX
PUSH HL
LD IX,MINI_COORDS
LD C,1
NXTM LD L,(IX)
LD H,(IX+1)
CALL ADR
LD DE,MINI
LD B,8
NXTL LD A,(ENEMY_COUNT)
CP C
JR C,ZERO
LD A,(DE)
JR NOZERO
ZERO XOR A
NOZERO LD (HL),A
INC DE
CALL DOWN
DJNZ NXTL
INC IX
INC IX
INC C
LD A,21
CP C
JR NZ,NXTM
POP HL
POP IX
RET
MINI_COORDS
DEFB 1,27,1,28
DEFB 2,27,2,28
DEFB 3,27,3,28
DEFB 4,27,4,28
DEFB 5,27,5,28
DEFB 6,27,6,28
DEFB 7,27,7,28
DEFB 8,27,8,28
DEFB 9,27,9,28
DEFB 10,27,10,28
MINI
DEFB 0,73,93,119,119,93,73,28
;---------------------------
BOX_COLLISION
LD A,(BOX_HL_W)
ADD A,H
CP D
JR NC,CLS16_1
XOR A
RET ;По X не пересекаются
CLS16_1
LD A,(BOX_DE_W)
ADD A,D
CP H
JR NC,CLS16_2
XOR A
RET ;По X не пересекаются
CLS16_2
LD A,(BOX_HL_H)
ADD A,L
CP E
JR NC,CLS16_3
XOR A
RET ;По Y не пересекаются
CLS16_3
LD A,(BOX_DE_H)
ADD A,E
CP L
JR NC,CLS16_4
XOR A
RET ;По Y не пересекаются
CLS16_4
LD A,1
RET
BOX_HL_H DEFB 0
BOX_HL_W DEFB 0
BOX_DE_H DEFB 0
BOX_DE_W DEFB 0
;---------------------------
;Сравнение двух пар на равенство
EQUAL_IX_HL
PUSH IX
POP DE
LD A,D
CP H
JR Z,EIH_1
XOR A
RET
EIH_1
LD A,E
CP L
JR Z,EIH_2
XOR A
RET
EIH_2 LD A,1
RET
;---------------------------
;Столкновение бокса HL и вражеского танка
ENEMY_COLLISION
;Размеры врага
LD A,15
LD (BOX_DE_W),A
LD (BOX_DE_H),A
LD (CURRENT_COOR),HL
PUSH HL
LD HL,ENEMY
LD B,E_COUNT
CO_E1
LD (ECOL_ADDR),HL
CALL EQUAL_IX_HL
CP 1
JR Z,C_NEXT ;Сами с собой не сталкиваемся
PUSH HL
LD DE,E_HP
ADD HL,DE
LD A,(HL)
POP HL
CP 0
JR Z,C_NEXT ;С трупами не сталкиваемся
PUSH HL
LD E,(HL)
INC HL
LD D,(HL)
LD HL,(CURRENT_COOR)
CALL BOX_COLLISION
POP HL
CP 1
JR Z,IS_COLLIZ ;Столкнулись с другим танком
C_NEXT
LD DE,ENEMY_LEN
ADD HL,DE
DJNZ CO_E1
XOR A ;Столкновений не обнаружено
POP HL
RET
IS_COLLIZ
LD A,1 ;Столкновение обнаружено
POP HL
RET
ECOL_ADDR
DEFW 0
;---------------------------
CURRENT_COOR
DEFW 0
;---------------------------
;Столкновение бокса HL и танка игрока
PLAYER_COLLISION
LD A,(T_ACTIVE)
CP 0
RET Z ;С трупом не сталкиваемся
;Размеры танка
LD A,15
LD (BOX_DE_W),A
LD (BOX_DE_H),A
LD DE,(T_COORD)
CALL BOX_COLLISION
RET
;---------------------------
;Столкновение бокса HL с пулей игрока
T_SHOT_COLLISION
PUSH IX
LD IX,T_SHOT
LD A,(T_COL_SHOT)
LD B,A
TSC_ALL PUSH BC
LD A,(IX+T_SH_ACTIVE)
CP 0
JR Z,TSC_NEXT
LD A,6
LD (BOX_DE_W),A
LD (BOX_DE_H),A
LD E,(IX+T_SH_COORD)
LD D,(IX+T_SH_COORD+1)
CALL BOX_COLLISION
CP 0
JR Z,TSC_NEXT
;...................
LD (IX+T_SH_ACTIVE),0
POP BC
POP IX
RET
;...................
TSC_NEXT
POP BC
LD DE,T_SH_LEN
ADD IX,DE
DJNZ TSC_ALL
POP IX
RET
;----------------------------
INIT_LEVEL
;Увеличим номер уровня
LD HL,STAGE_NUM
INC (HL)
;Обнулим счётчик убитых врагов
LD HL,0
LD (L_ECOUNT),HL
LD (L_ECOUNT+2),HL
;Установим новый таймер ожидания
LD A,150
LD (L_END_TIMER),A
LD IX,ENEMY
LD DE,ENEMY_LEN
LD B,E_COUNT
IL_EN XOR A
LD (IX+E_HP),A ;Враги не активированы
LD (IX+E_SH_ACTIVE),0 ;Патроны врагов не активированы
ADD IX,DE
DJNZ IL_EN
;Снаряды игрока не активированы
LD IX,T_SHOT
LD (IX+T_SH_ACTIVE),A
LD IX,T_SHOT+T_SH_LEN
LD (IX+T_SH_ACTIVE),A
;Персонаж не активирован
LD (T_ACTIVE),A
LD (T_SH_ACTIVE),A
;Бонус не активирован
LD (BONUS_COUNTER),A
LD (B_ACTIVE),A
;Количество врагов
LD A,20
LD (ENEMY_COUNT),A
;Подключим банку с уровнями
CALL BIND_BUF_0
LD DE,(LEVEL_ADDR) ;В DE адрес уровня
LD A,(DE)
LD (LEVEL_ADDR),A ;Следующий уровень
INC DE
LD A,(DE)
LD (LEVEL_ADDR+1),A
INC DE
;Распакуем уровень
LD HL,LEVEL
L_I_NXT LD A,(DE)
CP 0
JR Z,L_I_ENDLVL
AND 248
SRL A
SRL A
SRL A
LD B,A
LD A,(DE)
AND 7
L_I_IND LD (HL),A
INC HL
DJNZ L_I_IND
INC DE
JR L_I_NXT
L_I_ENDLVL
;Добавим штаб и забор
LD HL,#0101
LD (LEVEL+557),HL
LD (LEVEL+559),HL
LD A,1
LD (LEVEL+583),A
LD (LEVEL+586),A
LD (LEVEL+609),A
LD (LEVEL+612),A
LD HL,#0606
LD (LEVEL+584),HL
LD (LEVEL+610),HL
;Нарисуем уровень в первую банку при видимой первой
CALL SET_VIDEO5
LD B,5
LD A,0
CALL CLS
CALL CLOSE_WEIL
CALL COLORIZE_BUF
CALL PRINT_LEVEL
CALL START_MELODY
CALL OPEN_WEIL
CALL PRINT_MINI
CALL COLORIZE_RIGHT
;Нарисуем уровень во вторую банку при видимой уже рисованной первой
CALL SWAP_SCREEN
LD B,5
LD A,40
CALL CLS
CALL COLORIZE_BUF
CALL COLORIZE_SCREEN
CALL PRINT_LEVEL
CALL PRINT_MINI
RET
;---------------------------
;Инициализация врагов в ходе игры
INIT_EMPTY_ENEMY
LD A,(ENEMY_COUNT)
CP 0
RET Z ;Выходим, если кончились
LD IX,ENEMY
LD B,E_COUNT
IEE1 LD A,(IX+E_HP)
CP 0
JR Z,IEE2 ;Если этот враг жив, место занято
LD DE,ENEMY_LEN
ADD IX,DE
DJNZ IEE1
RET
IEE2 ;Нашли неактивированного врага
CALL RND_255
AND 3
LD (IX+E_TYPE),A
INC A
LD B,A
LD A,(DEFICULT)
ADD A,B
LD (IX+E_HP),A ;Сделаем живым
LD A,(SPAWN_POS)
LD HL,#0000 ;Первая точка спавна
CP 0
JR Z,IEE4
LD HL,#6000 ;Вторая точка спавна
CP 1
JR Z,IEE4
LD HL,#C000 ;Третья точка спавна
IEE4 INC A
CP 3
JR NZ,IEE5
XOR A
IEE5 LD (SPAWN_POS),A
LD (IX+E_BONUSED),0
LD (IX+E_VISIBLE),1
LD A,(BONUS_COUNTER)
INC A
CP 5 ;Каждый 5ый танк с бонусом
JR NZ,IEE_NB
LD (IX+E_BONUSED),1
LD (IX+E_BLINK_TIMER),0
XOR A
IEE_NB LD (BONUS_COUNTER),A
;Координаты
LD (IX+E_COORD),L
LD (IX+E_COORD+1),H
;Выбор спрайта
PUSH IX
CALL SELECT_E_SPRITE
POP IX
;Спрайт
LD L,(IX+E_SPRITE_ADDR)
LD H,(IX+E_SPRITE_ADDR+1)
LD DE,64
ADD HL,DE ;Направление вниз
LD (IX+E_SPR_ADR),L
LD (IX+E_SPR_ADR+1),H
LD (IX+E_SPR_H),16
LD (IX+E_SPR_W),2
LD (IX+E_DIRECT),4 ;Направление вниз
LD (IX+E_FASE),0
LD A,(ENEMY_COUNT)
DEC A ;Уменьшим количество врагов
LD (ENEMY_COUNT),A
CALL PRINT_MINI
CALL SWAP_SCREEN
CALL PRINT_MINI
CALL SWAP_SCREEN
RET
;--------------------------
INIT_PLAYER
LD A,(T_LIVES)
CP 0
RET Z ;Жизней больше нет
LD A,(T_ACTIVE)
CP 1
RET Z ;Если мы живы, не инициализируем
;Координаты
LD HL,#40B0
LD (T_COORD),HL
;Размеры спрайта
LD A,2
LD (T_SPR_W),A
LD A,16
LD (T_SPR_H),A
;Сам спрайт
LD HL,TANK_UP1
LD (T_SPR_ADR),HL
;Направление вверх
LD A,3
LD (T_DIRECT),A
;Делаем активным
LD A,1
LD (T_ACTIVE),A
;Защиту на первое время
LD A,50
LD (T_PROTECT_TIMER),A
;Выбор спрайта
CALL SELECT_T_SPRITE
RET
;--------------------------
INIT_BONUS
;Координаты
CALL RND_255
AND 10
SLA A
INC A
SLA A
SLA A
SLA A
LD (B_COORD),A ;Y
CALL RND_255
AND 11
SLA A
INC A
SLA A
SLA A
SLA A
LD (B_COORD+1),A ;X
;Индекс
CALL RND_255
LD B,0
CP 42
JR C,IB_1
LD B,1
CP 84
JR C,IB_1
LD B,2
CP 126
JR C,IB_1
LD B,3
CP 168
JR C,IB_1
LD B,4
CP 210
JR C,IB_1
LD B,5
;CP 210
;JR C,IB_1
IB_1 LD A,B
LD (B_INDEX),A
LD A,1
LD (B_ACTIVE),A
LD (B_VISIBLE),A
LD (B_BLINK_TIMER),A
;Подключим банку со спрайтами
;Сам спрайт
LD HL,B_1-32
LD DE,32
LD A,(B_INDEX)
LD B,A
INC B
IB_ADD ADD HL,DE
DJNZ IB_ADD
LD A,(#5B5C)
PUSH AF
CALL BIND_BUF_0
LD DE,B_SPRITE
LD BC,32
LDIR
POP AF
CALL SET_VIDEO_A
CALL ON_BONUS_SOUND
RET
;--------------------------
SET_VIDEO_A
DI
LD (#5B5C),A
LD BC,#7FFD
OUT (C),A
EI
RET
;--------------------------
;Переключение буфферов
SWAP_SCREEN
DI
BUF_MODE
LD A,%00011101 ;16+8+5
XOR %00001010 ;->%00010111=16+0+7
LD (BUF_MODE+1),A
LD (#5B5C),A
LD BC,#7FFD
OUT (C),A
EI
RET
;--------------------------
;Включение и бинд буффера 5
SET_VIDEO5
DI
LD A,%00011101 ;Востановим значение в свапскрине
LD (BUF_MODE+1),A
LD A,%00010101
LD (#5B5C),A
LD BC,#7FFD
OUT (C),A
EI
RET
;--------------------------
;Бинд буффера 0
BIND_BUF_0
DI
LD A,(#5B5C)
AND 24
LD (#5B5C),A
LD BC,#7FFD
OUT (C),A
EI
RET
;---------------------------
PRINT_ENEMYS
LD IX,ENEMY
LD B,E_COUNT
P_E1 PUSH BC
LD A,(IX+E_HP)
CP 0
JR Z,P_E2
LD L,(IX+E_COORD) ;В рабочие координаты
LD H,(IX+E_COORD+1)
LD (W_COORD),HL
LD A,(IX+E_SPR_W)
LD (W_SPRW),A
LD A,(IX+E_SPR_H)
LD (W_SPRH),A
LD A,(IX+E_VISIBLE)
CP 0
JR Z,P_E11
;Режим спрайта
LD A,MOD_OR
LD (MODE),A
;Рисуем спрайт
LD L,(IX+E_SPR_ADR)
LD H,(IX+E_SPR_ADR+1)
LD (W_SPRADR),HL
CALL PRINT_SPRITE
P_E11 LD A,(IX+E_BONUSED)
CP 0
JR Z,P_E2
LD A,(IX+E_BLINK_TIMER)
INC A
CP BLINK_TIME
JR NZ,P_E_NB
LD A,(IX+E_VISIBLE)
XOR 1
LD (IX+E_VISIBLE),A
XOR A
P_E_NB LD (IX+E_BLINK_TIMER),A
P_E2 POP BC
LD DE,ENEMY_LEN
ADD IX,DE
DJNZ P_E1
RET
;--------------------------
PRINT_PLAYER
LD A,(T_ACTIVE)
CP 0
RET Z
;Инициализируем переменные
LD HL,(T_COORD)
LD (W_COORD),HL
LD A,(T_SPR_W)
LD (W_SPRW),A
LD A,(T_SPR_H)
LD (W_SPRH),A
LD A,(T_VISIBLE)
CP 0
JR Z,P_P1
;Установим режим спрайта
LD A,MOD_OR
LD (MODE),A
LD HL,(T_SPR_ADR)
LD (W_SPRADR),HL
;Рисуем спрайт
CALL PRINT_SPRITE
P_P1 LD A,(T_PROTECT_TIMER)
CP 0
JR NZ,P_P2
LD A,1
LD (T_VISIBLE),A
RET
P_P2 DEC A
LD (T_PROTECT_TIMER),A
LD A,(T_BLINK_TIMER)
INC A
CP BLINK_TIME
JR NZ,P_P_NB
LD A,(T_VISIBLE)
XOR 1
LD (T_VISIBLE),A
XOR A
P_P_NB LD (T_BLINK_TIMER),A
RET
;--------------------------
PRINT_BONUS
;Нарисуем курицу
LD HL,#60B0
LD (W_COORD),HL
LD A,2
LD (W_SPRW),A
LD A,16
LD (W_SPRH),A
LD A,MOD_OR
LD (MODE),A
LD HL,SPR_BASE
LD A,(BASE_DAMAGED)
CP 1
JR NZ,P_BE
LD HL,SPR_BASE_DEAD
P_BE
LD (W_SPRADR),HL
CALL PRINT_SPRITE
LD A,(B_ACTIVE)
CP 0
RET Z
LD A,(B_BLINK_TIMER)
INC A
CP BLINK_TIME
JR NZ,PB_NB
LD A,(B_VISIBLE)
XOR 1
LD (B_VISIBLE),A
XOR A
PB_NB LD (B_BLINK_TIMER),A
LD A,(B_VISIBLE)
CP 0
RET Z
;Инициализируем переменные
LD HL,(B_COORD)
LD (W_COORD),HL
LD A,2
LD (W_SPRW),A
LD A,16
LD (W_SPRH),A
;Установим режим маски
LD A,MOD_AND
LD (MODE),A
LD HL,B_MASK
LD (W_SPRADR),HL
;Рисуем маску
CALL PRINT_SPRITE
;Установим режим спрайта
LD A,MOD_OR
LD (MODE),A
LD HL,B_SPRITE
LD (W_SPRADR),HL
;Рисуем спрайт
CALL PRINT_SPRITE
RET
;--------------------------
PRINT_T_SHOT
LD IX,T_SHOT
LD A,(T_COL_SHOT)
LD B,A
PTS_ALL PUSH BC
LD A,(IX+T_SH_ACTIVE)
CP 0
JR Z,PTS_NEXT
;Инициализируем переменные
LD L,(IX+T_SH_COORD)
LD H,(IX+T_SH_COORD+1)
LD (W_COORD),HL
LD A,2
LD (W_SPRW),A
LD A,8
LD (W_SPRH),A
LD A,H
LD HL,SPR_SHOT
AND 7
CP 0
JR Z,NO_ADDSH
LD DE,16
LD B,A
ADDSH ADD HL,DE
DJNZ ADDSH
NO_ADDSH
;PUSH HL
;LD DE,128 ;Смещение до маски
;ADD HL,DE
;Установим режим маски
;LD A,MOD_AND
;LD (MODE),A
;LD (W_SPRADR),HL
;Рисуем маску
;CALL PRINT_SPRITE
;POP HL
;Установим режим спрайта
LD A,MOD_OR
LD (MODE),A
LD (W_SPRADR),HL
;Рисуем спрайт
CALL PRINT_SPRITE
PTS_NEXT
POP BC
LD DE,T_SH_LEN
ADD IX,DE
DJNZ PTS_ALL
RET
;--------------------------
PRINT_E_SHOT
LD IX,ENEMY
LD B,E_COUNT
PES1 PUSH BC
LD A,(IX+E_SH_ACTIVE)
CP 0
JR Z,PENEXT
;Инициализируем переменные
LD L,(IX+E_SH_COORD)
LD H,(IX+E_SH_COORD+1)
LD (W_COORD),HL
LD A,2
LD (W_SPRW),A
LD A,8
LD (W_SPRH),A
LD A,H
LD HL,SPR_SHOT
AND 7
CP 0
JR Z,PES_NO_ADDSH
LD DE,16
LD B,A
PES_ADDSH
ADD HL,DE
DJNZ PES_ADDSH
PES_NO_ADDSH
;Установим режим спрайта
LD A,MOD_OR
LD (MODE),A
LD (W_SPRADR),HL
;Рисуем спрайт
CALL PRINT_SPRITE
PENEXT LD DE,ENEMY_LEN
ADD IX,DE
POP BC
DJNZ PES1
RET
;--------------------------
PRINT_FON
;Инициализируем переменные
LD HL,(T_OLD_COORD)
LD (W_COORD),HL
LD HL,(T_COORD)
LD (T_OLD_COORD),HL
LD A,(T_SPR_W)
LD (W_SPRW),A
LD A,(T_SPR_H)
LD (W_SPRH),A
;Восстановим фон под игроком
CALL RESTORE_FON
;.............................
LD IX,ENEMY
LD B,E_COUNT
P_F1 PUSH BC
LD L,(IX+E_OLD_COORD) ;В рабочие координаты
LD H,(IX+E_OLD_COORD+1)
LD (W_COORD),HL
LD L,(IX+E_COORD)
LD H,(IX+E_COORD+1)
LD (IX+E_OLD_COORD),L
LD (IX+E_OLD_COORD+1),H
LD A,(IX+E_SPR_W)
LD (W_SPRW),A
LD A,(IX+E_SPR_H)
LD (W_SPRH),A
;Восстановим фон под врагом
CALL RESTORE_FON
POP BC
LD DE,ENEMY_LEN
ADD IX,DE
DJNZ P_F1
;.............................
LD IX,T_SHOT
LD A,(T_COL_SHOT)
LD B,A
P_F3 PUSH BC
;Инициализируем переменные
LD L,(IX+T_SH_OLD_COORD)
LD H,(IX+T_SH_OLD_COORD+1)
LD (W_COORD),HL
LD L,(IX+T_SH_COORD)
LD H,(IX+T_SH_COORD+1)
LD (IX+T_SH_OLD_COORD),L
LD (IX+T_SH_OLD_COORD+1),H
LD A,2
LD (W_SPRW),A
LD A,16
LD (W_SPRH),A
;Восстановим фон под снарядом
CALL RESTORE_FON
POP BC
LD DE,T_SH_LEN
ADD IX,DE
DJNZ P_F3
;.............................
LD IX,ENEMY
LD B,E_COUNT
P_F2 PUSH BC
;Инициализируем переменные
LD L,(IX+E_SH_OLD_COORD)
LD H,(IX+E_SH_OLD_COORD+1)
LD (W_COORD),HL
LD L,(IX+E_SH_COORD)
LD H,(IX+E_SH_COORD+1)
LD (IX+E_SH_OLD_COORD),L
LD (IX+E_SH_OLD_COORD+1),H
LD A,2
LD (W_SPRW),A
LD A,16
LD (W_SPRH),A
;Восстановим фон под снарядом
CALL RESTORE_FON
POP BC
LD DE,ENEMY_LEN
ADD IX,DE
DJNZ P_F2
;.............................
;Инициализируем переменные
LD HL,(B_OLD_COORD)
LD (W_COORD),HL
LD HL,(B_COORD)
LD (B_OLD_COORD),HL
LD A,2
LD (W_SPRW),A
LD A,16
LD (W_SPRH),A
;Восстановим фон под бонусом
CALL RESTORE_FON
RET
;--------------------------
RESTORE_FON
;Ограничим выход буфера за пределы уровня
LD HL,(W_COORD)
SRL H
SRL H
SRL H
SRL L
SRL L
SRL L
LD A,(W_SPRW) ;2
INC A ;3
ADD A,H ;23+3=26
LD B,A ;26
LD A,(W_SPRH) ;16
SRL A
SRL A
SRL A ;2
INC A ;3
ADD A,L ;+0
LD C,A ;3
XOR A
CP H ;0
JR Z,N_DECH
DEC H ;23
N_DECH
CP L ;0
JR Z,N_DECL
DEC L
N_DECL ;0
LD A,25
CP B ;26
JR NC,N_DECB
LD B,26 ;25
N_DECB
LD A,23
CP C ;3
JR NC,N_DECC
LD C,24
N_DECC
LD A,C ;3
SUB L ;3-0=3
ADD A,A ;6
ADD A,A ;12
ADD A,A ;24
LD C,A ;24
LD A,B ;25
SUB H ;23
LD B,A ;2
CALL ADR ;C000
RES_DH PUSH HL
PUSH BC
LD E,L ;0
LD A,H ;C0
OR #20
LD D,A ;E0
RES_DW LD A,(DE)
LD (HL),A
INC HL ;C001
INC DE ;E001
DJNZ RES_DW
POP BC
POP HL
CALL DOWN ;C100
DEC C
JR NZ,RES_DH
RET
;--------------------------
FILL_COORD_POS
SRL H
SRL H
SRL H
SRL L
SRL L
SRL L
PUSH HL
CALL ADR
LD A,#20
OR H
LD D,A
LD E,L
PUSH IX
LD B,8
FCP_D LD IX,0
CCP LD A,(IX)
LD (DE),A
LD (HL),A
INC H
INC D
INC IX
DJNZ CCP
POP IX
POP HL
LD E,H
LD D,0
LD H,0
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,DE
LD DE,#D800
ADD HL,DE
LD A,#20
OR H
LD D,A
LD E,L
FCP_CLR LD A,0
LD (HL),A
LD (DE),A
RET
FCP_DATA EQU FCP_D+2
FCP_COLOR EQU FCP_CLR+1
;---------------------
PRINT_SPRITE
LD HL,(W_COORD)
SRL L
SRL L
SRL L
SRL H
SRL H
SRL H
CALL ADR
LD A,(W_COORD)
AND 7
ADD A,H
LD H,A
LD DE,(W_SPRADR)
LD A,(W_SPRH)
LD B,A ;Высота спрайта в пикселях
FOR_Y PUSH BC
PUSH HL ;Сохраним адрес буффера
LD A,(W_SPRW)
LD C,A ;Ширина спрайта в знакоместах
FOR_X LD A,(DE) ;Байт спрайта
MODE NOP
LD (HL),A ;В экран
INC DE ;Следующий байт спрайта
INC HL ;Соседнее знакоместо в экране
DEC C ;Уменьшим ширину спрайта
JR NZ,FOR_X
POP HL ;Вспомним адрес экрана
POP BC
CALL DOWN
DJNZ FOR_Y
RET
MOD_PUT EQU #00 ;NOP
MOD_OR EQU #B6 ;OR (HL)
MOD_AND EQU #A6 ;AND (HL)
MOD_XOR EQU #AE ;XOR (HL)
;------------------------------
COLORIZE_BUF
LD HL,#F800
LD DE,LEVEL
LD C,24
CLR_1 PUSH BC
PUSH HL
PUSH DE
LD B,26
CLR_2
LD A,(DE)
LD C,%00100010
CP 1
JR Z,CLR_3
LD C,%00000111
CP 2
JR Z,CLR_3
LD C,%01001111
CP 3
JR Z,CLR_3
LD C,%00100110
CP 4
JR Z,CLR_3
LD C,%00101111
CP 5
JR Z,CLR_3
LD C,%00000010
CP 6
JR Z,CLR_3
LD C,7
CLR_3
LD (HL),C
INC HL
INC DE
DJNZ CLR_2
POP HL
LD BC,26
ADD HL,BC
EX DE,HL
POP HL
LD BC,32
ADD HL,BC
POP BC
DEC C
JR NZ,CLR_1
RET
;------------------------------
COLORIZE_SCREEN
LD HL,#F800
LD DE,#D800
LD BC,768
LDIR
RET
;----------------------
COLORIZE_RIGHT
LD HL,#D81A
LD B,24
LD DE,32
C_R1 PUSH HL
LD (HL),%00101000
INC HL
LD (HL),%00101000
INC HL
LD (HL),%00101000
INC HL
LD (HL),%00101000
INC HL
LD (HL),%00101000
INC HL
LD (HL),%00101000
POP HL
ADD HL,DE
DJNZ C_R1
RET
;------------------------------
OPEN_WEIL
LD HL,#D960
LD (TOP_A),HL
LD HL,#D980
LD (BOT_A),HL
LD B,12
O_W1 PUSH BC
LD HL,(TOP_A)
LD DE,#2000
ADD HL,DE
LD DE,(TOP_A)
LD BC,26
LDIR
LD HL,(BOT_A)
LD DE,#2000
ADD HL,DE
LD DE,(BOT_A)
LD BC,26
LDIR
LD DE,32
LD HL,(TOP_A)
AND A
SBC HL,DE
LD (TOP_A),HL
LD HL,(BOT_A)
ADD HL,DE
LD (BOT_A),HL
LD BC,1000
O_W2 DEC BC
LD A,B
OR C
JR NZ,O_W2
POP BC
DJNZ O_W1
RET
TOP_A DEFW 0
BOT_A DEFW 0
;----------------------
CLOSE_WEIL
LD HL,#D800
LD (TOP_A),HL
LD HL,#DAE0
LD (BOT_A),HL
LD B,12
C_W1 PUSH BC
LD HL,(TOP_A)
PUSH HL
POP DE
INC DE
LD (HL),%00101101
LD BC,31
LDIR
LD HL,(BOT_A)
PUSH HL
POP DE
INC DE
LD (HL),%00101101
LD BC,31
LDIR
LD BC,1000
C_W2 DEC BC
LD A,B
OR C
JR NZ,C_W2
POP BC
LD DE,32
LD HL,(TOP_A)
ADD HL,DE
LD (TOP_A),HL
LD HL,(BOT_A)
AND A
SBC HL,DE
LD (BOT_A),HL
DJNZ C_W1
RET
;---------------------------
CLS
PUSH BC
LD DE,#C001
LD HL,#C000
LD (HL),0
LD BC,#1800
LDIR
LD (HL),A
LD BC,#0300
LDIR
LD DE,#E001
LD HL,#E000
LD (HL),0
LD BC,#1800
LDIR
LD (HL),A
LD BC,#0300
LDIR
POP AF
CALL 8859 ;BORDER
RET
;--------------------------
PRINT_LEVEL
LD HL,#0000 ;X,Y - В знакоместах
LD DE,LEVEL ;Данные уровня
P_L3 PUSH HL ;Сохраним X,Y
CALL ADR
LD C,26 ;Цикл по ширине уровня
P_L2 PUSH DE
PUSH HL
LD A,(DE) ;Значение из уровня
ADD A,A ;Умножим на 8
ADD A,A
ADD A,A
LD H,0
LD L,A
LD DE,SPR_C0
ADD HL,DE
EX DE,HL ;Адрес тайла
POP HL
PUSH HL
LD B,8
P_L1 LD A,(DE)
LD (HL),A
INC H
INC DE
DJNZ P_L1
P_L4 POP HL
POP DE
INC DE
INC HL
DEC C
JR NZ,P_L2
POP HL
INC L
LD A,L
CP 24
JR NZ,P_L3
;Сделаем копию уровня во второй половине банки
LD HL,#0000
CALL ADR
LD E,L
LD A,H
OR #20
LD D,A
LD BC,#1800
LDIR
RET
;--------------------------
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
;--------------------------
ADR LD A,L
AND 7
RRCA
RRCA
RRCA
ADD A,H
LD H,L
LD L,A
LD A,H
AND #18
OR #C0
LD H,A
RET
;---------------------------
E_SHOT_MOVE
;Данные для очистки/заполнения
LD HL,SPR_C0
LD (FCP_DATA),HL
LD A,7
LD (FCP_COLOR),A
LD A,3
LD (L_DOP),A
LD IX,ENEMY
LD B,E_COUNT
ESMALL PUSH BC
LD A,(IX+E_SH_ACTIVE)
CP 0
JP Z,ESM_NEXT
LD A,(IX+E_SH_DIRECT)
LD L,(IX+E_SH_COORD)
LD H,(IX+E_SH_COORD+1)
CALL UPDATE_COORD
CALL UPDATE_COORD
CALL UPDATE_COORD
LD A,H
CP 203
JR C,ESM1
XOR A
LD (IX+E_SH_ACTIVE),A
JP ESM_NEXT
ESM1 LD A,L
CP 187
JR C,ESM2
XOR A
LD (IX+E_SH_ACTIVE),A
JP ESM_NEXT
ESM2
LD A,6
LD (BOX_HL_W),A
LD (BOX_HL_H),A
CALL T_SHOT_COLLISION
CP 1
JR NZ,ESM3
LD (IX+E_SH_ACTIVE),0
JP ESM_NEXT
ESM3
CALL PLAYER_COLLISION
CP 1
JR NZ,ESM4
XOR A
LD (IX+E_SH_ACTIVE),A
LD A,(T_PROTECT_TIMER)
CP 0
JP NZ,ESM_NEXT
LD A,(T_POWER)
CP 3
JR NC,ESM_NODED
XOR A
LD (T_ACTIVE),A
LD A,(T_LIVES)
DEC A
LD (T_LIVES),A
;Уберём пистолет
XOR A
LD (T_POWER),A
INC A
LD (T_COL_SHOT),A
CALL ON_CRASH_SOUND
CALL SELECT_T_SPRITE
JP ESM_NEXT
ESM_NODED
;Уберём пистолет
LD A,2
LD (T_POWER),A
CALL ON_CLANG_SOUND
CALL SELECT_T_SPRITE
JP ESM_NEXT
;....................
ESM4 PUSH HL
CALL COORD_IS_FILL
CP 1
JR NZ,ESM5
XOR A
LD (IX+E_SH_ACTIVE),A
CALL TM_CLR
ESM5 POP HL
PUSH HL
LD A,5
ADD A,L
LD L,A
CALL COORD_IS_FILL
CP 1
JR NZ,ESM6
XOR A
LD (IX+E_SH_ACTIVE),A
CALL TM_CLR
ESM6 POP HL
PUSH HL
LD A,5
ADD A,H
LD H,A
CALL COORD_IS_FILL
CP 1
JR NZ,ESM7
XOR A
LD (IX+E_SH_ACTIVE),A
CALL TM_CLR
ESM7 POP HL
PUSH HL
LD A,5
ADD A,H
LD H,A
LD A,5
ADD A,L
LD L,A
CALL COORD_IS_FILL
CP 1
JR NZ,ESM_UC
XOR A
LD (IX+E_SH_ACTIVE),A
CALL TM_CLR
ESM_UC POP HL
LD (IX+E_SH_COORD),L
LD (IX+E_SH_COORD+1),H
ESM_NEXT
POP BC
LD DE,ENEMY_LEN
ADD IX,DE
DEC B
JP NZ,ESMALL
RET
;---------------------------
TM_CLR
LD B,A
LD DE,(CALCULATED_LPOS)
LD A,(DE)
CP 6
JR NZ,TM_C1
LD A,1
LD (BASE_DAMAGED),A
CALL ON_CRASH_SOUND
RET
TM_C1 LD A,B
CP 3
JR C,HER
;Данные для очистки/заполнения
TM_ZR LD DE,SPR_C0
LD (FCP_DATA),DE
LD A,7
LD (FCP_COLOR),A
XOR A
LD DE,(CALCULATED_LPOS)
LD (DE),A
TM_ZR1 PUSH HL
CALL FILL_COORD_POS
POP HL
CALL SWAP_SCREEN
CALL FILL_COORD_POS
CALL SWAP_SCREEN
RET
HER LD DE,(CALCULATED_LPOS)
LD A,(DE)
CP 2 ;Бетонка
RET Z
CP 7 ;Полуразрушеный кирпич
JR Z,TM_ZR ;Доламываем
LD A,7 ;Рушим кирпич
LD (DE),A
LD DE,SPR_C1
LD (FCP_DATA),DE
LD A,2
LD (FCP_COLOR),A
JR TM_ZR1
;---------------------------
T_SHOT_MOVE
LD A,3
LD (L_DOP),A
LD IX,T_SHOT
LD A,(T_COL_SHOT)
LD B,A
TSMALL PUSH BC
LD A,(IX+T_SH_ACTIVE)
CP 0
JP Z,T_SH_NEXT
LD A,(IX+T_SH_DIRECT)
LD L,(IX+T_SH_COORD)
LD H,(IX+T_SH_COORD+1)
CALL UPDATE_COORD
CALL UPDATE_COORD
CALL UPDATE_COORD
LD A,(IX+T_SH_SPEED)
CP 0
LD A,(IX+T_SH_DIRECT)
JR Z,NO_SPEED
CALL UPDATE_COORD
CALL UPDATE_COORD
NO_SPEED
LD A,H
CP 203
JR C,TSM1
LD (IX+T_SH_ACTIVE),0
JP T_SH_NEXT
TSM1 LD A,L
CP 187
JR C,TSM2
LD (IX+T_SH_ACTIVE),0
JP T_SH_NEXT
TSM2 LD A,6
LD (BOX_HL_W),A
LD (BOX_HL_H),A
PUSH HL
CALL ENEMY_COLLISION
POP HL
CP 0
JR Z,TSM3
LD (IX+T_SH_ACTIVE),0
PUSH IX
LD IX,(ECOL_ADDR)
DEC (IX+E_HP)
LD A,(IX+E_BONUSED)
CP 1
CALL Z,INIT_BONUS
LD (IX+E_BONUSED),0
LD (IX+E_VISIBLE),1
LD A,(IX+E_HP)
LD B,(IX+E_TYPE)
POP IX
CP 0
JR Z,CRASH
CALL ON_CLANG_SOUND
JP T_SH_NEXT
CRASH
LD HL,L_ECOUNT
LD E,B
LD D,0
ADD HL,DE
INC (HL)
LD HL,(SCORE)
INC E
ADD HL,DE
LD (SCORE),HL
CALL ON_CRASH_SOUND
JP T_SH_NEXT
TSM3 PUSH HL
CALL COORD_IS_FILL
CALL CUT_BUSH
CP 1
JR NZ,TSM4
LD (IX+T_SH_ACTIVE),0
LD A,(T_POWER)
CALL TM_CLR
TSM4 POP HL
PUSH HL
LD A,5
ADD A,L
LD L,A
CALL COORD_IS_FILL
CALL CUT_BUSH
CP 1
JR NZ,TSM5
LD (IX+T_SH_ACTIVE),0
LD A,(T_POWER)
CALL TM_CLR
TSM5 POP HL
PUSH HL
LD A,5
ADD A,H
LD H,A
CALL COORD_IS_FILL
CALL CUT_BUSH
CP 1
JR NZ,TSM6
LD (IX+T_SH_ACTIVE),0
LD A,(T_POWER)
CALL TM_CLR
TSM6 POP HL
PUSH HL
LD A,5
ADD A,H
LD H,A
LD A,5
ADD A,L
LD L,A
CALL COORD_IS_FILL
CALL CUT_BUSH
CP 1
JR NZ,TSMEND
LD (IX+T_SH_ACTIVE),0
LD A,(T_POWER)
CALL TM_CLR
TSMEND POP HL
LD (IX+T_SH_COORD),L
LD (IX+T_SH_COORD+1),H
T_SH_NEXT
POP BC
LD DE,T_SH_LEN
ADD IX,DE
DEC B
JP NZ,TSMALL
RET
;----------------------------
CUT_BUSH
LD (CUT_COORD),HL
PUSH HL
PUSH AF
LD HL,(CALCULATED_LPOS)
LD A,(HL)
CP 4
JR NZ,NO_CUT ;Не куст
LD A,(T_POWER)
CP 5
JR C,NO_CUT ;Не хватает силы
;Данные для очистки/заполнения
LD HL,SPR_C0
LD (FCP_DATA),HL
LD A,7
LD (FCP_COLOR),A
LD HL,(CUT_COORD)
CALL FILL_COORD_POS
CALL SWAP_SCREEN
LD HL,(CUT_COORD)
CALL FILL_COORD_POS
CALL SWAP_SCREEN
NO_CUT POP AF
POP HL
RET
CUT_COORD
DEFW 0
;----------------------------
UPDATE_COORD
CP 1
JR Z,UPD_L
CP 2
JR Z,UPD_R
CP 3
JR Z,UPD_U
CP 4
JR Z,UPD_D
RET
UPD_L DEC H
RET
UPD_R INC H
RET
UPD_U DEC L
RET
UPD_D INC L
RET
;-----------------------------
PRESS_F
LD A,(T_SH_TIMER)
CP 0
JR Z,PF_S
DEC A
LD (T_SH_TIMER),A
RET
PF_S LD IX,T_SHOT
LD A,(T_COL_SHOT)
LD B,A
PF_ALL PUSH BC
LD A,(T_SH_TIMER)
CP 0
JR NZ,PF_NEXT
LD A,(IX+T_SH_ACTIVE)
CP 1
JR Z,PF_NEXT
LD A,(T_DIRECT)
LD HL,(T_COORD)
LD D,5
LD E,5
ADD HL,DE
LD (IX+T_SH_COORD),L
LD (IX+T_SH_COORD+1),H
LD (IX+T_SH_DIRECT),A
LD (IX+T_SH_ACTIVE),1
LD (IX+T_SH_SPEED),0
LD A,(T_POWER)
CP 0
JR Z,NOSPEED
LD (IX+T_SH_SPEED),1
NOSPEED
CALL ON_SHOT_SOUND
LD A,1
LD (T_SH_TIMER),A
PF_NEXT POP BC
LD DE,T_SH_LEN
ADD IX,DE
DJNZ PF_ALL
RET
;-----------------------------
PRESS_R
LD A,(T_ACTIVE)
CP 0
RET Z
LD A,2
LD (T_DIRECT),A
LD A,(T_COORD) ;Сделаем "поперечную" координату кратной 8
BIT 2,A
JR Z,PR_R1
ADD A,8
PR_R1 AND 248
LD (T_COORD),A
LD A,3
LD (T_SPR_W),A
LD A,(T_COORD+1)
INC A
CP 193
JR Z,CLC_SN
LD HL,(T_COORD)
LD A,16
ADD A,H
LD H,A
PUSH HL
CALL COORD_IS_FILL
POP HL
CP 1
JR Z,CLC_SN
PUSH HL
LD A,15
ADD A,L
LD L,A
CALL COORD_IS_FILL
POP HL
CP 1
JR Z,CLC_SN
LD A,0
LD (BOX_HL_W),A
LD A,15
LD (BOX_HL_H),A
CALL ENEMY_COLLISION
CP 1
JR Z,CLC_SN
LD HL,(T_COORD)
INC H
LD (T_COORD),HL
CLC_SN LD HL,TANK_RIGHT1
LD A,(T_FASE)
XOR 1
LD (T_FASE),A
CP 0
JR Z,NO_RF2
LD HL,TANK_RIGHT2
NO_RF2
LD A,(T_COORD+1)
AND 7
CP 0
JR Z,NO_ADDSR
LD DE,48
LD B,A
ADDSR ADD HL,DE
DJNZ ADDSR
NO_ADDSR
LD (T_SPR_ADR),HL
RET
;-----------------------------
PRESS_L
LD A,(T_ACTIVE)
CP 0
RET Z
LD A,1
LD (T_DIRECT),A
LD A,(T_COORD)
BIT 2,A
JR Z,PR_L1
ADD A,8
PR_L1 AND 248
LD (T_COORD),A
LD A,3
LD (T_SPR_W),A
LD A,(T_COORD+1)
DEC A
CP 255
JR Z,CLC_SL
LD HL,(T_COORD)
DEC H
PUSH HL
CALL COORD_IS_FILL
POP HL
CP 1
JR Z,CLC_SL
PUSH HL
LD A,15
ADD A,L
LD L,A
CALL COORD_IS_FILL
POP HL
CP 1
JR Z,CLC_SL
LD A,0
LD (BOX_HL_W),A
LD A,15
LD (BOX_HL_H),A
CALL ENEMY_COLLISION
CP 1
JR Z,CLC_SL
LD HL,(T_COORD)
DEC H
LD (T_COORD),HL
CLC_SL LD HL,TANK_LEFT1
LD A,(T_FASE)
XOR 1
LD (T_FASE),A
CP 0
JR Z,NO_F2
LD HL,TANK_LEFT2
NO_F2
LD A,(T_COORD+1)
AND 7
CP 0
JR Z,NO_ADDSL
LD DE,48
LD B,A
ADDSL ADD HL,DE
DJNZ ADDSL
NO_ADDSL
LD (T_SPR_ADR),HL
RET
;-----------------------------
PRESS_U
LD A,(T_ACTIVE)
CP 0
RET Z
LD A,3
LD (T_DIRECT),A
LD A,(T_COORD+1)
BIT 2,A
JR Z,PR_U1
ADD A,8
PR_U1 AND 248
LD (T_COORD+1),A
LD A,2
LD (T_SPR_W),A
LD A,(T_COORD)
DEC A
CP 255
JR Z,CLC_SU
LD HL,(T_COORD)
DEC L
PUSH HL
CALL COORD_IS_FILL
POP HL
CP 1
JR Z,CLC_SU
PUSH HL
LD A,15
ADD A,H
LD H,A
CALL COORD_IS_FILL
POP HL
CP 1
JR Z,CLC_SU
LD A,15
LD (BOX_HL_W),A
LD A,0
LD (BOX_HL_H),A
CALL ENEMY_COLLISION
CP 1
JR Z,CLC_SU
LD HL,(T_COORD)
DEC L
LD (T_COORD),HL
CLC_SU LD HL,TANK_UP1
LD A,(T_FASE)
XOR 1
LD (T_FASE),A
CP 0
JR Z,NO_UF2
LD HL,TANK_UP2
NO_UF2
LD (T_SPR_ADR),HL
RET
;-----------------------------
PRESS_D
LD A,(T_ACTIVE)
CP 0
RET Z
LD A,4
LD (T_DIRECT),A
LD A,(T_COORD+1)
BIT 2,A
JR Z,PR_D1
ADD A,8
PR_D1 AND 248
LD (T_COORD+1),A
LD A,2
LD (T_SPR_W),A
LD A,(T_COORD)
INC A
CP 177
JR Z,CLC_SD
LD HL,(T_COORD)
LD A,16
ADD A,L
LD L,A
PUSH HL
CALL COORD_IS_FILL
POP HL
CP 1
JR Z,CLC_SD
PUSH HL
LD A,15
ADD A,H
LD H,A
CALL COORD_IS_FILL
POP HL
CP 1
JR Z,CLC_SD
LD A,15
LD (BOX_HL_W),A
LD A,0
LD (BOX_HL_H),A
CALL ENEMY_COLLISION
CP 1
JR Z,CLC_SD
LD HL,(T_COORD)
INC L
LD (T_COORD),HL
CLC_SD
LD HL,TANK_DOWN1
LD A,(T_FASE)
XOR 1
LD (T_FASE),A
CP 0
JR Z,NO_DF2
LD HL,TANK_DOWN2
NO_DF2
LD (T_SPR_ADR),HL
;LD HL,PRESS_D
;LD (LAST_DIRECT+1),HL
RET
;------------------------------
KEY_TEST
SLT EQU 8
XOR A
LD (U_PRESSED),A
LD (D_PRESSED),A
LD (L_PRESSED),A
LD (R_PRESSED),A
LD (F_PRESSED),A
LD A,(F_PORT)
IN A,(254)
F_BIT BIT 0,A ;будет заменяться при редефайне
JR Z,K_T1 ;уже нажата, кемпстон не проверяем
LD A,(IS_KEMPSTON)
CP 0
JR Z,K_T11 ;кемпстон отключен, не проверяем
IN A,(31)
BIT 4,A
JR Z,K_T11
K_T1 LD A,1
LD (F_PRESSED),A
K_T11 LD A,(L_PORT) ;#FD
IN A,(254)
L_BIT BIT 0,A
JR Z,K_T2
LD A,(IS_KEMPSTON)
CP 0
JR Z,K_T22
IN A,(31)
BIT 1,A
JR Z,K_T22
K_T2 LD A,1
LD (L_PRESSED),A
LD A,SLT
LD (T_SLIP_TIMER),A
LD HL,PRESS_L
LD (LAST_DIRECT+1),HL
K_T22 LD A,(D_PORT) ;#FD
IN A,(254)
D_BIT BIT 1,A
JR Z,K_T3
LD A,(IS_KEMPSTON)
CP 0
JR Z,K_T33
IN A,(31)
BIT 3,A
JR Z,K_T33
K_T3 LD A,1
LD (D_PRESSED),A
LD A,SLT
LD (T_SLIP_TIMER),A
LD HL,PRESS_D
LD (LAST_DIRECT+1),HL
K_T33 LD A,(R_PORT) ;#FD
IN A,(254)
R_BIT BIT 2,A
JR Z,K_T4
LD A,(IS_KEMPSTON)
CP 0
JR Z,K_T44
IN A,(31)
BIT 0,A
JR Z,K_T44
K_T4 LD A,1
LD (R_PRESSED),A
LD A,SLT
LD (T_SLIP_TIMER),A
LD HL,PRESS_R
LD (LAST_DIRECT+1),HL
K_T44 LD A,(U_PORT) ;#FB
IN A,(254)
U_BIT BIT 1,A
JR Z,K_T5
LD A,(IS_KEMPSTON)
CP 0
RET Z ;JR Z,K_T55
IN A,(31)
BIT 2,A
RET Z ;JR NZ,K_T55
K_T5 LD A,1
LD (U_PRESSED),A
LD A,SLT
LD (T_SLIP_TIMER),A
LD HL,PRESS_U
LD (LAST_DIRECT+1),HL
;K_T55
RET
;------------------------------
USE_BONUS
LD HL,(SCORE)
LD DE,5
ADD HL,DE
LD (SCORE),HL
XOR A
LD (B_ACTIVE),A
LD A,(B_INDEX)
CP 0 ;Каска
JR NZ,UB_1
LD A,255
LD (T_PROTECT_TIMER),A
CALL ON_BONUS_SOUND
RET
UB_1 CP 1 ;Будильник
JR NZ,UB_2
LD A,255
LD (STOP_TIMER),A
CALL ON_BONUS_SOUND
RET
UB_2 CP 2 ;Жизнь
JR NZ,UB_3
LD A,(T_LIVES)
INC A
LD (T_LIVES),A
CALL ON_ADD_LIVE_SOUND
RET
UB_3 CP 3 ;Пистолет
JR NZ,UB_4
LD A,(T_POWER)
CP 250
RET NC
ADD A,3
LD (T_POWER),A
LD A,2
LD (T_COL_SHOT),A
CALL SELECT_T_SPRITE
CALL ON_BONUS_SOUND
RET
UB_4 CP 4 ;Граната
JR NZ,UB_5
LD IX,ENEMY
LD DE,ENEMY_LEN
LD B,3
UB_EN LD (IX+E_HP),0
ADD IX,DE
DJNZ UB_EN
CALL ON_CRASH_SOUND
RET
UB_5 CP 5 ;Звезда
JR NZ,UB_6
LD A,(T_POWER)
CP 255
RET Z
INC A
LD (T_POWER),A
CP 2
JR C,NO_DBL
LD A,2
LD (T_COL_SHOT),A
NO_DBL CALL SELECT_T_SPRITE
CALL ON_BONUS_SOUND
RET
UB_6
RET
;------------------------------
T_ACTION
LD A,(BASE_DAMAGED)
CP 1
RET Z
CALL T_COORD_IS_ICE
XOR A
LD (L_DOP),A
LD A,(U_PRESSED)
CP 1
CALL Z,PRESS_U
LD A,(D_PRESSED)
CP 1
CALL Z,PRESS_D
LD A,(L_PRESSED)
CP 1
CALL Z,PRESS_L
LD A,(R_PRESSED)
CP 1
CALL Z,PRESS_R
LD A,(F_PRESSED)
CP 1
CALL Z,PRESS_F
;------------------------------
LD A,(T_SLIP_TIMER)
CP 0
JR Z,NOSLIP
DEC A
LD (T_SLIP_TIMER),A
LD A,(IS_ICE)
CP 0
JR Z,NOSLIP
LAST_DIRECT
CALL NZ,0
NOSLIP
;------------------------------
LD A,(B_ACTIVE)
CP 0
RET Z
LD HL,(B_COORD)
LD A,15
LD (BOX_HL_H),A
LD (BOX_HL_W),A
CALL PLAYER_COLLISION
CP 1
CALL Z,USE_BONUS
RET
;-----------------------------
E_FAST_DIRECT
;Пытаемся случайно изменить направление
CALL RND_255
AND 3
INC A
LD (IX+E_DIRECT),A
RET
;-----------------------------
E_ACTION
LD A,(STOP_TIMER)
CP 0
JR Z,E_A
DEC A
LD (STOP_TIMER),A
RET
E_A
XOR A
LD (L_DOP),A
LD IX,ENEMY
LD B,E_COUNT
E_A1 PUSH BC
LD A,(IX+E_HP)
CP 0
JR Z,E_ANEXT ;Пропускаем танк, если не активен
;Пытаемся случайно стрелять
CALL RND_255
AND 15
CP 7
CALL Z,E_FIRE
;Пытаемся случайно изменить направление
CALL RND_255
CP 32
JR NZ,E_ASD1
LD (IX+E_DIRECT),1
JR E_ASD4
E_ASD1 CP 96
JR NZ,E_ASD2
LD (IX+E_DIRECT),2
JR E_ASD4
E_ASD2 CP 160
JR NZ,E_ASD3
LD (IX+E_DIRECT),3
JR E_ASD4
E_ASD3 CP 224
JR NZ,E_ASD4
LD (IX+E_DIRECT),4
E_ASD4
LD A,(IX+E_DIRECT)
CP 1
JR NZ,E_AMR
CALL E_MOVE_L
JR E_ANEXT
E_AMR CP 2
JR NZ,E_AMU
CALL E_MOVE_R
JR E_ANEXT
E_AMU CP 3
JR NZ,E_AMD
CALL E_MOVE_U
JR E_ANEXT
E_AMD CP 4
JR NZ,E_ANEXT
CALL E_MOVE_D
E_ANEXT POP BC
LD DE,ENEMY_LEN
ADD IX,DE
DJNZ E_A1
RET
;-----------------------------
E_FIRE
LD A,(IX+E_SH_ACTIVE)
CP 1
RET Z
LD A,(IX+E_DIRECT)
LD L,(IX+E_COORD)
LD H,(IX+E_COORD+1)
LD D,5
LD E,5
ADD HL,DE
LD (IX+E_SH_COORD),L
LD (IX+E_SH_COORD+1),H
LD (IX+E_SH_DIRECT),A
LD A,1
LD (IX+E_SH_ACTIVE),A
RET
;-----------------------------
E_MOVE_R
XOR A
LD (R_OP2),A
LD (R_OP3),A
LD A,(IX+E_TYPE)
CP 1
JR NZ,R_NOINC
LD A,#3C ;INC A
LD (R_OP2),A
LD A,#04 ;INC B
LD (R_OP3),A
R_NOINC
LD A,(IX+E_COORD) ;Сделаем "поперечную" координату кратной 8
BIT 2,A
JR Z,EM_R1
ADD A,8
EM_R1 AND 248
LD (IX+E_COORD),A
LD A,3
LD (IX+E_SPR_W),A
LD A,(IX+E_COORD+1)
INC A
CP 193
JR NZ,EMR0
CALL E_FAST_DIRECT
JR E_CLC_SR
EMR0 LD L,(IX+E_COORD)
LD H,(IX+E_COORD+1)
LD A,16
R_OP2 NOP
ADD A,H
LD H,A
PUSH HL
CALL COORD_IS_FILL
POP HL
CP 1
JR NZ,EMR1
CALL E_FAST_DIRECT
JR E_CLC_SR
EMR1 PUSH HL
LD A,15
ADD A,L
LD L,A
CALL COORD_IS_FILL
POP HL
CP 1
JR NZ,EMR2
CALL E_FAST_DIRECT
JR E_CLC_SR
EMR2 LD A,0
LD (BOX_HL_W),A
LD A,15
LD (BOX_HL_H),A
PUSH IX
CALL ENEMY_COLLISION
POP IX
CP 1
JR NZ,EMR3
CALL E_FAST_DIRECT
JR E_CLC_SR
EMR3 CALL PLAYER_COLLISION
CP 1
JR NZ,EMR4
CALL E_FAST_DIRECT
JR E_CLC_SR
EMR4 LD B,1
R_OP3 NOP
EMR5 INC (IX+E_COORD+1)
DJNZ EMR5
E_CLC_SR
LD L,(IX+E_SPRITE_ADDR)
LD H,(IX+E_SPRITE_ADDR+1)
LD DE,896
LD A,(IX+E_FASE)
XOR 1
LD (IX+E_FASE),A
CP 0
JR Z,NO_ERF2
LD DE,1280
NO_ERF2
ADD HL,DE
LD A,(IX+E_COORD+1)
AND 7
CP 0
JR Z,NO_ADDESR
LD DE,48
LD B,A
ADDESR ADD HL,DE
DJNZ ADDESR
NO_ADDESR
LD (IX+E_SPR_ADR),L
LD (IX+E_SPR_ADR+1),H
RET
;-----------------------------
E_MOVE_L
XOR A ;NOP
LD (L_OP2),A
LD (L_OP3),A
LD A,(IX+E_TYPE)
CP 1
JR NZ,L_NOINC
LD A,#25 ;DEC H
LD (L_OP2),A
LD A,#04 ;INC B
LD (L_OP3),A
L_NOINC
LD A,(IX+E_COORD)
BIT 2,A
JR Z,EM_L1
ADD A,8
EM_L1 AND 248
LD (IX+E_COORD),A
LD A,3
LD (IX+E_SPR_W),A
LD A,(IX+E_COORD+1)
DEC A
CP 255
JR NZ,EML0
CALL E_FAST_DIRECT
JR E_CLC_SL
EML0 LD L,(IX+E_COORD)
LD H,(IX+E_COORD+1)
DEC H
L_OP2 NOP
PUSH HL
CALL COORD_IS_FILL
POP HL
CP 1
JR NZ,EML1
CALL E_FAST_DIRECT
JR E_CLC_SL
EML1 PUSH HL
LD A,15
ADD A,L
LD L,A
CALL COORD_IS_FILL
POP HL
CP 1
JR NZ,EML2
CALL E_FAST_DIRECT
JR E_CLC_SL
EML2 LD A,0
LD (BOX_HL_W),A
LD A,15
LD (BOX_HL_H),A
PUSH IX
CALL ENEMY_COLLISION
POP IX
CP 1
JR NZ,EML3
CALL E_FAST_DIRECT
JR E_CLC_SL
EML3 CALL PLAYER_COLLISION
CP 1
JR NZ,EML4
CALL E_FAST_DIRECT
JR E_CLC_SL
EML4 LD B,1
L_OP3 NOP
EML5 DEC (IX+E_COORD+1)
DJNZ EML5
E_CLC_SL
LD L,(IX+E_SPRITE_ADDR)
LD H,(IX+E_SPRITE_ADDR+1)
LD DE,128
LD A,(IX+E_FASE)
XOR 1
LD (IX+E_FASE),A
CP 0
JR Z,NO_ERL2
LD DE,512
NO_ERL2
ADD HL,DE
LD A,(IX+E_COORD+1)
AND 7
CP 0
JR Z,NO_ADDESL
LD DE,48
LD B,A
ADDESL ADD HL,DE
DJNZ ADDESL
NO_ADDESL
LD (IX+E_SPR_ADR),L
LD (IX+E_SPR_ADR+1),H
RET
;-----------------------------
E_MOVE_U
XOR A ;NOP
LD (U_OP2),A
LD (U_OP3),A
LD A,(IX+E_TYPE)
CP 1
JR NZ,U_NOINC
LD A,#2D ;DEC L
LD (U_OP2),A
LD A,#04 ;INC B
LD (U_OP3),A
U_NOINC
LD A,(IX+E_COORD+1)
BIT 2,A
JR Z,EM_U1
ADD A,8
EM_U1 AND 248
LD (IX+E_COORD+1),A
LD A,2
LD (IX+E_SPR_W),A
LD A,(IX+E_COORD)
DEC A
CP 255
JR NZ,EMU0
CALL E_FAST_DIRECT
JR E_CLC_SU
EMU0 LD L,(IX+E_COORD)
LD H,(IX+E_COORD+1)
DEC L
U_OP2 NOP
PUSH HL
CALL COORD_IS_FILL
POP HL
CP 1
JR NZ,EMU1
CALL E_FAST_DIRECT
JR E_CLC_SU
EMU1 PUSH HL
LD A,15
ADD A,H
LD H,A
CALL COORD_IS_FILL
POP HL
CP 1
JR NZ,EMU2
CALL E_FAST_DIRECT
JR E_CLC_SU
EMU2 LD A,15
LD (BOX_HL_W),A
LD A,0
LD (BOX_HL_H),A
PUSH IX
CALL ENEMY_COLLISION
POP IX
CP 1
JR NZ,EMU3
CALL E_FAST_DIRECT
JR E_CLC_SU
EMU3 CALL PLAYER_COLLISION
CP 1
JR NZ,EMU4
CALL E_FAST_DIRECT
JR E_CLC_SU
EMU4 LD B,1
U_OP3 NOP
EMU5 DEC (IX+E_COORD)
DJNZ EMU5
E_CLC_SU
LD L,(IX+E_SPRITE_ADDR)
LD H,(IX+E_SPRITE_ADDR+1)
LD A,(IX+E_FASE)
XOR 1
LD (IX+E_FASE),A
CP 0
JR Z,NO_ERU2
LD DE,32
ADD HL,DE
NO_ERU2
LD (IX+E_SPR_ADR),L
LD (IX+E_SPR_ADR+1),H
RET
;-----------------------------
E_MOVE_D
XOR A ;NOP
LD (D_OP2),A
LD (D_OP3),A
LD A,(IX+E_TYPE)
CP 1
JR NZ,D_NOINC
LD A,#3C ;INC A
LD (D_OP2),A
LD A,#04 ;INC B
LD (D_OP3),A
D_NOINC
LD A,(IX+E_COORD+1)
BIT 2,A
JR Z,EM_D1
ADD A,8
EM_D1 AND 248
LD (IX+E_COORD+1),A
LD A,2
LD (IX+E_SPR_W),A
LD A,(IX+E_COORD)
INC A
CP 177
JR NZ,EMD0
CALL E_FAST_DIRECT
JR E_CLC_SD
EMD0 LD L,(IX+E_COORD)
LD H,(IX+E_COORD+1)
LD A,16
D_OP2 NOP
ADD A,L
LD L,A
PUSH HL
CALL COORD_IS_FILL
POP HL
CP 1
JR NZ,EMD1
CALL E_FAST_DIRECT
JR E_CLC_SD
EMD1 PUSH HL
LD A,15
ADD A,H
LD H,A
CALL COORD_IS_FILL
POP HL
CP 1
JR NZ,EMD2
CALL E_FAST_DIRECT
JR E_CLC_SD
EMD2 LD A,15
LD (BOX_HL_W),A
LD A,0
LD (BOX_HL_H),A
PUSH IX
CALL ENEMY_COLLISION
POP IX
CP 1
JR NZ,EMD3
CALL E_FAST_DIRECT
JR E_CLC_SD
EMD3 CALL PLAYER_COLLISION
CP 1
JR NZ,EMD4
CALL E_FAST_DIRECT
JR E_CLC_SD
EMD4 LD B,1
D_OP3 NOP
EMD5 INC (IX+E_COORD)
DJNZ EMD5
E_CLC_SD
LD L,(IX+E_SPRITE_ADDR)
LD H,(IX+E_SPRITE_ADDR+1)
LD DE,64
LD A,(IX+E_FASE)
XOR 1
LD (IX+E_FASE),A
CP 0
JR Z,NO_ERD2
LD DE,96
NO_ERD2 ADD HL,DE
LD (IX+E_SPR_ADR),L
LD (IX+E_SPR_ADR+1),H
RET
;------------------------------
COORD_IS_FILL
PUSH HL
CALL CALC_LEVEL_POS
LD A,(L_DOP)
LD D,A
LD A,(HL)
CP 0
JR Z,C_NO_FILL
CP 4
JR Z,C_NO_FILL
CP 5
JR Z,C_NO_FILL
CP D
JR Z,C_NO_FILL
POP HL
LD A,1
RET
C_NO_FILL
POP HL
XOR A
RET
L_DOP DEFB 0
;----------------------------
T_COORD_IS_ICE
XOR A
LD (IS_ICE),A
LD HL,(T_COORD)
LD DE,#0202
LD A,L
AND 7
CP 0
JR Z,TCII_NOADDY
INC E
TCII_NOADDY
LD A,H
AND 7
CP 0
JR Z,TCII_NOADDX
INC D
TCII_NOADDX
PUSH DE
CALL CALC_LEVEL_POS
POP DE
LD A,E
LD (TCII_FOR_Y-1),A
LD A,D
LD (TCII_FOR_X-1),A
LD B,0
TCII_FOR_Y
PUSH BC
PUSH HL
LD B,0
TCII_FOR_X
PUSH BC
LD A,(HL)
CP 5
JR NZ,TCII_NOICE
LD A,1
LD (IS_ICE),A
TCII_NOICE
INC HL
POP BC
DJNZ TCII_FOR_X
POP HL
LD DE,26
ADD HL,DE
POP BC
DJNZ TCII_FOR_Y
RET
;----------------------------
CALC_LEVEL_POS
SRL L
SRL L
SRL L
SRL H
SRL H
SRL H
LD B,L
LD C,H
LD HL,LEVEL
LD A,B
CP 0
JR Z,NO_ADD_Y ;Не нужно прибавлять строки
LD DE,26
ADD_Y
ADD HL,DE ;Прибавляем строки
DJNZ ADD_Y
NO_ADD_Y
LD D,0
LD E,C
ADD HL,DE ;Прибавляем позицию по X
LD (CALCULATED_LPOS),HL
RET
CALCULATED_LPOS
DEFW 0
;---------------------------
RND_255
LD HL,(RND_VAL)
LD DE,7
ADD HL,DE
LD E,L
LD D,H
ADD HL,HL
ADD HL,HL
LD C,L
LD B,H
ADD HL,HL
ADD HL,BC
ADD HL,DE
LD (RND_VAL),HL
LD A,H
RET
RND_VAL DEFW 0
;--------------------------------------
FILL_SPRITE
CALL FILL_SPRITE_ADDR
LD A,(#5B5C)
PUSH AF
;Подключим банку со спрайтами
CALL BIND_BUF_0
;Скопируем спрайты UP1,UP2 в рабочие
PUSH HL
LD DE,(ADDR_UP1)
LD BC,64
LDIR
POP HL
;Скопируем спрайты LEFT1 в рабочие LEFT1 и RIGHT1
PUSH HL
LD DE,64
ADD HL,DE
PUSH HL
LD DE,(ADDR_LEFT1)
LD BC,48
LDIR
POP HL
LD DE,(ADDR_RIGHT1)
LD BC,48
LDIR
POP HL
;Скопируем спрайты LEFT2 в рабочие LEFT2 и RIGHT2
LD DE,112
ADD HL,DE
PUSH HL
LD DE,(ADDR_LEFT2)
LD BC,48
LDIR
POP HL
LD DE,(ADDR_RIGHT2)
LD BC,48
LDIR
;Отобразим сверху вниз танк1
LD HL,(ADDR_UP1)
CALL FLIP_V
;Отобразим сверху вниз танк2
LD HL,(ADDR_UP2)
CALL FLIP_V
;Развернём > танк1
LD IX,(ADDR_RIGHT1)
CALL FLIP_H
;Развернём > танк2
LD IX,(ADDR_RIGHT2)
CALL FLIP_H
;Проскроллим правый танк1
LD HL,(ADDR_RIGHT1)
CALL SCROLL_COPY
;Проскроллим правый танк2
LD HL,(ADDR_RIGHT2)
CALL SCROLL_COPY
;Проскроллим левый танк1
LD HL,(ADDR_LEFT1)
CALL SCROLL_COPY
;Проскроллим левый танк2
LD HL,(ADDR_LEFT2)
CALL SCROLL_COPY
POP AF
CALL SET_VIDEO_A
RET
;-------------------------
FILL_SPRITE_ADDR
PUSH HL
EX DE,HL
LD DE,32
LD (ADDR_UP1),HL
ADD HL,DE
LD (ADDR_UP2),HL
ADD HL,DE
LD (ADDR_DOWN1),HL
ADD HL,DE
LD (ADDR_DOWN2),HL
ADD HL,DE
LD DE,384
LD (ADDR_LEFT1),HL
ADD HL,DE
LD (ADDR_LEFT2),HL
ADD HL,DE
LD (ADDR_RIGHT1),HL
ADD HL,DE
LD (ADDR_RIGHT2),HL
POP HL
RET
ADDR_UP1 DEFW 0
ADDR_UP2 DEFW 0
ADDR_DOWN1 DEFW 0
ADDR_DOWN2 DEFW 0
ADDR_LEFT1 DEFW 0
ADDR_LEFT2 DEFW 0
ADDR_RIGHT1 DEFW 0
ADDR_RIGHT2 DEFW 0
;-----------------------------
FLIP_H LD C,16
FL_H1 LD L,(IX+0)
LD H,(IX+1)
LD B,16
FL_H2 SLA L
RL H
RR D
RR E
DJNZ FL_H2
LD (IX+0),E
LD (IX+1),D
INC IX
INC IX
INC IX
DEC C
JR NZ,FL_H1
RET
;---------------------------
FLIP_V
LD (SAVE_SP+1),SP
PUSH HL
LD DE,94
ADD HL,DE
POP DE
DI
LD SP,HL
LD B,16
FL_V LD (CPY_AD+1),DE
CPY_AD LD HL,(00)
PUSH HL
INC DE
INC DE
DJNZ FL_V
SAVE_SP LD SP,0
EI
RET
NOP
;-----------------------------
SCROLL_COPY
PUSH HL
LD DE,48
ADD HL,DE
POP DE
EX DE,HL
LD B,7
R_COPY PUSH BC
PUSH DE
PUSH HL
;------------
PUSH DE
LD BC,48
LDIR
POP HL
AND A
LD B,48
S_RR RR (HL)
INC HL
DJNZ S_RR
;------------
POP HL
POP DE
EX DE,HL
LD IX,48
ADD IX,DE
PUSH IX
POP DE
EX DE,HL
LD IX,48
ADD IX,DE
PUSH IX
POP DE
POP BC
DJNZ R_COPY
RET
;---------------------------------
; SPRITES
;---------------------------------
T1 EQU #C000+6607
T2 EQU T1+160
T3 EQU T2+160
T4 EQU T3+160
E1 EQU T4+160
E2 EQU E1+160
E3 EQU E2+160
E4 EQU E3+160
B_1 EQU E4+160
;Спрайты уровня
SPR_C0 DEFB 0,0,0,0,0,0,0,0
SPR_C1 DEFB 247,247,247,0,127,127,127,0
SPR_C2 DEFB 170,84,188,124,188,124,130,1
SPR_C3 DEFB 4,0,128,72,20,0,64,34
SPR_C4 DEFB 2,21,7,25,46,31,251,110
SPR_C5 DEFB 17,2,4,136,17,34,68,136
SPR_C6 DEFB 0,0,0,0,0,0,0,0
SPR_BASE DEFB 0,0,192,3,99,134,241,79,113,142,253,191,47,244,119,238,61,188,63,252,29,184,1,128,3,192,15,240,13,176,0,0
SPR_BASE_DEAD DEFB 0,0,0,0,4,0,13,0,11,128,23,192,55,248,47,252,111,252,79,246,95,150,71,4,65,4,64,0,64,0,64,0
;Спрайты бонусов
B_SPRITE DEFS 32
B_MASK DEFB 255,255,128,3,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,128,3,255,255
;Спрайт патрона
SPR_SHOT
DEFB 0,0,48,0,120,0,120,0,48,0,0,0,0,0,0,0
DEFB 0,0,24,0,60,0,60,0,24,0,0,0,0,0,0,0
DEFB 0,0,12,0,30,0,30,0,12,0,0,0,0,0,0,0
DEFB 0,0,6,0,15,0,15,0,6,0,0,0,0,0,0,0
DEFB 0,0,3,0,7,128,7,128,3,0,0,0,0,0,0,0
DEFB 0,0,1,128,3,192,3,192,1,128,0,0,0,0,0,0
DEFB 0,0,0,192,1,224,1,224,0,192,0,0,0,0,0,0
DEFB 0,0,0,96,0,240,0,240,0,96,0,0,0,0,0,0
T_SPRITE_1
TANK_UP1
TANK_UP2 EQU TANK_UP1+32
TANK_DOWN1 EQU TANK_UP2+32
TANK_DOWN2 EQU TANK_DOWN1+32
TANK_LEFT1 EQU TANK_DOWN2+32
TANK_LEFT2 EQU TANK_LEFT1+384
TANK_RIGHT1 EQU TANK_LEFT2+384
TANK_RIGHT2 EQU TANK_RIGHT1+384
E_SPRITE_1 EQU TANK_RIGHT2+384
ENEMY1_UP1 EQU E_SPRITE_1
ENEMY1_UP2 EQU ENEMY1_UP1+32
ENEMY1_DOWN1 EQU ENEMY1_UP2+32
ENEMY1_DOWN2 EQU ENEMY1_DOWN1+32
ENEMY1_LEFT1 EQU ENEMY1_DOWN2+32
ENEMY1_LEFT2 EQU ENEMY1_LEFT1+384
ENEMY1_RIGHT1 EQU ENEMY1_LEFT2+384
ENEMY1_RIGHT2 EQU ENEMY1_RIGHT1+384
E_SPRITE_2 EQU ENEMY1_RIGHT2+384
ENEMY2_UP1 EQU E_SPRITE_2
ENEMY2_UP2 EQU ENEMY2_UP1+32
ENEMY2_DOWN1 EQU ENEMY2_UP2+32
ENEMY2_DOWN2 EQU ENEMY2_DOWN1+32
ENEMY2_LEFT1 EQU ENEMY2_DOWN2+32
ENEMY2_LEFT2 EQU ENEMY2_LEFT1+384
ENEMY2_RIGHT1 EQU ENEMY2_LEFT2+384
ENEMY2_RIGHT2 EQU ENEMY2_RIGHT1+384
E_SPRITE_3 EQU ENEMY2_RIGHT2+384
ENEMY3_UP1 EQU E_SPRITE_3
ENEMY3_UP2 EQU ENEMY3_UP1+32
ENEMY3_DOWN1 EQU ENEMY3_UP2+32
ENEMY3_DOWN2 EQU ENEMY3_DOWN1+32
ENEMY3_LEFT1 EQU ENEMY3_DOWN2+32
ENEMY3_LEFT2 EQU ENEMY3_LEFT1+384
ENEMY3_RIGHT1 EQU ENEMY3_LEFT2+384
ENEMY3_RIGHT2 EQU ENEMY3_RIGHT1+384
LEVEL EQU ENEMY3_RIGHT2+384
[свернуть]
А вообще у Epsilon версия многими местами круче и он охотно контактирует по этому поводу(по крайней мере раньше), можешь ему вопросы задать(я этого не говорил)).
https://zx-pk.ru/threads/29225-igra-...990-(128).html
тему Epsilon'а тоже не сложно найти