На главную страницу
Форум txt.version   




Статья :: SVGA Немаскируемый курсор
 

Немаскируемый курсор

При построении обычных рисунков их образы копируются в видеопамять, но если таким способом построить рисунок, образ которого приведен в примере 6.3, то изображение белой стрелки будет расположено на фоне черного прямоугольника. Очевидно, что работать с подобным изображением

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

Один из таких способов мы уже использовали при построении текстового курсора, он описан в разделе, пример 5.24. Здесь нас интересует более универсальный вариант подобной подпрограммы, позволяющий строить изображение курсора произвольного размера и формы. Для записи кодов точек в видеопамять, по-прежнему, будет использоваться логическая операция XOR, вычисляющая функцию "исключающее ИЛИ" (exclusive OR).

Предварительные замечания

Образ рисунка курсора можно хранить в любом сегменте оперативной памяти. Учитывая его небольшой размер (294 байта). мы будем считать, что он расположен в сегменте данных (см. пример 6.3) и имеет имя pntimage. Маска при построении не используется, поэтому массив pntmask нас в данном случае не интересует.

Учитывая, что размеры рисунка не фиксированы и зависят от его формы, в разделе данных задачи надо описать две следующие переменные:

PntXsize dw 14 ; количество точек в строке рисунка курсора
pntYsize dw 21 ; количество строк в рисунке курсора

В приведенном описании значения переменных соответствуют размерам рисунка, показанного в примере 6.3.

Курсор является особым рисунком, его координаты в видеопамяти могут использоваться в различных целях. Поэтому они хранятся в специальных переменных, значение которых может изменяться только при перемещении манипулятора "мышь". В примере 6.8 будет описано несколько переменных, используемых при работе с курсором. Здесь нас интересуют только две из них. Переменная winpnt содержит текущее окно видеопамяти, a offspnt - адрес (смешение) точки левого верхнего угла рисунка курсора в этом окне.

Подпрограмма Tglpntr

Текст подпрограммы, изменяющей состояние курсора на противоположное, приведен в примере 6.4. При каждом нечетном вызове Tglpntr рисунок курсора появляется на экране, а при каждом четном на ею месте восстанавливается исходный фон. Явно задаваемые входные параметры отсутствуют. Регистр es должен содержать код видеосегмента.

Пример 6.4. Подпрограмма переключения состояния курсора

Tglpntr: pusha сохранение содержимого регистров
push Cur_win сохранение исходного окна
ir.ov ax, Winpnt ax = окно с рисунком курсора
mov Cur_win, ax Cur_win = Winpnt
call setwin установка исходного окна
lea si, pntimage si = адрес массива pntimage
mov di, Offspnt di = адрес Е сегменте видеопамяти
mov ex, pntYsize ex = кол-во повторов внешнего цикла
mov bx, horsize вычисляем константу для
sub bx, pntXsize коррекции адресов строк
Displ 1 : push ex сохраняем счетчик строк
mov ex, pntXsize сх = количество точек в строке рисунка
Displ 2: lodsb ! ! al = код очередной точки рисунка
xor es : [di] , al ! ! корректируем байт видеопамяти
inc di ! ! увеличение адреса видеопамяти
jnz @F -> адрес в пределах текущего сегмента
call nxtwin конец сегмента, смена окна
@@: loop Displ 2 управление повторами цикла
pop ex восстанавливаем счетчик строк
add di , bx адрес начала следующей строки
jnc @F -> адрес в пределах текущего сегмента
call nxtwin конец сегмента, смена окна
@@: loop Displ 1 управление повторами цикла
pop Cur win восстановление Cur win
popa восстановление содержимого регистров
call setwin восстановление исходного окна
ret возврат из подпрограммы

В подпрограмме примера 6.4 используется только 5 регистров - ах, bх, сх, si и di, но для сокращения ее текста первая команда pusna сохраняет в стеке содержимое всех регистров. Затем в стек помещается исходное значение переменной Cur win, а ей присваивается новое значение и устанавливается соответствующее окно видеопамяти. В регистры si, di записываются адреса оперативной и видеопамяти, а в сх - количество строк в рисунке курсора. В конце подготовки в регистре bх формируется разность horsize - pntxsize, используемая в цикле построения для коррекции адресов строк видеопамяти.

Построение рисунка выполняют два вложенных цикла. Внешний имеет метку oispi_i. Он начинается с сохранения в стеке и изменения содержимого регистра сх, после чего выполняется внутренний цикл.

Цикл построения строки имеет метку Dispi_2. Его первая команда lodsb считывает в регистр al байт, адрес которого находится в dsrsi, и увеличивает содержимое регистра si на 1. Затем логическая операция XOR записывает содержимое регистра al в видеопамять. Регистр-посредник al нужен потому, что у команды хог (как и у команды mov) оба операнда не могут находиться в памяти.

После вывода очередной точки адрес видеопамяти увеличивается на 1, и если его значение осталось в пределах сегмента, то команда jnz @F обходит call nxtwin. В противном случае команда call nxtwin выполняется и устанавливается следующее окно. Последняя команда (loop Disp_2) повторяет выполнение цикла до тех пор, пока не будет нарисована вся строка.

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

После построения (или удаления) курсора из стека выталкивается содержимое переменной cur_wir. и всех сохраненных регистров, восстанавливается исходное окно видеопамяти и происходит возврат на вызывающий модуль.

Недостатки немаскируемого курсора

чевидными преимуществами работы с немаскируемым курсором являются следующие:

  • для построения и удаления курсора нужна одна подпрограмма;
  • подпрограмма выполняется сравнительно быстро;
  • в оперативной памяти хранится только образ рисунка.

Однако такой способ построения имеет один существенный недостаток, сводящий на нет перечисленные преимущества.

Идея использования немаскируемого курсора основана на том, что при определенных значениях операнда-источника команда хог инвертирует код операнда-приемника или не изменяет его (см. раздел). В описанной подпрограмме источником являются точки заготовки рисунка, а приемником - точки видеопамяти. Образ рисунка черно-белый, коды его точек имеют значения либо 00, либо 0FFh. Поэтому при построении рисунка цвета точек экрана, расположенных под стрелкой, инвертируются, а окружающих стрелку не изменяются. Таким образом, цвет рисунка немаскируемого курсора на экране зависит от исходного цвета точек в том месте экрана, на котором он создается.

Вспомним табл. 4.1 из главы 4. При ее описании говорилось, что два цвета являются дополнительными, если при их наложении получается белый цвет. В частности, дополнением к черному цвету является белый, к синему - желтый, к красному - циан, к зеленому - мажента. Исходя из этого, можно представить, как изменяется цвет курсора в зависимости от исходного цвета точек экрана. Если же на экране находится какая-то картинка, т. е. цвет экрана не однороден, то и изображение курсора будет неоднородным. На пестром фоне оно может "потеряться" - стать трудно различимым для глаза.

При работе в режимах PPG описанная подпрограмма инвертирует не код цвета, а номер регистра видеокарты. Полученный при инверсии цвет будет зависеть от установленной (системной) палитры. Эта особенность успешно использовалась, например, в ранних версиях Windows - системная палитра подбиралась так, чтобы можно было использовать немаскируемый курсор.

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

 

SVGA Немаскируемый курсор

страницы в данном разделе 
 SVGA Глава 6. Курсор и мышь  SVGA Курсор и мышь
 SVGA Построение рисунка курсора  SVGA Курсоры для Windows
 SVGA Предварительная подготовка рисунка  SVGA Немаскируемый курсор
 SVGA Маскируемый курсор  SVGA Замечания к описанным подпрограммам
 SVGA Подготовка к работе с манипулятором  SVGA Общее описание драйвера мыши
 SVGA Предварительные действия  SVGA Работа в режиме опроса драйвера мыши
 SVGA Управляющий алгоритм для режима опроса  SVGA Формирование кодов событий
 SVGA Управление перемещением курсора  SVGA Работа в режиме прерываний
 SVGA Функции драйвера  SVGA Примеры прерывающих подпрограмм


Разделы
Околокомпьютерная литература (375)
Программирование (102)
Программы (75)
ОС и Сети (49)
Интернет (29)
Аппаратное обеспечение (16)
Базы данных (6)
Flutter
React Native
Xamarin

Содержание сайта (выборка)
Apache
Протоколы TCP/IP (принципы, протоколы и архитектура)

PHP, PELR, JSP
PHP
JavaServer Pages (JSP)

Базы данных
Основы mysql
СУБД INFORMIX
СУБД POSTGRES
Основы проектирования реляционных баз данных

HTML, javascript
Спецификация HTML 4.01
Каскадные Таблицы Стилей, Уровень 2
Клиентский JavaScript. Справочник.
JavaScript руководство пользователя
Серверный JavaScript 1.4. Руководство по Использованию.

Паскаль, C, C++, C#
GCC (примеры)
FAQ Валентинa Озеровa DELPHI
C





 
©  programming-lang.com  справочник программиста
©  http://ekb.programming-lang.com/tlg/  бесплатный телеграм бот
©  http://ekb.programming-lang.com/tlg/  бесплатный телеграм бот
React Native
demo forum