Рисунок 5.4. Окна в игре MICRONAUT ONE
Как видите, можно придумать множество типов окон, но давайте сначала посмотрим, как получить наиболее простые из них и напишем подпрограммы, выполняющие наиболее распространенные преобразования в окнах. Первую из них, которая выполняет очистку заданной области экрана, назовем в соответствии с аналогичной процедурой LaserBasic'а CLSV. Перед обращением к ней необходимо заполнить 4 переменные, под которые нужно зарезервировать память инструкцией ассемблера DEFB:
COL DEFB 0 ROW DEFB 0 LEN DEFB 0 HGT DEFB 0
Обратите внимание, что переменные должны располагаться именно в том порядке, в котором они указаны; менять их местами или разбрасывать по тексту программы недопустимо. Это условие введено для упрощения всех последующих процедур, работающих с окнами, о чем мы еще скажем при детальном разборе подпрограмм. Другое упрощение касается допустимых значений переменных: во-первых, окно не может иметь нулевые размеры ни по ширине, ни по высоте, а во-вторых, оно не должно выходить за пределы экрана.
Такие допущения сделаны не только для упрощения подпрограмм и сокращения их размеров. Это позволяет также и несколько увеличить их быстродействие, так как все необходимые проверки возлагаются на программиста. Кстати, в большинстве игровых программ операции с окнами (да и многие другие) производятся как раз безо всяких проверок корректности задаваемых параметров. Ведь подобные действия нужны, в основном, лишь на стадии отладки программы, а когда работа закончена, они становятся «мертвым грузом», только замедляющим выполнение процедур.
Итак, приводим подпрограмму очистки окна экрана:
CLSV LD BC,(LEN) ;чтение сразу двух переменных: ; C = LEN, B = HGT LD A,(ROW) CLSV1 PUSH AF PUSH BC CALL 3742 ;адрес начала строки экрана LD A,(COL) ;прибавляем смещение ADD A,L ; COL по горизонтали LD L,A LD B,8 ;в каждой строке 8 рядов пикселей CLSV2 PUSH HL LD E,C ;счетчик циклов в E, равный ширине окна XOR A ;в аккумуляторе 0 CLSV3 LD (HL),A ;обнуляем очередной байт видеобуфера INC HL ;переходим к следующему DEC E ;пока не дойдем до правого края окна JR NZ,CLSV3 POP HL INC H ;переходим к следующему ряду пикселей DJNZ CLSV2 POP BC POP AF INC A ;переходим к следующей строке экрана DJNZ CLSV1 ;повторяем, пока не дойдем ; до нижнего края окна RET