Vous êtes sur la page 1sur 117

VARGA MRTON

JTKPROGRAMOK KSZTSE
PASCAL S ASSEMBLY NYELVEN

A knyv nyomtatott formban megvsrolhat a

www.unisher.hu
oldalon

Minden jog fenntartva. A jelen knyvet elektronikus formban kizrlag a Magyar Elektronikus Knyvtr hozhatja nyilvnossgra, brmely ms felhasznlshoz a szerz rsbeli engedlye szksges.

Tartalom
Elsz...................................................................................................................................................................... 4 1. Alapfogalmak..................................................................................................................................................... 5 1.1. A VGA krtya zemmdjai, az MCGA zemmd ....................................................................................... 5 1.2. Kppont kigyjtsa ....................................................................................................................................... 5 1.3. Egy pixel sznnek lekrdezse .................................................................................................................... 6 1.4. A BOB-ok..................................................................................................................................................... 7 1.5. Az MCGA kp elmleti megjelentse ......................................................................................................... 7 1.6. A paletta ....................................................................................................................................................... 9
1.6.1. Egy szn RGB-komponenseinek olvassa .............................................................................................................. 10 1.6.2. Egy szn RGB-komponenseinek rsa.................................................................................................................... 10 1.6.3. Pldaprogramok a paletta mdostshoz .............................................................................................................. 10

2. BOB-ok megjelentse ..................................................................................................................................... 13 2.1. Egyszer BOB-megjelent ........................................................................................................................ 13 2.2. Tetszleges httr ....................................................................................................................................... 15 2.3. Tbb BOB egyszerre .................................................................................................................................. 18 2.4. Vltoztathat httr, animlt BOB-ok ........................................................................................................ 22 2.5. Teljes megjelents ..................................................................................................................................... 27 3. Billentyzet s egr.......................................................................................................................................... 34 3.1. A billentyzet mkdse ............................................................................................................................ 34 3.2. Az egr programozsa, a Mouse egysg..................................................................................................... 38 4. Httr ............................................................................................................................................................... 41 4.1. LBM kp betltse ..................................................................................................................................... 41 4.2. A MAP kpszerkezet .................................................................................................................................. 45 4.3. Megjelents ............................................................................................................................................... 47 4.4. Sor megjelentse........................................................................................................................................ 48
4.4.1. Legfels sor............................................................................................................................................................ 48 4.4.2. Brmely sor............................................................................................................................................................ 49 4.4.3. Tetszleges helyzet trkp egy sora ..................................................................................................................... 51

4.5. Oszlop megjelentse.................................................................................................................................. 54 4.6. Grdts ...................................................................................................................................................... 57


4.6.1. Jobbra .................................................................................................................................................................... 57 4.6.2. Balra....................................................................................................................................................................... 58 4.6.3. Fel .......................................................................................................................................................................... 59 4.6.4. Le ........................................................................................................................................................................... 60

4.7. Scroll pldaprogram, a MAP fjl formtuma.............................................................................................. 60 5. tkzsek ......................................................................................................................................................... 63 5.1. Egyszer BOB-BOB tkzs ..................................................................................................................... 64 5.2. Tnyleges BOB-BOB tkzs.................................................................................................................... 65 5.3. BOB-httr tkzs .................................................................................................................................... 70 5.4. BOB-BOX tkzs..................................................................................................................................... 71 6. BOB-EDITOR ................................................................................................................................................. 72 6.1. A program ltal hasznlt unitok.................................................................................................................. 72
6.1.1. Az MCGA egysg .................................................................................................................................................. 72 6.1.2. A _SYSTEM egysg.............................................................................................................................................. 73

6.2. A BOB-Editor megjelense s hasznlata .................................................................................................. 74


6.2.1. Menk.................................................................................................................................................................... 74 6.2.2. Szerkesztsi terlet................................................................................................................................................. 74 6.2.3. Paletta .................................................................................................................................................................... 75 6.2.4. llapotsor .............................................................................................................................................................. 75

6.3. Menk s funkcik ..................................................................................................................................... 76


6.3.1. A File men ........................................................................................................................................................... 76 6.3.2. Az Edit (szerkesztsi) men................................................................................................................................... 78 6.3.3. A Tools (eszkzk) men ...................................................................................................................................... 78

6.4. Funkcibillentyk ....................................................................................................................................... 80 6.5. Egyb lehetsgek ...................................................................................................................................... 81

7. MAP-EDITOR................................................................................................................................................. 82 7.1. A Menu egysg ........................................................................................................................................... 82


7.1.1. Eljrsok ................................................................................................................................................................ 82 7.1.2. Vltozk, konstansok............................................................................................................................................. 83 7.1.3. Pldaprogram......................................................................................................................................................... 83

7.2. A kperny felptse, az editor hasznlata ................................................................................................ 84


7.2.1. Menk.................................................................................................................................................................... 84 7.2.2. Trkpszerkesztsi terlet ...................................................................................................................................... 85 7.2.3. BOX-kivlaszt rsz .............................................................................................................................................. 85 7.2.4. BOX-szerkesztsi terlet........................................................................................................................................ 85 7.2.5. Paletta .................................................................................................................................................................... 85 7.2.6. llapotsor .............................................................................................................................................................. 86

7.3. Menk......................................................................................................................................................... 86
7.3.1. A File men ........................................................................................................................................................... 86 7.3.2. Az Edit (szerkesztsi) men................................................................................................................................... 87 7.3.3. Options (opcik) men .......................................................................................................................................... 88

7.4. Funkcibillentyk ....................................................................................................................................... 89 7.5. Tovbbi lehetsgek................................................................................................................................... 89 8. A GAME unit................................................................................................................................................... 91 8.1. DoneGame eljrs: az egysg lezrsa ....................................................................................................... 91 8.2. DoneKey eljrs: BIOS billentyzetmegszakts vissza............................................................................. 91 8.3. DrawBox eljrs: egy BOX megjelentse ................................................................................................. 92 8.4. FillBack eljrs: httr besznezse ............................................................................................................ 92 8.5. GrayPal eljrs: szrkesklv konvertls ................................................................................................ 92 8.6. HidePal eljrs: sznek egybemossa.......................................................................................................... 92 8.7. InitGame eljrs: az egysg inicializlsa .................................................................................................. 93 8.8. InitKey eljrs: mdostott billentyzetmegszakts................................................................................... 93 8.9. LoadLBM eljrs: kp betltse................................................................................................................. 94 8.10. LoadMap eljrs: trkp betltse............................................................................................................ 94 8.11. LoadPal eljrs: paletta betltse ............................................................................................................. 94 8.12. MakeScr eljrs: megjelents elksztse .............................................................................................. 95 8.13. NewPos eljrs: ugrs a trkpen ............................................................................................................. 95 8.14. PixelBack eljrs: httrpont megvltoztatsa.......................................................................................... 95 8.15. RetRace eljrs: vrakozs vertiklis visszafutsra .................................................................................. 96 8.16. Scroll eljrs: trkp grdtse ................................................................................................................. 96 8.17. SetArea eljrs: kp magassga................................................................................................................ 97 8.18. SetRGB eljrs: sznsszetevk vltoztatsa............................................................................................ 97 8.19. ShowPal eljrs: kivilgosts .................................................................................................................. 98 8.20. ShowScr eljrs: megjelents .................................................................................................................. 99 8.21. _KeyPressed fggvny: billentyzet figyelse.......................................................................................... 99 8.22. _ReadKey fggvny: SCAN-kd beolvassa ........................................................................................... 99 8.23. A BOB objektumtpus .............................................................................................................................. 99
8.23.1. Collision fggvny: tkzs BOB-bal ............................................................................................................... 100 8.23.2. CollBack fggvny: tkzs httrrel ................................................................................................................ 100 8.23.3. CollBox fggvny: tkzs trkpegysggel ..................................................................................................... 100 8.23.4. CollColors fggvny: tkzs httrrel.............................................................................................................. 101 8.23.5. Copy eljrs: BOB msolsa.............................................................................................................................. 101 8.23.6. Init eljrs: inicializls ..................................................................................................................................... 101 8.23.7. Load eljrs: Shape betltse............................................................................................................................. 102 8.23.8. OnScreen fggvny: lthatsg vizsglata ......................................................................................................... 102 8.23.9. Put eljrs: kpernyre rajzols ......................................................................................................................... 102 8.23.10. ShowUpon eljrs: prioritsvltoztats............................................................................................................ 102 8.23.11. A BOB tpus mezi.......................................................................................................................................... 103

8.24. A Game unit konstansai s vltozi........................................................................................................ 103 9. Pldajtk....................................................................................................................................................... 106 A lemezmellklet ismertetse ............................................................................................................................ 113 Trgymutat ...................................................................................................................................................... 114 Irodalomjegyzk ................................................................................................................................................ 117

Elsz
Sokan vannak, akik a szmtgppel csak jtszanak. Sokkal kisebb azoknak a tbora, akik kedvtelsbl, idtltsbl sajt maguk is rnak jtkokat, mg akkor is, ha ezek sznvonala jcskn alulmarad a kereskedelmi forgalomban lvknl. Igaz, hogy egy jtkprogram elksztse lnyegesen nehezebb, mint egy ksz jtk hasznlata, viszont sokkal rtelmesebb tevkenysg annl. A legtbb jtk csak a kzgyessget fejleszti, mg jtkprogram-rshoz szksges nmi fantzia, kreativits, tletek, grafikai kszsg stb. is. E knyv s lemezmellklete segtsgvel kszthet jtkok megjelensket tekintve ktdimenzisak, felbontsuk 320200, szneik szma 256. A knyv megrtshez elengedhetetlen a Pascal s az assembly nyelv ismerete, jtkok ksztshez azonban elegend a Pascal, mert a lemezmellkleten tallhat egy olyan programknyvtr (Game unit), ami magba foglalja a jtkok ksztshez nlklzhetetlen gpi rutinokat. A lemezmellkleten tallhat programok futtatshoz s a knyv alapjn ksztett jtkokhoz az albbiakra lesz szksg: egy IBM AT tpus szmtgpre, egy 286-os vagy annl fejlettebb processzorra, egy tetszleges VGA krtyra, Turbo Pascal 7.0 fejleszti krnyezetre. A programok szp s egyenletes futshoz azonban ez nem elg, ehhez legalbb egy 80-90 MHz-es processzor s egy PCI buszos VGA krtya kell. Jtkprogramok ksztshez sok sikert kvn A szerz jatek@vamarton.hu

1. Alapfogalmak
1.1. A VGA krtya zemmdjai, az MCGA zemmd
A VGA krtyk tbbfle zemmdban kpesek mkdni, melyek alapveten ktflk lehetnek, szveges s grafikus mdok. A szveges mdok karakteres kpernyt hasznlnak, felbontsuk vltoz, a leggyakrabban hasznlt a 8025 karakteres kpernyfelbonts. A grafikus kperny pixeleket tartalmaz, melyek lehetnek kett, 16 s 256 sznek. Nem rdemes a klnbz zemmdok felbontst, szneinek szmt stb. elemezgetni, mert jtkaink csak az MCGA (vagyis a 320200/256 szn) zemmdot alkalmazzk. MCGA videomdban a kperny felbontsa 320200, azaz vzszintesen 320, fgglegesen 200 pixelt tartalmaz. Ez a felbonts elg gyenge a ma hasznlatos SVGA felbontsokhoz kpest, viszont elnye, hogy knnyen kezelhet, s minden VGA krtyn alkalmazhat. Az MCGA az egyetlen a hagyomnyos szabvnyos VGA grafikus mdjai kzl, amelyik 256 sznt tud egyszerre megjelenteni. A memriban a kezdcme A000:0000, egy bjt egy pixelnek felel meg, melyek sorfolytonosan vannak trolva, balrl jobbra, fentrl le. A kperny helyignye 320200, azaz 64000 bjt, ami majdnem lefoglalja a teljes videomemrit (az $A000-s szegmenst). A matematikban hasznlthoz hasonl koordinta-rendszert hasznlunk, hogy a pontokat meg tudjuk klnbztetni, csak itt az ordintatengely (Y tengely) fordtott lls, lefel mutat. A (0;0) pont, az orig, a kperny bal fels sarkban tallhat kppont, gy cme: $A000:0000. Ettl jobbra az els, ettl lefele a msodik koordinta n. Pldul a $A000:0005 cm pont koordinti: (5;0). A koordintk rtelemszeren csak termszetes szmok lehetnek Egy pont abszcisszja (els koordintja) bele kell, hogy essen a [0..319] intervallumba, ordintjnak (msodik koordintjnak) pedig [0..199] kztt kell lennie. Ez a kperny MCGA zemmdbeli mrete miatt van (320200).

1.2. Kppont kigyjtsa


Azoknl a jtkoknl, melyeknl a f hangsly a grafikn van, nagyon fontos tudni, hogyan kell a kperny egy pontjt valamilyen sznre befesteni. Minden rajzols alapja a pont-rajzols, ezrt legelszr ezt kell megismerni. Szerencsre az MCGA kpszerkezet felptsnek ksznheten ez nem tl nehz feladat. Egy (X;Y) koordintj pont kirajzolshoz szksges kplet: CM=320*Y+X Ez nem egy nagy rdngssg, ebbl is lthatjuk, hogy a memriban a sorok egymst kveten helyezkednek el. Teht az A000. szegmensen az els 320 bjt az els sornak, a msodik 320 a msodik sornak felel meg, s gy tovbb. A kvetkez rvid pldaprogram bemutatja az MCGA zemmd be- s kikapcsolst, s pixelek kirajzolst. {putpixel.pas} procedure PutPixel( X,Y: word; C: byte); assembler; asm { (X;Y) helyzet C szn pont rajzolsa mov es,sega000 { A vidememria szegmenst a SEGA000 sz { tartalmazza, rtke $A000 mov ax,320 { A kp szlessge 320 pixel mul Y { A pont sornak kezdcme: 320Y add ax,X { A pont cme: 320Y+X mov di,ax { ES:[DI] a felgyjtand pont cme mov al,C { C-t kell rni ebbe a bjtba mov es:[di],al { Pixel kigyjtsa end; procedure MCGA_On; assembler; asm { MCGA zemmd bekapcsolsa mov ax,0013h { 00h zemmd, 13h funkci int 10h { 10h sorszm megszakts end; } } } } } } } } }

} } }

procedure MCGA_Off; assembler; asm { Visszatrs a szveges zemmdhoz mov ax,0003h { A 8025-s md a 03h funkci int 10h { Megint a 10h megszaktst hasznljuk end;

} } }

begin MCGA_On; PutPixel( 0, 0, 12); { A kperny ngy sarkba ngy klnb- } PutPixel( 319, 0, 13); { z szn pont kirajzolsa } PutPixel( 0, 199, 14); PutPixel( 319, 199, 15); readln; { Enter megnyomsra kilp } MCGA_Off; end. Az els eljrs, a PutPixel, egy C szn s (X;Y) koordintj pontot rajzol a kpernyre. A memriba rni Turbo Pascalban a MEM[ ] tmbbel lehet, teht a PutPixel eljrs helyett elg lett volna a MEM[$A000:320*Y+X]:=C rtkad utasts is. Viszont a ksbbiekben fleg assembly eljrsokat alkalmazunk, ezrt ismerni kell a pixel kirajzolshoz szksges assembly eljrst is. A program elszr bekapcsolja az MCGA zemmdot, a 10h megszakts segtsgvel. Jtkok ksztse szempontjbl a 10h megszakts funkcii nem fontosak, csupn ez a kett, amivel be- illetve kikapcsoljuk a 320200/256-os kpszerkezetet. Ezutn ngy, egy piros, egy lila, egy srga s egy fehr pontot gyjtunk ki a kperny ngy sarkba, majd kilps eltt visszalltjuk a szveges zemmdot. Ezt sohase felejtsk programunk befejezse el beiktatni, mert lehet, hogy csak gpnk jraindtsval tudunk ksbb karakteres kpernyt hasznlni. Pixelek rajzolsa nem tl bonyolult, elszr ki kell szmolni a kpcmet a koordintkbl (320Y+X), majd erre a cmre ki kell rni azt a bjtot, ami a kvnt sznhez tartozik. Az eljrsnak rgtn az els sorban tallhat a SegA000 vltoz. Ez a System unit egyik tipizlt konstansa (inicializlt kezdrtk vltozja), rtke $A000, vagyis az MCGA kp szegmenscme. Elnye pedig az, hogy a szegmensregisztereknek egy utastssal rtk adhat, nem kell valamelyik ltalnos cl regisztert, pldul az akkumultor regisztert kzbeiktatni. A kt albbi assembly utasts mov ax,0a000h mov es,ax helyett teht elg a kvetkez: mov es,sega000 Tovbbi elnye ennek a konstansnak, hogy vdett mdban is hasznlhat, mg az elz megolds ott nem mkdne, hiszen vdett mdban a szegmensek szervezse egszen mshogy mkdik, mint vals mdban.

1.3. Egy pixel sznnek lekrdezse


Csak a teljessg kedvrt foglalkozunk ezzel a problmval, ami valjban egy jtk rsa sorn szinte sohasem kerl el. Ugyanazt a kpletet hasznljuk, amit a pixel kiraksnl, csak nem rjuk, hanem olvassuk a kpernyrl az egybjtnyi adatot. A legrdekesebb dolog az egsz fggvnyben taln az, hogy a visszatrsi rtkt az AL regiszterben kell megadni. Ez jl alkalmazhat brmely ms assembly fggvnyben, pldul a function Fgv: byte; assembler; asm ... end; szubrutin vgn ha az AL-be berunk 3-at, az lesz a Fgv rtke, gy, mintha Pascalban rtuk volna, s a vgn kiadtuk volna az FGV:=3; rtkad utastst. function GetPixel( X,Y: word): byte; assembler; asm { Az (X;Y) koordintj pont szne } mov es,sega000 { A vidememria szegmenst a SEGA000 sz } { tartalmazza, rtke $A000 } mov ax,320 { A kp szlessge 320 pixel } mul Y { A pont sornak kezdcme: 320Y } add ax,X { A pont cme: 320Y+X }

mov mov end;

di,ax al,es:[di]

{ ES:[DI] a leolvasand pont cme { A fggvny visszatrsi rtke AL-ben

} }

1.4. A BOB-ok
A BOB-ok olyan tglalap alak grafikai objektumok, melyek tetszlegesen mozgathatak, eltntethetek s megjelenthetek. Szintn 256 sznek, tbb fzisbl (mozdulatokbl) llhatnak. A BOB elnevezs az Amiga gpekrl szrmazik, a Blitter OBject rvidtse. Akik jrtasak a Commodore 64 programozsban, azok tallkoztak mr a Sprite fogalommal. Nos, a BOB-ok is hasonl funkcit ltnak el, mint a Sprite-ok, azzal a klnbsggel, hogy a Sprite-ok ellltsa a hardver feladata, a BOB-ok programozsrl viszont neknk kell gondoskodni, szoftveres ton. A bobot teht nevezhetnnk akr szoftver SPRITE-oknak. Egyszerre tbb BOB-bal is dolgozhatunk, ezek egymstl s a httrtl is fggetlenek. BOB-nak tekinthet pldul az egr ikonja grafikus kpernyn, ami ltalban nyl formj. Vagy pldul BOB egy jtkban egy fut ember, radsul tbb fzis. Egy tbbfzis BOB olyan, mintha tbb, azonos mret egyfzis BOB-ot jelentennk meg egyms utn. Egy BOB bizonyos rszein ttetsz (transzparens) lehet, vagyis ott az ltszik, ami mgtte van (httr, egy msik BOB). Shape-nek nevezzk a BOB grafikus adatait a memriban. Egy egyfzis, W szlessg, H magassg Shape helyfoglalsa WH bjt. Ha ennek a BOB-nak nem csak egy, hanem P fzisa van (P>1), akkor bjtban mrt memriaignye PWH. A Shape-et dinamikus vltozknt troljuk, GetMem-mel foglalunk neki PWH bjt hosszsg memrit. A BOB adatait az adatszegmensben, Object tpus vltozknt, objektumknt deklarljuk. Ide tartozik pl. a BOB szlessge, magassga, fzisainak szma, bjtban vett helyfoglalsa, sorszma, s itt adjuk meg a Shape-re mutat pointert is.

1.5. Az MCGA kp elmleti megjelentse


MCGA kpszerkezet esetben a kpernyn megjelentend adatok az $A000 szegmens els 64000 bjtjn helyezkednek el, a bal fels sarokban lv pontot pl. a MEM[$A000:0000] tmbbel rhetjk el. Egy bjt egy kppont sznt hatrozza meg. A VGA krtya ebbl a tartomnybl olvassa ki a kppontokhoz szksges adatokat, majd ezeket a bjtokat a monitor szmra is rthet jelekk alaktja. A monitornak msodpercenknt legalbb 25-szr kell felfrisstenie a kpet ahhoz, hogy szemnk a vltozsokat folyamatosnak rzkelje, ne legyen darabos s villog. A kpalkots a monitorban az elektronsugr segtsgvel megy vgbe. Ez a sugr minden msodpercben tbbszr vgigpsztzza a kpcs felnk es tglalap alak rszt, a kpernyt. Szembl nzve a bal fels sarokbl indul, vgighalad egy soron, vzszintesen, majd jra a kperny bal oldalra ugrik, a kvetkez sorra. Ezt a bal oldalra trtn visszatrst nevezzk horizontlis visszafutsnak (horizontal retrace), amely minden sor vgigpsztzsa utn bekvetkezik. Amikor az utols soron is vgigszaladt az elektronnyalb, bekvetkezik a vertiklis visszafuts (vertical retrace), amikor a jobb als sarokbl a bal felsbe ugrik. Ezutn kezddhet az egsz ellrl. Az elektronsugr teht kigyjtja a kperny pontjait. Ezek nem alszanak el rgtn, hanem tovbbra is ingerelt llapotban vannak, tovbb vilgtanak. Ezrt ha egy kppont hossz ideig ugyanolyan szn, akkor az folyamatosan ltszik, nem alszik el teljesen. A televzis kszlkekben az elektronsugr elszr a pratlan, majd a pros sorokon halad vgig. Msodpercenknt 50 flkpet jelent meg, azaz 25 teljes kpet. Ekkor mondjuk, hogy a TV-kszlk 50 Hz-es. A monitorok ltalban 60-70 Hz-esek, de itt nem mindig rvnyes ez a flkp-kiraks mdszer. MCGA zemmdban gy kell az egszet elkpzelni, hogy az elektronsugr folyamatosan rajzol, kivve horizontlis s vertiklis visszatrsekor. Ilyenkor kialszik a nyalb, hiszen ha ilyenkor is felgyjtan a kppontokat, az zavar lenne. A horizontlis s a vertiklis visszafutst figyelni tudjuk, meg tudjuk vrni amg egy ilyen visszafuts bekvetkezik. A VGA krtya $03DA llapotregisztere alkalmas erre a clra. A 0. bit a vertiklis vagy horizontlis, a 3. bit csak a vertiklis visszafutst jelzi. ltalban ezt a bitet figyeljk, mert ha egy vertiklis visszafuts kzben kezdnk a kpernyre rni, akkor az egyszerre s egyben fog megjelenni. Ha nem figyeljk az elektronsugarat, s gy vltogatjuk egyms utn a klnbz tartalm kpeket, akkor ez darabossghoz vezet.

Vegynk egy pldt: fekete s fehr kpernyket vltogassunk egyms utn. Ez egyszer memriba rssal megvalsthat, 64000 darab 0, utna megint 64000 darab 15 rtk bjtot runk ki az $A000:0000 cmtl kezdve. Az elektronsugr haladsa lassabb, mint a memriba rs. Tegyk fel, hogy a kperny kzepn jr, s a 100. sort kezdi ppen frissteni. A kp eddig fekete volt, de mi most hirtelen fehrre vltoztatjuk, azaz a vidememria bjtjait 15-s rtkkel tltjk fel. Ez elg gyorsan vgbemegy, tegyk fel, hogy kzben az elektronsugr csak a 101. sorig jutott. Eddig csak fekete pontokat rajzolt (azaz nem rajzolt semmit), hiszen a kpmemriban nulla rtk bjtokat tallt. A kperny fels rsze teht fekete. Most a 101. sor kirajzolsa kezddik. E sor els kppontjhoz tartoz bjt rtke viszont mr nem nulla, hanem 15, hiszen elzleg az egsz kpmemrit 15-tel teltettk. Teht innentl kezdve a kperny fehr lesz. Egyszval a kp fels fele fekete, az als fehr egszen addig, amg be nem kvetkezik egy jabb frissts. A kp teht feketrl fehrre vltott, de ez a vlts a kperny kzepn ment vgbe. Ha sokszor egyms utn vgznk el ilyen teljes kpernys szn-vltsokat, akkor az ezzel a mdszerrel darabos lesz, nem lesz szp. De nzznk egy rvid pldaprogramot, mely illusztrlja az ilyen sznvltsok zavar hatst. (rdemes megjegyezni, hogy a teszt sem a szemnek, sem a monitornak nem tesz jt.) {villog1.pas} uses Crt; procedure Fill( C: byte); { mov es,sega000 { xor di,di { mov cx,32000 { mov al,C mov ah,al rep stosw { end; begin asm mov ax,13h int 10h end; repeat Fill( 0); Fill(15); until keypressed; readkey; asm mov ax,03h int 10h end; end. assembler; asm Kperny befestse C sznre A SEGA000 rtke elre meghatrozott, A $A000:0000 cmtl indulunk (ES:[DI]) 320200 bjt=32000 sz kirsa gy a leggyorsabb s a legrvidebb } } } } }

{ MCGA zemmd bekapcsolsa

{ A kperny vltakozik, fekete vagy fehr} { Billentynyomsra vge } { A gomb kdja ne maradjon a pufferben } { Visszatrs a szveges mdhoz }

A program mint ahogy azt szerettk volna vltogatja a kperny sznt, egyszer feketre, egyszer pedig fehrre. Elvileg. A gyakorlatban ez ennl a pldnl nem valsulhat meg, mert a fent emltett okok miatt a kperny sohasem lesz teljesen fehr vagy fekete. Mindig lesz benne egy trsvonal, s radsul mindig ms helyen. Ha az elektronsugarat figyeljk, s a vertiklis visszafuts bekvetkeztekor kezdjk el kirakni a 64000 bjtot, a vlts nem lesz darabos, villog. Ehhez persze szksges az is, hogy a bjtok rsnak sebessge gyorsabb legyen a visszatrsnl, ellenkez esetben az adatkivitelt beri, s gy hasonlan darabos lesz a kpnk (csak a trsvonal krlbell lland helyen lthat). De egy 80 MHZ-es gp sebessge mr legyzi az elektronsugarat. Nzzk az eljrst, ami egy vertiklis visszafuts bekvetkeztig vrakozik! procedure Retrace; assembler; asm { Vertiklis visszafutsra vrakozs } mov dx,03dah @1: { A $3da port 3. bitje 1, ha ppen felfe- } in al,dx { le halad az elektronsugr } test al,8 jz @1 end;

Ezt a szubrutint mindig kzvetlenl a kpre rs eltt alkalmazzuk, mert ha korbban tesszk, akkor az elektronsugr mr elkezd rajzolni, s a kp darabos lesz. Bvtsk a VILLOG1.PAS deklarcis rszt a fenti RetRace eljrssal, s a repeat until fciklust a kvetkezre mdostsuk (a bvtett program a VILLOG2.PAS a lemezmellkleten): repeat Retrace; Fill( 0); Retrace; Fill(15); until keypressed; Mg egyszer az egsz elektronsugr-figyels lnyege: ha akkor mdostjuk a kperny tartalmt, amikor az elektronsugr fgglegesen visszatr, a vltozs egyszerre kvetkezik be, nem lesz darabos. Ez persze felttelezi azt, hogy a kpmemria bjtjainak vltoztatsa nem tart tbb ideig mint egy vertiklis visszafuts, s amint elkezddik egy ilyen visszafuts, rgtn el kell kezdeni mdostani, hogy elg legyen az id. Teht az egyenletes futs rdekben nem csak alkalmazni kell a fenti (RetRace eljrsban elhelyezked) sorokat, hanem j helyen kell alkalmazni.

1.6. A paletta
A sznes monitorok kppontjai hrom, egy vrs, egy zld s egy kk rszbl llnak. A kppont szne ennek a hrom sszetevnek (alapszn komponensnek) a intenzitstl fgg. A VGA krtyk az MCGA kpszerkezetnl 256 sznt tudnak egyszerre megjelenteni. Minden sznhez hozz van rendelve hrom [0..63] zrt intervallumba es egsz szm, mely a szn sszetevinek erssgt hatrozza meg. Az MCGA mdban a paletta felptse a kvetkez. Minden sznsszetev egy bjton van trolva, amely bjtnak csak az als 6 (0-5.) bitje hasznlatos, a kt legmagasabb helyrtk bit llapota lnyegtelen. Minden sznnek hrom, vrs (red), zld (green) s kk (blue) sszetevje van, gy a paletta mrete 3256=768 bjt. A kvetkez tblzatban az alaprtelmezett VGA paletta els tizenhat sznnek RGB (vrs-zld-kk) komponensei olvashatak. (Alaprtelmezett paletta a beptett, az MCGA videmd bekapcsolsa utn kzvetlenl aktv paletta.) Szn 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Neve Fekete Kk Zld Trkiz Vrs Lila Barna Vilgosszrke Sttszrke Vilgoskk Vilgoszld Vilgos trkiz Vilgos piros Vilgos lila Srga Fehr Crt-azonost Black Blue Green Cyan Red Magenta Brown LightGray DarkGray LightBlue LightGreen LightCyan LightRed LightMagenta Yellow White R 0 0 0 0 42 42 42 42 21 21 21 21 63 63 63 63 G 0 0 42 42 0 0 21 42 21 21 63 63 21 21 63 63 B 0 42 0 42 0 42 0 42 21 63 21 63 21 63 21 63

Ebbl a tblzatbl krlbell ltni lehet, hogy melyik komponens milyen arny keverse milyen sznt eredmnyez. Sejthetjk, hogy a sttlila komponensei pldul a 21,0,21 lehetnek, s hogy szrke szneket gy llthatunk el, hogy a komponensek rtkei megegyeznek. rdemes a lemezmellkleten tallhat s az 1.6.3. fejezetben lert RGBSET.PAS pldaprogrammal ksrletezni, hogy ksbb, a grafikk ksztsnl mr jrtasak legynk az additv sznkevers sajtossgaiban.

A keret szne megegyezik a 0. sznnel, ami alapllapotban fekete. Ezrt ezt nem rdemes mdostani, mert ha megvltoztatjuk, nem lesz olyan szp a jtkunk, nem fog gy tnni pldul egy besz BOB, hogy a kperny szlbl csszik be. Ettl fggetlenl persze ppgy megvltoztathatjuk, mint brmely msik sznt, ha ez a clunk. A paletta szneit tetszlegesen mdosthatjuk, gy minden szn 646464=262144 fle RGB rtket vehet fel. sszesen teht ennyi, egyszerre azonban 256 a megjelenthet sznek szma. A vltoztats a VGA krtya $03C7-$03C9 regiszterein keresztl valsulhat meg.

1.6.1. Egy szn RGB-komponenseinek olvassa


Nagyon egyszer feladat. A $03C7 olvass cmregiszterbe (RGB Read Adress) az olvasni kvnt szn szmt rjuk. Ezutn a $03C9 adatregiszter (RGB Data) hromszor egyms utn olvasva megkapjuk a hrom rtket, elszr a vrs (R), majd a zld (G), vgl a kk (B) sszetevt. A kvetkez eljrs a fejben megadott R,G,B bjt tpus vltozkban megadja az N. szn alapkomponenseinek rtkt: procedure GetRGB( N: byte; var R, G, B: byte); assembler; asm { Az N. szn RGB-komponensei mov dx,03c7h { RGB olvass cmregiszter mov al,N { Jelezzk a krtynak, hogy az N. sznout dx,al { nel fogunk dolgozni (most: olvasni) mov dx,03c9h { RGB adatregiszter in al,dx { Els sszetev lekrdezse les di,R stosb in al,dx { Msodik sszetev lekrdezse les di,G stosb in al,dx { Harmadik sszetev lekrdezse les di,B stosb end;

} } } } } } } }

1.6.2. Egy szn RGB-komponenseinek rsa


Ez az elzhz hasonlan szintn nagyon egyszer feladat. Elszr a $03C8 RGB rs cmregiszterbe (RGB Write Adress) a kvnt szn szmt kldjk, majd a $03C9 adatregiszter hromszori rsval llthatjuk be a megfelel rtkeket, a vrs (R), a zld (G) s vgl a kk (B) sszetevt. Erre is nzznk egy pldt, ahol N a vltoztatni kvnt szn szma, R, G, B, pedig az sszetevi. procedure SetRGB( N, R, G, B: byte); assembler; asm { Az N. szn sszetevinek vltoztatsa mov dx,03c8h { RGB rs cmregiszter mov al,N out dx,al { N. szn mdostsa mov dx,03c9h { RGB adatregiszter mov al,R out dx,al { R sszetev rsa mov al,G out dx,al { G sszetev rsa mov al,B out dx,al { B sszetev rsa end; } } } } } } }

1.6.3. Pldaprogramok a paletta mdostshoz


Az els program segt gyakorolni az ppen szksges szn belltst. Ez a sznvltoztat mdszer a ksbbi grafikink elksztsben nagy szerepet fog jtszani, mert gy lehet belltani egy sznt, hogy kzben ltjuk azt, s az alapkomponenseinek rtkeit is. Nem lenne sszer egy program grafikai rsznek

10

palettamdostsait szmokkal bevinni, azaz nem clszer egy jtk grafikjhoz gy kitallni a sznek sszetevit, hogy kzben magt a sznt nem is ltjuk. A programban a httr s a keret sznt, vagyis a 0. sorszm sznt fogjuk mdostani. Indts utn a bal fels sarokban hrom fehr (15) szmot ltunk, ezek a httr R-G-B alapkomponensei. A kvetkez billentyk segtsgvel vltoztathatjuk ezeket az sszetevket: Q : R komponens nvelse A : R komponens cskkentse R G B W : G komponens nvelse + Q W E S : G komponens cskkentse A S D E : B komponens nvelse D : B komponens cskkentse {rgbset.pas} uses Crt; const R: byte = 0; G: byte = 0; B: byte = 0; var C: char; procedure SetRGB( N, R, G, B: byte); assembler; ... { Ez az elz eljrs } begin textbackground( black); { Kivtelesen szveges zemmdot alkaltextcolor( white); { mazunk, a palettt itt is meg lehet clrscr; { vltoztatni, de csak 16 szn ltszik gotoxy( 1, 3); writeln('Billentyk: Q/A: R+/-; W/S: G+/-; E/D: B+/-;'+ ' ESC: Kilps'); repeat gotoxy( 1, 1); write( R:3,' ', G:3,' ', B:3); C:= readkey; case upcase( C) of 'Q': if R<63 then inc(R); { R sszetev nvelse 'A': if R>00 then dec(R); { R sszetev cskkentse 'W': if G<63 then inc(G); { G sszetev nvelse 'S': if G>00 then dec(G); { G sszetev cskkentse 'E': if B<63 then inc(B); { B sszetev nvelse 'D': if B>00 then dec(B); { B sszetev cskkentse end; SetRGB( 0, R, G, B); { RGB sszetevk vltoztatsa { ESC-re kilps a programbl until c=#27; SetRGB( 0, 0, 0, 0); { A mdostott szn visszalltsa end.

{ Alapllapotban a httr s a keret, { vagyis a 0. sorszm szn fekete, RGB { sszetevinek rtke nulla

} } }

} } }

} } } } } } } } }

A msodik pldaprogram segtsgvel megnzhetnk egy httrtroln trolt palettafjlt. ltalban a 256 sznt hasznl jtkok a grafikhoz szksges palettt egy 768 bjt hosszsg fjlban troljk, melynek gyakori kiterjesztse a .PAL . A sznek alapkomponensei egy-egy bjton vannak trolva, sorban, gy jn ki a 768 bjtos hosszsg. Mi is ebben a formtumban mentjk majd el palettinkat, ezrt nha szksges lehet megtekinteni egy-egy ilyen fjlt. A program paramterben kell megadni a fjlnevet kiterjesztssel s tvonallal, ha szksges, majd futtats utn megjelenik a paletta. Billentynyomsra lehet kilpni.

11

{viewpal.pas} uses Crt; { Egy szn komponensei type Colors = record R,G,B: byte; end; var f: file; { Vltoz a fjlmveletekhez x,y: byte; { A FOR... ciklusokhoz vltozk Palette: array[0..255] of Colors; { Paletta sznei procedure Box8x8( X,Y: word; C: byte); { 88-as ngyzet kirajzolsa, bal fels var i,j: byte; { sarka koordinti: (X;Y) begin { Most nem assembly utastsokat runk, for i:= 0 to 7 do { mert a sebessg annyira nem fontos for j:= 0 to 7 do mem[$A000:320*(y+i)+(x+j)]:= C; end; procedure SetRGB( N, R, G, B: byte); assembler; asm ... { Ez az eljrs mr szerepelt feljebb } end; begin if paramcount=0 then halt; { Ha a paramterben nem adunk meg { semmit, lell a program futsa asm mov ax,13h int 10h { MCGA zemmd bekapcsolsa end; assign( f, paramstr( 1)); reset( f, 1); blockread( f, Palette, 768); { Fjl tartalmnak tltse close( f); for x:= 0 to 255 do with Palette[x] do SetRGB( x, R, G, B); { Paletta belltsa (a 'Palette' vltoz { adatai szerint) ... for x:= 0 to 15 do for y:= 0 to 15 do Box8x8( x*8, y*8, 16*y+x); { ... s megjelentse readkey; asm mov ax,03h int 10h { MCGA zemmd kikapcsolsa end; end. }

} } } } } } }

} } }

} } } }

12

2. BOB-ok megjelentse
Ebben a fejezetben megismerkednk a BOB-ok megjelentsnek klnbz lehetsgeivel. Lpsrl lpsre haladunk, a legegyszerbb megjelenttl a legsszetettebbig. Minden lehetsget kln pldaprogrammal szemlltetnk, melyekhez igyeksznk rszletes magyarzatot adni. A kulcseljrsok, azaz a legfontosabb, a megjelentst vgz eljrsok mindig assembly sorokbl llnak, hiszen mint azt ksbb ltni fogjuk msodpercenknt tbbszr vgre kell hajtani ezt a mveletet. Vegynk egy pldt. Egy BOB-ot mozgatni akarunk. A mozgs akkor lesz tkletes, ha kicsi lpsekbl ll, s kt lps kztt kevs id telik el. s ha tbb BOB-bal dolgozunk, mr lnyegesen szmt, hogy ezt a kulcsfontossg BOB-megjelentst vgz eljrst Pascalban vagy assemblyben rjuk. A legsszetettebb BOB-megjelents a kvetkez lehetsgekkel rendelkezik: Egyszerre tbb BOB s a httr is lthat a kpernyn. A httr fggetlen a grafikus objektumoktl, s akr tetszlegesen vltozhat is (pldul a grgetsnl). A BOB-ok tetszleges helyzetek, mretek s fzisak lehetnek. A BOB-ok bizonyos rszeiken tltszak (transzparensek) lehetnek, vagyis ezeken a pontokon a mgttk lv tartalom ltszdik, ami lehet a httr vagy egy msik BOB rsze. Ha egy BOB P. fzisnak (X;Y) pontja tltsz, akkor a Shape PWH+WY+X. bjtja zrus. W a Shape bjtban vett szlessgt, H pedig a magassgt jelli. Ha kt BOB egymson helyezkedik el, akkor meghatrozott, hogy melyik van fell, azaz melyik ltszik teljes egszben, s melyik van takarsban. (Meghatrozott a BOB-ok prioritsa.) A BOB-ok kilghatnak a kpbl, azaz nhny esetben csak egy rszk lthat. Ilyenkor gyelni kell arra, hogy nem kell s nem is szabad az egsz BOB-ot megjelenteni. A villogst s a darabossgot lehetsg szerint legjobban ki kell kszblni. Nehz lenne elsre az sszes pontot teljesteni, s megrtse is bonyolult lenne. ppen ezrt bontsuk szt a lpseket, s mindig tegynk hozz valamit, hogy a vgn megvalsthassuk a fenti kitteleknek eleget tev eljrst.

2.1. Egyszer BOB-megjelent


Ez a megjelent annyira primitv lesz, hogy csak igen nagy tlzssal lehet BOB-megjelentnek nevezni. A magunk el clul kitztt kritriumok kzl egyet sem teljest. Egyszerre csak egy, 1616-os mret, egy fzis, tltszatlan BOB-ot tudunk ltrehozni. Az egsznek rajta kell lennie a kpen, nem tud beszni. A httr egyszn, a megjelents pedig meglehetsen villog, lvezhetetlen. Viszont a f eljrs knnyen rthet, s j alapot ad a ksbbi, bonyolultabb megjelentkhz. Ez a BOB-brzols nagyon hasonlt a Turbo Pascal Graph egysgnek Putimage eljrshoz. Lnyege az, hogy a memrinak egy bizonyos helyrl (ahol a Shape van) 1616, azaz 256 bjtot kell tmsolni a kpmemria egy bizonyos bjtjtl kezdve (amit a BOB koordinti alapjn hatrozunk meg), de kzben a sorokat szt kell trdelni. Az eljrs vzlata: 1. Tegyk fel, hogy egyszer mr lefutott az eljrs, s a BOB lthat a kpernyn. A kpmemria azon rszt, amelyben a BOB helyezkedik el, fell kell rni a httr sznvel. gy onnan letakartjuk a BOB-ot. Most nagyon gyorsnak kell lenni, hiszen ilyenkor nem ltszik a BOB, s ha tl sokat vrunk, az villogshoz vezet. 2. A BOB brzolsa. DS:[SI]-be a Shape, ES:[DI]-be a kperny kezdcmt ($A000:0000) tltjk, majd DI-hez hozzadunk 320Y+X-et. Teht kiszmtjuk azt a cmet, ahov a BOB kerl, s ezt betesszk a DI regiszterbe. DS:[SI]-rl ES:[DI]-re msoljuk a Shape adatait a rep movsw utastssal. Minden sor kiraksa utn DI-hez hozz kell adni 304-et (32016-ot), gy a sorok egyms alatt elvglag helyezkednek el. A program elejn deklarljuk a BOB tpust, amely egy rekord. Ebben a koordintit s a kpmemriabeli kezdcmt troljuk. Ez a vltoz trolja a BOB elz helyzetnek cmt, amit a letrlshez fogunk hasznlni. A BOB tpus tartalmaz ezeken kvl egy pointert, ami a Shape kezdcmre mutat. A deklarcis rszben tallhat mg a BOB-megjelent eljrs, majd a fprogram kvetkezik. Itt lefoglaljuk a Shape szmra szksges 1616=256 bjtot, majd rtket adunk nekik, vletlenszeren. Az MCGA md bekapcsolsa utn feltltjk a kpmemrit a megadott httrsznnel, amit a f ciklus kvet, mely a BOB-ot mozgatja s megjelenti, majd billentynyomsra visszalpnk a szveges zemmdba, s befejezzk a programot.

13

{showbob1.pas} uses Crt; type BOB = record X,Y: word; CIM: word; DT: pointer; end; B: BOB; i: word; const C= 1; var { A Crt egysgre csak a billentynyoms { figyelsnl lesz szksg { A BOB nem grafikus adatai: { szlessg, magassg { elz cme a trlshez { a Shape mutatja-grafikus adatok { B a BOB azonostja { A FOR..TO..DO ciklusokhoz { A httr sttkk } } } } } } } } } }

procedure ShowBOB; assembler; asm { A megjelent eljrs { 1. BOB letrlse, azaz fellrsa C (httr) szn bjtokkal } mov lea mov mov mov cld mov @1:mov rep add dec jnz es,sega000 bx,B di,[bx+4] al,C ah,al dx,16 cx,8 stosw di,304 dx @1 { { { { { { { { { { { { { {

A segA000 rtke a Turbo Pascal 7.0-ban } elre megadott, $A000 } BX-be tlti a BOB ofszetcmt } DI-be a BOB elz helyzetnek cmt } AX bjtjaiba a httrszn kerl, ezzel } rjuk fell a BOB-ot } Nvekv sorrendben runk } 16 sor van, } s 16 oszlop, aminek a fele 8 (azrt a } fele, mert szavakat runk, nem bjtokat)} Egy sor trlse } DI a kvetkez sor kezdcme } A sorszmll cskkentse } Ismtls, amg el nem fogynak a sorok }

{ 2. BOB kiraksa az j helyre } mov mul add mov mov push lds mov @2:mov rep add dec jnz pop end; begin with B do begin getmem( DT, 256); { 1616=256 bjt lefoglalsa a Shape-nek CIM:= 0; X:= 0; Y:= 92; { Kezdrtket adunk a nem grafikus randomize; { adatoknak for i:= 0 to 255 do mem[seg(DT^):ofs(DT^)+i]:= random( 256); { A BOB pontjai vletlenszerek ax,320 word [bx+2] ax,[bx] di,ax [bx+4],di ds si,[bx+6] dx,16 cx,8 movsw di,304 dx @2 ds { { { { { { { { { { { { { { { { { j cm szmtsa a CIM=320Y+X kplettel} A B BOB cmhez (BX) 2-t adva megkaphat-} juk a BOB ordintjt } [BX] pedig pont az abszcisszt adja } DI-ben elllt a kpcm, } amit elreltan elmentnk, hogy a tr- } lshez ne kelljen ismt szmolgatni } Az adatszegmens megvltozik a MOVSW } utasts miatt, ezrt el kell menteni } DS:SI a grafikus adatok kezdcme } 16 sor msolsa, } s 16 oszlop } Az aktulis sor megrajzolsa } DI a kvetkez sor kezdcme } Egy sort kirajzoltunk } A tbbi sor kirajzolsa, amg DX>0 } Vissza az eredeti adatszegmenst }

} } } }

14

asm mov ax,13h int 10h { MCGA zemmd bekapcsolsa end; fillchar( mem[$A000:0000], 64000, C); { A kperny C szn (sttkk) repeat ShowBOB; { BOB megjelentse, inc( X); { mozgatsa balrl jobbra if X=304 then x:=0; { Ha a kperny szlre rt, az elejre { ugrik delay( 50); { Kis vrakozs, hogy lthat legyen { Billentynyomsra kilp until keypressed; readkey; { Billentykd ki a pufferbl asm mov ax,3 int 10h { MCGA zemmd kikapcsolsa end; end; end.

} } } } } } } } } }

Futs kzben is lthatjuk, hogy ez az brzolsmd a gyakorlatban gy nem alkalmazhat. A BOB mozgsa nem egyenletes, darabos s villdz. Viszont gyors. Ha a f ciklusbl eltvoltjuk a delay utastst, akkor szinte nem is ltunk semmit, mert a BOB kiraksa gyorsabb, mint a kpfrissts. Egy elnye mgis van ennek az eljrsnak. A megjelents alapjait viszonylag knny itt elsajttani, hiszen nehz lenne megrteni mr elsre a legfejlettebb BOB-brzol eljrst. Ezrt az Olvas, ha nem rti egszen, ne lpjen tovbb, mert a kvetkez megjelentk mind erre az arnylag primitv eljrsra plnek.

2.2. Tetszleges httr


Ha a httr nem egyszn, mint az elz pldaprogram futsa alatt, s a pixelek sznei nem szablyos elrendezsek, azaz ha a videomemriban tallhat kp tetszleges, akkor ms mdszert kell alkalmaznunk a BOB eltvoltsra, amire itt is szksg van, hiszen ha koordinti megvltoznak, akkor el kell valahogy tntetni, s csak azutn szabad elkezdeni kirakni az j helyre, mert nem lehet a BOB egyszerre kt helyen. Bizonyra rthet, hogy mirt nem lehet a sznfeltltses mdszert hasznlni. Ekkor ugyanis mdosulna a httr, s nem ez a clunk. A megolds, hogy a BOB ltal letakart terletet valamilyen formban trolni kell. Ezt gy fogjuk megvalstani, hogy elre lefoglalunk egy Shape hosszsg rszt a memribl, amire minden egyes kiraks eltt tmsoljuk a kirakand BOB alatti terletet. Eszerint a megjelent eljrs hrom f lpsbl ll. Itt is felttelezzk, hogy az eljrs mr egyszer lefutott, vagyis a BOB mr lthat, s a BOB-hoz tartoz dinamikus vltoz a BOB ltal letakart httr-rszletet trolja. 1. A kpernyn mg lthat, elz helyzet BOB-ot el kell tntetni, rmsoljuk az elzleg elmentett httrrszt. 2. Kiszmoljuk a BOB kezdcmt, s az ott tallhat 1616-os tglalapot elmentjk. 3. Kirakjuk a BOB-ot. Legelszr az els lps kimarad, mert klnben a httr mdosulna. Kln eljrsba kerl az 1. lps (ClearBOB) s a 2-3. lpsek (ShowBOB), gy legelszr csak a ShowBOB-ot hvjuk meg. Az elektronsugr figyelsvel, vagyis vertiklis visszafutsra vrakozssal megprbljuk kikszblni a darabossgot s a villogst. Ez lelasstja ugyan a futst (elvgre minden megjelentskor vrni kell), de kzben szebb varzsolja. Megoldjuk mg az tltszs problmjt is, azaz a BOB bizonyos pontjain ttetsz lehet, mely pontokon a httr megfelel pixele lthat. Ezeket a pontokat gy jelljk, hogy a hozzjuk tartoz Shape-bjtoknak zrus rtket adunk. A feladat megoldshoz egy movsw utastst kell nhny msik paranccsal helyettesteni, melyek megvizsgljk, hogy az ppen aktulis Shape-bjt nem nulla-e, mert csak akkor lehet kirni ha nem nulla. (Termszetesen brmelyik sznt vlaszthattuk volna transzparensnek. Itt s a tovbbiakban a 0-t hasznljuk erre a clra, mert ez ltalban fekete, az res httr szne). A programban elszr lefoglaljuk a szksges 2256 bjt hosszsg memrit, majd betltjk a Shapeet, amit a lemezen trolunk. A httrre vletlenszeren kirakunk 1000 tetszleges szn pontot a MEM[ ] tmb segtsgvel. Ezutn belpnk a megjelent ciklusba, ami billentynyomsig mkdik, s a vgn visszalltjuk a szveges mdot (amit a program elejn bekapcsoltunk). 15

{showbob2.pas} uses Crt; type BOB = record X: word; Y: word; A: word; S: pointer; H: pointer; end; var B: BOB; f: file; i: word; const dx: shortint = 1; dy: shortint = 1; { Megint csak a billenty miatt { Bjt { 0. { { 2. { 4. { 6. { 10. }

Lers } A BOB abszcisszja, ez a 0. s az } 1. bjt a BOB tpusban } Ordinta, 2-3. bjt } Elz helyzetnek cme (4-5.) } Shape mutatja (6-9. bjt) } Ide kerl a BOB mgtti rsz }

{ A grafikus adatokat fjlbl tltjk be

{ Vzszintes irny jelzje (1=jobbra) { Fggleges irny jelzje (1=le)

} }

procedure ClearBOB; assembler; asm { 1. BOB letrlse } lea mov mov push lds mov @1:mov rep add dec jnz pop end; bx,B es,sega000 di,[bx+4] ds si,[bx+10] dx,16 cx,8 movsw di,304 dx @1 ds { { { { { { { { { { { { BX a BOB cme $A000 az rtke a SEGA000 konstansnak Elz helyzetnek cme, eltroltuk, gy nem kell ismt kiszmolni (gyorsabb) A DS regiszter kell majd a MOVSW-hez A BOB alatti httrrsz mutatja (H) 16 sor van s 8 sznyi oszlop (16) Egy sor visszalltsa A kvetkez kezdcme 304-gyel nagyobb Sorszmll cskkentse, ismtls, amg el nem ri a nullt } } } } } } } } } } } }

procedure ShowBOB; assembler; asm { BOB megjelentse { 2. Az j koordintk szerinti 1616-os rsz mentse } lea mov mul add mov mov les push mov mov @1:mov rep add dec jnz pop bx,B ax,320 word [bx+2] ax,[bx] [bx+4],ax si,ax di,[bx+10] ds ds,sega000 dx,16 cx,8 movsw si,304 dx @1 ds { { { { { { { { { { { { { { { BX a BOB ofszetcme (szegmenscme: DS) Kpcm kiszmolsa a szoksos mdon Sor cme=320Y Kppont cme=sor cme+X Kpcm elmentse (B.A szba) A forrsindex a kpcm, innen olvasunk A clcm a BOB rekord H mezje Ugyancsak a MOVSW miatt kell a DS A kpmemribl trtnik az olvass 16 sor 16 pixel soronknt (16 bjt, 8 sz) Egy sor elmentse Forrsindex a kvetkezre mutat Egy sort tmsoltunk A tbbi sor mentse (ha mg van)

} } } } } } } } } } } } } } }

16

{ 3. BOB megjelentse } mov mov push lds mov @2:mov @3:lodsb cmp jz mov @4:inc loop add dec jnz pop end; es,sega000 di,[bx+4] ds si,[bx+6] dx,16 cx,16 al,0 @4 es:[di],al di @3 di,304 dx @2 ds { { { { { { { { { { { { { { { { Most ES tartalmazza a kpszegmenst } Szerencsre egyszer mr kiszmoltuk a } kpcmet, gy idt s helyet sprolunk } Megint kell a DS, de most a LODSB miatt } A BOB grafikus adatainak kezdcme } DX ismt a sorokat szmllja } CX pedig a pontokat (16 pixel, 16 bjt) } DS:[SI] ltal cmzett bjt AL-be tltse} Ha ez nulla, nem runk semmit a kper- } nyre } Egybknt kirajzoljuk } DI a kvetkez kpbjtot cmzi meg } Kvetkez pixel megjelentse } A kvetkez sor cme } Sorszmll cskkentse } Amg nagyobb nullnl }

procedure Retrace; assembler; asm { Vrakozs egy vertiklis visszafutsra, mov dx,03dah { hogy a megjelents ne legyen darabos, @1:in al,dx { villdz. A vertiklis visszafuts idetest al,8 { je alatt a $3DA port 3. bitje 1. Ezt jz @1 { kell vizsglni end; begin { A B rekord mezivel foglalkozunk with B do begin getmem( S, 256); { 1616=256 bjt a Shape szmra, getmem( H, 256); { 1616=256 bjt a httrrszletnek assign( f,'rec.dat'); { A grafikus adatok a lemezen vannak, a reset( f, 1); { REC.DAT fjlban, sorfolytonosan blockread( f, s^, 256); close( f); x:= 0; y:= 0; { A BOB kiindulpontja a bal fels sarok asm mov ax,13h int 10h { MCGA zemmd bekapcsolsa end; randomize; for i:= 1 to 1000 do mem[$a000:random( 64000)]:=random( 256); { A httr tetszleges besznezse ShowBOB; { BOB megjelentse repeat Retrace; { A szp, egyenletes futs miatt vrakoClearBOB; { zs a visszafutsra, majd ez id alatt ShowBOB; { letrljk s jra kirakjuk a BOB-ot { gy nem villog, igaz, lassabb lesz inc( X, dx); { BOB vzszintes mozgatsa if (X=0) or (X=304) then dx:= -dx; { Kp szln irnyvlts inc( Y, dy); { BOB fggleges mozgatsa if (Y=0) or (Y=184) then dy:= -dy; { Kp szln irnyvlts until keypressed; readkey; { A lenyomott billenty kiolvassa

} } } } }

} } } } } } }

} } } } } } } } } } }

17

asm mov int end; end; end.

ax,03h 10h

{ Visszatrs a szveges mdhoz

(Megjegyzs: a Turbo Pascal 7.0 beptett assemblyjben a rekordok, objektumok mezire gy is lehet hivatkozni: pl. [BX].BOB.X, azonban a knyvbeli programok tbbsge a 6.0-s verziban kszlt, amiben mg nincs meg ez a lehetsg.) Az egrkurzor grafikus kpernyn val megjelentse hasonl, csak az egr nyila mr jobboldalt s lent kicsszhat. Vegyk t mg egyszer, milyen elnyei s htrnyai vannak ennek az eljrsnak! Elnyk: A httr tetszleges lehet, nem kell egysznnek lennie. A BOB tltsz rszeket is tartalmazhat, ahol a httr ltszik. A megjelents nagyon gyors, prbljuk csak meg eltvoltani a RetRace utastst a fciklusbl! Ha ezutn nem iktatunk be egy vrakoz parancsot (delay), akkor az brzols nagy sebessge miatt szinte semmi sem lthat. Kevs memrit ignyel, mindssze 256 bjt hosszsg az a dinamikus vltoz, ahol a BOB ltal takart httrdarabot troljuk. Htrnyok: Csak egy BOB brzolst biztostja, melynek mretei elre meghatrozottak, s csak egyfzis. Nem tudjuk megvalstani a BOB beszst, vagyis nem helyezhetjk el gy, hogy a kperny szle keresztbevgja. Prbljuk meg a fciklust a kvetkez sorral helyettesteni: B.X:=312; ShowBOB; Azt szeretnnk ezzel elrni, hogy a BOB csak flig ltszdjon. Ezzel ellenttben a msik fele is megjelenik, a msik oldalon s egy sorral lejjebb. (A magyarzat, hogy az MCGA zemmd pixelei sorfolytonos bjtokknt jelennek meg a memriban.) A httr nem vltozhat, mert a httr vltoztatshoz a BOB-hoz tartoz puffert is t kellene rni. Nos, van mg mit javtanunk, folytassuk a fejlesztst!

2.3. Tbb BOB egyszerre


Egyszerre tbb grafikus objektum megjelentsnl kt problma merl fel. Az egyik, amelyiknek megoldsa egyszerbb, az, hogy ha kt BOB fedi egymst akkor melyik legyen fell, azaz melyik ne legyen takarsban. Ezt egyszeren a megjelents sorrendjvel hatrozhatjuk meg. Amelyik BOB-ot elszr rakjuk ki, az lesz alul, a kvetkez pedig fell. A msik nehzsg a httr aktulis rsznek trolsban rejlik. Tegyk fel, hogy csak kt BOB brzolsrl akarunk gondoskodni, melyek legyenek B1 s B2. B1 pozcija legyen (X;Y), B2- pedig (X+8;Y+8). Most nzzk meg, mi trtnik, ha a httrtrols megjelentst alkalmazzuk, ahogy azt az elz rszben tettk. Az eljrs B1 kirajzolsa eltt lemsolja az (X;Y) bal fels sark 1616-os tglalapot, majd kirakja a B1-es azonostj BOB-ot. Ezutn B2 kvetkezik. Itt viszont baj van, mert a trolsra kerl httr-rsz mr tartalmazza a B1 jobb als rszt. Teht ez a B1-rszlet is elmentdik, miszerint a B2 httr pufferben nem a valsgos httr tallhat. Ez majd csak a BOB-ok letakartsnl jelent problmt, amit ktflekppen oldhatunk meg. B1 B2 B2 httrpuffere tartalmazza a B1 egy rszlett teht nem az eredeti htteret.

18

Az egyik megolds az, hogy a BOB-okat fordtott sorrendben tntetjk el, mint ahogy kiraktuk ket. Az elz pldnl maradva a kpernyn ltszik B1 s B2, B2 takarja B1 egy rszt. Ha most ugyanolyan sorrendben tvoltannk el ket, mint ahogy megjelentettk, akkor a B1 jobb als sarka a kpernyn maradna. De ha fordtott sorrendben trljk ket, akkor lssuk, mi trtnik. B2 eltvoltsa utn ott marad B1, teljes egszben, srtetlenl; hiszen B2 httrpuffere tartalmazta a B1-bl kiharapott rszt. Vgl a B1 eltntetse mr nem okoz gondot. Ez a fordtott letrls jnak tnik, mert arnylag kevs memrit ignyel (minden BOB utn 256 bjtot, Shape-pel egytt 512-t). Htrnya, hogy mindegyik objektum ms-ms ideig ltszik. A legelszr brzolt tbb idt tlt a kpernyn, mint az utoljra megjelentett, ez villogshoz vezethet. s ha nem kett, hanem mondjuk 256 BOB-ot szeretnnk lthatv tenni, akkor az sszes httr-rszlet eltrolsa mr tetemes memrit emszt fel (1616256 = 65536). Fleg, ha a BOB-ok nem 1616-os mretek, hanem ennl nagyobbak. A msik megolds a httr pufferelse. A memriban is trolunk egy 320200-as kpet, amelynek tartalma megegyezik a kpmemria tartalmval. gy teht kt ugyanolyan kpnk van, csak az egyik, amelyik a norml memriban van, nem ltszik. Segtsgkkel lnyegesen leegyszersdik a BOB-ok letrlse, azaz a kpernyn az eredeti httr visszalltsa. Egyszeren csak t kell msolni BOB-onknt egy-egy 1616-os tartomnyt a megfelel helyre, s mr el is tnt a BOB. A jobb rthetsg kedvrt, nzzk meg rviden, hogyan mkdik az j, tovbbfejlesztett eljrs! Legyen H1 az a httr, amelyik nem ltszik, tartalma vltozatlan, H2 pedig a valdi kp, amelyik megjelenik, kezdcme $A000:0000, s amelyre a grafikus objektumok kerlnek. 1. Minden egyes BOB eltrolt kezdcmtl kezdve tmsolunk H1-rl H2-re egy 1616-os tartomnyt. 2. BOB-ok kiraksa H2-re, de mindegyik BOB-nl meg kell jegyezni annak a kezdcmt (320Y+X), a letrlshez a kvetkez ciklusban. Httr memriban H1 kezdcm: BackGround Kperny kpmemriban H2 kezdcm: $A000:0000 BOB BOB

Ezeket a httr-rszeket kell a kpmemriba msolni, hogy a BOB-ok eltnjenek. Itt nem kell els futtatsnl az els lpst tugrani, hiszen eleinte (BOB-ok megjelentse eltt) H1 s H2 ugyanazt a kpet tartalmazza, gy igaz, hogy hiba, de nyugodtan msolhatunk egyikrl a msikra. Viszont az elektronsugrra annl inkbb figyelni kell! Sok BOB van, ezrt egy-egy megjelentsi ciklusban a kpernyn viszonylag sokig nem ltszanak egyes BOB-ok. (Letrlsnl amelyiket elszr tvoltjuk el, az ltszik a legkevesebb ideig.) Ha a kperny megtiszttst nem egy vertiklis visszafuts alatt vgezzk, az villogshoz vezet! Amennyiben nagyon sok BOB-ot prblunk megjelenteni, akkor egy bizonyos hatrtl felfel mr gyse lehet kikszblni ezt a villogst, mert a kperny letakartsa tbb ideig tart, mint egy vertiklis visszafuts. Ez a hatr tbbek kztt fgg a gp sebessgtl, a memriarezidens programoktl, s a BOB-ok mrettl. Egy kb. 133 MHz-es gpen 40 BOB megjelentse mg nem okoz gondot, de 50 darab brzolsa mr villogssal jr. A pldban a msodik, a ketts-httr technikt valstjuk meg. A program elejn belltjuk a szksges adatokat, betltjk a lemezrl a Shape-eket stb. A fciklusban a BOB-ok mozgsa tls irny, falrl lepattan, ezrt a BOB rekordhoz mg hozz kellett venni a DX s DY elemeket, amelyek a vzszintes illetve fggleges irnyt jelzik. {showbob3.pas} uses Crt; type BOB = record X : word; Y : word; { Egy BOB nem grafikus adatai { 0 Vzszintes koordinta { 2 Fggleges koordinta 19 } } }

A : G : DX: DY:

word; { 4 Elz helyzetnek ofszetcme pointer; { 6 Grafikus adatok kezdcme shortint;{ Vzszintes irny (1: jobb, -1: bal) shortint;{ Fggleges irny (1: le , -1: fel) { (A 0,2,4,6 szmok a mez tvolsgt je{ lentik, bjtban, a SHOWBOB eljrshoz)

} } } } } }

end; const Bnum = 15; Snum = 3; Blen = sizeof( BOB); var B: S: f: n: i:

{ BOB-ok szma: BNUM+1 (itt: 16) { Shape-ek szma: SNUM+1 { A BOB nem grafikus adatainak hossza

} } } } } } } } }

array[0..Bnum] of BOB; { Az sszes BOB nem grafikus adatai array[0..Snum] of pointer; { A grafikus adatok mutati { Fjl vltoz a Shape-ek tltshez file; { Ugyancsak a tltshez kell string[1]; word; { ltalnos vltoz a FOR ciklusokhoz { A httr kezdcme

BackGround: pointer;

procedure ShowBOB; assembler; asm { Vrakozs, amg nincs vertiklis visszafuts } mov @W: in test jz al,dx al,8 @W dx,03dah { { { { { Nagy hiba lenne ezt a rszt kihagyni, az villogssal jrhat. Lass gpeknl ez gy is elfordulhat, ilyenkor nem r vget egy elektronsugr-visszatrs alatt az eljrs 2. s 3. rsze } } } } }

{ 1. A BOB-ok helyre az eredeti httr-rszletek visszarsa } mov cld mov @1: push lea mov mul add mov push lds add mov @2: mov rep add add dec jnz pop pop loop cx,8 movsw di,304 si,304 dx @2 ds cx @1 { { { { { { s CX az egy sorban lv szavakat 16 pixel visszalltsa httr sznre Kvetkez sor: DI:=DI+320-16 A httr szlessge is 320 bjt Eggyel kevesebb a visszarand sor Ismtls, amg DX el nem ri a nullt } } } } } } } } cx bx,b ax,blen cx bx,ax di,[bx+4] ds si,background si,di dx,16 { { { { { { { { { { A REP utastshoz is szksg lesz CX-re A BOB-adatokat trol tmb cme BX-hez annyit kell adni, hogy az az aktulis (CX.) BOB-ra mutasson (BX:=BX+CXBOB tpus hossza) A BOB elz helyzetnek cme ('A' mez) A MOVSW utastshoz kell A httr kezdcme DS:[SI]-be SI-hez a kpcm hozzadsa Most is a DX szmllja a sorokat } } } } } } } } } } es,sega000 cx,bnum { A kperny szegmenscme { D bit eloltsa a sztring-mveletekhez { BNUM(=16) db BOB eltvoltsa } } }

{ CX jra a BOB-okat szmllja { Tbbi BOB eltntetse

20

{ 2. BOB-ok kiraksa } mov @3: push lea mov mul add mov mul add mov mov push lds mov @4: mov @5: lodsb cmp jz mov @6: inc loop add dec jnz pop pop loop end; begin { 1. Httr, kperny belltsa } asm mov ax,13h int 10h { MCGA zemmd bekapcsolsa end; getmem( BackGround, 64000); randomize; for i:= 1 to 1000 do mem[$a000:random( 64000)]:= random( 256); move( ptr($A000, 0)^, BackGround^, 64000); { A httr ugyanazt a kpet tartalmazza, mint a kperny } { 2. Grafikus adatok betltse } for i:= 0 to Snum do begin getmem( S[i], 256); { A Shape hossza 1616=256 bjt str( i, n); assign( f, 'bob'+n+'.dat'); reset( f, 1); seek( f, 7); { Az els 7 bjt lnyegtelen (pl. mret) blockread( f, s[i]^, 256); close( f); end; } di @5 di,304 dx @4 ds cx @3 { { { { { { DI a kvetkez kppontot cmzi Egy egsz sor megjelentve, ha CX=0 ES:[DI] a kvetkez kpsor (X-1). bjtjnak cme Sorszmll cskken Sorok kiraksa, amg szmlljuk (DX)>0 } } } } } } } al,0 @6 es:[di],al { { { { DS:[SI]-vel cmzett bjt tltse, SI n Ha ez a bjt nulla, nem kell kirni a kpernyre, mert itt a BOB tltsz Egybknt igen } } } } cx,16 { s ugyangy 16 pontbl egy sor } cx bx,b ax,blen cx bx,ax ax,320 word [bx+2] ax,[bx] di,ax [bx+4],ax ds si,[bx+6] dx,16 { { { { { { { { { { { { { Most is menteni kell, pontszmll lesz Megint gy jrunk el, mint a 2. rszben (ahhoz, hogy a BX regiszter az aktulis BOB-ra mutasson) Kpcm szmtsa a szoksos mdon A 3. bjttl tallhat az ordinta Az 1. kt bjt pedig az abszcissza DI-ben elllt a kpcm (320Y+X), amit elmentnk a BOB eltvoltshoz Most a LODSB-hez kell A forrscm a BOB tpus 7. bjtjtl kezddik, ez a Shape-re mutat Mg mindig 16 sorbl ll a BOB } } } } } } } } } } } } } cx,bnum { CX most is BOB-szmll }

{ Tbbi BOB megjelentse

21

{ 3. Nem grafikus adatok vletlenszer belltsa } for i:= 0 to Bnum do with B[i] do begin G:= S[random( Snum+1)]; { Vletlenszer minta kivlasztsa X:= random( 303)+1; Y:= random( 183)+1; DX:= 2*random( 2)-1; { rtke csak -1 vagy +1 lehet DY:= 2*random( 2)-1; { rtke csak -1 vagy +1 lehet end; { 4. Fciklus, megjelents s mozgats billentynyomsig } repeat ShowBOB; for i:= 0 to Bnum do with B[i] do begin inc( X, DX); if (X=0) or (X=304) then DX:=-DX; inc( Y, DY); if (Y=0) or (Y=184) then DY:=-DY; { Falrl lepattan mozgs end; until keypressed; readkey; { 5. Visszatrs a szveges mdhoz, vge } asm mov int end; end. ax,03h 10h } } }

{ Visszatrs a szveges mdhoz

A lemezen lv grafikus adatfjlok (pl. BOB3.DAT) csak a 8. bjtjuktl kezdve tartalmazzk a Shape adatait, sorfolytonosan, gy ahogy a memriban is trolni szoktuk. Az els 7 bjt a Shape mreteit s fzisait hatrozzk meg, ami adott (1616, 1 fzis. Ez okbl ugrottunk a fjl 7. bjtjra a seek utastssal. (A Shape-ek a BOB-Editorral kszltek, melynek fjlformtumrl rszletesebben a 6. fejezet elejn olvashatunk.) Ezzel a mdszerrel elvileg 5389 BOB-ot brzolhatunk. Viszont ha ezt a szmot (azaz nla eggyel kevesebbet 5388-at) berjuk a Bnum konstans utn, s gy futtatjuk a programot, akkor az eredmny: a kperny tele lesz fejecskkkel, szvekkel, rombuszokkal s almkkal (ezek a BOB-ok), s temesen elsttl, mindig, amikor egy BOB-letrl rsz fut. De mr kevesebb BOB-nl is feltn zavar hatsokat vehetnk szre, 100 BOB megjelentsnl a kp fels rszben azok nem ltszdnak. Ez azrt van, mert az elektronsugr mr elkezdte frissteni a kpet, mieltt az sszes BOB eltntetse s jbli kiraksa befejezdtt volna, azaz a ShowBOB eljrs futsi ideje tbb, mint egy vertiklis visszafuts. A htteret nem tudjuk egyszeren vltoztatni. Ez majd akkor okoz problmt, ha olyan jtkot szeretnnk rni, amelyik szntere nagyobb egy kpernynl, gy azt grgetni akarjuk. A BOB-ok mg mindig lland mretek s fzisak (16161), s nem tudnak beszni. Szmuk korltozott, gptl fgg. Folytassuk teht a fejlesztst!

2.4. Vltoztathat httr, animlt BOB-ok


Tovbbfejlesztjk az eljrst, bvtjk egy lpssel, hogy tetszleges szm BOB brzolsa se jrjon villogssal. A bvts lnyege, hogy a kpalkots a memriban trtnik, s az ott elksztett, mr ksz kpet rakjuk ki a kpmemriba. Ehhez az eljrshoz szksg van teht a memriban mg egy 320200 bjt hossz tartomnyra, a munkaterletre. Ez a munkaterlet ltest kapcsolatot a grafikai adatok (httr, Shape-ek) s a kpmemria kztt. Hasznlatnak elnye: a BOB-ok letrlsnek s jbli kiraksnak ideje megnhet, ami legfeljebb a program futst lasstja, de villogst mr nem okoz. gy tbb BOB-ot tudunk zavar hatsok nlkl brzolni, s a htteret is knnyebben vltoztathatjuk. A munkaterlet lnyegnek knnyebb megrtshez nzzk meg eljrsunk lpseit, mely megmutatja azt is, hogy a httr egy egyszer memriba rssal mdosthat.

22

1. Az egsz httr, azaz 32000 sz tmsolsa a munkaterletre a movsw utasts segtsgvel. 2. BOB-ok megrajzolsa a munkaterleten. 3. Munkaterlet (32000 sz) msolsa a kpmemriba, vagyis maga a megjelents. A kvetkez bra szemlletesebb teszi az brzolsnak ezt a mdszert, s segt megrtetni a munkaterlet hasznlatt. A nyilak memribl memriba msolst, a nyilak feletti szmok ezek sorrendjt jellik. Httr (BackGround) 1. Munkaterlet (WorkArea) 3. Kperny ($A000:0000)

BOB

2.
BOB

Ha a htteret egyszer csak gykeresen megvltoztatjuk, az sem okoz problmt, gy fogjuk tapasztalni, mintha az a BOB-ok mgtt vltozott volna meg, teht elrtk clunkat. Viszont mi lenne akkor, ha az els lpsben nem az egsz htteret msolnnk, hanem csak azon rszeit, amit a munkaterleten a BOB-ok takarnak? Nos, ez nylvn lland httrnl gyorsabb futst eredmnyez, de azt vltoztatni nehezebb lenne. Meg kne vltoztatni magt a htteret s a BOB-oktl mentes munkaterletet is. Ez grgetsnl 264000 bjt mozgatst jelenti, ami semmiben sem gyorstja a futst, hanem mg lasstja is. Vltozatlan httrnl bevlik, ennek ellenre nem trnk ki kln erre a mdszerre. Mirt van szksg arra, hogy a kpet a munkaterleten lltsuk el? Ez fleg a scrollozs, grgets miatt van gy. Ha egy jtkban a htteret grgetjk, akkor minden grdtsi fzisban az egsz kperny tartalma megvltozik, hiszen minden egyes pixelnek ms helyen kell megjelennie. Teht mindig fell kell rni az egsz kpernyt, azaz 64000 bjttal bizonyos mveleteket kell vgrehajtanunk. Amg a kpernyt odbb toljuk, vagyis ppen fellrjuk a grdts miatt, a BOB-ok nem ltszanak, s ez a mvelet hosszsga (64k bjt) miatt ers villogshoz vezet. Ha a memriban, a munkaterleten vgezzk mindezt, az nem jr villogssal, mert a kpernyn a kp korbbi llapota ltszdik, egszen a 3. lps vgrehajtsig. Lehetsg nylik az animcira is, a BOB-ok tbb fzisak lehetnek. Ezt egy egyszer szorzs beszrsval rjk el, aminek eredmnyt hozzadjuk a Shape-re mutat forrsindexhez, gy az mr a kvnt fzisra mutat. A pldaprogramban a BOB-ok mrete mg mindig 1616, fzisaik szma viszont 4. Ebbl addan egy-egy Shape helyfoglalsa 16164=1024 bjt. {showbob4.pas} uses Crt; type BOB = record X,Y: word; P: word; Shp: pointer; V,F: shortint; end; const Bnum Snum Blen Pspd { Bjt Tartalom { 0;2 Koordintk { 4 Aktulis fzis sorszma (0-tl) { 6 Grafikus adatok kezdcme { Vzsz. s fgg. irnyjelz bjtok } } } } }

= 15; = 3; = sizeof( BOB); = 10;

{ { { {

Megjelentend BOB-ok szma -1 A BOB-okhoz tartoz mintk szma -1 Egy BOB tmbelem hossza a memriban Fzisvltsi ksleltets

} } } } } } } } }

Pcur: word = 0; Retr: boolean = true;

{ Szmll a fzisksleltetshez { Vertiklis visszatrs figyelse

var B: array[0..Bnum] of BOB; { BOB nem grafikus adatok tmbje S: array[0..Snum] of pointer; { Grafikus adatok tmbje BackGround, Workarea: pointer; { Httr s munkaterlet cme f: file;

23

i: word; n: string[1];

{ ltalnos cl vltozk

procedure ShowBOB; assembler; asm { 1. Httr msolsa a munkaterletre, 32000 sz mozgatsa } cld mov push les lds rep pop { { cx,32000 { ds { di,workarea { si,background { movsw { ds { D-bit eloltsa, gy az indexregiszterek nnek a karakterlnc-mveleteknl 320200 bjt = 32000 sz A DS regisztert megvltoztatjuk A clcm a munkaterlet kezdcme A forrscm pedig a httr kezdcme A belltsok utn lehet msolni Az adatszegmens visszalltsa } } } } } } } }

{ 2. BOB-ok felraksa a munkaterletre } mov @1: push lea mov mul add les mov mul add add push mov mul lds add mov @2: mov @3: lodsb cmp jz mov @4: inc loop add dec jnz pop pop loop di @3 di,304 dx @2 ds cx @1 { { { { { A kvetkez bjt cme eggyel nagyobb Egsz sor kiraksa ciklus alja Kvetkez sor els bjtjnak cme Eggyel kevesebb sort kell mg kirakni 16 sort kell kirakni, ismtls } } } } } al,0 @4 es:[di],al { { { { A Shape egy bjtjnak betltse Ha ez nulla, nem kell a munkaterletre rni semmit Egy pixel kigyjtsa a munkaterleten } } } } cx,16 { CX pedig a soron belli pixelek } cx bx,B ax,blen cx bx,ax di,workarea ax,320 word [bx+2] ax,[bx] di,ax ds ax,256 word [bx+4] si,[bx+6] si,ax dx,16 { { { { { { { { { { { { { { { { { CX majd msra is kell } A BOB-adatok tmbjnek kezdcme BX-be } BX-hez CXBLEN-t adva megkapjuk az ak- } tulis (CX-edik) BOB nem grafikus ada- } tainak kezdcmt } A clcm nem a kperny, hanem a } munkaterlet kezdcme } Kiszmtjuk annak a bjtnak a cmt, a- } mi a BOB bal fels sarka alatt lesz } A kplet jl ismert: cm=320Y+X } ES:[DI] mr a megfelel bjt cme } DS lesz a forrsszegmens } A Shape kezdcmhez P256-ot kell adni,} hogy az aktulis fzis (P) cme legyen } A forrscm a Shape cme, csak mg hoz- } zadunk P256-ot. (Fzishossz: 1616 b) } Ahogy megszoktuk, DX a sorok szmllja } cx,bnum { BNUM a BOB-ok szma }

{ Tbbi BOB megrajzolsa a munkaterletre }

{ 3. Munkaterlet msolsa a kpernyre, maga a megjelents } { 3.1. Ha a RETR logikai vltoz igaz, vrakozs az elektronsugr fggleges irny visszatrsre } cmp jz mov retr,0 @6 dx,3dah { Ha a RETR hamis, nem kell vrni }

24

@5: in test jz al,dx al,8 @5 { Csak visszafuts alatt folytatdhat }

{ 3.2. Az 1. rszhez hasonlan 32000 sz mozgatsa } @6: mov xor mov push lds rep pop end; procedure Pixel( A: word; C: byte); assembler; asm { C szn pont kiraksa a httrre, A=320Y+X (X;Y-koordintk) } les add mov mov end; begin { 1. Belltsok, inicializlsok, helyfoglalsok } randomize; getmem( BackGround, 64000); getmem( Workarea, 64000); for i:= 0 to Snum do begin getmem( S[i], 1024); { A Shape hossza 41616, 4 fzisbl ll str( i, n); assign( f, 'anim'+n+'.dat'); reset( f, 1); seek( f, 7); { Az els 7 bjt szmunkra nem fontos, { lersuk a kvetkez rszben (2.5.) blockread( f, s[i]^, 1024); close( f); end; for i:= 0 to Bnum do with B[i] do begin Shp:= S[random( Snum+1)]; X:= random( 303)+1; Y:= random( 183)+1; P:= random( 4); V:= random( 3)-1; { A BOB egyszerre kt, egy vagy nulla iF:= random( 3)-1; { rnyba mozoghat end; asm mov ax,0013h int 10h end; for i:= 0 to 63999 do Pixel( i, 0); { A httr kezdetben fekete di,background { Most a httrre rajzolunk di,A al,C es:[di],al } es,sega000 di,di cx,32000 ds si,workarea movsw ds { MCGA kpmemria szegmenscme $A000 { A bal fels sarokbl kezdnk (DI=0) { 32000 sz, 64000=320200 bjt { { { { A forrscm a munkaterlet kezdcme Msols Soha ne felejtsk a DS regiszter eredeti rtkt visszalltani! } } } } } } }

} }

} }

25

{ 2. Fciklus, megjelents s mozgats, animci } repeat ShowBOB; for i:= 0 to 3 do Pixel( random( 64000), random( 256)); { Httr vltoztatsa for i:= 0 to Bnum do with B[i] do begin inc( X, V); if (X=0) or (X=304) then V:=-V; inc( Y, F); if (Y=0) or (Y=184) then F:=-F; end; inc( Pcur); if Pcur=Pspd then begin { Fzisksleltets, csak minden { PSPD-edik temben van fzisvlts Pcur:= 0; for i:= 0 to Bnum do with B[i] do begin inc( P); if P=4 then P:= 0; end; end; until keypressed; readkey; { 3. Videomd visszalltsa, vge } asm mov int end; end. ax,3 10h

} }

Itt abba is hagyhatnnk a fejlesztst, mert mr majdnem minden kritriumot teljestettk. Kt dolgot kell mg megvalstanunk: a BOB-ok legyenek tetszleges mretek, s ha gy helyezzk el, hogy a kperny szle kettszelje ket, akkor csak az a rszk ltszdjk, ami a kpernyn rajta van. Sok jtkban szksg van a beszs lehetsgre, mert mondjuk egy autversenyzs jtkban igazn nem lenne szp, ha az autk csak gy hirtelen megjelennnek. A BOB-ok tetszleges mretnek szksgessge pedig egyrtelm, mert pldul egy lvldzs programban egy 11-es lvedknek 1616-os mret Shape-et adni egyszeren pazarls. Ennek az brzolsmdnak kt nagy problmja van: lass s sok memrit ignyel. Lasssga abbl fakad, hogy minden megjelentsnl legalbb 264000 bjtot kell mozgatni, s ehhez mg hozzjnnek a BOBok. Ez azt jelenti, hogy a futs csak egy 80 MHz-es gptl lesz egyenletes s szp, ha a visszatrsre vrakozst alkalmazzuk (RetRace). Ennl lassabb gpeknl rdemes ennek a vltoznak hamis rtket adni, ezzel nveljk valamivel a sebessget. Msik gyorst mdszer az lehetne, hogy a BOB-ok letakartshoz a SHOWBOB3.PAS programban megismert mdszert alkalmaznnk, ezzel azonban kizrnnk a httr vltoztathatsgnak lehetsgt, azaz pldul nem tudnnk azt grgetni, ami sok jtkhoz nlklzhetetlen. A programfuts sebessgt a processzor sebessge mellett nagymrtkben meghatrozza a videokrtya sebessge. Az jabb PCI buszos krtyk szerencsre mr elg gyorsan tudjk kezelni a videomemrit, gy a mdszer jl hasznlhat. Rgebbi ISA buszos krtykon a futs elg lass lehet. A msik gond a nagy memriaigny, amit a SHOWBOB2.PAS pldaprogram megjelent eljrsban megvalstott httrrsz-trol mdszerrel tudnnk kikszblni, ez azonban lehetetlenn tenn a httr tetszleges vltoztatst. A munkaterlet kiiktatsnak meg azrt nem lenne rtelme, mert ha adott szm BOB adott gpen villogsmentesen megjelenthet, annak brzolsa lassabb gpen mr villogssal jrhat. s klnben is mg gyors gpen is nagy esly van a villdzsra, hiszen minden vgrehajtskor az egsz kpernyt fellrjuk, azaz elg sokig ltszik csak a httr. Ezeket a problmkat teht nem fogjuk s nem is kell megoldani. Ha az Olvas olyan programot szeretne rni, amiben a httr vltozatlan, nyugodtan kombinlhatja a megjelentket a szmra optimlis memriafoglals s sebessg szerint.

26

2.5. Teljes megjelents


Elrkeztnk a BOB megjelents utols rszhez, amely a fejezet elejn megfogalmazott felttelek mindegyikt teljesti. Egyszerre tbb transzparens, tetszleges mret s fzis BOB jelenthet meg, melyek kpesek beszni, s a httr tetszlegesen vltoztathat. A villogs szinte kizrva. A 2.4. fejezet pldaprogramjhoz kpest kt j dolgot valstunk meg, a BOB-ok tetszleges mretek s helyzetek lehetnek. Az brzols f lpsei ugyanazok lesznek mint az elz pldban, csupn a BOB rekordot bvtjk nhny elemmel, s persze a ShowBOB eljrst is. A brmekkora mret megvalstsa az egyszerbb feladat, annyi az egsz, hogy az eljrsban kt 16-os szm helyett (ennyi volt a szlessg s a magassg) egy-egy vltozt runk. A BOB-ok mretnek s fzisszmnak kivlasztsnl csupn egyvalamire kell gyelni, hogy a Shape mrete ne haladja meg a 64K bjtot. Az, hogy a BOB a kperny szln is megjelenhessen mr egy kicsit sszetettebb. Meg kell vizsglni, hogy melyik irnyban lg ki s mennyire. Az is megeshet, br ritka, hogy a BOB egyszerre mind a ngy irnyban kilg a kpbl. Ez pldul egy 322202-es mret objektumnl fordulhat el, de ilyen nagy BOB-ot nincs rtelme megjelenteni. Ellenben az gyakori, hogy egyszerre kt irnyban nylik ki a kpbl, pldul ha a kperny sarkn helyezkedik el. Hogy a kperny fels vagy bal oldali szln is megjelenhessen, integer tpus koordintkat fogunk hasznlni. A kperny bal fels sarka lesz a (0;0) pont, ettl balra s felfel az adott irnyhoz tartoz koordinta negatv. Ha egy BOB bal oldalrl szik be, akkor els koordintja negatv s egyre n. gy teht van egy nagy koordinta-rendszernk, melynek szlessge s magassga egyarnt 65536 pixel, s egy arnylag kicsi, 320200as tglalap alak tartomnya a kperny. Egy BOB, koordinti alapjn hromfle helyzet lehet: a) Teljes terjedelmben rajta van a kpernyn. Ilyenkor nem okoz nagy problmt a megrajzolsa, a korbban kidolgozott mdszert kell alkalmazni, egy kis vltoztatssal persze, hogy tetszleges mret lehessen. b) Csak egy rsze van rajta a kpernyn. Ez a legbonyolultabb, mert meg kell hatrozni, melyik tglalap alak tartomnya ltszik, s ezt s csak ezt a rszt kell megjelenteni. c) Nincs rajta a kpernyn. Ez a legegyszerbb, mert nem kell semmit tenni. Ha nem csinlunk semmit, akkor a BOB nem ltszik. Nzznk egy brt, amely szemllteti a koordinta-rendszert, benne a kpernyt s a BOB-ok klnbz elhelyezkedsi lehetsgeit. (-32768;-32768) (0;0) Kperny szle Koordintarendszer szle a) BOB, amelyik teljesen ltszik b) BOB, amelyiknek csak egy rsze ltszik c) BOB, amelyik nem ltszik (319;199) (32767;32767) Eddig 304184-es mret koordinta-rendszereket alkalmaztunk (azrt nem 320200-asat, mert akkor a 1616-os BOB-ok a szlre kerltek volna), ami csak a kpernyt foglalta magba. Most ezt kibvtettk, ltrehozvn ezzel egy 6553665536 nagysg rendszert, aminek rsze a kperny. A bvts miatt felmerlt egy problma, hogy egy BOB lehet olyan helyzet, hogy a kperny szle keresztl szelje, s ilyenkor megjelentse egy fokkal sszetettebb. Ezt a problmt igyeksznk az albbiakban megoldani. A megjelentst vgz eljrs BOB kirak rsze (2.) a kvetkez lpsekkel mdosul: 1. Ellenrizzk, hogy a BOB rajta van-e a kpernyn, egyszer sszeadsok s kivonsok segtsgvel. Ha nincs rajta, nem kell brzolsval a tovbbiakban trdni. 2. Meghatrozzuk a BOB-on bell azt a tartomnyt, ami lthat. Ha az egsz BOB lthat, akkor ennek a tartomnynak a mretei megegyeznek a BOB mreteivel.

27

3. Kirajzoljuk a meghatrozott tglalap alak BOB-rszletet a munkaterletre. A korbbiakkal ellenttben nem szabad folytonosan msolni a bjtokat, a rszlet minden sora utn valamennyivel nvelni kell a szmllt, hiszen nem szabad az egszet megjelenteni. Azt, hogy egy BOB a kperny szln helyezkedik el, ngy alapesetre bonthatjuk, majd ezeket kombinlva brmilyen elhelyezkeds BOB-okat tudunk brzolni. Nzzk teht ezt a ngy esetet: Csak a kperny bal szle szeli keresztl. Ekkor a BOB megrajzoland rsze keskenyebb lesz, minden sor kirsa eltt a forrsindexet meg kell nvelni annyival, amennyivel a BOB balra kilg, vagyis az abszcisszjnak (-1)-szeresvel. A kp jobb szle vgja kett. Ez esetben a megrajzoland rsz minden sora utn a forrsindexet nvelni kell annyival, amennyivel a BOB abszcisszjnak s szlessgnek sszege 320-nl nagyobb. Ha a kperny teteje metszi el, akkor a kiraks eltt kell megnvelni a forrsindexet -YW-vel, ahol Y a BOB ordintja, W pedig a szlessge. Amikor a kp als szln helyezkedik el, egyszeren cskkenteni kell a sorkiraks szmlljt a rajzols megkezdse eltt. Nyilvn minden esetben, amikor a BOB mrete cskkent, az aktulis irnyhoz tartoz szmllt is cskkenteni kell, hiszen nem szabad tbbet kirakni belle, mint amennyi ltszik. Ha egyszerre a kperny tbb szle is keresztlmegy a BOB-on, akkor sszegezni kell nhnyat a ngy alapeset kzl. Pl. ha a bal fels sarkt tartalmazza, akkor mindenekeltt nvelni kell a forrsindexet annyival, amennyivel felfel nylik ki, majd minden sorrszlet kiraksa eltt annyival, amennyivel balra lg ki a kpernybl, egyszval kombinljuk az els s a harmadik alapesetet. Ha a kp jobb s bal oldaln is tlnylik, akkor az els kt esetet kell egyszerre alkalmaznunk. Az albbiakban kt brt lthatunk, kt szlssges helyzetet arra nzve, hogy a BOB hny kpszlt tartalmaz. A bal oldali rajzon egyet sem, teht teljes egszben lthat, a jobb oldali pedig mind a ngy szlt tartalmazza a kpernynek gy a sarkait is. A betk jelentse: X, Y koordintk, W szlessg, H magassg, U = 320-X-W, V = 200-Y-H. 320 Y X W V U X 320 V BOB BOB Kperny W H 200 200 U H

Kperny

A megjelents tovbbra is hrom lpsbl ll, melyek megegyeznek az elz rszben lertakkal (1. httr msolsa a munkaterletre, 2. BOB-ok megjelentse a munkaterleten, 3. munkaterlet msolsa a kpmemriba). A msodik lps, a BOB-ok rajzolsa ms, amelyet a fenti brk segtsgvel runk le. Elszr megnzzk, hogy az X, Y, U, V vltozk kzl melyik negatv. Ha egyik sem, akkor az egsz BOB lthat, s nem kell tovbb azzal trdni, hogy a BOB mely rszt kell kirajzolni, mert az egsz BOB-ot meg kell jelenteni. Ha a ngy rtk kzl negatv X A BOB a kperny bal szln van. DI (a munkaterletre mutat) eltolsa 320Y, a sorok kiraksa utn 320(W+X)-szel n. Minden sor kirajzolsa eltt az SI (Shape ofszetjre mutat) regisztert meg kell nvelni -Xszel. s CX (oszlopszmll) rtke minden sor kiraksakor W+X lesz. (X<0) Y A kp tetejn nylik tl. A DX (sorszmll) regiszter H+Y, SI-t -YW-vel nveljk. DI kezdeti eltolsa X, majd ez minden sor elksztse utn 320-W-vel n. U Jobbra lg ki. DI-t eleinte 320Y+X-szel nveljk, soronknt 320-(W+U)-val n. CX rtke W+U, SI minden sor befejezse utn -U-val n. V Olyan, mint a normlis megjelents, csak a DX regiszter H+V lesz.

28

Vegyk pldul a fenti jobb oldali brt. SI-hez eleinte hozzadunk -YW-t, majd -X-et, s minden sor kiraksa utn -U+(-X)-szel nveljk. DI eltolsa nulla, vagyis a munkaterlet elejre mutat, egy sor kiraksa utn nem kell nvelni semmivel, mert a BOB a kperny minkt fggleges szln is tlnylik. CX 320, DX rtke pedig 200. Ez mr gy meglehetsen szraz s rthetetlen, ezrt nzzk magt a pldaprogramot! A fenti brk sokat segthetnek a krdses BOB-megrajzol rsz megrtsben. {showbob5.pas} uses Crt; type BOB = object {Eltols} {00} A : wordbool; { Aktivitsjelz. Ha TRUE, akkor lthat {02} X : integer; { X koordinta (abszcissza) {04} Y : integer; { Y koordinta (ordinta) {06} LX: word; { Szlessg (lx=0-nl ez 1 kppont) {08} LY: word; { Magassg (ly=0-nl ez 1 kppont) {10} P : word; { Fzisszmll (p=0 : els fzis) {12} DT: pointer; { Shape helye a memriban {16} PL: word; { Egy fzis helyfoglalsa {18} W : word; { Valsgos szlessg (width ) {20} H : word; { Valsgos magassg (height) {22} LN: word; { Shape helyfoglalsa bjtban {26} PN: word; { Fzisszm (fzisok 0-val kezddnek) procedure Load( FileName: string); { Shape betltse lemezrl end; { Most csak kettt jelentnk meg const Bnum = 1; Blen = sizeof(BOB); { BOB tpus hossza Retrace: boolean = true; { Vertiklis visszafuts-jelz var B: array[0..Bnum] of BOB; { BOB-ok nemgrafikus adatai BackGround:pointer; { Httr mutatja WorkArea: pointer; { Munkaterlet mutatja u,v: integer; { A SHOWBOB eljrs hasznlja ket i: word; { ltalnos cl vltoz (FOR ciklushoz) procedure BOB.Load; var f: file; begin assign( f, FileName); reset( f, 1); seek( f, 1); blockread( f, LX, 2); blockread( f, LY, 2); blockread( f, PN, 2); W:= LX+1; H:= LY+1; PL:= W*H; LN:= PL*(PN+1); getmem( DT, LN); blockread( f,DT^,LN); close( f); A:= true; P:= 0; end;

} } } } } } } } } } } } } } } } } } } } }

{ { { { { { { { {

A fjl els bjtja nem hasznlatos A 2-3. bjt a Shape szlessgt adja A 4-5. pedig a magassgt Ezt kvet sz a fzisok szma Az igazi mretek eggyel nagyobbak Egy fzis hossza = szlessg magassg Shape hossza = fzishossz fzisszm Helyfoglals a Shape-nek Grafikus adatok betltse

} } } } } } } } } } }

{ Bekapcsoljuk, hogy lthat legyen { A fzismutatt az elsre lltjuk

procedure ShowBOB; assembler; asm { Ez a f eljrs, a megjelentst vgzi { 1. Httr msolsa a munkaterletre }

29

push mov mov cld les lds rep mov

bp bp,ds cx,32000

{ { { { di,workarea { si,background { movsw { ds,bp {

BP regisztert msra hasznljuk, az adatszegmenst troljuk benne A httr hossza 32000 sz (64000 bjt) D jelzbit trlse a REP utastshoz ES:[DI] mutat a munkaterletre DS:[SI] pedig a httrre Httr msolsa a munkaterletre DS jra az eredeti adatszegmens

} } } } } } } }

{ 2. BOB-ok rajzolsa a munkaterletre } mov @putbob: push lea mov mul add cx,bnum cx bx,B ax,blen cx bx,ax { { { { { BNUM BOB kiraksrl kell gondoskodni } Egy BOB kiraksa ciklus kezdete } CX-et majd msra hasznljuk (oszlopszm-} ll lesz a sorok megrajzolsnl) } BX:= B tmb ofszetcme }

{ BX-hez hozzadunk annyit, hogy az ppen } { aktulis (CX.) BOB-ra mutasson }

{ 2.1. Ellenrizzk, hogy a BOB, koordinti alapjn lthat-e } cmp jz cmp jge cmp jge mov add jnge mov mov add jnge mov neg add neg add word [bx],0 { @nextbob { word [bx+2],320 @nextbob { word [bx+4],200 @nextbob { ax,[bx+6] { ax,[bx+2] { @nextbob { u,ax { ax,[bx+8] { ax,[bx+4] @nextbob { v,ax { u u,319 { v v,199 { Az aktivitst jelz sz ellenrzse Ha hamis, akkor nem szabad kirajzolni { Ha X>=320, akkor nem lthat, ugrs a kvetkez BOB-ra { Ha Y>=200, akkor a kperny alja alatt van, ezrt nem kell megjelenteni Amikor balra helyezkedik el a kpernytl, LX+X<=0 Ekkor se kell brzolni LX+X-et troljuk, mert ksbb mg szksg lesz r, nem kell jra kiszmolni Ha LY+Y<=0, akkor ugrs a kvetkezre LY+Y-t is megjegyezzk U=320-X-W (=319-X-LX) V=200-Y-H (=199-Y-LY) } } } } } } } } } } } } } } }

{ 2.2. Meghatrozzuk a BOB lthat rszt } les mov mul add push les mov mul add add { 2.2.1. mov mov sub mov mov cmp jge si,[bx+12] ax,[bx+16] word [bx+10] si,ax es di,workarea ax,320 word [bx+4] ax,[bx+2] di,ax { { { { { { { { { { ES:[SI] mutat most a grafikus adatokra } [BX+16] = egy fzis hossza (PL) } [BX+10] az aktulis fzis (P) } SI a Shape aktulis fzisra mutat } ES-t troljuk, ksbb ez lesz a DS } ES:[DI] a munkaterlet mutatja } Kiszmoljuk a kpcmet, mint ha normli-} san brzolnnk (CIM=320Y+X) } Ksbb majd ezt fogjuk mdostani } DI=320Y+X } } } } } } } } }

Ha a kp fels szln helyezkedik el } dx,[bx+20] { DX a sorszmll az brzolsnl ax,320 { Egy sor kirajzolsa utn DI-t @DIPLUSax,[bx+18] { szal kell nvelni, amelynek rtke word [@diplus],ax { eleinte: 320-W word [@siplus],0 { @SIPLUS: amit SI-hez kell adni egy { sor kiraksa utn. Eleinte ez nulla word [bx+4],0 { [BX+4] a BOB ordintja (Y) @left { Ha ez nem negatv, lpnk tovbb

30

add mov add mov neg push mul pop add { 2.2.2. @left: mov cmp jge sub mov sub neg add add sub { 2.2.3. @right: cmp jge add mov sub sub { 2.2.4. @down: cmp jge add

dx,[bx+4] di,[bx+2]

{ sszesen H+Y sort kell kirakni { DI rtke X, kzvetlenl a kperny { tetejtl kezdve rajzoljuk a pontokat di,word [workarea] { DI-hez mg hozzadjuk a munkaterax,[bx+4] { let ofszetcmt } ax dx word [bx+18] { Csak a -Y. sortl kezdve kell megjeledx si,ax { nteni, ezrt SI-hez hozzadunk -YW-t Bal oldal } cx,[bx+18] { CX: hny pontot kell egy sorban kirakni word [bx+2],0 { [BX+2] a BOB abszcisszja (X) @right { Ha nem negatv, a jobb oldalt vizsglja di,[bx+2] { Kzvetlenl a bal szln kezdnk ax,[bx+2] { @DIPLUS rtkt X-szel cskkentjk, word [@diplus],ax { vagyis @DIPLUS n ax word [@siplus],ax { @SIPLUS n (-X-szel) si,ax { A -X. oszloptl kezdjk a sorokat cx,ax { Oszlopszmll cskkentse Jobb oldal } u,0 { U=320-X-W, ha nem negatv, nincs rajta @down { a kperny jobb szln, teht ugrs cx,u { CX cskken, kevesebb oszlop ax,u word [@siplus],ax { @SIPLUS n, egy sor kiraksa utn { SI-hez -U-val tbbet kell adni word [@diplus],ax { @DIPLUS is n Vizsgljuk, hogy a BOB az als szlen van-e } v,0 @put dx,v { V=200-Y-H, ha nulla vagy pozitv, nem { nylik tl a kpernyn lefele { Csak a sorszmllt kell cskkenteni

} } } }

} }

} } } } } } } } }

} } } } } }

} } }

{ 2.3. A BOB kirajzolsa a munkaterletre } @put: mov word [@cxsave],cx { CX-et elmentjk, ne kelljen minden } { sor kirakshoz jra kiszmolni } pop ds { A veremben legfell a Shape szegmense } { volt, gy DS:[SI] a forrscm } @putlines: { Sorok rajzolsa ciklus kezdete } mov cx,word [@cxsave] { CX a kirakand oszlopok szma } @putline: { Egy sor kiraksa ciklus kezdete } lodsb { AL:=byte ptr DS:[SI], SI:= SI+1 } cmp al,0 { Csak akkor kell kirajzolni ezt a pontot,} jz @notput { ha nem nulla } mov es:[di],al @notput: inc di loop @putline { Egy sor kiraksa ciklus vge, ha CX=0 } add di,word [@diplus] add si,word [@siplus] dec dx { Sorszmll cskkentse } jnz @putlines { Sorok rajzolsa ciklus vge, ha DX=0 } mov ds,bp { DS jra az eredeti adatszegmens } @nextbob: { Ide ugrik, ha a BOB nem ltszik } pop cx { CX megint a BOB-okat szmolja }

31

dec cmp jnz

cx cx,-1 @putbob

{ Egyet mr kiraktunk { De mg a tbbit is brzolni kell

} }

{ 3. Munkaterlet bemsolsa a grafikus trba (megjelents) } { 3.1. Vrakozs egy vertiklis visszafutsra } cmp retrace,0 { Ha a RETRACE rtke FALSE, jz @show { egybl a megjelents jn, nem vrunk mov dx,3dah { A $3DA porton keresztl figyeljk a @wait: { vertiklis visszafuts bekvetkeztt in al,dx test al,8 { 3. bit jelzi a visszatrst jz @wait { Ha nulla, mg vrni kell { 3.2. Munkaterlet msolsa } @show: mov es,sega000 { $A000 a grafikus tr kezdcme xor di,di mov cx,32000 { Ugyancsak 32000 szt msolunk lds si,workarea { A munkaterletrl msolunk rep movsw { Megjelents mov ds,bp pop bp jmp @exit @diplus: dw 0 @siplus: dw 0 @cxsave: dw 0 @exit: end; begin asm mov ax,13h int 10h { MCGA zemmd bekapcsolsa end; with B[0] do begin Load('plane.bob'); { Az egyik BOB egy repl x:=-w; { Balrl szik be (ppen nem lthat) y:= 100- h div 2; { Pont kzpen megy end; with B[1] do begin Load('rocket.bob'); { A msik meg egy rakta x:= 160- w div 2; y:= 200; { Lentrl jn felfele end; getmem( background, 64000); { Helyfoglals a httrnek s a getmem( workarea, 64000); { munkaterletnek for i:= 0 to 63999 do { Httr letakartsa mem[seg( background^):ofs( background^)+i]:= 0; randomize; { 1000 sznes pixel rajzolsa a httrre for i:= 1 to 1000 do mem[seg( background^):ofs( background^)+random( 64000)]:= i; { Fciklus, a megjelentst vgzi repeat ShowBOB; { Az 1. BOB mozgatsa with B[0] do begin inc( x, 4); { Balrl jobbra, amg ki nem szik a kpif x>=320 then begin { bl, majd az elejre ugrik, csak msik x:=-w; y:= random( 200+h)-h; { sorban end; end; } } } } } }

} } } }

{ Ez a hrom vltoz a kdszegmensben van,} { azrt nem az adatszegmensben, mert arra } { szksg van a BOB rajzolsnl }

} } } }

} } } } } } } } } } }

32

{ A 2. BOB mozgatsa, hasonlan, csak fel } with B[1] do begin dec( y, 3); if y<=-h then begin y:= 200; x:= random( 320+w)-w; end; if random( 3)=0 then p:= random( 3); { Kb. minden 3.-ra vlts } end; } until keypressed; {*} { Billentynyomsig megy az animci readkey; asm mov int end; end. ax,03h 10h

{ MCGA zemmd kikapcsolsa

A program elejn ltrehozzuk a BOB tpust, ami egy kicsit eltr az eddig megszokottaktl. Ugyanis nem rekord, hanem egy objektum, gy egy egysgbe tudjuk foglalni az adatokat s a Load utastst. A klnbz mezk lersa a mgttk tallhat {} rszben tekinthetek meg s a 8.23.11. fejezetben, hiszen a Game egysg BOB tpusa az itt szereplnek egy bvtett vltozata. A sebessg nemcsak a gp, hanem a videokrtya fggvnye is. PCI buszos krtykon ltalban jl megy, de ISA buszos krtyk esetben bizony elg lass a megjelents. Ez fkpp a kt busz sebessge miatt van, de meghatroz a videokrtya chipset-je s az alkalmazott memria sebessge is! Szerencsre a PCI buszos krtyk az elterjedtebbek, s az id elrehaladtval egyre gyorsabb hardverelemek kerlnek forgalomba. A ma legolcsbban kaphat krtyk is olyan gyorsak, hogy ez a mdszer jl alkalmazhat rajtuk. De termszetesen egy elavult, lass krtyn a futs is lass, darabos lesz. A konstansok kzl a RetRace szorul rszletesebb magyarzatra. Ez egy kezdrtkkel rendelkez logikai vltoz, ha rtke igaz, a megjelents 3. lpse eltt vrakozik egy vertiklis visszafuts bekvetkeztre. Ez lassabb, de szebb futst eredmnyez. Ha gpnk 80 MHz alatti, vagy tl sok a rezidens program, adjunk ennek a vltoznak hamis rtket. A vltozk deklarlst kveti a BOB tpus Load eljrsnak meghatrozsa. Ez egy fjl alapjn lltja be a BOB grafikus s nem grafikus adatait. A Shape-et a BOB-Editorral (6. fejezet) megszerkesztett fjlban troljuk, melynek felptse a kvetkez: Cm 0 1 3 5 7 Hossz (bjtban) 1 2 2 2 (LX+1)(LY+1)(PN+1) Jelents Fejlesztsre fenntartva, rtke 1. (Verziszm) Shape szlessge-1 (LX). A valdi szlessg ennl eggyel nagyobb. Magassg-1 (LY). Fzisok szma-1 (PN). Grafikus adatok

Ezutn jn a megjelent eljrs (ShowBOB). Lnyege megegyezik a 4. pldban megfogalmazottval, teht tovbbra is hrom f lpsbl ll, httr s BOB-ok msolsa a munkaterletre, munkaterlet megjelentse (kpmemriba msolsa). s vgl a fprogramban elvgezzk a szksges belltsokat, ezutn belpnk a megjelent s mozgat ciklusba, amibl billentynyomssal lehet kilpni. A ShowBOB eljrs vgn, a kdszegmensben tallhat hrom vltoz: @diplus, @siplus, @cxsave. Ezekre azrt van szksg, hogy a megjelent cikluson bell ne kelljen mindig visszatlteni az eredeti adatszegmens-regisztert, mert az sok idt vesz ignybe. Viszont emiatt a programot nem lehet vdett (protected) zemmdban futtatni, mert ilyenkor a kdszegmenset nem lehet rni. Ezzel befejeztk a fejleszts, elrtk vgs clunkat, ez a megjelent a fejezet elejn megfogalmazottak mindegyikt teljesti. Mint mindennek, termszetesen vannak htrnyai is, legfbb htultje taln a lasssg, a nagy memriaigny s a vdett md kizrsa. Viszont mindez kell a grdthet httr megvalstshoz. A pldaprogramoknak nem csak az a cljuk, hogy lpsenknt kzeltsk meg a vgs eljrst, hanem az is, hogy az Olvast lehetleg minl tbb megjelentsi mdszerrel ismertesse meg. Ezrt ha egy jtkban nincs szksg grgetsre, nyugodtan kombinlhatjuk a 3. s az 5. pldaprogramban tallhat BOB-megjelent (ShowBOB) eljrst. Ilyenkor a httr lland, teht nem kell minden frisstsnl az egszet lemsolni, hanem elg csak a BOB-ok ltal takart rszeit. Ezzel lnyegesen megnvelhetjk programunk sebessgt, viszont kizrjuk a tetszlegesen vltoztathat httr lehetsgt. A ksbb ismertetsre kerl Game egysg megjelent eljrsai (MakeScr 8.12., ShowScr 8.20) is ezt, a SHOWBOB5.PAS pldaprogramban megismert megjelentsi mdszert alkalmazzk. (Annak egy kicsit bvtett formjt.)

33

3. Billentyzet s egr
Ez a kt eszkz nem tartozik ugyan szorosan a jtkok grafikai rsznek megvalstshoz, viszont nagyon fontos foglalkozni velk, fknt a billentyzettel. Ez ugyanis a leginkbb hasznlt bemeneti egysg, szinte az sszes jtk, st az sszes program kezelhet csak billentyzettel. A jtkok irnytsa ltalban a kvetkez ngy berendezs valamelyikvel trtnik, melyeket elfordulsuk gyakorisgnak sorrendjben mutatunk be, nhny szval: 1. Billentyzet. Minden szmtgp elengedhetetlen tartozka. Teht a leggyakoribb, ezrt kln kitrnk r. 2. Egr. A programok tbbsgnl nlklzhet az egr, gyakran ugyanazt a hatst sokkal gyorsabban el tudjuk rni, mint a billentykkel. De a felhasznli programok nagy tbbsgnl, a kezels egyszersge s knyelmessge rdekben nlklzhetetlen. Ezrt majdnem minden gp mellett megtallhat. 3. Botkormny. Kifejezetten jtkok irnytshoz alkalmazhat. 4. Gamepad. A videojtkok elengedhetetlen tartozka, de egyre inkbb trt hdt a szmtgpes vltozata is. A ngy lehetsg kzl csak a kt leggyakoribbal, a billentyzettel s az egrrel foglalkozunk. Ezek sokkal srbben fordulnak el, mint a msik kett, emiatt rdemes egy kicsit rszletesebben is kitrni rjuk.

3.1. A billentyzet mkdse


Ha megnyomunk vagy felengednk egy billentyt, aktivldik a $09-es megszakts. A $09 sorszm megszakts beolvassa az t kivlt billenty adatait (SCAN kd, llapot) a $60-as portrl, majd ellltja annak az ASCII kdjt. Gpelsre, egyszer adatbevitelre kivlan alkalmas, hiszen pldul automatikusan kiszmolja az ASCII kdot a SCAN kdbl. Jtkok irnytsra viszont alkalmatlan. Ha egy BOB koordintit a normlis BIOS billentyzet-megszakts alkalmazsval akarjuk megvltoztatni, akkor a BOB mozgsa meglehetsen darabos lesz, s az els lps utn vr egy ideig. Az a clunk, hogy egy billenty lenyomst folyamatosan tudjuk rzkelni. Ez megvalsthatatlan a bekapcsols utni aktv BIOS megszaktssal, tbb okbl is. Folyamatosan nem figyelhet egy billenty, mg ha a kvetkez sort be is gpeljk a DOS prompt utn: MODE CON RATE=32 DELAY=1 Ha ezzel vezrelnnk egy mozgst, az darabos lenne. Msik problma, hogy ha minden billentynyoms utn nagy memriatartomnyokat mozgatunk (pldul a (megnyomsra jobbra grgetjk a htteret), akkor a hangszr spol, programunk futsidejben nagy kihagysok keletkeznek. (A spols oka, hogy a billentypuffer betelik, s a mi programunk nem tudja kell gyorsasggal kiolvasni az adatokat.) Teht pldul a Crt egysg billentyvezrl eljrsaival (readkey, keypressed), amik az eredeti megszaktst hasznljk, nem rdemes egy jtk vezrlst vgeztetni, mert az irnytott elem (BOB, httr) mozgsa meglehetsen darabos, egyenetlen lesz. Akr rhatunk egy rvidke kis pldaprogramot is, hogy errl meggyzdhessnk. A SHOWBOB5.PAS pldaprogram {*}-gal jelzett sort (htulrl az 5. sor) rjuk t a kvetkezre: until readkey=#27; Most a BOB-ok csak akkor mozognak, ha folyamatosan nyomva tartunk egy billentyt, ESC-re pedig befejezdik a program futsa. Nos, szemmel lthat, hogy a BIOS megszaktsa erre a clra alkalmatlan. Mit kell akkor tenni? Egyszer, t kell rni a $09 megszaktst, vagyis a megszaktsvektor mdostsval utastani kell a processzort, hogy billenty llapotnak vltoztatsakor ne az eredeti BIOS rutint hajtsa vgre, hanem a sajt assembly utastsainkat. Ez a sajt rutin nem tl bonyolult, elmenti a verembe a hasznlt regisztereket, beolvas a $60 portrl egy bjtot (0-6. bit: SCAN kd, 7. bit: llapot), trolja ezt a kt adatot, nyugtzza a megszaktsi ramkrket, majd a regiszterek visszatltse utn egy iret utastssal zrul. A billenty adatait a kvetkez mdon troljuk. A program elejn ltrehozunk egy 128 elem logikai tmbt, majd igaz vagy hamis rtket adunk annak a tagjnak, amelyiknek sorszma megegyezik a lenyomott vagy felengedett billenty SCAN kdjval. Ebbl ltszik az is, hogy a SCAN kdok maximlis rtke 127, ami jval tbb, mint a billentyk szma (86-102). Minden billentyhz egy SCAN kd tartozik. Nzzk teht a pldaprogramot, mely folyamatosan kirja a lenyomott billenty(k) SCAN kdjt.

34

{keyb1.pas} uses DOS; var KEY: array [0..127] of boolean; { Ez a tmb trolja a billentyk adatait OLD: procedure; { A rgi megszaktsvektor i : byte; { A FOR ... TO ... DO ... ciklushoz } } }

procedure push push push push xor mov mov mov in mov shl cmc adc and mov in mov or out mov nop nop nop out cli mov out sti pop pop pop pop iret end;

NewIRQ; assembler; asm ds { Azokat a regisztereket, amelyek a meg- } ax { szakts vgrehajtsa kzben mdosulnak,} bx { a veremben troljuk } cx cl,cl { Nhny regiszter kezdeti rtke } bh,cl ax,seg key { DS a KEY tmb szegmense } ds,ax al,60h { AL-be beolvassuk a billenty SCAN-kdot } bl,al { BL-be is bevisszk a kdot } al,1 { C jelzbit (FLAG) = 7. bit } { Ezt negljuk, gy ha 0, felengedtk az } { adott billentyt, ha 1, akkor lenyomtuk } cl,00 { CL most 0 vagy 1 lehet (FALSE, TRUE) } bl,127 { Az als 7 bit adja a valdi SCAN-kdot } [offset key+bx],cl { A megszaktst kivlt billenty- } { hz tartoz logikai vltoz belltsa } al,61H { A megszakts csatorna visszalltsa } ah,al al,80H 61H,al { Jelzs a billentyzetnek } al,ah { Kevs vrakozs } { (soros adatkiklds sebessge miatt) } 61H,al al,20H 20H,al cx bx ax ds { "Megszakts vge" jelzs { Regiszterek visszaolvassa a verembl } }

{ Vge a megszaktsnak

begin getintvec( $09, @OLD); { A rgi megszaktsvektort troljuk } setintvec( $09, @NewIRQ); { A $09 megszakts ezentl a NEWIRQ } { eljrst hvja meg } fillchar(key,sizeof(key),0); { KEY tmb nullzsa (FALSE) } repeat for i:= 0 to 127 do if key[i] then writeln(i); { A lenyomott billenty kdja a kpernyre} { ESC megnyomsig } until key[1]; setintvec( $09, @OLD); end. Mint ahogy az a program f rszbl is ltszik, egy billenty figyelshez egyszeren csak figyelni kell a KEY tmb hozz tartoz elemt. Ha pldul lenyomjuk az ESC billentyt, amelynek a SCAN-kdja 1, akkor a KEY[1] rtke igaz lesz, ami addig igaz, amg az ESC-t lenyomott llapotban tartjuk.

35

Elfordulhat, hogy a programbl val kilps utn a billentyzet nem mkdik helyesen. gy viselkedik ilyenkor, mintha valamelyik Ctrl billenty le lenne nyomva. A hiba megszntetshez nyomjuk meg mindkt Ctrl billentyt egyszerre! Ezt a hibt sajnos nem tudjuk kikszblni. Addhat egy msik hiba is. Nhny billenty lenyomsakor (pl. szrke nyilak) a program azt mutatja, hogy a $2A(42) kd bal oldali Shift-et is megnyomtuk volna, holott nem is tettk ezt. Ez ellen csak annyit tehetnk, hogy nem hasznljuk egyszerre a bal Shift gombot s a nylbillentyket. (Egybknt a NumLock letsvel megsznik ez a problma, majd jbli megnyomsval jra megjelenik.) Hasonltsuk ssze az elz programot a kvetkezvel, ami a lenyomott billenty ASCII kdjt rja ki, a BIOS megszakts hasznlatval. Figyeljk meg, az elz mennyire gyorsabb s egyenletesebb! {keyb2.pas} uses Crt; var C: char; begin repeat C:= readkey; writeln( ord( C)); until C=#27; end. { Most a CRT egysget, vagyis a BIOS { billenty megszaktst hasznljuk { A lenyomott billenty ASCII kdja lesz } } }

{ A C karakter ASCII kdjt kirjuk { ESC-re kilps a programbl

} }

A mdostott megszaktsnak is van egy htrnya, csak az XT-khez gyrtott billentyzeteknl mkdik tkletesen, 101 gombos klaviatrn egyes billentyprok kztt mr nem tudunk klnbsget tenni. Pldul mindkt Ctrl kdja $1D, pedig gyakran szksg lenne a megklnbztetskre. Nevezzk el bvtett billentyknek azokat, amelyek a 101 gombos tasztatrn megtallhatak, a 86 gomboson viszont nem. Minden ilyen bvtett billenty lenyomsakor vagy felengedsekor a SCAN kd eltt a $60 perifriacmrl egy $E0 rtk bjt rkezik, ezt hasznljuk majd ki arra, hogy az azonos funkcij billentyket megklnbztessk. A kvetkez billentyk llapotvltoztatsakor jn ltre ez az $E0 rtk: Szrke nylbillentyk, Szrke Ins, Del, Home, End, Page Up s Down, Jobb oldali Alt s Ctrl, A numerikus billentyzet Enter s / gombja. Msknt szlva ezek a billentyk jak a 86 gombos XT billentyzetekhez kpest. Az albbi brn lthatjuk elhelyezkedsket:

A kvetkez pldaprogram annyiban tr el az elztl, hogy mr az sszes billentynek sajt kdja van. A KEY tmbt 256 elemre tgtjuk, a bvtett billentyk a [128..255] intervallumba esnek. Eredeti SCAN kdjukat gy kapjuk meg, hogy az igazra vlt elembl kivonunk 128(80h)-t. Mivel az sszes billenty kdja nagyobb nullnl, ezrt a nulladik elemben troljuk tmenetileg az informcit a bvtett billentykrl. (Ha KEY[0]=TRUE, akkor a kvetkez billenty SCAN kdjhoz 128-at adunk.) {keyb3.pas} uses DOS; var KEY: array [0..255] of boolean; { Most 2128 elem a tmb OLD: procedure; { A rgi megszaktsvektor i : byte; { A FOR ... TO ... DO ... ciklushoz } } }

36

procedure push push push push xor mov mov mov in cmp jnz mov jmp @1: cmp jnz mov mov @2: mov and add xor shl cmc adc mov

NewIRQ; assembler; asm ds { Azokat a regisztereket, amelyek a meg- } ax { szakts vgrehajtsa kzben mdosulnak,} bx { a veremben troljuk } cx cl,cl { Nhny regiszter kezdeti rtke } bh,cl ax,seg key { DS a KEY tmb szegmense } ds,ax al,60h { AL-be beolvassuk a billenty SCAN kdjt} al,0e0h { Ha bvtett, eltte E0-t olvashatunk be } @1 { Ha nem az, azt tesszk, amit korbban } byte [offset key],1 { Jelezzk, hogy a kvetkez bil} { lenty kdjhoz 128-at kell majd adni } @end { Most nincs tbb dolgunk } { Ha nem $E0 kdot kaptunk } byte [offset key],1 { Megvizsgljuk, hogy elzleg nem } @2 { $E0 kdot kaptunk-e } cl,128 { Ha igen, 128-cal nveljk a SCAN-kdot } byte [offset key],0 { Nullzzuk a jelz-vltozt } bl,al bl,127 bl,cl cl,cl al,1 { BL-be is bevisszk a kdot { Az als 7 bit adja a valdi SCAN-kdot { Ha bvtett a billenty, BL:= BL+128 { CL regiszter nullzsa { C jelzbit (FLAG) = 7. bit { Ezt negljuk, gy ha 0, felengedtk az { adott billentyt, ha 1, akkor lenyomtuk cl,00 { CL most 0 vagy 1 lehet (FALSE, TRUE) [offset key+bx],cl { A megszaktst kivlt billenty{ hz tartoz logikai vltoz belltsa } } } } } } } } } }

@end: in al,61H { A megszakts csatorna visszalltsa } mov ah,al or al,80H out 61H,al { Jelzs a billentyzetnek } mov al,ah nop { Kevs vrakozs } nop { (a soros adatkiklds sebessge miatt) } nop out 61H,al cli mov al,20H { "Megszakts vge" jelzs } out 20H,al sti pop cx { Regiszterek visszaolvassa a verembl } pop bx pop ax pop ds iret { Vge a megszaktsnak } end; begin getintvec( $09, @OLD); { A rgi megszaktsvektort troljuk } setintvec( $09, @NewIRQ); { A $09 megszakts ezentl a NEWIRQ } { eljrst hvja meg } fillchar(key,sizeof(key),0); { KEY tmb nullzsa (FALSE) } repeat 1 to 127 do if key[i] then writeln(i:3); for i:= { A lenyomott billenty kdja a kpernyre} for i:= 128 to 255 do if key[i] then { Ha a bvtett a billen- } writeln(i-128:3,'+');{ ty, egy pluszjelet is kirunk utna } { ESC megnyomsig } until key[1]; setintvec( $09, @OLD); end.

37

A kvetkez tblzat az egyes billentykhz tartoz kdokat mutatja be, tizenhatos szmrendszerben. Sok ms knyvben tallhat ugyanilyen tblzat, egy klnbsggel, hogy itt nhny billenty kdja nagyobb 80hnl. Az eredeti SCAN kdjt ezeknek a billentyknek a kdbl 80h-at kivonva kaphatjuk meg. Ugyanez a tblzat megtallhat a lemezmellkleten, a SCANCODE.TXT fjlban. Ezt rdemes kinyomtatni, gy nem kell mindig idelapozni. Az egyes billentyk SCAN-kdjai, tizenhatos szmrendszerben

A mdostott megszakts a Game egysg InitKey eljrsval (8.8. rsz) is bellthat. Ez a unit is tartalmaz egy Key tmbt. Ha lenyomott llapotban van egy billenty, akkor ennek a tmbnek a billentyhz tartoz eleme igaz. Hogy melyik billentyhz melyik elem tartozik, azt olvashatjuk le a fenti tblzatbl (ami a SCANCODE.TXT fjlban is megtallhat).

3.2. Az egr programozsa, a Mouse egysg


Az egr adatait legegyszerbben a $33 megszakts segtsgvel krdezhetjk le, illetve llthatjuk be. A 33h sorszm megszakts alapesetben res, csak az egrkezel (mouse driver) programok betltse utn lteznek a rutinok. Ezt a megszakst hasznlja a Mouse Pascal unit is. Elszr az InitMouse fggvnnyel inicializlni kell az egeret, majd ha az egrkurzort meg akarjuk jelenteni, a ShowMouse eljrst is meg kell hvni. Ennyi elegend ahhoz, hogy lthat legyen, az egysg azonban nem csak ezt a kt szubrutint tartalmazza, ebben a rszben a tbbi eljrssal s fggvnnyel is megismerkedhetnk, betrendben. Az egr koordintira ugyanazok rvnyesek, mint egy pixel koordintjra, abszcisszja 0 s 319 kz esik, ordintjnak pedig 0 s 199 kztt kell lennie. Ez a koordinta-rendszer azonban csak erre az egysgre s MCGA kpszerkezetre rvnyes. Valjban az egrkurzor abszcisszja minden kpszerkezetnl beleesik a [0..639] intervallumba, vagyis a kperny jobb oldali legszls kppontjainak els koordintja 639. Hogy ne kelljen mindig kettvel osztani vagy szorozni, a Mouse egysg mr a norml MCGA koordintkat hasznlja. Ezrt ez a unit csak 320200-as felbonts mellett ad helyes koordintkat, szveges mdban pldul mr nem, annak ellenre, hogy ms videomdoknl is mkdik. ButtonPressed fggvny Szintaxis: ButtonPressed: boolean; rtke akkor igaz, ha az egr egy gombja le van nyomva. A 33h megszakts sok egr kzps gombjnak lenyomst nem tudja rzkelni, ezrt legtbbszr csak a bal vagy a jobb gomb kattintsa utn kapunk igaz rtket.

38

DisableArea eljrs Szintaxis: DisableArea(X1, Y1, X2, Y2: word); Meghatroz egy (X1;Y1) bal fels sark, (X2;Y2) jobb als sark tglalap alak tartomnyt, ahol az egr nem mozoghat. Az X1 s X2 vltozk rtknek 0 s 319 kz kell esnie, az Y1 s Y2 pedig 0 s 199 kztt lehet. Ezenkvl igaznak kell lennik a kvetkezknek: X1<X2 s Y1<Y2. Ha pldul a kperny jobb als sarkban lv 88-as rszen nem mozoghat az egrkurzor, a kvetkezt kell berni: DisableArea( 312,192,319,199); EnableArea eljrs Szintaxis: EnableArea(X1, Y1, X2, Y2: word); Az egr mozgstert vltoztatja, az utasts vgrehajtsa utn az egr csak az (X1;Y1) bal fels s (X2;Y2) jobb als sark tglalapon bell mozoghat. A koordintkra ugyanazok rvnyesek, mint a DisableArea eljrsnl, vagyis X1 s X2 0 s 319, Y1 s Y2 pedig 0 s 199 kz esik (a szls rtkeket mg felvehetik), s X1<X2, Y1<Y2. Az eljrs a kvetkez paramterekkel az egsz kpernyn engedlyezi a mozgst: EnableArea( 0,0,319,199); Azt, hogy az egrkurzor a kperny bal feln jelenhessen meg, ktflekppen oldhatjuk meg: EnableArea( 0,0,159,199); vagy DisableArea( 160,0,319,199); GetMouse eljrs Szintaxis: GetMouse(var M: MouseType); Az eljrs az egr adatait adja meg a paramterben megadott vltozba. A MouseType tpus a Mouse egysgben gy lett deklarlva: type MouseType = record X,Y: word; Left, Middle, Right: boolean; end; X s Y az egr koordinti, az utols hrom mez (Left, Middle, Right) rtke pedig akkor igaz, ha a bal, kzps vagy jobb gombot lenyomtuk. Ezeket az adatokat egyszerbben megkaphatjuk a MouseX, MouseY, LeftButton, RightButton fggvnyek segtsgvel. GetSensitivity eljrs Szintaxis: GetSensitivity(var M: SensType); Az egr rzkenysgt krdezi le az M vltozba, melynek tpusa a Mouse unit meghatrozsa szerint: type SensType=record X,Y,S: word; end; X s Y a vzszintes s fggleges rzkenysget adjk, vagyis az adott irnyban hny kb. 1/200 hvelyk hosszsg egysg (Mickey) tallhat. Az S tartalmazza a sebessget, a msodpercenknti Mickey-ek szmt. Nem tl gyakran van szksg erre az eljrsra, taln inkbb a prjra, a SetSensitivity-re. GotoMouse eljrs Szintaxis: GotoMouse(X, Y: word); Az egrkurzor helyzett a paramterekben megadott rtkek szerint lltja be. A koordintk az MCGA kperny-koordintkkal kompatibilisek. HideMouse eljrs Szintaxis: HideMouse; Eltnteti az egrkurzort. Ha nem lthat, attl mg ugyangy le tudjuk krdezni helyzett, llapott, ugyanolyan mveletek hajthatk vgre, mintha lthat lenne. Csak a felhasznl szmra lesz egy kicsit nehezebb az egeret a kell helyre irnytani. InitMouse fggvny Szintaxis: InitMouse: boolean;

39

Inicializlja az egeret, bekapcsolja azt, de lthatv mg nem teszi. Minden egrkezel program elejn le kell futtatni ezt a szubrutint. Ha a visszatrsi rtk igaz, a mvelet sikeresen befejezdtt, ha nem, akkor az egr nem installlhat. LeftButton fggvny Szintaxis: LeftButton: boolean; A fggvny rtke akkor, s csak akkor igaz, ha az egr bal oldali gombja le van nyomva. Hasznlata igen egyszer, a kvetkez rvid program be is mutatja: uses Mouse; begin if not InitMouse then halt; {Megllts, ha nem installlhat} write('Kilps - bal gomb'); repeat until LeftButton; end. MouseMoved fggvny Szintaxis: MouseMoved: boolean; A fggvny akkor igaz, ha az egeret megmozdtottuk. Pldul a kpkmlknl lehet hasznos ez a rutin, vagy ha az egr koordintit llandan ki szeretnnk rni a kpernyre, gy nem kell folyamatosan rni, elg csak akkor, ha azok megvltoztak. MouseSpeed eljrs Szintaxis: MouseSpeed(S: word); Az egr maximlis sebessgnek belltsa. S a sebessg fels korltja (lpskz/msodperc). Nem rdemes nagyon tlltani, mert az InitMouse utni alaprtkek ltalban megfelelek, de ksrletezni persze lehet. MouseX fggvny Szintaxis: MouseX: word; Az egr abszcisszja (els koordintja) az MCGA kpszerkezethez igaztva, gy rtke [0..319] kztt van. MouseY fggvny Szintaxis: MouseY: word; Az egr msodik koordintja. rtke MCGA zemmdban [0..199] kz esik. RightButton fggvny Szintaxis: RightButton: boolean; A fggvny igaz, ha a jobb oldali gomb le van nyomva (a LeftButton-hoz hasonlan). Sensitivity fggvny Szintaxis: Sensitivity: word; Az egr rzkenysgt adja, azt hogy milyen sebessggel mozog. Nem lnyeges annyira ez a fggvny. SetSensitivity eljrs Szintaxis: SetSensitivity(X, Y, S: word); Az egr rzkenysgt vltoztathatjuk vele, ha a kiindulsi llapot nem felel meg. X a vzszintes, Y a fggleges Mickey-ek (1/200 inch egysgek) szma, S a sebessg (Mickey/msodperc). Ha nem jk az alaprtkek kevs ksrletezssel, prblkozssal megfelelen be tudjuk lltani egernk rzkenysgt. ShowMouse eljrs Szintaxis: ShowMouse; Az egrkurzort lthatv teszi. Ez grafikus zemmdban egy fehr nyl, fekete szegllyel.

40

4. Httr
Legegyszerbb az egyszn httr, azonban a legtbb jtk ennl jobb kpet ignyel. Vegyk alapul a SHOWBOB5.PAS pldaprogramot! A httrnek mint az MCGA zemmdnak is 320200 felbontsnak s 256 sznnek kell lennie. A memriban a BackGround pointerrel meghatrozott 64000 bjton helyezkedik el. A kvetkez eljrs a htteret az eljrs paramterben megadott C sznre festi. gy nagyon knnyen elkszthetjk az egyszn htteret. procedure asm mov mov mov cld les rep end; FillBackGround( C: byte); assembler; al,C ah,al cx,32000 di,background stosw

Ha tudjuk, hogy jtkunk httere egyszer, de nem egyszn, klnbz szn pontokat kell kigyjtani. Ezt hasonlkppen rhetjk el, mint a PUTPIXEL.PAS program PutPixel eljrsban, csak az ES:[DI] most nem a kpernyre, hanem a BackGround pointer ltal meghatrozott tartomny valamely bjtjra mutat. Egybknt az eljrs ugyanaz, elszr ES:[DI]-be betltjk a BackGround mutatt, majd DI-hez hozzadunk 320Y+X-et. procedure les mov mul add add mov mov end; PixelBack( X, di,background ax,320 y ax,x di,ax al,c es:[di],al Y: word; C: byte); assembler; asm { { { { Egy sor 320 kppontbl ll Megvan a megfelel sor els bjtja AX a megfelel cmet tartalmazza, mr csak hozz kell adni DI-hez } } } } }

{ A megfelel bjt C-re vltoztatsa

Ezzel a kt eljrssal mr tudunk egyszer htteret kszteni. Elszr befestjk egysznre a FillBackkel, majd a PixelBack eljrs s FOR TO DO ciklusok segtsgvel vzszintes vonalakat rajzolva ksz is egy egyszer ugrls jtk httere.

4.1. LBM kp betltse


Egy ignyesebb jtkhoz nem elg ilyen primitv httr. Ha olyan programot runk, melyben a jtk mgtti kp vltozatlan, legjobb rajzolprogrammal elkszteni, vagy kzzel, s utna egy szkenner segtsgvel lemezre vesszk. Akr programmal, akr kzzel rajzolunk, vgl kpnknek egy szabvnyos, sokak ltal ismert kpformtumban kell elhelyezkednie. Kpformtum az a trolsi mdszer, mely a kp egyes bjtjait (szneit, pontjait) trolja. Ez lehet tmrtett s tmrtetlen. A legltalnosabb kpformtumok: BMP, GIF, JPG, LBM, PCX, TIF. Az esetek tlnyom tbbsgben a fjl kiterjesztse megegyezik az elbb felsorolt szavakkal, teht pldul a RAJZ.BMP nagy valsznsggel kpfjl (kpet tartalmaz fjl), BMP formtum. Ezeket a trolsi mdszereket a legtbb grafikakszt vagy -feldolgoz program ismeri, ezrt clszer lenne az egyiket kivlasztani, s az ltala trolt kp megjelentsi mdjt kicsit rszletesebben ismertetni. Elg egy formtummal foglalkozni, mert a rajzol- s kpnz-programok legtbbjvel ezek egymsba konvertlhatk. Mire lesz szksg? Ahhoz, hogy rajzunk a szmtgpben megjelenjen szksg van vagy egy rajzolprogramra, vagy egy szkennerre (a hozz tartoz kezelszoftverrel egytt), vagy egy kplopra. A kplop (capture) programok lnyege a kvetkez: memriarezidensek, egy tetszleges programbl, akr egy jtkbl elre megszabott billenty vagy billentykombinci lenyomsa utn az ppen akkor aktulis kp a lemezre kerl, elre meghatrozott kptrolsi formban. Persze nem vall valami fantziads s ignyes munkra, ha jtknak httereit valaki ilyen lopott kpekbl lltja ssze.

41

A rajz most mr a fent emltett formtumok egyikvel trolva a lemezre kerlt, feltve hogy rajzolvagy kplop programunk, vagy szkennernk szoftvere ismeri a fenti formtumok valamelyikt. Ebben a knyvben csak az LBM kpszerkezet ismertetsre kerl sor, gy szksg lesz mg egy kpkonvertl programra, mely LBM formban is el tudja menteni a kpet. Mieltt rtrnnk arra, mirt pont az LBM-et vlasztjuk, ismerkedjnk meg nhny ms tpussal is! A BMP fjlok a kpet tmrtetlen (ritkbb esetben RLE kdolssal) formban troljk, egy 320200/256 kp trolsa gy legalbb 64000 bjtot vesz ignybe, ehhez mg hozzjn a fejlc hossza s a paletta. A fejlc tartalmazza a kpre vonatkoz adatokat (szlessg, magassg, sznek szma). Igaz hogy a BMP-ben trolt kpek megjelentse egyszer, s a BMP szerkezet is elterjedt (taln a legelterjedtebb trolsi forma), ennek ellenre nem ezt hasznljuk, mert tl nagy helyet foglal. Tegyk fel, hogy egy hzban jtszd jtkot szeretnnk rni, a hz minden szobjt BMP fjlknt troljuk. Hogy jtkunkat knnyen msolhassuk egyik gprl a msikra, rdemes rvidnek lennie, mert j ha rfr egy 31/2-es lemezre, ami ltalban 1,44 Mbjt mret. Kevs szmols utn nyomban kiderl, hogy a hz legfeljebb 22-23 szobt tartalmazhat. A GIF s a JPG formtumok elterjedtek, nagyon j arnyban tmrtnek, azaz a fjl mrete a tmrtetlen kp mretnl sokkal kisebb. A GIF-ben s JPG-ben kdolt kpek megjelentse azonban nagyon nehz megjelenteni, s arnylag sok idt vesz ignybe. Radsul a GIF fjlokban alkalmazott LZW kdols jogvdett, ezrt elvileg nem is lehet szabadon alkalmazni. (Visszafejteni azrt mg lehet.) A kzputat az LBM jelenti, melynek visszafejtse egyszer, s a kpet srtve trolja. A tmrts lnyege az, hogy az egyms mellett elhelyezked azonos bjtok helyre kt bjt kerl. Ez pont j neknk, mert jtkaink tbbsgnek httere sok azonos szn pontot tartalmaz, pldul a fal vagy az g. gy elg j tmrtsi arnyt rhetnk el. A lenti LoadLBM megjelent csak 256 szn, 320200-as felbonts kpeket tud megjelenteni, noha az LBM fjlok trolhatnak teljesen ms mret s szn grafikkat. Viszont mi csak az MCGA kpszerkezettel foglalkozunk, ezrt ms szn kpeket nem is vagy csak igen nehezen tudnnk brzolni. A kp mrete ettl fggetlenl ugyan lehetne nagyobb, s ilyenkor egy megadott 320200-as tartomnyt rajzolnnk ki a kpernyre, de a fjl mrete a megjelents mdja miatt nem haladhatja meg a 65520 bjtot. Egybknt ha az MCGA felbontstl eltr lenne a kp mrete, az a megjelentst lassabb tenn, nem lehetne folyamatos megjelentst alkalmazni, a memriaignye is nagyobb lenne stb. Maradjunk annl, hogy kpnk szlessge 320, magassga 200 kppont, a sznek szma pedig 256. Erre mr az elksztsnl is gyeljnk! A fjl felptst tekintve kt fbb rszre oszthat, elejn a kp nem-grafikus adatait tallhatjuk (fejlc, paletta stb.), a vgn pedig a grafikus adatokat. Az elsvel klnsebben nem rdemes foglalkoznunk, hiszen a kpmret, sznek szma adott, csak a palettt olvassuk ki onnan. A msodik nagy egysget az elstl nyolc bjt vlasztja el egymstl: a BODY cmke az els ngy bjt, a msodik ngy bjt a kp tmrtett mrete. Itt jegyezzk meg, hogy az LBM fjlokban a bjtnl nagyobb mret adatok (szavak, duplaszavak) nem bjtfordtottan kerlnek trolsra, egy sz beolvassa utn annak als s fels bjtjt ki kell cserlni (az xchg utastssal). A tmrtsi eljrs pedig a kvetkez. A kppontok (sorfolytonosan) vltoz hosszsg egysgekre vannak felosztva, melyek hossza legfeljebb 128 pixel. Egy ilyen egysg lehet tmrtett vagy tmrtetlen. Minden egysg elejn tallhat egy B bjt, amelynek ha a 7. bitje 0, akkor az azt kvet B+1 bjt (legfeljebb 128, mert a B 7. bitje zrus) nincs tmrtve, azaz egy bjt egy pixelt hatroz meg, melyeket sorfolytonosan kell kirni. Ha a B legfels bitje 1, akkor tmrtsrl van sz. Ilyenkor az egysg hossza (B-vel egytt) 2 bjt, s a msodikat kell (neg B)+1-szer kirakni, vagyis a B kettes komplemenshez egyet adunk, s ennyiszer egyms utn, sorfolytonosan kirakjuk a B-t kvet bjtot. Az egyes egysgek vgt nem jelzi semmi, gy be kell iktatni egy szmllt, aminek kezdeti rtke B vagy (neg B)+1, ha ez elri a nullt, j egysg kezddik. Kis szmols utn rjhetnk, hogy egsz j tmrtsi arnyt rhetnk el. Ha a kp egyszn, minden 128 pixelt 2 bjton trolva az arny 1/64 (1,6%). A fjl mrete gy 64 helyett (nem-grafikus adatokkal s a palettval) nem tbb, mint 2 kB. Viszont ha minden kppont ms szn, mint a mellette lev, akkor a fjl mrete nagyobb lesz (64000/128 bjttal), mintha nem lenne tmrtve. A paletta a fjl $30 cmtl kezddik, 256 sznnl 768 bjt hossz. Mr a mretbl is ltszik, hogy RG-B sznsszetevnknt van trolva, csak egy kicsit mskpp, mint ahogy azt gondolnnk (8 bites formban). Itt a 7-2. bit jelzi az adott szn adott sszetevjnek az intenzitst, a 1-0. bit rtke nulla. Ezrt, hogy a videokrtya a megfelel adatokat kapja, minden P palettabjtot el kell forgatni jobbra kettvel (normlis sznadat = P shr 2). Most mr mindent ami neknk fontos tudunk az LBM fjlrl, vzoljuk a megjelent eljrst! 1. A lemezrl az egsz fjl tartalmnak beolvassa egy elre lefoglalt vltozba. ppen ezrt a fjl mrete nem lehet nagyobb 65520 bjtnl, mert ez a vltozk maximlis mrete. Megtehetnnk azt is, hogy egybl a lemezrl fejtjk vissza az adatokat, gy nem lenne szksges felttel a 64K szabad memria, de lnyegesen lelasstan a mveletet.

42

2. A paletta belltsa a $30. bjttl kezdve, minden bjtot 2 bittel jobbra forgatva. 3. BODY cmke megkeresse. Elszr a B-t kutatja a scansb karakterlnc-mvelet segtsgvel, majd ha tallt egy ilyen bjtot (rtke 66), sszehasonltja az azt kvet hrom bjttal egytt a BODY cmkvel. Ha vgigvizsglta a megadott tartomnyt gy, hogy nem tallta meg ezt a ngy karaktert, hibt jelez. 4. Megjelents. Az eljrs meghvsa eltt be kell lltani a videokrtyt MCGA zemmdba, ha a kpet a kpernyre akarjuk kirajzolni. A FileName paramterben a fjl nevt adjuk meg, elrsi tvonallal egytt, ha szksges, a P pedig arra a legalbb 64000 bjt hosszsg terletre mutasson, ahova a kpet meg szeretnnk jelenteni. Pldul ha a msodik paramter PTR($A000,0), akkor a kpernyn lesz lthat. procedure LoadLBM( FileName: string; p: pointer); { FILENAME: forrs, P: cl (ide rjuk) } { Vltoz a fjlmveletekhez } var f: file; p1, p2: pointer; { Mutatk a memriafoglal eljrsokhoz } i,j: byte; { Szmllk a FOR... ciklusokhoz } Error: boolean; { Hibt jelz logikai vltoz } fs: word; { A fjl mrett fogja trolni } const lab: array[0..3] of char = 'BODY'; { Ezt a cmkt kell majd megkeresni: BODY } begin mark( p1); assign( f, FileName); reset( f, 1); if ioresult<>0 then begin write('Nincs ilyen fjl'); halt; end; fs:= filesize( f); if fs>65520 then halt;{ Ennl nagyobb fjlt nem tudunk brzolni} getmem( p2, fs); { Helyfoglals, itt ltszik, hogy a fjl } { mrete nem haladhatja meg a 64 kB-ot } blockread( f, p2^, fs); { Fjl beolvassa a memriba } close( f); for i:= 0 to 255 do begin port[$3c8]:=i; for j:= 0 to 2 do port[$3c9]:=mem[seg(p2^):ofs(p2^)+$30+3*i+j] shr 2; { Paletta belltsa end; asm mov mov les mov mov cld @1:repnz jnz mov push push dec mov repz pop pop jnz mov xchg error,0 { A hibt jelz vltoz nullzsa al,byte [lab] { AL-be 'B'(66) kerl (a cmke 1. bjtja) di,p2 { A P2 ltal meghatrozott terleten kebx,di { ressk a 'BODY' cmkt. cx,fs { A szmll kezdeti rtke a fjl mrete scasb @err si,offset lab di cx di cx,4 cmpsb cx di @1 dx,es:[di+5] dl,dh { { { { { { { { { { { { { {

} } } } } }

Az els bjt keresse } Ha nem tallt, hibs a fjl } Ha tallt egy 'B' karaktert, az mg nem } biztos, hogy a 'BODY' els karaktere, } ezrt ellenrizni kell a msik hrmat is} DI most a tallt 'B'-re mutat } sszesen 4 karaktert vizsglunk, ennyi } a cmke hossza (4 bjt) } A vizsglathoz szksges, elzleg el- } mentett regiszterek visszalltsa } Ha valahol eltrs volt, folytatjuk } A 'BODY'-t kvet duplasz a tmrtett } mret, neknk csak az utols 2 bjt kell} A msik kett nulla, mert a fjl nem le-}

43

{ add di,7 { push ds { mov ax,di { les di,p { lds si,p2 { sub ax,bx { add si,ax { xor ch,ch { @2:cmp dx,0 { jz @vege mov cl,[si] { inc si { dec dx { test cl,128 { jz @normal { neg cl { inc cl { mov al,[si] { inc si { dec dx rep stosb jmp @2 @normal: inc cl sub dx,cx { rep movsb { jmp @2 @err: mov error,1 @vege: pop ds end; { if Error then begin asm mov ax,03h int 10h { end; writeln('Olvassi hiba: halt end; release( p1); { end;

het 65520 bjtnl nagyobb } Az els adat a 'BODY' utni 5. bjt } DS kell a MOVSB utastshoz } DI-t tmenetileg troljuk } ES:[DI]-be a clcm kerl (P) } DS:[SI]-be pedig a forrscm } AX-bl levonjuk a P2^ ofszetjt } s ezt adjuk SI-hez, gy DS:[SI] az els} grafikus adat helyt hatrozza meg } Ha a szmll elrte a nullt - vge } CL az egysg els bjtja (B) Ezutn a kvetkez bjttal lesz dolgunk Szmll cskkentse Ellenrizzk CL legfels bitjt Ha 0, CL+1 tmrtetlen bjt kvetkezik Egybknt neglni kell, s hozz kell adni egyet. s ennyiszer kell kirakni a kvetkez bjtot } } } } } } } } }

A szmll cskkentse (ezrt CH=0) CL+1 bjt egyszer kimsolsa

} }

Ha hiba volt...

Visszatrs a szveges mdhoz '''+FileName+''''+#7); Lefoglalt memria felszabadtsa

Ha a ksbbiekben LBM htteret vlasztunk jtkunkhoz, mindig gyeljnk arra, hogy a BOB-ok a fjlban trolt paletta szerint fognak megjelenni. Most pedig nzznk egy pldt egy ilyen httr elksztsre! Tegyk fel, hogy hozzjutottunk egy 1024768-as, 256 szn BMP kphez (pldul szkennerrel beolvastuk). Ezt egy j fnykpfeldolgoz programmal lekicsinytjk 320200-ass, lehetleg a torztst is kikszbljk. (A torzts oka: 320/1024200/768.) Ha a 256 szn kztt nincs olyan, amit ksbb a BOB-okhoz fel szeretnnk hasznlni, sszemosunk kettt. Legyen a kp C1 s C2 szne kzel azonos (ugyanolyan szn, csak egy kicsit ms rnyalat). Az sszes C1 szn pontot cserljk ki C2 sznre (a legtbb fnykpfest ezt el tudja vgezni), gy felszabadult egy szn, C1, amellyel ksbb tetszlegesen rendelkezhetnk (brhogy vltoztathatjuk sznsszetevit). Tegyk fel, hogy van egy kis problma: kpfeldolgoz programunk nem ismeri az LBM formult. Ekkor szksgnk van egy kpkonvertlra. Ilyen a VPIC 6.2 kpnz program is, mellyel nemcsak kpeket tudunk megnzni, hanem a kpfjlokat ms formtumban is elmenthetjk. Hogyan konvertljuk vele a kpeket? Nzzk meg lpsenknt: 1. A program elindtsa utn nyomjuk meg az F9-et, majd gpeljk be az talaktand kp elrsi tvonalt. 2. A kurzormozgat billentykkel vlasszuk ki a kpet, s nyomjunk Enter-t. 3. ssk le a kvetkez billentyket, ilyen sorrendben: D, Y, Y, Y. (Nyugodtan vrhatunk kt gomb megnyomsa kzt, gy legalbb el tudjuk olvasni, mit r ki a program.) 4. Kevs vrakozs utn nyomjunk Enter-t, majd ESC-vel lpjnk ki a programbl.

44

Vgl nzznk egy rvid kis programot, mely a paramterben megadott LBM kpet jelenti meg. Ezt DOS-segt fjlkezelnkbe akr be is pthetjk, persze csak ha van r lehetsg (pldul az Extension file edit menpontnl lehet egyes programoknl belltani). {wiewlbm.pas} uses Crt; procedure LoadLBM( FileName: string; p: pointer); { Ez a fenti eljrs } begin if ParamCount=0 then halt; asm mov ax,13h int 10h end; LoadLBM( ParamStr( 1), PTR($A000,0)); ReadKey; asm mov ax,03h int 10h end; end. Ez a rvid kis program gyorsabban jelenti meg a kpet, mint a legtbb kpnz, viszont kevesebbet is tud a legtbb kpnznl.

4.2. A MAP kpszerkezet


Ahhoz, hogy a httr grdthet legyen, mrett nvelni kell. Ha a httr pixeleit bjtonknt trolnnk, akkor csak nhny ezer bjttal lehetne nagyobb 64000-nl, legfeljebb 65520 bjt, ennl nagyobb vltozkat ugyanis a Pascal nem kpes kezelni. Teht be kell frnie egy szegmensbe (64K), s mretnek nagyobbnak kell lennie 320200-nl. Ezrt valahogy tmrteni kell. Tmrts nlkl meg lehetne oldani a kvetkezkppen is. Van kt 320200-as httr: H1 s H2, H1 ltszik, H2 nem. H2-t jobbrl grgetjk be gy, hogy a httr (ami az elejn mg H1) minden oszlopt (a 2.-tl kezdve) eggyel balra toljuk, majd az utols oszlopba H2 els oszlopt rjuk. Ezt 320-szor megismtelve (persze ksbb mr nem a H2 els oszlopt, hanem a msodikat, harmadikat stb. kell berni) a kt kp kicserldik. (Lsd az brt lent.) Ennek a grgetsi mdszernek az az egy elnye van, hogy a kt kp tetszleges lehet. Htrnyai: nagy memriaigny (128K), egyszerre csak egyirny grgets, darabossg. Ez utbbi akkor jelenik meg, ha kettnl tbb kpet grgetnk, ilyenkor 320 lptets utn (az elz pldnl maradva) H1 helyre j kpet kell betlteni, ami sok idt vesz ignybe. H1 H2 Az ppen lthat rsz

Legjobb az lenne, ha a memriban egy hatalmas kpet trolhatnnk, s brmely rszlete megjelenthet lenne. Viszont ezt nagyon nehz megoldani, a bvtett memriatartomnyt is ignybe kellene venni, ami miatt jtkunk nem futna minden gpen (ami mg nem is lenne olyan nagy baj, mert manapsg mr mindegyik gpben tbb RAM van 640KB-nl). Egyetlen megolds, ha kitallunk egy olyan tmrtsi eljrst, ami knnyen visszafejthet, s j arnyban kpes tmrteni. Elrkezett az id, hogy megismerkedjnk a MAP kpszerkezettel. Ez nem egy szabvnyos kptrolsi mdszer, a fogalmak, defincik nknyesek. A grafikus adatokat kt rszletben troljuk, egyik memriatartomnyban van a trkp (MAP), msikban a 256 darab 88 pixel mret doboz (BOX). A trkp minden

45

bjtja meghatroz egy-egy dobozt, aminek 64 bjtjt a msodik memriarszben adjuk meg. gy elg egy dobozt csak egyszer megadni, a trkpben csak utalni kell r. Olyan ez, mint a mozaik. Tegyk fel, hogy van 256-fle mozaikkvnk, mindegyik tpusbl korltlan mennyisg ll rendelkezsnkre. A mozaikkvek jelkpezik a BOX-okat, a kp, amit a kvekbl rakunk ki, a trkpet. Csak a 256 mozaikdarabkt kellett meghatroznunk, s azt, hogy a kp egyes rcspontjaiba milyen tpus mozaik kerljn. Legyen pldul a httr egy hatalmas 800400 pixeles virgmez, 255 klnbz virggal. Minden virg belefr egy 88-as ngyzetbe. A 256. virg egy zld ngyzet, ebbl lesz a f ott, ahova nem akarunk virgot rakni. Ha minden pixelt egy bjton trolnnk, a rt mrete 800400, vagyis 320000 bjt lenne. A MAP szerkezetben ez sokkal kevesebb helyet ignyel. Elszr is meg kell adnunk a virgok pontjait: 25688=16384 bjt. Msodszor meg kell adnunk a trkpen, hova milyen virg kerljn. Mivel a trkpen, a teljes kphez kpest, minden 64 bjtot egy bjt helyettest, mrete 64-ede a ksz kpnek: 5000 bjt. Ez sszesen 16384+5000=21384 bjt, ami 6,7%-a a tmrtetlen legelnek. Nzznk minderre egy brt: MAPPTR^ BOXPTR^

BOX BOX

BPL A kt nagy tglalap a kt memriatartomnyt szemllteti, kezdcmk MapPTR s BoxPTR. A rajzon a BOX-okat szemlltet kis ngyzetekbl csak nhny van berajzolva, termszetesen gy kell elkpzelni mind a kt vltozt, hogy az egsz fel van osztva kis ngyzetekre (nincs res hely). A BPL vltoz megadja, hogy a trkpen soronknt hny doboz tallhat. E vltoz segtsgvel lesz a trkp ktdimenzis. Ez a kpszerkezet nagyon hasonlt a karakteres zemmdra. A trkp, funkcijt tekintve, megegyezik a karakteres kpmemrival ($B800:0000 cmtl kezdd tartomny). Ott kt bjt hatroz meg egy karaktert, itt egy bjt egy BOX-ot. A karakterkszlet meg lnyegben ugyanolyan, mint a BOX-kszlet, csak mi mshogy troljuk az adatokat. Minden bjt egy pixelt hatroz meg. Minden dobozra jut 64 egymst kvet bjt, a BOX-ok pontjait sorfolytonosan troljuk. Az N. doboz (0N255) (X; Y) koordintj (0X7 s 0Y7) pontjnak szne: MEM[seg(BOXPTR^):ofs(BOXPTR^)+N*64+Y*8+X] A trkppel ellenttben a BoxPTR vltoznak csak egy kiterjedse van (egydimenzis), csak a knnyebb szemlltets rdekben brzoltuk tglalapnak. rdemes elindtani a MAP-EDITOR programot (MAPEDIT.EXE a lemezmellkleten), tltsk be a PELDA.MAP kpet! gy, kevs ismerkeds utn, az a nhny lehetsges homlyos folt is kitisztul, ami az eddig olvasottak utn taln mg maradt. A trkp koordinta-rendszere nincs sszefggsben a BOB-ok koordinta-rendszervel. Mrete mindkt irnyban lehet 65520 BOX, viszont szlessgnek s magassgnak szorzata nem haladhatja meg a 65520 BOX2-et, ennyi bjt lehet ugyanis legfeljebb egy Pascal-vltoz hossza. A koordinta-rendszer egysgei azonban nem BOX-ok, hanem kppontok, pixelek. gy a szlessge s a magassga [1..524160] pixel kztt lehet. (655208=524160.) A nagy MAP fix, ezen mozog a httr, s a trkp koordinti valjban a httr bal fels sarkt jelentik majd. Az albbi bra segt megrteni. X s Y a trkp koordinti, BPL a soronknti BOX-ok szma (Boxs Per Line). Persze nem lnyeges az, hogy X s Y oszthat legyen 8-cal, azaz a httr szlei BOXhatrra essenek, pp ez fogja a megjelentst megnehezteni.

46

(0;0) Httr szle 200 320 Trkp szle

(X;Y)

BPL8

Foglaljuk ssze a fogalmakat s azok meghatrozst: MAP Trkp. A memriban nincs sszefggsben a httrrel, teljesen kln tartomny. Bjtjai egy-egy BOX-ot hatroznak meg. BOX 88-as mret, 256 szn grafikai objektumok. 256 klnbz mintj BOX van, ezek egymst kvetve helyezkednek el a memria egy 16384 bjt hossz tartomnyn. Httr Ez is egy memriatartomny, 64000 (320200) bjt hossz. Itt semmifle BOX-ot nem tallunk, csak pixeleket meghatroz bjtokat. BPL A trkp szlessge, BOX-ban. Kppontokban mrve a trkp szltiben ennek nyolcszorosa. (A BOX szlessge 8.) Vgl vegyk szmba ennek a kptrolsi mdszernek elnyeit s htrnyait! Elnyk: A tmrtsi arny nagyon j, magt a kpet 64-ed rszre srtjk. Knny s gyors az adatok visszafejtse. Ez utbbiban nagyrszt segt a 88-as BOX-mret (osztani kell, s a 8-cal val oszts bitforgatssal is megoldhat, ami lnyegesen gyorsabb, mind a DIV utasts). A kp mrete meglehetsen terjedelmes is lehet, tbb mint 65 kpernynyi. Htrnyok: A BOX mrete elre meghatrozott. Kevs a 256 BOX, gy kpnk nem elgg vltozatos. Br ha elg gyesek vagyunk, akkor ez pont elg. Nyilvn gyelni kell a trkp elksztsnl arra, hogy sok ismtld elemet kell alkalmaznunk. Nagy memriaigny (16384 bjt + a trkp, ami legfeljebb 65520 bjt).

4.3. Megjelents
A httr s a trkp, tartalmt tekintve, tulajdonkppen teljesen elklnl, kzttk kapcsolatot csak a BOX-ok kpeznek, melyek a trkp grafikus adatait troljk. A megjelents alapelve nagyon egyszer: a trkp bizonyos bjtjtl kezdve annak bjtjai ltal meghatrozott BOX-okat elkezdjk kirakosgatni a httrre, persze ha a httr egy sornak vgre rtnk, kis kihagys kvetkezhet, mert a trkp szlesebb lehet a httrnl. A gyakorlatban tl lass lenne minden kpfrisstsnl vagy grgets utn ennyit szmolgatni. A valdi megjelents lpsei a kvetkezk: 1. A trkpnek egy rszlett, a kezd kpet meg kell jelenteni. Ez lass, mert sokat kell szmolni (pldul 8-cal osztani), de a legelejn egyszer mindenkpp vgre kell hajtani, mert ez lesz a kiinduls. 2. Ha a httr elmozdul a trkpen (vagy a trkp mozdul el a httr alatt), azaz grgetnk, a httr megvltozik, amit ktflekppen rhetnk el. jra vgrehajtjuk az 1-es pontot, ez azonban nem szerencss, mert nagyon lass. A msik megolds, hogy eltoljuk a httr pontjait a rep movsw utastsok segtsgvel, ami mr kellen gyors, majd a felszabadult helyre, ami legfeljebb nhny sor lehet a httr egyik szln, visszafejtjk a trkp adataibl az oda tartoz BOX-rszleteket.

47

Mi trtnik, ha a trkp elmozdul egy egysgnyit, pldul felfele? A legfels sor eltnik, minden tovbbi sor eggyel felugrik, az utols sorba pedig az alulrl besz sor kerl, amit a trkp s a BOX-ok adatai, valamint a koordintk alapjn nehz s idignyes visszafejteni. Viszont ez mg mindig gyorsabb, mintha az egsz htteret jrarajzolnnk. Az eljrsbl kvetkezik, hogy ez a scrollozs valban scrollozs, nem jelenthetjk meg tetszlegesen egyms utn a trkp brmely 320200-as rszlett, azaz megtehetjk, de az mindenkpp lass lesz. A httr kt lps kztt csupn nhny pixelnyit mozdulhat el, annak ellenre, hogy valjban egy kpernynyit is arrbb toldhat. A szerencse az, hogy ez a nhny kppontnyi elmozduls bven elegend a grdtshez, mert az nem is lenne scrollozs, ha sszevissza ugrlna a trkpen a httr. Persze erre is lesz lehetsg, gy kombinlni lehet a ktfle httrtpust: azt, amelyik tbb, egy kpernynyi (320200) kpbl ll, s azt, amelyik egy globlis kp. Meg lehet valstani pldul azt, hogy ha a jtk fhse a konyhban tartzkodik, ami egy kperny nagysg, kilpve az elszobba mr annak csak egy rszlete ltszik, s ha arrbb megy, akkor az elszoba grdl. Teht a kt legfontosabb s legnehezebb feladat: egy sor s egy oszlop visszafejtse a trkp- s a BOXadatok alapjn. Az mr ehhez kpest nagyon egyszer lesz, hogy a httr vltozatlan rszt odbb toljuk. Ehhez egy jl megrt ciklus, a ciklusban a rep movsw utastsok kellenek.

4.4. Sor megjelentse


A fggleges grgets alapja a trkp brmely sornak 320 egyms melletti pontjnak visszafejtse. Ez a grdts mdszerbl kvetkezik, ami nagyjbl a kvetkez: a httr minden egyes sort eggyel feljebb cssztatjuk (a legfels sor eltnik), az utols sorba pedig kirakjuk a trkpnek az odaill 320 pontjt (ekkor a grdts irnya: fel). A feladat els rsze egyszerbb, sima movsw utastssal knnyen megoldhat, egyszeren csak arrbb kell mozgatni a bjtokat a httren. A sorvisszafejts mr egy kicsit nehezebb, ppen ezrt hrom lpsben fogjuk megoldani: 1. Legfels sor megjelentse, gy, hogy a trkp koordinti: (0;0). 2. Brmely (0-199.) sor megjelentse, a trkp koordinti mg mindig (0;0), vagyis a httr a trkp bal fels sarkban van. 3. Vgleges megjelents, tetszleges helyzet httr, tetszleges sor.

4.4.1. Legfels sor


Eleinte tegyk fel, hogy a trkp szlessge 320, ekkor egy sorban tallhat BOX-ok szma 320/8=40 (8 a BOX szlessge). Ekkor a httr szle BOX-hatrra esik, ami valamikpp megknnyti egy-egy sor megrajzolst. Ezenkvl knnytsl legyenek a httr koordinti (0;0), azaz ppen a trkp bal fels sarkban foglaljon helyet, s a legfels sor visszafejtsrl kelljen csak gondoskodni. Teendnk ekkor nagyon egyszer: 1. Beolvassuk a trkp legels bjtjt, ez megadja a bal fels sarokba kerl BOX sorszmt. Legyen ez n. (ami valjban a n+1., mert 0-val kezddik a szmozs). 2. Meghatrozzuk az n. BOX kezdcmt: a BoxPTR a 0. BOX kezdcme, s a 256 BOX egyms utn, nvekv sorrendben helyezkedik el. Egy BOX hossza 88=64 bjt, gy az n. BOX kezdcme a BoxPTR-nl (amit tudunk) n64-gyel nagyobb. 3. Az n. BOX legfels sort, vagyis az els 8 bjtjt kirajzoljuk a httrre, a bal fels sarokbl indulva, jobbra, a rep movsw utastsok segtsgvel. Ezek utn megismteljk mg 39-szer ezt a mveletet, csak az 1. lpsben nem az els, hanem a msodik, harmadik, , negyvenedik trkp-bjtot olvassuk be. Ez nem olyan nehz, igaz, hogy az alapelv elsajttsn kvl semmire sem lehet hasznlni.

A BOX-oknak most mg csak az els sort jelentjk meg.

48

procedure push mov xor @1: push les add mov xor mov mul les lds add mov mul add mov cld rep mov pop inc cmp jnz pop end;

HLine; assembler; asm { H=Horizontal Line, vzsz. sor } bp { BP is a DS-t trolja, hogy ne kelljen } bp,ds { a verembe menteni, mert az sok id } cx,cx { CX szmllja majd a kirakott BOX-sorokat} cx di,mapptr di,cx al,es:[di] ah,ah bx,64 bx di,background si,boxptr si,ax ax,8 cx di,ax cx,4 movsw ds,bp cx cx cx,40 @1 bp { { { { { { { { { { { { { { { { { { { { Itt a CX a REP utastshoz kell MAPPTR a trkp kezdcme DI a trkp CX. bjtjra mutat AL a trkp aktulis bjtja A szorzs miatt az AX fels bjtja 0 Egy BOX mrete 64 bjt AX a kirakand BOX eltolsi cme A clcm a httr egy bjtja A forrscm a BOXPTR egy bjtja DS:[SI] mr a kirakand BOX-ra mutat DI clindexet is belltjuk, hogy a httr kell bjtjra mutasson DI:= DI+CX*8 (CX a szmll) 8 bjt=4 sz mozgatsa kvetkezik Egy BOX egy sornak megjelentse Az eredeti adatszegmens visszalltsa CX a BOX-okat szmllja Szmll nvelse Elrte-e a 40-et? (Ennyit kell kirakni) Ha mg nem, megismteljk az egszet } } } } } } } } } } } } } } } } } } } }

Az eljrsban szerepl vltozk (amelyek tpusa pointer): MapPTR Trkp kezdcme. BoxPTR BOX grafikus adatok kezdcme. BackGround Httr kezdcme.

4.4.2. Brmely sor


Az itt szerepl eljrsban osztani fogunk. Ehhez azonban nem a div, hanem az shr utastst hasznljuk. Ezt azrt tehetjk meg, mert 8 lesz az oszt. A bittols sokkal gyorsabb, mint az oszts vagy a szorzs, s rvidebb, igaz, hogy sebessgben klnbsget nem lehet szrevenni, de a tudat megnyugtathat, hogy programunk logikusabb, gyorsabb s nhny bjttal rvidebb. 8-cal val osztsra akkor lesz szksg, amikor a httr koordinta-rendszerbl, aminek egysge a pixel, ttrnk a trkp koordinta-rendszerbe, aminek egysge egy BOX-oldal, 8 pixel. De hogy jobban megrtsk, nzzk az eljrs lpseit! A bemeneti paramter (L) a megjelentend sor szma, [0..199] kz esik. 1. L-bl ki kell szmolni, a trkp hnyadik bjtjtl kezddik a megjelents. Az erre szolgl kplet: els bjt = (L SHR 3)40, ahol 40 az egy sorban lv BOX-ok szma. 2. Azt, hogy egy BOX-on bell melyik sort kell a httrre msolni, szintn az L-bl kapjuk meg, csak nem az oszts egsz rszt, hanem a maradkt vizsgljuk. Hogy gyorsabb legyen, az oszts utni maradk kiszmtshoz az and utastst alkalmazzuk: BOX brzoland sora = L AND 7. Ezzel kimaszkoljuk az als hrom bitet. 3. Most mr ugyanazt kell tenni, mint az elz eljrsnl, csak a BOX-oknak nem az 1., hanem a 2. lpsben kiszmtott sort kell megjelenteni. Mivel a trkp koordinti mg mindig (0;0), a httr szle megegyezik az els s az utols oszlopban elhelyezked BOX-ok bal, illetve jobb szlvel. Ez megknnyti a munknkat, viszont emiatt ez az eljrs szintn nem hasznlhat. procedure HLine( L: word); assembler; asm { A trkp L. sornak megjelentse mov ax,L { Elszr kiszmoljuk az els bjt cmt mov cx,ax { CX-be is bevisszk

} } }

49

shr mov mul mov mov mul mov and shl mov push mov xor @1: push lds add add lodsb xor shl mov les add shl add lds add add mov cld rep mov pop inc cmp jnz pop jmp @a:dw @b:dw @c:dw @exit: end;

ax,3 bx,40 bx word [@A],ax ax,320 cx word [@B],ax cx,7 cx,3 word [@C],cx bp bp,ds cx,cx cx si,mapptr si,word [@A] si,cx

{ { { { { { { { { { { { {

8-cal val oszts=3 bit forgats jobbra 40 BOX-bl ll egy sor Az els tkpbjt eltolsi cme AX-ben Eltroljuk, ne kelljen jra kiszmolni Az els pixel cme: 320L Ezt is troljuk, idt sprolunk vele Als 3 bit marad, tbbi 0 8-cal szorzunk, CX: BOX-on belli eltolsi cm Ezt is megjegyezzk A BP regiszterre nincs szksg, gy az trolhatja az adatszegmens regisztert CX szmllja a bjtokat, 8-asval A sorkiraksnl pixelszmll lesz MAPPTR a trkp kezdcme A megjelentend sor els bjtja Most mr az aktulis (CX.) bjt AL a trkp aktulis bjtja AX fels bjtja 0 AX SHL 6 = AX64, csak gyorsabb DS ismt az eredeti adatszegmens A clcm a httr egy bjtja Nveljk a clcmet, a sor els bjtja Mg nveljk, hogy a kvnt bjtra mutasson (DI:=DI+320L+CX8) A forrscm a BOXPTR egy bjtja DS:[SI] mr a kirakand BOX-ra mutat s mr a megfelel sornak 1. bjtjra 8 bjt=4 sz mozgatsa kvetkezik Egy BOX egy sornak megjelentse Az eredeti adatszegmens visszalltsa CX a BOX-okat szmllja Szmll nvelse Elrte-e a 40-et? (Ennyit kell kirakni) Ha mg nem, megismteljk az egszet

} } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } }

{ { { { { ah,ah { ax,6 { ds,bp { di,background { di,word [@B] { cx,3 { di,cx { si,boxptr { si,ax { si,word [@C] { cx,4 { movsw ds,bp cx cx cx,40 @1 bp @exit 0 0 0 { { { { { {

{ Nhny vltozt a kdszegmensben helye- } { znk el, gy rtkk kiolvasshoz nem } { kell az eredeti adatszegmens }

A MapPTR, BoxPTR, BackGround vltozk ugyanazt a clt szolgljk, mint az elz eljrsban, taln csak az eljrs vgn, a kdszegmensben elhelyezett sz hosszsg vltozk szorulnak nmi magyarzatra. Ezekre azrt van szksg, hogy a fcikluson bell, ami sokszor (negyvenszer) ismtldik, ne kelljen mindig jra kiszmolni az ltaluk trolt rtket. @A Az (L SHR 3)40 rtket trolja, azt, amit a MapPTR-hez kell adni, hogy a kvnt sor kezdcmt megkapjuk. @B rtke 320L, ennyit mindenkpp hozz kell adni a clcmhez, hogy ne a httr els, hanem az L. sorba kerljn a visszafejtett trkprszlet. @C L AND 7, ezt a sort kell minden egyes BOX-on bell megjelenteni. Viszont ezen kdszegmensben lv vltozk hasznlata szintn azt eredmnyezi, hogy a program vdett zemmdban nem futtathat. Ez az eljrs a grdtshez mg nem hasznlhat fel, hiszen a trkpnek csak a bal fels sarkban elhelyezked 4025 BOX brzolhat vele. Tovbb a httr csak fggleges mozgatsnl sem alkalmazhat, mert a httr msodik koordintja nem vltoztathat, rtke nulla. De a kvetkez rszben megismerkedhetnk a vgleges HLine eljrssal, ami a fggleges grgets alapja lesz.

50

4.4.3. Tetszleges helyzet trkp egy sora


Ha a httr szle a trkpen nem BOX-hatrra esik, nem lehet az elz kt mdszert alkalmazni, mert a kt szls BOX-nak nem szabad teljes szlessgben egyik sort megjelenteni. Legyen a httr helyzete (3;0), s nzzk meg, mit kell tenni pldul a legfels sor kirajzolsnl. sszesen 41 BOX ltszik, de az els s az utols csak rszben, gy az els BOX els sornak csak az utols 5 pixelt, az utols BOX els sornak pedig csak az els 3 pontjt kell s szabad megjelenteni. A kvetkez bra szemlletesen mutatja be egy httrhatrra es BOX egy sornak brzolst. Httr szle, ettl jobbra van a httr BOX szle

A kirajzolsra kerl sor Csak azokat a pontokat kell tmsolni, amik rajta vannak a httren

Az els s az utols BOX-ot kivve ugyangy kell eljrni, mint az elz rutinnl. Ha a httr ordintja a trkp koordinta-rendszerben Y, s a httr L. sort szeretnnk megjelenteni, akkor a BOX-ok (Y+L) AND 7. sort kell teljes szlessgben a httrre msolni. Azt, hogy az els BOX els hny pontjt nem kell kirajzolni, a httr abszcisszjnak 8-cal val oszts utni maradka adja, s ennyi pontot kell az utols BOX-bl megjelenteni. Itt oszts s maradkszmts helyett szintn az shr, ill. and mveletet alkalmazzuk, ez gyorsabb s rvidebb. Az eljrshoz szksges kpletek: A: B: C: D: E: Els BOX cme Clcm eltolsa a httr kezdcmhez kpest A BOX-okon belli eltolsi cm Els BOX nem ltsz pontjainak szma Els BOX httrre kerl pontjainak szma ((Y+L) SHR 3)BPL+(X SHR 3) L320 ((Y+L) AND 7) SHL 3 X AND 7 8-(X AND 7)

A kpletekben szerepl vltozk: X,Y A httr koordinti a trkpen L A megjelentend sor, 0L199 BPL Egy trkpsorban lv BOX-ok szma Az eljrs els felben szmtjuk ki ezeket az rtkeket, amelyeket a vgn, a kdszegmensben trolunk. Ez szintn azt eredmnyezi, hogy az eljrs vdett zemmdban nem mkdne. Az eljrs msodik felben pedig a megjelents kvetkezik, ami hrom rszre tagoldik, azrt, mert a httr lehet brmilyen helyzet: 1. Els BOX valamely sornak megjelentse, arra kell gyelni, hogy ha a httr szle nem BOX-hatrra esik, akkor nem szabad az els nhny pontjt kirajzolni. 2. A kzps 39 BOX valahnyadik sornak tmsolsa a httrre, ugyangy, mint az elz eljrsban tettk, teljes szlessgben (8 pixel). 3. Utols BOX. A kirajzoland sorbl csak annyi pontot szabad brzolni, amennyit az els BOX-nl kihagytunk. Ha egyet sem hagytunk ki, vagyis az els BOX-sort teljes szlessgben kirajzoltuk, a BOX-ok fggleges szlei httrhatrra esnek. Ekkor nem jelenik meg az utols BOX-nak egyetlen pontja sem, mivel az mr nem rsze a httrnek. Ezt kln meg kell vizsglni. A HLINE.PAS pldaprogram, ami a szban forg eljrst tartalmazza, ltrehoz egy 4126 BOX mret trkpet (ami szlessgben s hosszsgban 8 pixellel szlesebb a kpernynl), majd vletlenszeren rtket ad bjtjainak. A BOX-ok egysznek, gy knnyen meg tudjuk klnbztetni ket. A httr koordinti a trkpen (4;4), ami azt jelenti, hogy a kp szln csak olyan BOX-okat lthatunk, amelyeknek csak a fele ltszik (a kp sarkaiban pedig csak a negyede). Ez a pldaprogram segthet megrteni, mirt problms a tetszleges

51

helyzet trkp megjelentse, mert ltszik, hogy egy-egy sor szln a BOX-oknak nem kell az sszes pixelt brzolni. {hline.pas} var Background: MAPPTR: BOXPTR: X, Y: BPL: i,j: pointer; pointer; pointer; word; word; word; { { { { { { Httr kezdcme Trkp kezdcme BOX-adatok kezdcme Httr koordinti a trkpen Egy sorban lv BOX-ok szma Vltozk a FOR... ciklusokhoz } } } } } } } } } } } } } } } } } } } }

procedure HLine( L: word); assembler; asm { A httr L. sora alatti trkp rszlet { visszafejtse { 1. Cmek szmtsa } mov add mov shr mul mov shr add mov mov mul mov and shl mov mov and mov mov sub mov ax,L ax,Y bx,ax ax,3 BPL cx,X cx,3 ax,cx word [@A],ax ax,320 L word [@B],ax bx,7 bx,3 word [@C],bx ax,X ax,7 word [@D],ax bx,8 bx,ax word [@E],bx { A = ((Y+L) SHR 3)*BPL+(X SHR 3) { { { { Az Y+L rtket eltroljuk (helyet s idt takartunk meg vele) A trkp szlessge mr brmennyi lehet (csak 40-nl ne legyen kisebb)

{ @A: els trkp-bjt cme { B = L320 { @B: els httr-bjt cme { C = ((Y+L) AND 7) SHL 3 { Y+L rtket a BX-ben troltuk { @C: els bjt egy BOX-on bell { D = X AND 7

{ @D: els BOX nem ltsz pontjainak szma} { E = 8-D { @E: els BOX lthat pontjainak szma } }

{ 2. Sor visszafejtse, a httrre } { 2.1. Els BOX } push bp mov bp,ds lds si,mapptr add si,word [@A] lodsb xor ah,ah shl ax,6 mov ds,bp les di,background add di,word [@B] lds add add add mov cld si,boxptr si,ax si,word [@C] si,word [@D] cx,word [@E] { { { { { { { { { { { { { { { { BP-re nincs szksg, } az adatszegmenst trolja } DS:[SI] a trkp kezdcme } Az els visszafejtend bjt cme } AL az els BOX sorszmt tartalmazza } AH nullzsa, a forgats miatt } 64-gyel szorzunk, AX a BOX eltolsi cme} Vissza kell tlteni az eredeti DS-t, } mert a httr kezdcme abban van } ES:[DI] a clcm, a kivlasztott sor } els bjtjra mutat } A forrscm a BOXPTR nhny bjtja } A kirakand BOX els bjtja } A BOX brzoland sornak els bjtja } Az els megjelentend pont cme } 8-D db pontot kell kirajzolni }

52

rep mov

movsb ds,bp

{ Rajzols bjtonknt, 'E' lehet pratlan }

{ 2.2. Kzps 39 BOX } mov bx,1 { BX szmllja a BOX-okat, az 1. BOX [@C].} @1: { sora mr ki van rakva a httrre } lds si,mapptr { MAPPTR a trkp kezdcme } add si,word [@A] { A megjelentend sor msodik bjtja } add si,bx { Most mr az aktulis (CX.) bjt } lodsb { AL a trkp aktulis bjtja } xor ah,ah { AX fels bjtja 0 } shl ax,6 { AX SHL 6 = AX64, csak rvidebb } mov ds,bp { DS ismt az eredeti adatszegmens } lds si,boxptr { A forrscm a BOXPTR egy bjtja } add si,ax { DS:[SI] mr a kirakand BOX-ra mutat } add si,word [@C] { s mr a megfelel sornak 1. bjtjra } mov cx,4 { 8 bjt=4 sz mozgatsa kvetkezik } rep movsw { Egy BOX egy sornak megjelenitse } mov ds,bp { Az eredeti adatszegmens visszallitsa } inc bx { Szmll nvelse } cmp bx,40 { Ha mg nem rte el a 40-et, } jnz @1 { megismteljk az ciklust } { 2.3. utols BOX } lds si,mapptr add si,word [@A] add si,40 lodsb xor ah,ah shl ax,6 mov ds,bp lds si,boxptr add si,ax add si,word [@C] mov cmp jz rep @2: mov pop jmp @A:dw @B:dw @C:dw @D:dw @E:dw @exit: end; ds,bp bp @exit 0 0 0 0 0 { Sohase felejtsk el visszalltani a DS } { rtkt, ha megvltoztattuk } { Ezek a vltozk azrt vannak a kdszeg- } { mensben, hogy elrskhz ne kelljen az } { eredeti adatszegmenst visszarni. } { A vltozk lerst lsd feljebb } cx,word [@D] cx,0 @2 movsb { { { { MAPPTR a trkp kezdcme Ehhez hozzadunk annyit, hogy a most megjelentend BOX-ra mutasson AL-be tlti a BOX sorszmt } } } } }

{ AX=64AL, AX a BOXPTR eltolsa

{ { { {

Most annyi pont ltszik, amennyi az el- } s BOX-nl kilgott, s ennyit kell } csak kirajzolni } Ha ez nulla, nincs semmi dolgunk } }

{ Utols BOX nhny pontjnak kiraksa

begin getmem( BackGround, 64000); { A httr marad 320200-as getmem( MAPPTR, 41*26); { A trkp (418)(268)=328208 pixel getmem( BOXPTR, 16384); { 256 db 88-as BOX=25688=16384 bjt randomize; { Vletlenszm-genertor inicializlsa { Trkp vletlenszer feltltse for i:= 0 to 1065 do mem[seg(MAPPTR^):ofs(MAPPTR^)+i]:= random( 256); { BOX-adatok feltltse, minden BOX egyfor i:= 0 to 255 do { szn, szne sorszma=sajt sorszma for j:= 0 to 63 do mem[seg(BOXPTR^):ofs(BOXPTR^)+i*64+j]:=i; X:=4; Y:=4; BPL:=41; { A trkp koordinti: (4;4), egy sorban { 41 BOX tallhat

} } } } } } } } }

53

asm mov ax,13h int 10h end; for i:= 0 to 199 do HLine( i); asm push ds mov es,sega000 xor di,di lds si,background cld mov cx,32000 rep movsw pop ds end; readln; asm mov ax,3 int 10h end; end.

{ MCGA zemmd bekapcsolsa { { { { { { { { { { Sorok megrajzolsa, 200 db van Most mg csak a httren ltszik, ezrt a htteret a kpernyre kell msolni DS lesz a forrsszegmens (httr) A clszegmens a kpmemria szegmense A clindex nulla A forrscm a httr kezdcme Nvekv adatirny 32000 sz msolsa Httr megjelentse

} } } } } } } } } } } }

{ Enter megnyomsra kilp

{ Visszatrs a szveges mdhoz

A fggleges irny grdts alapeljrsval tisztban vagyunk, most mr csak a trkpet az ordintatengely irnyban elmozgat eljrs msik felvel kell megismerkedni, ami a httr pixeleit arrbb mozgatja. Ezt majd a vzszintes grgetssel egytt, a fejezet vgn a ScrollR, ScrollL eljrsokban valstjuk meg (4.6.1-2.), mert elbb meg kell oldani a vzszintes mozgats problmjt is.

4.5. Oszlop megjelentse


Mint ahogy a fggleges grdtsnek az alapja a trkp egy sornak visszafejtse, a trkp vzszintes irny elmozdtshoz elszr az oszlop kirajzolsnak mdjval kell megismerkedni. Az alapelv ugyanaz, ezrt itt nem bontjuk fel a megoldst lpsekre, mindjrt a legsszetettebbet rjuk le, amit a ScrollU, ScrollD eljrsokban is alkalmazunk (4.6.3-4. fejezet). Oszlop visszafejtse az, amikor a httr tetszleges oszlopa alatti trkpmintzatot kell a httrre kirajzolni. Ez sszesen 200 bjt tmsolst jelenti, ennyi pixel ugyanis a httr magassga. Maga a grdts kt rszbl ll. Legyen a grdts irnya: jobb, vagyis a trkp a httr alatt balra mozdul el. Ekkor elszr a httr minden egyes sornak 2-320. bjtjt tmsoljuk rep movsb utastsokkal az 1319. bjtba. A sorrendjk kzben nem vltozik, ezrt gy tnik, mintha az egsz httr egy pixellel balra lenne az elz helyzethez kpest. Ezutn meghvjuk a VLine eljrst, ami visszafejti a httr jobb legszls oszlopra az oda ill trkprszletet. A grdts els fele knny, a fejezet vgn mind a ngy irnyhoz megtallhat a hozzjuk tartoz memriamozgat rutin. Mint a sormegjelent eljrs, ez is kt rszbl ll. Elszr kiszmtjuk a koordintk s egyb adatok alapjn a szksges cmeket, amiket szintn a kdszegmensben trolunk az eljrs vgn, majd az eljrs msodik felben kirajzoljuk az oszlopot a httrre. Ez egy kicsit bonyolultabb, mint a sormegjelentsnl, mert nem lehet sorfolytonosan rni a movsw segtsgvel, minden egyes pixel trsa utn nvelni kell mind a forrs-, mind a clindexet annyival, hogy a pontok egyms alatt, fgglegesen helyezkedjenek el. ppen ezrt lassabb is lesz, de a klnbsget nem lehet majd szrevenni, mert a httr oszlopai rvidebbek, mint a sorai. Termszetesen az eljrs els fele, a cmek kiszmtsa is ms, a kvetkez tblzat tartalmazza az ehhez szksges kpleteket. Az els oszlopban tallhat bet lesz majd az eljrson bell az azonostja, gy az eljrst vizsglva knnyen sszeprosthatjuk az egybets vltozkat (pl. @A) s a kpletet, amivel az ltaluk trolt rtket meghatrozzuk. A: B: C: D: E: Els BOX cme Clcm eltolsa a httr kezdcmhez kpest A BOX-okon belli eltolsi cm Els BOX nem ltsz pontjainak szma Els BOX httrre kerl pontjainak szma (Y SHR 3)BPL+((X+C) SHR 3) C (ez nem szerepel majd az eljrsban) (X+C) AND 7 Y AND 7 8-(Y AND 7)

54

A kpletekben szerepl vltozk jelentse: X,Y A httr koordinti a trkpen C A megjelentend oszlop (column), 0C319 BPL Egy trkpsorban lv BOX-ok szma (BOXs per line) Ha sszevetjk a fenti tblzatot a 4.4.3. rsz elejn tallhatval, szrevehetjk, hogy tulajdonkpp ugyanazt tartalmazza, csak a kpletekben trtnt vltozs, leggyakrabban X helyett Y szerepel (s fordtva). Az eljrs msodik fele most is hrom rszbl ll: els BOX egy oszlopnak rszleges kirajzolsa, kzps 24 BOX egy oszlopnak teljes kirajzolsa, utols BOX-oszlop legfels nhny pixelnek tmsolsa. Termszetesen itt is tugorjuk a 3. lpst, ha a httr fels szle kt BOX hatrra esik. A VLINE.PAS program, amiben az oszlopvisszafejt eljrs helyet kapott, ugyanazt ltja el, amit a HLINE.PAS, csak a trkprszletet a httrre nem soronknt, hanem oszloponknt rajzolja ki. Itt csak a programban felhasznlt VLine eljrst ismertetjk, ezt kell beszrni a HLINE.PAS program elejre, s t kell rni a HLine(i); utastst Vline(i);-re, hogy megkapjuk a VLINE.PAS pldaprogramot (ami a lemezmellkleten termszetesen megtallhat). procedure VLine( C: word); assembler; asm { A httr C. oszlopa alatti trkprsz{ let visszafejtse a httrre { 1. Kpletek alkalmazsa, @A-E vltozknak rtkads } mov shr mul mov add mov shr add mov and mov mov and mov neg add mov ax,Y ax,3 BPL bx,X bx,C cx,bx bx,3 ax,bx word [@A],ax cx,7 word [@C],cx ax,Y ax,7 word [@D],ax ax ax,8 word [@E],ax { A = (Y SHR 3)BPL+((X+C) SHR 3) { { { {

} } }

AX-ben az sor els bjtjnak cme } A trkp els koordintja } BX tartalma: X+C, ezt az sszeget C-nl } mg felhasznljuk, ezrt troljuk } }

{ @A: els BOX eltolsi cme

{ C = (X+C) AND 7, CX-ben volt az X+C } { @C: BOX-okon belli kirajzoland oszlop } { D = Y AND 7 } { BX tartalma most: Y AND 7 } { @D: fels BOX nem ltsz sorainak szma } { E = 8-(Y AND 7) } { AX rtke: -(Y AND 7)+8 } { @E: als BOX nem lthat sorainak szma }

{ 2. Oszlop megjelentse } { 2.1. Legfels BOB [@C]. oszlopa [@E] db pontjnak tmsolsa } les di,background { A clcmet mr most belltjuk } add di,C { az els mdostand httr-bjtra } push bp { BP ebben az eljrsban csak az } mov bp,ds { adatszegmenscmet trolja } lds si,mapptr { MAPPTR a trkp kezdcme } add si,word [@A] { DS:[SI] az els rintett BOX-ra mutat } lodsb { AL az els BOX sorszma, ebbl } xor ah,ah { szmtjuk ki az eltolsi cmt, } shl ax,6 { 64-gyel val szorzssal } mov ds,bp { A kv. mvelethez az eredeti DS kell } lds si,boxptr { BOXPTR a BOX-adatok kezdcme } add si,ax { A kirajzoland BOX kezdcme } add si,word [@C] { Kirajzoland oszlop } mov ax,8 { Egy BOX szlessge 8 bjtnyi } mul word [@D] { [@D]8, ennyit kell adni SI-hez, hogy } add si,ax { a fels [@D] sor ne ltszdjon } mov cx,word [@E] { [@E] db bjt tmsolsa kvetkezik }

55

cld @1: movsb add add loop mov si,7 di,319 @1 ds,bp

{ { { { { { {

Az irny: nvekv Most sajnos nem hasznlhat a REP Egy bjt trsa Forrscm nvelse 1+7-tel Clcm a kvetkez sor kell pontja CX-szer van ismtls DS vissza [@C]. oszlopnak trajzolsa } Az els BOX-szal mr nincs dolgunk A szorzshoz kell majd DS:[SI] a trkpre mutat Az els megjelentend BOX bjtjra Szorzs, AX-ben elllt a BX. BOX eltolsi cme AL-be tltjk az rintett BOX szmt A rgi DS visszatltse AH nullzsa a forgatshoz Szorzs, AX:= AX64 (egy BOX hossza) A forrscm a BOXPTR egy bjtja Az rintett BOX els bjtja DS:[SI]^ Most mr az els trajzoland pontja 8 bjt tmsolsa, most nem lehet szavanknt, mert nem egybefggk Egy bjt tmsolsa Clindex nvelse Forrsindex nvelse Amg CX 0-ra nem cskken DS vissza Egy BOX-oszlopot trajzoltunk sszesen 25 kzps BOX van Kirjuk azokat is

} } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } }

{ 2.2. Kzps 24 db BOX mov bx,1 { @2: mov ax,BPL { lds si,mapptr { add si,word [@A] { mul bx { add si,ax { lodsb { mov ds,bp { xor ah,ah { shl ax,6 { lds si,boxptr { add si,ax { add si,word [@C] { mov cx,8 { @3: { movsb { add di,319 { add si,7 { loop @3 { mov ds,bp { inc bx { cmp bx,25 { jnz @2 {

{ 2.3. Az utols BOX-oszlop megrajzolsa, ha ltszik } mov cx,word [@D] { Als BOX lthat sorai, akkor nulla, cmp cx,0 { ha a httr szle BOX-hatrra esik, jz @exit { ekkor nincs tbb dolgunk mov ax,BPL { Elre berjuk BPL-t a szorzshoz, DS { mdostsa utn mr nem tudjuk lds si,mapptr { Trkp kezdcme add si,word [@A] { Httr C. sora alatti fels bjt cme mov bx,25 { 26. BOX egy oszlopnak tmsolsa mul bx { AX-ben elllt az eltolsi cm add si,ax { El is toljuk az SI regisztert lodsb { Megvan a BOX sorszma mov ds,bp { DS ismt az eredeti adatszegmens lds si,boxptr { A forrscm belltsa xor ah,ah { AX fels bjtja nulla shl ax,6 add ax,word [@C] { @C a BOX brzoland oszlopa add si,ax { SI:= SI+64AX+[@C] @4: movsb { Egy BOX-pont msolsa a httrre add si,7 { Forrs- s clindex nvelse, add di,319 { a fggleges sorokhoz loop @4 { CX-szer kell ismtelni mov ds,bp jmp @exit

56

@a:dw @c:dw @d:dw @e:dw @exit: pop end;

0 0 0 0 bp

{ A kdszegmensben elhelyezked { vltozk

} }

{ BP kivtele a verembl

A fenti tblzatban a B kpletet csak a teljessg kedvrt adtuk meg, az eljrsban nem alkalmaztuk, mert a C (paramter) rtke az adatszegmens mdostsa utn is elrhet, hiszen a vermen keresztl kapja meg az eljrs, s az SS-t nem vltoztattuk. Vigyzzunk arra, hogy a C s a @C vltozkat ne keverjk ssze, az els a httr megjelen sora, a msik pedig egy eljrson belli trol (a BOX-ok kirajzoland oszlopnak szma). Ha a VLine eljrst sszevetjk testvrvel, a HLine eljrssal, szrevehetjk a hasonlsgokat, felptsknek elve teljesen ugyanaz. ppen ezrt itt nincs rtelme rszletesebben lerni ezt a szubrutint.

4.6. Grdts
A sor- s oszlopvisszafejt eljrs nmagban nem sok mindenre alkalmazhat, scrollozni velk mg nem lehet. Kell mg ngy olyan eljrs, amely magba foglalja az egyes irnyokhoz tartoz httrmozgatsokat s meghvja a sor- vagy oszlop-megjelent eljrst. Termszetesen ezeket is assemblyben rjuk, hiszen itt aztn lnyeges a sebessg, minden futskor majdnem 64000 bjt tmozgatsrl van sz, s ennek msodpercenknt 25-szr le kell futnia, hogy a trkp mozgst szemnk folyamatosnak rzkelje. Ngy ilyen grdt eljrst kell teht rnunk, melyek mindegyike kt rszbl ll: 1. Httr bjtjainak elmozdtsa. A rep movsw utastsokkal hajtjuk vgre, csak a kezd cl- s forrscm megadsa jelenthet nmi nehzsget, egybknt nem bonyolult feladat. 2. A httr szln megresed rszekre kirjuk az odaill sort vagy oszlopot. Ha egyszerre tbb pixelt mozog a httr, rtelemszeren tbb sort vagy oszlopot kell visszafejteni.

4.6.1. Jobbra
A httrbjtok traksnak alapelve jobban megrthet a kvetkez bra segtsgvel. Itt a httr egy pixelnyit jobbra mozog a trkpen, vagyis bjtjai balra grdlnek. Mivel minden sorral ugyanaz trtnik, elg csak egyet megvizsglni:

forrscm (SI) clcm (DI)

a msols irnya felszabadul oszlop

Az indexek kezdrtke a kvetkez: forrsindex az aktulis sor 2., a clindex az 1. bjtjra mutat. A D irnyjelz bitet kioltjuk, gy a msols irnya nvekv lesz. Ez esetben az els bjt tmozgatsa a kvetkezkppen trtnik: [SI]-bl [DI]-be msoljuk, kzben mindkt regiszter rtke n (a D kikapcsolt llapota miatt). Ezt teszi a movsb utasts, a rep segtsgvel pedig mindezt 319-szer vgre kell hajtani. (A sebessg nvelse rdekben a sorokat nem bjtonknt toljuk arrbb a movsb segtsgvel, hanem a movsw utastst alkalmazzuk. Ez persze sszetettebb teszi a mozgatshoz szksges CX regiszter belltst, mert osztani kell majd kettvel, azaz a biteket eggyel jobbra tolni.) Az els oszlopba csak rtunk, ezrt ami ott volt, eltnik, az utols oszlopbl pedig csak olvastunk, gy az felszabadul, ide kerlnek majd a VLine eljrssal az j adatok. Hogy az egsz msols folyamatos legyen, a felszabadul, utols oszlop bjtjaiba a kvetkez sor els bjtjt vagy bjtjait rjuk, hiszen teljesen mindegy, hogy ott milyen rtkek vannak. gy nem kell minden sor elksztse utn megllni, nvelni a forrs- s clindexet, hanem lehet folyamatosan msolni, ami nhny pixeles grdtsnl mg gyorsabb, mintha minden sor vgn megllnnk. Persze ha pldul fl httrnyit mozgatunk, nem j ez a mdszer, mert rengeteg bjtot feleslegesen mozgatunk, viszont a 8 pixeles grdts is mr olyan gyors, hogy nem igazn lesz szksgnk a httr helyzetnek ilyen nagymrtk hirtelen megvltoztatsra. Az eljrs teht kt rszbl ll, melyekkel mr az 4.6. fejezet elejn megismerkedhettnk, paramterben kell megadni a grdts mrtkt (azt, hogy hny darab pixellel mozduljon el).

57

procedure ScrollR( Count: word); assembler; asm { A httr jobbra mozog, a trkp balra { 1. Forrs- s clcm belltsa } mov bx,count { Legelszr megnveljk a httr abszadd X,bx { cisszjt les di,background { A cl- s a forrsszegmens egyarnt a mov si,di { httr szegmense add si,bx { A forrs a cltl jobbra tallhat mov cx,32000 { A httr 32000 szbl ll cld { Nvekv direkciban haladunk rep seges movsw { Httr sorainak eltolsa { 2. Jobboldalt felszabadul oszlop(ok) kitltse } mov cx,bx { BX tartalma mg mindig COUNT, ennyi @1: { oszlopot kell visszafejteni push cx { Csak a CX rtkt kell megjegyezni mov ax,320 { Az oszlop sorszmnak kiszmtsa: sub ax,cx { oszlop = 320-CX push ax { Ezt a veremen keresztl adjuk t a call vline { VLINE eljrsnak, aminek futtatsa sopop cx { rn CX megvltozik, ezrt visszatltjk loop @1 { Ismtls, amg CX (oszlopszmll) > 0 end;

} } } } } } } } } } } } } } } } } }

Az eljrs paramterbl ltszik, hogy ugyan brmennyit lehet a httr pozcijn egyszerre vltoztatni (persze annak mreteinl tbbet nem), de az elmozduls csak egsz szm lehet. Ez egy olyan jtknl jelenthet problmt, ahol szksges lenne igazi, ngyzetes gyorsulsra, de a maximlis sebessg csak pldul 2 pixeles grdts lehet egyszerre. Ekkor, ha a gyorsuls kettnl tbb lpsbl ll, a htteret trtszmmal kellene mozdtani. Ez nem megoldhatatlan feladat, rni kell egy j eljrst, ami koordintk alapjn grget, s a koordintk lehetnek vals szmok, ha kerekt a rutin. Nem megoldhatatlan, de a megvalstst az Olvasra bzzuk.

4.6.2. Balra
A balra grdts majdnem ugyanolyan, mint a jobbra grdts, csak a memriamozgats irnya, s ezrt a forrs- s clindexek kezdeti rtke ms. Az eljrs msodik felben a vltoztats csak annyi, hogy rtelemszeren nem a httr jobb, hanem a bal szlre fejtjk vissza az oszlopokat. Ugyangy egyszerre mozgatjuk az egsz htteret, gy ugyan minden sorban nhny bjtot (annyit, amennyi az eltols mrtke) flslegesen msolunk, viszont maga a mvelet folyamatos, ezltal gyorsabb. Nem is rdemes itt tovbb magyarzni, lssuk magt az eljrst! procedure ScrollL( Count: word); assembler; asm { A httr balra mozgatsa { 1. Httr bjtjainak tmozgatsa } mov ax,count { Httr abszcisszjnak cskkentse: sub X,ax { X:= X-COUNT les di,background { A httr szegmensn bell dolgozunk add di,63999 { DI az utols bjtra mutat mov si,di { Most mg SI is, de cskkentjk, mert a sub si,ax { forrs tle balra tallhat mov cx,32000 { Megint 64000 bjtot mozgatunk, std { de most a msik irnyba rep seges movsw { Httr jobbra cssztatsa { 2. Baloldalt felszabadult oszlopok helyre az jakat rjuk } mov cx,ax { CX szmolja a kirakand oszlopokat @1: { (ez AX-ben mg benne van) push cx { A VLINE eljrsban CX megvltozik dec cx { A visszafejtend oszlop sorszma CX-1

} } } } } } } } } } } } } }

58

push call pop loop end;

cx vline cx @1

{ { { {

A paramtertads a vermen keresztl valsul meg CX ismt az oszlopok szmt tartalmazza Ha mg nem nulla, ismt

} } } }

4.6.3. Fel
Amikor a trkp lefele mozog, hozz viszonytva a httr pontjai felfele mozdulnak el. A httr als nhny sora eltnik, a fels pr sorba pedig olyan sorok kerlnek, amik eddig mg a httren nem voltak jelen. A tbbi sor pedig lejjebb csszik. Az eljrs els rsze, a memriamozgats hasonlkppen megy vgbe, mint az elz kt eljrsnl. Az extraszegmens-regiszterbe (ES) betltjk a httr szegmenst, az indexregisztereket pedig gy lltjuk be, hogy a httr utols bjtjra mutassanak. Ezutn a forrsindexbl kivonunk N320-at (N a grgets mrtke), gy az feljebb ugrik N sorral. Kezddhet a msols, ami most is fordtott irny (ki kell gyjtani az irnyjelz bitet az std utastssal). Most is szavanknt msolunk, de CX rtke nem 32000 lesz, hanem annl N160-nal kevesebb, mert gy nem msolunk flslegesen. (A vzszintes grdtsnl nem cskkentettk ezt a 32000-es rtket, gy egynl nagyobb mrtk mozgatsnl nhny bjtot szksgtelenl msoltunk t, ez azonban elenysz. Ha itt nem cskkentennk ezt az rtket, termszetesen semmit sem vennnk szre, nem lenne lassabb, de a tudat megnyugtat, hogy nem dolgoztatjuk gpnk hasztalanul.) Az eljrs msodik rszben az elzhz kpest csupn annyi vltozs lesz, hogy VLine helyett HLine betsort runk. procedure ScrollU( Count: word); assembler; asm { SCROLL-ozs felfel, a trkp: lefel { 1. Minden sor lejjebb csszik } mov ax,count { Mindenekeltt cskkentjk a httr orsub Y,ax { dintjt les di,background { ES:[DI] a httrre mutat add di,63999 { Mr annak az utols bjtjra mov si,di { Most mr SI is mov bx,320 { Kivons eltt szorzunk, 320COUNT-tal mul bx { lesz SI rtke kevesebb, gy mr a kelsub si,ax { l sorra mutat mov cx,32000 { A httr 32000 sz, de nem kell ennyit shr ax,1 { mozgatni, elg ennl COUNT*160-nal kesub cx,ax { sebbet (COUNT160=COUNT320 SHR 1) std { Az irny most is cskken rep seges movsw { Az ES-en bell trtnik az adatmsols inc di { A httr bal fels sarkban lv bjtot inc si { is lejjebb rakjuk, mert azt eddig kiseges movsb { hagytuk { 2. Fels COUNT darab mov cx,count @1: push cx dec cx push cx call hline pop cx loop @1 end; sor megrajzolsa } { AX rtke mr megvltozott, ezrt itt { COUNT-ot runk helyette

} } } } } } } } } } } } } } } } } } }

{ Most vzszintesen jelentjk meg a bj- } { tokat }

Az els rszben CX-be 32000,5-et kellene rni ahhoz, hogy a legfels sort is teljesen lejjebb cssztassuk. Ha 32000-et runk, akkor a szavanknti mozgats miatt a bal fels sarokban lv bjt helyn a rgi adat marad, gy az 1. rsz vgn mg egy movsb-vel azt is tmsoljuk.

59

4.6.4. Le
A ScrollR (jobbra) s a ScrollU (felfel grget) eljrs ismeretben a lefel grdts annyira egyszer, hogy magyarzat nlkl, csak magt az eljrst kzljk, azt is csak a teljessg kedvrt. procedure ScrollD( Count: word); assembler; asm { Vgl a lefel grdts kvetkezik { 1. Sorok feljebb mozgatsa a httren } mov ax,count { A httr (trkp) msodik koordintjadd Y,ax { nak nvelse les di,background { A httren dolgozunk mov si,di { SI is felveszi a httr ofszetcmt mov bx,320 { A httr szlessge 320 pixel mul bx { Ezzel szorozva COUNT-ot megkapjuk, add si,ax { mennyit kell SI-hez adni mov cx,32001 { CX a httr hossza+1 (word-ben) shr ax,1 { Ez tulajdonkppen oszts 2-vel sub cx,ax { Csak hogy gyorsabb legyen... cld { Irny: nvekv rep seges movsw { Sorok felcssztatsa { 2. Az alul megresedett rsz megjelentse } mov cx,count { COUNT db. sort kell kirni @1: mov ax,200 { 200-bl kell kivonni, hogy megkapjuk a sub ax,cx { HLINE-hoz a sor szmt push cx { CX a HLINE sorn megvltozik, elmentjk push ax { AX tartalmazza a rajzoland sor szmt call hline { Egy sor visszafejtse pop cx loop @1 { A tbbi sor kirsa (ha mg van) end;

} } } } } } } } } } } } } } } } } } } }

Az 1. rszben a CX regiszter kezdeti rtke 32001, gy egy bjttal tbbet msolunk a kelletnl, viszont most ezt megtehetjk, mert a clindex, ahova runk, mg gy is a httr tartomnyn bell van. Ezzel megsprolunk egy movsb utastst az els rsz vgbl.

4.7. Scroll pldaprogram, a MAP fjl formtuma


Itt, a httrrel foglalkoz fejezet vgn egy rvid pldaprogram ltal szemllhetjk meg magt a grdtst. Ez elszr betlti a lemezrl a PELDA.MAP fjlban tallhat trkpet s BOX-adatokat. A MAP trkptrol fjlok szerkezete a kvetkez: Cm 0 1 3 5 16389 ezutn Mret Tartalom 1 Ennek a bjtnak az rtke egy, a MAP fjl verzijt jelli. A tovbbfejleszts miatt szksges. 2 Egy trkpsorban elhelyezked BOX-szm (BPL), vagyis a trkp pixelben vett szlessgnek nyolcadrsze. 2 A trkp hossza, bjtban (L). Ennyi BOX-ot tartalmazhat. Magassgt ebbl s az elz adatbl a kvetkezkppen kaphatjuk meg: H=L/BPL. Mivel a trkp tglalap alak, H csak egsz szm lehet. 16384 A BOX grafikus adatai. Olyan sorrendben vannak trolva, ahogy a memriban, teht egyszeren csak be kell olvasni ezeket a bjtokat a BoxPTR vltozba. L Trkpadatok. Ezeket is csak egyszeren be kell olvasni a MapPTR cmtl kezdve. 32 A BOX tkzsi vza (maszk). A kvetkez fejezetben rszletesen megtudhatjuk, mi ez.

Miutn az adatok a lemezrl a memriba kerltek, elvgezzk a szksges belltsokat (pl. MCGA zemmd bekapcsolsa), s belpnk a fciklusba. Itt a nylbillentykkel mozgathatjuk a trkpet, s felhasznljuk a 3.1. fejezetben megismert billenty-megszaktst. Ezt a Game egysg InitKey eljrsval (8.8.) rhetjk el. Ha nem a BIOS megszaktst hasznljuk, a mozgs sokkal egyenletesebb lesz.

60

{scroll.pas} uses Game; { Most mg csak a billentyzetkezel r{ szt hasznljuk a GAME egysgnek { { { { A httr kezdcme Trkp, BOX-adattmb kezdcme Koordintk, BOX/sor A FOR... ciklushoz } } } } } } } } } } } }

var BackGround: pointer; MAPPTR, BOXPTR: pointer; X, Y, BPL: word; i: byte; f: file; {$I {$I {$I {$I {$I {$I HLine.inc} VLine.inc} ScrollR.inc} ScrollL.inc} ScrollU.inc} ScrollD.inc} { { { { { {

Ezek az include fjlok a fejezet sorn megismert eljrsokat tartalmazzk, mindegyik azt, aminek azonostja a fjlnvvel megegyezik. Pldul a ScrollU.inc fjl a felfel grdt eljrst foglalja magba.

begin { 1. Adatok belltsa, betltse } getmem( BOXPTR, 16384); { getmem( MAPPTR, 80*50); { getmem( BackGround, 64000); X:= 0; Y:= 0; { BPL:= 80; { Helyfoglalsok A trkp 8050 BOX A httr kezdpozcija A trkp szlessge 80 BOX { { { { { Trkp, grafikus adatok betltse. A fjl els 5 bjtjt nyugodtan tugorhatjuk, mert az ott trolt adatokat (pl. BPL) mr ismerjk } } } } } } } } } }

assign( f, 'PELDA.MAP'); reset( f, 1); seek( f, 5); blockread( f, BOXPTR^, 16384); blockread( f, MAPPTR^, 80*50); close( f); InitKey; asm mov ax,13h int 10h end; for i:= 0 to 199 do HLine( i); { 2. Fciklus: mozgats } repeat if KEY[$C8] if KEY[$D0] if KEY[$CB] if KEY[$CD] asm mov @1:in test jz cld push mov mov xor dx,3dah al,dx al,8 @1 ds cx,32000 es,SegA000 di,di and and and and (y>0 ) (y<199) (x>0 ) (x<319) then then then then

{ Sajt billentyzetmegszakts

{ MCGA kpmd bekapcsolsa { Kezdkp kirsa

} }

ScrollU(1); ScrollD(1); ScrollL(1); ScrollR(1);

{ Az egyenletesebb futs rdekben vra{ kozunk egy vertiklis visszafutsra

} }

{ Megjelents: a httr bjtjait sza} { vanknt, nvekv sorrendben tmsoljuk } { az $A000-s szegmens els 64000 bjtjra }

61

lds rep pop end;

si,background movsw ds { ESC megnyomsra lphetnk ki }

until KEY[1]; asm mov ax,3 int 10h end; DoneKey; end.

{ Szveges md { BIOS-megszakts visszalltsa

} }

Ha kt nyilat nyomunk meg egyszerre, a trkp kt irnyban grdl, ha ez a kt nyl nem ellenkez irny, a kp tlsan mozog. Ez lass gpeken darabos lehet, ha azok nem tudjk egy elektronsugr-visszatrsi id alatt mindkt irnyhoz tartoz memriamozgatsokat s sorvisszafejtseket vgrehajtani. Ez esetben, de a gyorsabb futs rdekben mindenkpp rdemes mg ngy tls irny grget eljrst rni, melyek ugyangy tmozgatjk az egsz httr bjtjait, de nemcsak egy sort vagy oszlopot rajzolnak a megresed helyre, hanem mindkettt. Ennek a problmnak a megoldst az Olvasra bzzuk, mert gyors gpeknl (80-100 MHz) nem annyira jelents.

62

5. tkzsek
Egy jtkprogramban elengedhetetlenl fontos figyelni, hogy egy BOB mikor tkzik egy msikkal, mikor ri el a kperny szlt, vagy mikor rinti a httr bizonyos pontjait. Amikor egy lvldzs jtkban a lvedk eltallja az ellensget, vagy egy autsban a gpkocsi nekimegy a falnak, a lvedk s az ellensg, az aut s a fal nhny pontja fedi egymst, egyms felett helyezkednek el. Ekkor ezek rintkeznek, tkztek egymssal. Egy BOB mozgsa sorn llandan figyelni kell, mikor kerl bizonyos elemekkel (BOB-bal, httregysggel, bizonyos pixelekkel) fedsbe, mert ettl fgg a program tovbbi menete: felrobban-e az ellensg, vagy a fhs veszt leteibl. Azt, hogy a BOB rintkezik-e egyes pontokkal, ktflekppen vizsglhatjuk. Minden elemhez rendelhetnk egy tkzsi vzat, maszkot, aminek egysgei bitek. Kt BOB tallkozsa akkor kvetkezik be, ha koordintik alapjn az tkzsi vzukbl legalbb egy 1-es pixel fedi egymst. De nemcsak BOB-hoz rendelhetnk ilyen maszkot, hanem httrhez is, pldul ott 1-re vltjuk a maszk bitjeit, ahol fal van, s gy tudjuk figyelni, mikor tkzik falnak a BOB. Ennek az eljrsnak a legnagyobb elnye az, hogy mindegyik grafikus elemhez tbb ilyen vzat, maszkot is rendelhetnk, gy megvalsthat pldul az, hogy ahol a jtk fhse falnak tkzik, ott egy szellem tjuthat. Htrnya az, hogy minden BOB-hoz, httrkphez kln meg kell szerkeszteni annak a maszkjt, s ezt trolni kell, ami helyet foglal, igaz, hogy a trols miatt csak nyolcadannyit, mint a hozz tartoz grafikus elem (nyolc bitet lehet egy bjton trolni). Egy ilyen bitmaszkot alkalmaz tkzsvizsgl rutin felptse a kvetkez lehet: beolvassuk az egymst fed bjtokat, ezeket el kell forgatni, mivel ltalban az abszcisszk kzti klnbsg nem oszthat nyolccal, majd ha az elforgatott bjtokon vgrehajtunk egy S mveletet, s lesz olyan bjtpr, amelyiknl az eredmny nem nulla, akkor a kt egysg fedi egymst. Mivel mi itt nem ezzel a bitmaszkos tallkozsfigyel mdszerrel fogunk foglalkozni, a feladat megoldsa az Olvasra vr, feltve, hogy szksgesnek tallja. Csupn a vgrehajtshoz jl alkalmazhat kiindul tletet emltettk meg, a forgatst s az AND mvelet alkalmazst. Termszetesen mshogy is megoldhat ez a feladat, pldul gy, hogy bitenknt vgignzzk a kt tkzsi vzat, gy nem kell a forgatssal veszdni. Az tkzs vizsglatra a msik megolds a sznvz. Ennek lnyege az, hogy kijellnk egy vagy tbb sznt, s ha kt grafikus egysg ilyen szn pontjai fedik egymst, akkor azok sszetkztek. Nem kell kln helyet lefoglalni a maszknak, csupn arra kell gyelni, hogy kt kln sznt kell alkalmazni azokon a helyeken, ahol az tkzs megengedett, s azokon, ahol nem, mg ha ez a kt szn teljesen ugyanolyan, akkor is. Pldul egy auts jtkban legyen a jrda s az ttest egyarnt szrke, de a jrda a kocsi szmra tiltott vezet. Ez esetben mr a httr szerkesztsnek kezdetnl figyelni kell arra, hogy ms sorszm sznnel kell a jrdt s ms sorszmval az utat befesteni. A sznvzas mdszer a logiktlanabb, de egyszerbb. Vele nem tudjuk pldul megoldani azt, hogy egy ellensg csak akkor haljon meg, ha a fejt eltalljuk, mert a BOB-okat egysgesen kezeli. (Termszetesen nincs olyan problma, ami nem megoldhat, itt megolds lehet pldul az, hogy az ellensget kt BOB-knt kezeljk, kln a fejt s kln a testt. Ez csak egy plda arra, hogy soha nem szabad feladni, mg ha egy kicsit nehezebben megoldhat feladat eltt llunk is, mindig tartsuk szem eltt azt, hogy semmi sem megoldhatatlan, csupn trelem s tlet krdse.) E sznmaszkot alkalmaz mdszer utn az Olvas kifejlesztheti a maga bitmaszkos tkzsvizsgljt. A fejezetben tallhat szubrutinok mindegyike fggvny, visszatrsi rtkk logikai vltoz, mely akkor igaz, ha a megadott adatok szerint a vizsglt egysgek fedsben vannak. Ezt knnyedn alkalmazhatjuk Pascal programunkban, a kvetkez feltteles mondatok beptsvel: HA BOB1.tkzik(BOB2-vel) AKKOR BOB1.meghal. Persze az utastsok formja nem ilyen, csak a knnyebb rthetsg miatt fordtottuk le magyar nyelvre. De az mr ltszik, hogy ezentl minden BOB nem-grafikus adatait object vltozknt fogunk deklarlni, ami a mi szempontunkbl csak annyiban tr el a rekordtl, hogy magba foglalja a BOB-hoz tartoz eljrsokat, fggvnyeket, gy az tkzst vizsgl szubrutinokat is. Minden rintkezs egyik alanya BOB lesz, hiszen nem lenne rtelme pldul a trkp egymshoz viszonytva vltozatlan helyzet egysgeinek fedst vizsglni. Viszont a BOB mr rintkezhet: 1. msik BOB-bal, 2. a httr elre meghatrozott szn pixeleivel 3. a trkp jelzett egysgeivel (bizonyos BOX-okkal).

63

5.1. Egyszer BOB-BOB tkzs


Ha kt BOB alakja tglalap, melyek teljesen kitltik a rendelkezsre ll terletet, azaz a BOB-ok szln nincsenek res pixelek, 0 rtk bjtok, akkor tkzsk figyelshez elegend csupn minden mozgsuk utn a koordintjukat s mretket vizsglni. Ebbl a ngy adatbl (abszcissza, ordinta, szlessg, magassg) egyrtelmen, knnyen s gyorsan meghatrozhat, hogy kt tglalap alak BOB mikor kerl fedsbe, vagy ha a BOB-ok nem tglalap formjak, akkor a terletk mikor rintkezik. Sok jtkban elegend csupn ezt a fajta rintkezst vizsglni, melynek elnye, hogy knnyen rthet, rviden megvalsthat, s a vizsglat gyorsan vgrehajthat. Hogy jobban megrtsk, figyeljk meg a kvetkez brt!

Itt kt BOB mintjnak fekete-fehr rajza lthat. A fekete ngyzetekhez tartoz bjtok rtke nulltl klnbz, a fehr rszekhez tartoz memriaegysgek rtke pedig nulla, ezeken a helyeken a BOB tltsz. Az brn jl ltszik, hogy a kt BOB nem ttetsz pontjai nem fedik egymst, teht valjban a kt BOB nem rintkezik. Mgis, ha az tkzst csak a BOB-ok koordinti s mretei alapjn vizsgljuk, eredmnyl IGEN-t kapunk, mert a kt BOB alapterlete fedi egymst. Az albbi eljrsban teht a legtbb esetben nem azt kapjuk, hogy kt BOB mikor tallkozik, hanem azt, hogy mikor kzelti meg egymst. Biztosan csak akkor kaphatunk helyes eredmnyt, ha mindkt BOB tglalap alak, s nem tartalmaznak tltsz, 0 szn pontokat. A feladat megoldsa nagyon egyszer, csak arra kell gyelni, hogy a koordintk negatv szmok is lehetnek, mivel a BOB a httr felett s attl balra is elhelyezkedhet (meg persze a msik kt irnyban is). Termszetesen kt BOB tallkozsa teljesen fggetlen a httrtl, rintkezhetnek gy is, hogy azt mi nem ltjuk, magyarul a BOB koordinta-rendszere lthat rszn, a httren kvl trtnik az tkzsk. function Collision: boolean; assembler; asm mov ax,X1 { A 2. BOB legalbb az els oszlopnak add ax,W1 { legalbb egy pixele (mg ha tltcmp ax,X2 { sz is) belelg-e az 1. BOB tartomnyjng @nocoll { ba? (Ha nem - nem rintkezhetnek) mov add cmp jng mov add cmp jng mov add cmp jng mov jmp @nocoll: mov @exit: end; ax,Y1 ax,H1 ax,Y2 @nocoll ax,X2 ax,W2 ax,X1 @nocoll ax,Y2 ax,H2 ax,Y1 @nocoll al,1 @exit al,0 { A 2. BOB fgglegesen alulrl rinti-e { az 1. BOB-ot? } } } } } }

{ Az 1. BOB abszcisszja nagyobb-e a 2. { BOB abszcisszjnak s szlessgnek { sszegnl? (Ha igen - nincs tkzs) { Ugyanez csak ordintkra s magassgra { megvizsglva

} } } } }

{ A fggvny visszatrsi rtke 1, azaz { TRUE, ha mind a ngy kittel igaznak { bizonyult.

} } }

64

A fggvnyben szerepl word tpus vltozk: X1 X2 Els BOB abszcisszja Msodik BOB abszcisszja Y1 Y2 Els BOB ordintja Msodik BOB ordintja W1 W2 Els BOB szlessge Msodik BOB szlessge H1 H2 Els BOB magassga Msodik BOB magassga Nem azt vizsgltuk tulajdonkppen, hogy fedsben vannak-e, hanem azt, hogy nem rintkeznek. Csak akkor lehetsges, hogy ne legyen egymst fed rszk, ha a kvetkez ngy eset mindegyike teljesl: 1. X1+W1X2 2. Y1+H1Y2 3. X2+W2X1 4. Y2+H2Y1 A fggvny els ngy egysge megvizsglja ezeket az egyenltlensgeket, az utols rsze pedig belltja a visszatrsi rtket. Itt megint azzal a mdszerrel tallkozunk, amivel a GetPixel fggvnyben (1.2.), a fggvnyrtket az AL regiszterben adjuk meg. Ez a mdszer a koordintk alapjn vgzett vizsglat a legegyszerbb s a leggyorsabb. Ezrt ltalban ezt alkalmazzuk, de van, amikor szksges a pixelenknti ellenrzs is.

5.2. Tnyleges BOB-BOB tkzs


Tegyk fel, hogy jtkunkban kacskat kell ldzni. Ha a lvedk a kacsa csre alatt halad el, de rinti a madr terlett, vagyis azt a tglalap alak rszt, amiben a madralak elhelyezkedik, akkor mg nem talltuk el, ellenben az imnti fggvny tallatot jelez.

A kt szls brn az tkzs megllaptsa egyrtelm. A baloldalt lvn sem a lvedk, sem a kacsa, de mg tglalap alak terletk egyetlen pontja sem rintkezik, ezek teht nincsenek fedsben. A jobb szlsnl valsgos tkzs kvetkezett be, van legalbb egy-egy olyan pont, amelyek kzl az egyik a msikat takarja. gy teht a terletknek is rintkeznik kell, vagyis az elz fggvny visszatrsi eredmnye: TRUE. A kzps rajzon azonban a goly mg nem hatolt be a kacsa testbe, viszont a mintjt tartalmaz tglalap alak tartomnyba mr igen. Az elz rszben bemutatott Collision fggvny teht tallatot jelez, holott ha a goly balra halad tovbb, akkor a madr mg nem fog meghalni. s nem is nzne ki jl, ha a tltnyek tbbsge csak megkzelten, de nem talln el a kacst, s tvolrl vgezne vele. Eszerint a koordintk s a mretek figyelsn kvl mg tovbbi vizsglatra lesz szksg. Hogyan llaptsuk meg, hogy bekvetkezett-e valsgos tkzs? Mindenekeltt meg kell vizsglni, hogy a kt BOB terletnek vannak-e egymst fed pontjai. Ezt az elz rszben megismert mdon tesszk, a koordintk, a szlessgek s a magassgok alapjn. Ha a kt terlet nem rintkezik, a kt BOB-nak nem lehet egymst fed tltszatlan pontja, ekkor nem is kell mst tenni. Ez az eset fent, az els rajzon lthat. Hogyha egymsba lg a kt BOB mintjnak alapterlete, meg kell vizsglni a kzs rszt. Ehhez vgig kell psztzni annak pontjait, s ha tallunk legalbb egy olyan helyet, ahol mindkt BOB tltszatlan, vagyis ezen a helyen mindkt pixelhez tartoz bjt nulltl klnbz, akkor ez a kt BOB rintkezik, tkztek. Ez azonban nem olyan egyszer. Hasonlt a problma a BOB-megjelents utols fokozathoz (2.5. fejezet), ott is meg kellett hatrozni egy kzs rszt, a BOB-nak azt a tglalap alak terlett, ami rajta van a httren. Itt is ezt kell tenni, de ktszer, mindkt BOB-bl ki kell vgni egy azonos nagysg tglalapot, s ezeket kell bjtonknt sszehasonltani. A legnehezebb azonban az sszevetend terletek szlessgt, magassgt s kezdcmt meghatrozni (ez utbbi a kt BOB-nl klnbz, csak akkor lehet egyenl, ha a kt BOB azonos mintj, ugyanaz a Shapejk kezdcme, s koordintik megegyeznek). A vizsglt BOB-ok egymshoz viszonytott helyzete sokfle lehet, elfordulhat pldul az is, hogy az egyik magba foglalja a msikat. A kvetkez brk kt lehetsget mutatnak be ezekbl, de az sszes szmts elvgzsnek mdjt megtudhatjuk bellk.

65

AY1 ABW

BY1 ABH

AX1

BX2

BX1

AX2

BY2

AY2

A vltozk jelentse az A jelzs BOB esetben (a B-vel kezdd ismeretlenek jelentse ezekbl rtelemszeren kvetkezik): AX1 A BOB bal oldali nem vizsgland oszlopainak szma. A fenti msodik brn ez nulla, mert az sszehasonltand terlet bal szle itt egybeesik az A BOB bal szlvel. AY1 A fels nem ellenrizend sorok szma. AX2 Jobb oldali oszlopok szma, amiket nem kell figyelni. AY2 Als sorok szma. Ezt tulajdonkppen nem hasznljuk a fggvnyben, csak a teljessg kedvrt szerepel az brn ABW A vizsgland tartomny szlessge. Kiszmtsnak mdja: AW-(AX1+AX2), AW az A jel BOB szlessge. Ha az A BOB benne van a B BOB-ban, akkor ABW=AW. ABH A vizsgland tglalap magassga. Meghatrozsa: AH-(AY1+AY2), AH az A BOB magassga. A vltozk meghatrozshoz szksges kpletek (megint csak az A BOB-ra vizsglva): AX1 = BX-AX (B s A abszcisszjnak klnbsge) AY1 = BY-AY (B s A ordintjnak klnbsge) AX2 = (AX+AW)-(BX+BW) (AW, BW a BOB-ok szlessge) AY2 = (AY+AH)-(BY+BH) (AH, BH a BOB-ok magassga) ABW = AW-AX1-AX2 vagy BW-BX1-BX2 (ennek a kt rtknek egyeznie kell) ABH = AH-AY1-AY2 vagy BH-BY1-BY2 Ezek csak nemnegatv egsz, azaz termszetes szmok lehetnek. Erre a kiszmtsuknl mg nem kell gyelni, lesz az eljrsban egy olyan rsz, mely ellenrzi az brn jellt sszes vltozt (ABW s ABH kivtelvel, mert ezek nullnl nagyobbak), s amelyik negatv, annak rtkt nullra vltoztatja. A msodik esetben pldul, amikor AX>BX (A a B-tl jobbra tallhat), AX1 negatv lesz, de az els nem vizsgland oszlopok szma nulla, mert az sszehasonltsi terlet s az A BOB bal szle megegyezik. Ezrt ebben az esetben AX1-et nullra vltoztatjuk. Egy msik pldt az albbi bra szemlltet. Itt az A jel BOB krlveszi a B-t, mert mretei nagyobbak, s a koordintk gy vannak belltva. Ekkor AX1, AX2, AY1, AY2 mind nagyobb mint 0, viszont ezek B-hez tartoz prja mindegyike zrus. AY1 A AX1 B AX2 AY2 Az sszehasonltst pontonknt vgezzk el. Elkezdjk megvizsglni az A BOB meghatrozott tartomnynak pontjait, majd ahol nulltl eltr sznre bukkanunk, megnzzk, hogy az ezen a helyen lv B BOB pontja milyen. Ha nulla, nincs rintkez pont, mehet tovbb egszen a kvetkez nem nulla A pontig, vagy a rsz jobb als sarkig. Ha nem nulla, akkor a kt BOB legalbb egy pixele fedsben van, teht a kt BOB sszetkztt. A fenti brk vltozira a regiszterek belltsnl lesz szksg: DI+ = AY1AW+AX1 sszevetsi tartomny eltolsi cme az A Shape-jn (ennyit kell DI-hez adni, miutn az ES:[DI]-be betltttk az A kezdcmt) SI+ = BY1BW+BX1 Tartomny eltolsi cme a B-Shape-en CX = ABW Egy sor hossza DX = ABH Sorszmll (a vizsglds tgabb ciklushoz)

66

A gyorsasg rdekben a terletek vizsglathoz ugyan lehetne a repnz scasb utastsprt alkalmazni, de ekkor csak a DI regiszter mutat a megfelel pontba, SI nem vltozik. Ezrt olyan mdszert hasznlunk, ami minden A-beli pont ellenrzse utn a DI s az SI regisztert is nveli. Az ABW s ABH vltozkat a kdszegmensben troljuk, @W s @H a cmk. A fggvny ismertetse eltt rviden tekintsk t annak menett! 1. Koordintk s mretek alapjn az tkzs lehetsgnek vizsglata. (Nagyjbl megegyezik az elz fggvny soraival.) 2. Koordintk s mretek alapjn az egymst fed terletek nagysgnak s kezdcmeinek meghatrozsa. 2.1. AX1, AX2 stb. kiszmtsa, kaphatunk negatv eredmnyeket is. 2.2. AX1, AX2 stb. kzl a negatvakat nullra vltoztatjuk. 2.3. Regiszterek belltsa (DS:[SI], ES:[DI]). 3. sszehasonlts, megnzzk, hogy akad-e legalbb egy olyan hely, ahol mindkt BOB nem tltsz. {coll2.inc} function BOB.Collision( var B: BOB): boolean; assembler; asm jmp @start { Kdszegmensben trolt vltozk tugrsa } @W:dw @H:dw @A:dw @B:dw @start: mov mov push 0 0 0 0 { { { { ABW, a kzs rsz szlessge ABH, a kzs rsz magassga AX1+AX2 sszeget troljuk itt BX1+BX2 sszeg } } } } } } }

di,word [Self] { [DI] az A BOB adatainak kezdcme si,word [B] { B BOB adataira pedig az [SI] mutat ds { DS is kell

{ 1. Megvizsgljuk, hogy vannak-e kzs pontjaik } mov and jz mov add cmp jng mov mov add cmp jng mov mov add cmp jng mov mov add cmp jng mov ax,[di] ax,[si] @nocoll ax,[di+2] ax,[di+18] ax,[si+2] @nocoll XA,ax ax,[di+4] ax,[di+20] ax,[si+4] @nocoll YA,ax ax,[si+2] ax,[si+18] ax,[di+2] @nocoll XB,ax ax,[si+4] ax,[si+20] ax,[di+4] @nocoll YB,ax { { { { { { { { { { Ha valamelyik BOB nem aktv, nem kell tovbb vizsgldni, nem rintkezhetnek, mert az egyik nem ltszik 'A' BOB abszcisszja 'A' BOB szlessgt hozzadjuk 'B' BOB ettl jobbra van-e? Ha igen, nem rintkezhetnek Az sszeget troljuk Ugyanezt megvizsgljuk, csak fgglegesen } } } } } } } } } } } } }

{ Idsprols miatt Y+H-t is elmentjk { Jhet a msik kt vizsglat: { vzszintesen...

{ ... s fgglegesen

{ 2. Most mr biztos, hogy van a kt BOB-nak kzs terlete, meg kell hatrozni annak mrett s helyt } { 2.1. rtket adunk az AX1-BY2 vltozknak a fenti kpletek szerint } mov ax,[si+2] sub ax,[di+2]

67

mov mov sub mov mov sub mov mov sub mov mov sub mov mov sub mov mov sub mov mov sub mov

AX1,ax ax,[si+4] ax,[di+4] AY1,ax ax,[di+2] ax,[si+2] BX1,ax ax,[di+4] ax,[si+4] BY1,ax ax,XA ax,XB AX2,ax ax,YA ax,YB AY2,ax ax,XB ax,XA BX2,ax ax,YB ax,YA BY2,ax

{ 2.2. Amelyik ezek kzl negatv, nullra vltozik } cmp ax1,0 jg @A1 mov ax1,0 @A1: cmp ax2,0 jg @A2 mov ax2,0 @A2: cmp ay1,0 jg @A3 mov ay1,0 @A3: cmp ay2,0 jg @A4 mov ay2,0 @A4: cmp bx1,0 jg @B1 mov bx1,0 @B1: cmp bx2,0 jg @B2 mov bx2,0 @B2: cmp by1,0 jg @B3 mov by1,0 @B3: cmp by2,0 jg @B4 mov by2,0 @B4: mov add mov mov add mov mov sub mov mov sub sub mov ax,ax1 ax,ax2 word [@A],ax ax,bx1 ax,bx2 word [@B],ax ax,[di+18] ax,word [@A] word [@W],ax ax,[di+20] ax,ay1 ax,ay2 word [@H],ax { { { { Az AX1+AX2 sszeg a sorok vgn az ugrshoz szksgesek, ezrt troljuk a kdszegmensben Ugyangy a BX1+BX2 sszeget is } } } } } } }

{ Mr csak az sszehasonltand terlet { mreteit kell megadni: { szlessge: A.W-(AX1+AX2)

magassga:

A.H-AY1-AY2

68

{ 2.3. Regiszterek belltsa, kezdcmek kiszmolsa } mov ax,[di+10] { AX: az aktulis fzis tvolsga mul word [di+16] { (fzisszmfzishossz) mov cx,ax { AX ideiglenes trolsa mov ax,[di+18] { Meghatrozzuk az A BOB-on bell a vizsmul ay1 { glt tartomny kezdpontjt: add ax,cx add ax,ax1 { A.WAY1+AX1 (+fzisfzishossz) les di,[di+12] { ES:[DI] a Shape kezdcmre mutat add di,ax { Most mr az els vizsgland pontra mov mul mov mov mul add add lds add ax,[si+10] word [si+16] cx,ax ax,[si+18] by1 ax,cx ax,bx1 si,[si+12] si,ax { Ugyanezeket a szmtsokat B-re is el{ vgezzk { Kezd pont: B.PB.PL+B.WBY1+BX1 { A B Shape-re a DS:[SI] mutat { SI-hez hozzadjuk a fenti rtket

} } } } } } } } } } } } }

{ 3. sszehasonlts } mov dx,word [@H] @nextline: mov cx,word [@W] @scan: lodsb cmp al,0 jz @nil mov al,es:[di] cmp al,0 jnz @coll @nil: inc di loop @scan add di,word [@A] add si,word [@B] dec dx jnz @nextline @nocoll: mov al,0 jmp @exit @coll: mov al,1 @exit: pop ds end; A BOB tpust objektumknt kell deklarlni majdnem gy, mint a SHOWBOB5.PAS pldaprogramban, csak mg hozz kell rni a kvetkez sort: function Collision( B: BOB): boolean; A fggvny demonstrcija megtallhat a lemezmellklet COLLBOB.PAS programjban, kt BOB kzl az egyiket irnythatjuk, a msik ll, s ha sszetkztek, hangjelzst hallunk. A program csak az eddig megismert eljrsokat tartalmazza, gy annak rszletei nem szorulnak tovbbi magyarzatra. { DX szoks szerint a sorszmll { CX pedig a pontokat szmllja { { { { { { { { { { { { { { Egy pont a B-Shape-bl Ha nulla, akkor ott a kt BOB nem rintkezhet Ha nem nulla, megvizsgljuk, hogy az A BOB ezen a helyen tltsz-e Ha nem, tkzs van } } } } } } } }

DI nvelse (SI a LODSB miatt ntt) } Egy sor letapogatsa } DI s SI nvelse, hogy a kvetkez sor } AX1. ill BX1. oszlopra mutasson } Sorszmll cskkentse } sszes sor letapogatsa } Ha nincs tkzs } AL=0, teht a fggvnyrtk FALSE } } }

{ Ellenben AL=1, TRUE { Eredeti DS

69

5.3. BOB-httr tkzs


Mit is rtnk valjban egy BOB httrrel trtn tkzse alatt? Azt, hogy annak bizonyos, ltalunk elre meghatrozott rszei felett helyezkedik el, egyes pontjait takarja. Egy labirintusos jtkban pldul szksges azt figyelni, hogy a BOB, a fhs mikor tkzik falnak, mert arra nem mehet tovbb. Ezt a vizsgldst is el lehetne vgezni egy httrmaszk segtsgvel, ppgy, mint a BOB-BOB tkzsnl, mi azonban megint csak a sznfigyels mdszerrel foglalkozunk. A lnyeg teht: ha a BOB legalbb egy, nem tltsz (nem 0 szn) pontja a httrnek elre megadott szn pontja felett van, azt takarja, akkor a kt grafikus elem (BOB s httr) sszetkztt. Fontos, hogy tbb olyan szn legyen, aminek rintsvel az tkzst vizsgl fggvny mg hamis, false eredmnnyel trjen vissza, mert legtbbszr a httr azon rsze, amelyben a BOB szabadon mozoghat, nem egyszn. Mr egy egyszer auts program is sokkal szebb, ha az tra fehr tburkolati jelek vannak festve, gy az aut szabad mozgsterlete, az t mindjrt kt szn: szrke s fehr. Maga a fggvny nagyon hasonlt a vgs ShowBOB eljrs kzps rszre, amikor a BOB a httrre kerl, a klnbsg csupn annyi, hogy egy BOB-bal dolgozunk, s httrre rs helyett onnan olvasunk, ppgy, mint a BOB-BOB tkzsben a kzs rsz vizsglatnl. Egyszval szinte semmi jat nem ksztnk, kt eddig ismertetett alprogram, a ShowBOB eljrs (2.5. fejezet) s a Collision fggvny (5.2.) egy-egy rszlett hasznljuk fel jra. A fggvny alapelve ugyanaz, mint a BOB-BOB tkzsnl: elszr meg kell hatrozni a kt grafikus elem kzs rszt. Ez ugyanaz, mint a ShowBOB eljrs 2.1-2.2. jelzs rsze, vagyis meghatrozzuk, a BOB mennyire lg ki a httrbl, mekkora az sszehasonltand terlet nagysga s kezdcme a httren, valamint a BOB-on bell. Ha nincs rajta a httren, nem tkzhetnek. A kzs terletet ellenrz sorok viszont msok, mint a BOB-BOB tkzsnl, de az alapelv itt is ugyanaz. Csupn annyiban klnbzik, hogy a httrnek tbb olyan szne van, aminek rintsvel mg nincs tkzs (ezeket a szneket mi adjuk meg), gy a httr bjtjait msknt kell megvizsglni. A BOB-ot ellenben ugyangy ellenrizzk. Hogy milyen szn httrpontok hatsra ne jelezzen tkzst a fggvny, legegyszerbb, ha egy tartomnyknt adjuk meg. Kt vltoz trolja ennek az egybefgg intervallumnak az als s fels hatrt, az olyan pixelek, amelyek ezek, vagy ezek kz esnek, a httr szabad rszt kpezik, ahol a BOB szabadon mozoghat. Erre mr a grafika elksztsnl, a sznek meghatrozsnl gyelni kell. Egy repls jtkban tegyk fel, hogy csak akkor robban fel a repl, ha a fldbe csapdik. A hely, ahol mozoghat, legyen tbbszn: kk g, amely vilgosszrke felhket tartalmaz. A felhk t sznbl llnak, a vilgosszrke klnbz rnyalataibl. Ez esetben, mr a httr megrajzolsa kezdetn ki kell jellni hat egymst kvet sznt, az ezzel a sznnel befestett httrpixelek adjk a BOB szabad mozgstert, mshol nem szabad ket felhasznlni. A fggvnynek csak azt a rszt ismertetjk, ami j, vagyis a BOB s a httr kzs terlett letapogat sorait. Az albbi regiszterekbe s vltozkba a kvetkez rtkeket kell tlteni: BL A szntartomny als hatra, ez alatt olyan sznek tallhatk, aminek rintsre a fggvny tkzst jelez. BH A szntartomny fels hatra. [BL..BH] intervallum adja azon pixelek sznt, melyek fltt a BOB szabadon, tkzs nlkl mozoghat. DX Az ellenrizend terlet magassga, ennyi sort kell megnzni. DS:[SI] A megvizsgland tglalap kezdcme a Shape-en bell. ES:[DI] A tglalap kezdcme a httren. @CXSAVE A megfigyelt terlet szlessge. A kdszegmensben kell trolni, gy DS visszalltsa nlkl is el lehet rni. @DIPLUS, @SIPLUS Ennyi kell adni DI-hez, ill. SI-hez egy sor ellenrzse utn. @nextline: mov cx,word [@cxsave] @scan: lodsb { cmp al,0 { jz @nil { mov al,es:[di] { cmp al,bl { jc @coll { cmp al,bh { ja @coll {

{ Egy sorban ennyi pontot ellenrzmk } Egy bjt megvizsglsa a Shape-en bell, ha nulla, tltsz, akkor itt nem rintkezhet a httrrel Ha nem nulla, s az ES:[DI] ltal megcmzett bjt nem esik a megadott sznintervallumba, tkzs kvetkezett be, a @coll-ra ugrik, ahol 1-re lltja a visszatrsi rtket (AL) } } } } } } } }

70

@nil: inc loop add add dec jnz

di { @scan { di,word [@diplus] si,word [@siplus] dx { @nextline {

Minden pont ellenrzse utn nvelni kell a DI-t is { Egy sor megvizsglsa utn a DI s { az SI is nvekszik Sorszmll cskkentse, ha mg nem nulla, jra vgrehajtjuk

} } } } } }

Ez a BOB-httr tkzst vizsgl fggvny magja, a tbbi rszt elksztst mr az Olvasra bzzuk. Nem lesz tl nehz, az eddig ismertetett ShowBOB s Collision szubrutinokbl kell bizonyos rszeket kivagdosni. A ksz fggvny egybknt megtallhat a Game egysgben a lemezmellkleten (CollColors nven), ezt a unitot a 8. fejezetben rszletesen megismerhetjk. A lemezmellkleten tallhat mg egy COLLBACK.PAS nev program, ami betlt egy LBM fjlt httrnek, s bemutatja a BOB-httr tkzst.

5.4. BOB-BOX tkzs


Ha a 4. fejezetben lert trkptechnikt alkalmazzuk, gyakran felmerlhet az a problma, hogy a httren kvl is vizsglhassunk sszetkzst, a BOB s a trkpnek a httrtl klnll rszei kztt. Ugyanis a BOBok, helyzetket tekintve, teljesen fggetlenek a httrtl, mozoghatnak nem lthat rszeken is, s nhny jtkban ezt jl ki lehet hasznlni: elre belltjuk a BOB-ok koordintit, nem baj, ha nmelyik nem ltszik, s grgetsnl vltoztatjuk ket. gy a jtk terlete az egsz trkpre kiterjedhet. ppen ezrt, hogy a httren kvl is folyik a jtk, ott is kell tkzseket vizsglni, ott sem mehet neki pldul egy aut a falnak. Most egy tkzsi maszkos mdszert alkalmazunk. Mindegyik BOX-hoz hozzrendelnk egy bitet, ami ha 1, akkor azzal a vizsglt BOB-nak nem szabad rintkeznie, vagyis a fggvny igaz eredmnnyel tr vissza. Nem vizsgljuk pixelenknt, csak azt, hogy az adott BOB terlete rint-e olyan BOX-ot, amihez korbban 1-et rendeltnk. A fggvny rszletesebb magyarzata a Game egysg lersnl tallhat (8.23.3. fejezet, CollBOX fggvny).

71

6. BOB-EDITOR
A lemezmellkleten tallhat BOBEDIT segdprogrammal BOB-okat lehet rajzolni. A BOB-adatok a lemezen gy kerlnek trolsra, hogy az a Game egysg ltal felhasznlhat legyen, a kvetkez sorrendben: Bjt 0. 1-2. 3-4. 5-6. 7Tartalom Ennek a bjtnak az rtke 1, a BOB verziszma. Shape szlessge (a valdi szlessg ennl 1-gyel nagyobb). Shape magassg (ugyanez itt is rvnyes). Fzisok szma. Ha ez nulla, akkor a BOB egyfzis. Grafikus adatok olyan sorrendben, ahogy a memriba kerlnek.

Az editor forrsszvege a lemezen megtallhat, a program ltal hasznlt unitok forrskdjval egytt. Ezeket az egysgeket valsznleg az Olvas is tudja hasznostani, ezrt elszr ezekkel ismerkedhetnk meg. Majd a program kezelse kvetkezik, amit a menrendszer s a funkcik lersa kvet. Mindezek eltt nhny fontos tudnival. 1. A program hasznlathoz nlklzhetetlen az egr, csak ezzel lehet ugyanis szerkeszteni, sznt vlasztani, s a menk is csak egrrel rhetk el, igaz, hogy a hozzjuk kapcsold funkcik legtbbje n. forrkulcsokkal is elrhet. 2. Angol nyelv. 3. A programhoz tartozik egy HOTKEYS.TXT fjl, ami nlkl a Help men Hot Keys funkcija nem mkdik.

6.1. A program ltal hasznlt unitok


A BOB-szerkeszt segdprogram a kvetkez unitokat alkalmazza: Crt, DOS, Game, MCGA, Mouse, _System. Ezek kzl a Crt s a DOS beptett Pascal-unitok, a Mouse egysggel mr foglalkoztunk (3.2.) s a Game egysg ismertetsre majd a 8. fejezetben kerl sor. Ezek szerint most az MCGA grafikai rutinokat tartalmaz, s a _System unit lersa kvetkezik, amely a beptett Sytem bvtse.

6.1.1. Az MCGA egysg


Az MCGA unit segtsgvel egyszer mveleteket vgezhetnk el a kpernyn 320200/256-os zemmdban. Elszr eljrsait, fggvnyeit, majd beptett konstansait ismerhetjk meg. procedure SetMode( Mode: word); A videokrtyt a MODE vltozban megadott zemmdba lltja. Szveges kpmdot pldul a SetMode(3); utastssal rhetnk el, az MCGA zemmd bekapcsolsra pedig $13-at kell paramterknt megadni. procedure PutPixel( X, Y: word; C: byte); Pixel kigyjtsa. A balrl X. oszlopban, fentrl Y. sorban lv kppontot C sznre festi. (A sorok s az oszlopok szmozsa 0-val kezddik.) procedure Point( X, Y: word); Az egysg Interface rszben deklarlt Pointcolor tipizlt konstans ltal meghatrozott sznre festi az (X;Y) pontot. procedure Rectangle( X1, Y1, X2, Y2: word); Keret rajzolsa, melynek bal fels sarka (X1;Y1), a jobb als pedig (X2;Y2). Sznt a PointColor vltozban adjuk meg, az eljrs meghvsa eltt. procedure CBar( Color: byte; X1, Y1, X2, Y2: word); Color szn (X1;Y1) bal fels sark s (X2;Y2) jobb als sark kitlttt tglalap rajzolsa.

72

procedure Bar( X1, Y1, X2, Y2: word); Tglalap rajzolsa, csak sznt nem az eljrs fejben, hanem a PointColor vltozban kell megadni. procedure OutText( X, Y: word; TXT: string); Szveg kiratsa. A karakterlncot a TXT vltoz tartalmazza, helyt pedig az X;Y szmprral hatrozhatjuk meg. A szveg a 88-as karakterekbl ll, a szabvny VGA karakterkszletet alkalmazza, ezrt egyes kezetes betk nem jelenthetk meg (pl. , ). Sznt a PointColor, a szveg alapsznt (httert) a TextBackColor vltoz tartalmazza. procedure OutTransparentText( X, Y: word; TXT: string); tltsz szveg kirsa. Annyi klnbsg van kzte s az elz eljrs kztt, hogy az OutTransparentText ltal kirt szveg tltsz, mgtte ltszik, ami eltte a kpernyn volt. procedure SaveBar( P: pointer; X1, Y1, X2, Y2: word); Tglalap alak tartomny elmentse a P mutat ltal megcmzett terletre. A tglalap bal fels sarka: (X1;Y1), jobb als: (X2;Y2). A kpernyrszlet tartalmt bjtonknt, sorfolytonosan trolja. procedure LoadBar( P: pointer; X1, Y1, X2, Y2: word); Elzleg elmentett terlet jra megjelentse. P a forrscm, X1, Y1, X2, Y2 adjk a tglalap koordintit. procedure VerticalBlink; Vrakozs addig, amg az elektronsugr el nem ri a kperny jobb als sarkt. function GetPixel( X, Y: word): byte; Pixel sznnek lekrdezse. const PointColor: byte = 15; Ezzel a bjttal hatrozhatjuk meg a rajzolsi sznt a kvetkez eljrsokban: Point, Rectangle, Bar, OutText, OutTransparentText. Mindig az eljrs meghvsa eltt kell rtket adni neki. const TextBackColor: byte = 0; Az OutText eljrs ltal kirt szveg htternek szne. Ennek is az eljrs meghvsa eltt kell rtket adni.

6.1.2. A _SYSTEM egysg


function _VAL( S: string): longint; Az S sztringet szmm konvertlja. Ha S a 09 szmjegyeken kvl mg egyb karaktereket is tartalmaz, a fggvny visszatrsi rtke 0. function _STR( X: longint): string; A paramterben megadott egsz szmot szvegg konvertlja (akkor hasznljuk majd, amikor az egr koordintit szeretnnk az OutText eljrssal megjelenteni). function _COPY( S: string; B: byte): char; Visszatrsi rtke az S karakterlnc B. karaktere. procedure sw_byte( var A, B: byte); procedure sw_word( var A, B: word); Ezek az eljrsok felcserlik A s B tartalmt. function IOError: word; Ellenrzi az IOResult vltoz rtkt. Ha nem nulla, hibt jelez s meglltja a program futst.

73

6.2. A BOB-Editor megjelense s hasznlata


A BOB-Editor indtsa utn a kvetkez felpts kpet lthatjuk:

1. Menk

2. res rsz (itt kell majd a BOB-ot szerkeszteni)

3. Paletta

4. llapotsor Programnv, verziszm, szerz, kelt

6.2.1. Menk
Ngy fmen van: File, Edit, Tools s Help. Az egrrel, kattintssal rhetjk el ket, aminek hatsra legrdlnek a kivlasztott men funkcii. Rszletesebben ksbb foglalkozunk a menrendszerrel (6.3. fejezet).

6.2.2. Szerkesztsi terlet


A kperny bal-kzps rsze a BOB rajzols terlete. Ha nem adunk meg a programnak paramtert, indts utn ezen a rszen mg semmi sem tallhat, csak fjl megnyitsa vagy j fjl ltrehozsa utn lehet szerkeszteni. Hozzunk ltre egy j fjlt: kattintsunk a File menre, majd a legrdl New funkcira. Itt meg kell adni a Shape mreteit (elszr a szlessgt, majd a magassgt), legyen ez kerek szm, pl. 3232. Ezutn a szerkesztsi terlet bal fels sarkban egy fehr keret tallhat, most mr lehet r rajzolni: egyszeren csak ki kell vlasztani (bal oldali egrgombbal) a paletta egy sznt, majd az egrkurzort a szerkesztsi terletre irnytva a bal oldali egrgomb lenyomsval befesthetjk a BOB pontjait. Ahol a BOB 0 szn, ott tltsz lesz. Nagytani a +, kicsinyteni a gombbal lehet (rdemes a numerikus billentyzetet hasznlni), grdteni pedig a nylbillentykkel, vagy egrrel a kpernyn a paletta alatt tallhat nyl gombokkal lehet. Ha ez utbbit hasznljuk, mindig egy pixelt mozdul el a BOB, viszont a billentyk segtsgvel gyorsabban, 10 pontonknt vlaszthatjuk ki a BOB ltsz rszt (ha a nagytsi arny ZOOM 10-nl nagyobb, akkor ezekkel is 1-1 pixelt mozdthatunk). A maximlis nagytsi arny 174-szeres, a Home billenty hatsra ez 1-re vltozik, s a BOB is hirtelen az alaphelyzetbe grdl, vagyis ltszik a bal fels sarka. Ezzel a gombbal gyorsan meg tudjuk nzni, milyen a BOB eredeti, 1:1-es nagysgban, majd az End billenty hatsra gyorsan visszaugorhatunk az eredeti nagytshoz s helyzethez. Ha 1:1 arny a nagyts (ZOOM=1), akkor az egr jobb oldali gombjval egy tglalap alak rsz jellhet ki, ehhez folyamatosan kell nyomni a jobb gombot, amg a kijells el nem ri a kvnt nagysgot. Ha ezutn a bal gombbal kattintunk a kijellt rszre (amihez hozztartozik annak szeglye is), azt arrbb mozgathatjuk. Ezenkvl mg sok ms mvelet is elvgezhet, ha van rvnyes kijells (pl. kivgs, msols, tkrzs, forgats), ezekre majd a menrendszer trgyalsnl trnk ki. A kijellt rsz szlessgt s magassgt a paletta alatt a W s a H betk utn leolvashatjuk. Ez akkor fontos, ha a kijellst forgatni akarjuk (Tools\Rotate men), mert ilyenkor rdemes ngyzet alakra trekedni, csak ekkor lesz tkletes a forgats. j fzist az Ins vagy az I billentyvel szrhatunk be az ppen aktulis fzis mg. Az els hatsra az j fzis az elznek a mintjt tartalmazza (gy knnyen tudunk olyan animcit kszteni, amikor csak kis vltozs van kt fzis kztt), mg az I billentyvel res, 0 szn fzist iktathatunk be. A fzisokat a Page Up/Down billentykkel vltoztathatjuk, de az els tizet a 0-9 gombokkal is elrhetjk. Az aktulis fzis sorszmt a kperny jobb als sarkban, a Phase felirat alatt lthatjuk.

74

6.2.3. Paletta
A jobboldalt tallhat paletta mind a 256 sznt tartalmazza, a program indtsa utn ezek a VGA-alappaletta sznei. Az egrmutat alatti szn hexadecimlis sorszma knnyen leolvashat a paletttl balra s felfele elhelyezked szmjegyek segtsgvel, tzes szmrendszerbeli sorszmt pedig az alatta lev informcis rszbl tudhatjuk meg. Ha a bal gombbal kattintunk egy sznre, az lesz a rajzolszn, a jobb oldali egrgombbal pedig mdosthatjuk az egrmutat bal fels sarka alatti szn sszetevit. Sznszerkesztsnl eltnik minden, csak a paletta marad, s a kperny bal oldaln a kvetkezket lthatjuk (fentrl lefel haladva): billentyk hasznlata, sznsszetevk intenzitsa, egy, a kivlasztott sznnel besznezett tglalap, amely a mdostott sznt szemllteti. A sznsszetevket billentykkel mdosthatjuk, az albbi tblzat s bra szerint: Q Vrs (Red) nvelse. R G B A Vrs cskkentse. W Zld (Green) sszetev nvelse. + Q W E S Zld cskkentse. A S D E Kk (Blue) komponens nvelse D Kk cskkentse Ha a bal egrgombbal egy msik sznre kattintunk, tmsolhatjuk annak sszetevit a mdostand sznre, teht ugyanolyan lesz a kt szn. Ez akkor lehet elnys, ha egy szn fokozatos rnyalatait ksztjk el: mindig lemsoljuk az elz sznt, s csak kevssel vltoztatjuk sszetevit attl fggen, hogy milyen finom rnyalatot kvnunk ltrehozni. A palettaszerkesztsbl visszalpni a jobb gombbal vagy az Enter billentyvel lehet. Ezutn ugyan megvltoznak az adott szn sszetevi, de ez mg nmagtl nem kerl sehol trolsra, a BOB mentsvel csak azt jegyezzk meg, hogy melyik helyen milyen sorszm szn szerepel, magt a sznt nem. Ezrt, ha mdostjuk az alappalettt (amire gyakran lesz szksg), minden kilps eltt mentsk el az F4 billenty vagy a File\Save Pal funkci segtsgvel, mert ha ezt nem tesszk, a sznek adatai elvesznek. Egybknt a program kilps utn megkrdezi, hogy el akarjuk-e menteni a palettt, nyomjunk Enter-t vagy Y-t, ha igen, ms gombot, ha nem. A 15-s sznt ($0F, els sor utols szn, fehr) nem rdemes mdostani, lvn ez az eltr szne, ha pldul feketre vltoztatjuk, elfordulhat, hogy nem ltunk semmit. Ekkor nyomjuk meg az F8-at, s vlasszunk j sznt az eltrnek (bal gomb), majd a jobb gombbal vagy brmely billentyvel lphetnk vissza. Ez fleg nem ltalunk ksztett, pldul LBM-bl importls utn kiszedett palettk esetben szksges, mert ezeknl elfordulhat, hogy a 15-s szn halvny vagy nem ltszik. Ezenkvl termszetesen akkor is mdosthatjuk az eltrszn sorszmt, ha fehr helyett pldul zldet szeretnnk ltni, ami egy sokkal kellemesebb szn.

6.2.4. llapotsor
A paletta alatt tallhat terleten egyrszt informcikat kaphatunk a koordintkrl, sznrl stb., msrszt az itt elhelyezked nyilak segtsgvel a BOB-ot pixelesen tudjuk grgetni. Az llapotot jelz elemek jelentse (balrl jobbra, fentrl le): X,Y Ha az egrkurzor a szerkesztsi terleten van, akkor az ltala mutatott pont koordinti, egybknt a grgets mrtke, a szerkesztsi hely bal fels sarkban tallhat pont koordinti. (vltoz szn ngyzet) Ha az egrkurzor a szerkesztsi terleten vagy a palettn van, akkor az alatta lv pont szne s sorszma, egybknt pedig a kivlasztott szn s annak sorszma. Nyilak A BOB-bl ltsz rszt llthatjuk, ha az egyik egrgombbal rjuk kattintunk. Ezenkvl mg a billentyzet nyl gombjaival is lehet grgetni, radsul gyorsabban. ZOOM A nagyts arnyt mutatja. 1 esetn nincs nagyts, rtkt a +/- billentykkel vltoztathatjuk, szlsrtkei: 1 s 174 (csak egsz szm lehet). PHASE Az aktulis, ppen lthat fzis sorszma (nullval kezddik a szmozs). Vltoztatni a 0-9, valamint a Pg Up/Down gombokkal lehet. W,H Kijells kzben lthatk, a kijellt rsz szlessgt (W) s magassgt (H) mutatjk, ha egy BOBrszletbl j BOB-ot kvnunk ltrehozni, ezeket adjuk meg az j BOB mreteinek.

75

6.3. Menk s funkcik


A BOB-Editor menrendszere kt szintbl ll, az indts utn is lthat fmenkbl (pl. File) s a kattints hatsra legrdl funkcikbl. Ez utbbiak legtbbjhez tartozik egy-egy funkcibillenty, amivel gyorsabban, knyelmesebben rhetjk el az adott funkcit. Ezeket a billentyket a kvetkez rszben kln is felsoroljuk, ismeretk hasznos lehet. Ellenben a menket csak egrrel, gombnyomssal rhetjk el (s nhny funkcit is).

6.3.1. A File men


Mint a felhasznli programok ltalban, fjlmveletek (megnyits, ments stb.) kezelsre szolgl. A kvetkez funkcikat tartalmazza: Funkci Billenty Rvid lers New j fjl ltrehozsa. Open F3 Meglv fjl megnyitsa. Save F2 Fjl mentse. Save As Shift+F2 Fjl mentse ms nven. Import Shift+F3 Grafika importlsa LBM fjlbl. Load Pal F5 Paletta betltse lemezrl, alappaletta visszalltsa. Save Pal F4 Paletta mentse. DIR Aktulis knyvtr tartalma, knyvtrvlts. Exit Alt-X Kilps (mentsi szndk krdezse nlkl!). New j fjlt hozhatunk ltre vele. Ha esetleg mr volt szerkeszts alatt egy fjl, az krdezs nlkl kitrldik a memribl, igaz, hogy res Enter megnyomsra mg visszalphetnk. A funkci meghvsa utn elszr gpeljk be a Shape szlessgt, majd magassgt (mindkett utn Enter-t kell nyomni), s mr lehet is dolgozni rajta. Arra kell csupn gyelni, hogy a szlessg s a magassg szorzata ne haladja meg a 65534-et. Eleinte a BOB egyfzis, amit az I vagy INS billentykkel lehet bvteni. Ha valamelyik mrethez nem adunk meg adatot, csak letjk az Enter-t, vltozs nlkl visszalphetnk, mintha egy Cancel gombra kattintottunk volna, gy nem vsz el a korbban szerkesztett fjl. Open (F3) Egy 4025-s felbonts kp jelenik meg, kzpen kk rszben az aktulis knyvtr llomnyai tallhatk, baloldalt pedig egy kis segtsg az Open mvelet hasznlathoz. A fjlok fizikai sorrendben kvetik egymst (ahogy a lemezen megtallhatak), Enter letsre a legfell lthat fjl nylik meg. A BOB kiterjeszts fjlok srga sznnel ki vannak jellve, gy knnyebben szrevehetk. A fjlkivlasztst s megnyitst a kvetkez billentyk segtik: A kpernyn a legfels, a fehr nyilakkal megjellt fjl megnyitsa. Ha ez kt pont, vagy egy knyvtr, akkor directory-vlts kvetkezik. ESC Mvelet visszavonsa, ha esetleg meggondoltuk magunkat (pldul nem mentettk el az elz fjlt). A-Z Lemezmeghajt-vlts. A meghajthoz tartoz betvel megjellt billentyt kell letni a kvnt meghajt aktulis knyvtrnak listzshoz. Szkz Gyakran egyszerbb a fjl nevt s tvonalt begpelni, mint kikeresni, ezt tehetjk meg a Space billenty lenyomsval. (Pldul ha tl sok fjl tallhat az aktulis knyvtrban.) Fjllista grdtse fel s le, egyesvel. , Home Ugrs a fjllista elejre (az els fjlra). End Ugrs a fjllista vgre (az utols fjlra). Page Up Egy oldal (22 fjl) ugrs felfele. Page Down Egy oldal ugrs lefele. Itt mg rdemes megjegyezni, hogy az Open mvelet magjt a programban a FileList fggvny alkotja, paramterben kell megadni a srgn kiemelt fjlok kiterjesztst, visszatrsi rtke pedig a kivlasztott fjl neve. Ezt a szubrutint taln az Olvas is fel tudja hasznlni egy sajt editor ksztshez. Enter

76

Save (F2) Ha a fjl mg nem volt elmentve (vagyis nem egy meglv, hanem j fjlt kezdtnk mdostani), akkor a Save As-nl lert funkci lp rvnybe, egybknt elmenti a fjlt a rgi nevn. Fontos, hogy a Save mvelettel a paletta mg nem kerl elmentsre, errl kln gondoskodni kell a Save Pal funkcival! Save As (Shift+F2) gy menthetjk el a fjlt, hogy j nevet adunk neki. A funkci hatsra megjelenik egy kk csk, ez a beviteli mez, neknk csupn be kell gpelni a fjl nevt, kiterjesztst, s elrsi tvonalt, ha ms knyvtrba kvnjuk menteni. Ha mr ltezik ilyen fjl, a program visszakrdez, hogy valban fell akarjuk-e rni (Overwrite?). Ha igen, nyomjunk Y-t vagy Enter-t; ms billentyt, ha nem. Ha nem adunk meg fjlnevet, csupn egy Enter-t nyomunk, visszavonhatjuk a megkezdett mveletet (a mentst). A funkci utn, a szerkesztshez visszatrs eltt a program figyelmeztet, hogy ne felejtsk elmenteni a palettt, amirl most is kln kell gondoskodni (Save Pal vagy F4). Import (Shift+F3) Elszr meg kell adni a fjl nevt kiterjesztssel (s elrsi tvonallal egytt, ha szksges), ahonnan a BOB grafikjt importlni szeretnnk, itt mg res Enter-re visszalphetnk. Fontos, hogy jl adjuk meg a fjlnevet, s tnyleg LBM formtum legyen a kp, mert klnben a program futsa megszakad (ms funkciknl nem szakad meg, csak hibt jelez), s fontos az is, hogy elzleg elmentsk a palettt s a szerkesztett BOB-ot, mert azok tartalma megvltozik. Ha nincs semmi hiba, megjelenik a megadott LBM-kp, rajta j esetben ltszik egy egrrel mozgathat kppont. Ez eltr szn, s ha sehogy sem akar megjelenni, adjunk az eltrnek ms sznt (F8). A jobb oldali gomb folyamatos nyomsa s az egr mozgatsa mellett jellhetjk ki az importland rszlet nagysgt, majd a gomb elengedse utn a szksges helyre irnythatjuk a kijellst. Ezutn a bal gomb megnyomsa utn msolhatjuk ki a megjellt rszt, ami a BOB grafikus adata lesz. Nemcsak grafikt, palettt is importlunk ezzel a funkcival, gy tudjuk pldul lelopni egy LBM kp sznskljt, viszont ha magt a kpet is felhasznljuk jtkunk htterhez, a paletta szneinek sszetevit nem szabad mdostani, mert megvltozhat a httr szne. Csak palettaimportlshoz nem a bal egrgombot, hanem egy billentyt kell megnyomni. Akkor elnys ez a funkci, ha egy msik rajzolprogrammal szerkesztjk a BOB-ok grafikjt, gy konvertlni tudjuk az ismertebb LBM formtum kpet a kevsb ismert BOB formtumba. Load Pal (F5) Egy 768 bjt hosszsg fjl nevt s kiterjesztst, esetleg elrsi tvonalt kell megadni, res Enter hatsra innen is visszalphetnk. Az alappaletta visszalltshoz csupn a kvetkezt kell begpelni: def pal, kisbetkkel. Save Pal (F4) Adjuk meg a fjl nevt, kiterjesztst, ahova a paletta adatait menteni kvnjuk. Csak Enter letsre termszetesen innen is visszalphetnk. Ha mr ltezik a megadott fjl, a program megkrdezi, hogy szndkunkban ll-e azt fellrni. Nyomjunk Enter-t vagy Y-t, ha igen, ms billentyt, ha nem. A paletta mentse nagyon fontos, ha egyszer elfelejtjk, csak nagyon nehezen tudjuk jra belltani a mdostott szneket, s ez sok bosszsgot okozhat. A paletta sznsszetevinek a trolsa is olyan mdon trtnik, hogy az a Game unit LoadPal eljrsval (8.11.) egybl betlthet. DIR A BOB-Editor hskorbl maradt meg ez a funkci, ezt mveletet az Open-nel is vgrehajthatjuk. Listzza az aktulis knyvtr tartalmt, majd megkrdezi, hogy kvnunk-e knyvtrat vltani (Change directory?). Ha Y-t vagy Enter-t tnk le, meg kell adni az j knyvtrat, kt pont a feljebblps. Exit (Alt-X) Kilps eltt mindig mentsk el a BOB-adatokat s a palettt, kilps utn mr csak a paletta mentsre van lehetsgnk (ha netn elfelejtettk volna).

77

6.3.2. Az Edit (szerkesztsi) men


Ngy funkcijval a kijellt rsz trolsa, eltntetse, visszahelyezse valsthat meg. Indts utn kzvetlenl mg egyik funkci sem hasznlhat, ehhez rvnyes kijells szksges. Elszr tekintsk t a funkcikat s a hozzjuk tartoz billentyket! Funkci Billenty Rvid lers Delete Del Kijellt rsz trlse. Cut Kijellt rsz kivgsa. Copy Ins Kijellt rsz memriba msolsa. Paste Elzleg memriba msolt rsz beillesztse. Delete (Del) Ha 1:1 arny nagyts (ZOOM=1) mellett a jobb egrgombbal kijelltnk egy tglalap alak rszt, ezzel a funkcival trlhetjk gy, hogy azt visszarni ksbb nem tudjuk, a trlt rszt a program nem jegyzi meg. A kijellst 0 rtk bjtokkal tlti fel. Cut Ugyangy eltntethetjk vele a kijellt rszt (0 sznre fests), csak azt a program megjegyzi, s ksbb a Paste funkcival beszrhatjuk. Ezzel lehet egy BOB bizonyos rszeit egy msik BOB-ba tvinni, mert j BOB ltrehozsa vagy megnyitsa esetn a memribl nem trldik ki a Cut funkcival elmentett rsz. Copy (Ins) Ez is a memriba msolja a kijellt rsz tartalmt, viszont nem trli azt, s a kijellst sem sznteti meg. A memriban mindig csak egy, a legutols Cut vagy Copy mvelettel bevitt rszlet troldik, kt Copy vagy Cut mvelet utn az els ltal elmentett rsz trldik a memribl. Paste Ha elzleg a Cut vagy a Copy funkcival elmentettnk egy rszletet, azt a Paste funkcival rajzolhatjuk vissza, ha nincs aktv kijells. A Paste funkci meghvsa utn az egr mozgatsval irnythatjuk a beillesztend rszletet, majd ha a kell helyre rt, kattintssal ragaszthatjuk be.

6.3.3. A Tools (eszkzk) men


Funkcii fknt a kijellt rsz mdostsra (tkrzsre, forgatsra stb.) szolglnak, de innen rhet el a szncsere s az animci mvelet is. Funkcii rviden: Funkci Billenty Rvid lers Turn Aktulis fzis tetszleges forgatsa. Inverse I A kijellt rszt inverzre vltoztatja. X, H Kijellt rsz horizontlis tkrzse. Mirror Mirror Y, V Kijellt rsz vertiklis tkrzse. Rotate R Kijellt rsz derkszg forgatsa. Bar Kijellt rsz feltltse egy sznnel. Change F7 Szncsere. Animate F6 Animci. Turn Tetszleges szggel forgathatjuk el a BOB aktulis fzist. A funkci meghvsa utn meg kell adni a forgats szgt, melynek egsz szmnak kell lennie, tovbb -32768 s 32767 kz kell esnie (Integer tpus). Ha csak Enter-t nyomunk, mg visszalphetnk, egybknt a mveletet nem lehet visszavonni.

78

A Turn funkci a BOB-ot kzppontja krl forgatja el, az albbi brn lthat mdon:

Az elforgatott tglalap sarkai kilghatnak a Shape terletbl, az itt lv adatok elvesznek. Ezrt forgatsnl mindig nagyobb mret BOB-bal dolgozzunk, aminek csak a kzepre rajzolunk. Maga a forgats termszetesen nem tkletes, hiszen tl nagyok a pixelek, gy nmi utmunkra, igaztsra mindig szksg van. Inverse (I) Csak az alappaletta alkalmazsa mellett eredmnyes ez a funkci. A kijells pontjainak szne gy vltozik meg, mintha a palettt fgglegesen tkrznnk, egy soron bell az els sznnel besznezett pontok a soron belli utols sznt kapjk (egy sor 16 sznbl ll). gy pldul a 16-os fekete szn pontokbl 31-es fehr lesz, s fordtva. Ezrt kell az alappaletta, mert ott legalbbis az els 32 szn esetben a sznek megfelelen vannak sorrendbe rakva. Mirror (X,H) Csak rvnyes kijells mellett alkalmazhat; a kijellt rsz pontjait annak fggleges, a tglalapot megfelez tengelyre tkrzi, teht a tkrzs irnya vzszintes lesz. Mirror (Y,V) A kijellt rszt fgglegesen tkrzi (annak kzps, vzszintes tengelyre). Ha az Inverse vagy a Mirror funkcik valamelyikt ktszer egyms utn alkalmazzuk, a mdostott rsz visszall az eredeti llapotba, gy ezekkel btran prblkozhatunk, az eredeti grafika visszallthat. Rotate (R) Hogy a Rotate funkci ne mdostsa a kijellt rszen kvli pontokat, rdemes a kijellst ngyzet alakra szabni, a jobb gomb nyomsa kzben figyelni kell, hogy a paletta alatti W s H betk utn egyenl szmok lljanak. Ha ez sikerlt, a Rotate hatsra a megjellt ngyzetet ramutat jrsval ellenttesen elforgathatjuk 90-kal (ngyszer megismtelve a mveletet az eredeti grafikt kapjuk). Ha a kijellt tglalap nem ngyzet, a BOB bizonyos pontjai elveszhetnek, vagy egyltaln nem is mkdik a funkci (ekkor hangjelzst hallhatunk). Bar A kijellt tglalapot feltlti az aktulis sznnel. Ha a palettra kattintunk, az nem sznteti meg a kijellst (ha mshova, akkor igen), gy j sznt vlaszthatunk anlkl, hogy jra meg kellene hatrozni a feltltend terletet. A Bar funkcival azonban vatosan bnjunk, a kijellt rsz eredeti tartalma visszallthatatlan. Change (F7) A BOB-on bell bizonyos szn pontokat ms sznre fest, nem csak egy fzison bell. A funkci meghvsa utn a szerkesztsi terlet kivtelvel minden eltnik, de ez vltozatlan marad (pldul a nagyts nem sznik meg). Elszr ki kell vlasztani a megvltoztatand pontok eredeti sznt, r kell kattintani az egyik ilyen pontra a bal egrgombbal. A kperny jobb als sarkbl leolvashatjuk a kivlasztott pont helyzett, sznt. Jobb gombbal kattintva vagy billentynyomsra visszalphetnk. Ha kivlasztottuk az tfestend sznt, helybe a palettbl j sznt kell kijellni, a bal gombbal. Billentynyomssal vagy a jobb gombbal mg mindig visszalphetnk. tfests utn mg ms sznekre is megismtelhetjk a mveletet, a ciklusbl a jobb gombbal (vagy egy billentyvel) lehet kilpni. A funkci az sszes fzis kivlasztott szn pontjait tfesti! Animate (F6) gy jelenti meg a BOB-ot, ahogy az egy jtkban majd felhasznlsra kerl. Az Animate funkci meghvsa utn a kperny kt rszre oszlik: fell lthat maga az animci, alul pedig a kzben hasznlhat billentyk lersa, valamint az animci sebessge. A BOB fzisai nvekv sorrendben kvetik egymst, a legutols utn a legels jn. A nyilakkal mozgathat, mg a sebessget a +/- gombokkal llthatjuk (numerikus billentyzet). A funkci kzben hasznlhat billentyk:

79

+, Nyilak V Ctrl-X

Sebessg nvelse, cskkentse; ksleltetsi id (Delay) cskkentse, nvelse. BOB mozgatsa. Bellthatjuk, hogy minden egyes megjelents utn vrakozzon-e az elektronsugr vertiklis visszafutsra (ON = vrakozs bekapcsolva, OFF = kikapcsolva). Itt megfigyelhet, hogy a mozgs szebb, de lassabb, ha figyeljk az elektronsugarat. Visszalps a szerkesztshez.

6.4. Funkcibillentyk
A Help men Hot Keys funkcija is megjelenti az itt lertak egy rszt, ezt a funkcit az F1 billentyvel rhetjk el kzvetlenl. Szerkeszts kzben hasznlhat billentyk F1 HOTKEYS.TXT fjl megjelentse (Help men). F2 Fjl mentse. Shift+F2 Fjl mentse j nven. F3 Fjl megnyitsa. Shift+F3 Importls (fjl men). F4 Paletta mentse. F5 Paletta tltse, alappaletta visszalltsa. F6 Animci (Tools\Animate). F7 Szncsere (Tools\Change). F8 j szn kivlasztsa az eltrnek (ha a fehr nem tetszik). Ha palettabetlts vagy importls utn nem ltunk semmit, nyomjuk meg az F8-at! Nyilak BOB grgetse tz pixelenknt; ha a nagytsi arny 9-nl nagyobb, csak 1 pixelenknt. +, Nagytsi arny vltoztatsa. Home Vlts 1:1-es nzetbe. A nagytsi s eltolsi rtkeket trolja. End A trolt nagytsi s eltolsi rtkek szerint a Home billenty megnyomsa eltti llapot visszalltsa. INS, I j fzis beszrsa, az elz lemsolsval, ill. anlkl. 0..9 Gyors fzisvlts. Page Up/Down Kvetkez/elz fzis. Alt-X Kilps. Eltte ne felejtsnk menteni! Kijells alatt hasznlhat billentyk X, H Vzszintes irny tkrzs. Y, V Fggleges tkrzs. R 90-os forgats (ramutat jrsval ellenttes irnyba). I Kijellt rsz inverzre vltsa. (Alappaletta mellett a fehrbl fekete lesz.) INS Memriba msols (Edit\Copy). DEL Kijellt rsz trlse (Edit\Del). Megnyits funkci kzben alkalmazhat billentyk Enter Megnyits. ESC Visszavons. A-Z Meghajtvlts. Szkz Fjlnv begpelse. Fjllista grdtse fel, le. , Home Els fjl. End Utols fjl. Page Up/ Down Egy oldal ugrs fel/le. Animci kzben hasznlhat billentyk +, Sebessg vltoztatsa. Nyilak BOB mozgatsa. V Vertiklis visszafuts figyelsnek ki-, ill. bekapcsolsa. Ctrl-X Visszalps.

80

6.5. Egyb lehetsgek


A BOB-Editort a DOS-bl paramteresen is meghvhatjuk, egy vagy kt paramterrel, pl.: BOBEDIT.EXE BOBFILE.BOB PALFILE.PAL Az els paramter annak a BOB-fjlnak a neve, amivel a program bejelentkezse utn rgtn dolgozni szeretnnk, a msodik paramter pedig egy palettafjl, ami szintn automatikusan betltdik (ha adunk a programnak paramtert). Elrsi tvonalat is rhatunk a fjlnevek el, ha szksges, viszont a kiterjesztst ne felejtsk el. Az editor ltal elksztett grafikus objektum kzvetlenl, talakts nlkl felhasznlhat jtkainkban a Game egysg segtsgvel. A betlts mdjt a unit ismertetsnl, a 8.23.7. fejezetben ismerhetjk meg. A pldaprogramok ltal hasznlt BOB-okat is talakthatjuk, prbljuk meg betlteni pldul a ROCKET.BOB fjlt!

81

7. MAP-EDITOR
A trkpszerkeszt segdprogrammal MAP formtum htteret kszthetnk jtkainkhoz, amelyet a Game unit is tud kezelni. Felptse: Cm 0. 1. 3. 5. 16389. ezek utn Mret 1 2 2 16384 (3.) 32 Tartalom Verziszm, rtke 1. Egy sorban tallhat dobozok szma (trkp szlessge). Trkp hossza (bjtban vett helyfoglalsa). BOX adatok, sorrendben, sorfolytonosan. Trkpadatok, sorfolytonosan. Maszk, tkzsi vz. Minden bit egy BOX-hoz tartozik.

A program ltal hasznlt unitok kzl eddig egy kivtelvel mindet ismertettk, most mr csak a Menu egysg mkdsnek lersa van htra, ezzel kezdjk a fejezetet. Ezutn a program megjelense, hasznlata, majd a menk s funkcik ismertetse kvetkezik, mint a BOB-Editor lersnl. A MAP-Editor forrsprogramja a MAPEDIT.PAS fjlban tallhat, mkdshez szksges mg a MECR.DAT fjl, ha ez nincs az editor knyvtrban, nem indul. A program szintn angol nyelv, s kezelshez elengedhetetlenl fontos egy mkdkpes egr, aminek legalbb kt gombja van.

7.1. A Menu egysg


A korbban keletkezett BOB-Editor menkezelse mg a programon belli eljrsokkal van megoldva, amik rugalmatlanok, bvthetetlenek (vagy csak nehezen). Ezzel szemben a MAP editor olyan eljrsokat hasznl, amelyek kln egysgben tallhatk (MENU.PAS), a menk feliratt, funkcijuk szmt s nevt a felhasznl hatrozza meg, tetszlegesen, gy egy sajt szerkesztprogramhoz az Olvas is hasznostani tudja. A Menu unit eljrsai csak MCGA kpszerkezet mellett mkdnek, az MCGA egysg (MCGA.PAS 6.1.1. fejezet) szubrutinjait hasznljk. A menk s funkcik csak egrrel rhetk el, nincsenek gyorsbillentyk, Hot Key-ek. A unithoz ezrt szksges mg a MOUSE.PAS egysg is. A unit ltal elkszthet menk ktszintesek, egy fmenbl s egy almenbl llnak. A fmenk a kperny legfels sorban helyezkednek el, ha egyikkre rkattintunk, legrdlnek a fmenbl nyl almenk, funkcik, de eltte a funkcilista ltal eltakart rsz troldik, a visszalltssal teht nem kell trdnnk. A mensor vastagsga nyolc pixel, szlessge lehet teljes kpernynyi (320) vagy annyi, amennyi szksges (ezt a Refresh eljrsnl szabhatjuk meg).

7.1.1. Eljrsok
MainMenu( s: string); A fmen meghatrozsa. gy kell megadni az elemeit, ahogy azok megjelennek, szkzkkel elvlasztva. Pldul: MainMenu('FILE EDIT SEARCH TOOLS HELP'); Semmi egyebet nem kell tenni, a program magtl sztszedi az egyes menket, s elraktrozza. A MainMenu eljrs hatsra a menk mg nem jelennek meg. SubMenu( count: word; s: string); Almenk, funkcik ltrehozsa. A Count vltozban adjuk meg a fmen azon elemnek szmt, amelybl az S ltal meghatrozott lista legrdl. A funkcilistt az S paramterben a kvetkezkpp kell megadni: egyms utn rjuk a funkcineveket, pontosvesszvel elvlasztva, szkz nlkl. Az elz pldnl maradva a SubMenu(2,'Cut;Copy;Paste'); vgrehajtsa utn gy fog kinzni a menrendszer: FILE EDIT SEARCH TOOLS HELP Cut Copy Paste

82

A legrdl lista sorrendjt mi szabjuk meg, szlessge automatikus. A SubMenu eljrs nmagban mg nem jelent meg semmit, ehhez a Refresh eljrs szksges. GetMenu; Kivlasztott men, kivlasztott funkci lekrdezse. A programban, ahol ezt a unitot felhasznljuk, figyelni kell, a felhasznl mikor kattint a fels, 8 pixel vastagsg rszre, ezutn kell meghvni ezt az eljrst, ami a MainRes vltozba a kivlasztott fmen sorszmt, a MenuRes-be pedig a funkcisorszmot tlti (1, ha a legfels funkci lett kivlasztva). Neknk nincs ms dolgunk, mint meghvni ezt az eljrst, ami ezutn elvgzi a funkcilista legrdtst, figyeli az egeret stb. A legrdl funkcilista alatti rsz nem vsz el, elraktrozdik, s az eljrsbl val kilps eltt visszardik. Refresh( BarToEnd: boolean); Megjelenti a fment (a funkcilista legrdtst a GetMenu vgzi). Ha IGAZ (true) paramtert adunk, a fmen jobb szle egybeesik a kperny jobb szlvel, ellenkez esetben (false) hossza annyi, amennyi minimlisan szksges. Fontos, hogy az eljrs meghvsa eltt a videokrtya MCGA ($13-as) zemmdban legyen.

7.1.2. Vltozk, konstansok


Azonost MainRes MenuRes Tpus word word rtk Lers A kivlasztott fmen s funkci sorszmt tartalmazzk a GetMenu meghvsa utn.

A kvetkez ngy konstanst csak gy tudjuk mdostani, hogy trjuk rtkket a forrsllomnyban (a MENU.PAS fjlban). A unit e ngy rtk alapjn hatrozza meg az implementcis rszben deklarlt vltozk mreteit, ezrt nem lehet ket futs kzben mdostani. Azonost Tpus rtk Lers MaxLength 8 Fmen egy-egy elemnek maximlis hossza (karakterben). MaxMains 8 Fmenk maximlis szma. MenuLen 12 Funkcinevek maximlis hossza (karakterben). MaxMenus 7 Egy menbl legfeljebb ennyi funkci grdlhet le. Az albbi vltozk rtkt brmikor mdosthatjuk, ha a fekete-fehr sszellts nem tetszik, vagy ha nem az alappalettt hasznljuk. Minden vltoztats utn, hogy az eredmny lthat legyen, meg kell hvni a Refresh eljrst. Azonost Tpus rtk Lers MFColor byte 0 Menk s funkcik elternek szne. MBColor byte 15 Szvegek alap-, httrszne. SFColor byte 15 Kivlasztott men, ill. funkci eltrszne. SBColor byte 0 Kivlasztott elem httrszne. Menk, funkcik betsort trol vltozk, azok tpusa: MainStr: array [1..MaxMains] of string [MaxLength]; SubStr: array [1..MaxMains,1..MaxMenus] of string [MenuLen];

7.1.3. Pldaprogram
Az albbi plda szemllteti a Menu egysg hasznlatt, de felhasznljuk benne a Mouse s az MCGA egysg rszeit is. A programbl gy lehet kilpni, ha nem a mensoron kattintunk. Egr nlkl nem indul. {menudemo.pas} uses Menu, Mouse, MCGA; { Ezeket a unitokat mr ismertettk begin SetMode($13); { MCGA zemmd bekapcsolsa if not InitMouse then begin SetMode( 3); writeln('Az egr nincs installlva.'+#7 { Hangjelzs } ); halt end; } }

83

MainMenu('Zldsg Gymlcs'); SubMenu( 1, 'Rpa;Retek;Dinnye'); SubMenu( 2, 'Alma;Krte;Meggy'); MFColor:= 1; SBColor:= 12; Refresh( true); ShowMouse; PointColor:= 12; TextBackColor:= 0;

{ { { { { { {

A mensor kt egysgbl ll A 'Zldsg' men funkcii A 'Gymlcs' men funkcii Eltrszn: kk Vlasztott elem httrszne Mensor megjelentse Egrkurzor megjelentse

} } } } } } }

repeat { Gombnyomsra vrakozs repeat until ButtonPressed; GetMenu; { Kivlasztott elem lekrdezse PointColor:= 15; { Ezt a kt vltozt a GetMenu TextBackColor:= 0; { eljrs megvltoztatja if MenuRes>0 then OutText( 0, 100, { Eredmny kirsa SubStr[MainRes,MenuRes]+' '+MainStr[MainRes]+' '); { Kilps, ha mshol kattintunk until MainRes=0; SetMode( 3); end. { Szveges md

} } } } } } }

7.2. A kperny felptse, az editor hasznlata


Indts utn a kvetkez kp tlik szemnkbe: 1. Menk 3. BOX-ok 2. Trkpszerkesztsi terlet 5. 4. BOX Paletta szerkeszts

6. llapotsor

Ez egy kicsit bonyolultabb, mint a BOB-Editor megjelense, els indts utn taln egy kicsit nehz lenne megrteni, mi hol van, melyik fekete tglalapon mit kell szerkeszteni (mert eleinte a BOX-bjtok mindegyike nulla, gy a kperny nagy rsze fekete). Ha rgtn az elejn betltjk a PELDA.MAP fjlt, knnyebb lesz megrteni a szerkeszt felptst. A MAP-Editor hasznlathoz szksges a trkpszerkezet ismerete (4.2. fejezet), ami sszetettebb, mint egy egyszer pixelenknti kptrolsi mdszer, ezrt most rviden tismteljk. Kt rszbl ll: a trkpbl, s 256 BOX-bl. Minden BOX 88-as, s a memriban egyms utn helyezkednek el. A trkp minden egyes bjtja helyn egy 88-as ngyzet, BOX jelenik meg. Ez akkor j, ha egy grafikus brt tbbszr fel akarunk hasznlni, ezzel a mdszerrel lnyeges memrit tudunk sprolni.

7.2.1. Menk
A fmenk szma ngy, ezek sorrendben: File, Edit, Options, Help. Ha valamelyikre rkattintunk, legrdl egy funkcilista, melyekkel a 7.3. fejezetben foglalkozunk rszletesebben. Itt elg annyit megjegyezni, hogy a menk a Menu unittal kszltek, s hogy a Help men funkcii nem mkdnek, tetszs szerint kiegszthetek.

84

7.2.2. Trkpszerkesztsi terlet


A menk alatt tallhat rszen szerkeszthetjk a trkpet. Ez nem tl bonyolult, a bal egrgombbal szrhatjuk be az aktulis dobozt, amit a kperny jobb fels rszben (3.) vlaszthatunk ki, szintn a bal gombbal. Ha az egrkurzort a szerkesztsi terleten mozgatjuk, a sttussor jobb oldaln a BOX felirat utn olvashatjuk le a kurzor alatti doboz sorszmt. Mr indts utn lehet szerkeszteni, akkor is, ha nem adunk paramtert, a futtats utn bekszn trkp mrete 4025 BOX, ami ppen egy kpernynyi (320200 pixel). Mivel a trkpszerkesztsi terlet (2.) ennl sokkal kisebb, a MAP-et grdteni kell. Ha ehhez a nylbillentyket hasznljuk, akkor az Options men Tab size (7.3.3. rsz) funkcijval belltott rtkkel mozgathatjuk a trkpet, ami alapllapotban egy, teht eleinte a nyilak hatsra egy BOX-nyit mozdul el a trkp. Tzesvel grdthetnk a kvetkez billentykkel: Jobbra Crtl- Balra Crtl- Page Up Fel Page Down Le A jobb oldali egrgomb folyamatos nyomsa mellett egy tglalap jellhet ki, ezzel klnbz szerkesztsi mveletek vgezhetk el (Edit men 1-3. funkci 7.3.2. fejezet). Ha a bal gombbal rkattintunk a kijellt rszre, tmsolhatjuk egy msik helyre. Ekzben a kivlasztott rszt egrrel mozgathatjuk. A trkpet beilleszts alatt is lehet grdteni, a nyilakkal s a fenti billentykkel. Ha a megfelel helyre irnytottuk a kijellt tglalapot, a bal oldali gomb megnyomsval szrhatjuk be.

7.2.3. BOX-kivlaszt rsz


A kperny jobb oldaln, fell vannak felsorakoztatva a dobozok, egyms utn, nvekv sorrendben. Ha az egrkurzort valamelyikre rirnytjuk, megjelenik annak mintja s sorszma az llapotsoron. A bal gomb megnyomsval vlaszthatjuk ki a szerkeszteni kvnt BOX-ot, s ez lesz egyben az aktulis doboz, amit a trkpszerkesztsi terleten (2.) a bal gombbal illeszthetnk be. Ha kivlasztunk egy dobozt, annak mintja a kperny jobb als rszben, a BOX-szerkesztsi terleten (3.) nyolcszoros nagytssal jelenik meg. Kivlasztson kvl mg egy egyszer msolsi mvelet is elvgezhet a kpernynek ezen a rszn: ha valamelyik BOX fltt a jobb oldali gombot nyomjuk meg, mintjt tmsoljuk az aktulis dobozra. Teht ha azt akarjuk hogy pldul az 1. BOX mintja olyan legyen, mint a 2.-, akkor elszr a bal gombbal kattintsunk az els dobozra, majd a jobb oldalival a msodikra. Nem szabad sszekeverni, mert az sok kellemetlensget okozhat, ugyanis az 1. BOX mintjt csak gy tudjuk visszalltani, ha jrarajzoljuk. Az aktulis, bal gombbal kivlasztott BOX sorszma az llapotsorrl olvashat le, ha az egrkurzort a kperny tetejre vagy bal szlre hzzuk.

7.2.4. BOX-szerkesztsi terlet


A kperny jobb als sarkban tallhat. A jobb vagy bal oldali gombbal sznezhetjk t az aktulis BOX pixeleit, a rajzolsznt a palettbl a bal gombbal lehet kivlasztani. Az egr kurzora alatti szn sorszma az llapotsorbl olvashat le. Ha tfestjk egy BOX pixeleit, a vltozs megjelenik a dobozkivlaszt (3.) rszen is, ahol megnzhetjk, hogyan nz ki lekicsinytve, 1:1-es arnyban.

7.2.5. Paletta
A dobozkivlaszttl lefele, a dobozszerkeszttl balra tallhat, sznes ngyzeteirl mr els indts utn is knny felismerni. A bal oldali gombbal lehet a rajzolsznt kivlasztani, a jobb egrgombbal pedig szerkeszteni, sszetevit vltoztatni. Az egrkurzor ltal mutatott szn sorszma az llapotsoron megjelenik. Az egsz paletta nem frt volna el gy, hogy ilyen nagy rszen (88 pixel) jelenik meg egy-egy szne, ezrt vagy kicsinyteni kellett, vagy gy megoldani, hogy mindig csak egy rszt ltjuk. Ha egy palettasznhez tartoz terletet negyedre cskkentennk, a paletta ugyan elfrne, viszont nagyon nehz lenne egy sznt kivlasztani. Nem maradt ms htra, grgetses mdszert kell alkalmazni. Ha a paletta felett tallhat UP felirat rszre kattintunk, felfel, ha a DOWN-ra, lefel grdl egy sorral.

85

Az egyik sznre a jobb egrgombbal kattintva vltoztathatjuk annak sszetevit. Ekkor a palettt kivve az egsz kperny megvltozik, feliratok, szmok jelennek meg annak bal oldaln, s egy tglalap, amelynek szne megegyezik az ltalunk kivlasztottal, itt ellenrizhetjk, hogy jl lltottuk-e be a sznsszetevket. A komponensek vltoztatsa a kvetkez gombokkal trtnik: Q Vrs (Red) nvelse. R G B A Vrs cskkentse. W Zld (Green) sszetev nvelse. + Q W E S Zld cskkentse. A S D E Kk (Blue) komponens nvelse. D Kk cskkentse. Itt is, mint a BOB-Editorban, ha a bal oldali gombbal kattintunk egy sznre, tmsolhatjuk annak sszetevit az ppen szerkeszts alatt ll sznre. Kilpni a sznszerkesztbl Enter-rel vagy az egr jobb oldali gombjnak megnyomsval lehet. Ha a 15-s, fehr sznt mdostjuk, a szerkeszt eltrelemeinek j sznt kell adni a 7.5. fejezetben lertak szerint.

7.2.6. llapotsor
A trkpszerkeszt rsz alatt tallhat llapotsor kt rszre oszthat. Bal oldaln kaphatunk informcikat a koordintkrl, ha az egrkurzor a trkpen van, akkor az ltala megjellt BOX koordintjt lthatjuk itt, a kvetkez sorrendben s formban: abszcissza : ordinta. A koordinta-rendszer alapegysge 1 BOX. Ha az egr mutatja nem a trkpszerkeszt rszen van, akkor az llapotsor bal oldaln a trkp lthat rsznek bal fels sarkban elhelyezked BOX koordintit lthatjuk, ms szval a trkp eltolsi mrtkt vzszintesen s fgglegesen. A sttussor jobb oldaln pedig az aktulis vagy az egr ltal mutatott dobozrl vagy sznrl kaphatunk informcikat. Az aktulis, kivlasztott BOX mintjt s sorszmt akkor lthatjuk ezen a rszen, ha az egeret a kperny bal oldalra vagy tetejre mozgatjuk, pldul a mensorra. A rajzolszn sorszmt pedig akkor tudhatjuk meg, ha a kperny jobb als rszre visszk az egrkurzort.

7.3. Menk
A MAP-Editor menrendszere is ktszintes, egyrszt ll a fmenkbl, amit a kperny tetejn, baloldalt lthatunk, msrszt a funkcikbl, melyek egy fmenre val kattints utn grdlnek le. Ugyanilyen menkezelst az Olvas is alkalmazhat sajt programjban, a 7.1. rszben kifejtett Menu egysg segtsgvel.

7.3.1. A File men


A fjlmveletek (pl. ments, tlts) elvgzsre szolgl, funkcii: Funkci Billenty Rvid lers New j fjl ltrehozsa. Open F3 Meglv fjl megnyitsa. Save F2 Fjl mentse. Save as Shift+F2 Fjl mentse ms nven. Save Pal F4 Paletta mentse. Load Pal F5 Paletta betltse lemezrl. Exit Alt-X Kilps. New Az aktulis fjlt alaphelyzetbe lltja: a trkpen lv BOX-ok sorszma 0 lesz, mindegyik dobozt 0 sorszm sznnel tlti fel. Eltte azonban a program megkrdezi, hogy valban j trkpet akarunk-e szerkeszteni. Ha igen, nyomjunk Enter-t vagy Y-t, ha nem, brmely ms billentyt vagy egrgombot. Az j fjl mreteit nem itt, hanem az Options men Map size funkcijval lehet belltani, a New funkcival ltrehozott trkp mrete megegyezik az azelttivel. Open (F3) Egy grdthet listbl kell kivlasztani a megnyitni kvnt fjlt. Ez a funkci teljes egszben megegyezik a BOB-Editor File\Open funkcijval (6.3.1. fejezet), ezrt itt mr csak a fjl kivlasztst segt billentyket rjuk le, rviden.

86

Enter ESC A-Z Szkz , Home End Page Up Page Down

Fjlkivlaszts vagy knyvtrvlts. Visszavons, megnyits nlkli visszalps. Lemezmeghajt-vlts. Fjl megadsa nevnek (s tvonalnak) begpelsvel. Fjllista grdtse fel s le, egyesvel. Ugrs a fjllista elejre (az els fjlra). Ugrs a fjllista vgre (az utols fjlra). Egy oldal (22 fjl) ugrs felfele. Egy oldal ugrs lefele.

Save (F2) Fjl gyorsmentse azonos nven. Ha a trkpet eddig mg nem mentettk el, a Save as funkci lp rvnybe, ahol meg kell adni a nevt. A Save csak a trkp adatait menti el, a palettt nem! Save as (Shift+F2) Fjl mentse ms nven. A mveletbl egy res Enter megnyomsval visszalphetnk. Ha a fjlnak nem adunk kiterjesztst, az automatikusan .MAP lesz. Ha szksges, a fjl neve el gpeljk be az elrsi tvonalat is. Ha mr ltezik a megadott fjl, a program megkrdezi, hogy fell kvnjuk-e rni. ssnk Enter-t vagy Y-t, ha igen, mst, ha nem. A paletta elmentsrl most is kln kell gondoskodni (Save pal vagy F4). Save pal (F4) A paletta mentsnl az elbbiek rvnyesek, csak az alapkiterjeszts .PAL, s termszetesen a paletta mentsrl ezutn mr nem kell kln gondoskodni. A sznsszetevk trolsa: 0. szn R, G, B; 1. szn R, G, B; ... (s gy tovbb egszen 256-ig). Minden sznsszetev egy bjtot foglal, gy a PAL-fjl mrete: 3256=768 bjt. Load pal (F5) Ugyanolyan mdszerrel vlaszthatjuk ki a betlteni kvnt paletta-fjlt, mint a kt editor Open funkcijnl (6.3.1. s 7.3.1. fejezet), csak a srgn kijellt fjlok kiterjesztse most .PAL. Az alappalettt visszalltani nem itt, hanem az Options men Default pal funkcijval lehet. Exit (Alt-X) Kilps eltt a program megkrdezi, hogy valban ki akarunk-e lpni. Ekkor rdemes vgiggondolni, hogy mindent elmentettnk-e (trkpet, palettt), s ha igen, nyomjunk Enter-t, vagy az Y billentyt

7.3.2. Az Edit (szerkesztsi) men


A fels hrom funkcijhoz (Delete, Cut, Copy) szksges egy rvnyes kijells a trkp-szerkesztsi terleten (a jobb oldali egrgomb folyamatos nyomsa mellet kerthetnk el egy ilyen tglalap alak terletet). Az Edit men funkcii: Funkci Billenty Rvid lers Delete Del Kijellt rsz trlse. Cut Kijellt rsz kivgsa. Copy Ins Kijellt rsz memriba msolsa. Paste Elzleg memriba msolt rsz beillesztse. Clear map Trkp trlse, 0-sorszm BOX-okkal trtn feltltse. Go to F6, Enter Ugrs a megadott pozciba. Mask BOX tkzsi vz szerkesztse. Delete (Del) A kijellt rsz trlse (0-sorszm dobozokkal fellrsa), gy, hogy azt nem lehet visszalltani, csak ha jrarajzoljuk. Ha nincs rvnyes kijells, a funkci hatstalan. Cut Kijellt rsz trlse, de annak tartalma a memriban megmarad egszen addig, amg ezt a memriban egy jabb Cut vagy Copy mvelettel fell nem rjuk (mindig a legutols Cut vagy Copy ltal elraktrozott rsz troldik csak a memriban). Az elmentett tartomny a Paste funkcival illeszthet be.

87

Copy (Ins) Ugyanazt a hatst rhetjk el vele, mint az elz funkcival, csak a kijellt rsz nem trldik. Ha a kijellt tglalapra a bal oldali egrgombbal kattintunk, a program elszr vgrehajt egy Copy mveletet, majd egy Paste eljrst. Paste Ha elzleg a Copy vagy a Cut funkci valamelyikvel elmentettnk egy tglalapot a trkpbl, azt a Paste mvelettel illeszthetjk be egy j helyre, vagy akr egy msik fjlba. Ha elzleg a memriba nem mentettnk el ilyen rszt, a Paste funkci meghvsa utn hangjelzst hallhatunk. Beilleszts kzben ESC-vel visszavonhatjuk a vgrehajtst, a bal gombbal pedig nyugtzhatjuk azt. Clear map Ezzel a funkcival letrlhetjk a trkpet, gy, hogy a BOX-ok vltozatlanok maradnak. Az eljrs vgrehajtsa eltt azonban mg rkrdez, hogy biztosak vagyunk-e a dolgunkban (Enter vagy Y, ha igen). Go to (F6, Enter) Meghvsa utn kirl a kperny, majd az els sorbl kiolvashatjuk az aktulis pozcit. Ezek utn a program megkrdezi, hova szeretnnk ugrani, elszr az abszcisszt, majd az ordintt, s belltja a trkpet, hogy a bal fels sarkban az ltalunk megadott koordintj BOX legyen lthat. A koordintk egysge: 1 BOX. Ha valamelyik irnyhoz nem runk be semmit, csak egy Enter-t tnk, annak az rtkt a program 0-nak veszi. Mask Az tkzsi vzat a Game egysg BOB tpusnak CollBOX fggvnye hasznlja (8.23.3. fejezet). A funkci kivlasztsa utn a bal gombbal jellhetk ki azok a dobozok, amelyekkel a vizsglt BOB nem rintkezhet, azaz ha ezekkel rintkezik, a CollBOX fggvny visszatrsi rtke igaz (true). A jobb oldali gombbal kapcsolhat ki a maszk adott BOX-hoz tartoz bitje. Visszalpni brmely billenty letsvel lehet.

7.3.3. Options (opcik) men


Klnfle belltsok vgezhetk el az Options men ngy funkcijval, melyek rviden sszefoglalva az albbi tblzatban lthatk: Funkci Billenty Rvid lers Tab size Elmozdulsi egysg mretnek vltoztatsa. Map size Trkp mretnek tlltsa. Full screen Szkz Teljes kpernys nzet. Default pal Alappaletta visszalltsa Tab size A nylbillentykkel trtn trkpgrgets nagysgt adhatjuk meg itt, 1 s 23 kz kell esnie, az alaprtk: 1. Ha rossz rtket adunk meg, spolst hallhatunk, majd jra kell prblkoznunk. Map size A trkp mreteit vltoztathatjuk ezzel a funkcival. A legfels sorban olvashatjuk az aktulis mreteket, mikzben be kell gpelni az j szlessget, majd a magassgot. Csupn egy Enter megnyomsra a mvelet visszavonhat. Ha nveljk vagy nem vltoztatjuk valamelyik irnyhoz tartoz mretet, a trkp tartalma nem vltozik, az j rszre 0 sorszm dobozok kerlnek. Viszont ha cskkentjk szlessgt vagy magassgt, az gy levgott rszek elvesznek, ezrt legynk vatosak! Full screen (szkz) A MAP megjelentse az egsz kpernyn. A szerkesztsi terleten a bal fels sarokban tallhat BOX kerl a kperny bal fels sarkba. Billenty- vagy gombnyomssal lehet visszalpni. Default pal VGA-alappaletta visszalltsa. A funkci kivlasztsa utn megjelen krdsre igennel kell vlaszolni (Enter vagy Y billenty), ha az alappalettt valban vissza szeretnnk lltani, brmely ms billenty vagy egrgomb hatsra visszavonhatjuk a mveletet.

88

7.4. Funkcibillentyk
Mivel a Help men egyik funkcija sem mkdik, az egyes mveletek gyors elrsre szolgl billentyket az albbi tblzatban foglaljuk ssze. Nhny billenty csak bizonyos felttelek mellett hasznlhat (pl. rvnyes kijells, megnyits kzben), ezeket kln jelezzk. F2 Shift+F2 F3 F4 F5 F6, Enter Szkz Alt-X Nyilak Ctrl-/Ctrl- Page Up/Down Del Ins Fjl mentse. Fjl mentse j nven. Fjl megnyitsa. Paletta mentse. Paletta betltse. Ugrs. Teljes kpernys nzet. Kilps. Trkp mozgatsa, az Optoins men Tab size funkcijnl megadott egysggel. Eleinte ez 1. Trkp mozgatsa tzesvel jobbra/balra. Trkp mozgatsa tzesvel fel/le. Kijellt rsz trlse (rvnyes kijells szksges). Kijellt rsz memriba msolsa (rvnyes kijells szksges).

Megnyits vagy palettabetlts kzben alkalmazhat billentyk Enter Megnyits. ESC Visszavons. A-Z Meghajtvlts. Szkz Fjlnv begpelse. Fjllista grdtse fel, le. , Home Els fjl. End Utols fjl. Page Up/ Down Egy oldal ugrs fel/le. Sznsszetevk vltoztatsra szolgl billentyk Q Vrs (Red) nvelse. A Vrs cskkentse. W Zld (Green) sszetev nvelse. S Zld cskkentse. E Kk (Blue) komponens nvelse D Kk cskkentse

R G B + Q W E A S D

7.5. Tovbbi lehetsgek


A MAP-Editort is paramterezhetjk, ppgy, mint a BOB-Editort. Ha csak egy paramtert adunk meg, az annak a trkp-fjlnak a neve, ami indts utn automatikusan betltdik. Kt paramter esetben az els ugyanez, mg a msodik az automatikusan betltd palettafjl neve. Egy MAPEDIT.COL nev fjl ltrehozsval megvltoztathatk az editor eltrsznei. A program futtats utn megvizsglja, hogy van-e ilyen nev fjl az aktulis knyvtrban, ha van, annak megfelelen lltja be a szneket, ha nincs, akkor az eltr fehr lesz, ami meglehetsen egyhang. A szerkeszt klnbz egysgei (keretek, menk stb.) ms-ms sznek lehetnek, a fjl soraiban ezeket kell megadni. Szveges legyen az adatllomny, minden sorba kerljn egy 0 s 255, vagy ezek kz es egsz szm, s semmi ms. sszesen 11 sorbl ll, ezek a kvetkez szneket tartalmazzk: 1. Szvegek, informcik szne (pl. koordintk az llapotsorban). 2. Keretek, pldul a szerkesztsi terletet krllel ponthalmaz szne. 3. Paletta Scroll gombjainak (UP ill. DOWN felirattal) betszne. 4. Palettagrget gombok alapszne. 5. Menk, funkcik betinek szne. 6. Menk, funkcik alapszne. 7. Kivlasztott men vagy funkci eltrszne. 8. Kivlasztott men vagy funkci httrszne.

89

9. Krdez ablakok alapszne (ilyen ablak jelenik meg pldul a kilps eltt). 10. Krdez ablakok betszne. 11. Kurzor szne, a kurzor egy ngyzet alak keret, ami krlveszi az egrmutat ltal kijellt BOX-ot. A lemezmellkleten tallhat COLORS.PLD fjlt nevezzk t MAPEDIT.COL-ra, s ezek utn indtva az editornak sokkal kellemesebb sznei lesznek. A MAP-Editor a trkpet olyan formban menti el, hogy az a Game egysg LoadMAP (8.10.) eljrsval sajt jtkban is felhasznlhat.

90

8. A GAME unit
E fejezetben lert Game egysg egy olyan programknyvtr, melynek eljrsai, fggvnyei nagy segtsget nyjtanak egy jtk elksztshez. Maga a forrsszveg nagy terjedelme miatt itt, a knyvben nem tallhat meg, csak a knyvhz mellkelt lemezen egy GAME.PAS nev fjlban. A unit nem hasznl ms, ltalunk ksztett unitot, csak a Crt s a DOS egysgeket, melyek a Turbo Pascal rendszer rszt kpezik. gy a GAME.PAS lefordtshoz nem szksges semmilyen ms fjl, feltve persze, hogy a Crt s DOS unitok a rendszer szmra elrhetk. (A Turbo Pascal teleptse utn ez a kt unit a TURBO.TPL fjlban tallhat meg, s ha nem trljk ket onnan a tpumover programmal, akkor a Crt s a DOS mindig hozzfrhet.) A Game egysg fknt a ktdimenzis jtkhoz szksges grafikai megoldsokat biztostja, de megtallhatk benne pldul tkzseket vizsgl fggvnyek is. A unit ltal kszthet jtkok a VGA krtya MCGA zemmdjt alkalmazzk, ezrt grafikjuk felbontsa nem tl j (320 pixel vzszintesen, 200 pixel fgglegesen), viszont az egyszerre megjelenthet sznek szma (256) mr kielgt. Az egysgben eddigi tapasztalatainkat foglaljuk ssze s bvtjk. Sok olyan szubrutint tartalmaz, aminek forrskdja a knyvben is megtallhat, ezek helyre mindig utalni fogunk. Viszont akadnak olyan eljrsok, fggvnyek is, amelyek teljesen jak vagy csak rintlegesen foglalkoztunk velk. Pldul a palettrl csak az 1. fejezetben volt sz, ezzel szemben a unitban tallhat egy elsttt (8.6.) s egy kivilgost (8.19.) eljrs, melyek mr sokkal bonyolultabbak egy egyszer sznbelltsnl. A Game unit eljrsainak, fggvnyeinek s vltozinak egy rsze a BOB objektumtpusban tallhat meg, ennek a tpusnak lerst s hasznlatt a tbbi eljrstl kln, a 8.23. rszben tallhatjuk meg. Az albbiakban elszr azokat a szubrutinokat ismertetjk, amelyek kzvetlenl elrhetk, majd a BOB tpus lersa kvetkezik, vgl pedig az egysg Interface rszben megtallhat globlis vltozk s konstansok bemutatsra kerl sor.

8.1. DoneGame eljrs: az egysg lezrsa


Szintaxis: DoneGame; Lezrja a Game egysg hasznlatt, felszabadtja a lefoglalt memriatartomnyokat s visszalltja a szveges zemmdot. Mkdse ellenttes az InitGame eljrssal. A hasonlsg kztk annyi, hogy mindkettt csak egyszer szabad hasznlni egy programban, mivel a Turbo Pascal memriakezelse hagy nmi kvnnivalt maga utn. Ha teht egy jtk kzben valamirt szveges kpernyt szeretnnk hasznlni (pl. toplista kirsa), semmikpp sem ajnlatos a text zemmdot a DoneGame eljrssal belltani, inkbb hasznljuk a 10h megszaktst a kvetkezkppen: asm mov ax,3 int 10h end; vagy az MCGA unit SetMode eljrst (6.1.1. fejezet). A DoneGame ugyanis felszabadtja a megjelentshez szksges memrit (httr s munkaterlet), radsul szabadd teszi a Shape-ek trolshoz felhasznlt bjtokat is. s a tapasztalatok azt mutatjk, hogy egy Turbo Pascalban rt program memriakezels szempontjbl akkor lesz j, ha az elejn lefoglaljuk az sszes szksges memrit, s csak a vgn szabadtjuk fel, vagy a szabadd ttelvel egyltaln nem is trdnk.

8.2. DoneKey eljrs: BIOS billentyzetmegszakts vissza


Szintaxis: DoneKey; Az InitKey eljrssal mdostott billentyzetmegszakts vektort visszalltja az eredeti cmre, vagyis ezek utn ismt a BIOS-megszakts lesz aktv. Csak akkor hvjuk meg a DoneKey eljrst, ha eltte prjt, az InitKey-t mr lefuttattuk, ellenkez esetben a rendszer lefagyhat. A mdostott billentyzetmegszakts lnyege, hogy egyszerre tbb billenty llapota figyelhet, folyamatosan. Rszletesebben a 3.1. rszben olvashatunk rla. Minden olyan program vgn meg kell hvni ezt az eljrst, amiben az InitKey-t is meghvtuk, klnben a rendszer lefagyhat, mert nem lltottuk vissza az ltala hasznlt megszaktsvektort. Elfordulhat, hogy utna a billentyzet nem mkdik helyesen, ekkor nyomjuk meg mindkt Ctrl billentyt egyszerre.

91

Az InitKey s DoneKey eljrsprt akrhnyszor meghvhatjuk egy program sorn, arra azonban gyelni kell, hogy egyms utn ktszer ne futtassuk le csak az egyiket. A DoneKey kikapcsolja az InitKey ltal belltott megszaktst, amire akkor lehet pldul szksg, amikor valamilyen adatot kell bevinni (nv, szm stb.). Ekkor sokkal egyszerbb a BIOS megszaktst alkalmazni, ami gpelsre, adatbevitelre sokkal megfelelbb.

8.3. DrawBox eljrs: egy BOX megjelentse


Szintaxis: DrawBox(P: pointer; B, X, Y: word); Egy BOX-ot rajzol ki a megadott helyre. P annak a memriatartomnynak a kezdcme, ahov a BOX kerl. Ez lehet pldul a httr (Background), a munkaterlet (WorkArea) vagy a kpmemria ($A000:0). B-ben adjuk meg a BOX sorszmt, X-ben s Y-ban pedig a koordintit. Ez utbbiak maximlis rtke 311, illetve 192, vagyis a koordinta-rendszer alapegysge 1 pixel. Ellenrzs nincs, ezrt rossz paramterbelltssal a rendszer akr le is llthat. A DrawBox eljrssal megvalsthat, hogy legyen a httrnek olyan rsze, ami valjban eltr, mert minden ms grafikus elem fltt helyezkedik el. Ezt gy kell megvalstani, hogy elszr sszelltjuk a kpet a munkaterleten a MakeScr eljrssal (8.12. rsz), de mg nem jelentjk meg, hanem meghvjuk a DrawBox szubrutint, aminek els paramterben a munkaterlet kezdcmt adjuk meg. Pldul gy: MakeScr; DrawBox( WorkArea, 2, 220, 150); ShowScr; Ekkor a megjelen kpen lesz egy BOX, melynek a sorszma 2, bal fels sarknak kperny-koordinti pedig (220;150). Ez a doboz minden alatta lev BOB-ot eltakar, gy gy tnik, mintha legfell lenne. Ez a mdszer alkalmazhat pldul egy hajs jtkban, amikor a haj a hd alatt szik t. De vigyzzunk, minl nagyobb az a rsz, ami legfell van, azaz minl tbb BOX-ot rakunk ki egyszerre egy ciklusban, annl lassabb lesz a program futsa.

8.4. FillBack eljrs: httr besznezse


Szintaxis: FillBack(Color:byte); Besznezi a htteret az eljrs paramterben megadott sznre. Az eljrs nagyjbl megegyezik a 4. fejezet elejn ismertetett eljrssal. Az InitGame eljrs is meghvja a FillBack-et, paramterknt a BackColor vltozt adja meg, aminek kezdrtke 0.

8.5. GrayPal eljrs: szrkesklv konvertls


Szintaxis: GrayPal(First, Last: word); Szrkesklt llt el a paletta bizonyos tartomnybl. A tartomny els sznt az eljrs els, mg az utolst a msodik paramterben kell megadni. Akkor lehet az eljrsra szksg, ha sznes monitorra rt jtkot monokrm monitorral rendelkez gpen akarunk futtatni. Azok a sznek ugyanis, amelyek nem tartalmaznak zld sznsszetevt, ezeken a monitorokon nem ltszdnak. Az eljrs egyszeren meghvja a BIOS 10h sorszm megszaktst, a megfelel paramterekkel.

8.6. HidePal eljrs: sznek egybemossa


Szintaxis: HidePal(Speed: word; First, Last, R, G, B: byte); A First s a Last paramterek ltal meghatrozott szntartomny szneit fokozatos tmenettel azonos sznv varzsolja. Ennek a sznnek az sszetevit adjuk meg az utols hrom paramterben (R, G, B). Ha ezek mindegyike 0, a kp fokozatosan, de egyenletesen elsttl, fekete lesz. A folyamat sebessgt az els paramterrel szablyozhatjuk, ami valjban nem a sebessg nagysgt, hanem a ksleltetsi idt tartalmazza. Ha ez nulla, akkor lesz a leggyorsabb, s ha nveljk ezt a szmot, a sebessg cskken, lassabban tnik el a kp. Fontos azt megjegyezni, hogy az eljrs vgrehajtsa alatt a program ll, nem lehet irnytani vagy ms

92

eljrsokat meghvni. A vezrls csak a sznek egybemossa utn kerl vissza a fprogramhoz. Az aktulis sznsszetevket az eljrs eltrolja a Colors globlis vltozba, hogy a ShowPal eljrs vissza tudja ket lltani. A HidePal eljrst pldul a jtk vgn vagy a fhs hallnl alkalmazzuk. Prjval, a ShowPal eljrssal szp kpvltsokat valsthatunk meg: pldul ha a jtk fszereplje tmegy az egyik szobbl a msikba, kilpskor elsttl a kp, ezutn trajzoljuk a htteret (ha trkpet hasznlunk, akkor a NewPos eljrssal), s jra kivilgostjuk a ShowPal eljrssal, csak most mr a kvetkez szoba lesz lthat. Megjegyzs: a HidePal nem mdostja a 0. sznt, mert az nem szp. Ha 0 szn, de fekete kppontokat tartalmaz a kperny, akkor a HidePal eljrs utols hrom paramtere legyen mindig 0, mert ha ettl eltr, akkor a keletkezett egyszn kp fekete pontokat tartalmaz. Legegyszerbb a problma megoldsa akkor, ha a 0. szn fekete, azaz sszetevi: 0-0-0, s ezt a sznt nem hasznljuk a grafika pixeleihez.

8.7. InitGame eljrs: az egysg inicializlsa


Szintaxis: InitGame; Inicializlja a Game unitot, lefoglalja a httrhez s a munkaterlethez szksges 264000 bjtot, bekapcsolja az MCGA zemmdot, a BackColor vltozban megadott sznre festi a htteret. Mieltt elkezdjk hasznlni a Game egysg eljrsait, fggvnyeit, meg kell hvni az InitGame eljrst. Azonban gyeljnk arra, hogy egy programban csak egyszer szerepeljen, a Pascal memriakezelsbeli tkletlensge miatt. Ha egy jtk kzben valamirt tvltunk egy msik VGA zemmdba, semmikpp se hasznljuk az InitGame-et az MCGA mdba val visszatrshez, alkalmazzuk helyette inkbb a kvetkez assembly-sorokat: asm mov ax,13h int 10h end; vagy az MCGA egysg (6.1.) zemmd-bellt eljrst: SetMode($13); A Game egysg hasznlatt az InitGame eljrs nyitja, s a DoneGame eljrs zrja, mkdsk teht hasonlt a Graph unit InitGraph s CloseGraph eljrsaihoz. Ha gy indtjuk el pldul a MakeScr eljrst, hogy eltte nem hvtuk meg az InitGame-et, az lefagyshoz vezet, teht nagyon fontos minden Game unitot hasznl jtkprogram elejre berni egy InitGame; sort. Ajnlatos mindjrt ezzel kezdeni a programot.

8.8. InitKey eljrs: mdostott billentyzetmegszakts


Szintaxis: InitKey; Bekapcsolja a mdostott billentyzetmegszaktst, vagyis a $09 megszaktsvektort egy sajt eljrsra irnytja, a NewIRQ-ra. Ez a programrsz megegyezik a 3.1. fejezetben lert s a lemezmellkleten megtallhat KEYB3.PAS pldaprogram NewIRQ elnevezs eljrsval. Kzvetlenl nem rhet el (a unit implementcis rszben van), de nincs is r szksg. Ha meghvjuk az InitKey-t, azontl a billentyk llapotrl a Key logikai tmbbl kaphatunk informcit. Ez a tmb 256 elem, a unit Interface rszben lett deklarlva, a kvetkezkppen: var Key: array [0..255] of boolean; . Mindegyik billentyhz tartozik egy szm (egy SCAN-kd), ha lenyomunk egy billentyt a hozz tartoz Key elem igazra (true) vlt, ha nincs lenyomva, a vltoz rtke hamis (false). Hogy melyik billentyhz melyik Keyelem tartozik, a 3.1. rsz vgn tallhatjuk meg (kzvetlenl a 3.2. fejezet kezdete eltt), s a lemezmellklet SCANCODE.TXT fjljban. Az eredeti megszaktst a DoneKey eljrssal llthatjuk vissza. Ha ezt programunk vgn elmulasztjuk, az hatatlanul lefagyshoz vezet. A mdostott megszakts mellett ne hasznljuk a Crt unit billentyzetkezel fggvnyeit (ReadKey s KeyPressed), mert ez szintn a rendszer azonnali munkabeszntetst vonja maga utn. Helyettk inkbb e unit _ReadKey ill. _KeyPressed fggvnyeit alkalmazzuk.

93

8.9. LoadLBM eljrs: kp betltse


Szintaxis: LoadLBM(FileName: String; P: pointer); Egy LBM kp betltsre szolgl. A FileName paramterben adjuk meg az LBM-fjl nevt, elrsi tvonallal, ha szksges, a P paramterben pedig a clcmet, annak a tartomnynak a kezdcmt, ahov az LBM kp kerl. Ha ez a httr kezdcme (Background), akkor a lemezen tallhat LBM formtumban trolt kpet jtkunk httereknt jelenthetjk meg, de megadhatjuk msodik paramternek a kpernyt is: PTR($A000,0), ekkor a kp rgtn megjelenik, ami pldul kezdkpek kirajzolsra alkalmas. A LoadLBM eljrs egyben betlti a paramterben megadott fjlban tartalmaz palettt is. A forrskdja megegyezik a 4.1. fejezetben tallhat programszveggel. gyelni kell arra, hogy a fjlban trolt kp 256 szn s 320 pixel szlessg legyen, mert az eljrs nem ellenrzi ezeket az rtkeket

8.10. LoadMap eljrs: trkp betltse


Szintaxis: LoadMap(FileName: string); Paramterknt azt a fjlt kell megadni, ami a trkpet trolja, kiterjesztse ltalban .MAP. A trkpszerkezetrl rszletesebben a 4.2. fejezetben olvashatunk, a trkpszerkeszt segdprogrammal (MAPEditor) pedig a 7. fejezet foglalkozik. A MAP-Editorral ksztett s elmentett trkpek betltsre alkalmas ez az eljrs, a fjl bjtjainak helyet foglal, s elhelyezi ket a memriban, hogy azok a DrawBox, NewPos s Scroll eljrsok szmra hozzfrhetk legyenek. Az eljrs hatsra az albbi vltozk kapnak rtket: Vltoz BoxPtr MapPtr BPL MapLength Mask Tpus pointer pointer word word tmb, 162 bjt Tartalom BOX grafikus adatainak kezdcme. Trkp kezdcme. Egy trkpsorban lv dobozok szma (Boxs Per Line). Trkp hossza bjtban, dobozainak szma (1 bjt1 doboz). BOB-BOX tkzsi vz.

Egy programban ltalban csak egyszer alkalmazhat a LoadMap eljrs, mivel a lefoglalt memrit nem szabadtja fl, gy hamar betelik a rendelkezsre ll szabad heap. Ha mgis j trkpet szeretnnk a rgi helybe tlteni, azt megtehetjk elvileg az albbi mdon. Ez azonban a gyakorlatban nem alkalmazhat, mert a Turbo Pascal memriakezelse nem tkletes. freemem( MapPtr, MapLength); freemem( BoxPtr, 16384); { 256 db 88-as BOX helyignye 16384 bjt } LoadMap( 'UJFILE.MAP'); Vgezetl nzzk meg mg egyszer, hogyan pl fel egy MAP fjl. A msik megolds arra, hogy egy programon bell tbb trkpet is megjelenthessnk, az lehet, hogy runk egy sajt trkpbetlt eljrst. Ehhez nyjt segtsget az albbi tblzat. Cm 0. 1. 3. 5. 16389. vgl Hossz 1 2 2 16384 [3.] 32 Tartalom Verziszm. Ez ellenrzsre is felhasznlhat, ha rtke nem 1, biztos, hogy nem MAP-Editorral ksztett trkppel van dolgunk. Egy sorban tallhat dobozok szma (trkp szlessge), a BPL vltozba kell tlteni. Trkp hossza (bjtban vett helyfoglalsa), MapLength vltoz. BOX adatok, sorrendben, sorfolytonosan (BoxPTR). Trkpadatok, sorfolytonosan (MapPTR). Maszk, tkzsi vz. Minden bit egy BOX-hoz tartozik (Mask).

8.11. LoadPal eljrs: paletta betltse


Szintaxis: LoadPal(FileName: string); Betlt s megjelent egy lemezen trolt palettt. Egyetlen paramterben annak a fjlnak a nevt (elrsi tvonallal, ha kell) adjuk meg, ami a paletta sznsszetevinek adatait tartalmazza. ltalban .PAL a kiterjesztse. Legalbb 768 bjt hosszsgnak kell lennie, mert 256 szn van, s minden szn hrom sznsszetevjt 1-1 bjt hatrozza meg. A BOB-Editorral (6. fejezet) s a MAP-Editorral (7. fejezet) kszthetnk ilyen palettafjlokat. Felptsnek elve a kvetkez:

94

Cm 1. 2. 3. 4. 768.

Tartalom 0. szn vrs (Red) sszetevje. 0. szn zld (Green) komponense. 0. szn kk (Blue) alkoteleme. 1. szn vrs sszetevje. 255. szn kk sszetev.

8.12. MakeScr eljrs: megjelents elksztse


Szintaxis: MakeScr; A munkaterleten (WorkArea) sszelltja a megjelentend kpet, ezt mr csak t kell msolni a kpmemriba, a ShowScr eljrssal. A megjelents elve nagyban hasonlt a 2.5. rsz ShowBOB eljrsnak elvhez. A MakeScr ugyanazt vgzi el, mint a ShowBOB az els kt lpsben, azaz letakartja a munkaterletrl a BOB-okat (fellrja azt a httrrel), s kirakja ket jra, de most mr ms helyre, ha koordintik megvltoztak. Megjegyzs: az els lpsben az egsz htteret trja a rep movsw segtsgvel. Ez alapllapotban 32000 sz mozgatst jelenti, ami meglehetsen idignyes. Azonban mindenkpp szksg van r a tetszlegesen vltoz httr miatt, brmikor kirajzolhatunk egy pontot a httrre a PixelBack eljrssal, s a grgetshez is elengedhetetlen a szabad httr. Ha tl lass a gpnk (80 MHz alatt), vagy tl sok a memriarezidens program, melyek srn szaktjk meg a futst, valahogy gyorstani kell az eljrson. Pldul cskkenthetjk a kp mrett a SetArea eljrssal (8.17. rsz), gy a ciklusonknti trand terletek nagysga is cskken. Nehezebb megvalstani, hogy egy j MakeScr eljrst runk. Alapjt a 2.3. fejezet ShowBOB eljrs szolgltathatja, de termszetesen ki kell egszteni a 2.4-5. rszekben megismert lehetsgekkel (tetszleges mret, animci stb.). A vltoztathat httrrel szaktanunk kell, hiszen a httrnek csak a BOB-ok ltal takart rszt rjuk vissza a munkaterletre, ez a sebessgnvekeds lnyege. Joggal krdezhetjk, hogy mirt kellett a megjelent eljrst kt rszre (MakeScr s ShowScr) bontani. A vlasz egyrtelm: mert gy tbb elnye van, mint htrnya. Htrnya csupn annyi, hogy ktszer kell eljrst meghvni a mvelet vgrehajtshoz. Elnye pedig, hogy a ksz munkaterletre rhatunk, gy az sszes grafikai elem fl helyezhetnk httrelemeket, adatokat, bekeretezhetjk az egsz kpet, s a grgets a kereten bell folyik stb. Kirhatjuk akr kzpre is, hogy hny pontot rt el a jtkos, s hogy hny lete van mg. Csak sajnos egy ilyen munkaterletre r eljrs elksztsrl az Olvasnak kell gondoskodnia. Alapul az MCGA egysg OutText eljrsa szolglhat, melynek lersa a 6.1.1. fejezetben tallhat meg. Nem is kell benne sokat vltoztatni csak annyit, hogy a clcm ne a kperny, hanem a munkaterlet legyen.

8.13. NewPos eljrs: ugrs a trkpen


Szintaxis: NewPos(X, Y: word); A httr bal fels sarkt a trkp (X;Y) koordintj pontjba lltja. Meg is jelenti a httren a trkprszletet, gy az eljrs meghvsa utn a httr mr a trkp visszafejtett pixeleit tartalmazza. Az eljrs paramtereinek megfelelen lltja be a PosX s PosY trkpkoordinta-jelz vltozkat. Ha csupn ennek a kt vltoznak az rtkt vltoztatjuk, a httr mg vltozatlan marad. Ezrt minden trkpet hasznl program elejn, a trkp betltse utn hvjuk meg ezt az eljrst, ha azt szeretnnk, hogy a trkp rgtn lthat legyen. nmagban grgetsre nem alkalmas, mert tl lass, a trkp kis lpsenknti mozgatsra a Scroll eljrst hasznljuk (8.16. rsz). Jl hasznlhat pldul akkor, ha a trkp szobkra van felosztva, s a fhs tmegy az egyik szobbl a msikba. Ez gyorsabb s kevesebb helyet ignyel, mint az LBM-es mdszer.

8.14. PixelBack eljrs: httrpont megvltoztatsa


Szintaxis: PixelBack(X, Y: word; C: byte); A httr egy bjtjt C-re vltoztatja. A BackGround vltozban trolt cm utni 320Y+X. bjtot lltja t. Hasonlt a lemezmellklet PUTPIXEL.PAS programjban tallhat PutPixel eljrshoz (1.2. fejezet), csak a clcm nem a kperny ($A000:0), hanem a httr (BackGround). Tartomnyvizsglat nincs, ezrt vigyzzunk, hogy az X s Y paramterek ltal meghatrozott bjt ne essen a httren kvlre (biztos nem lesz baj, ha 320Y+X<64000).

95

Folyamatosan vltoz httr megvalstshoz hasznlhat fel ez az eljrs, de gyeljnk arra, hogy nagy vltozsok jelentsen lassthatjk a program futst. Erre is van megolds: gy kell sszelltani a httr pontjait, hogy palettamdostssal animcit lehessen elidzni.

8.15. RetRace eljrs: vrakozs vertiklis visszafutsra


Szintaxis: RetRace; Felfggeszti a program futst mindaddig, amg az elektronsugr a kp als sarkba nem r. Ha kzvetlenl a ShowScr eljrs eltt hvjuk meg, programunk szp s egyenletes lesz, igaz, egy kicsit lassabb is. Ha minden megjelents eltt meghvjuk, kikszbljk az abbl ered problmt, hogy a gpek klnbz sebessgek. Ha nagyon gyors egy gp, elvileg nagyon gyors lenne a jtk is, viszont minden ciklusban vrakoznia kell a RetRace eljrs miatt. Ezrt a program sebessge nem a gptl, hanem a videokrtytl fgg, a kpvltsi frekvencitl. Szerencsre ez nagyjbl lland (60-70 Hz). Ha tl lass a gpnk (kb. 80 MHz alatt), elfordulhat, hogy az elektronsugr beri a memriba rst, mivel egy ciklusban nagyon sok adatot kell tmozgatni (lt. 232000 sz). Ez szintn darabossghoz vezet, radsul sokkal zavarbb, mint ha a RetRace eljrst nem alkalmaznnk, mivel a trsvonal nagyjbl lland helyen lesz. Az elektronsugrrl rszletesebben az 1.4. fejezetben olvashatunk. Az ott tallhat RetRace eljrs megegyezik a Game unit elektronsugr-figyel eljrsval. A $3da regiszterrl beolvasott bjtnak jobbrl a negyedik bitje 1, ha az elektronsugr vertiklisan visszafut, egybknt 0. Ezt a bitet figyeli az eljrs.

8.16. Scroll eljrs: trkp grdtse


Szintaxis: Scroll(Dir: byte; Count: word); A trkpet kis lpssel mozdtja el, ha tbbszr meghvjuk egyms utn (mondjuk, egy cikluson bell), folyamatosan grdti a htteret. Els paramterben adjuk meg az irnyt, msodikban pedig az elmozduls mrtkt, pixelben. Az irny megadst a kvetkez konstansok segtik: Up = 8; { Fel } Down = 2; { Le } Left = 4; { Balra } Right = 6; { Jobbra } (Az egyes szmokhoz tartoz irnyt a numerikus billentyzetrl is leolvashatjuk. Ha a nyllal megjellt billentykn tallhat szmot rjuk az eljrs els paramterbe, akkor a trkp a nyl irnyban mozdul el.) A Scroll eljrs egyesti a 4.6. fejezetben trgyalt ngy eljrst. A PosX s PosY trkp-koordintkat jelz vltozkat megvltoztatja, azonban a kt vltoz rtknek mdostsa nem elg ahhoz, hogy a httren is megjelenjenek a vltozsok. Az eljrs meghvsa jelentsen lasstja a program futst, mivel a httr tartalmt, annak az sszes bjtjt tmozgatja. Szp, egyenletes grdtshez legalbb 80-90 MHz-es gp kell, ez alatt ugyanis a mozgs darabos. Hogy valjban mit jelent a grgets, az bra segt megrteni. Itt ppen jobbra grdl a httr, teht a trkp hozz viszonytva balra mozdul el, ezrt els paramterknt a Left konstanst kell megadni. Trkp Httr Httr elmozdulsnak irnya

Trkp elmozdulsnak irnya

Egy megjelents sorn a trkpnek a kisebbik tglalapba (httr) es rsze lesz lthat. A gyakorlatban ez ebben az esetben gy oldhat meg a leggyorsabban, hogy a httr minden pixelt balra toljuk eggyel (az els oszlopot termszetesen nem), s a jobboldalt felszabadul oszlopba visszafejtjk a tmrtett trkpadatokat.

96

Ez az eljrs csak ngy irnyban tud grgetni. tls mozgats az eljrs egyms utn ktszeri meghvsval valsthat meg, de ez tl lass, a program sebessge ebben az esetben a felre cskken. Gyors gpeknl termszetesen ez nem problma, viszont lass gpekre az tls irny grdts kifejlesztse mr az Olvas feladata. A MAP-kpszerkezetrl s a grdtsrl rszletesebben a 4.2-7. rszekben olvashatunk.

8.17. SetArea eljrs: kp magassga


Szintaxis: SetArea(Fst, Lst: word); A megjelen kp fggleges mrett, vagyis annak kezd s zr sort llthatjuk ezzel az eljrssal. Ebbl kvetkezik, hogy a httr s a munkaterlet mrete is vltozhat, gy cskkenthetjk a ciklusonknti tmozdtand bjtok szmt. Az eljrs els paramterben adjuk meg az els olyan kpernysort, amire a ShowScr eljrs r, a msodikban pedig az utolst. rtelemszeren az els paramter nem nagyobb a msodiknl. rtkknek a kperny-koordintknak megfelelen a [0..199] intervallumba kell esnik. Teljes kpernys mdhoz hasznljuk a (0, 199) szmprt. Sok elnye van annak, ha jtkunk nem az egsz kpernyt hasznlja, hanem annak csak egy vzszintes svjt. A jtkkp felett s alatt elhelyezked terletet a ShowScr eljrs nem mdostja, ide brmit rhatunk, az vltozatlan marad. Teht felhasznlhatjuk ezt a rszt pldul dekorcira, de az llapot megjelentsre is alkalmas (pontszm, energia, id stb. ehhez ajnljuk az MCGA unit OutText eljrst, 6.1.1. rsz). Msrszt ha cskkentjk a kp mrett, nvekszik a jtk sebessge, mivel egy cikluson bell egy sor cskkentse utn 2160 szval kevesebb adat kerl tmozgatsra. A kp magassgnak cskkentse semmilyen kvetkezmnyt nem okoz, a BOB-ok nem sznak ki a jtktren kvli rszre, teljesen olyan mintha magt a kpernyt szktennk. Ha az els paramter nem nulla, a koordinta-rendszer egy kicsit megvltozik. Kezdpontja nem egyezik meg a kperny kezdpontjval, hanem annl lejjebb lesz. De ez csak annyiban jelenthet problmt, hogy nehezebb a kperny koordinta-rendszerhez viszonytani. A kvetkez bra bemutatja egy BOB kperny-koordintinak meghatrozst: Kperny: (0; 0) Jtktr: (0; FST) BOB (X;Y+FST) Utols sor (LST) Els sor (FST)

A Game unit s a knyv els felben tallhat eljrsok kzti klnbsgnek oka ez a vltoztathat jtkkpmagassg. Pldul a ShowScr eljrsban nem szabad mindig 32000 szt megjelenteni, mert ez mindjrt a felre cskken pldul egy SetArea(0, 99); utastssal. A paramterknt megadott vltozk ksbb visszaolvashatk a First s a Last globlis vltozkbl. Ezek vltoztatsval a jtkkp magassga nem llthat, ezeket a vltozkat inkbb csak olvassra hasznljuk.

8.18. SetRGB eljrs: sznsszetevk vltoztatsa


Szintaxis: SetRGB(ColNum, R, G, B: byte); Az eljrs mkdst tekintve teljes egszben megegyezik a Graph egysg SetRGBPalette eljrsval. Az els paramterben megadott szn sszetevit llthatjuk be vele. Az R, G, B paramterek hatrozzk meg a vrs, zld s kk sznsszetevket. Ezeknek rtke legfeljebb 63 lehet, ha ennl nagyobb, akkor csak az als 6 bit szmt. Az eljrs felhasznlhat pl. egyni palettabetltsre vagy elstttsre. A palettrl rszletesebben az 1.6. fejezetben olvashatunk.

97

8.19. ShowPal eljrs: kivilgosts


Szintaxis: ShowPal(Speed: word; First, Last: byte); Az eljrs els megkzeltsben a HidePal (8.6.) eljrssal eltntetett palettt jelenti meg ismt. A megjelents sebessge kerl az els paramterbe, ami valjban nem sebessg, hanem ksleltetsi id (ha ez 0, akkor a leggyorsabb). Az utols kt paramter azt a szntartomnyt hatrozza meg, amelynek sznei megvltoznak, ezek rtke ltalban 1 s 255. A msodik paramter nem lehet nagyobb a harmadiknl. Ez az eljrs azonban nemcsak a HidePal eljrssal egybemosott paletta lass visszalltsra szolgl, hanem kt paletta szp, lineris vltsa is megoldhat vele. A rgi palettt a VGA krtya regiszterei tartalmazzk, pldul a LoadPal (8.11.) eljrssal lehet ezt megvalstani. Az j paletta pedig a Colors vltoz bjtjaiban foglal helyet, melynek deklarcija: type RGBType = record Red, Green, Blue: byte; end; var Colors: array [0..255] of RGBType; Ha az j palettt elhelyeztk a Colors vltozba az albbi utastssal tudjuk linerisan megjelenteni. (Lassts vgett rjunk az els paramterbe nagyobb szmot!) ShowPal( 0, 1, 255); A kzps paramter lehet nulla is, de ez hatstalan, mert sem a HidePal, sem a ShowPal nem vltoztatja a keret sznt s a 0 szn kppontokat, mert az nem lenne szp. ppen ezrt a 0. szn legyen mindig fekete, s lehetleg ne hasznljuk fel a grafikhoz. Lassan eltntethet brmelyik paletta a HidePal eljrssal, lass megjelentsre mutat be egy pldt az albbi program. {palette.pas} uses Crt, Game; var f: file; i: word;

{ Vltoz a paletta betltshez { A FOR ciklusokhoz

} }

begin assign( f, 'default.pal'); reset( f, 1); blockread( f, Colors, 768); { Paletta beolvassa - mg nem lthat close( f); asm mov ax,13h int 10h { MCGA zemmd bekapcsolsa end; for i:= 0 to 255 do SetRGB( i, 0, 0, 0); { Minden szn fekete randomize; for i:= 0 to 64000 do mem[$a000:i]:= random( 256); { Kperny vletlenszer feltltse ShowPal( 100, 1, 255); { Paletta lass megjelentse ReadKey; asm mov ax,3 int 10h { Szveges md end; end.

} } } }

98

8.20. ShowScr eljrs: megjelents


Szintaxis: ShowScr; Megjelenti a munkaterletet, amit elzleg a MakeScr (8.12. rsz) eljrssal lltottunk ssze, vagyis a munkaterlet bjtjait a kpernyre msolja. A unitban ez az egyetlen kpernyre r eljrs. A MakeScr; RetRace; ShowScr; eljrsok lnyegben ugyanazt hajtjk vgre, mint a 2.5. fejezetben s a SHOWBOB5.PAS pldaprogramban megtallhat ShowBOB eljrs. Arrl, hogy mirt elnysebb gy hrom rszletben, a 8.12. rszben olvashatunk. A szp, egyenletes megjelents rdekben minden ShowScr eltt kzvetlenl hvjuk meg a RetRace eljrst!

8.21. _KeyPressed fggvny: billentyzet figyelse


Szintaxis: _KeyPressed: Boolean; rtke akkor igaz, ha van legalbb egy lenyomott billenty. A Crt unit KeyPressed fggvnyt helyettesti a mdostott billentyzet-megszakts mkdse alatt. Csak az InitKey eljrs meghvsa utn s a DoneKey eltt alkalmazhat. Ha ekkor a Crt-fle KeyPressed fggvnnyel vizsglnnk a billentyzetet, gpnk lefagyna.

8.22. _ReadKey fggvny: SCAN-kd beolvassa


Szintaxis: _ReadKey: byte; Vrakozik addig, amg le nem nyomunk egy billentyt. Ha ezt megtettk, a lenyomott billenty SCANkdjval tr vissza. A Crt unit ReadKey fggvnyt helyettesti a mdostott megszakts mellett. A programot {$X+} direktvval fordtva hasznlhat egyszer vrakozsra, ha eljrsknt hvjuk meg a fggvnyt, a program addig vr, amg le nem nyomunk egy billentyt, s futsa csak akkor folytatdik, ha jra felengedtk.

8.23. A BOB objektumtpus


A BOB-okhoz kapcsold vltozkat s szubrutinokat a Game uniton bell egy kln egysgbe foglaltuk, a BOB tpusba, amely egy objektum. Ez sok szempontbl elnys. Minden BOB-nak kln nevet adhatunk, nem szksges ket egy tmbben trolni, szabadon kezelhetk, s az objektumok rkt lehetsge rvn tetszlegesen bvthetk. Ezenkvl ttekinthetbb teszi a programot. Mieltt elkezdennk a BOB tpus mezit s metdusait trgyalni, nzznk egy rvid pldaprogramot, amely betlti s megjelenti az egyik lemezmellkleten tallhat fjlban trolt BOB-ot. Mr ebbl is lthatjuk, milyen egyszer a unit kezelse. {loadbob.pas} uses Crt, Game; var Nap: BOB; begin InitGame; with Nap do begin Load('napocska.bob'); X:= 10; Y:= 10; end; MakeScr; ShowScr; readkey; DoneGame; end.

{ A BOB azonostja 'nap' lesz { { { { { { { { GAME egysg inicializlsa A BOB-bal kapcsolatos mveletek BOB inicializlsa, Shape betltse Koordintk belltsa Megjelents elksztse Megjelents Vrakozs egy billentyre Egysg lezrsa

} } } } } } } } }

99

A BOB objektumban tallhatk meg tbbek kztt az tkzseket vizsgl fggvnyek, a Shape betltse eljrs, a mreteket, koordintkat jelz vltozk stb. Ezeket foglaljuk ssze ebben a rszben, elszr a BOB metdusait, majd mezit, teht fordtva, mint ahogy egy objektumot deklarlunk. A BOB tpus nem tartalmaz privt mezket vagy metdusokat, gy az sszes eleme tetszlegesen hozzfrhet, brmikor olvashat vagy megvltoztathat.

8.23.1. Collision fggvny: tkzs BOB-bal


Szintaxis: Collision(var B: BOB): boolean; Teljes egszben megegyezik az 5.2. fejezetben tallhat CollBob fggvnnyel. rtke akkor igaz, ha a BOB tkzik a fggvny paramterben megadott BOB-bal. Ez az tkzs valsgos tkzs, teht csak akkor kapunk true rtket eredmnyl, ha a vizsglt kt BOB-nak legalbb egy-egy pixele rintkezik. Ha csak terletknek van kzs rsze, de nem nulla rtk pixeleik nem fedik egymst, a fggvnyrtk false lesz. Errl rszletesebben az 5.1-2. rszekben olvashatunk. Nzznk egy rvid pldt kt BOB tkzsnek vizsglatra! Itt lthatjuk, hogyan kell BOB-ot ltrehozni, s hogyan kell kezelni a BOB tpus metdusait. Ha a fggvnyben felcserljk az A s B bett, ugyanazt az eredmnyt kapjuk. uses Game; var A, B: BOB; begin if A.Collision( B) then ... end.

{ A kt BOB azonostja: A, ill. B { Ha A tkzik B-vel, akkor ...

} }

Ha X egy aktv BOB azonostja, akkor X.Collision( X) mindig igaz (nmagval mindig rintkezik). Ha a vizsglt BOB-ok valamelyike nem lthat, vagyis az A aktivitsjelz mezjnek rtke false, akkor a fggvny visszatrsi rtke is mindenkpp false.

8.23.2. CollBack fggvny: tkzs httrrel


Szintaxis: CollBack: boolean; Ha a BOB a httren van, s legalbb egy pontja olyan httrpontot fed, amelynek szne klnbzik a BackColor vltozban megadott szntl, a fggvny visszatrsi rtke igaz, true, vagyis a BOB rintkezik a httrrel. Ez esetben a BackColor globlis, 0 kezdrtkkel rendelkez bjt tpus vltozban adjuk meg a httr alapsznt. Ha a BOB nem nulla pontjai csak ilyen pixeleket rintenek, nincs tkzs. A fggvny nagyon hasonlt a CollColors fggvnyhez (8.23.4.), vele szemben az a htrnya, hogy a httr szabad rsze csak egyszn lehet (ez az a rsz, ahol a BOB szabadon mozoghat, tkzs nlkl).

8.23.3. CollBox fggvny: tkzs trkpegysggel


Szintaxis: CollBox: boolean; A Mask globlis tmb 32 bjt hossz, a LoadMap eljrssal tltdik fel, de rtkt brmikor megvltoztathatjuk. Mindegyik bitjhez egy BOX tartozik, egymsnak sorrendben megfeleltetve. Ha a BOB egy olyan BOX-szal rintkezik, amihez 1-es rtk bit tartozik, a fggvny true rtkkel tr vissza, egybknt az eredmny hamis, false lesz. Azt, hogy melyik BOX-hoz milyen bit tartozik, a trkp szerkesztsnl lehet megadni (Edit\Mask menpont, 7.3.2. rsz vge). A fggvny alkalmazsval a jtkteret megnvelhetjk. Ha csak a CollBack s a CollColors fggvnyekkel vizsgljuk a BOB-httr tkzst, a jtktr a kpernyn is lthat legfeljebb 320200 pixel nagysg terlet. Ezzel szemben a CollBox-szal a jtk az egsz trkp terletre kiterjedhet. Annyit kell csupn tenni, hogy az olyan BOX-okhoz, aminek nem szabad nekimenni (pl. fa, fal, hz), 1-et rendelnk a maszkban, a szabad BOX-okhoz (pl. f, t) pedig 0-t.

100

8.23.4. CollColors fggvny: tkzs httrrel


Szintaxis: CollColors: boolean; Akkor igaz, ha a httr egy meghatrozott szntartomnyon kvl es szn pontjaival tkzik a BOB. Ezt a szntartomnyt a CFirst s CLast globlis vltozk hatrozzk meg, kezdrtke mindkettnek nulla, tpusuk pedig bjt. Ha teht a BOB minden nem tltsz pontja csak olyan httrpontokkal rintkezik, melyeknek szne beleesik ebbe a tartomnyba, a CollColors fggvny rtke false, ekkor nincs tkzs. Ez a CollBack fggvny tovbbfejlesztett vltozata. Ott csak egyszn lehetett az a rsz, ahol a BOB szabadon mozoghat, itt viszont brmennyi lehet e terlet szneinek szma. Csak az a fontos, hogy ezeknek a szneknek egyms utn kell kvetkeznik, s erre mr a grafika megszerkesztsnl is gyelni kell. Minderrl rszletesebben az 5.3. fejezetben olvashatunk.

8.23.5. Copy eljrs: BOB msolsa


Szintaxis: Copy(var B: BOB); Az eljrs a paramterben megadott BOB vltoz mezrtkeit vltoztats nlkl tmsolja a sajt mezibe. Ezeltt inicializlja a BOB-ot, vagyis meghvja az Init metdust. A Copy eljrst akkor hasznljuk, ha sok azonos mintj BOB-ot szeretnnk ltrehozni. Helyfoglals szempontjbl nem lenne ugyanis elnys, hogy mindegyik Shape-hez kln helyet foglalunk le, hiszen ugyanolyanok. Ekkor csak egynek foglalunk helyet (a Load, betlt metdussal), s a tbbinek adatait ehhez igaztjuk a Copy segtsgvel. Ezek utn mr teljesen kln kezelhet valahny BOB. A kvetkez sorok bemutatjk hasznlatt: uses Game; var B: array [00..99] of BOB; { Itt vannak a BOB-ok, most tmbben i: byte; { Vltoz a FOR ciklushoz begin B[00].Load('valami.bob'); { { { for i:= 01 to 99 do B[i].Copy( B[00]); { ... end. Az els BOB-hoz meghatrozzuk a Shape-et, a tbbit pedig errl lemsoljuk

} } } } } }

Ezek utn a B tmb 100 db egyforma BOB-ot tartalmaz, s nem kellett mind a 100-szor memrit lefoglalni, csupn egyszer, a B[00].Load... metdussal. Ezenkvl az sszes BOB-ot inicializltuk, mert a Copy meghvja ezt a metdust is, neknk nem kell ezzel trdni. (Hogy az inicializls, az Init meghvsa mirt fontos, lsd lejjebb, az eljrs lersnl, a 8.23.6. rszben.)

8.23.6. Init eljrs: inicializls


Szintaxis: Init; Ha BOB tpus vltozkat deklarlunk, azok a memriban szanaszt helyezkednek el. A megjelentend kpet sszellt MakeScr eljrsnak (8.12.) nehz dolga lenne. ssze kellene szednie az sszes BOB-ot, ami lehetetlen feladat, ha nincsenek rendszerezve. Ezrt a Game unit implementcis rszben tallhat egy olyan tmb, ami rendszerezi a BOB-okat, miutn meghvjuk az Init metdust, a tmb egy eleme a BOB-ra mutat, gy a MakeScr-ben knnyen kikereshet, melyik BOB hol tallhat. Ebbl az is kvetkezik, hogy nem hozhatunk ltre akrhny BOB-ot, mivel a tmbnek kell hogy legyen egy fels hatra. Ez a hatr 512. Ennl tbb BOB-ot nem deklarlhatunk, csak akkor, ha a unit implementcis rszben tallhat MaxBOB konstans rtkt nveljk.

101

A Load s Copy eljrsok automatikusan meghvjk az Init metdust, teht ha ltalnos mdszerrel adjuk meg a BOB-adatokat (betltjk vagy lemsoljuk), akkor az inicializlssal nem kell trdnnk. Mg annyit jegyezznk meg, hogy nem rdemes ktszer meghvni ezt az eljrst, mert akkor a BOB ktszer szerepel a listn, s grafikus adatai ktszer lesznek kimsolva egy-egy megjelents sorn, ami lasstja a program futst. Egybknt ms kvetkezmnye nem lesz.

8.23.7. Load eljrs: Shape betltse


Szintaxis: Load(FileName: string); Inicializlja a BOB-ot, s betlti a paramterben megadott fjlt. Az eljrs meghvsa utn majdnem minden mez rtket kap (a koordintk nem). A memriba kerl a Shape is, aminek kezdcmt a DT mez trolja. Ha az eljrst meghvjuk s a koordintkat belltjuk, a MakeScr; ShowScr; eljrsprral vagy a Put metdussal (8.23.9.) a BOB mr meg is jelenthet. Ezzel az eljrssal a BOB-Editorral (6. fejezet) ksztett BOB-okat tlthetjk be. Az editorral ellltott fjlok felptse a kvetkez: Cm 00 01 03 05 07 Hossz 1 2 2 2 Tartalom A BOB verziszma, rtke 1. Shape szlessge (a valdi szlessg ennl 1-gyel nagyobb). Shape magassg (a valdi magassg ennl 1-gyel nagyobb). Fzisok szma. Ha ez nulla, akkor a BOB egyfzis. Grafikus adatok.

8.23.8. OnScreen fggvny: lthatsg vizsglata


Szintaxis: OnScreen: boolean; Ha a BOB aktv, s legalbb egy pontja rajta van a httren gy megjelents utn a kpernyn is akkor a fggvny visszatrsi rtke true, egybknt false. Mindez a BOB A (aktivitsjelz) mezje s koordinti alapjn dl el.

8.23.9. Put eljrs: kpernyre rajzols


Szintaxis: Put(XX, YY, PP: word; ShowBack: Boolean); Az eljrs egybl a kpernyre rajzolja a BOB-ot, minden kzbls lps nlkl. Els kt paramterben a koordintit kell megadni a kperny koordinta-rendszerhez igaztva (bal fels sarok 0;0). PP adja a megjelentend fzis szmt (0, ha az 1. fzis), az utols paramterben pedig azt adhatjuk meg, ltszdjon-e az, ami a BOB mgtt van, vagyis a BOB 0 szn pontjai tltszak legyenek-e. Akkor szksges pldul ez az eljrs, ha a Setarea eljrssal cskkentettk a jtkkp mrett, s az gy ltrejtt szabad terleten a fhs leteinek szmt magval a fhs grafikjval szeretnnk szemlltetni. Termszetesen ezenkvl mg sok helyen felhasznlhat, pldul a BOB-Editorral megrajzolt brkat dekorciknt alkalmazhatjuk.

8.23.10. ShowUpon eljrs: prioritsvltoztats


Szintaxis: ShowUpon(var B: BOB); Meghvsa utn a BOB biztos, hogy a paramterben megadott msik BOB felett lesz. Ez azt jelenti, hogy ha rintkeznek, akkor a B lesz takarsban. Mindig az a BOB van legfell, amelyet utoljra inicializltunk az Init, Load vagy Copy metdusok valamelyikvel. Ezen a sorrenden lehet vltoztatni a Showupon eljrssal.

102

8.23.11. A BOB tpus mezi


Itt tallhatk meg a BOB nem grafikus adatai (koordintk, fzisszm stb.). A grafikus adatok, a Shape bjtjai a heap-ben foglalnak helyet, mert dinamikus vltozknt troljuk ket. Kezdcmt a DT mez adja. Az albbiakban olyan sorrendben ismertetjk a BOB tpus mezit, ahogy deklarlva lettek, gy knnyen kiszmthat az elemek eltolsi cme. Mezkd A X Y LX LY P DT PL W H LN PN NR Tpus Eltols wordbool 0 integer integer word word word pointer word word word word word word 2 4 6 8 10 12 16 18 20 22 24 26 Tartalom Aktivitsjelz. Ha false, akkor a BOB nem lthat, akrhol van, s ilyenkor minden tkzsvizsglat eredmnye is false. Abszcissza. Ha 0, akkor a BOB a httr bal szln helyezkedik el. (Lehet 0nl kisebb is.) Ordinta. Ha 0, akkor a BOB a httr tetejvel egy vonalban van. rtke a BOB szlessgnl eggyel kevesebb (W-1). rtke a BOB magassgnl eggyel kevesebb (H-1). Fzisszmll, a kvetkez megjelentskor a kirajzoland fzis. Ha rtke 0, akkor az 1. fzis kerl kirajzolsra. Shape kezdcme. A Load metdussal kap rtket. Egy fzis hossza, bjtban. (A MakeScr eljrs hasznlja.) Szlessg pixelben. Magassg. Shape hossza bjtban. rtke az sszes fzisnl eggyel kevesebb. BOB sorszma.

Ha a fzisokat folyamatosan szeretnnk grgetni, gy, hogy az utols utn az els jjjn, ptsk be a megjelent ciklusba a kvetkez sort (B egy BOB tpus vltoz): inc( B.P); if B.P>B.PN then B.P:=0; Mivel az els mez wordbool s nem boolean tpus, az {$A+} direktvval a mezk szhatrra kerlnek. Ez valamennyire nvelheti a program sebessgt.

8.24. A Game unit konstansai s vltozi


A konstansok, vltozk mkdst mr lertuk, elszrva, mindig egy-egy szubrutin trgyalsnl. Most csak sszefoglaljuk s rendszerezzk ket. Hrom csoportba sorolhatk: konstansok, tipizlt konstansok, vltozk. sszesen ngy nem tipizlt konstans van, melyek a Scroll eljrs (8.16. rsz) paramterezst segtik. Ennek az eljrsnak az els paramterben adjuk meg ezeket az rtkeket, s a trkp az adott irnyban fog elmozdulni. const Up Down Left Right = = = = 8; 2; 4; 6; { { { { Fel Le Balra Jobbra } } } }

Tipizlt konstansbl, azaz kezdrtkkel rendelkez vltozbl csak hrom van. Ezek a BOB-httr tkzsvizsglathoz kellenek (8.23.2, 8.23.4.), meghatrozzk azokat a szneket, ahol a BOB-ok szabadon mozoghatnak, tkzs nlkl. const BackColor: CFirst: CLast: byte byte byte = 0; = 0; = 0; { Httr alapszne a CollBack-hez } { Szntartomny els s utols szne } { a CollColors metdushoz }

103

Vltozkbl mr jval tbb van, mint konstansokbl. Ezekhez rszletesebb magyarzatot is adunk, s bcrendben rjuk le ket. var BackGround: pointer; A httr kezdcme. Az InitGame meghvsa utn az eljrs ltal lefoglalt 64002 bjt nagysg terletre mutat. Ez az rtk akkor sem vltozik, ha a SetArea eljrssal cskkentjk a httr mrett. var BoxPtr: pointer; BOX-adatok kezdcme. A LoadMap eljrs meghvsa utn a BOX-ok grafikus adataira mutat. Ennek a dinamikus vltoznak a hossza 16384 bjt. 256 db 64 bjtos egysgre bonthat, melyek egy-egy 88-as doboz pontjait troljk. var BPL: word; Egy trkpsorban tallhat dobozok szma, azaz a trkp szlessge. A NewPos, a Scroll s nhny bels eljrs hasznlja. var Colors: array [0..255] of RGBType; Az RGBType tpus deklarcija a kvetkez: type RGBType = record Red, Green, Blue: byte; end; A Colors tmb trolja a ShowPal eljrs (8.19) szmra a megjelentend paletta szneinek sszetevit. rtket a HidePal eljrs ad elemeinek. var First: word; A kpernyn megjelen jtkkp els sora, a kperny bal fels sarkhoz viszonytva. Csak olvassra ajnljuk, vltoztatni a SetArea eljrssal lehet (8.17.). var key: array [0..255] of boolean; A billentyk informciit trolja, ha korbban meghvtuk az InitKey eljrst, de annak a DoneKey prjt mg nem futtattuk le. Mindegyik billentyhz hozz van rendelve egy szm, ha lenyomtuk, a billentyhz tartz sorszm Key-elem igazra vlt. Teht ez a tmb azt mutatja, hogy az adott sorszm billentyt lenyomtuk-e vagy sem. A hozzrendelsi tblzat a 3.1. fejezet vgn s a lemezmellklet SCANCODE.TXT fjljban tallhat. Ezt rdemes kinyomtatni. var Last: word; A kpernyn a jtktr utols sora. A First vltozhoz hasonlan szintn nem rdemes mdostani, csak a Setarea eljrssal (8.17.). var MapLength: word; A trkp hossza bjtban, dobozainak szma. A LoadMap eljrs meghvsval kap rtket. A trkp magassgt nem troljuk kln vltozban, ennek kiszmtsra a kvetkez egyszer kplet szolgl: trkp magassga = MapLenght/BPL var MapPtr: pointer; Trkp kezdcme. A LoadMap eljrssal a trkpnek lefoglalt terlet els bjtjra mutat. var Mask: array [0..31] of byte; BOB-BOX tkzsi vz. A BOB tpus CollBOX metdusa (8.23.3. rsz) hasznlja. sszesen 256 bitet tartalmaz, mindegyik bithez egy BOX tartozik. Ha a BOB 1-es jelzs BOX-szal rintkezik, a CollBOX fggvny visszatrsi rtke igaz lesz. tkzsi vzat a trkphez a MAP-Editorral szerkeszthetnk, az Edit men Mask funkcijnak kivlasztsval. A LoadMap eljrssal a trkphez tartoz maszk is betltdik.

104

var PosX, PosY: word; A trkp koordinti, pontosabban a httr pixelekben mrt vzszintes s fggleges eltolsa a trkp bal fels sarkhoz viszonytva. A Scroll s a NewPos eljrs vltoztatja meg rtkket. Ha mi rjuk t ket, megoldhat pldul a vgtelentett trkp: figyeljk, mikor r vget a trkp mondjuk balra grdtsnl, s ha ez bekvetkezett, a PosX vltozt 0-ra lltjuk. Ezutn mr a trkp eleje grg be, de a vge mg nem tnik el, hanem szp lassan kicsszik balra. var WorkArea: pointer; Munkaterlet kezdcme. A munkaterletnek az InitGame eljrssal foglalunk helyet. Ha ezt nem tettk meg, s gy indtjuk el a MakeScr eljrst, gpnk nagy valsznsggel lefagy, mivel ez az eljrs a munkaterletre r. Ezrt is nagyon fontos, hogy minden jtkban lehetleg minl elbb hvjuk meg az InitGame eljrst.

105

9. Pldajtk
Ebben a fejezetben a Game egysg hasznlatra lthatunk pldt. Annak elemeit az elz rszben mr megismertk, most tltetjk mindezt a gyakorlatba. A jtkot a lemezmellklet EXAMPLE knyvtrban tallhatjuk meg, lefordtott s eredeti llapotban egyarnt (EXAMPLE.EXE, EXAMPLE.PAS). Az EXE kiterjeszts fjlt rgtn le is futtathatjuk. A jtk meglehetsen primitv, egy hz faln kell felmsznia a fhsnek, kzben ki kell kerlnie a nyitott ablakokat, erklyeket s a potyog trgyakat (virgcserp, akvrium stb.). Ha egy ilyen zuhan trgy eltallja a fhst, az holtan esik al, s veszt egyet leteibl. A jtk lnyege: felmszni a hz tetejre. Taln elg egyszer ahhoz, hogy ne legyen megterhel mkdst megismerni. {example.pas} uses Crt, Game, MCGA, _System; A Game uniton kvl az MCGA s a _System unit eljrsait is hasznlja a program. Ezek a 6.1.1-2. rszekben lelhetk meg. (A _System unitbl csak az _Str fggvnyre van szksg, amit a magassg s az letek szmnak kirshoz hasznlunk.) const MaxFalls PalSpd Skill = = = 3; 10; 50;

A MaxFalls konstans rtke a lefel es trgyak szmnl eggyel kevesebb. Knnyen bvthetjk a program grafikjt, ha a BOB-Editorral terveznk egy zuhan objektumot, amit FALL4.BOB nven elmentnk, s nveljk a MaxFalls konstans rtkt. Ezutn a lefel es dolgok kzt ott lesz az ltalunk tervezett BOB is. A PalSpd konstans az elstttsek s kivilgostsok sebessgt adja, a HidePal s a ShowPal eljrsok els paramternek mindig ezt az rtket adjuk meg. Ha cskkentjk, n a palettavltoztats sebessge. Vgl a Skill konstans a zuhan trgyak gyakorisgt szablyozza. Ennyi kt szomszdos trgy ordintjnak tlagos klnbsge. PDly: Lives: Height: byte byte word = = = 0; 9; 0;

A PDly 0 kezdrtk vltoz a fzisvlts ksleltetshez szksges vltoz. A fhs ngyfzis, az els kett a fggleges, a msodik kett a vzszintes irny mozgs kzben vltakozik. Fzisksleltets nlkl vagy nagyon sok fzist kellene ltrehozni, vagy pedig tl gyors lenne a mozgs. A Lives az letek szmt tartalmazza, a Height pedig a magassgot kppontban. var Hero: Fall: POld: Killed: Won: GameOver: i: f: BOB; array [0..MaxFalls] of BOB; word; boolean; boolean; boolean; word; file;

A Hero a fhs azonostja, a Fall tmb pedig az ellensgek, a zuhan trgyak nemgrafikus adatait tartalmazza. A POld vltozra a fzisvltoztatsnl lesz szksg az elz fzis sorszmt trolja. A Killed, Won, GameOver logikai vltozk a repeatuntil ciklusok vgt jelzik, a Killed akkor lesz igaz, ha a fhs meghalt, a Won, ha nyert, a GameOver pedig akkor kap true rtket, ha elfogytak az letek, vagy ESC-t nyomtunk. Az utols kt vltoz ltalnos cl, i-re a for ciklusoknl, f-re a palettabetltsnl lesz szksg.

106

A deklarcis rsz vgn tallhat kt eljrs megjelenti az letek szmt, illetve az aktulis BOX-ban mrt magassgot. Alapelvk a kvetkez: az MCGA unit (6.1.1) CBar eljrsval letrlik a rgi szmokat, egy fekete tglalappal bortjk be, majd kirjk az jat, ugyanennek az egysgnek az OutTransparentText eljrsval. Kirsnl szp trbeli hatst rhetnk el, ha ktszer jelentjk meg a szveget, csak msodszor egy pixellel balra s fel elcssztatva s ms, lehetleg vilgosabb sznnel. A szmok szvegg konvertlshoz a _System unit (6.1.2.) _Str fggvnyt hasznljuk. procedure ShowLives; begin CBar( 19, 220, 190, 300, 199); PointColor:= 7; OutTransparentText( 221, 192, _str( Lives)); PointColor:= 15; OutTransparentText( 220, 191, _str( Lives)); end; procedure ShowHeight; begin CBar( 19, 80, 190, 120, 199); PointColor:= 7; OutTransparentText( 81, 192, _str( Height shr 3)); PointColor:= 15; OutTransparentText( 80, 191, _str( Height shr 3)); end; Most kvetkezik a fprogram. Elejn el kell vgezni a szksges inicializlsokat, betltseket, majd kvetkezhetnek az egybegyazott ciklusok, melyek a jtk mozgatst vgzik. Vgl egy rvid lezr rsz tallhat, melyben visszalltjuk az eredeti billentymegszaktst s a szveges kperny zemmdot. begin InitGame; LoadLBM( 'example.lbm', ptr($a000,0)); readkey; HidePal( PalSpd, 1, 255, 0, 0, 0); Rgtn els eljrsknt az InitGame-et hvtuk meg. Nagyon fontos, hogy a Game egysg rszeit csak az utn hasznljuk, miutn inicializltuk a unitot ezzel az eljrssal. Ennek itt eleget tettnk. Az MCGA zemmdot az InitGame bekapcsolta, gy a LoadLBM eljrssal a kezdkp megjelenthet. Ez addig ltszik, amg meg nem nyomunk egy billentyt, utna lassan eltnik, a HidePal eljrsnak ksznheten. A kvetkez kt sor betlti a trkpet, ami a hzat tartalmazza, s belltja, hogy a legalja ltszdjon. Ezenkvl a NewPos eljrsnak ksznheten a httren is megjelenik a kp, ha utna kzvetlenl kiadnnk a MakeScr; ShowScr; utastsprt, a trkp alja lthat lenne. LoadMap( 'example.map'); NewPos( 0, (MapLength div BPL) shl 3 - 190); with Hero do begin Load( 'hero.bob'); X:= 160 - w shr 1; Y:= 180 - h; end; A fhs inicializlst elvgzi a Load metdus. Ez egyben betlti a Shape-et is, viszont a koordintkat nem vltoztatja. A betltst kvet kt sorban trtnik az elhelyezs: vzszintesen pont kzpen van (W SHR 1=W DIV 2), fgglegesen pedig gy foglal helyet, hogy talpa pont a 180. sort rinti. Az albbi ciklus a hull trgyakat inicializlja. A Fall tmb elemeibe sorszmuk alapjn betlti a lemezen lv FALLx.BOB fjlokat. Ezutn vletlenszeren elhelyezi ezeket a BOB-okat. A httr fggleges szleinek vonaln bell helyezkednek el, viszont fgglegesen a httr fltt, gy eleinte nem lthatk. A fggleges elhelyezsnl kap szerepet a Skill konstans. Minl nagyobb ez az rtk, annl ritkbban jnnek a BOB-ok. Teht most, a vletlenszm-genertor inicializlsa utn kvetkezik az ellenfelek inicializlsa.

107

randomize; for i:= 0 to MaxFalls do with Fall[i] do begin Load( 'fall'+_str(i)+'.bob'); X:= random( 320-w); Y:= -h-random( Skill*MaxFalls); end; SetArea( 0, 189); MakeScr; ShowScr; A SetArea belltja a jtkteret gy, hogy a kpernyn az als 10 sor szabadon maradjon, ezt a svot a ShowScr eljrs nem mdostja. Ide kerl majd az llapotsor, mely jelzi a magassgot s az letek szmt. A MakeScrShowScr eljrspr megjelenti a kezd jtkkpet. Viszont ez mg nem lthat, hiszen a kezdkp eltntetse utn a paletta minden szne fekete lett, s ez azta nem vltozott. CBar( 19, 0, 190, 319, 199); TextBackColor:= 19; PointColor:= 3; OutText( 1, 192, 'Magassg:'); OutText( 161, 192, 'letek:' ); PointColor:= 14; OutTransparentText( 0, 191, 'Magassg:'); OutTransparentText( 160, 191, 'letek:' ); ShowLives; ShowHeight; A fenti sorok az llapotsort jelentik meg. Elszr befedjk ezt a rszt egy fekete tglalappal, a CBar eljrssal. Br a jtk ltal hasznlt (albb betltend) palettban a 0. szn is fekete, mgsem ezzel tltjk fel a kperny als 10 sort. Ugyanis palettagrgetsnl a 0. szn vltozatlan marad, s nem lenne szp, ha fekete rszek maradnnak, miutn a kp elpiroslik (hall utn) vagy elfehredik (gyzelem utn). Teht nagyon fontos, hogy a HidePal s a ShowPal eljrsokat hasznl programok grafikjhoz sehol ne hasznljuk a 0. sznt. Ezutn megjelennek a feliratok s a szmok, ktszer, a trbeli hats rdekben. Termszetesen mg mindig nem lthat semmi, mert a paletta fekete. Azt ksbb lltjuk be, a most kvetkez ngy sor csupn betlti a Colors tmbbe (Game egysg). Ezutn egy ShowPal eljrssal fokozatosan megjelenthet. Persze sokkal egyszerbb lenne a palettt a LoadPal eljrssal elvarzsolni, viszont az nem lenne ilyen szp, mert hirtelen jelenne meg. assign( f, 'example.pal'); reset( f, 1); blockread( f, Colors, 768); close( f); CFirst:= 64; CLast := 79; A CFirst s a CLast vltozk belltsval meghatrozzuk azt a szntartomnyt, aminek szneivel a fhs tkzhet. Ebbe az intervallumba esik a hzfal, a cserp s a zrt ablakok szne. Viszont ezen kvl kell lennie az gsznnek, az erklyek s a nyitott ablakok sznnek, mivel ezekkel nem rintkezhet a fhs, ki kell kerlnie. Minden jtk grafikjnak elksztsnek mr a kezdetn vegyk figyelembe, hogy meg kell hatrozni egy ilyen sznintervallumot, s aszerint kell a pontokat besznezni. InitKey; A fciklus megkezdse eltt inicializljuk a sajt billentymegszaktst. Ezt lehetleg minl ksbb tegyk, gy cskken az esly arra, hogy a gp befagy. Ha az InitKey eljrst mr a program elejn meghvtuk volna, egy-egy lemezmveletnl knnyen lellhat a rendszer. Ha pldul az adott fjl nem rhet el, a program futsa megszakad, s ha nem lltjuk vissza a megszaktsvektort, akkor jra kell indtani a gpet. Teht: vagy a fjlmveletek elvgzse utn hvjuk meg az InitKey eljrst, vagy pedig tzetesen vizsgljunk meg minden fjlmveletet.

108

Elrkeztnk a fciklus kezdethez. Ez tulajdonkppen kt egybegyazott ciklus. A bels kap nagyobb szerepet: ez vgzi a jtk mozgatst. Ebbl csak hall, gyzelem vagy az ESC billenty megnyomsa esetn lpnk ki. (Ha a Killed, Won vagy GameOver logikai vltozk valamelyike igazra vlt.) repeat Killed:= false; ShowPal( PalSpd, 1, 255); A bels ciklus megkezdse eltt a Killed vltoz hamisra vlt, s a paletta kivilgosodik. Erre szksg lesz egy-egy let elvesztse utn is, amikor az elpirosodott kpbl kell az eredeti palettt visszalltani. Ezrt nem hvtuk meg a ShowPal eljrst az inicializl rszben a fciklus eltt. repeat if Key[$C8] then with Hero do begin Scroll( Down, 1); if CollColors then Scroll( Up, 1) else begin A bels ciklusban legelszr a felfel mutat nylbillenty megnyomst vizsgljuk. Ha ez bekvetkezik, a trkp lefel mozdul egy pixellel. Ha most olyan helyzetbe kerlt, hogy a BOB rintkezik a CFirstClast vltozkban megadott szntartomnyon kvl es sznnel, akkor visszagrdl a trkp, egy pixelt felfele. (Magyarul: nyitott ablakon, erklyen nem lehet felmszni.) Ekkor teht a trkp megmozdult: lefele s felfele grdlt egy sort, mindebbl azonban semmit sem vesznk szre, mert csak a httr vltozott, a kperny tartalma nem. Ha sikerlt a fhsnek felfel mozdulni (nem tkztt pl. nyitott ablakba), be kell lltani mg pr dolgot. Elszr nveljk a magassgot jelz vltozt, majd kirjuk a kpernyre. (A ShowHeight eljrs a jtk deklarcis rszben tallhat.) Ezutn ellenrizzk, nem rt-e fl a hs a hz tetejre, ennek megfelelen lltjuk be a Won gyzelmet jelz vltozt, amit a ciklus aljn, az until utn ellenrznk. inc( Height); ShowHeight; Won:= PosY=4; A kvetkez rszben a fzisvlts kvetkezik. Legelszr troljuk az aktulis fzist a POld vltozba, hogy vissza lehessen lltani, ha a BOB a fzisvltoztats utn tiltott sznekkel rintkezik (nyitott ablakkal, ggel stb.). A felfel mozgst az els kt fzis tartalmazza, gy ha a BOB a 3. vagy a 4. szakaszban van, az albbi rsz msodik sora 0-ra lltja a fzisszmllt (az 1. fzisra). POld:= P; if P>1 then P:= 0; inc( PDly); if PDly=10 then begin PDly:= 0; inc( P); if P>1 then P:= 0; sound( 200); end; if CollColors then P:= POld; A fzisvlts lnyege a kvetkez: van egy szmll, mely folyamatosan nvekszik, s ha elrt egy bizonyos hatrt (itt: 10), lenullzdik, s ekzben megvltozik az aktulis fzis. gy ugyan darabosabb a mozgs, de legalbb nem kell minden pixel elmozdulshoz kln peridust rajzolni. Ezt a fzisksleltet mdszer sajt jtkokban is felhasznlhat. Ezenkvl minden fzisvltst hangads ksr, majd az utols sor visszalltja az eredeti fzist, ha a CollColors metdus visszatrsi rtke true. A BOB felfel mozgshoz tartozik mg az ellensgek, a hull trgyak lefel mozgatsa: for i:= 0 to MaxFalls do inc( Fall[i].y); end; end

109

Ezutn kvetkezik a balra, illetve jobbra mozgs. Alapelvk ugyanaz, mint a felfel mozgsnak. Csak apr klnbsgek vannak: nem a trkp mozog, hanem a BOB, a 3. s a 4. fzis vltakozik, mlyebb hang szl egy-egy fzisvltsnl. Csupn annyit rdemes mg megjegyezni, hogy a hrom vizsglt nylbillenty kzl egyszerre csak egynek a lenyomst rzkeli a program (a kvetkez kt rsz else kezdete miatt), teht nem lehet tls irnyban haladni. else if Key[$CB] then with Hero do begin dec( x); if CollColors then inc( x) else begin POld:= P; if P<2 then P:= 2; inc( PDly); if PDly=10 then begin PDly:= 0; inc( P); if P>PN then P:= 2; sound( 100); end; if CollColors then P:= POld; end; end else if Key[$CD] then with Hero do begin inc( x); if CollColors then dec( x) else begin POld:= P; if P<2 then P:= 2; inc( PDly); if PDly=10 then begin PDly:= 0; inc( P); if P>PN then P:= 2; sound( 100); end; if CollColors then P:= POld; end; end; Az albbi rszre azrt van szksg, hogy minden billenty lenyomsakor legyen fzisvlts: if not( Key[$C8] or Key[$CB] or Key[$CD]) then PDLy:= 9; ESC nyomsra vge a jtknak: GameOver:= Key[1]; A bels ciklus vgn mr csak a trgyak folyamatos essrl s a megjelentsrl kell gondoskodni. Ha egy trgy elhagyta alul a kpet, visszaugrik flje, j koordintkkal. tlagosan minden harmadik pont a fhs feje fltt esik. Ha valamelyik tkzik a fhssel, a Killed vltoz igaz rtket kap, aminek hatsra a program alul, az until sznl kilp a bels ciklusbl. A megjelents a MakeScr; RetRace; ShowScr; eljrshrmassal trtnik. Ezutn hvjuk meg a Nosound eljrst. Ha a megjelents eltt halktannk el a hangszrt, sokkal rvidebb ideig szlna a fzisvltsoknl kiadott hang, mivel a megjelents meglehetsen sok idt vesz ignybe. for i:= 0 to MaxFalls do with Fall[i] do begin inc( y); Killed:= Killed or Collision( Hero); if y>190 then begin y:= -h-random( Skill*MaxFalls); if random( 3)>0 then x:= random( 320-w) else x:= Hero.X; end; end;

110

MakeScr; RetRace; ShowScr; nosound; until Killed or Won or GameOver; A program kilp a bels ciklusbl, ha a fhs meghalt vagy nyert; vagy a jtkos megnyomta az ESC billentyt, aminek hatsra a GameOver igazra vltozott. A kls ciklus mg kt rszbl ll: az els akkor kerl vgrehajtsra, ha a fhs meghalt, a msodik akkor fut le, ha nyert. if Killed then begin Ha a fhst eltallta egy trgy, lezuhan. Ekzben gondoskodni kell a trgyak essrl s a megjelentsrl is. Ezutn elvrslik a kp. A vrsnek egy vletlenszeren kivlasztott rnyalata telti be a kpernyt. Vgl cskkentjk s megjelentjk az letek szmt, majd visszalltjuk a BOB-ok koordintit. A sznek sszetevi a kls ciklus elejn llnak majd vissza eredeti llapotukba, a ShowPal eljrs segtsgvel. inc( Hero.y); repeat for i:= 0 to MaxFalls do with Fall[i] do inc( y); inc( Hero.y); MakeScr; RetRace; ShowScr; until Hero.y>220; HidePal( PalSpd, 1, 255, random( 64), 0, 0); dec( Lives); ShowLives; for i:= 0 to MaxFalls do with Fall[i] do begin y:= -h-random( Skill*MaxFalls); x:= random( 320-w); end; Hero.y:= 180-Hero.h; GameOver:= Lives=0; MakeScr; ShowScr; end; Ha a fhs feljutott a hz tetejre, nyert. Ekkor a kperny lassan elfehredik, majd elsttl. if Won then begin HidePal( PalSpd, 1, 255, 63, 63, 63); HidePal( PalSpd, 1, 255, 0, 0, 0); end; until GameOver or Won; A program befejezdik, ha ESC-t nyomott a jtkos, ha elfogytak az letek, vagy ha nyert. A BIOS billentymegszakts s a szveges md visszalltsn kvl mr nem is kell mst tenni, viszont ezeket nem szabad elfelejteni! DoneKey; DoneGame; end. Megjegyzs: a DoneGame eljrs helyett rhattuk volna a kvetkezt: SetMode( 3);

111

Egy konkrt pldn keresztl mutattuk be a Game unit mkdsnek fbb elveit, de persze ltalnossgokat is le lehetett szrni belle. Az egysg minden rszt csak egy sokkal terjedelmesebb plda ltal lehetett volna megismertetni, aminek megrtse is sokkal nehezebb lenne. Bzunk abban, hogy az Olvas azokat a lehetsgeket is jl tudja majd hasznostani, melyek ebben a programban nem szerepelnek. A lemezmellkleten tallhat mg egy jtk, a TANK knyvtrban, ami szintn fknt a Game unit elemeit hasznlja. rdemes elindtani.

112

A lemezmellklet ismertetse
A lemezmellkleten megtallhat minden program forrskdja, grafikai adatfjlok s ms, a programok futtatshoz szksges adatllomnyok. Nmelyik program lefordtott, rgtn indthat llapotban is meglelhet, ilyenek pl. az editorok. A knyvben tallhat nll eljrsok, fggvnyek pedig include (.INC) fjlokban kaptak helyet. A programok knnyen megtallhatk, fejezetenknt vannak csoportostva a FEJEZET1, FEJEZET2, knyvtrakban. Ezeken kvl mg ms knyvtrak is vannak a lemezen, melyekbe kiemeltnk egyes programokat. A lemezmellklet knyvtrai teht: BOBEDIT EXAMPLE FEJEZET1 FEJEZET2 FEJEZET3 FEJEZET4 FEJEZET5 FEJEZET6 FEJEZET7 FEJEZET8 FEJEZET9 MAPEDIT TANK UNIT BOB-szerkeszt segdprogram. Rgtn futtathat. Pldajtk, ami a Game unit egyszer demonstrcija. Fordts nlkl indthat. Az Alapfogalmak fejezet programjai. A BOB-ok megjelentse fejezet programjai. A Billentyzet s egr fejezet programjai. A Httr fejezet programjai. Az tkzsek fejezet programjai. A BOB-Editor fejezet programjai. A MAP-Editor fejezet programjai. A Game unit fejezet programjai. A Pldajtk fejezet programjai. MAP-szerkeszt segdprogram. Lefordtott llapotban is megtallhat. Egy msik pldajtk. Szintn a Game unit felhasznlsval kszlt. Rgtn futtathat. A lemezen szerepl legtbb program az itt tallhat unitokat hasznlja (_System, Game, MCGA, Menu, Mouse), ezrt rdemes ezeket lefordtani, s a keletkezett TPU fjlokat egy sajt unit-knyvtrba msolni, hogy a Turbo Pascal szmra hozzfrhetek legyenek.

A knyvben szerepl nll eljrsok/fggvnyek a lemezmellkleten is megtallhatk. A kvetkez tblzat megmutatja, hogy melyik szubrutin melyik fjlban lelhet meg. Nv Collision Collision FillBack GetPixel GetRGB HLine HLine LoadLBM ScrollD ScrollL ScrollR ScrollU SetRGB VLine Tpus fggvny fggvny eljrs fggvny eljrs eljrs eljrs eljrs eljrs eljrs eljrs eljrs eljrs eljrs Fejezet 5.1. 5.2. 4. 1.3. 1.6.1. 4.4.1. 4.4.2. 4.1. 4.6.4. 4.6.2. 4.6.1. 4.6.3. 1.6.2. 4.5. Fjl COLL1.INC COLL2.INC FILLBACK.INC GETPIXEL.INC GETRGB.INC HLINE1.INC HLINE2.INC LOADLBM.INC SCROLLD.INC SCROLLL.INC SCROLLR.INC SCROLLU.INC SETRGB.INC VLINE.INC

Ha a lemezmellkleten tallhat programokat futtatni kvnjuk, a kvetkez fordt direktvkat kapcsoljuk be: G 286-os kd generlsa I I/O ellenrzs X a kiterjesztett szintaxis alkalmazsa

113

Trgymutat
_COPY, 73 _KeyPressed, 99 _ReadKey, 99 _STR, 73 _SYSTEM egysg, 73 _VAL, 73 Commodore 64, 7 Copy, 78, 88, 101 Cut, 78, 87

D
Default pal, 88 delay, 15, 18 Delete, 78, 87 DIR, 77 DisableArea, 39 doboz, 45 DoneGame, 91 DoneKey, 91 Down, 103 DrawBox, 92

1
10h megszakts, 6

A
adatregiszter, 10 alapszn komponens, 9 llapotsor, 75, 86 Amiga, 7 Animate, 79

E
Edit men, 78, 87 egrkurzor, 40 elektronsugr, 7 EnableArea, 39 Exit, 77, 87

B
BackColor, 103 Background, 92, 94 BackGround, 41, 95, 104 Bar, 73, 79 bitmaszk, 63 Blitter OBject, 7 blue, 9 BMP, 42 BOB, 7 BOB tpus, 13, 33, 99 BOB-EDITOR, 72 BOB-formtum, 72 BOX, 45, 47, 84 BoxPtr, 104 BoxPTR, 46, 94 Boxs Per Line, 46, 94 BPL, 46, 47, 94, 104 ButtonPressed, 38

F
Fall, 106 flkpet, 7 File men, 76, 86 Fill, 8 FillBack, 41, 92 First, 104 Full screen, 88

G
Game, 106 GAME unit, 91 GameOver, 106, 111 Gamepad, 34 GetMenu, 83 GetMouse, 39 GetPixel, 6, 73 GetRGB, 10 GetSensitivity, 39 GIF, 42 Go to, 88 GotoMouse, 39 Graph, 13 GrayPal, 92 green, 9

C
capture, 41 CBar, 72 CFirst, 103 Change, 79 CLast, 103 Clear map, 88 ClearBOB, 15, 16 CollBack, 100 CollBox, 100 CollBOX, 71 CollColors, 71, 101 Collision, 64, 67, 70, 100 Colors, 104

114

H
Httr, 47 Height, 106 Hero, 106 HideMouse, 39 HidePal, 92 HLine, 49, 52 horizontal retrace, 7 horizontlis visszafuts, 7 Hot Key, 82

I
Import, 77 Init, 101 InitGame, 93 InitKey, 38, 93 InitMouse, 38, 39 Inverse, 79 IOError, 73

J
JPG, 42

K
kpformtum, 41 kplop, 41 kettes komplemens, 42 key, 104 Key, 38, 93, 104 KEY, 35 Killed, 106, 110

Map size, 88 MAP-EDITOR, 82 MAP-formtum, 60, 82 MapLength, 104 MapPtr, 104 MapPTR, 46, 94 Mask, 88, 94, 100, 104 MaxFalls, 106 MaxLength, 83 MaxMains, 83 MaxMenus, 83 MBColor, 83 MCGA, 5, 91 MCGA egysg, 72 Menu egysg, 82 MenuLen, 83 MenuRes, 83 MFColor, 83 Mickey, 39, 40 Middle, 39 Mirror, 79 Mouse, 38 mouse driver, 38 Mouse egysg, 38 MouseMoved, 40 MouseSpeed, 40 MouseType, 39 MouseX, 39, 40 MouseY, 39, 40

N
New, 76, 86 NewPos, 95

L
Last, 104 LBM, 42 Left, 39, 103 LeftButton, 39, 40 Lives, 106 Load, 29, 33, 102 Load pal, 87 Load Pal, 77 LoadBar, 73 LoadLBM, 42, 43, 94 LoadMap, 94 LoadPal, 94 LZW kdols, 42

O
OnScreen, 102 Open, 76, 86 Options men, 88 OutText, 73 OutTransparentText, 73

P
paletta, 9, 75, 85 PAL-formtum, 94 PalSpd, 106 Paste, 78, 88 PDly, 106 PixelBack, 41, 95 Point, 72 PointColor, 73 POld, 106, 109 PosX, 105 PosY, 105 priorits, 13 protected, 33 Put, 102

M
MainMenu, 82 MainRes, 83 MainStr, 83 MakeScr, 95 MAP, 45, 47

115

Putimage, 13 PutPixel, 5, 6, 41, 72

R
Rectangle, 72 red, 9 Refresh, 83 Retrace, 8, 17 RetRace, 9, 18, 26, 33, 96 RGB, 9 RGB Data, 10 RGB Read Adress, 10 RGB Write Adress, 10 RGBType, 104 Right, 39, 103 RightButton, 39, 40 Rotate, 79

ShowBOB, 14, 15, 16, 20, 22, 24, 27, 29 ShowMouse, 38, 40 ShowPal, 98 ShowScr, 99 ShowUpon, 102 Skill, 106 Sprite, 7 SubMenu, 82 SubStr, 83 sw_byte, 73 sw_word, 73 szerkesztsi terlet, 74 sznvz, 63

T
Tab size, 88 trkp, 45 trkpszerkesztsi terlet, 85 TextBackColor, 73 Tools men, 78 transzparens, 7, 13 Turn, 78

S
Save, 77, 87 Save as, 87 Save As, 77 Save pal, 87 Save Pal, 77 SaveBar, 73 SBColor, 83 SCAN kd, 34, 38 scroll, 57 Scroll, 60, 96 ScrollD, 60 ScrollL, 58 ScrollR, 58 ScrollU, 59 SegA000, 6 Sensitivity, 40 SetArea, 97 SetMode, 72 SetRGB, 10, 97 SetSensitivity, 40 SFColor, 83 Shape, 7

U
Up, 103

V
vertical retrace, 7 VerticalBlink, 73 vertiklis visszafuts, 7 VLine, 55

W
Won, 106, 109 WorkArea, 92, 95, 105

Z
ZOOM, 74

116

Irodalomjegyzk
Pirk Jzsef Turbo Pascal 6.0 (for Windows. LSI oktatkzpont, 1992. Agrdi Gbor IBM PC Gyakorlati assembly. LSI oktatkzpont, 1993. Lszl Jzsef A VGA krtya programozsa. ComputerBooks, 1995. Marton Lszl Bevezets a Pascal nyelv programozsba. Novadat, 1996.

117

Vous aimerez peut-être aussi