Справочник программиста на персональном компьютере фирмы 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] и выводе их на границе области  заполне-
ния.  Короче, в данной области Вы имеете все возможности проявить
сообразительность,  а  зачастую  стоит подумать, а нужна  ли  Вам
столь сложная графика в данной задаче.