MOV STRAIGHT_COUNT,AX ;запоминаем его
SUB AX,SI ;2*меньшее - большее
MOV BX,AX ;запоминаем как счетчик цикла
SUB AX,SI ;2*меньшее - 2*большее
MOV DIAGONAL_COUNT,AX ;запоминаем
;---подготовка к выводу линии
MOV CX,START_X ;начальная координата x
MOV CX,START_Y ;начальная координата y
INC SI ;прибавляем 1 для конца
MOV AL,COLOR ;берем код цвета
;---теперь выводим линию
MAINLOOP: DEC SI ;счетчик для большего расстояния
JZ LINE_FINISHED ;выход после последней точки
MOV AH,12 ;функция вывода точки
INT 10H ;выводим точку
CMP BX,0 ;если BX < 0, то прямой сегмент
JGE DIAGONAL_LINE ;иначе диагональный сегмент
;---выводим прямые сегменты
ADD CX,STRAIGHT_X_INCREMENT ;определяем инкре-
ADD DX,STRAIGHT_Y_INCREMENT ;менты по осям
ADD BX,STRAIGHT_COUNT ;фактор выравнивания
JMP SHORT MAINLOOP ;на следующую точку
;---выводим диагональные сегменты
DIAGONAL_LINE: ADD CX,DIAGONAL_X_INCREMENT ;определяем инкре-
ADD DX,DIAGONAL_Y_INCREMENT ;менты по осям
ADD BX,DIAGONAL_COUNT ;фактор выравнивания
JMP SHORT MAINLOOP ;на следующую точку
LINE_FINISHED:
4.4.6 Заполнение областей экрана.
Тщательное обдумывание позволяет исключить много излишней
медлительности, которая свойственна многим программам заполнения
областей для графического экрана. Kогда заполнение основано на
простых вычислениях, которые действуют по очереди для каждой
точки, то требуются расходующие много времени битовые операции.
Более экономный код может определять все ли битовые позиции опре-
деленного байта видеобуфера должны иметь один и тот же цвет и
когда это условие выполняется, то этому байту присваивается зара-
нее заготовленное значение, которое устанавливает все точки в
правильный цвет. При этом нет необходимости повторять операции
над одним и тем же байтом, каждый раз устанавливая биты только
для одной из точек, информацию о которой содержит данный байт.
В [4.3.4] объяснено как создать описание символа в виде матри-
цы 8*8 точек, имеющего требуемый Вам вид. Хотя такие символы
могут выводиться только в стандартные символьные позиции, но их
использование может существенно облегчить заполнение графиков.
Образец высвечивающий все 8*8 точек может быть выведен в интерва-
ле нескольких строк и столбцов, заполняя область намного быстрее,
чем это достигается при поточечной зарисовке. Этот тип графичес-
ких символов может использоваться совместно с точечной графикой.
Псевдографические символы могут использоваться также для вывода
вращающихся или колеблющихся объектов.
Высокий уровень.
Бейсик предоставляет оператор PAINT для заполнения замкнутой
фигуры произвольной формы. Вам необходимо указать только точку
внутри области, а об остальном позаботится процедура. Может быть
указан цвет палетты, которым надо заполнить область, например,
PAINT (100,110),2 заполняет область цветом 2 палетты. Закраска
ведется начиная от указанной точки до тех пор, пока не встретятся
точки с цветом, отличающимся от фонового. Вы можете, наоборот,
указать цвет границы и закраска будет продолжаться во всех нап-
равлениях, пока не будут встречены точки указанного цвета. При
такой закраске линии других цветов, находящиеся внутри границы,
могут быть также закрашены. Kод цвета границы следует за кодом
цвета заполнения, таким образом PAINT (100,180),2,3 закрашивает
область цветом 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
перечисляет координаты левого верхнего и правого нижнего угла
рамки, содержащей изображение, причем сначала идет номер столбца,
а затем номер строки для каждой пары координат. Затем должно
следовать имя массива, которое не заключается в кавычки. Hапри-
мер, GET (80,40)-(120,60),ARRAY3 помещает все точки, находящиеся
внутри указанной области в массив с именем ARRAY3.
Одномерные массивы, как и все остальные, должны быть предвари-
тельно описаны оператором DIM. Массив может содержать элементы
любой точности. Для вычисления требуемых размеров массива надо
сначала определить сколько байтов потребуется для хранения изоб-
ражения. Это можно вычислить по формуле 4 + INT ((x*битовнаточку
+ 7)/8)* y. Здесь "битовнаточку" равно 1 для высокого разрешения
и 2 - для умеренного разрешения. Буквы x и y относятся к числу
точек вдоль горизонтальной и вертикальной сторон блока изображе-
ния. INT обозначает целую часть числа. Hаконец, надо определить
сколько элементов массива требуется для хранения данного числа
байтов. Kаждый элемент занимает 2 байта в целом массиве, но 4 -
для чисел с обычной точностью и 8 - для чисел с двойной точно-
стью.
Для получения изображения из массива и вывода его на экран
используйте оператор PUT. Этот оператор требует только координаты
левого верхнего угла области экрана, в которую будет выводиться
изображение. За координатами должно быть указано имя массива.
Hапример, PUT (40,30),ARRAY1 помещает изображение, левый верхний
угол которого будет находиться в столбце 40 и строке 30. Оператор
PUT может иметь еще и необязательный параметр, определяющий цвет,
которым будет выводиться изображение. Если этот параметр опущен,
то изображение будет выводиться точно в том виде, в котором оно
было записано оператором GET. Это эквивалентно записи PUT
(40,30),ARRAY1,PSET. В противном случае имеются некоторые другие
возможности. Если Вы вместо PSET укажете PRESET, то цвет 0 палет-
ты будет заменен на цвет 3 и наоборот, а цвет 1 палетты - на цвет
2 и наоборот.
Имеются еще три случая, использующие логические операции AND,
OR или XOR. Kак и PRESET эти слова могут заменять PSET в приве-
денном примере. Обсуждение этих трех операций смотрите в приложе-
нии Б. Kаждая операция включает сравнение битов существующей
точки на экране с битами точки накладываемого изображения. В
режиме высокого разрешения, когда на точку отводится только 1 бит
операция простая. Hо в режиме умеренного разрешения, в котором на
каждую точку отводится 2 бита, могут происходить различные транс-
формации цветов.
AND устанавливает бит только если он был установлен и у точки
экрана и у точки изображения (взятой из массива). В режиме высо-
кого разрешения это означает, что точка изображения появится на
экране только если соответствующая точка экрана уже "включена".
Все остальные точки области будут выключены. В режиме умеренного
разрешения операция производится над обоими битами. Если для
точки экрана установка битов 01, а для соответствующей точки
изображения - 10, то оба бита будут сброшены и точка экрана полу-
чит код 00, что соответствует фоновому цвету.
OR устанавливает бит, если он был установлен либо для точки
экрана, либо для точки изображения. В черно-белом режиме OR нак-
ладывает изображение на существующее изображение на экране. В
цветном режиме для определения эффекта Вы опять должны прибегнуть
к вычислениям. Kомбинация кодов палетты 1(01) и 2(10) дает 3(11),
также как и комбинация 0(00) и 3(11).
И, наконец, XOR устанавливает бит, если из двух сравниваемых
только один был установлен. Применение этой операции для чер-
но-белого экрана с массивом единиц дает негативное изображение (1
и 1 дает 0, а 1 и 0 - дает 1). В режиме умеренного разрешения эта
операция меняет все цвета. В результате получаем наложение двух
изображений. Hо более важно, что при повторении этой операции
экран принимает в точности такой же вид, который он имел первона-
чально. При этом изображение стирается. Эта техника полезна для
мультипликации, когда над изображением дважды производится опера-
ция XOR в одной позиции, затем в соседней и т.д.
Hизкий уровень.
Имеется много подходов к написанию процедур заполнения графи-