Файл: jourdain_spravochnik_programmista.docx

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 04.07.2020

Просмотров: 3084

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

область цветом 2 до линий цвета 3. Отметим, однако, что эта про-

цедура не заполняет области, находящиеся "за углом", т.е. если

вдоль какой-либо горизонтальной или вертикальной траектории

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

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

причудливую форму и эти точки принадлежат внутренней части фигу-

ры. В следующем примере выводятся две перекрывающихся рамки цве-

тами циан и магента, а затем последняя рамка заполняется белым

цветом. Сегменты первой рамки, которые попадают в закрашенную

область также заполняются белым.


100 LINE (50,70)-(270,130),1,B 'рисуем рамку цветом циан

110 LINE (100,30)-(220,170),2,B 'рисуем рамку цветом магента

120 PAINT (101,31),3,2 'заполняем вторую рамку белым



Помните, что команда LINE может сама заполнить рамку, если Вы

укажете в качестве параметра 'BF', а не 'B'. Смотрите [4.4.5].

Оператор PAINT имеет "орнаментальные" возможности, которые

позволяют Вам заполнять области указанной картинкой. Элементы

орнамента, которые в режиме умеренного разрешения имеют размер 4

точки в ширину и 8 в высоту (8*8 для высокого разрешения) повто-

ряются по всей указанной области. Рисунок описывается набором

байтов, содержащих цепочку битов для последовательных рядов эле-

мента орнамента. В режиме умеренного разрешения цепочка битов

10000011 описывает 4 точки, первая из которых имеет цвет 2, сле-

дующие 2 - фоновый цвет, а последняя - цвет 3. Эта цепочка соот-

ветствует числу 131 или &H83 (см. приложение Б, в котором обсуж-

даются битовые операции в Бейсике). Обращение этой цепочки в

11000010 даст 193 (&HC1). Они могут быть объединены в элемент

орнамента шириной в 4 точки и высотой в 2 строкой CHR$(&H83) +

CHR$(&HC1). В такую строку могут включаться до 8 байтов, доводя

высоту до 8 точек. Такая строка используется в операторе PAINT

вместо цвета. Вот вывод квадрата, заполненного описанным орнамен-

том:


100 LINE (100,110)-(150,150),1,B 'рисуем рамку

110 PAINT (125,125),CHR$(&H83)+CHR$(&HC1),1 'заполняем ее


Отметим, что нерегулярности элемента орнамента могут приводить к

тому, что процедура PAINT завершается, не закончив заполнения

области. Бейсик решает эту проблему указанием параметра фона для

оператора PAINT. Если у Вас возникнут проблемы, обращайтесь к

руководству по Бейсику за деталями.

Оператор DRAW, позволяющий рисовать сложные линии, также может

заполнять области. Он обсуждается в [4.4.5]. "Текущая точка" (из

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

помещена внутрь области, ограниченной границей указанного цвета.

В строку оператора DRAW надо поместить кодовую букву P, за кото-

рой должен следовать код цвета закраски и код цвета границы. Для

вывода рамки цветом 1 палетты, а затем ее заполнения цветом 3

напишите DRAW "U10R10D10L10BH1P3,1". Здесь первые четыре кода

рисуют границы рамки, затем код 'BH' перемещает текущую точку


внутрь рамки, не рисуя линии, а затем код 'P' приводит к заполне-

нию рамки. Таким образом могут быть заполнены и более сложные

формы. Отметим, что необязательно при перемещении точки внутрь

области отменять рисование линии вдоль этого пути. Однако, в этом

случае надо использовать для этого сегмента код цвета, отличный

от цвета заполняемой границы.

Бейсик имеет также возможность заполнения областей экрана

заранее подготовленным изображением. Изображение может быть любо-

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

в массиве. Обычно, изображение создается с помощью всех доступных

средств, а затем запоминается в массиве оператором GET. Массив

может быть помещен в последовательный файл [5.4.3], из которого

программа может загрузить его и вывести изображение. Оператор GET

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

рамки, содержащей изображение, причем сначала идет номер столбца,

а затем номер строки для каждой пары координат. Затем должно

следовать имя массива, которое не заключается в кавычки. Напри-

мер, GET (80,40)-(120,60),ARRAY3 помещает все точки, находящиеся



внутри указанной области в массив с именем ARRAY3.

Одномерные массивы, как и все остальные, должны быть предвари-

тельно описаны оператором DIM. Массив может содержать элементы

любой точности. Для вычисления требуемых размеров массива надо

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

ражения. Это можно вычислить по формуле 4 + INT ((x*битовнаточку

+ 7)/8)* y. Здесь "битовнаточку" равно 1 для высокого разрешения

и 2 - для умеренного разрешения. Буквы x и y относятся к числу

точек вдоль горизонтальной и вертикальной сторон блока изображе-

ния. INT обозначает целую часть числа. Наконец, надо определить

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

байтов. Каждый элемент занимает 2 байта в целом массиве, но 4 -

для чисел с обычной точностью и 8 - для чисел с двойной точно-

стью.

Для получения изображения из массива и вывода его на экран

используйте оператор PUT. Этот оператор требует только координаты

левого верхнего угла области экрана, в которую будет выводиться

изображение. За координатами должно быть указано имя массива.

Например, PUT (40,30),ARRAY1 помещает изображение, левый верхний

угол которого будет находиться в столбце 40 и строке 30. Оператор

PUT может иметь еще и необязательный параметр, определяющий цвет,

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

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

было записано оператором GET. Это эквивалентно записи PUT

(40,30),ARRAY1,PSET. В противном случае имеются некоторые другие

возможности. Если Вы вместо PSET укажете PRESET, то цвет 0 палет-

ты будет заменен на цвет 3 и наоборот, а цвет 1 палетты - на цвет

2 и наоборот.

Имеются еще три случая, использующие логические операции AND,


OR или XOR. Как и PRESET эти слова могут заменять PSET в приве-

денном примере. Обсуждение этих трех операций смотрите в приложе-

нии Б. Каждая операция включает сравнение битов существующей

точки на экране с битами точки накладываемого изображения. В

режиме высокого разрешения, когда на точку отводится только 1 бит

операция простая. Но в режиме умеренного разрешения, в котором на

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

формации цветов.

AND устанавливает бит только если он был установлен и у точки

экрана и у точки изображения (взятой из массива). В режиме высо-

кого разрешения это означает, что точка изображения появится на

экране только если соответствующая точка экрана уже "включена".

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

разрешения операция производится над обоими битами. Если для

точки экрана установка битов 01, а для соответствующей точки

изображения - 10, то оба бита будут сброшены и точка экрана полу-

чит код 00, что соответствует фоновому цвету.

OR устанавливает бит, если он был установлен либо для точки

экрана, либо для точки изображения. В черно-белом режиме OR нак-

ладывает изображение на существующее изображение на экране. В

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

к вычислениям. Комбинация кодов палетты 1(01) и 2(10) дает 3(11),

также как и комбинация 0(00) и 3(11).



И, наконец, XOR устанавливает бит, если из двух сравниваемых

только один был установлен. Применение этой операции для чер-

но-белого экрана с массивом единиц дает негативное изображение (1

и 1 дает 0, а 1 и 0 - дает 1). В режиме умеренного разрешения эта

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

изображений. Но более важно, что при повторении этой операции

экран принимает в точности такой же вид, который он имел первона-

чально. При этом изображение стирается. Эта техника полезна для

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

ция XOR в одной позиции, затем в соседней и т.д.


Низкий уровень.


Имеется много подходов к написанию процедур заполнения графи-

ческих объектов. Ни один из них не является идеальным, поскольку

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

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

которая заполняет область точку за точкой будет медленной, неза-

висимо от того, насколько элегантно она реализована. Имейте вви-

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

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

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

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

байта за один доступ к ячейке видеобуфера. Например, поточечная

очистка экрана требует на IBM PC нескольких секунд при использо-


вании функции BIOS, в то время как прямой доступ в память произ-

водит эту операцию мгновенно:


MOV AX,0B800H ;ES указывает на буфер экрана

MOV ES,AX ;

MOV CX,8192 ;заполняем все байты

MOV AX,0 ;в каждый байт пишем 0

MOV DI,0 ;DI поочередно указывает на все байты

REP STOSW ;повторяем запись 8192 раза


Многие процедуры заполняют по одной горизонтальной строке,

проверяя на цвет границы справа и слева. Поскольку строки состоят

из смежных байтов данных, то надо поочередно брать байты из ви-

деобуфера и проверять присутствует ли в них цвет границы. Если

цвет границы отсутствует, то можно заменить сразу весь байт на

цвет заполнения. В противном случае к данному байту применяется

поточечный подход.

Имеется очень быстрый способ определения присутствует ли гра-

ничный цвет в данном байте видеобуфера. Предположим, что процеду-

ра ищет цвет 1 палетты в режиме умеренного разрешения с четырьмя

цветами. Этому цвету соответствует код 01, поэтому сначала запол-

ним весь байт этим кодом: 01010101. Затем используем операцию NOT

для обращения каждого бита, после чего байт примет вид 10101010.

Проделаем операцию XOR со значением взятым из видеобуфера; в

результате получим байт, у которого оба бита, относящиеся к одной

точке равны 1 только для точек, имеющих граничный цвет. Затем

снова используем операцию NOT с тем, чтобы пара битов, относящих-

ся к точке граничного цвета имела код 00. После этого используем

операцию TEST для нахождения полей со значением 00. Если такое



поле найдено, то граничный цвет обнаружен и процедура переходит к

обычному поточечному анализу данного байта. Эту процедуру можно

еще убыстрить, если использовать словные данные.


MOV AL,ES:[BX] ;берем байт из видеобуфера

XOR AL,10101010B ;устанавливаем биты для цвета границы

NOT AL ;обращаем биты

TEST AL,11000000B ;проверяем биты 7-6

JZ FOUND_BOUND ;переход если граничный цвет

TEST AL,00110000B ;проверяем биты 5-4

JZ FOUND_BOUND ;переход если граничный цвет

TEST AL,00001100B ;проверяем биты 3-2

JZ FOUND_BOUND ;переход если граничный цвет

TEST AL,00000011B ;проверяем биты 1-0

JZ FOUND_BOUND ;переход если граничный цвет

MOV AL,FILL_COLOR ;граничного цвета нет, заполняем байт

MOV ES:[BX],AL ;возвращаем байт в видеобуфер

.

.

FOUND_BOUND:


Когда это возможно, постарайтесь, чтобы границы прямоугольных

областей Ваших картинок были выравнены на границу двух, четырех

или восьми точек, с тем чтобы прямое отображение в память имело

дело с целыми байтами. Другая возможность, хотя и не столь быст-

рая, состоит в создании определяемых пользователем псевдографи-

ческих символов [4.3.4] и выводе их на границе области заполне-

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

сообразительность, а зачастую стоит подумать, а нужна ли Вам

столь сложная графика в данной задаче.




4.4.7 Графический вывод с использованием символов псевдографики.





Когда Вы выводите изображение точка за точкой, то это отнимает

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

кации. Один из способов экономии времени состоит в сведении всех

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

на матрице точек 8*8. Такие фигуры могут быть созданы, как опре-

деляемые пользователем символы, как показано в [4.3.4]. После

того, как эти символы определены они выводятся на экран очень

быстро и просто. Эти символы могут выводиться вперемешку с пото-

чечными графиками, как обычные буквы. Один из способов быстрого

заполнения фигуры состоит в последовательном выводе внутри фигуры

полностью закрашенного блока. Отметим, что эти символы всегда

располагаются в стандартных позициях курсора.


Средний уровень.


В этом примере рисуется фигура человека, занимающая 2 символа

в высоту и 2 символа в ширину. Как объяснено в [4.3.4] вектор

прерывания 1FH указывает на начало области данных, определяющих

символы. Четыре символа могут быть выведены обычными процедурами

DOS или BIOS. Легко создать другой набор символов, для вывода

фигуры с руками и ногами в другом месте экрана. Два набора симво-

лов могут поочередно меняться в соседних позициях курсора, созда-

вая иллюзию человека, идущего по экрану.


;---в сегменте данных

CHARACTER_DATA DB 00110000B ;левый верхний квадрант

DB 01100111B

DB 01100111B

DB 00110011B

DB 00011111B

DB 00001111B

DB 00001111B

DB 00000111B


DB 00000011B ;правый верхний квадрант

DB 10001100B

DB 10011000B

DB 00110000B

DB 11100000B

DB 11000000B

DB 11000000B

DB 10000000B


DB 00001111B ;левый нижний квадрант

DB 00011111B

DB 00011100B

DB 00011000B

DB 00011000B

DB 00110000B

DB 01100000B

DB 00010000B



DB 11000000B ;правый нижний квадрант

DB 11000000B

DB 11000000B

DB 11000000B

DB 01100000B

DB 01100000B

DB 00010000B

DB 00011110B

DB 00000000B


;---установка вектора прерывания

PUSH DS ;сохраняем DS

MOV DX,OFFSET CHAR_DATA ;смещение для данных в DX

MOV AX,SEG CHAR_DATA ;сегмент для данных в DS

MOV DS,AX ;

MOV AH,25H ;функция установки вектора

MOV AL,1FH ;номер вектора

INT 21H ;устанавливаем вектор

POP DS ;восстанавливаем DS


;---рисуем фигуру

;---позиционируем курсор на верхний ряд

MOV AH,2 ;функция установки курсора

MOV DH,13 ;строка 13

MOV DL,20 ;столбец 20

MOV BH,0 ;страница 0

INT 10H ;установка курсора

;---рисуем верхние два символа

MOV DL,128 ;берем символ 128

MOV AH,2 ;функция вывода/курсор вперед

INT 21H ;вывод символа

MOV DL,129 ;берем символ 129

INT 21H ;выводим его

;---позиционируем курсор на нижнюю строку

MOV DH,14 ;строка 14

MOV DL,20 ;столбец 20

MOV AH,2 ;функция установки курсора

INT 10H ;устанавливаем курсор

;---рисуем нижние два символа