Tento dokument byl vypracován podle skvělého „VGA Trainer Program by Denthor of Asphyxia“ s cílem pomoci začínajícím programátorům (v jejich mateřském jazyce).
Prohlašuji, že nejsem žádný vynikající angličtinář a ani češtinář, proto prosím o shovívavost.
Následující text je „splácán“ z překladu originálu a mých drobných úprav.
Ahoj! Tento text je zaměřen především na mladé programátory. Každý z vás by měl mít základy programování. Budete potřebovat také základní znalostí matematiky. Chtěl bych vás naučit, jak napsat své vlastní demo. Veškeré informace můžete využít třeba i při programování svých her.
Budu tu popisovat jak určité rutiny pracují a na závěr lekce dostanete zdrojový kód od Asphyxie s kterým si můžete trochu vyhrát.
Měli byste alespoň trochu ovládat Pascal, protože většina příkladů je napsaná právě v něm. Ale C-éčkaři se nemusí rmoutit. Je tu toho spousta v assembleru a pokud umí vkládat assembler jsou za vodou.
Takže dnes se naučíme jak se dostat do a ven z 320 x 200 x 256 grafického módu (13h) , pak probereme různé metody zobrazení pixelu a dozvíte se jak po sobě vyčistit obrazovku.
Jak se dostat do módu 13h bez BGI?
Proč vlastně nechceme používat BGI unity pro grafiku? Odpověď je jednoduchá, těžko se hledá něco pomalejšího než je BGI, proto je absolutně bezcenné pro programování různých dem a her. Jak se tedy dostat do módu 13h? Jednoduše, pomocí assembleru. Když se podíváte do Norton Guides to Assembly Language, naleznete …
INT 10h, 00h (0) Set Video Mode
Sets the video mode.
On entry: AH 00h
AL Video mode
Returns: None
Registers destroyed: AX, SP, BP, SI, DI
Říkáte si, co to sakra znamená? Je to zcela jednoduché, když do registru AL vložíte video mód a zavoláte přerušení 10h, HUPS a jste v módu, který jste si zvolili. Teďka pozor, MCGA video mód je mód 13h. Tady je, jak to vypadá v Pascalu.
procedure SetMCGA; assembler;
asm
mov ax,0013h
int 10h
end;
A máte to! Stračí zavolat tuto proceduru a ŠUP a jste v 320 x 200 x 256 módu. Zatím ještě nic neumíte tak HOP zase ven. Stačí nastavit video mod na 03h:
procedure SetTEXT; assembler;
asm
mov ax,0003h
int 10h
end;
A jste zase zpět v textovém módu. Ptáte se co teď, jak něco zobrazit na obrazovce? Stačí číst dále.
Vyčištění obrazovky danou barvou
Teď když jsme v MCGA módu, jak vyčistit obrazovku? Odpověď je jednoduchá: musíte si jen pamatovat, že základní adresa obrazovky je a000h. Z a000h dalších 64000 bytů je to co se zobrazuje na monitoru. (Všimněte si: 320 x 200 = 64000). A tak k vyčištění obrazovky stačí použít příkaz fillchar (jeden ze základních příkazů Pascalu), a to následovně:
FillChar (Mem
[$a000:0], 64000, col)
Příkaz MEM předává segmentovou bázi a offset části paměti. V tomto případě segmentem je segment obrazovky a začínáme na hořejšku obrazovky: offset 0. Číslo 64000 je velikost obrazovky a col je hodnota mezi 0 a 255, která reprezentuje barvu, kterou chcete vyčistit obrazovku.
Umístění pixelu na obrazovku (dvě různé metody)
Když kouknete do Norton Guides na umisťování pixelu na obrazovku, najdete následující:
Writes a pixel dot of a specified color at a specified screen coordinate.
On entry: AH 0Ch
AL Pixel color
CX Horizontal position of pixel
DX Vertical position of pixel
BH Dispaly page number (graphics modes with more than 1 page)
Returns: None
Registers destroyed: AX, SP, BP, SI, DI
Jak jste viděli v našem příkladu se SetMCGA, měli byste ti napsat následujícím způsobem:
Procedure INTPutpixel (x,y : integer; col : byte); assembler;
asm
mov ah, 0Ch
mov
al,
[col]
mov
cx,
[x]
mov
dx,
[y]
mov
bx,
[1]
int
10h
end;
X je Xová souřadnice, Y je Yová souřadnice a col by měla být barva pixelu. Všimněte si, že MCGA má 256 barev číslovaných od 0 do 255.
Mrkněte se na následující:
CGA = 4 colours
4x4 = 16
EGA = 16 colours
16x16 = 256
VGA = 256 colours
Protože EGA je CGA na druhou a VGA je EGA na druhou ;o)
Zpět do reality. Ačkoliv je předchozí procedura zapsaná v assembleru je pooomalá. Proč? Slyším , jak vaše pátrající mysl křičí. Důvod je jednoduchý: používá přerušení (volá int 10h). Přerušení jsou pooomalá … což je v pořádku při vstupování do módu MCGA, ale ne pro snahu položit pixel nato tata. Tak, proč nezkusit následující …
Procedure
MEMPutpixel (x,y : integer; col : byte);
begin
Mem [VGA: x+(y*320)] :=
col;
end;
Příkaz MEM, jak jsme viděli výše, vám dovoluje ukázat na daný bod v paměti … počáteční bod je $a000, základ VGA paměti, a pak specifikujeme jak daleko v paměti začneme. Přemýšlejte o monitoru následujícím způsobem. Začíná v levém horním rohu na 0. Jak zvyšujete číslo, začínáte se pohybovat napříč obrazovkou doprava, dokud nedosáhnete 320. Na 320 se vracíte napříč celou obrazovkou, a skončíte zpět vlevo o jeden pixel níž. Tak to pokračuje dokud nedosáhnete 63999, na spodní pravé straně monitoru. To je způsob jakým jsme získali rovnici x+(y*320). Pro každé zvetšení Y musíme k číslu přičíst 320. Jakmile jsme na začátku Y řádku, který chceme, přidáme takové X, jak daleko chceme být a pak to nastavíme na hodnotu pixelu, jaký chceme.
MEM metoda umístění pixelu je omnoho rychlejší, to je vidět v našem ukázkovém programu na konci lekce. ASPHYXIA tým nepoužívá ani jednu metodu. Používáme DMA-Straight-To-Screen-Kill-Yer-Momma-With-An-Axe typ putpixel metody, která je RYCHLÁ.
Užijte si naši ukázkou, snažte se vše pochopit a příští týden se budeme bavit s paletou.
Naschle všichni – Denthor
Pozn. překladatele jakékoliv
dotazy, připomínky můžete zaslat na adresu: ales.prog@centum.cz