Иллюстрированный самоучитель по SVGA

Рисунки, не использующие палитру. Рисунки, подготовленные в стандарте BMP.

Выполнение примера 7.25 начинается с сохранения в стеке содержимого "всех" регистров. Команда pusha не сохраняет сегментные регистры, поэтому содержимое fs и переменной cur_win сохраняет макровызов pushReg.

Для чтения данных вызывается подпрограмма Readf, текст которой приведен в примере 3.23. Она размещает данные в буфере обмена, начиная с адреса, указанного в swpoffs. Для максимального использования пространства буфера эта переменная предварительно очищается, а в регистр fs записывается сегмент буфера обмена из SwpSeg.

После этого выполняются подготовительные действия, смысл и назначение которых описаны выше. Три первые команды вычисляют константу для коррекции адресов строк, ее значение помещается в регистр bx и используется в основном цикле. Следующие восемь команд формируют значения переменных fwidth и rmndr. Затем шесть команд вычисляют значения переменных part и numbyte. Последние десять команд формируют адрес начала последней строки рисунка в видеопамяти и устанавливают окно, которому он принадлежит.

Основной цикл имеет метку NewPart. Он практически совпадает с одноименным циклом примера 7.24. Отличие заключается в следующем. При переадресации строк видеопамяти вычисляется адрес начала предыдущей строки, поэтому содержимое регистра bx вычитается из содержимого регистра di, а в случае переполнения результата вычитания устанавливается предыдущее окно видеопамяти. Кроме того, для исключения "лишних" точек адрес буфера обмена, хранящийся в регистре si, увеличивается на величину rmndr. Ну и, конечно же, имя drawiine соответствует разным подпрограммам.

Подпрограммы для построения строк

В отличие от основного текста примера 7.25, тексты подпрограмм построения строк существенно зависят от установленного задачей видеорежима. Это связано с необходимостью преобразования исходного формата bgr в формат Hi-color или True Color. Варианты подпрограмм для обоих режимов показаны в примере 7.26.

Пример 7.26. Варианты подпрограммы построения строки.

; Вариант 1 для работы в режимах True Color
drawline: movs word ptr [di], f s: [si]; копируем коды синего и зеленого
lods byte ptr fs:[si]; al = код красного цвета
xor ah, ah очистка резервного байта
stosw записываем старшее слово кода
or di, di адрес в пределах сегмента?
jnz @F › да, обход команды
call NxtWin установка следующего окна
@@: loop drawline управление повторами цикла
ret возврат из подпрограммы
; Вариант 2 для работы в 15-разрядных режимах Hi-Color
drawline: mov al, fs:[si+2] читаем код красного цвета в
al shr al, 03 сокращаем его до 5-ти разрядов
mov bh, fs:[si+1] читаем код зеленого цвета в
bh shld ax, bx, 05 добавляем в ах код зеленого цвета
mov bh, f s:[si] читаем код синего цвета в
bh shld ax, bx, 05 сдвигаем и дополняем код в
ах add si, 03 добавляем в ах код синего цвета
stosw записываем код в видеопамять
or di, di адрес в пределах сегмента?
jnz @F › да, обход команды
call NxtWin установка следующего окна
@@: loop drawline управление повторами цикла
ret возврат из подпрограммы

В предыдущих разделах описано преобразование цветов, хранящихся в палитрах, в форматы Hi-color и True Color. Отличие рассмотренного здесь случая в том, что исходные цвета расположены не в палитре, а в строке образа рисунка, находящейся в буфере обмена. Поэтому первый вариант примера 7.26 является циклом примера 7.19, а второй вариант примера 7.26 является циклом примера 7.18.

Таким образом, при построении полноцветных рисунков формата BMP текст основной подпрограммы не зависит, а вспомогательной (drawline) зависит от видеорежима. Исключить эту зависимость невозможно, но при использовании директив условного ассемблирования можно задавать признак для выбора нужной подпрограммы.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.