PDA

Просмотр полной версии : BattleCity демо-недоделка



Biland
13.05.2019, 22:49
Вот решил выложить. Это первое знакомство с ассемблером, судя по надписи 1997 год. Было желание его изучить. Даже съездил на Митино, нашёл "точку", где мне обещали через две неделю чудо-книгу подвезти. Приехав в назначенный день (был школьником), перелез неудачно через забор с такими же, только взрослыми. Был пойман охраной и получил совет ехать домой или получить по полной программе. Выбрал первый вариант, как второй часто безнаказанно практиковался в то время. Через неделю, всё же пробравшись, сказали, что книгу продали кому-то ещё и больше нет таких.

В общем, в каком-то книжном варианте журнала у товарища, были на страницу расписаны команды и комментарии в двух словах. Команды простые (основные), типа, LD и т.п. Вооружившись списком из 10 команд и Tasm начал создавать игру. Где-то через STS смотрел как клавиши опрашивать и т.п. Но всё равно не хватало фундамента, чтобы чужой код читать. Создав редактор уровней, с загрузкой и выгрузкой, основное меню - решил перейти к самой игре. Во тут всё и затихло. Вывод за один фрейм нескольких танков не получался, луч всё дело портил. Про экраны теневые, управление стеком и т.п. я не знал вообще, как и всего остального. Решил, что сделаю демонстрационный проезд танчиков и до лучших времён, когда подучусь. В общем книгу так и не нашёл, на этом знакомство с ассемблером закончилось.

В принципе, почитав на досуге немало статей про вывод графики, так и не понял как можно за один фрейм выводить 5-6 танков, без мерцания. Что за приёмы используют в других играх? Ведь с теневым экраном точно не успею.

^m00h^
13.05.2019, 23:07
Лайтовый оффтоп - а ты не был в фирме Амигайн на презентации первого выпуска журнала Мир Амиги в 1999м году ? Приезжали двое амижников из Подольска.

Biland
14.05.2019, 06:53
Не, на мероприятиях никаких не был. Я сам из г.Климовска (ныне ставшим г.Подольск). А Амижника знал только Алексея с Перово (как он сейчас, тоже не знаю), он на Царицыно дисками торговал. Больше никого из мира ZX и Amiga не знал, кроме редких встреч на самом Царицыно людей. Встречал пару раз там парня (он показался мне очень головастым) со станции Колхозная (или рядом), он мне covox подарил и процедурку на диске, где подменял код в самой процедуре байтами. Этот уровень программирования меня удивил, но до применения я в этом не достиг.

OMu4
14.05.2019, 08:47
а есть силы и желание доделать?

PATHNK
14.05.2019, 09:29
В принципе, почитав на досуге немало статей про вывод графики, так и не понял как можно за один фрейм выводить 5-6 танков
Так вы хотите доделать?

Biland
14.05.2019, 09:47
В принципе, наверное, можно и доделать. Я по сути своей больше алгоритмик, на всяких там олимпиадах участвовал по программированию, места занимал. Как оптимизатор - нет, решение найду, но оно будет стандартное (по времени выполнения). В начале 2000г. был сайт европейский, образовательный (найти его сейчас не смог, если кто знает ссылкой поделитесь, для многих хорошая проверка будет), где задачи давали. Чтобы отличиться, нужно было найти решение нестандартное (отсылаешь мнемонику на любом языке, а тебе результат по времени присылают). У меня там всегда стандарт был, да и желания не было оптимизировать. Рисовать не умею, но это видно. С музыкой не дружу (нот, октав и т.п. не понимаю), только могу оценить качество звучания и настроить оборудование, т.к. высокие герцы слышу (из-за этого не переношу МP3 ниже 320kbps, пищалки на широкополосных колонках).

Чтобы доделать, мне нужно понять на чём программу дописывать на PC, т.к. редакторов много, запутался. И основное нужно, чтобы объяснили как графику динамическую выводить без мерцания и желательно в один фрейм, хотя бы образно (всё перерисовывать или затирать динамические объекты и заново рисовать). В два фрейма, как помню мне не понравилась динамика. Движение хотел пиксельное сделать (без автоматической доездки), но сейчас думаю, что это через чур, в повороты вписываться будет очень сложно.

Titus
14.05.2019, 11:30
А Амижника знал только Алексея с Перово (как он сейчас, тоже не знаю), он на Царицыно дисками торговал. Больше никого из мира ZX и Amiga не знал, кроме редких встреч на самом Царицыно людей.
Леха Летаев (FFC) - это, пожалуй, единственный корифей, который сохранил торговлю спектрумовскими дисками, когда все остальные продавцы уже загнулись. Если на Митинском рынке торговля спектрумовскими дисками прекратилась примерно весной-летом 1997 года (Softstar и MagicSoft). То на Царицыно Леха умудрился торговать вплоть до начала 2000-х. Правда, основное его занятие тогда было - это купля-продажа PC-шного железа, но для постоянных клиентов подторговывал спектрумовскими дисками.

NEO SPECTRUMAN
14.05.2019, 13:39
И основное нужно, чтобы объяснили как графику динамическую выводить без мерцания

у тебя всегда черный фон
все стены выравнены по знакоместам
спрайты никогда не наезжают друг на друга\не пересекаются
и если движение всегда с шагом один пиксель

то можно (ябы сделал(но я не большой уметелей в спрайтах))
для каждого направляния движения
спрайты с проХОRенным своим же изображением смещенным на пиксель
в итоге при выводе такого безобразие по XOR-у поверх
сразу бы удалялись и предыдущие следы
и при этом бы рисовались и новое положение
без каких либо дополнительных буферов

при этом два спрайта легко могут разместится по краям одного знакоместа

при условии что спрайты не анимированные
или же занимаемое ими место помножится на 5

Biland
14.05.2019, 22:15
при этом два спрайта легко могут разместится по краям одного знакоместа


Здесь логику выдёргивания придётся мудрить, нужно будет посчитать сколько всего памяти уйдёт на спрайты. С XOR интересный приём, не слышал о таком, спасибо.

Далее тогда вопросы.

1. Выводить лучше как, по таблице адресов заранее сгенерированной или на месте рассчитывать?

2. С лучом как бороться, чтобы он не обгонял?

3. Спрайты смещёнными заранее держать или в реальном времени смещать?

4. И какой всё же асм-редактор на PC использовать, чтобы ещё можно было в реальном времени отслеживать (трассировка, вроде бы называется)?

NEO SPECTRUMAN
15.05.2019, 00:10
2. С лучом как бороться, чтобы он не обгонял?
смотря чего хотим и под шито пишем
под 48к
можно повесить выводилку спрайтов на прерывание
спрайты можно посортировать по Y-ку на экране (в конце предыдущего фрейма)
и выводить в порядке их размещения на экране
тоесть гонятся с лучом
конечно при желании можно рисовать и после луча

если под 128 с 2-м экраном
ты жизнь несколько упрощается
спокойно рисуем
и переключаем активные экраны по началу фрейма


3. Спрайты смещёнными заранее держать или в реальном времени смещать?
опять же сколько спрайтов
и под шито пишем


4. И какой всё же асм-редактор на PC использовать, чтобы ещё можно было в реальном времени отслеживать (трассировка, вроде бы называется)?
я по началу пользовался emuzwin
но это безбожно глючащий эмулятор
постоянная потеря исходника при зависании обеспена
да и сам асм не осиливает многие конструкции и нужно плясать с бубном
щас я использую его
только для отладки отдельных процедур

есть асм в zx spin
но его возможностей я не знаю


самый труЪ асм
это sjasmplus
можно гегерировать гигантские процедуры при помощи lua (на которую нет нормальных доков)
с использованием злобного матана

но это только компилятор
дебажить нужно в чем то другом

Bedazzle
15.05.2019, 06:58
В начале 2000г. был сайт европейский, образовательный

https://www.brainbench.com/
Дизайн конечно, сильно поменялся.

romancha
15.05.2019, 09:19
интересный ресурс (https://chuntey.wordpress.com)с примерами.

Biland
16.05.2019, 08:51
Titus, точно FFC, я его в Царицыно и под конец 2000-х видел раз, он там тоже писишное, раритетное реализовывал. Интересно как он сейчас...

Спасибо за ссылки, пригодятся обязательно.

По поводу 48 или 128, разница есть или все и так на эмуляторах сидят?

Спрайтов там 4 вида танков.

Посмотрел описание новых TASM и ALASM, интереснее они стали, но с unreal будет тяжко привыкать. Сразу спрошу, кто всё таки из них функциональный, ALASM?

И, ещё, посмотрел связку Notepad + SjASMPlus + UnrealSpeccy, думаю это оптимально будет.

zebest
16.05.2019, 10:14
кто всё таки из них функциональный, ALASM?
при выборе из TASM vs ALASM надо сразу выбирать SjASM :) Могу и имхо добавить, есичо
Вот только Unreal это все же больше под Пентагон заточен, zx48\128 там постольку поскольку.
а из связки лучше какой нить специализированный редактор, у кого то Crimson, у кого то Эмеральд плюс любой эмуль, или сразу несколько.

NEO SPECTRUMAN
16.05.2019, 11:40
По поводу 48 или 128, разница есть или все и так на эмуляторах сидят?
все сидят на эмуляторах
да и у нас как бы стандарт пентагон 128 + Ау + Тырдырдос
хотя и любители писать только для 48 имеются

вот если начать лезть выше на всякие 256 и 512
уже может начаться шум
и крики что не спектрум
можно было вместить и в 128 итд
буржуины не смогут запустить это на своих некстах и обидятся... (но нам же все равно пусть играю в свои jet set willy 19 на своих +3)

- - - Добавлено - - -


при выборе из TASM vs ALASM надо сразу выбирать SjASM
аминь

- - - Добавлено - - -


сразу выбирать SjASM
конечно к нему тожо надо привыкать
но потом и не хочетсо кодить в чем то другом

я запилил жменю макросов
чтоб компилировать код chip8 в sjasm-е
вправление мозгов самому sjasm-у пока неасилил
но есть большое желание иметь прикрученным к нему
какой нить 6502
можот тоже удасцо написать пачку макросов

чтоб не асиливать еще один какой нибудь кривой асм которых тысячи...

- - - Добавлено - - -


Вот только Unreal это все же больше под Пентагон заточен
а нужно что то другое?
у нас главное работоспособность на пентагоне
несовместимые мультиколоры он врятли писать будет
да и тырдырдос он использует
что тоже только у нас...

вот дебагер в уриале несколько специфичен
и требует читания мануала

Biland
16.05.2019, 19:34
SjASM - это уже SjASMPlus, а какой стандартный или от z00m лучше, толком сложно сразу понять? И как я понимаю, он понимает мнемонику ассемблера ZX80 в чистом виде? Конечно, посмотрел на LUA или как там его, это не затягивает. Сразу вспомнил мультфильм "Простоквашино", где они письмо по очереди писали, типа, javascript и query. Тернарные операторы как я понял тоже понимает? Java? И как я понимаю компилирует в машинный код z80 оптимально?

П.С.: В основном пользовался Delphi. Turbo pascal, C и С++ давно, Visual basic ковырял, недавно на php, JS и query сайт допиливал (но в этой троице конца и края не видно в познании, 2 и 3 по скорости не впечатляли всегда). Из этого что более похоже или более применимо?

zebest
16.05.2019, 19:59
какой стандартный или от z00m лучше, толком сложно сразу понять?
у мну например парк, зоо-парк ужасмов. Т.к. компилятор вызываеЦЦа по абсолютному пути из кримсон эдитора, то я чтобы попробовать другой\новый\старый - просто переименовываю exe-шник, текущий всегда один :)
http://s3.micp.ru/Jezhz.jpg
Для моих нужд подходит практически любой, и от z00m - то жи. LUA пользоваЦца можно по желанию, можно соовсем не использовать. Попробуй перетянуть свои исходники и покомпилить, вдруг что-то и получится

NEO SPECTRUMAN
17.05.2019, 03:58
Т.к. компилятор вызываеЦЦа по абсолютному пути из кримсон эдитора,
тк я живу в каменном веке и пользуюсь блокнотом

у меня есть глупый вопрос

а можно ли в каком то редакторе
дружно переименовать все одноименные метки, ссылки на них, названия переменных итд
так же легко как это делается в IDA?
(и вообще я хочу писать прямо в иде!)

Bedazzle
17.05.2019, 09:11
а можно ли в каком то редакторе
дружно переименовать все одноименные метки, ссылки на них, названия переменных итд
так же легко как это делается в IDA?

Не так же просто, но вполне хорошо справляется к примеру, Notepad++
У него (как и в других редакторах) есть возможность замены по файлам:

https://i.imgur.com/POA8ret.png

NEO SPECTRUMAN
18.05.2019, 08:35
к примеру, Notepad++
ага шото похоже на оно

...как меня радует автозакрытие окна поиска
какая сволочь додумалась?
что аж хочется арать...

и как то явно много телодвижений...
ладно хоть так...
это лучшо чем просто ручками

Biland
19.05.2019, 09:18
Спрошу здесь, чтобы не плодить темы...

Есть такая программа Best View(er) Ивана Рощина. У меня версия 2.8 от 1999 года, также он выпустил 2.9 чуть позже. Но в 2004г. выпущена версия 2.19. И какая получается более новее, что-то нить событий теряется?

И, ещё, вопрос. Как при компиляции в SJAsm за место Stealth Boot по умолчанию, при создании .trd, прикрутить этот BV? Из него можно файлы code запускать, по другому пока что не додумался как это делать.

NEO SPECTRUMAN
19.05.2019, 09:42
Из него можно файлы code запускать, по другому пока что не додумался как это делать.
компиль сразу в sna (при условии что ничего не подгружается в игре)
и не морочь голову
а потом когда закончишь уже приделаешь нормальный загрузчик

Biland
19.05.2019, 11:22
Ну, вроде бы, разобрался. Спасибо.

Но буду рад, если кто ответит про версии Best View и как его прикрутить, на будущее.

NEO SPECTRUMAN
19.05.2019, 13:31
Но буду рад, если кто ответит про версии Best View и как его прикрутить, на будущее.
пересохрани образ диска с БВ в трд любым эмузвином

и добавь в батник который собирает сорец
копирование этого трд в новый файл (возможно удаление предыдущего)
потом компилирование самого сорца (в котором сохранение в этот новый файл)

так при каждом запуске
у тебя старый файл с добавленным .c будет удалятся
а на место него, перед компиляцией, будет подсовываться новый без него

- - - Добавлено - - -

батник

copy BV.TRD GAME.TRD
sjasmplus.exe game.asm

сорец

device zxspectrum128
;итд
SAVETRD "GAME.TRD","game001.c",$C000,$4000

проверил
6-ти game001 на диске не образовалось

- - - Добавлено - - -

вот те еще подсветка синтаксиса z80 для notepad++
69045
мож пригодится
позавчера надыбал ее дето тут на форуме
но там было абсолютно все ужас как вырвиглазно
а я оно перекрасил по образу и подобию emuzwin
и стало чуть лучшо
+в оригинале аффтар не знал\забыл что в lua тоже есть коменты

tiboh
19.05.2019, 17:21
Ну, вроде бы, разобрался. Спасибо.

Но буду рад, если кто ответит про версии Best View и как его прикрутить, на будущее.

2.19 последняя и самая новая версия Best View. После версии 2.9, были версии 2.10, 2.11 и т.д...

Biland
19.05.2019, 20:42
2.19 последняя и самая новая версия Best View. После версии 2.9, были версии 2.10, 2.11 и т.д...

Увидев сообщение, сразу понял, что 2.9 - это 2.09, далее 2.10, 2.11. Не мог от мышления заточенного под корректную "сортировку" переключиться.

И как я понял, здесь принято "кибибайт" "килобайтом" называть. Хотя я их тоже часто путаю...

Dart Alver
20.05.2019, 21:54
И как я понял, здесь принято "кибибайт" "килобайтом" называть. Хотя я их тоже часто путаю...
В рамках спектрума о кибибитной ереси лучше забыть ))) тем более что этот плод продажной любви законодателей мер и весов к недобросовестным производителям родился намного позже устоявшихся спековских канонов, да и в обиходе по большому счету нифига не прижился, как называли кило/мега/гигабайтами (килограмами, метрами, гектарами) оба варианта, так и называют )))

Biland
24.05.2019, 17:04
Разбираюсь с экраном, много чего почерпнул. Но остались общие вопросы, для полной картины.

1. Как я понимаю некоторые игры используют буфер экрана, это где собирается экран, а потом перекидывается в область отображения.

Несмотря на специфический экран ZX, работа с ним с помощью процедур удобна по своей сути. Но возникает вопрос про буфер.

Вот найденный пример, который рисует шириной один байт вниз (28т на два вертикальных байта), в стандартный ZX экран


pop bc ;10
ld (hl),c ;7
inc h ;4
ld (hl),b ;7

Если буфер экрана (или его части), хранить последовательно, то работа с ним упирается в код,
примерно, такой (шириной для двух знакомест)



ld de,31 ;новая строка
pop bc ;данные спрайта
ld (hl),c ;первый байт
inc hl ;в буфере вправо на байт
ld (hl),b ;второй байт
add hl,de ;переход на следующую строку 31+1
---------
pop bc ;10
ld (hl),c ;7
inc hl ;6
ld (hl),b ;7
add hl,de ;11

Что явно увеличивает число тактов (41т на два горизонтальных байта), но позволяет заполнять экран без перерасчёта знакоместа. Сложно сейчас вычислить, что на дистанции быстрее, т.к. первый вариант готовит заранее HL (стек спрайта) под прерывание (что съедает немного тактов). Но,второй вариант явно долгий более 8.000т на всю вертикальную полосу шириной в два байта, плюс подготовка.

Отсюда вопрос, т.к. оптимизировать второй вариант, вряд ли получится (если можно, то подскажите как). Можно ли сделать так буфер, чтобы с ним легко было работать без перерасчёта знакоместа и убрав команду ADD, например, сгруппировав его как-то своеобразно, нелинейно? Даже можно с шагом значения через два байта графики, через два байта команд, "вписавшись" в вывод



D SP,экран
LD HL,NN ;два байта графики, здесь будет подставляться спрайт
PUSH HL
LD HL,NN
PUSH HL


Были ли такие темы и рассуждения?

2. Для расчёта стандартного экрана координат используется небольшая процедура, которая вычисляет
адрес, также есть быстрая процедура смещения вниз на строку.

Вопрос, если использовать таблиц адресов первой колонки, чтобы быстро находить адрес строки, не будет ли быстрее? Конкретных примеров не нашёл (только в комплексе, где осилить сейчас весь код не полчуится), а свой метод перехода, отрабатывает долго. Есть ли по этому поводу комментарии?

3. Ну и третий, вопрос, про буфер. Его используют, если много страниц со спрайтами и два видео экрана. Предполагаю, но это не точно, что в ЧВ сделано так, хотя не факт.

Получается, что в продвинутых ZX, в cpu0 можно устанавливать не только 0 страницу (это тоже редкость), а любую. Значит от буфера можно отказаться, генерировать в экран cpu3 (страницы 5 и 7), подхватывая спрайты из cpu0. Тем самым экономя время на переброску буфера на экран. Это верно? За исключением того, что это могут только новые ZX.

Titus
24.05.2019, 19:11
Не бывает структуры буфера, оптимизации его и т.д. без изначально поставленной задачи.
Под каждый тип графического движка оптимален тот или иной вывод на экран.
Сперва надо определиться с задачей, потом уже придумывать, как ее реализовывать.

Что же касается 'продвинутых ZX', то их не бывает.
Есть классика - 48, 128 (буржуйские) и Пентагон-128 (наш).
А есть новодел типа Пентевы, Next'а и т.д.
Если писать под новодел, то о страничках заморачиваться не надо, надо сразу писать под новые графические режимы, битпланы, спрайты и что там еще у новодела есть.
Но аудитория у новодела пока что значительно меньше, чем у классики.
Я, например, вообще не запускаю софт под новодел, хотя эмулятор под рукой, т.к. для меня это уже не Спектрум, не ностальгия, и зачем он тогда нужен вообще)

Reobne
25.05.2019, 18:53
Можно ли сделать так буфер, чтобы с ним легко было работать
Можно, в него будет легко выводить спрайты, но бросать такой буфер в экранную область будет неудобно.

Как я понимаю, ты хочешь сделать на полный экран, 50фпс, как можно больше спрайтов, в основном не пересекающихся на чёрном фоне и без маски. Уровень без скролла, много статичных тайлов, которые и перерисовать не нужно, следовательно бросаемый двойной буфер смысла нет использовать.

Можно попробовать переключаемый двойной буфер(седьмую страницу). Помнить какие знакоместа были со спрайтами подвижных объектов(СПО) два кадра назад, нарисовать новые СПО, запоминая в новой карте знакомест, и забывая знакоместа в старой карте. Потом пробежаться по старой карте знакомест, и затереть недотёртые. Потом переключить экраны. Вычислить продвижения объектов и всё по новой.

Чтобы не использовать седьмую страницу, нужно всё успевать перерисовать в нужном месте в нужное время. Кадровая развёртка у нас бежит сверху вниз. Вот нужно успеть "между струйками". :) Чтобы не сортировать СПО по координате Y, можно сделать так: Экран на спектруме как-бы состоит из трёх третей: верхней, средней и нижней. Вот, значит, пишем процедуру, которая обновляет содержимое одной трети. То есть перерисовывает все СПО и прочую индикацию в выбранной трети экрана. А в главном игровом цикле, начинаем вызывать её по порядку для верхней трети, средней, и нижней. Потом синхронизируемся с прерыванием 50гц, двигаем координаты обьектов. И по новой. А для режима пентагона, предусмотреть другой главный игровой цикл: синхронизация, перед обновлением нижней трети. Или средней трети. И ли перед перерасчётом. Всего четыре варианта, можно, думаю, подобрать, для каждого клона методом тыка.

Чтобы не подчищать лохмоты за СПО, зная их динамику, можно нарисовать их таким образом, чтобы они сами себя подчищали. Например танчик, который всегда за кадр может ехать на 1 пиксель вперёд максимум, может сам себя подчищать, имея за кормой один рядок пустых пикселей. В два раза более быстрый танк, должен иметь два рядка пустых пикселей, соответственно. При взрыве танка, последний спрайт анимации взрыва должен затереть всё. И так далее с летящими снарядами и прочим.

А что же делать, если изредка(например, каждый шестнадцатый) кадр будет такой сложный, что чуть-чуть не успеет перерисоваться за 1/50 секунды. Зато соседние кадры с гораздо большим запасиком времени успевают. Так что-же у нас будет дёрганье? Можно ведь это избежать. Но, конечно, синхронизация по HALT, мы отставим, а сделаем цикл ожидания, когда нам IM2_процедура добавит потребность в новом кадре.
LD HL,NeedFrame
INC (HL)
При старте игры или снятии с паузы (NeedFrame) надо обнулить.

Начать цикл ожидания надо с того, что один кадр отрисован, и мы его отнимаем.

LD HL,NeedFrame
DEC (HL)
А потом ждём, когда-же NeedFrame станет неотрицательной.

PHALT:
BIT 7,(HL)
JP NZ,PHALT
Если случайно один сложный кадрик нас(то есть наш Z80) притормозит, то просто INC (HL) выполнится чуть раньше DEC (HL). Ну и ничего страшного, результат-то тот же. JP не сделает переход ни разу, то есть мы сразу выйдем из цикла ожидания и кинемся догонять время. Вместо тупого аппаратного HALT, который нас-бы(ну мы, щас за Z80 думаем), заставил бы стоять до скончания кадра, почти целый кадр.

Всё пишу из головы, код не отлажен, не пытайтесь бездумно копипастить и компилировать. :)

krt17
25.05.2019, 19:07
JetPac на пару с Cookie ненавистного местными 83 года ржет над вами со своими 16к.

NEO SPECTRUMAN
25.05.2019, 20:39
Если буфер экрана (или его части), хранить последовательно, то работа с ним упирается в код,
примерно, такой (шириной для двух знакомест)

Если хранить буфер экрана линейно
то оптимальный вариант строения буфера таков

FEDC BA98 7654 3210
***X XXXX YYYY YYYY

преимущества
переход влево dec h 4t
переход вправо inc h 4t
переход вверх dec l 4t
переход вниз inc l 4t

буфер хоть и занимает собой 8К
но в 64 байтной щелке вполне можно хранить спрайты и таблицы
так же таблицы можно хранить и "вертикально"
то есть в L закидываем номер таблицы
а в H число пропускаемое через таблицу

из недостатков
если читать буфер стеком
то выводить нужно столбцами
что сечется с лучом заметней

если рисовать стеком а читать просто линейно
то проблем уже нет

- - - Добавлено - - -


но бросать такой буфер в экранную область будет неудобно.
кто сказал?

Biland
26.05.2019, 14:21
преимущества
переход влево dec h 4t
переход вправо inc h 4t
переход вверх dec l 4t
переход вниз inc l 4t

Да, хороший вариант. Надо только после смещения вправо, возврат по Х организовать и сместиться по Y, для разный ширины спрайта. Пока оптимально по тикам, что-то не соображу как.



но бросать такой буфер в экранную область будет неудобно.

Бросать можно и через


POP HL
LD (#4000),HL
POP HL
LD (#4002),HL

, где адреса заранее рассчитаны. Получается чуть более 80тыс. тактов на весь экран. Теоретически, если нужен весь экран, то эту процедуру можно кинуть в нулевую страницу и подключить по cpu0. Хотя этой возможности подключать в cpu0 (ram0) лет 20 уже, предполагаю, что всё равно это специфично.

Ещё бы в такой буфер быстро кидать


D SP,экран
LD HL,NN ;два байта графики, здесь будет подставляться спрайт
PUSH HL
LD HL,NN
PUSH HL

, то весь экран в 67тыс. тактов укладывается и не используется дополнительный буфер. Можно и без cpu0 обходиться.

NEO SPECTRUMAN
26.05.2019, 17:36
Надо только после смещения вправо, возврат по Х организовать
можно и нужно по возможности двигаться змейкой

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

- - - Добавлено - - -


D SP,экран LD HL,NN ;два байта графики, здесь будет подставляться спрайт PUSH HL LD HL,NN PUSH HL

в условиях демосцены или жесткого извращения и если мы пишем под 128
и если мы не боимся медленной памяти и пишим под пентагон и ложим на фирменные машины
а может мы просто захотели рисовать мультиколор
опять же
мы можем организовать чуть более удобно и такой буфер для 128 строк

ld hl,nn push hl занимает 4 байта на 2 байта экранной области

тоесть делаем так
включаем теневой экран навсегда
в итоге у нас появляется место по $4000-7FFF под маневры

далее раскидываем развернутую процедуру в виде

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

можно 127 строк
и выровнять более удобно
чтоб nnnn приходилось на кратный адрес $хх00

и в принципе если хотим ЕЩЕ БЫСТРЕЕ
то можем убрать ld sp,xxxx
а поставить Jp по образу и подобию строения спековского экрана
ТОГДА мы выиграем 1К тактов
но не сможем рисовать линейно сверху в низ
чтоб не сектись с лучом
тогда 128 строк улетят в экран за 44298 тактов

при этом у нас остается свободное переключаемое окно С000-FFFF
графику можно хранить между каждой строкой
по 186 байт на строку свободно
таблицу вектора прерываний нужно будет ложить в каждой банке (кроме тех что всегда по адресам 4000-BFFF)
так же как и обработчик
(как вариант можно пожертвовать пару строк и положить вектор и обработчик в более надежном месте)

на время рисования в буфере
видео память отключаем из адресного пространства проца вообще

так же в странице с видеопамятью у нас еще свободно 9К памяти

так же чтоб жестко не извращатся переключением страниц кодом находящимся в переключаемой странице (гемор же)
можно переместить некоторые процедуры
переключалки страниц рамы
переменные
в те 186 байтные щелки что есть в 32К процедуре перекидывания буфера в видеопамять

в итоге перемещение по вертикали
у нас остается достаточно быстрое inc h dec h

но по горизонтали
уже нужно извращаться
так у нас чередуются 2 байта данных и 2 байта кода


- - - Добавлено - - -


Бросать можно и через


POP HL
LD (#4000),HL
POP HL
LD (#4002),HL

, где адреса заранее рассчитаны. Получается чуть более 80тыс. тактов на весь экран. Теоретически, если нужен весь экран, то эту процедуру можно кинуть в нулевую страницу и подключить по cpu0. Хотя этой возможности подключать в cpu0 (ram0) лет 20 уже, предполагаю, что всё равно это специфично.

по адресам 4B00-BFFF вполне найдется 29К памяти
чтоб поместить 24К процедуру
и без cpu0 которого ниукогонет...

но опять же это или в условиях 128К
или при большом извращении

Biland
26.05.2019, 18:22
Кстати, да. Про змейку подумал, а увидев наглядно пример, понял, что можно спрайты тоже змейкой хранить.

Для буфера и вывода сразу

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, только что прочитал. Нужно время, чтобы переосмыслить полностью.

NEO SPECTRUMAN
26.05.2019, 18:58
структурированных сайтов,
близко нет
все в перемешку

есть некоторые сайтеке
которые содержат большой набор процедур для матана
просто для z80

не факт что оптимизированные и оптимальные...


может чего то я не знаю
и за пару лет все изменилось?

вангую что воз и ныне там

- - - Добавлено - - -


Кстати, да. Про змейку подумал, а увидев наглядно пример, понял, что можно спрайты тоже змейкой хранить.
про хранение "змейкой" и для общего развития
прочитай эту статью
https://zxpress.ru/article.php?id=8659

тоже иногда можно применять

- - - Добавлено - - -


Нужно время, чтобы переосмыслить полностью.
смысл таков
забываем про десятичные цифры при размышлении
и переходим на шестнадцатеричные и двоичные

осмысляем выравнивание по кратным адресам и как этим пользоватсо
ну и таблицы с любым количеством переменных в любой форме и в любом направлении

представляем память спека как квадрат 256х256 с координатами H и L...
а не как "с 32768 на резинке у нас быстра память"...

итд...

и будет вам счастие

- - - Добавлено - - -

В качестве авторитетного примера приведу вот эту поделку alone coder-а
https://jpegshare.net/images/3c/ea/3cea0cc2796d4181a0471702156e4b32.png
(вертикальные столбцы это младшие 256 байт)

где видно что видео буфер лежит "вертикально" а в образовавшихся щелях понапихано еще :)

в моем представлении
$0000 верхний левый угол
$FFFF нижний правый

а тут все повернуто на 90 градусов :)

да и термины типа нижняя\верхняя память не люблю
пушо как по мне вверху должен быть и так естественней адрес 0
а называют совершенно на оборот...

goodboy
26.05.2019, 19:17
а не проще бегло просмотреть готовые BattleCity (на вирте их штук 10) ?

Biland
26.05.2019, 20:12
а не проще бегло просмотреть готовые BattleCity (на вирте их штук 10) ?

Может и проще, только от чужой мнемоники голова идёт кругом, т.к. нет опыта ни в ассемблере, ни в оптимизации кода на нём. Да и про вопросы о таких способах вывода графики, как я уже выше писал, в этой игре мало имеет значения, т.к. там не нужен будет буфер и т.п. Это всё для полной картины понимания, чтобы нюансы потом не всплывали, камнями. Да и работу с экраном нужно осмыслить с разных сторон.


про хранение "змейкой" и для общего развития
прочитай эту статью
https://zxpress.ru/article.php?id=8659

тоже иногда можно применять

Да, интересный метод. В голове проскакивала мысль об управление битами при смещении, а здесь более подробно метод описан, 26 тактов на байт, без стека. А со стеком



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


и змейкой - 36 тактов на два байта, т.е. 18 тактов на один. Итого 576 тактов на квадратный спрайт-фон из 4-х выровненных знакомест, без подготовки.

NEO SPECTRUMAN
26.05.2019, 21:06
а не проще бегло просмотреть готовые BattleCity (на вирте их штук 10) ?
свой велосипед ортопедически правильней повторяет форму...

Dwa83
11.06.2019, 16:18
Я не так давно загорелся подобной идеей, помог сайт http://zxpress.ru/article.php?id=5437, там много полезных статей, в которых описано то, что я только недавно узнал про спек.
Имхо делай 128 версию, мороки меньше, когда разберёшься со страницами памяти, особенно со сменными видеостраницами, всё пойдёт и тормозов станет меньше.

при выборе из TASM vs ALASM надо сразу выбирать SjASM
Я себе придумал челендж, написать программу в которой можно написать программу)) То-есть потратил неделю на написание своего "компилятора", старая версия которого тут выложена.

Листинг последней версии 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


;--------------------------
PRINT
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,17 6,0,0
SPR_BASE_DEAD DEFB 0,0,0,0,4,0,13,0,11,128,23,192,55,248,47,252,111,2 52,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-tank-1990-(128).html
тему Epsilon'а тоже не сложно найти

Bedazzle
13.06.2019, 00:01
Листинг последней версии Tank 1990(немного оптимизированный по занимаемой памяти)


Как-то оно у меня странно скомпилилось.
Менюшка, выбор клавиш вроде ок, а игра идёт на пустом поле, ни стен, ни танчиков...

https://i.imgur.com/wRTjHic.png

Dwa83
15.06.2019, 18:16
Как-то оно у меня странно скомпилилось.
Менюшка, выбор клавиш вроде ок, а игра идёт на пустом поле, ни стен, ни танчиков...

Извиняюсь забыл, ещё один листинг с уровнями и спрайтами




ORG #C000
;6607 байт+

LEVEL1 DEFW LEVEL2
DEFB 37,16,49,16,49,16,69,16,49,16,49,16,69,16,17,16,17 ,16,17,16,17,16,69,16,17,16,17,16,17,16,17,16,69,1 6,49,16,17,16,17,16,69,16,49,16,17,16,17,16,69,48, 17,16,17,16,17,16,69,48,17,16,17,16,17,16,69,16,49 ,16,49,16,69,16,49,16,49,16,253,205,18,80,18,80,34 ,64,17,18,17,64,18,20,64,49,64,36,17,16,17,16,49,6 4,36,17,18,17,18,49,18,17,18,17,36,17,18,17,18,49, 18,17,18,17,36,17,16,17,16,17,16,17,16,17,16,17,36 ,17,16,17,80,17,16,17,36,17,16,17,80,17,16,17,36,1 7,16,17,80,17,16,17,68,112,36,16,52,112,36,16,0
LEVEL2 DEFW LEVEL3
DEFB 20,17,16,18,48,17,16,17,16,17,16,20,17,16,18,48,17 ,16,17,16,17,16,20,17,16,52,33,16,17,18,17,16,20,1 7,16,52,33,16,17,18,17,16,20,32,17,32,33,16,18,48, 20,32,17,32,33,16,18,48,20,32,17,16,17,18,32,17,20 ,17,18,20,32,17,16,17,18,32,17,20,17,18,36,16,49,3 2,18,17,20,32,36,16,49,32,18,17,20,32,81,36,18,33, 20,17,16,81,36,18,33,20,17,64,18,20,17,16,17,16,17 ,16,17,64,18,20,17,16,17,16,17,16,17,16,18,17,19,1 8,16,17,16,17,16,35,17,19,18,17,19,18,16,17,16,17, 16,35,17,35,17,16,17,16,49,16,17,18,17,35,17,16,17 ,16,49,16,17,18,17,19,20,17,16,17,16,49,64,19,20,1 7,16,17,16,49,64,35,17,112,17,16,17,35,17,112,17,1 6,17,35,17,16,17,80,49,16,19,17,16,17,80,49,16,0
LEVEL3 DEFW LEVEL4
DEFB 21,52,17,128,21,52,17,80,34,16,18,52,149,18,52,149 ,19,52,48,17,16,65,19,52,48,17,16,65,19,52,65,16,1 7,24,9,16,19,52,49,32,17,24,9,16,19,52,32,17,72,9, 16,19,52,32,17,72,9,16,19,20,69,50,37,20,21,19,20, 69,50,37,20,21,19,128,68,19,17,16,17,80,68,18,57,1 6,57,68,18,57,16,9,48,68,17,64,17,48,68,17,64,17,1 6,33,68,17,32,10,56,33,19,36,19,17,32,10,88,19,36, 19,33,16,10,88,52,19,33,16,10,88,52,19,18,49,80,33 ,32,18,49,80,33,32,0
LEVEL4 DEFW LEVEL5
DEFB 20,21,48,17,16,68,16,36,21,32,33,16,68,16,36,21,24 ,25,36,21,33,32,18,20,21,24,25,36,21,49,32,18,16,2 1,33,37,33,36,9,56,21,33,37,33,36,9,64,17,56,49,16 ,9,64,9,80,33,16,9,24,19,24,9,16,10,24,10,24,25,56 ,19,24,9,16,10,24,10,24,25,88,17,80,25,24,35,32,17 ,16,33,32,25,24,35,18,16,33,36,21,49,16,20,17,18,1 6,33,36,21,49,16,20,17,18,8,41,20,89,8,20,17,18,8, 41,20,89,8,20,17,21,49,20,97,20,17,21,32,17,20,65, 32,20,17,21,33,16,65,16,33,21,20,21,49,16,33,16,49 ,21,36,16,33,64,33,16,52,160,36,18,20,128,36,16,18 ,20,128,36,16,0
LEVEL5 DEFW LEVEL6
DEFB 48,21,17,48,33,18,64,17,21,17,48,33,18,32,18,16,17 ,21,32,17,16,21,32,21,20,18,16,17,21,32,17,16,21,3 2,21,84,17,16,33,21,35,21,19,68,17,16,33,21,35,21, 19,36,16,21,17,16,53,19,37,16,36,16,21,32,53,19,37 ,48,17,21,35,21,51,21,33,32,17,21,35,21,51,21,65,1 6,21,19,57,8,37,16,21,33,16,21,19,57,8,37,16,21,48 ,21,19,64,21,8,18,8,21,48,21,19,64,21,8,18,8,21,51 ,21,19,17,18,17,18,17,8,10,16,21,51,21,19,17,18,17 ,18,17,8,10,16,21,168,10,33,48,33,88,10,33,18,48,8 1,64,18,48,17,48,33,48,49,16,18,64,33,32,33,32,18, 80,17,32,17,16,18,128,17,48,18,128,17,16,0
LEVEL6 DEFW LEVEL7
DEFB 21,9,16,10,16,9,64,9,20,9,16,9,20,21,9,16,10,16,9, 64,9,20,9,16,9,20,21,9,16,10,16,9,24,17,24,9,20,9, 16,9,20,21,9,16,10,16,9,24,17,24,9,20,9,16,9,20,21 ,17,32,33,18,33,20,16,17,20,21,17,32,33,18,33,20,1 6,17,20,21,40,9,18,41,8,17,10,24,36,21,40,9,32,25, 24,10,24,36,41,40,20,17,20,40,81,40,20,17,20,40,41 ,19,53,8,9,52,9,8,53,35,53,8,9,52,9,8,53,19,18,33, 16,17,52,17,8,41,34,33,32,52,24,41,66,48,20,48,50, 64,17,16,20,16,17,64,21,17,37,17,48,18,85,17,37,17 ,48,18,69,20,25,40,17,16,17,40,25,36,25,128,25,20, 32,17,112,52,160,52,32,18,128,36,32,18,112,17,36,0
LEVEL7 DEFW LEVEL8
DEFB 32,19,50,64,18,64,19,112,18,32,17,16,19,48,20,16,1 8,17,19,16,33,16,19,48,20,32,17,19,16,17,16,17,48, 20,18,48,19,17,32,17,48,20,18,48,19,17,48,17,16,20 ,19,18,52,19,18,48,17,16,20,19,18,52,19,18,16,34,3 6,19,34,16,18,17,20,32,34,36,19,34,16,18,17,20,32, 52,18,19,17,32,17,18,16,84,18,19,17,32,17,18,16,36 ,10,56,18,16,17,34,40,10,20,10,56,18,16,17,34,40,1 0,20,24,26,48,33,20,32,18,20,24,26,48,33,20,32,18, 20,16,18,48,17,18,20,17,16,34,20,16,18,48,17,18,20 ,17,16,34,20,16,50,17,16,20,32,18,32,20,48,18,17,1 6,20,32,18,32,20,17,35,17,80,18,17,16,18,17,35,17, 96,17,16,18,49,160,49,160,0
LEVEL8 DEFW LEVEL9
DEFB 20,49,16,17,48,33,32,20,49,16,17,16,18,16,33,32,52 ,32,17,16,17,16,17,24,17,8,52,64,17,56,17,8,20,83, 17,67,52,83,17,67,36,33,64,17,48,52,33,64,33,32,52 ,17,20,17,40,9,18,17,18,33,34,17,20,17,40,9,18,17, 18,33,32,33,16,81,20,97,16,81,20,65,36,16,18,20,16 ,84,18,16,36,16,18,20,18,84,18,16,18,19,16,83,16,6 7,18,19,16,83,16,67,36,24,9,128,21,36,24,9,32,33,6 4,21,36,17,16,9,48,9,48,17,21,36,17,16,9,48,9,16,1 8,33,21,20,16,17,16,9,72,17,16,17,21,20,18,17,16,9 ,104,17,53,33,112,17,53,33,80,17,32,21,0
LEVEL9 DEFW LEVEL10
DEFB 16,17,48,20,16,36,26,8,17,32,17,48,20,16,36,26,8,1 7,16,20,19,20,16,20,8,34,8,20,18,20,19,17,20,19,20 ,18,20,8,34,8,20,16,20,19,33,19,8,34,8,20,18,20,48 ,19,20,17,19,8,34,8,20,16,20,48,19,20,17,19,20,18, 20,96,19,33,19,20,16,20,96,19,33,19,16,20,16,20,16 ,20,16,20,16,19,33,19,16,20,18,20,16,20,18,20,16,1 9,17,18,17,24,34,32,34,24,33,18,17,24,34,32,34,24, 49,19,16,20,18,20,16,20,18,20,16,19,20,17,19,16,20 ,16,20,16,20,16,20,16,19,20,17,19,16,20,16,20,16,2 0,16,20,16,19,33,19,16,20,18,20,16,20,18,20,16,19, 33,19,24,34,32,34,24,19,33,19,24,34,32,34,24,19,17 ,20,19,16,20,18,20,16,20,18,20,16,19,17,20,19,16,2 0,16,20,16,20,16,20,16,19,49,144,81,112,113,80,129 ,80,65,0
LEVEL10 DEFW LEVEL11
DEFB 16,17,16,33,64,49,32,17,16,33,64,49,16,9,16,33,16, 9,68,9,48,17,16,33,16,9,68,9,48,33,8,17,8,25,68,9, 8,73,8,17,8,25,68,9,40,49,16,33,20,34,20,17,40,41, 16,33,20,34,20,49,8,9,8,25,16,17,16,67,9,48,9,8,25 ,16,17,16,67,9,48,73,16,18,17,34,33,18,81,16,18,17 ,34,33,18,17,64,18,16,17,16,18,128,18,16,17,16,18, 96,153,56,153,24,17,20,49,34,65,18,33,20,48,34,64, 18,17,18,180,17,18,180,17,32,52,48,68,48,52,48,68, 64,9,104,9,72,18,9,104,9,40,0
LEVEL11 DEFW LEVEL12
DEFB 21,8,41,21,17,16,17,80,21,8,41,21,17,16,17,80,21,4 9,21,81,52,21,49,21,81,52,21,49,37,17,18,17,20,18, 36,21,49,37,17,18,17,20,18,36,21,19,16,33,21,18,33 ,20,18,19,17,21,19,16,33,21,18,33,20,18,19,17,21,1 9,33,18,37,17,16,36,33,21,19,32,18,37,17,16,36,33, 21,19,33,16,18,84,53,19,33,16,18,84,53,32,18,32,20 ,51,20,53,32,18,32,20,51,20,37,18,21,16,68,18,52,1 7,21,18,21,16,68,18,52,17,53,18,68,64,33,37,18,68, 64,33,21,17,36,32,17,16,18,49,16,21,17,36,32,17,32 ,49,16,21,17,36,80,49,16,21,17,36,80,49,16,21,17,3 6,144,21,17,36,144,0
LEVEL12 DEFW LEVEL13
DEFB 20,49,80,17,48,20,65,64,17,48,20,48,17,16,17,64,33 ,20,48,17,96,33,20,83,16,25,8,35,17,18,20,83,16,25 ,8,35,17,16,36,48,19,16,17,16,26,8,17,52,50,19,16, 17,16,26,8,17,20,17,20,49,51,16,19,33,20,17,20,49, 51,16,19,33,84,18,19,36,18,19,116,18,19,36,18,19,5 2,51,16,35,33,16,19,32,20,51,16,35,33,16,19,32,20, 17,64,17,34,16,35,18,20,17,64,17,48,35,18,20,21,33 ,144,20,21,33,144,20,21,33,16,34,32,18,33,16,37,33 ,80,18,33,16,21,18,33,96,17,53,18,33,96,17,53,49,9 6,113,96,65,0
LEVEL13 DEFW LEVEL14
DEFB 8,25,16,9,16,25,24,33,16,25,24,25,16,9,16,25,24,33 ,16,25,32,9,24,9,16,9,16,9,16,9,16,9,16,9,16,9,24, 9,24,9,16,9,16,9,16,9,16,9,16,9,16,9,8,9,8,9,8,9,8 ,9,16,33,16,33,16,9,16,9,8,9,8,9,8,9,8,9,16,33,16, 33,16,9,16,9,8,41,8,9,40,9,40,9,16,9,16,9,8,41,8,9 ,40,9,40,9,16,9,16,9,8,9,24,9,8,9,16,33,16,33,16,3 3,8,9,24,9,8,9,16,33,16,33,16,33,248,176,18,180,34 ,180,18,96,26,184,26,96,18,32,18,32,17,24,50,24,18 ,32,18,32,17,24,50,40,10,16,10,40,33,16,18,72,10,1 6,10,40,33,32,18,64,18,112,18,64,18,128,18,48,18,9 6,50,48,18,96,50,16,0
LEVEL14 DEFW LEVEL15
DEFB 48,21,32,20,32,21,96,21,32,20,32,21,80,18,32,20,16 ,20,32,18,64,18,32,20,16,20,32,18,48,21,32,20,16,1 7,16,20,32,21,32,21,32,20,16,17,16,20,32,21,16,17, 32,20,16,17,16,17,16,20,32,33,32,20,16,17,16,17,16 ,20,32,17,32,20,16,17,48,17,16,20,64,20,16,17,48,1 7,16,20,48,20,16,17,32,18,32,17,16,20,32,20,16,17, 32,18,32,17,16,20,48,20,16,17,48,18,16,20,64,20,16 ,17,48,18,16,20,32,18,32,20,16,17,16,17,16,20,32,3 4,32,20,16,17,16,17,16,20,32,18,16,17,32,20,16,17, 16,20,32,17,32,17,32,20,16,17,16,20,32,17,48,21,32 ,20,16,20,32,21,64,21,32,20,16,20,32,21,32,17,32,1 7,80,17,32,33,32,17,80,17,32,49,144,65,144,33,0
LEVEL15 DEFW LEVEL16
DEFB 16,20,16,49,32,17,8,17,8,17,32,20,96,17,8,17,8,17, 16,52,8,50,24,17,8,17,8,17,16,52,8,10,32,10,24,17, 8,17,8,17,48,20,8,10,32,10,24,17,8,17,8,17,48,20,8 ,50,24,17,8,17,8,17,32,20,80,100,16,20,16,66,132,1 6,10,16,18,16,10,16,17,8,17,8,17,16,36,16,10,16,18 ,16,10,16,17,8,17,8,17,32,36,66,16,17,8,17,8,17,32 ,36,66,16,17,8,17,8,17,32,20,16,10,16,18,16,10,16, 17,8,17,8,17,32,20,16,10,16,18,16,10,16,17,8,17,8, 17,32,20,16,33,34,8,25,8,17,8,17,32,20,88,25,8,17, 8,17,16,10,16,34,104,18,32,10,16,34,104,18,32,10,1 6,10,104,66,8,10,16,10,104,10,16,18,16,10,8,10,16, 34,80,10,16,18,16,10,8,10,16,10,16,10,80,66,8,10,1 6,10,16,10,104,18,32,10,16,34,104,18,32,0
LEVEL16 DEFW LEVEL17
DEFB 16,17,48,17,16,17,48,17,32,17,48,17,16,17,48,17,48 ,17,16,17,52,17,16,17,64,17,16,17,52,17,16,17,32,2 0,32,18,16,20,19,20,16,18,32,36,32,18,16,20,19,20, 16,18,32,20,32,17,16,17,52,17,16,17,64,17,16,17,52 ,17,16,17,48,17,52,17,16,17,52,18,32,17,52,17,16,1 7,52,18,16,18,16,20,19,20,16,18,16,20,19,20,16,34, 16,20,19,20,16,18,16,20,19,20,16,18,16,17,52,17,16 ,17,52,18,32,17,52,17,16,17,52,18,48,17,16,81,16,1 7,64,17,16,81,16,17,32,20,32,18,16,17,19,17,16,18, 32,36,32,18,16,17,19,17,16,18,32,20,32,33,18,97,64 ,33,18,97,48,49,80,49,32,49,80,49,16,33,18,112,81, 18,112,49,0
LEVEL17 DEFW LEVEL18
DEFB 16,33,19,80,52,32,33,19,80,52,248,216,19,32,81,16, 17,48,19,32,81,16,17,16,19,16,19,32,17,16,18,16,17 ,16,51,16,19,32,17,16,18,16,17,16,35,18,16,52,17,5 0,17,16,36,18,16,52,17,50,17,16,36,32,20,32,17,16, 18,16,17,32,20,32,20,32,17,16,18,16,17,32,20,32,20 ,32,17,18,16,18,17,32,17,32,20,32,17,18,16,18,17,3 2,17,16,18,16,20,16,17,48,17,32,17,16,18,16,20,16, 17,48,17,32,17,18,48,20,81,48,18,48,20,81,208,10,8 ,18,8,10,160,10,8,18,8,10,33,18,16,18,80,10,8,18,8 ,10,33,18,16,18,80,10,8,18,8,10,16,17,128,50,16,17 ,128,50,0
LEVEL18 DEFW LEVEL19
DEFB 16,17,112,18,64,17,112,18,48,65,32,18,32,17,16,34, 65,32,18,32,17,16,34,16,17,48,17,16,18,9,16,41,18, 16,17,48,17,16,18,9,16,41,18,17,16,17,16,18,48,9,7 2,17,16,17,16,18,48,9,72,33,18,17,32,17,8,9,24,10, 16,9,8,9,8,33,18,17,32,17,8,9,24,10,16,9,8,9,40,18 ,48,17,32,10,16,41,32,18,48,17,32,10,16,41,32,17,4 8,17,24,10,8,10,32,9,40,17,48,17,24,10,8,10,32,9,8 ,34,33,24,9,16,9,32,10,8,41,34,33,24,9,16,9,32,10, 8,41,32,18,32,9,32,10,24,10,32,9,40,18,32,9,32,10, 24,10,32,9,40,17,24,9,48,9,104,17,24,9,48,9,72,18, 160,36,18,160,52,18,16,17,88,10,16,52,18,16,17,88, 10,16,36,0
LEVEL19 DEFW LEVEL20
DEFB 48,18,36,56,10,20,80,18,36,56,10,20,32,252,172,26, 8,10,8,9,16,25,8,10,8,9,16,25,8,18,17,26,8,10,8,9, 16,25,8,10,8,9,16,25,8,18,17,10,24,10,8,9,32,10,8, 10,8,9,16,9,8,9,8,9,16,9,10,24,10,8,9,32,10,8,10,8 ,9,16,9,8,9,8,9,16,9,26,8,10,8,9,24,9,16,10,8,9,16 ,9,8,9,8,33,16,10,8,10,8,9,24,9,16,10,8,9,16,9,8,9 ,8,33,16,10,8,33,8,9,24,26,9,8,9,8,9,8,9,16,9,16,1 0,8,33,8,9,24,26,9,8,9,8,9,8,9,16,9,26,24,10,16,25 ,24,10,16,25,8,33,26,24,10,16,25,24,10,16,25,8,33, 252,172,25,8,33,16,68,16,10,40,25,8,17,32,68,16,10 ,48,9,16,17,112,10,24,18,8,9,16,33,96,10,48,9,16,3 3,96,10,24,18,8,9,16,17,112,10,48,9,16,17,112,34,2 4,9,16,33,96,34,16,0
LEVEL20 DEFW LEVEL21
DEFB 32,33,176,33,16,18,64,34,16,17,164,49,164,145,16,1 9,177,16,19,65,32,33,16,20,32,19,33,64,33,16,20,32 ,19,33,48,49,36,32,19,36,9,16,9,16,49,36,32,19,36, 9,16,9,32,33,16,17,18,17,18,36,9,16,9,32,33,16,17, 18,17,18,36,9,16,9,16,49,99,25,16,9,16,49,99,25,16 ,41,18,17,64,33,34,49,18,17,64,33,34,17,32,33,18,6 4,9,88,33,18,64,9,56,18,16,33,18,64,9,16,9,8,9,16, 18,16,33,18,64,9,16,9,8,9,32,49,80,9,16,9,8,9,32,4 9,80,9,16,9,8,9,48,18,17,80,65,32,18,17,80,65,0
LEVEL21 DEFW LEVEL22
DEFB 80,17,16,17,18,16,34,96,17,16,17,18,16,34,16,17,32 ,17,21,16,18,32,17,32,33,32,17,21,16,18,32,17,32,3 3,16,19,16,19,48,19,16,19,16,33,16,19,16,19,48,19, 16,19,16,17,16,17,19,16,19,17,16,17,19,16,19,17,32 ,17,19,16,19,17,16,17,19,16,19,17,48,19,16,35,16,3 5,16,19,64,19,16,35,16,35,16,19,80,81,18,17,112,65 ,18,64,17,48,18,48,17,48,33,48,18,16,18,33,48,33,4 8,33,16,33,48,33,48,33,16,33,48,17,18,48,18,33,16, 17,48,17,18,48,18,48,17,48,33,16,18,16,81,48,33,16 ,18,97,18,32,33,34,33,48,49,16,33,34,33,48,49,16,1 7,18,176,34,176,18,0
LEVEL22 DEFW LEVEL23
DEFB 16,33,32,17,16,17,16,34,48,33,32,17,16,17,16,34,72 ,18,80,17,96,18,80,17,104,20,64,17,32,36,48,20,64, 17,32,36,19,40,18,48,17,24,20,17,20,19,40,18,48,17 ,24,20,17,20,64,20,32,20,32,36,17,64,20,32,20,32,3 6,33,20,40,18,16,17,40,20,18,33,20,40,18,16,17,40, 20,18,17,18,17,48,34,32,20,17,20,17,18,17,48,34,32 ,20,17,20,33,16,17,32,33,32,17,20,33,32,17,32,33,3 2,17,20,16,17,16,17,16,17,16,18,17,32,36,16,17,48, 17,16,18,17,32,36,16,17,32,17,32,33,32,17,20,112,3 3,48,20,32,33,144,35,33,144,35,18,17,128,49,18,17, 128,49,0
LEVEL23 DEFW LEVEL24
DEFB 32,49,21,17,34,17,18,64,49,21,17,34,17,18,32,37,49 ,21,17,18,17,53,17,37,49,21,17,18,17,53,33,133,17, 21,18,33,133,17,21,18,33,18,21,17,18,17,34,21,17,2 1,18,33,18,21,17,18,17,34,21,17,21,18,33,18,21,65, 18,21,18,37,33,18,21,65,18,21,18,37,17,16,37,33,21 ,34,21,18,37,17,16,37,33,21,34,21,18,37,17,16,21,1 8,33,69,17,37,18,16,21,18,33,69,17,37,34,21,16,33, 18,65,53,18,21,16,33,18,65,53,18,37,32,33,50,37,20 ,18,37,32,33,50,37,20,34,21,32,18,17,18,48,36,34,2 1,32,18,17,18,48,52,16,21,16,18,56,10,32,52,16,21, 16,18,56,10,32,68,21,128,68,21,128,36,0
LEVEL24 DEFW LEVEL25
DEFB 32,17,20,64,17,20,32,21,32,17,20,64,17,20,32,69,14 4,69,144,69,16,18,19,17,16,18,117,16,18,19,17,16,1 8,69,32,21,49,19,17,32,18,21,17,32,21,49,19,17,32, 18,21,17,20,16,37,18,49,16,33,21,36,16,37,18,49,16 ,33,21,20,18,20,37,33,18,64,37,18,20,37,33,18,64,3 7,33,20,33,67,68,33,20,33,67,68,32,19,48,36,51,18, 20,32,19,48,36,51,18,20,16,18,19,112,19,17,20,16,1 8,19,112,19,17,20,33,19,112,19,17,20,33,19,112,19, 17,20,33,19,112,19,65,19,112,19,65,18,112,81,18,11 2,49,0
LEVEL25 DEFW LEVEL26
DEFB 32,36,16,17,16,17,16,36,48,17,36,16,17,16,17,16,36 ,17,32,17,20,32,17,16,17,32,20,17,48,20,17,16,17,1 6,17,16,17,20,64,20,17,32,18,32,17,20,48,17,20,48, 18,48,20,32,18,33,48,17,48,17,50,33,16,17,16,17,16 ,17,16,17,34,19,48,18,48,17,64,19,192,19,17,18,17, 80,49,35,17,18,17,16,49,16,49,35,17,16,17,16,49,16 ,20,16,17,35,17,16,17,16,17,48,20,16,17,35,17,20,1 7,32,17,32,20,16,17,35,17,20,17,32,17,32,20,16,17, 35,32,17,48,17,16,17,16,17,35,32,17,16,49,16,17,16 ,17,19,65,16,49,16,49,19,65,80,49,35,192,19,192,19 ,52,80,18,36,16,19,52,80,18,36,16,0
LEVEL26 DEFW LEVEL27
DEFB 32,21,49,16,65,16,20,32,21,49,16,65,18,20,35,37,32 ,17,48,17,16,20,35,37,32,17,48,17,16,36,32,21,19,2 0,17,20,32,17,16,36,16,17,21,19,20,17,20,34,17,18, 36,33,21,19,16,17,48,17,16,36,33,21,19,16,17,48,17 ,16,36,33,21,19,20,17,20,18,16,18,16,36,33,21,19,2 0,17,20,66,20,18,16,17,21,19,16,17,16,19,16,17,16, 20,18,16,17,21,19,16,17,16,19,16,17,16,36,33,21,36 ,17,20,17,16,17,16,36,33,21,36,17,20,17,18,17,18,3 6,33,21,32,17,21,67,36,33,21,32,17,21,67,20,18,49, 18,33,53,49,18,49,18,33,53,49,20,16,17,48,17,48,17 ,34,20,16,17,48,17,48,17,34,33,18,112,17,32,33,18, 112,17,32,49,112,17,32,49,112,17,32,0
LEVEL27 DEFW LEVEL28
DEFB 20,17,16,18,80,17,36,16,20,17,16,18,80,17,36,16,21 ,17,16,17,16,17,18,16,17,18,20,34,21,17,16,17,16,1 7,18,16,17,18,20,34,21,17,48,35,117,17,48,35,117,1 7,18,16,33,16,33,16,18,17,37,17,18,16,33,16,33,16, 18,17,53,17,16,18,19,32,18,16,19,17,53,17,16,18,19 ,32,18,16,19,17,21,18,21,18,16,33,16,18,17,16,33,2 1,18,21,18,16,33,16,18,17,16,33,21,17,21,17,32,17, 67,17,20,21,17,21,17,32,17,67,17,20,21,20,17,20,17 ,16,65,16,17,37,20,17,20,17,16,65,16,17,37,20,17,2 0,80,17,16,20,18,17,20,17,20,80,17,16,20,18,17,52, 17,16,33,32,18,36,17,52,17,16,33,32,18,36,33,20,33 ,80,17,18,20,33,20,33,80,17,18,20,33,36,17,96,17,2 0,33,36,17,96,17,20,17,0
LEVEL28 DEFW LEVEL29
DEFB 64,33,16,17,48,17,32,17,32,33,16,17,48,17,16,33,84 ,33,20,81,84,17,16,20,57,8,17,20,16,17,16,20,33,20 ,8,9,20,25,8,17,20,16,17,16,20,17,16,20,8,9,20,49, 20,16,17,16,20,33,20,8,9,36,33,20,16,17,16,20,17,1 6,20,8,9,36,9,8,17,84,33,20,16,36,9,8,17,84,33,20, 16,36,33,20,16,18,20,18,33,20,17,36,33,20,16,18,20 ,18,17,16,20,17,36,32,20,32,20,16,20,18,20,16,20,4 8,20,32,20,16,20,18,20,16,20,16,18,17,20,16,33,20, 33,16,49,18,17,20,16,17,16,20,17,32,9,24,25,24,17, 16,81,16,9,24,25,24,17,16,81,16,17,16,65,112,17,16 ,65,112,17,16,17,32,17,112,17,16,17,32,17,112,17,1 6,49,18,112,81,18,112,49,0
LEVEL29 DEFW LEVEL30
DEFB 21,32,17,20,32,20,32,21,32,21,32,17,20,32,20,32,21 ,18,16,21,32,17,20,80,21,32,21,32,17,20,16,18,48,2 1,32,37,32,20,32,52,21,20,17,37,32,20,32,52,21,20, 17,16,21,18,36,32,20,17,16,21,20,17,18,21,18,36,32 ,20,17,16,21,20,33,69,33,21,20,16,21,20,33,69,33,2 1,20,16,21,20,49,37,18,33,21,18,20,21,18,49,37,18, 33,21,18,20,21,18,49,37,33,21,36,37,18,49,37,33,21 ,36,37,18,33,32,18,17,48,33,53,17,32,18,17,32,17,3 2,53,65,16,17,18,33,16,17,20,21,65,16,17,18,49,16, 20,21,49,80,49,16,20,49,80,49,16,36,160,20,17,20,1 60,20,33,20,16,17,96,20,17,19,17,20,16,17,96,20,17 ,19,0
LEVEL30 DEFW LEVEL31
DEFB 16,49,34,16,17,48,18,32,49,34,16,17,32,34,64,18,16 ,17,16,18,17,19,36,64,18,16,17,16,18,17,19,36,32,1 8,33,16,17,16,17,32,36,8,10,16,18,33,16,17,16,17,3 2,36,8,10,48,17,48,33,32,20,8,10,48,17,48,33,32,20 ,8,10,16,36,17,18,49,26,16,10,33,16,36,17,18,49,26 ,16,10,33,18,33,18,16,34,16,18,33,16,17,18,33,18,1 6,34,16,18,33,16,17,16,20,34,16,18,20,16,20,16,17, 16,17,16,20,34,16,18,20,16,20,16,17,16,17,16,19,34 ,32,20,24,10,16,10,24,17,16,19,18,48,20,24,10,16,1 0,24,17,16,19,18,48,26,24,17,24,25,16,19,18,48,26, 24,17,24,25,35,18,64,49,34,16,35,80,49,18,48,17,11 2,34,48,17,112,34,240,66,128,18,0
LEVEL31 DEFW LEVEL32
DEFB 48,18,52,32,33,80,18,52,32,33,80,17,16,52,18,33,80 ,17,16,52,18,33,32,35,33,18,33,16,17,35,32,35,33,1 8,33,18,17,35,16,18,33,48,17,16,49,37,18,33,48,17, 18,49,37,16,17,21,48,20,16,20,16,17,37,20,17,21,48 ,20,16,20,16,17,37,36,21,16,18,16,17,16,18,16,17,3 7,36,21,16,18,16,17,16,18,16,17,37,36,21,32,33,48, 17,37,36,21,32,33,48,17,37,20,16,21,16,18,16,65,37 ,33,16,21,16,18,16,65,37,33,16,21,48,65,34,17,32,2 1,48,65,34,17,32,18,48,17,32,17,48,17,34,48,17,96, 17,18,16,49,64,33,64,49,64,33,176,33,80,18,80,33,3 2,0
LEVEL32 DEFW LEVEL33
DEFB 52,160,52,160,36,48,18,81,18,16,36,48,18,16,17,16, 17,16,18,96,18,81,18,96,18,80,18,32,17,64,18,52,16 ,9,16,9,16,81,18,52,25,16,9,16,81,18,52,25,16,9,16 ,17,64,18,52,16,9,16,9,80,18,80,18,96,18,81,18,96, 18,16,17,16,17,16,18,96,18,81,18,64,17,112,36,48,1 7,112,36,35,33,18,52,16,35,36,35,33,18,52,16,35,36 ,34,33,18,36,32,37,8,10,20,34,33,18,36,32,37,8,10, 20,37,18,96,53,17,37,18,96,53,17,53,96,21,18,21,18 ,53,96,21,18,21,18,0
LEVEL33 DEFW LEVEL34
DEFB 48,17,80,33,80,17,80,33,32,35,64,17,36,33,37,35,64 ,17,36,33,37,35,16,37,16,9,8,36,32,37,35,16,37,16, 9,8,36,32,37,32,9,8,37,32,17,16,17,80,9,8,37,32,17 ,16,17,32,18,32,33,32,37,48,17,48,33,32,37,48,17,1 6,37,33,32,37,18,17,16,35,37,33,32,37,18,17,18,35, 37,32,18,33,37,17,16,35,37,32,18,33,37,17,16,35,40 ,18,40,34,16,20,18,72,18,40,34,16,20,18,96,18,20,3 4,16,36,96,18,20,34,16,36,32,17,16,17,16,36,48,18, 48,17,16,17,16,36,64,17,32,18,16,33,96,33,16,18,16 ,33,96,33,18,33,8,10,112,18,36,33,8,10,112,18,36,0
LEVEL34 DEFW LEVEL35
DEFB 32,36,34,64,36,48,36,34,64,36,32,33,16,35,33,32,36 ,32,33,16,35,33,32,36,32,33,37,16,33,34,32,17,16,3 3,37,16,33,34,32,17,48,37,48,34,32,17,48,37,48,34, 32,17,19,20,32,36,16,33,16,35,16,19,20,32,36,16,33 ,16,35,16,18,17,32,36,16,33,16,34,16,18,17,32,36,1 6,33,16,34,64,35,16,34,48,33,48,35,16,34,48,33,48, 35,16,34,48,33,48,35,16,34,48,33,32,33,64,17,19,80 ,33,64,17,19,80,18,17,64,17,19,80,18,17,64,17,19,4 8,34,32,18,80,33,16,34,32,18,80,33,16,34,128,33,16 ,34,128,33,16,0
LEVEL35 DEFW LEVEL36
DEFB 16,18,33,16,52,16,33,18,32,18,33,16,52,16,33,18,32 ,37,20,80,36,21,32,37,20,80,36,21,16,10,8,53,16,21 ,17,21,16,36,37,10,8,53,16,21,17,21,16,36,37,16,21 ,20,17,21,48,21,17,20,21,32,21,20,17,21,48,21,17,2 0,21,32,21,20,33,16,17,19,21,17,18,21,18,16,21,20, 33,32,19,21,17,18,21,34,21,20,17,21,17,32,21,17,20 ,21,16,18,21,20,17,21,33,16,21,17,20,21,32,21,20,1 6,21,48,37,16,21,32,21,20,16,21,48,37,16,21,16,9,8 ,21,20,16,37,18,53,16,37,9,8,21,20,16,37,18,53,16, 69,20,16,101,16,69,20,16,101,16,37,16,34,17,34,16, 18,33,34,32,34,17,34,16,18,33,34,248,184,10,40,17, 80,18,40,18,40,17,80,18,40,10,0
LEVEL36 DEFW 0;Это последний уровень
DEFB 16,19,16,51,16,19,16,19,16,19,32,19,16,51,16,19,16 ,19,16,19,16,20,32,17,80,19,48,20,32,17,80,19,48,2 0,51,20,19,17,19,20,51,16,20,51,20,19,17,19,20,51, 16,17,19,17,36,17,32,20,17,20,32,17,19,17,36,17,32 ,20,17,20,32,20,32,51,16,51,20,35,20,32,51,16,51,2 0,35,20,19,16,19,32,17,16,20,17,20,32,20,19,16,19, 32,17,16,20,17,20,32,34,16,18,16,17,34,20,8,9,34,6 4,18,16,17,16,18,20,8,9,34,64,18,16,17,32,18,33,36 ,48,18,16,33,16,18,33,36,24,10,17,34,17,18,16,49,1 8,17,24,10,17,16,18,17,32,49,16,17,32,33,64,17,96, 33,64,17,192,49,32,18,112,49,32,34,176,66,128,18,0

;Спрайты танка
T1
T1_UP1 DEFB 0,0,0,0,1,0,1,0,113,28,17,16,113,28,23,208,127,252 ,31,112,127,124,30,112,119,220,16,16,112,28,0,0
T1_UP2 DEFB 0,0,0,0,1,0,1,0,17,16,113,28,17,16,119,220,31,240, 127,124,31,112,126,124,23,208,112,28,16,16,0,0
T1_LEFT1 DEFB 0,0,0,10,170,0,10,170,0,15,254,0,1,248,0,3,252,0,3 ,252,0,63,236,0,3,140,0,3,252,0,1,248,0,15,254,0,1 0,170,0,10,170,0,0,0,0,0,0,0
T1_LEFT2 DEFB 0,0,0,5,84,0,5,84,0,15,254,0,1,248,0,3,252,0,3,252 ,0,63,236,0,3,140,0,3,252,0,1,248,0,15,254,0,5,84, 0,5,84,0,0,0,0,0,0,0

T2
T2_UP1 DEFB 1,0,1,0,1,0,1,0,115,156,20,80,127,252,23,208,119,2 20,23,80,119,92,23,80,126,124,23,208,112,28,0,0
T2_UP2 DEFB 1,0,1,0,1,0,1,0,19,144,116,92,31,240,119,220,23,20 8,119,92,23,80,119,92,30,112,119,220,16,16,0,0
T2_LEFT1 DEFB 0,0,0,10,170,0,10,170,0,15,254,0,2,8,0,7,252,0,11, 132,0,251,244,0,11,252,0,7,252,0,2,8,0,15,254,0,10 ,170,0,10,170,0,0,0,0,0,0,0
T2_LEFT2 DEFB 0,0,0,5,84,0,5,84,0,15,254,0,2,8,0,7,252,0,11,132, 0,251,244,0,11,252,0,7,252,0,2,8,0,15,254,0,5,84,0 ,5,84,0,0,0,0,0,0,0

T3
T3_UP1 DEFB 3,128,3,128,1,0,1,0,117,92,7,192,111,236,15,96,111 ,108,15,96,111,108,6,64,119,220,0,0,112,28,0,0
T3_UP2 DEFB 3,128,3,128,1,0,1,0,5,64,103,204,15,224,111,108,15 ,96,111,108,15,96,102,76,7,192,112,28,0,0,0,0
T3_LEFT1 DEFB 0,0,0,0,0,0,10,170,0,10,170,0,8,10,0,3,224,0,15,24 8,0,198,8,0,255,232,0,199,248,0,15,248,0,3,224,0,8 ,10,0,10,170,0,10,170,0,0,0,0
T3_LEFT2 DEFB 0,0,0,0,0,0,5,84,0,5,84,0,0,4,0,3,224,0,15,248,0,1 98,8,0,255,232,0,199,248,0,15,248,0,3,224,0,0,4,0, 5,84,0,5,84,0,0,0,0

T4
T4_UP1 DEFB 1,128,113,142,61,184,109,182,61,180,127,230,63,228 ,127,230,63,164,127,166,46,36,111,230,63,212,112,1 4,0,0,0,0
T4_UP2 DEFB 1,128,49,140,125,190,45,180,125,182,63,228,127,230 ,63,228,127,166,63,164,110,38,47,228,127,214,48,12 ,0,0,0,0
T4_LEFT1 DEFB 0,0,0,85,84,0,127,252,0,111,204,0,63,248,0,63,248, 0,7,248,0,255,216,0,255,216,0,7,24,0,63,240,0,56,8 ,0,96,4,0,95,252,0,85,84,0,0,0,0
T4_LEFT2 DEFB 0,0,0,42,168,0,127,252,0,111,204,0,63,248,0,63,248 ,0,7,248,0,255,216,0,255,216,0,7,24,0,63,240,0,56, 8,0,96,4,0,127,252,0,42,168,0,0,0,0

;Спрайты врагов
E1
E1_UP1 DEFB 1,0,1,0,1,0,115,156,23,208,119,220,31,240,127,124, 31,112,127,124,30,240,119,220,23,208,115,156,1,0,0 ,0
E1_UP2 DEFB 1,0,1,0,1,0,19,144,119,220,23,208,127,252,31,112,1 27,124,31,112,126,252,23,208,119,220,19,144,1,0,0, 0
E1_LEFT1 DEFB 0,0,0,0,0,0,21,84,0,21,84,0,31,252,0,3,224,0,15,24 8,0,30,60,0,255,222,0,31,252,0,15,248,0,3,224,0,31 ,252,0,21,84,0,21,84,0,0,0,0
E1_LEFT2 DEFB 0,0,0,0,0,0,10,168,0,10,168,0,31,252,0,3,224,0,15, 248,0,30,60,0,255,222,0,31,252,0,15,248,0,3,224,0, 31,252,0,10,168,0,10,168,0,0,0,0

E2
E2_UP1 DEFB 1,0,1,0,45,100,109,108,109,108,15,224,15,224,47,22 8,108,108,109,236,13,224,15,224,47,228,96,12,97,12 ,0,0
E2_UP2 DEFB 1,0,1,0,109,108,45,100,109,108,15,224,15,224,111,2 36,44,100,109,236,13,224,15,224,111,236,32,4,97,12 ,0,0
E2_LEFT1 DEFB 0,0,0,0,0,0,57,206,0,24,198,0,0,0,0,63,248,0,63,24 8,0,7,120,0,255,122,0,7,24,0,63,248,0,63,248,0,0,0 ,0,57,206,0,24,198,0,0,0,0
E2_LEFT2 DEFB 0,0,0,0,0,0,57,206,0,41,74,0,0,0,0,63,248,0,63,248 ,0,7,120,0,255,122,0,7,24,0,63,248,0,63,248,0,0,0, 0,57,206,0,41,74,0,0,0,0

E3
E3_UP1 DEFB 3,128,1,0,1,0,115,156,23,208,127,252,30,240,125,25 2,29,112,127,124,30,112,126,252,23,208,119,220,19, 144,0,0
E3_UP2 DEFB 3,128,1,0,1,0,19,144,119,220,31,240,126,252,29,240 ,125,124,31,112,126,124,30,240,119,220,23,208,115, 156,0,0
E3_LEFT1 DEFB 0,0,0,0,0,0,21,84,0,21,84,0,31,254,0,7,240,0,15,25 2,0,159,30,0,253,206,0,158,126,0,15,252,0,7,240,0, 31,254,0,21,84,0,21,84,0,0,0,0
E3_LEFT2 DEFB 0,0,0,0,0,0,10,170,0,10,170,0,31,254,0,7,240,0,15, 252,0,159,30,0,253,206,0,158,126,0,15,252,0,7,240, 0,31,254,0,10,170,0,10,170,0,0,0,0

E4
E4_UP1 DEFB 99,156,27,160,109,108,31,96,111,108,31,64,111,204, 30,192,108,204,29,192,111,204,31,192,104,44,16,16, 99,140,0,0
E4_UP2 DEFB 19,144,107,172,29,96,111,108,31,96,111,76,31,192,1 10,204,28,192,109,204,31,192,111,204,24,32,96,28,3 ,128,0,0
E4_LEFT1 DEFB 0,0,0,170,170,0,170,170,0,85,84,0,127,248,0,63,240 ,0,223,50,0,254,114,0,195,242,0,63,240,0,120,8,0,1 28,4,0,170,170,0,170,170,0,0,0,0,0,0,0
E4_LEFT2 DEFB 0,0,0,85,84,0,85,84,0,170,168,0,127,248,0,63,240,0 ,223,50,0,254,114,0,195,242,0,63,240,0,120,8,0,128 ,4,0,85,84,0,85,84,0,0,0,0,0,0,0

;Спрайты бонусов
B_1 DEFB 0,0,127,252,128,2,128,2,128,2,135,194,143,226,143, 226,143,226,159,226,128,242,128,2,128,2,128,2,127, 252,0,0
B_2 DEFB 0,0,127,252,128,2,131,194,130,50,135,130,143,194,1 57,226,157,226,158,226,143,194,135,130,128,2,128,2 ,127,252,0,0
B_3 DEFB 0,0,127,252,128,2,128,2,129,194,159,194,129,194,13 5,34,143,194,159,242,156,10,138,170,135,242,128,2, 127,252,0,0
B_4 DEFB 0,0,127,252,128,2,128,2,144,2,191,226,191,242,152, 18,134,250,130,106,129,234,128,74,128,122,128,2,12 7,252,0,0
B_5 DEFB 0,0,127,252,128,2,135,194,134,34,143,18,155,82,148 ,146,155,82,148,146,155,66,136,130,135,2,128,2,127 ,252,0,0
B_6 DEFB 0,0,127,252,128,2,129,2,131,130,131,130,191,250,15 9,242,143,226,135,194,142,226,156,114,144,18,128,2 ,127,252,0,0




Так же листинг загрузчика(но не обязательно нужно). Встраивается в первую РЕМ строку в бейсике.



ORG 48500
START
;Новые адреса процедур
NEW_LD_EDGE_2 EQU LOADER+141
NEW_LD_EDGE_1 EQU LOADER+145
NEV_LD_8_BITS EQU LOADER+116

;Перекинем программу
LD BC,LOADER-START
LD DE,(23635)
LD HL,5
ADD HL,DE
LD DE,48500
LDIR
JP GOTO

TEXT DEFB 22,11,12,#EF,8,"I","N","G"

GOTO ;Напишем "LOADING"
LD A,2
CALL 5633
LD DE,TEXT
LD BC,8
CALL 8252

;Окрасим экран в нужные атрибуты
LD HL,#5800
LD DE,#5801
LD BC,#2FF
XOR A
LD (HL),A
LDIR

;Утолщим вторую треть
LD BC,2048
LD HL,18432
BOLD LD A,(HL)
SRL A
OR (HL)
LD (HL),A
INC HL
DEC BC
LD A,B
OR C
JR NZ,BOLD

;Подготовим цвета букв
LD B,7
LD HL,22892
LD DE,1345
CLR LD A,(DE)
AND 71
LD (HL),A
INC HL
INC DE
DJNZ CLR


;Скопируем стандартный загрузчик
LD HL,#0556
LD DE,LOADER
LD BC,175
LDIR

;Начальный цвет бордюра
XOR A
LD (LOADER+5),A
LD (LOADER+17),A

;Изменим хвост загрузчика
LD A,#AF
LD (LOADER+173),A ;XOR A
LD A,#D3
LD (LOADER+174),A ;OUT
LD A,#FE
LD (LOADER+175),A ;(#FE),A
LD A,#37
LD (LOADER+176),A ;SCF
LD A,#C9
LD (LOADER+177),A ;RET


;Изменим задержку 358 тактов на вызов нашей процедуры
LD A,#CD
LD (LOADER+145),A ;CALL DELAY
LD HL,DELAY
LD (LOADER+146),HL
XOR A
LD (LOADER+148),A ;NOP
LD (LOADER+149),A ;NOP


;Обновим адреса переходов на LD_EDGE_1
LD HL,LOADER+145
LD (LOADER+23),HL
LD (LOADER+60),HL
LD (LOADER+70),HL
LD (LOADER+142),HL

;Обновим адреса переходов на LD_EDGE_2
LD HL,LOADER+141
LD (LOADER+38),HL
LD (LOADER+45),HL
LD (LOADER+117),HL

;Обновим адреса переходов на LD_8_BITS
LD HL,LOADER+116
LD (LOADER+128),HL


;Данные блоков
BLOCK1 LD HL,BLOCK2 ;Изменим адреса возврата(было #053F)
LD (LOADER+9),HL
LD DE,8263
LD IX,32768
LD A,255
SCF
JP LOADER

BLOCK2 LD HL,32768
LD (LOADER+9),HL
LD DE,8079
LD IX,#C000
LD A,255
SCF
JP LOADER

DELAY ;Подпрограмма задержки должна быть 329 тактов
PUSH BC ;11
PUSH HL ;11
LD HL,22892 ;10
LD C,(HL) ;7
LD B,6 ;7
C4 INC HL ;6
LD A,(HL) ;7 32
DEC HL ;6
LD (HL),A ;7
INC HL ;6

DJNZ C4 ;13,8 (45,40)

LD (HL),C ;7
POP HL ;10
POP BC ;10
RET ;10

LOADER ;Тут будет загрузчик

Bedazzle
16.06.2019, 13:39
Извиняюсь забыл, ещё один листинг с уровнями и спрайтами


Сохранил графику как отдельный файл, заинклудил в основном коде
INCLUDE "tank_gfx.a80"

Вывалились ошибки про очень длинные строчки с байтами. После разбиения на более короткие, и комментирования в основном коде меток

;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

скомпилялось и запустилось.

https://i.imgur.com/ibQl2rq.png

Labrador
16.06.2019, 15:18
Dwa83, немного не в тему, но как откомпиленный в ZX-Gens листинг из байткода превратить в что-то читаемое эмуляторами (например sna)?

Black Cat / Era CG
16.06.2019, 16:21
Не байткод, наверное, а машинный код, Gens - это ассемблер. Запустить код на исполнение в эмуляторе, сохранить sna.

Labrador
16.06.2019, 16:31
Спасибо, Black Cat / Era CG, я имел ввиду ZX-Gens by Dwa83 от сюда - https://vtrd.in/pcutilz.php (редактор, кроскомпиллер или что-то вроде этого), он компилит в байткод, вот мне интересно, что с ним делать дальше (с байткодом).

Black Cat / Era CG
16.06.2019, 16:36
Аааа. А у него документации нет в комплекте? А ваще это суровый оффтоп.

Labrador
16.06.2019, 16:50
Да, за оффтоп конечно дико извиняюсь. Просто хотел скомпилить листинг Dwa83, естественно имея утилиту от Dwa83 захотелось скомпилить в ней, все прошло без ошибок, но что делать с байткодом дальше... Доков к сожалению нет, с ней идут примеры, при чем с готовыми scl, но как они получены я не знаю :)
В целом скомпилил в zDevStudio, танчики работают :)

zx-kit
16.06.2019, 18:49
В качестве авторитетного примера приведу вот эту поделку alone coder-а
https://jpegshare.net/images/3c/ea/3cea0cc2796d4181a0471702156e4b32.png
(вертикальные столбцы это младшие 256 байт)

где видно что видео буфер лежит "вертикально" а в образовавшихся щелях понапихано еще :)


Получается, что буферы бывают двух типов ? Линейный по-горизонтали и вертикли как описанный у alone и линейный только по-горизонтали, когда идут подряд линии по несколько байтов. А при копировании на экран эти линии переставляются как надо. При этом по-горизонтали может быть 32 байта или меньше.

- - - Добавлено - - -

Или в играх бывают и другие варианты ?

- - - Добавлено - - -

Я когда-то тоже игру про танчики пытался написать. Можете посмотреть мои исходники: http://www.zxkot.ru/software/s01

NEO SPECTRUMAN
16.06.2019, 18:59
буферы бывают двух типов ?
сколько типов можот представить больная фантазия столько и бывает
главное чтоб они хорошо выполняли поставленную задачу

zx-kit
16.06.2019, 19:22
сколько типов можот представить больная фантазия столько и бывает
главное чтоб они хорошо выполняли поставленную задачу
Я хочу сделать аппаратное копирование буфера на микросхемах. Два типа копирования сделать можно. По предварительным подсчетам копирование 32-х байтов займет 16 тактов, а загрузка параметров для копирования из Z80 командами LD A, N; OUT (ADR), A 72 такта. Надо бы оптимизировать скорость загрузки адресов в буфере и на экране.

- - - Добавлено - - -

А какие еще вы встречали способы расположения байтов в буферах ?

- - - Добавлено - - -

Если применить 4 команды OUTI, то время уменьшится до 64 тактов.

NEO SPECTRUMAN
16.06.2019, 19:26
Я хочу сделать аппаратное копирование буфера на микросхемах. Два типа копирования сделать можно. По предварительным подсчетам копирование 32-х байтов займет 16 тактов, а загрузка параметров для копирования из Z80 командами LD A, N; OUT (ADR), A 72 такта. Надо бы оптимизировать скорость загрузки адресов в буфере и на экране.
раз ты уже пилишь свой велосипед то
как вариант
завести буфер килобайт на 8
а памяти видео карты\или прямо в памяти спека

и записывать в него

1 управляющий байт
d0 инкримент\декремент адреса источника
d1 инкримент\декремент адреса приемника
d2 инкримент\декремент старшего\младшего байта источника
d3 инкримент\декремент старшего\младшего байта приемника
d4 итд
d5
d6
d7
2 байта адрес источник
2 байта адрес приемник
1/2 байта число байт для пересылки

потом засылаешь такой список в видеокарту
или кидаешь в видео карту адрес от куда читать такую таблиц

и чтоб потом оно само автоматически по этой таблице
перекину все что нужно в нужном виде (с зеркалинием\столбиками как напишешь)

- - - Добавлено - - -

от тебя нужно
правильно угадать все нужные возможности управляющего байта\слова
чтоб можно было описать переброску любой сложности

zx-kit
16.06.2019, 19:30
раз ты уже пилишь свой велосипед то
как вариант
завести буфер а памяти видео карты\или прямо в памяти спека

и записывать в него

1 управляющий байт
d0 инкримент\декремент адреса источника
d1 инкримент\декремент адреса приемника
d2 инкримент\декремент старшего\младшего байта источника
d3 инкримент\декремент старшего\младшего байта приемника
d4 итд
d5
d6
d7
2 байта адрес источник
2 байта адрес приемник
1/2 байта число байт для пересылки

потом засылаешь такой список в видеокарту
или кидаешь в видео карту адрес от куда читать такую таблиц

и чтоб потом оно само автоматически по этой таблице
перекину все что нужно в нужном виде (с зеркалинием\столбиками как напишешь)

- - - Добавлено - - -

от тебя нужно
правильно угадать все нужные возможности управляющего байта\слова
чтоб можно было описать переброску любой сложности
Да, наверно более универсально записать один раз в дополнительную память адреса отрезков в буфере и экране. А потом данные для очередного копирования будут читаться на более высокой скорости. Конечно сложение адресов и длины отрезка на микросхемах сложнее сделать. Проще заранее посчитать и загрузить в таблицу.

NEO SPECTRUMAN
16.06.2019, 19:37
зачем сложение?
яжо вроде описал набор счетчиков
с установкой начальных значений


хотя только их может не хватить
и предется ну очень детально описывать что и куда мы перекидываем

zx-kit
16.06.2019, 19:59
зачем сложение?
яжо вроде описал набор счетчиков
с установкой начальных значений


хотя только их может не хватить
и предется ну очень детально описывать что и куда мы перекидываем
Когда байты идут последовательно управляющий байт показывает в какую сторону уменьшить/увеличить каждый счетчик на 1. А если последовательность прерывается, то загружать адреса заново ?

- - - Добавлено - - -

Для простоты автомата можно байты парами записывать. 1 - что делать: увлеичивать или загружать и какой счетчик, а второй байт - байт для загрузки части адреса или не использовать.

NEO SPECTRUMAN
16.06.2019, 20:00
А если последовательность прерывается, то загружать адреса заново ?
если не можем описать переброску одной "управляющей строкой"
то целая таблица
для каждой строки подряд друг за другом
управляющий байт
адреса
управляющий байт
адреса

в конце управляющий байт (конец кадра)

zx-kit
16.06.2019, 20:02
В первом байте: один бит - признак загрузки, два бита - куда загружать.
Во втором байте: байт адреса.

NEO SPECTRUMAN
16.06.2019, 20:09
Один бит - признак загрузки, два бита - куда загружать.
еще нужно учитывать
направление счета

в идеале нужно чтоб был инкримент\декремент
начинаю от любого бита адреса

ХХХХ ХХХХ ХХХХ ХХХХ
ХХХХ ХХХХ ХХХХ ХХХN
ХХХХ ХХХХ ХХХХ ХХNN
....
XXNN NNNN NNNN NNNN
XNNN NNNN NNNN NNNN

где N - биты которые остаются неименными
X - биты которые инкрементятся декрементятсо

пушо строение экрана спектрума оставляет желать лучшого

но это усложнит конструкцию



или же можно сделать хардварное перетасовывание битов приемника
чтоб писать в видео память так
будто она линейно расположена

zx-kit
16.06.2019, 20:25
еще нужно учитывать
направление счета
Если байты идут последовательно, то в первом байте - соответствующее число.
Во втором байте: по два бита на счетчик - что делать.

Ориентировочно:
00 - не менять
01 - +1
10 - -1
11 - перенос из младшего счетчика

- - - Добавлено - - -



или же можно сделать хардварное перетасовывание битов приемника
чтоб писать в видео память так
будто она линейно расположена
Это можно.

- - - Добавлено - - -

Тогда к экрану лучше обращаться не по адресам, а по координатам в байтах и аппаратно биты переставить.

NEO SPECTRUMAN
16.06.2019, 20:35
Тогда к экрану лучше обращаться не по адресам, а по координатам в байтах и аппаратно биты переставить.
и тут вопрос
а если нужно будет перекинуть буфер
в спектрумовском формате...

- - - Добавлено - - -


Тогда к экрану лучше обращаться не по адресам, а по координатам в байтах и аппаратно биты переставить.
и тут вопрос
а если нужно будет перекинуть буфер
в спектрумовском формате...

zx-kit
16.06.2019, 21:01
и тут вопрос
а если нужно будет перекинуть буфер
в спектрумовском формате...

Буфер обычно в другом формате. Но можно указать адреса линий из нескольких байтов.

А как можно сохранить часть фона перед рисованием в буфер спрайта, а потом восстановить ? Самое простое - сохранить весь буфер, но в друг это не для всех игр подойдет.

Если буфер линейный наверно можно змейкой. Указать вначале адреса, а потом +-1.

- - - Добавлено - - -

Может проще все игры под линейный буфер переделывать для однотипности ?

- - - Добавлено - - -

Линейный буфер также можно весь змейкой копировать - так быстрее.

goodboy
16.06.2019, 21:04
Может проще все игры под линейный буфер переделывать для однотипности ?
а играм быстрая переброска буфера не всегда идёт на пользу.
можно вспомнить `ускоренный` savage. его ускорили программно, но это сказалось на играбельности.
или допустим игра Eidolon, экран там перебрасывается быстро, но все тормоза из-за рисования графики в буфер.

zx-kit
16.06.2019, 21:20
а играм быстрая переброска буфера не всегда идёт на пользу.
можно вспомнить `ускоренный` savage. его ускорили программно, но это сказалось на играбельности.
или допустим игра Eidolon, экран там перебрасывается быстро, но все тормоза из-за рисования графики в буфер.
Дополнительную графику можно перебросить только аппаратно. А линейный буфер упрощает переход к байту вниз.
Замедлить наверно легче, чем ускорить.

Если переставить биты аппаратно, то даже экран становится линейным. А вот если в буфере строки идут подряд по 32 байта, то для перехода к байту вниз надо прибавить 32 к адресу...

Можно для этого случая сумматор добавить, но если игру переделать под линейный буфер, то и рисование графики в буфер ускорится .

- - - Добавлено - - -

Если линейный буфер сделать с адреса 0000H, то еще проще и быстрее.

goodboy
16.06.2019, 21:23
проще ускорить z80

Bedazzle
17.06.2019, 07:10
сколько типов можот представить больная фантазия столько и бывает
главное чтоб они хорошо выполняли поставленную задачу

К примеру, при копировании из буфера на экран может происходить масштабирование.



stretch_to_scr:
ld b, #08 ; pixelrows in char

draw_scanline:
push de
ld c, #20

dup #20
ldi
edup

bit 0, b
jr nz, next_scanline

ld de, -32
add hl, de ; draw same bytes on even line

next_scanline:
pop de
inc d
djnz draw_scanline

ex de, hl
ld bc, -32*63 ; #F820 = -2016
add hl, bc
ex de, hl
dec a
jr nz, stretch_to_scr

ret

Lethargeek
17.06.2019, 14:52
раз ты уже пилишь свой велосипед то
как вариант
завести буфер килобайт на 8
а памяти видео карты\или прямо в памяти спека

и записывать в него

1 управляющий байт
d0 инкримент\декремент адреса источника
d1 инкримент\декремент адреса приемника
d2 инкримент\декремент старшего\младшего байта источника
d3 инкримент\декремент старшего\младшего байта приемника
d4 итд
d5
d6
d7
2 байта адрес источник
2 байта адрес приемник
1/2 байта число байт для пересылки

потом засылаешь такой список в видеокарту
или кидаешь в видео карту адрес от куда читать такую таблиц

и чтоб потом оно само автоматически по этой таблице
перекину все что нужно в нужном виде (с зеркалинием\столбиками как напишешь)

- - - Добавлено - - -

от тебя нужно
правильно угадать все нужные возможности управляющего байта\слова
чтоб можно было описать переброску любой сложности
чего только эти русские не придумают, лишь бы нормальные дороги не строить и нормальный блиттер не делать :v2_dizzy_facepalm:

NEO SPECTRUMAN
17.06.2019, 15:46
нормальный блиттер не делать
как бы у 99% платформ которые меня интересуют
никаких блитеров нету
я и не знаю какие у него должны быть возможности
только поверхностное представление


попривыкали к своим бгмерским амигам понимаешь

- - - Добавлено - - -


как бы у 99% платформ которые меня интересуют
никаких блитеров нету
до походу как минимум одна платформа есть (в одной из версий эту приблуду впилили)
но ее железную часть я еще не изучил

Lethargeek
17.06.2019, 18:48
как бы у 99% платформ которые меня интересуют
никаких блитеров нету
я и не знаю какие у него должны быть возможности
только поверхностное представление
просто твой пример уже мало отличаться будет по сложности от универсального блиттера
будучи при этом преднамеренно неуниверсальным, узкозаточенным
(что, впрочем, должно понравиться zst)))

NEO SPECTRUMAN
17.06.2019, 19:34
просто твой пример уже мало отличаться будет по сложности от универсального блиттера
А универсальные блитеры
умеют читать не линейно из набор проивольных мест
и так жо перекидывать опять же с любым шагом вдоль и поперек памяти

к примеру
ложить нелийно считанное "прибавляя 256 к шагу"


и чего тогда описанное не есть блитер?
(не считая возможности наложения друг на друга)

хотя мое описание наверное большо смахивает на весьма раздутый ДМА
что вощем та тожо есть во всех этих ваших девайсах с блитерами