Смекни!
smekni.com

Программирование в СИ (стр. 2 из 8)

Графический драйвер должен быть помещен в оперативную память до того, как произойдет обращение к какой-нибудь функции графической библиотеки.

Простейшим способом включения драйвера в программу является его автоматическая загрузка при помощи функции initgraph с прототипом

void initgraph(int far *graph_driver,int far *graph_mode,char far *path_to_bgi);

Аргументами данной функции являются указатели на переменные, содержащие номер графического драйвера, номер графического режима и путь к BGI-файлу драйвера. Функция initgraph ищет на диске BGI-файл, содержащий требуемый драйвер, загружает файл целиком в динамически выделяемую память и настраивает ядро системы на работу с этим драйвером. Если инициализация прошла успешно, функция graphresult возвратит нулевое значение GR_Ok, в противном случае – одно из отрицательных значений, определенных в файле graphics.h.

Функция

void far closegraph(void)

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

Пример автоматической загрузки драйвера и инициализации
системы:

intmain(void){intgd,gm,err;detectgraph(&gd,&gm); /* определение номера драйвера и режима */err=graphresult(); /* получение кода завершения */if(err) { printf(“\n%s”,grapherrormsg(err)); return 1; }initgraph(&gd,&gm,”c:\borlandc\bgi”); /* инициализациясистемы */err=graphresult(); /* получение кода завершения */if(err) { printf(“\n%s”,grapherrormsg(err)); return 2; }/* ................различные операторы..............*/closegraph(); /* завершение работы системы */return 0;}

Можно не определять номера драйвера и режима тестированием аппаратуры, а задавать их по желанию, главное при этом соблюдать соответствие выбираемого драйвера и имеющегося в распоряжении видеоадаптера. Приведенный выше пример можно изменить тогда следующим способом:

int main(void){int gd=VGA,gm=VGAHI,err;initgraph(&gd,&gm,”c:\borlandc\bgi”);err=graphresult();if(err) { printf(“\n%s”,grapherrormsg(err)); return 1; }/* ................различные операторы..............*/closegraph();return 0;}

Главным недостатком автоматической загрузки драйвера при помощи функции initgraph является то, что она обращается к диску для чтения BGI-файла во время выполнения программы. Альтернативой автоматической загрузке графического драйвера является его статическое включение на этапе построения программы. Предварительно бинарный файл драйвера .bgi должен быть превращен в обычный объектный файл типа .obj специальной утилитой bgiobj.exe. Кстати, данная утилита используется также для конвертирования chr-файлов с графическими шрифтами в объектные модули. Полученные объектные модули подключаются на этапе компоновки.

В программе, прежде чем инициализировать графическую систему, необходимо нужные драйверы зарегистрировать, т. е. сообщить графической системе, что данный драйвер уже находится в оперативной памяти. Для этого существует функция registerbgidriver, которой нужно сообщить местоположение драйвера:

int registerbgidriver(void (*driver)(void));

Аргумент функции – имя указателя на место в памяти, содержащее регистрируемый драйвер. Имена подобных указателей уже определены в объектных файлах, созданных при помощи утилиты bgiobj.exe. Ниже приведены прототипы функций, имена которых нужно употреблять для стандартных драйверов:

void CGA_driver(void);void EGAVGA_driver(void);void IBM8514_driver(void);void Herc_driver(void);void ATT_driver(void);void PC3270_driver(void).

Если регистрация прошла успешно, функция graphresult возвратит нулевое значение, в противном случае -4. После регистрации драйвера можно инициализировать графическую систему при помощи функции initfgraph, при этом ее третий параметр не используется (передается нулевая строка “”).

Пример статической загрузки драйвера и инициализации системы:

int main(void){int gd,gm,err;detectgraph(&gd,&gm); err=graphresult(); if(err) { printf(“\n%s”,grapherrormsg(err)); return 1; }registerbgidriver(EGAVGA_driver); err=graphresult(); /* получениекодазавершения */if(err) { printf(“\n%s”,grapherrormsg(err)); return1; }initgraph(&gd,&gm,""); /* инициализация системы */if((err = graphresult()) != grOk) { printf(“\n%s”,grapherrormsg(err)); return1; }/* ................различные операторы..............*/closegraph(); /* завершение работы системы */return 0;}

Если графическая система активизирована и необходимо по ходу выполнения программы переключиться на использование другого графического драйвера, то до повторного вызова функции initgraph необходимо сбросить графическую систему функцией closegraph для освобождения всей памяти, которую занимала система.

Имя текущего графического драйвера можно узнать с помощью функции

char far *getdrivername(void);

Она возвращает указатель на строку, содержащую имя активного в данный момент драйвера.

Максимальное значение номера графического режима, допустимое для текущего графического драйвера, можно узнать с помощью функции

int far getmaxmode(void);

Текущее значение номера графического режима для активизированного драйвера возвращает функция

int far getgraphmode(void);

По номеру режима можно получить строку с описанием данного режима для текущего драйвера. Это делается с помощью функции

char far *getmodename(int mode_number);

В графической библиотеке есть функция определения минимально и максимально допустимых значений номера графического режима для графического драйвера, номер которого ей передается (необязательно активизированного)

void far getmoderange(int graph_driver,int far *min_mode,int far *max_mode);

Есть две функции, позволяющие изменять установленный графический режим без повторного обращения к функции initgraph и даже переходить временно в текстовый режим работы видеоадаптера. Если нужно перейти в другой графический режим активизированного в данный момент драйвера, то можно воспользоваться функцией

void far setgraphmode(int new_mode);

Аргумент new_mode передает желаемый номер режима для текущего драйвера и не должен превосходить максимально допустимое для этого драйвера значение.

Для временного перехода в текстовый режим предусмотрена
функция

void far restorecrtmode(void);

Эта функция переводит видеоадаптер в тот текстовый режим, в котором он находился в момент последней инициализации графической системы, т. е. непосредственно перед обращением к функции initgraph. Из текстового режима можно вернуться в графический при помощи функции setgraphmode.

При инициализации графической системы всевозможные параметры системы устанавливаются по умолчанию. Различные функции могут менять значения параметров. Для того чтобы в любой момент восстановить характеристики системы, установленные при ее инициализации, существует функция

void far graphdefaults(void);

Перечислим действия, выполняемые данной функцией:

· для вывода и отображения на экране выбирается нулевая страница видеопамяти;

· графическое окно устанавливается размером во всю страницу;

· текущая графическая позиция перемещается в точку (0,0);

· устанавливаются по умолчанию цвета палитры, текущий рисующий цвет (15) и цвет фона (0);

· устанавливается сплошной шаблон для рисования линий и заполнения областей;

· инициализируется встроенный матричный шрифт со стандартным расположением и позиционированием строки.

1.3. Работа с растром точек

Растром точек называется двумерная совокупность точек, представляющая экран дисплея.

Чтобы в прикладной программе иметь возможность отобразить на экране любую из имеющихся страниц видеопамяти, в графической библиотеке предусмотрена функция

void far setvisualpage(int page);

Функция немедленно отображает на экране ту страницу видеопамяти, номер которой был ей передан в качестве аргумента. Страницы нумеруются с нуля. Функция graphresult не реагирует на попытку установить недопустимый номер страницы. Вся ответственность за правильность указанного номера лежит на программисте. Функция

void far setactivepage(int page);

не вызывает перерисовки страницы на экране дисплея, но зато направляет весь последующий графический вывод на ту страницу, которая указана ее аргументом. Как и при вызове предыдущей функции, ответственность за допустимость номера страницы остается на программисте.

Страницу видеопамяти (и экран дисплея) можно представить как двумерный прямоугольный массив точек (пикселей). На этом массиве точек вводится система координат X, Y. Начало системы лежит в левом верхнем углу страницы (экрана). Ось X проходит по верхнему краю страницы слева направо, а ось Y – по левому краю сверху вниз. Левая верхняя точка страницы имеет координаты (0, 0), правая нижняя – координаты (M-1, N-1), где M и N – размеры страниц по горизонтали и вертикали.

Определить максимальные значения координат точек можно с помощью функций

int far getmaxx(void);int far getmaxy(void);

Значения, возвращаемые этими функциями, зависят только от текущего режима, установленного функциями initgraph или setgraphmode.

В распоряжении программиста кроме страницы как целого имеется еще одна двумерная структура. Внутри основного массива точек страницы всегда выделен некоторый его подмассив, который называется графическим окном (viewport). Графическое окно является прямоугольным массивом точек со своей системой координат. Начало этой системы координат находится в левом верхнем углу графического окна, а оси X и Y параллельны соответствующим осям координат страницы. Само окно имеет переменные размеры и может располагаться в любом месте экрана. Замена страницы никак не влияет на характеристики окна.

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

При установке графического режима при помощи функций initgraph и setgraphmode сразу же создается и графическое окно, совпадающее по размерам со всей страницей. Однако есть возможность управлять размерами и расположением графического окна динамически. Делаетсяэтоспомощьюфункции

void far setviewport(int left.int top,int right,int bottom,int clip);

Первые четыре аргумента – это координаты левой верхней и правой нижней границ графического окна в системе координат страницы. Ни одна из границ окна не может лежать за пределами страницы. Последний аргумент устанавливает режим отсечения: если он не нулевой, то всякий графический вывод будет обрезаться на границах графического окна. Если при вызове фунции setviewport были неверно заданы аргументы, то функция graphresult возвратит -11 и сохранится предыдущая установка графического окна. Функция setviewport не меняет содержимое страницы видеопамяти.