| ReadLn { пауза до нажатия ввода }
| END.
Рис. 20.3
20.2. Организация доступа к видеопамяти
Структура видеопамяти проста. Видимые строки экрана хранятся последовательно, выстраиваясь в цепочку от стартового адреса видеопамяти. Единственная сложность в том, что один символ на экране занимает два байта в памяти: первый байт содержит его ASCII-код, а второй — его цветовой атрибут (значение TextAttr для этого символа). Поэтому все четные адреса видеопамяти, начиная с нуля, содержат символы, а нечетные — их цвета.
Доступ к видеопамяти можно организовать, наложив на нее регулярную структуру в виде одномерного массива двухбайтовых элементов (рис. 20.4).
Запись VideoWord содержит два поля: первое соответствует четным адресам видеопамяти и хранит в себе код выводимого символа; а второе поле (нечетные адреса) содержит его цветовой атрибут.
- 475 -
| TYPE
| VideoWord = RECORD { Пара байтов: }
| Symbol : Char; { символ, }
| Attrib : Byte { его цвет. }
| END;
| TYPE
| VideoText = Array [1..50*80] of VideoWord;
| { Максимальный размер экрана - 80x50 }
| { MDA —> 80x25; }
| { CGA --> 80x25 и 40x25; }
| { EGA --> 40x25, 80x25, 40x43 и 80x43; }
| { VGA —> 40x25, 80x25, 40x50 и 80x50. }
| VideoTextPtr = ^VideoText;
| { ссылка на образ экрана в памяти ПЭВМ }
Рис. 20.4
Размер массива VideoText определяется максимальной емкостью экрана 80x50 для адаптера VGA. Все менее емкие режимы вполне уместятся в этой структуре. Непосредственное обращение к видеопамяти производится через динамическую переменную типа «ссылка на структуру VideoText». В процедурах на рис. 20.5 такая переменная обозначена именем VT. Инициализация динамической переменной производится без вызовов процедур New или GetMem. Вместо того ей просто присваивается адрес начала видеопамяти и тем самым устанавливается, что ссылки на элементы структуры VT^ будут соответствовать ячейкам видеопамяти.
Если известно текущее число столбцов M, то преобразование двумерных координат X и Y в номер i элемента массива V^[i] поизводится по формуле
i := М*(Y-1) + X
Используя это соотношение, можно считать или записать пару символ-атрибут» в любое место видеопамяти, задавая координаты символа обычным способом через X и Y.
На рис. 20.5 приводятся две процедуры. Одна из них, FillArea, записывает прямо в видеопамять постоянную пару значений типа VideoWord, тем самым максимально быстро заполняя заданную прямоугольную область на экране. Вторая процедура, ChangeAttr, меняет цвет любой прямоугольной области экрана, задаваемой координатами X1, Y1, X2, Y2. Ее действие таково: сначала в данной координате считывается код находящегося там символа, а после этого
- 476 -
пара «символ-атрибут» с предварительно измененным атрибутом цвета записывается на то же место в структуре видеопамяти.
Процедуры работают во всех текстовых режимах, но не содержат в себе контроля корректности координат области (см. рис. 20.5). Параметр VT в процедурах — это ссылка на начало экранной памяти, на которую наложена структура VideoText. Цвет символов задается параметром Attr так же, как переменная TextAttr.
| USES CRT;
| TYPE
| VideoWord = RECORD { Пара байтов: }
| Symbol : Char; { символ, }
| Attrib : Byte { его цвет. }
| END;
| VideoText = Array [1..50*80] of VideoWord;
| { Максимальный размер экрана - 80x50 символов. }
| VideoTextPtr = ^VideoText;
| { ссылка на образ экрана в памяти ПЭВМ }
| { Процедура закраски области экрана символом Ch }
| PROCEDURE FillArea(VT : VideoTextPtr;X1,Y1,X2,Y2 : Byte;
| Ch : Char; Attr : Byte);
| VAR
| i, j, k : Word; { счетчики циклов и пр. }
| BuffWord : VideoWord; { символ и его атрибут }
| M : Byte absolute 0:$44А; { текущее число столбцов }
| BEGIN
| with BuffWord do begin
| { определение символа }
| Symbol := Ch;
| Attrib := Attr
| end;
| for j:=Y1 to Y2 do begin { Запись в видеопамять }
| k := M*(j-1); { символов Ch в цвете Attr }
| for i:=X1 to X2 do
| VT^[k+i] := BuffWord;
| end; {for j}
| END;