| { Процедура смены цвета прямоугольной области экрана }
| PROCEDURE ChangeAttr( VT : VideoTextPtr; X1,Y1,X2,Y2,
| Attr : Byte );
| VAR
| VW : VideoWord; { один символ и его цвет }
Рис. 20.5
- 477 -
| i, j, k, n : Word; M : Byte absolute 0:$44A; { число столбцов }
| BEGIN
| VW.Attrib := Attr;
| { запись нового цвета }
| for j:=Y1 to Y2 do
| begin { цикл обновления цвета }
| k :=M*(j-1);
| for i:=X1 to X2 do
| begin n :=k+i; { индекс доступа }
| VW.Symbol := VT^[n].Symbol;
| { запоминание символа }
| VT[n] := VW { вывод его в новом цвете}
| end {for i}
| end {for j}
| END;
| {$I get_ptr.inc}
| { функция GetScreenPtr (см. рис. 20.1) }
| VAR V : Pointer; { основной блок примера }
| BEGIN V := GetScreenPtr; { адрес видеопамяти }
| if Seg( V^ )=$8000
| then TextMode( Mono )
| else TextMode( C080);
| Write( 'Нажимайте клавишу ввода ...' );
| ReadLn;
| FillArea( V, 2, 2, 80, 25, #177, White );
| { Весь экран (режим С080) закрашивается сим- }
| { волом 177 белого цвета. }
| ReadLn; FillArea( V, 5, 5, 40, 20, #176, Blue+16*lightGray );
| { Область закрашивается символом 176, цвет - }
| { синий по белому. }
| ReadLn;
| ChangeAttr( V, 5, 5, 40, 20, Yellow+16*Red );
| { Область меняет цвет на желтый по красному. }
| ReadLn;
| ChangeAttr( V, 25, 15, 75, 24, Green+16*Cyan );
| { Область меняет цвет на зеленый по голубому.}
| ReadLn;
| { пауза до нажатия ввода }
| ClrScr { очистка экрана }
| END.
Рис. 20.5 (окончание)
В качестве входного параметра процедуры используют параметр VT, совместимый по типу со значениями типа Pointer. Такой подход предоставляет еще большие возможности. Так, можно передавать адрес различных видеостраниц (если адаптер ПЭВМ их
- 478 -
поддерживает) или даже просто областей динамической памяти. Это позволяет заполнять альтернативные невидимые экраны и после этого копировать их в активную видеопамять командой Move (или переключать страницы), получая эффекты быстрой смены кадров.
Подобные действия с видеопамятью используются при организации накладывающихся окон. Перед созданием окна весь экран или его часть сохраняется (запоминается вся структура или подынтервалы из нее), а после уничтожения окна восстанавливается вновь. Стандартная процедура Window всегда уничтожает изображение «под окном».
20.3. Запомнинание окон экрана и их восстановление
20.3.1. Общие принципы работы с окном
Введенные выше типы структур для обращения к видеопамяти можно с успехом использовать для работы с произвольными областями экрана — окнами. Единственное, что потребуется — это, чтобы окно имело прямоугольную форму. В таком случае надо обрабатывать (считывать, запоминать, заполнять) не всю последовательность ячеек видеопамяти, а набор фрагментов, каждый из которых представляет собой одну строку окна. Число таких фрагментов равно числу строк в окне. Длина каждого фрагмента равна ширине окна. Начало первого фрагмента в структуре видеопамяти (Start) для окна, заданного координатами X1, Y1, X2, Y2, можно вычислить по формуле:
Start * M*( Y1 - 1 ) +X1,
где M — число столбцов для текущего текстового режима. Начало каждого последующего фрагмента получается добавлением числа M к началу предыдущего. Ширина окна (Width), она же длина одного фрагмента, определяется очевидным образом:
Width = ( Х2 - Х1 ) + 1
а число фрагментов (Height) находится как
Height = ( Y2 - Y1 ) + 1.
Для того чтобы запомнить (сохранить) все окно, потребуется область памяти размером
Size = Width * Height * 2,
где 2 появляется из-за того, что один символ на экране представляется двумя байтами в памяти. Обычно при сохранении окна фрагменты записываются в память последовательно, и при их восстановлении на экране необходимо вновь вычислять положение каждого из них.
20.3.2. Модуль Win