XI.1.4. Р е ж и м ы SCREEN 2 и SCREEN 4 Есть медленно и умеренно, не пить во время еды, тщательно разжевывать пищу и с легко- стью вставать из-за стола с чувством, что мог бы съесть еще. Ж.Фрумузак Разделим экран (размером 256╳192 точек) на к в а д р а т ы размером по 8╳8 точек. Легко подсчитать, что мы получим 768 таких квадратов.Каждый из них имеет свой номер, который хранится в Таблице PNT. А так как макси- мальное целое число, которое можно "разместить" в одном байте памяти (в данном случае VRAM), равно 255, поэтому Таблицу PNT необходимо разбить на т р и области, каждая из которых будет отвечать за нумерацию только 256 квадратов. При установке режимов SCREEN 2 или SCREEN 4 (при инициализации) в каж- дую треть Таблицы PNT последовательно заносятся целые числа от 0 до 255. ┌───────────────────────────────────────────────────────────────────┐ │ Адрес байта PNT, отвечающего за к в а д р а т с номером n2, │ │ вычисляется при помощи арифметического выражения: │ │ BASE(5·N) + 256·n1 + n2 │ │ где: N - номер режима SCREEN (2 или 4); │ │ n1 - номер трети таблицы PNT, в которой находится квадрат; │ │ n2 - номер квадрата. │ └───────────────────────────────────────────────────────────────────┘ Соответственно Таблице PNT, весь экран также разбивается на три области (каждая размером 256╳64 точек), которые мы будем называть о к н а м и. ┌───┬───┬─────────────────────┬───┐ │ 0 │ 1 │··· ···│ 31│ ├───┴───┘ └───┤ │ ··· О к н о 0 ···│ ├───┬───┐ ┌───┤ │224│225│··· ···│255│ ├───┼───┼─────────────────────┼───┤ │ 0 │ 1 │··· ···│ 31│ ├───┴───┘ └───┤ │ ··· О к н о 1 ···│ ├───┬───┐ ┌───┤ │224│225│··· ···│255│ ├───┼───┼─────────────────────┼───┤ │ 0 │ 1 │··· ···│ 31│ ├───┴───┘ └───┤ │ ··· О к н о 2 ···│ ├───┬───┐ ┌───┤ │224│225│··· ···│255│ └───┴───┴─────────────────────┴───┘ Если мы захотим изменить "что-нибудь" в Таблице PNT, это немедленно ска- жется на изображении в соответствующем окне. Таблица PNT редко используется при составлении программ. Более того,мож- но рассматривать структуру экрана, "забыв" о делении экрана на окна. Доста- точно при этом мысленно пронумеровать квадраты экрана от 0 до 767. Покажем, как можно использовать Таблицу PNT для копирования изображения в пределах о д н о г о экранного окна. Пусть, например, Вам нужно скопи- ровать изображение из квадрата с номером A в квадрат с номером B.Для этого в байт Таблицы PNT, отвечающий за квадрат с номером B, поместите номер ква- драта A. Этого достаточно для того, чтобы произошел процесс копирования! П р и м е р 1. ───────────── 10 COLOR 1,15:SCREEN 2 20 LINE(8,8)-(15,15),,BF 'Сформировано изображение в квадрате 33 30 A$=INPUT$(1) 40 VPOKE &H1800+40,33 'Скопировали его в квадрат 40 50 GOTO 50 Более того, Вы можете заранее (до того, как будете что-то рисовать на экране) "размножить" по нужным адресам номер определенного блока. Далее, Вам достаточно лишь заполнить изображением тот квадрат,номер которого был "размножен",и, к Вашей радости,это изображение появится и в других местах! П р и м е р 2. ───────────── 10 COLOR 1,15:SCREEN 2 20 VPOKE &H1800+40,33 'Квадрат 40 подготовлен для приема 30 A$=INPUT$(1) 'копии из квадрата 33 40 LINE(8,8)-(15,15),,BF 'Сформировано изображение в 33-м и 50 GOTO 50 'в 40-м квадрате Если же Вы захотите скопировать какой-либо элемент в другое о к н о экрана, то Вам поможет работа с Таблицами PGT и CT,к рассмотрению которых мы и переходим. Каждый квадрат 8╳8 точек разобьем на 8 горизонтальных участков,которые будем называть л и н и я м и . Информация о каждой линии (1 байт) содержится в Таблице PGT. Следовательно, объем этой Таблицы равен 768╳8 = 6144 байтам. ┌───────────────────────────────────────────────────────────┐ │ Адрес байта Таблицы PGT, отвечающего за расположение │ │ л и н и и вычисляется при помощи арифметического │ │ выражения BASE(5·N+2) + (256·n1+n2)·8 + k │ │ где: N - номер режима SCREEN; │ │ n1 - номер окна; │ │ n2 - номер квадрата в этом окне; │ │ k - номер линии в этом квадрате. │ └───────────────────────────────────────────────────────────┘ Отметим, что если в Таблице PNT были изменения, то могут возникнуть за- труднения при попытке "нарисовать" что-либо в квадрате с измененным номе- ром. П р и м е р 3. ───────────── 10 COLOR 1,15:SCREEN 2 20 VPOKE 6144+40,VPEEK(6144+33)'Произошло изменение в Таблице PNT 30 A$=INPUT$(1) 'Ждем нажатия клавиши! 40 LINE(64,8)-(71,15),,BF 'Попытка вывести изображение в квадрате 50 GOTO 50 '40 не привела к ожидаемому результату! Так как информация о линии хранится в одном байте, то каждой точке ли- нии соответствует определенный бит этого байта. Оказывается, что "высве- тить точку на экране" - это значит установить нужный бит в 1,"стереть точ- ку с экрана" - это значит установить бит в 0 ! Если некоторый бит равен 0,то соответствующую ему точку на экране бу- дем называть точкой ф о н а, в противном случае будем называть ее точкой и з о б р а ж е н и я. Каждому байту Таблицы PGT однозначно соответствует один байт в Таблице цветов (CT), причем четыре младших бита этого байта кодируют локальный цвет ф о н а для каждой линии, а четыре старших - локальный цвет и з о- б р а ж е н и я. Например: Т о ч к и ф о н а │ │ │ │ │ ┌────┬──▼─┬──▼─┬──▼─┬────┬────┬──▼─┬──▼─┐ │ 1 │ 0 │ 0 │ 0 │ 1 │ 1 │ 0 │ 0 │ Байт PGT └──▲─┴────┴────┴────┴──▲─┴──▲─┴────┴────┘ │ │ │ Т о ч к и и з о б р а ж е н и я ┌────┬────┬────┬────┬────┬────┬────┬────┐ │ 0 │ 1 │ 0 │ 1 │ 1 │ 1 │ 0 │ 1 │ Байт CT └────┴────┴────┴────┴────┴────┴────┴────┘ └────────▲────────┘ └────────▲─────────┘ │ │ Цвет и з о б р а ж е н и я Цвет ф о н а Таким образом,точки изображения будут иметь цвет 5, а точки фона будут иметь цвет 13. Так как из четырех двоичных цифр можно составить только 16 комбинаций, то ясно, что ┌─────────────────────────────────────────────────────────────┐ │ одновременно на экране может быть не б о л е е 16 цветов │. └─────────────────────────────────────────────────────────────┘ ┌───────────────────────────────────────────────────────────────────────┐ │Вследствие этого,изменение цвета одной точки приводит к переопределению│ │ цвета и з о б р а ж е н и я в с е й линии! │ └───────────────────────────────────────────────────────────────────────┘ ┌───────────────────────────────────────────────────────────┐ │ Адрес байта Таблицы CT, отвечающего за ц в е т линии, │ │ вычисляется при помощи арифметического выражения: │ │ BASE(5·N+1) + (256·n1+n2)·8 + k │ │ где: N - номер режима SCREEN; │ │ n1 - номер окна; │ │ n2 - номер квадрата в этом окне; │ │ k - номер линии в этом квадрате. │ └───────────────────────────────────────────────────────────┘ П р и м е р 4. Предположим, что Вам захотелось в 5-й линии 58-го квад- ───────────── рата 2-го окна в режиме SCREEN 2 точки 0÷3 изобразить цветом 3, а точки 4÷7 - цветом 15. 10 SCREEN 2 20 A=BASE(5*2+1)+(256*2+58)*8+5 30 B=BASE(5*2+2)+(256*2+58)*8+5 40 VPOKE B,&B11110000 50 VPOKE A,&H3F 60 GOTO 60 А теперь - давно обещанный Вам пример... П р и м е р 5. Копирование содержимого 0-го квадрата из 0-го окна в ────────────── содержимое 0-го квадрата 2-го окна 10 COLOR 15,1,1:SCREEN2 20 LINE(0,0)-(7,7),,BF 25 FOR I=0 TO 7 30 VPOKE BASE(5*2+2)+(256*2+0)*8+I,VPEEK(BASE(5*2+2)+(256*0+0)*8+I): 'Копирование изображения 35 VPOKE BASE(5*2+1)+(256*2+0)*8+I,VPEEK(BASE(5*2+1)+(256*0+0)*8+I): 'Копирования цвета 40 NEXT 50 GOTO 50 П р и м е р 6. Изобразим квадрат, стороны которого имеют разные цвета, ───────────── не используя оператор PSET. 10 SCREEN 2 14 DATA 0,5,1,37,2,37,4,37,8,165,4,165,2,165,1,21,0,5,0,5,128,133,64, 133,32,133,64,21,128,21,0,5 'Фон синего цвета 15 FOR I=0 TO 1 · 16 FOR J=0 TO 7 Точки · · Точки 20 A=BASE(5*2+2)+(256*0+I)*8+J зеленого ──▶· ·◀── красного 30 B=BASE(5*2+1)+(256*0+I)*8+J цвета · · цвета 40 READ Z,U:VPOKE A,Z:VPOKE B,U Точки ──▶· ·◀── Точки 60 NEXT J желтого · · черного 70 NEXT I цвета · цвета 80 GOTO 80 ┌──────────────────────────────────────────────────┐ │ Важно заметить, что Таблица CT инициализируется │ │ цветом ф о н а, задаваемым в операторе COLOR. │ └──────────────────────────────────────────────────┘ Опишем алгоритм установки точки в режимах SCREEN 2 и SCREEN 4. 1. Первый шаг состоит в нахождении адреса байта Таблицы PGT в зависи- мости от координат (X,Y) ("г р у б а я настройка"). ┌────────────────────────────────────────┐ │ А д р е с = ((Y\8)*32+Х\8)*8+Y MOD 8 │ └────────────────────────────────────────┘ 2. После этого нужно точно определить номер бита найденного байта, от- вечающего за данную точку ("т о ч н а я настройка"). Трудность состоит в несоответствии номеров битов в байте и значений Х-координат тех точек, за которые этот байт отвечает: ┌────────────┬───┬───┬───┬───┬───┬───┬───┬───┐ │ Х MOD 8 │ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ ├────────────┼───┼───┼───┼───┼───┼───┼───┼───┤ │ Номер бита │ 7 │ 6 │ 5 │ 4 │ 3 │ 2 │ 1 │ 0 │. └────────────┴───┴───┴───┴───┴───┴───┴───┴───┘ Формула, при помощи которой можно найти номер бита по Х - к о о р д и- н а т е, выглядит следующим образом: ┌──────────────────────────┐ │ NB = 2^(8+NOT(X MOD 8)) │. └──────────────────────────┘ 3. Теперь остается записать "1" в найденный бит. ┌───────────────────────────────────────────┐ │ VPOKE А д р е с, VPEEK (А д р е с) OR NB │. └───────────────────────────────────────────┘ И...точка появится в требуемом месте экрана. 4. Наконец, изменим цвет изображения выведенной точки: ┌────────────────────────────────┐ │ А д р е с = А д р е с + &h2000 │ └────────────────────────────────┘ ┌────────────────────────────────────────────────────┐ │ VPOKE А д р е с, VPEEK(А д р е с) MOD 16 + COL*16 │ , └────────────────────────────────────────────────────┘ где COL - номер цвета. Опишем алгоритм работы видеопроцессора при выводе содержимого квадрата 8╳8 на графические экраны SCREEN 2 или SCREEN 4. Предположим, что нам известно местоположение данного квадрата на экра- не. Пусть N - номер квадрата с координатами (X,Y) (0≤X≤31,0≤Y≤23)(номер N пока нам неизвестен!). Взгляните на рисунок: ┌───┬───┬─────────────────────┬───┐ Y=0 │ 0 │ 1 │··· ···│ 31│ · ├───┴───┘ └───┤ · │ ··· ··· │ Окно 0 · ├───┬───┐ ┌───┤ Y=7 │224│225│··· ···│255│ ├───┼───┼─────────────────────┼───┤ Y=8 │ 0 │ 1 │··· ┌───┐ ···│ 31│ · ├───┴───┘ ┼▼┼ X └───┤ · │ ··· Y───▶N│ ··· │ Окно 1 · ├───┬───┐ ┼─┼ ┌───┤ Y=15 │224│225│ ···│255│ ├───┼───┼─────────────────────┼───┤ Y=16 │ 0 │ 1 │ ···│ 31│ · ├───┴───┘ └───┤ · │ ··· ··· │ Окно 2 · ├───┬───┐ ┌───┤ Y=23 │224│225│ ···│255│ └───┴───┴─────────────────────┴───┘ ┌─────────────────────────────────────────────────────────────────────┐ │ "Посмотрев" Таблицу PNT по адресу (Y\8)*256+(YMOD8)*32+X, найдем N. │ │ "Запишем" информацию о квадрате в Таблицу PGT по адресам: │ │ (Y\8)*2048+N*8 , (Y\8)*2048+N*8+1,(Y\8)*2048+N*8+2,(Y\8)*2048+N*8+3,│ │ (Y\8)*2048+N*8+4,(Y\8)*2048+N*8+5,(Y\8)*2048+N*8+6,(Y\8)*2048+N*8+7,│ │ в результате на экране в квадрате (X,Y) Вы увидите то, что хотели! │ │ А теперь "раскрасим" изображение. │ │ "Запишем" информацию о цвете в Таблицу CT по адресам: │ │ (Y\8)*2048+N*8 , (Y\8)*2048+N*8+1,(Y\8)*2048+N*8+2,(Y\8)*2048+N*8+3,│ │ (Y\8)*2048+N*8+4,(Y\8)*2048+N*8+5,(Y\8)*2048+N*8+6,(Y\8)*2048+N*8+7,│ │ в результате квадрат с координатами (X,Y) будет раскрашен в нужные │ │ Вам цвета │ └─────────────────────────────────────────────────────────────────────┘ П р и м е р 7. ───────────── 10 COLOR 1,15,8:SCREEN 2:X=5:Y=10 20 N=VPEEK(BASE(5*2+0)+(Y\8)*256+(YMOD8)*32+X) 'Видеопроцессор "опраши- вает" байт номер 69 в окне 1 Таблицы PNT и находит значение N (N=69, е сли Таблица PNT не изменялась) 30 FOR I=0 TO 7 40 VPOKE(&H800+N*8+I),&B11100011'Таблица PGT разделена на три окна,каж дое из которых содержит по 2048 байтов. Следовательно, окно 1 этой Таб лицы начинается по адресу 2048=&H800. Первый из 8 байтов квадрата, на который указывает N в окне 1, размещается в ячейке &Н800+N*8 50 NEXT 'Содержимое этих 8 байтов и будет выведено в квадрате (X,Y) 60 GOTO 60 П р и м е р 8. ───────────── 10 SCREEN 2:X=15:Y=12 20 A=VPEEK(BASE(5*2+0)+(Y\8)*256+(YMOD8)*32+X) '"Смотрим" PNT 30 FOR I=0 TO 7 40 VPOKE(BASE(5*2+2)+(Y\8)*2048+A*8+I),&b11100011 'Формируем "содерж имое" квадрата 50 NEXT 60 GOTO 60 П р и м е р 9. Раскрасим выводимый квадрат 8-м и 10-м цветами. ───────────── 10 SCREEN 2:X=15:Y=12 20 A=VPEEK(BASE(5*2+0)+(Y\8)*256+(YMOD8)*32+X) '"Смотрим" Таблицу PNT 30 FOR I=0 TO 7 40 VPOKE(BASE(5*2+2)+(Y\8)*2048+A*8+I),&B11100011 'Формируем "содерж имое" квадрата 50 NEXT 60 FOR I=0 TO 7 70 VPOKE(BASE(5*2+1)+(Y\8)*2048+A*8+I),&H8A ' "Раскрасим" квадрат 80 NEXT 90 GOTO 90 Однако в режимах SCREEN 2 и SCREEN 4 используется система координат (X,Y), в которой Х изменяется от 0 до 255, а Y от 0 до 191. Следующий при- мер иллюстрирует, как эта система координат соотносится с делением экрана на квадраты. П р и м е р 10. ────────────── 10 SCREEN 2:X=100:Y=75 30 N=(Y\8)*32+(X\8) 'Номер квадрата, в котором будет выведена точка 40 M=Y MOD 8 'Номер линии в квадрате 50 AP=N*8+M 'Адрес соответствующего байта в Tаблице PGT 60 VA=&b00001000 65 AC=AP+&H2000 'Для определения соответствующего адреса в Таблице 'CT прибавим &H2000 к адресу Таблицы PGT 70 VPOKE AP,VA 'Значение VA=&B00001000 загрузим в PGT 80 VPOKE AC,&HF1 'Вводим значение &HF1 в Таблицу цветов для изображ 'ения точки белого цвета на черном фоне 90 IF INKEY$="" THEN 90 100 PSET(X,Y),6 110 GOTO 110 Сначала будет нарисована белая точка на черном фоне. Когда Вы нажмете любую клавишу, эта точка приобретет красный цвет. При программировании на MSX-BASIC этот способ формирования изображения применяется редко. Однако, если Вы хотите нарисовать что-либо с помощью программы на м а ш и н н о м я з ы к е, то приведенный выше алгоритм несомненно поможет Вам! Ясно,что обладая определенным набором графических элементов, можно син- тезировать различные графические изображения. Приведем без комментариев ряд примеров: 11) Одинаковые шаблоны 20 COLOR 15,1,1:CLS:SCREEN 2:COLOR 15,1:CLS 60 FOR I=0 TO 7 70 READ A:VPOKE I,A:VPOKE I+2048,A:VPOKE I+4096,A 80 NEXT 90 FOR I=6144 TO 6144+767:VPOKE I,0:NEXT 120 FOR I=8192 TO 14435:VPOKE I,241:NEXT 150 GOTO 150 160 DATA &b11111111 170 DATA &b10011001 180 DATA &b10111101 190 DATA &b11100111 200 DATA &b11100111 210 DATA &b10111101 220 DATA &b10011001 230 DATA &b11111111 12) 10 COLOR 1,15,6:SCREEN 2 20 FOR T=8 TO 15:LINE(8,T)-(15,T),T:NEXT:A$=INPUT$(1) 30 FOR T=0 T0 7:VPOKE 2048+33*8+T,VPEEK(33*8+T):NEXT 40 A$=INPUT$(1) 50 FOR T=0 TO 7:VPOKE 10240+33*8+T,VPEEK(8192+33*8+T):NEXT 60 A$=INPUT$(1) 13) 10 'Шахматная доска! 20 INPUT "Координаты X,Y";X,Y:X=X-XMOD8:Y=Y-YMOD8 21 IF X=0 THEN X=8 22 U=Y/8*32+X/8 25 COLOR 1,15,1:SCREEN 2 30 FOR T=0 TO 3:FOR I1=0 TO 1:FOR I2=0 TO 1:FOR F=U TO U+12 STEP 4: FOR K=0 TO 1 40 VPOKE BASE(10)+(F+(64+2)*K)+I2+32*I1+128*T,VPEEK (BASE(10)):NEXT K,F,I2,I1,T 50 LINE(0,0)-(8,192),1,BF:LINE(X,Y)-STEP(128,128),1,B:A$=INPUT$(1) 14) 10 COLOR 1,15,8:SCREEN 2:LINE(0,64)-(255,127),,BF 'Фон! 20 LINE(0,64)-(7,71),8,BF 'Перемещаемый объект! 30 FOR T=1 TO 31 40 F=VPEEK(6400+T):VPOKE 6400+T,VPEEK(6400+T-1):VPOKE 6400+T-1,F'Об мен значений между ячейками видеопамяти! 50 IF T=31 THEN VPOKE 6400+T,T:VPOKE 6400,0 60 NEXT T:GOTO 30 15) 10 CLEAR 200,&HC300:SCREEN 2 20 CIRCLE(90,70),56:PAINT STEP(0,0) 'Сформировано изображение 25 'Сохраняем изображения в памяти (RAM) 30 FOR I=BASE(5*2+1) TO BASE(5*2+1)+6143:POKE &HC300-BASE(5*2+1)+I, VPEEK(I):NEXT 40 FOR I=BASE(5*2+2) TO BASE(5*2+2)+6143:POKE &HC300+6144-BASE(5*2+ 2)+I,VPEEK(I):NEXT 50 SCREEN 0 60 SCREEN 2 'Вывод изображения на экран 70 FOR I=BASE(5*2+1) TO BASE(5*2+1)+6143:VPOKE I,PEEK(&HC300-BASE(5 *2+1)+I):NEXT 80 FOR I=BASE(5*2+2) TO BASE(5*2+2)+6143:VPOKE I,PEEK(&HC300-BASE(5 *2+2)+6144+I):NEXT 90 A$=INPUT$(1) 'Программа работает ≈ 5 минут