Манипуляции с палитрой цветов
Пополнение системной палитры
Вместо простой установки палитры добавляемого рисунка она размешается в системной палитре. При этом код каждого добавляемого цвета последовательно сравнивается с кодами всех цветов, находящихся в системной палитре. Отсутствующий цвет помещается в первую свободную строку системной палитры, а значение переменной numcol увеличивается на 1. В результате будут добавлены только те цвета, которых не было раньше. Если в добавляемой палитре повторится один и тот же цвет (такое бывает), то в системную палитру он будет включен только один раз.
Рассмотрим конкретный пример. Предположим, что после инициализации системной палитры на экран выводится рисунок, использующий стандартную для Windows 3Х 16-цветную палитру. При ее добавлении в системной палитре появятся 14 новых цветов, поскольку черный и белый там уже находились. Теперь при добавлении на экран любого количества рисунков, использующих 16-цветную палитру Windows, системная палитра не изменяется. В этом случае эффективность описанного алгоритма очевидна.
Добавленные в системную палитру цвета надо записать в регистры цвета видеокарты, иначе их нельзя будет использовать. Запись в регистры видеокарты производится либо при добавлении каждого нового цвета, либо после обработки всех цветов добавляемой палитры. Вы можете выбрать любой из этих вариантов по своему усмотрению, очевидных преимуществ друг перед другом у них нет.
Новые номера цветов
Коды точек образа рисунка являются номерами строк палитры, хранящейся в том же файле. При использовании описанного алгоритма порядок расположения части или всех исходных цветов может измениться. Поэтому при обработке каждого цвета добавляемого рисунка надо запоминать его расположение в системной палитре, а при построении рисунка выполнять перекодировку точек.
Для хранения новых значений кодов точек рисунка в памяти резервируется пространство размером в 256 байтов (максимальное количество цветов палитры). Небольшой размер этого пространства позволяет расположить его в сегменте данных программы, например, так:
Index db 256 dup (?); выделение 256 байтов для массива Index
Массив index имеет следующую структуру. Номера байтов соответствуют номерам строк палитры добавляемого рисунка, а содержимое байтов является номерами строк системной палитры. При построении рисунка по коду точки выбирается соответствующий байт массива index и его содержимое записывается в видеопамять.
Подпрограмма установки палитры
Текст подпрограммы, выполняющей описанные действия, приведен в примере 4.7. Перед ее вызовом добавляемая палитра должна быть прочитана в буфер обмена, и адрес ее начала указан в регистрах fs:di (сегмент: смещение). Размер палитры (количество строк, или описанных в ней цветов) помещается в регистр сх. Как прочитать палитру и определить ее размер при работе с файлами формата BMP, описано в Приложении А данной книги.
Если при добавлении новых цветов произойдет переполнение системной палитры, то перед возвратом из подпрограммы будет установлен С-разряд и восстановлено исходное значение переменной numcoi.
Пример 4.7. Установка палитры добавляемого рисунка формата BMP.
AnlsPal pusha сохранение "всех" регистров PushReg <gs,numcol> сохранение содержимого gs и numcol xor bx, bx исходный номер байта в Index anls 1: PushReg <cx,bx> сохранение содержимого сх и bx mov ebx, fs: [di]!! очередной добавляемый цвет shr ebx, 02 масштабирование кода этого цвета and ebx, 03F3F3Fh выделение 6-ти младших разрядов mov dx, OFFh номер белого цвета в SysPal cmp ebx, 03F3F3Fh добавляется белый цвет? jz anls 4 › да Igs si, dword ptr Sy spal; установка сегмента и смещения mov ex, numcol количество цветов в Syspal xor dx, dx очистка номера строки в Syspal ; Цикл сравнения с цветами, записанными в Syspal anls_2: lods dword ptr gs: [si ] чтение текущего цвета из Syspal cmp eax, ebx сравнение с добавляемым цветом jz anls 4 › цвета совпали inc dx номер следующей строки Syspal loop anls 2 управление циклом сравнений ; Добавляемый цвет отли' лается от хранящихся в Syspal cmp numcol, 255 использованы все регистры цвета? jnz anls 3 › нет stc установка С-разряда PopReg <bx, ex, numcol> восстановление bx, сх и numcol jmp short anls 5 "короткий" переход на метку anls 5 ; Запись нового цвета в Syspal и в регистр цвета anls_3: mov [si], ebx добавляем новый цвет в Syspal inc numcol увеличиваем счетчик цветов в Syspal