Информационный сервер для программистов: Исходники со всего света. Паскальные исходники со всего света
  Powered by Поисковый сервер Яndex: Найдется ВСЁ!
На Главную Pascal Форум Информер Страны мира
   Графика    >>    ns_bgi
   
 
 BGI - Работа с Нестандартными драйверами   Виктор Вагнер 13.07.1996

О методах работы с нестандартными BGI драйверами



5k 
 

From: vitus@agropc.msk.su Subject: Nonstandard BGI drivers HOW-TO (или "как это делается") Date: 12 Jul 1996 20:41:54 +0400 Увидел в конфе в очередной раз вопрос на эту тему и решил сразу написать все ответы. Возможно, это дело стоило бы отполировать, ну да ладно. ----- 1.Как определить, можно ли использовать данный BGI драйвер со своей программой? 1). Не используйте драйверов от Quattro Pro или Paradox - они несовместимы с Borland Pascal/Borland С. 2). Если Ваша программа написана на Turbo Pascal 6.0 и ниже, то вам нужны драйверы версии 2.х Программа на Borland Pascal версии 7.0 в реальном режиме может использовать как драйверы версии 2.х, так и 3.0 Программа в Protected Mode нуждается в драйвере версии 3.0 Отличить драйвер версии 2.х от 3.0 очень просто - если первые два байта в файле с расширением bgi это 'pk' маленькими буквами, то это 2.х (а может 1.х - с последними ни разу не сталкивался). Если же файл начинается с символов 'FBGD', то это - 3.0 и он будет работать в Protected, но не будет работать с 6-м паскалем. 2. Как получить номер драйвера, который следует передавать в процедуру InitGraph? RTFM: InstallUserDriver Function InstallUserDriver(DrvName:String;AutoDetectPtr:pointer):integer; Эта функция получает имя драйвера БЕЗ ПУТИ И РАСШИРЕНИЯ. Второй параметр указатель на функцию автодетектирования (см вопрос 4) При первых экспериментах вместо него можно смело передавать nil. Например: Gd:=InstallUserDriver('SVGA256',nil); Gm:=3; InitGraph(GD,GM,'C:\BP\BGI'); 3. Как заставить модуль GRAPH использовать нужный мне драйвер вместо заданного по умолчанию?. Явным образом присвоить значение переменной, которая будет передана в процедуру InitGraph в качестве первого параметра (см. пример к вопросу 2) При этом надо не забыть присвоить значение и параметру GraphMode (графический режим), поскольку если GraphDriver<>Detect, автоматического определения режима не происходит. 4. Как заставить программу автоматически определять режим нестандартного драйвера? Написать процедуру автодетектирования и передать ее вторым параметром в InstallUserDriver. Процедура должна быть описана как far и представлять собой функцию без параметров, возвращающую номер режима или -1, если ни один из режимов данного драйвера не поддерживается. Хороший пример процедуры автодетектирования приведен в программе BGIDEMO.PAS, входящей в комплект поставки Borland Pascal. Если вы не боитесь ассемблера и вам не лень разбираться в функциях VESA BIOS вы легко адаптируете ее к 256-цветному драйверу (если она у вас будет работать и в Real и в Protected - киньте мне, а то мне лень :-) Простейшая процедура детектирования для драйвера VGA256 (режим 13H, 320x200x256,VGA) выглядит так: Function DetectVGA:integer;far;assembler; asm MOV AX,1A00H INT 10H CMP AL,1AH JZ @@1 mov ax,-1 ;{Не вышло} jmp @@2 @@1:MOV AX,0;{вышло - ставим нулевой режим} @@2: end; Модуль GRAPH выполняет детектирование следующим образом: вызывает процедуру детектирования для всех установленных драйверов, начиная с конца (с последнего) и устанавливает первый драйвер, процедура детектирования которого вернула режим, больший или равный 0. (это, естественно, происходит только если параметр GraphDriver в процедуре InitGraph был равен Detect) 5. Как прилинковать нестандартный BGI-драйвер? 1). преобразовать его в объектный файл с помощью утилиты binobj 2). Прилинковать Для этого надо написать следующие две строки: Procedure SVGADriver;External; {$L SVGA.OBJ} где имя процедуры - это то, что Вы указали третьим параметром утилиты BINOBJ, а имя объектного файла - то что Вы указали вторым параметром. 3). Вызвать InstallUserDriver точно так же, как вы вызывали его при отдельно лежащем драйвере. 4). Вызвать RegisterBgiDriver, передав в него адрес процедуры, в качестве которой вы прилинковали драйвер RegisterBgiDriver(@SVGADriver); 5). Вызвать InitGraph, указав в качестве BGIPath тот каталог, откуда вы будете грузить CHR шрифты (или пустую строку, если шрифты не нужны или тоже прилинкованы) Номер драйвера в данном случае будут возвращать и InstallUserDriver и RegisterBgiDriver. 6. Как отловить все ошибки, связанные с загрузкой и инициализацией драйвера? Во-первых, можно проверять GraphResult после каждой операции. Напишите для этого такую процедурку Procedure CheckError; var Result:Integer; begin Result:=GraphResult; if Result<>grOk then begin Writeln(GraphErrorMsg(Result)); Halt(1); end; end; GraphErrorMsg, конечно, ругается по-английски, но она дает больше информации, чем просто анализ кода GraphResult - она выдает имя неправильного драйвера или шрифта. Кроме того функции InstallUserDriver, InstallUserFont, RegisterBGIDriver, и RegisterBGIFont возвращают, а InitGraph присваивает параметру GraphMode в случае ошибки отрицательное значение, соответсвующее коду GraphResult. 7. Как добиться русских шрифтов в BGI-графике? а) шрифт 0 (DefaultFont) Для того, чтобы этот шрифт был русским, вектор прерывания 1F должен быть установлен корректно. Добудьте откуда-нибудь русский шрифт 8x8 (например, выдерите из EGA.CPI от русской DOS или из какого-нибудь руссификатора), возьмите от него вторую половину (1024 байта) и прилинкуйте к своей программе (см вопрос 5). После это сделайте SetIntVec($1F,@RussianFont); Не забудьте обеспечить корректное восстановление этого вектора при завешении программы. На уровне команд DOS того же эффекта можно добиться загрузив резидентную программу GRAFTABL, входившую в комплект DOS версий до 6. Запускать ее надо командой GRAFTABL 866, а сама программа должна быть взята из русской DOS. б) векторные (CHR) шрифты Возьмите файлы шрифтов из комплекта русского Paradox или Quattro Pro. В отличие от BGI драйверов они совместимы. 8. Куда делся мой курсор мыши? К сожалению, большинство драйверов мыши не поддерживают режимов SVGA. Поэтому вы можете попробовать найти драйвер BGI, который содержит встроенную эмуляцию курсора или написать свою эмуляцию (процедур GetImage и PutImage для этого вполне достаточно) Кроме того, в 256 цветных режимах 255 и 0 цвета по умолчанию оба черные, так что курсор мыши будет напоминать черную кошку в темной комнате. Сделайте SetRGBPalette(255,63,63,63); 9. Как добиться того, чтобы программе была доступна работа со всей палитрой VGA (256 К цветов) а не только 63 цвета, котроые предлагает EGA-совместимая процедура SetPalette? Используйте SetRGBPalette. В 256-цветных режимах вы не встретите никаких проблем, а в 16 цветных все несколько сложнее. Дел в том, что в этих режимах первым параметром в SetRGBPalette передается не номер цвета, а индекс в палитре EGA. Я с этим борюсь простейшим способом: For i:=0 to 15 do SetPalette(i,i); После чего устанавливаю нужную мне палитру уже средствами SetRGBPalette. Moжно еще делать так Var Pal:PaletteType; ...... GetPalette(Pal) SetRBPalette(Pal.Colors[Color],R,G,B); Если вы хотите переназначить все 256 цветов, то конструкция вида For i:=0 to 255 SetRGBPalette(i,R[i],G[i],B[i]); вас, вероятно, не устроит, так как выполняется несколько секунд. Вот несколько полезных процедур для любителей работать с палитрой: Procedure SetRGBArray(Index,Count:Integer;var RGB);assembler; asm LES DX,RGB MOV BX,Index MOV CX,Count MOV AX,1012H INT 10H end; Устанавливает сразу много цветов(идущих подряд) Index - номер первого из них, Count - их количество переменная RGB должна быть описана как Array[1..Max] of Record R,G,B:Byte; end; Впрочем Type TcolorComponent=(R,G,B); var PaLETTE256:ARRAY[0..255,R..B] of Byte; тоже годится. Procedure GetRGBPalette(Index:Integer;var R,G,B:Byte);assembler; asm MOV AX,1015H; MOV BX,INDEX INT 10H LES DI,R MOV ES:[DI],DH LES DI,G MOV ES:[DI],CH LES DI,B MOV ES:[DI],CL end; Возвращает три компоненты одного цвета, указанного в переменной Index Procedure GetRgbArray(Index,Count:Integer;var RGB);assembler; asm MOV BX,Index MOV CX,Count LES DX,RGB MOV AX,1016H INT 10H end; Копирует в переменную RGB описание Count цветов, начиная с Index 10. Почему PCX-файл, выведенный на экран в соответствии с рекомендациями п.9 выглядит совершенно непохоже на оригинал? Потому что регистры палитры VGA шестибитные, то есть каждая из компонент R G B принимает значения от 0 до 63, а в стандарте PCX на каждую компоненту отводится 8 бит - от 0 до 255. Поделите содержимое палитры PCX-файла на 4 прежде чем передавать в SetRGBPalette или SetRGBArray. --------------------------------------------------------------------------- Phone: 7(095)230-80-61 Victor B. Wagner Fax: 7(095)230-80-42 Dokuchaev Soil Institute EMail: vitus@agropc.msk.su Moscow, Russia