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

Построение рисунков с использованием палитры

Построение большого рисунка

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

Измененный текст приведен в примере 7.24. Напомним, что в этом случае при вызове явно указывается только адрес начала рисунка в видеопамяти (в регистре di). Размеры рисунка подпрограмма выбирает из переменных iheight и iwidth. Как обычно, должно быть установлено исходное окно видеопамяти, а в регистре es указан код видеосегмента (обычно А000h).

Пример 7.24. Построение рисунка из файла произвольного размера.

BigDraw: pusha сохраняем стандартные регистры
PushReg <fs, gs, CL г win>; сохраняем fs, gs и Cur win
mov fs, SwpSeg fs = сегмент буфера обмена
mov gs, GenSeg gs = сегмент таблицы цветов
mov SwpOffs, 0 нулевой адрес в буфере обмена
xor dx, dx старшая часть делимого dx=0
mov ax, – 1 младшая часть делимого ах=65535
div iwidth ах = 65535 / iwidth
mov part, ax число строк в порции для чтения
mul iwidth количество байтов в порции для чтения
mov nurnbyte, ex сохраняем его в numbyte
mov ax, iheight копируем количество строк в рисунке
mov remline, ax в счетчик не выведенных строк
mov dx, iwidth dx = iwidth, ширина рисунка
call calloffs вычисляем константу переадресации
NewPart: mov ex, numbyte размер порции для чтения
call readf чтение очередной порции данных
jnc sucread › чтение без ошибок
; Здесь должны выполь яться действия в случае ошибки чтения
sucread: mov ex, part ex = стандартное количество строк
cmp remiine, ex осталось меньше строк?
jae lbl_l › нет, обходим команду пересылки
mov ex, remiine сх = оставшееся число строк
1Ы 1: sub remiine, ex уменьшаем оставшееся число строк
xor si, si адрес начала в буфере обмена
drwout: push ex сохраняем счетчик повторов
mov ex, dx задаем размер строки рисунка
call drawline построение очередной строки
pop ex восстанавливаем счетчик повторов
add di, bx адрес начала следующей строки
jnc @F › адрес в пределах сегмента
call NxtWin установка следующего окна
@@: loop drwout управление повторами цикла
cmp remiine, 0 все строки выведены?
jne NewPart › нет, продолжаем построение
PopReg <Cur win, js, fs>; восстановление Cur win, gs и fs
popa восстановление всех регистров
call setwin восстановление исходного окна
ret возврат из подпрограммы

По сравнению с оригиналом (см. пример 3.22), текст примера 7.24 изменился в той части, где выполняются подготовительные действия. Добавилось сохранение в стеке содержимого регистра gs и запись в него кода сегмента, содержащего таблицу цветов, а для вычисления константы переадресации строк видеопамяти вызывается подпрограмма calioffs. В заключительной части примера добавилось восстановление из стека исходного содержимого gs.

Цикл построения рисунка не изменился, но имя drawline соответствует другой подпрограмме построения строки, поскольку нужна перекодировка точек по таблице цветов.

Учет лишних байтов

В примерах 7.23 и 7.24, так же, как и в примерах 3.21 и 3.22, предполагается, что строки образа рисунка расположены в файле подряд друг за другом. На практике это не всегда так. По разным причинам к каждой строке может быть добавлено некоторое количество байтов, содержимое которых не определено и их нежелательно записывать в видеопамять.

В указанных примерах вывод "лишних" байтов исключен, поскольку обрабатывается ровно столько точек, сколько их содержится в строке. Однако в них отсутствует пропуск "лишних" байтов в строке образа рисунка. Если таковые имеются, то построенное изображение будет искажено.

Способ определения наличия дополнительных байтов зависит от особенностей формата (или стандарта), которому соответствует файл, содержащий образ рисунка. Общих правил не существует. Как это делается при работе с файлами формата BMP, подробно описано в Приложении А.

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