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

Универсальная процедура построения рисунка

В данном разделе описана универсальная процедура построения рисунка формата BMP, использующего палитру цветов. Двухцветные и 16-цветные рисунки хранятся в упакованном виде, поэтому процедура выбирает нужную подпрограмму для их распаковки. Будем так же считать, что в зависимости от размера файла выбираются подпрограммы из примеров А.9 или А.10.

Текст процедуры приведен в примере А.11, программы описаны ниже.

Пример А.11. Начало построения рисунка формата BMP.

BmpShow: lea bx, mode_8; bx = адрес подпрограммы mode_8
cmp bitcnt, 08; bitcnt = 8?
je @F; › да, переход на локальную метку
lea bx, mode_4 bx = адрес подпрограммы mode_4
cmp bitcnt, 04 bitcnt = 4?
je @F › да, переход на локальную метку
lea bx, mode__2 bx = адрес подпрограммы mode_2
@@: mov ax, fwidth ax = fwidth, размер строки в файле
mul iheight dx:ax = fwidth*iheight
or dx, dx образ рисунка помещается в сегменте?
jne @F › нет, файл большого размера
mov si, ax si = размер образа рисунка
jmp Smlbmp переход на Smlbmp
@@: jmp BigBmp переход на BigBmp

Для того чтобы выполняемые в примере А.11 действия имели смысл, в текстах примеров А.9 и А.10 надо заменить call drawiine на call bx, как указано в комментарии. Первые 7 команд примера А. 11 формируют в bх адрес подпрограммы обработки строки (примеры А.12-А.14), в зависимости от размера кода точки образа рисунка. После этого вычисляется размер образа рисунка, и если он помещается в одном сегменте (dx=o), то выбирается подпрограмма Smlbmp, в противном случае BigBmp.

Таким образом, для построения рисунка формата BMP задача должна обращаться к процедуре BmpShow, как к подпрограмме. Перед ее вызовом в регистре di указывается адрес левого верхнего угла рисунка в видеопамяти и устанавливается окно, которому принадлежит этот адрес. Регистр es должен содержать код видеосегмента (хранящийся в vbuff).

Подпрограммы обработки строк

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

В примере А.12 приведена подпрограмма, выполняющая построение строки рисунка, у которого код точки занимает 1 байт. Ее отличие от описанных ранее вариантов только в том, что для записи кода точки вызывается вспомогательная подпрограмма outpnt.

Пример А.12. Вывод строки формата 8 бит на точку (256 цветов).

mode_8: lods byte ptr f s:[si]; al = код очередной точки
call outpnt; обращение к подпрограмме записи
loop mode_8; управление повторами цикла
ret; возврат из подпрограммы

В примере А.13 приведен текст подпрограммы, выполняющей распаковку точек 16-цветного рисунка в процессе построения строки.

Пример А.13. Вывод строки формата 4 бита на точку (16 цветов).

mode 4: lods byte ptr fs: [si] al = код очередных 2-х точек
push ax сохраняем содержимое ах
shr al, 04 выделяем код старшей тетрады
call outpnt обращение к подпрограмме записи
pop ax. восстанавливаем содержимое ах
dec ex сх = сх – 1, счетчик точек в строке
je @F › все точки выведены
and al, OFh выделяем код младшей тетрады
call outpnt обращение к подпрограмме записи
loop mode 4 управление повторами цикла
§@: ret возврат из подпрограммы

Сравните текст примера А.13 с текстом подпрограммы drwiin4 (см. Пример 3.17). В данном случае он упростился за счет использования вспомогательной подпрограммы outpnt.

Замечание
Напомним, что дополнительная коррекция и проверка значения счетчика повторов цикла (сх) нужна потому, что при нечетном количестве точек в рисунке последний байт содержит код только одной точки (младшую тетраду выводить на экран нельзя)
.

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