Справочник программиста на персональном компьютере фирмы IBM. Вывод на терминал - Заполнение областей экрана. Часть 2
ОГЛАВЛЕНИЕ
Для получения изображения из массива и вывода его на экран
используйте оператор 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] и выводе их на границе области заполне-
ния. Короче, в данной области Вы имеете все возможности проявить
сообразительность, а зачастую стоит подумать, а нужна ли Вам
столь сложная графика в данной задаче.