int21h

Úvod do grafické knihovny VenomGFX

Možná, že jste narazili na problém, že byste rádi začali programovat ve Freepascalu pro DOS, ale skončili jste ještě dřív, než jste začali, protože jste nenašli vhodnou grafickou knihovnu.
Nuže, zkuste VenomGFX
VenomGFX původně vyvíjel Venom z Německa, ale už několik let se jí nevěnuje. Ten samý člověk teké napsal sesterskou knihovnu VGFX, což je předělávka VenomGFX pro prostředí windows. Té už se také něvěnuje.
Nicméně já jsem se sirotka VenomGFX ujal a pokračuji v jejím vývoji. Nejnovější verze této jednotky je tedy proto na mých stránkách, konkrétně zde.
Funguje pod oběma generacemi Freepascalu - verzí 1.0.10 i 2.0.2
Co je důležité z technického hlediska je to, že VenomGFX podporuje pouze grafické režimy s 16bitovou barevnou hloubkou (tedy s 65536 barvami). Sice to může být poněkud omezující, ale na druhou stranu tato úzká specializace umožňuje opravdu vynikající rychlost všech grafických rutin.
Pojďme se podívat na nějaký velmi jednoduchý zdroják:
uses VenomGFX;
begin
Init_Graph(Find_Mode(800,600));

Circle(vga,vga.breitediv2,vga.hoehediv2,vga.hoehediv2-1,40,0,0);
readln;

Kill_Graph;
end.  

Tento prográmek nakreslí červenou kružnici.
Vraťme se ale ještě jednou k technickému aspektu věci. Tento zdroják používá LFB přístup. Pokud jste předchozí větu nepochopili, čtěte dál:
Grafické karty mají totiž dva režimy činnosti: přes bankya přes LFB. Bankový mód je jakýsi mód kompatibility a hlavně umožňuje práci s grafikou v 16-bitových programech. Jde o to, že v jeden moment není programátorovi přístupná celá obrazovka, ale pouze její část - takzvané vstupně/výstupní okno. Toto okno se dá samozřejmě posouvat, takže programátor se nakonec dostane na celou obrazovku, ale je s tím dost starostí, protože je potřeba starat se o posouvání, přesněji přepínání, banků.
LFB režim umožňuje přístup na celou obrazovku bez omezení. Mohou ho ovšem používat jenom 32-bitové programy. (LFB režim používají například celé windows) Freepascal 32-bitové programy tvoří, takže LFB tudíž můžeme používat i my.
Problémy jsou dva.
1) staré počítače LFB neumí.
Dá se říct, že 386 LFB neumí nikdy, 486 zřídka, Pentium I většinou ano a novější téměř určitě ano. Samozřejmě to záleží na grafické kartě, a ne na procesoru, ale pro orientační přehled toto stačí.

2) LFB pro DOS nepodporují některé ovladače windows
To je mnohem vážnější problém. Ve windows se totiž DOSové funkce grafické karty přesměrovávají na windowsí ovladače, které ne vždy podporují režim LFB.
A ještě horší je to, že windows 2000, XP a patrně i Vista nepodporují LFB pro DOS z principu. U nich můžete být rádi, když vám povolí bankový režim.
Ovladače Windows 95, 98 a ME přístup v LFB režimu DOSu většinou povolují, i když někdy se objevují divné chyby.

Shrnutí - pod Windows XP a Vista nefunguje LFB.

Ten samý zdroják sem dám ještě jednou, abyste ho měli znovu na očích.(tento text píšu v T602 a už jsem o obrazovku níže. Ve webovém prohlížeči je to ale možná jenom kousek...)
uses VenomGFX;
begin
Init_Graph(Find_Mode(800,600));

Circle(vga,vga.breitediv2,vga.hoehediv2,vga.hoehediv2-1,40,0,0);
readln;

Kill_Graph;
end.  

Podívejte se na řádku s Init_Graph. Všimněte si, že neudávám kód videomódu, ale jenom jeho rozměry a kód vygeneruje až funkce Find_Mode
Zápis Init_Graph($114) je také možný, ale je to fuj. - nepoužívejte to.

Zajímavá je i řádka s Circle.
*první parametr vga znamená, že má kreslit přímo na skutečnou obrazovku a ne do žádné virtuální obrazovky.

*vga.breitediv2 X-střed v polovině šířky obrazovky (z německého Breite - šířka)

*vga.hoehediv2 Y-střed v polovině výšky (z Hoehe - výška)

*vga.hoehediv2-1 je tudíž jasné
*40,0,0 určuje barvu kružnice ve složkách RGB (červené, zelené a modré)

To bychom měli. Uživatelé Windows XP ale smutní, že oni mají smůlu. Nemají. VenomGFX podporuje i práci v bankovém režimu. I když, pravda, omezeně.
Podívejte se na tuto variantu stejného programu:
uses VenomGFX;
var v:virtualwindow;
begin
{SetRequestedVideoAccess(BANK_ACCESS)}
Init_Graph(Find_Mode(800,600));
Init_VW(v,800,600,true);

Circle(v,vga.breitediv2,vga.hoehediv2,vga.hoehediv2-1,40,0,0);
Flip_SVGA(v);
readln;

Kill_Graph;
end.  
Vidíte, že tady nekreslím přímo na obrazovku, ale do jakési struktury V, kterou pouze na obrazovku následně kopíruju speciální procedurou.
Možná se divíte, proč je volání SetRequestedVideoAccess zakomentované. Chceme banky nebo ne?
Vtip je v tom, že pokud není řečeno jinak, tak Init_Graph napřed zkusí nahodit LFB režim a když to nejde, tak nahodí bankový režim. Takže Ixpesáci nebojte, tenhle zdroják vám fungovat bude. Když ale bude dostupné LFB, tak se nahodí LFB, ale to nijak nebrání v tom, kreslit si na virtuální obrazovky a pak to jen kopírovat na skutečnou obrazovku pomocí Flip_SVGA
Když mermomocí chcete bankový režim i v případě, že je dostupné LFB, tak před Init_Graph použijte právě SetRequestedVideoAccess(BANK_ACCESS)
Když naopak tvrdě vzžadujete LFB, tak volejte SetRequestedVideoAccess(LFB_ACCESS) a program při nedostupnosti LFB skončí s příslušnou chybovou hláškou.
Pojďme na další bod - myš a zobrazovací frekvenci
uses VenomGFX;
begin
SetRequestedFrequency(BEST_FQ or 70);
Init_Graph(Find_Mode(800,600));
Init_Mouse(MOUSEDEF,vga); {misto MOUSEDEF muzes pouzit i prazdny retezec ''}

Circle(vga,vga.breitediv2,vga.hoehediv2,vga.hoehediv2-1,40,0,0);
MouseShow;
repeat
if mouse.b<>0 then Break;
until keypressed;
while keypressed do readkey;
MouseRel;

Kill_Mouse;
Kill_Graph;
end.  

Obsluha myši je dostupná pro oba režimy činnosti: LFB i banky.
Vidíte, jak je to krásně jednoduché. Inicializujete myš pomocí Init_Mouse a už se o nic nemusíte starat. Zobrazovač myši poslušně visí na hardarovém přerušení a vy nemusíte nic dělat. Můžete když chcete, ale nemusíte.
V tomto případě se použije zabudovaný standardní kurzor, ale místo něho můžete použít jakýkoliv obrázek ve formátu PCX.
Je dobré také vědět, že VenomGFX podporuje kolečko myši. Na to ale musíte mít DOSový ovladač myši, který kolečko podporuje. V současné době je to jenom ovladač CTMouse v2.0

Význam zobrazovací frekvece v současné době klesá s tím, jak se rozšiřují LCD monitory, na nichž je pěkný stabilní obraz. Ale na klasických CRT monitorech je zobrazovací (nebo také obnovovací) frekvence veledůležitý pojem. Když je moc nízká, tak obraz pomrkává a brzy vás začnou bolet oči.
Klíčová je zde řádka
SetRequestedFrequency(BEST_FQ or 70);
Toto volání zabezpečí, že procedura Init_Graph při nastavovní videomódu nastaví i požadovanou obnovovací frekvecni. Když to nenastavíte, tak v rozlišení 800x600 vám bude takové bílé pozadí dost blikat.
Kolik ale nastavit? Když dáte hodnotu moc velkou, tak to monitor nemusí zvládnout a celý se začerní a nic se na něm nezobrazí. Jiné monitory se prostě přepnou do stand-by módu a čekají, co jako bude. Uživatel je zmaten. Takže?
Dá se říct, že 55Hz rve bulvy z očí, 60Hz je nevyhovující, 65Hz na hraně, 70 ujde a 80 a výš je fajn. Tím jsme ale nevyřešili omezení monitoru...
Novější monitory naštěstí podporují tzv. VESA Display channel interface (VESA DDC)
Volání SetRequestedFrequency(BEST_FQ); zjistí pomocí VESA DDC maximální obnovovací frekvenci pro požadovaný videorežim a nastaví ji.
Jestliže ale máte starý monitor, který VESA DDC nepodporuje, tak byste měli smůlu a nic by se nastalo. Proto doporučuji BEST_FQ jistit nějakou pevně danou "záchranou frekvencí"
Já obvykle používám SetRequestedFrequency(BEST_FQ or 70); - tedy záchranou frekvenci na 70Hz.
Dlužno ještě poznamenat, že ne všechny ovladače windows podporují uživatelské nastavování zobrazovací frekvence. Prostě, používejte DOS, ten je v tomhle spolehlivý. Také zase platí, že ne všechny videokarty to umí. Jestli je starší než 7 nebo 8 let, tak to asi umět nebude.

Myslím, že tím jsme probrali všechny technické aspekty knihovny VenomGFX a grafiky pod DOSem obecně. Teď se podíváme na jiný příklad.
VenomGFX je velice silná v práci se sprajty. Má spoustu funkcí z "rodiny" PutImage/GetImage, všelijaké s ořezáváním, podsvěcováním, poloprůhledností a podobně. Naopak má menší sadu geometrických funkcí (chybí práce s polygony) a chybí FloodFill. Doufám, že to časem doplním, ale zatím prostě chybí. Ve VenomGFX samotné je jenom rudimentální podpora práce s výstupem textu. Tyto funkce jsou ještě od Venoma a přiznám se, že jsem je nikdy nekoušel. Na výstup textu používám vlastní přídavnou jednotku FNfont2, která je součástí mého balíku Wokna32. Ten si rovněž můžete stáhnout z mých stránkek. Jednotce FNfont2 i celým Woknům32 se budu věnovat někdy příště.
Takže slíbený příklad:
uses VenomGFX;
var v1,v2,v3:virtualwindow;
begin
SetRequestedFrequency(BEST_FQ or 70);
Init_Graph(Find_Mode(800,600));
Init_Mouse(MOUSEDEF,vga); {misto MOUSEDEF muzes pouzit i prazdny retezec ''}

Circle(vga,vga.breitediv2,vga.hoehediv2,vga.hoehediv2-1,40,0,0);

Init_VW(v1,300,300,false);
Init_VW(v2,300,300,true);
Init_VW(v3,400,400,false);

ClrPackedSprite(v1,MyRGB2Word($aa,$82,$0));
FullEllipse(v2,150,50,90,40,500);

Rotate_scale_sprite(v2,v3,200,200,300,300,50);
PutClippedHCSprite(v1,v3,0,0,0);
PutTransSprite(vga,v1,10,10,0,0,50);

MouseShow;
repeat
if mouse.b<>0 then Break;
until keypressed;
while keypressed do readkey;
MouseRel;

Kill_VW(v1);
Kill_VW(v2);
Kill_VW(v3);
Kill_Mouse;
Kill_Graph;
end.  
V tomto prográmku vdíte některé procedury pro práci se sprajty. Spíše si ale všimněte jiné věci, a to, že můžete kreslit do jakékoli proměnné typu VirtualWindow. (proměnná VGA je také mimochodem typu VirtualWindow). Kreslicí procedury tedy nevyžadují, aby bylo VirtualWindow velké stejně jako obrazovka. Můžete kreslit i do prťousů 10x10 pixelů, není problém. Jedinou výjimkou jsou procedury Clr a ClrPacked, které chtějí, aby byla šířka VW dělitelná čtyřmi či osmi, protože kvůli rychlostním optimalizacím je to zkrátka tak uděláno. Místo nich můžete použít univerzální ClrSprite a ClrPackedSprite.

Teď je řada na vás. Experimentujte!
Venom_GFX dokáže načítat obrázky ve formátech BMP, PCX, GIF, PNG a JPG. Ukládat umí jenom BMP.
Programování zdar!
DOS-u-akbar!
2006-12-06 | Laaca
Reklamy:
„Člověk, který nikdy neplakal nežil opravdový život!“ Jan Werich