Графические устройства

         

Замечания к описанным подпрограммам

В двух предыдущих разделах описаны действия, которые надо выполнить для построения или удаления изображения курсора. Здесь мы рассмотрим, как изменяются команды, выполняющие эти действия в зависимости от тех или иных дополнительных условий. Нас будут интересовать способы ускорения работы с курсором и построения изображения в режимах direct color, когда цвет указывается непосредственно в коде точки.

Ускорение работы с курсором. Курсор является основным средством управления процессом выполнения графических задач. Чем меньше времени затрачивается на перемещение его рисунка, тем больше времени остается на выполнение основных действий. Поэтому ускорение манипуляций с курсором представляет определенный практический интерес.

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

В подпрограмме Hidepnt (пример 6.6) основное действие выполняет одна команда n\ovsb (ее метка hid_2), поэтому в этом случае применимы способы ускорения построения строк, описанные в разделе. В частности, вместо внутреннего цикла можно использовать подпрограмму


примера 3.16, внеся в нее незначительные изменения.

К подпрограммам Tgipntr (см. пример 6.4) и showpnt (см. пример 6.5) описанные в разделе способы ускорения не применимы, поскольку в них основные действия выполняют несколько (2 или 5) команд.

На первый взгляд достаточно просто изменить основные команды так, чтобы они оперировали не с байтами, а со словами или двойными словами, т. е. обрабатывали коды сразу двух или четырех точек. В первом случае количество повторов внутреннего цикла сократится в 2, а во втором — . в 4 раза. Перед входом в цикл содержимое регистра ex (pntxsize) надо уменьшить, соответственно, в 2 или в 4 раза.

Такая замена дает нужный результат, но необходимы дополнительные меры защиты от возможной аварийной ситуации. Давайте разберемся в причине ее возникновения.

Курсор может находиться в любом месте экрана, поэтому вполне вероятно, что одна из строк его изображения расположится в смежных окнах видеопамяти. Если при этом первая точка строки имеет нечетный адрес в видеопамяти, то обрабатывать одной командой сразу две точки такой строки нельзя. При чтении или записи одной из пар точек первый байт операнда окажется в пределах, а второй за пределами текущего сегмента. Это одна из типичных аварийных ситуаций, чаще всего она приводит к тому, что на программистском жаргоне называется "компьютер завис", т. е. он не реагирует ни на какие внешние события, кроме выключения питания.

Для исключения аварийной ситуации можно, например, сделать так, чтобы при работе с курсором адрес его начала в видеопамяти всегда был четным. Изображение курсора следует за манипулятором "мышь". Если при опросе состояния последнего окажется, что он находится в столбце с нечетным номером, то этот номер принудительно делается четным. Такой трюк уменьшает точность позиционирования курсора на экране, поэтому вам придется выбирать меньшее из двух зол. К вопросу о точности позиционирования мы вернемся при описании программирования работы с мышью.

Таким образом, при некотором ограничении точности позиционирования выполнение подпрограмм Tgipntr и showpnt можно ускорить в 2 раза, внеся в них описанные выше изменения. Более существенное ускорение связано со значительным увеличением размеров текстов подпрограмм и едва ли целесообразно.

Изменения для режимов direct color. Подробному описанию особенностей программирования для видеорежимов с указанием цвета в коде точки посвящена главы 7. Здесь мы только покажем, какие изменения надо внести в описанные подпрограммы для их использования при работе в режимах direct color. Это позволит в дальнейшем не повторять описание способов построения курсора. Вы можете пропустить эту часть раздела и вернуться к ней после прочтения главы 7.

В режимах PPG код точки является номером регистра цвета видеокарты, а в режимах direct color он является кодом конкретного цвета и занимает 16 разрядов в режиме Hi-Color и 32 разряда в режиме True color.

Прежде всего, вам придется изменить заготовку рисунка и маску, которые хранятся в массивах pntimage и pntmask (см. пример 6.3).

Проще всего изменить описание маски и черно-белого рисунка курсора. В пояснениях к примеру 6.3 мы советовали при его использовании в конкретной программе заменить все коды OFF десятичным числом -1. Если вы это сделали, то остается только заменить все директивы db на dw для режима Hi-coior или на dd для True color. Макроассемблер зарезервирует требуемое пространство памяти и заменит число — 1 кодами OFFFFh или OFFFFFFFFII, в зависимости от указанной директивы (dw или dd).

Изменить описание цветного рисунка курсора сложнее, в этом случае недостаточно простой замены директив db на dw или dd. У заготовок цветных рисунков распакованный код точки является порядковым номером строки палитры, хранящейся вместе с рисунком. По коду точки надо выбрать из палитры код цвета, преобразовать его в нужную форму и поместить в описание рисунка. Такое преобразование делается программно, а не вручную. В главе 7 описаны способы преобразования рисунков из формата PPG в форматы direct color, их и можно использовать. Однако на первое время лучше ограничиться черно-белым курсором, а к работе с цветным перейти позже, по мере накопления опыта программирования графики.

В режимах direct color размеры массивов pntimage и pntmask увеличивают-ся в 2 или в 4 раза, во столько же раз надо увеличить размер массива pntbuff. Это можно сделать одним из двух способов: заменить в его описании директиву db на dw или dd, либо оставить директиву db, а количество резервируемых байтов умножить на 2 или на 4.

Изменения в текстах подпрограмм примеров 6.4, 6.5 и 6.6 связаны только с увеличением размера кода точки в 2 (режим Hi-Color) или 4 (режим True color) раза. Прежде всего, нужно увеличить значение константы, которая используется для коррекции адресов строк. Во всех примерах ее вычисляют две следующие команды:

mov bx, horsize ; вычисляем константу для sub bx,
pntXsize ; коррекции адресов строк

После них надо записать третью команду, сдвигающую содержимое регистра bх на один (shi bx, i) или на 2 (shi bx, 2) разряда влево. Значение константы увеличится, соответственно, в 2 или в 4 раза.

Остальные изменяемые команды расположены во внутренних циклах. Комментарий к ним начинается с двух восклицательных знаков. Изменения этих команд делятся на следующие три категории:

  • у строковых команд lodsb, stosb и movsb последняя буква (b) заменяется буквами w (Hi-Color) или d (True Color);
  • если один из операндов команды находится в регистре ai, то имя регистра надо изменить на ах (Hi-Color) ИЛИ на еах (True Color);
  • команды inc di и inc si увеличивают значение адреса на 1. Они заменяются командой сложения (add), которая прибавляет к регистру число 2 (Hi-Color) или 4 (True Color).

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

Промежуточные итоги

При программировании конкретной задачи важно не только составить нужную подпрограмму, но и корректно ее использовать. Применительно к нашему случаю это означает следующее:

  1. 1. При выводе изображения курсора на экран вы должны быть уверены в том, что его там уже нет, в противном случае на экране может оказаться несколько изображений курсоров или будет испорчен фон, сохраненный при выводе предыдущего изображения. Такая уверенность есть при первом выводе курсора в начале выполнения задачи, но после этого задача должна контролировать его текущее состояние.
  2. 2. Перед удалением курсора также надо убедиться в том, что он находится на экране, а исходный фон сохранен в массиве pntbuff. В противном случае при попытке удалить курсор на экране появится прямоугольник, цвет и узор которого не соответствует ожидаемым.

При организации работы с текстовым курсором в разделах Текстовый курсор в графическом режиме и Ввод символов с клавиатуры мы использовали специальный признак, указывающий текущее состояние текстового курсора. Работа с графическим курсором имеет специфические особенности, а способы определения его текущего состояния зависят от того, как задача получает данные от манипулятора "мышь".

Если текущее положение манипулятора задача определяет в режиме опроса, то специальный признак состояния курсора не нужен,- оно определяется логикой выполняемых действий. Однако если задача взаимодействует с манипулятором в режиме прерываний, то без указанного признака не обойтись. Подробное обсуждение этих вопросов будет производиться в процессе описания программирования работы с манипулятором "мышь", к которому мы и переходим.


Содержание раздела