                        A VideoManager unit lersa
                        ===========================

  A unittal meg lehet valstani a vibrlsmentes kpmegjelentst, azltal,
hogy az eljrsok elszr egy bufferben ptik fel a kpet, majd, ha ez
elkszlt, a fggleges visszatrst megvrva egy eljrs tmsolja a
vide memriba. Ez a unit a $13 - as, a 320x200-as 256 szn video md
kezelshez nyjt segtsget. A bufferes mdszer elnye, hogy megsznik
a vibrls, mivel a vide memria csak akkor mdusul, amikor az elektron-
sugr ppen fggleges visszatrsben van ( vertical retrace ). A mdszer
htrnya, hogy sokat kell msolni. Ahhoz, hogy egy animci elfogadhat
legyen, minimlisan 15 - 20 kpet kell megjelenteni msodpercenknt. Ez
azt jelenti, hogy msodpercenknt 15 * 64000 = 960000 bjtot kell a vide
memriba mozgatni, amihez bizony egy gyors gp kell... A htrnyok ellenre
tapasztalatom szerint elgg elterjedt ez a mdszer a jtkok krben
( kaland, szimulci ). A unit f rszt egy grafikus kprszlet msol
eljrs teszi ki. A grafikus kprszletek maximlis mrete 255 x 255 pixel
lehet, ami "sprite" mretnek elgg nagy, br egszkpernys httrgrafiknak
mr nem elg. A msol eljrs assembly nyelven rdott, gy sebessge
elfogadhat, s csak a kpernyre es kprszletet msolja, gy, hogy a
0 - s sznt nem msolja t, teht felhasznlhat sprite kezelsre, a btrabbak
jtkrson is gondolkodhatnak. Ezenkvl gyors vzszintes, fggleges, s
egy ltalnos vonalrajzol, pontrajzol, valamint palettabellt, stringkir
eljrsok kaptak helyet a unitban.
  Megjegyzs a rutinokkal kapcsolatban: A blokkmsol, karakterkir,
palettabellt rutinok elvgzik az adott feladatot, azaz ha tadunk nekik
egy pointert, ami a blokkra/palettra/karakterkszletre mutat. De az adott
informcik memriba tltse a unitot hasznl program feladata. Kivtelt
jelent a karakterkszlet, mivel egy "HALFFAT" s egy "SIMPLE" nev
karakterkszletet raktam a unitba, mint Inline szekvencit.
  Lssuk azokat a lehetsgeket, amelyekkel az informcik a rutinok "keze
gybe" helyezhetk: Mint kezdrtkkel elltott bjtos tmbt rakjuk be a
programba pl.: a palettt. Ez a megolds azonban nem csak fradsgos gpelst
jelent (hacsak nem ksztnk egy konvertert, ami kszt egy unitot, pldul a
karakterkszletbl ), hanem a max 64Kb mret adatszegmenset terheli, elveszi a
helyet vltozink ell. Egy msik megolds kls fjlknt trolni adatainkat.
Ez viszont sok kicsi fjlt jelent, ami sem nem elegns, sem nem bizton-
sgos (ha egy vletlenl letrldik...), a harmadik megolds, ami szerintem
dvzt, ha *.obj fjll alaktjuk adatainkat. Pl.: karakterszerkesztvel
ksztnk egy "MYCHAR.CHR" nev fjlt. Ezt "BINOBJ" programmal *.obj fjll
alaktjuk: BINOBJ MYCHAR.CHR MYCHAR.OBJ MYCHAR. lssuk a magyarzatot:
az els paramter a forrsfjl neve, a msodik az objektfjl neve, a harmadik
pedig az a nv, amivel majd hivatkozhatunk r programunkban. Ezek utn
helyezzk el programunkban a megfelel hivatkozst az objekt fjlra:

  procedure MyChar; external; {$L MYCHAR }

Ez annyit jelent, hogy a fordt a MyChar eljrs kdjhoz a MYCHAR kls
objekt fjl tartalmt rendeli hozz. Az ilyen defincikat rdemes
unitokba rakni, mivel ilyen objekt hozzrendels esetn a fordt az
adatokat a kdszegmensbe rakja.Mivel minden unithoz max. 64Kb-os
kdszegmens tartozhat, gy eloszthatunk akr 1Mb adatot is - 16 unit kztt.
Itt meg is mutatkozott a mdszer htrnya - egy objekt fjl maximum
64Kb adatot tartalmazhat, hiszen ennl nagyobb "nem fr" bele egy unit
kdszegmensbe. Hogyan hivatkozzunk a karakterkszletre ? Hasznljuk az
@ direktvt, vagy az Addr fggvnyt: (a kt kifejezs megegyezik, s mivel az
@ rvidebb ezrt okosabb ezt alkalmazni)

  SetCharType(@MyChar);

Ltezik mg egy "hibrid" megolds is: fjlunkat Inline szekvenciv alaktjuk,
majd egy eljrs trzst kpezzk vele:

  procedure MyChar;
  begin
    Inline($12/$34/$76/ ... $90);
  end;

Itt azonban szembe kell nzni azzal a tulajdonsgval a fordtnak, hogy
eljrsunk nem csak az Inline szekvencibl ll, hanem az els hrom
bjtja a verem elksztst vgzi:

  55     PUSH BP
  8B EC  MOV BP, SP
         .
         .
         .

Ezrt ha rmutatunk egy pointerrel: @MyChar, nem adatainkra mutat, hanem
hrom bjttal "korbbi" cmet tartalmaz. Ennek kikszblsre van a unitban
az "Adj" nev fggvny, amely korriglja a pointert, teht ha hasznlni
akarunk egy Inline-os eljrsra mutat pointert akkor hasznljuk az Adj
fggvnyt:

  SetCharType(Adj(@MyChar));

Akit rdekel a grafika, az elrhet az albbi cmen:

  Nmeth kos
  8230, Balatonfred
  Arany Jnos u. 5.

s most lssuk a unitot rszletesen:

  GRAFIKA KEZELSE:
  -----------------

procedure InitGraph;
  * bekapcsolja a grafikt,
  * elmenti az aktulis vide zemmdot SavedVideoMode vltozba
  * lefoglalja a szksges memrit a buffernek a heapben
      ha ez nem lehetsges hibazenettel lelltja a programot

procedure CloseGraph;
  * visszakapcsolja az eredeti, InitGraph meghvsa eltti vide zemmdot
  * felszabadtja a buffernek lefoglalt memrit


  BUFFER KEZELS:
  ---------------

procedure ClearBuffer;
  * trli a buffert ( 0 - val tlti fel )
    rdemes brmifle grafika megjelentse, fleg InitGraph utn meghvni,
    mert a buffer sohasem tiszta, mindg van benne valamilyen "szemt"

procedure CopyBuffer;
  * a buffer tartalmt tmsolja a $A000 -nl kezdd vide memriba,
    de gy hogy elbb megvrja a vzszintes visszatrtst


  GRAFIKUS BLOKK KEZEL ELJRSOK:
  --------------------------------

function GetBlockWidth(P: Pointer): Byte;
  * a P pointerrel megadott kprszlet szlessgt adja meg pixelben

function GetBlockHeight(P: Pointer): Byte;
  * a P pointerrel megadott kprszlet magassgt adja meg pixelben

procedure PutPlock(X, Y: Integer; P: Pointer);
  * a kperny X, Y  pozcijra msolja a P pointerrel magadott
    kprszletet. Csak a kpernyre es rszt jelenti meg, a 0 - s sznt
    ( transzparens szn ) nem msolja t.


  KARAKTER, STRING KEZELS:
  -------------------------

procedure PutChar(X, Y: Integer;Color: Byte; C: Char);
  * az X, Y pozcira rak ki egy C ASCII kd Color szn karaktert

procedure PutString(X, Y: Integer; C: Byte; S: String);
  * az X, Y pozcira rak ki egy C szn S stringet

procedure SetCharType(P: Pointer);
  * a P pointerrel megadott karakterkszletet lltja be.


  VONAL, PONTRAJZOLS:
  --------------------

procedure VLine(X, Y, Y1: Integer; Color: Byte);
  * egy fggleges vanalat rajzol X, Y koordinttl X, Y1 koordintig,
    Color sznnel

procedure HLine(X, Y, X1: Integer; Color: Byte);
  * egy vzszintes vonalat rajzol X, Y koordinttl X1, Y koordintig,
    Color sznnel

procedure Line(X, Y, X1, Y1, Color: Integer);
  * egy ltalnos vonalat rajzol X, Y koordinttl X1, Y1 koordintig,
    Color sznnel. Ezt a rutint a "VGA krtya programozsa" c. knyvbl
    rtam t assembly nyelvre. Az eredetije a knyv 147-150 oldaln tall-
    hat pascal nyelven, a knyv lemezmellkletn LINERUT.PAS nven szerepel.
    Br a knyv tartalmaz egy kln a 320x200 -as 256 szn vide mdra
    rt assembly nyelv eljsst 241-244 oldaln (a knyv lemezmellkletn a
    GR256.PAS nev unit forrsprogramjban tallhat "Line" nven ), de
    ez nem alkalmaz vgst a kperny szlnl, gy csak a kpernyn
    bell hasznlhat, ellenkez esetben, pl.: Line(12, 23, 1345, 233, 34),
    azaz 12, 23 -tl 1345, 233 -ig vonalat hzva a hats kiszmthatatlan...

procedure PutPixel(X, Y: Integer; Color: Byte);
  * egy Color szn pontot rak az X, Y koordintj kperny pozicira

function GetPixel(X, Y: Integer): Byte;
  * a Buffer X, Y koordintj pontjnak sznt adja vissza

  PALETTA KEZELS:
  ----------------

procedure SetPalette(Number, Red, Green, Blue: Byte);
  * a Number szn komponenseit lltja be. Piros = Red, Zld = Green,
    Kk = blue. A 0 - s szn a httr s a keret szne is. Mindegyik
    komponensnek csak az als 6 bitjt veszi figyelembe, gy
    0 - 63 tartomnyban llthatk be. A tbbi bitet figyelmen kvl
    hagyja. A palettabellts a VIDEO BIOS segtsgvel trtnik.

procedure GetPalette(Number: Byte; var Red, Green, Blue: Byte);
  * a Number szn komponenseit krdezi le. A piros komponenst a Red,
    a zld kmponenst a Green, a kk komponenst a Blue vltozba
    tlti.

procedure SetAllPalette(Palette: Pointer);
  * azt a palettt lltja be, amire a Palette pointer mutat.
    a palettt ler tmb szerkezete:

      PalType = Array[0..255] of Array[0..2] of Byte;

    Az els tmbindex a sznt lltja be, a msodik a sznkomponenst
    0 = Red ( Piros ), 1 = Green ( Zld ), 2 = Blue ( Kk ). Alltsunk
    be minden sznt feketre, a htteret pirosra:

    var
      P: PalType;
    begin
      FillChar(P, SizeOf(P), 0);      { Minden palettaelem nulla rtket kap }
      P[0][0] := 63;                  { A 0 -s szn 0 -s, azaz piros
                                        komponense 63 lesz                   }
      SatAllPalette(@Pal);
    end;

procedure GetAllPalette(Palette: Pointer);
  * a Palette mutat ltal meghatrozott vltozba tlti az aktulis
    palettt. pl.:

    var
      P: PalType;
    begin
      GetAllPalette(@P);
    end;

  KERET, KITLTTT TGLALAP RAJZOL ELJRSOK:
  --------------------------------------------

procedure Box(X, Y, X1, Y1: Integer; Color: Byte);
  * egy Color szn keretet rajzol aminek bal fels sarknak X, Y a
    koordintja, jobb als sarknak X1, Y1 a koordintja

procedure Bar(X, Y, X1, Y1: Integer; Color: Byte);
  * egy kitlttt Color szn tglalapot rajzol, amelynek bal fels
    sarka X, Y koordintj pont, jobb als sarknak koordinti:
    X1, Y1


  A UNIT VLTOZI:
  ----------------

GraphicsOn: Boolean;
  * True rtke jelzi, hogy grafikus mdban vagyunk, ellenkez esetben
    rtke False

SavedVideoMode: Byte;
  * ez a vltoz tartalmazza az InitGraph meghvsa eltti vide md szmt

Buffer: Pointer;
  * ez a vltoz tartalmazza az ideiglenes buffer cmt

BufSeg: Word;
  * az ideiglenes buffer szegmenscmt tartalmaz vltoz

Font: Pointer;
  * a karakter s stringkezel eljrsok ltal hasznlt karakterkszletre
    mutat pointer

FontSeg: Word
  * a hasznlt karakterkszlet szegmenscme

FontOfs: Word;
  * a hasznlt karakterkszlet offszetcme

  KIEGSZT ELJRSOK:
  ---------------------

function Adj(P: Pointer):Pointer;
  * arra szolgl, hogy egy Inline szekvencival definilt eljrsra mutat
    pointert kiigaztsa gy, hogy tnylegesen adatainkra mutasson. pl.:

    SetCharType(Adj(@SIMPLE));

function IsVGA: Boolean;
  * igaz rtket ad, ha van VGA krtya a rendszerben, egybbknt hamis
    rtket ad. Arra hasznlhatjuk, hogy programunk csak akkor indul el,
    ha VGA krtyt tall:

    begin
      If not IsVGA then
        begin
          WriteLn('Sajnos ez a program csak VGA krtyval elltott gpen fut!);
          Halt;
        end;
      .
      .
      .

procedure HALFFAT;
procedure SIMPLE;
  * ezek valjban nem eljrsok. Ne hvjuk meg ket, az eredmny katasztroflis
    lehet! Ezek ugyanis karakterkszletek. A unit inicializl rsze indulskor
    a SIMPLE karakterkszletet lltja be. Mi is bellthatjuk azt a karakter-
    kszletet amelyiket szeretnnk. Lsd az Adj eljrst!

							Nmeth kos