ASSEMBLER CURSUS - Les 6 In deze les zullen we leren hoe we texten op het scherm krijgen, screens heen en weer scrollen (alweer) die groter zijn dan het scherm, en hoe men Tabellen met voorgedefinieërde waarden gebruikt om 'Hup'-bewegingen en Sinus-bewegingen te simuleren. Om te leren hoe men text op het scherm krijgt is heel belangrijk, want er is geen spel of demo of programma dat zonder text werkt: Of men nu de puntenstand wil tonen, de Levens van Player 1, een boodschap tussen de Levels door, een 'Greeting' aan anderen, vragen om een diskette in de drive te plaatsen enz.. enz.. Ik hoop dat u begrepen heeft dat dat niet elke keer een Plaatje is van 320x256 dat in Dpaint gemaakt is met de texten erop. Stelt u zich voor! Stel u wilt 5 pagina's text als intro voor uw spel tekenen: 'Er was eens een Ridder, lang, heel lang geleden, die op zoek was naar het Zwaard van ........'. Begrepen? Goed. Dus OF u tekent met uw teken-programma 5 plaatjes met de text erop die onze plaats op het schijfje en in het geheugen opvreet (= 5 * 40 * 256 = 51200 Bytes!) OF we doen alles met 1kb Fonts en enkele bytes routine en bereiken hetzelfde. Alleen gebruiken we 50kb minder geheugen. Heeft u de Character-Fonts van het bedrijfssysteem voor ogen zoals TOPAZ,DIAMOND en al die anderen? Zeer goed, maar die interesseren ons nul komma nop. 't Spijt me. Maar we gaan onze eigen fonts gebruiken. Natuurlijk, we KUNNEN ze wel gebruiken, maar die zijn begrensd.Als we zelf iets in elkaar knutselen en kunnen tonen wat we zlef willen, is er geen Grootte of Breedte die ons tegenhoudt! We kunnen desnoods een Arabische karakterset maken! (Als U Arabisch kent...). Ook kleuren; No Problemo! Dan maakt u toch lekker een Kleurenfontje en schrijft u zelf de routine daarvoor? Maar eerst maar eens proberen iets op het scherm te krijgen, daarna zien we wel verder. Als men eenmaal het PRINT-systeem begrepen heeft,dus het systeem dat de letters op de monitor zet, dan zijn Variaties geen probleem meer. Laten we eerst eens leren een klein fontje op het scherm te zetten: 8 maal 8 pixels groot,in 1 kleur. Allereerst hebben we een Bitplane nodig, waarop we onze letters kunnen 'drukken', en een CharacterFont, waarin deze letters zijn opgeslagen. Het stuk bitplane is geen probleem, want we hoeven alleen maar een stuk geheugen op te vullen met nullen. Om dit lege stuk geheugen te creeëren, kunnen we dcb.b 40*256,0 gebruiken, dat het juiste aantal nullen in het geheugen plaatst. Maar er is een speciale SECTION voor de leggen "Buffers": BSS-Section's genaamd. Daarin kan men de instructies ds.b / ds.w / ds.l gebruiken die aangeven hoeveel bytes, word of longwords we op nul willen zetten. Het voordeel ligt in de totale lengte van de geassembleerde file: Als we "Bitplane: dcb.b 40*256,0" gebruiken, dan worden 10240 'lege' bytes in de file ingebouwd. Daarentegen: SECTION EenBitPlaneHier,BSS_C ;_C betekent dat de nullen ; in het CHIP RAM moeten ; komen; Anders zou het ; systeem ze in het ; FASTRAM kunnen laden, en ; Bitplanes moeten ALTIJD ; in het CHIP Ram! Bitplane: ds.b 40*256 ; 10240 Bytes op 0 Aan het einde van de file wordt er dan een HUNK aangehangen, die op het moment dat we de file lezen niets anders betekent dan 40*256. Dit kost echter maar een paar bytes van de file. Het is alsof men een zak vol guldens heeft, en met de 'ds.b 40*256' een briefje van 100. Hetzelfde geldt voor de file; deze wordt 'magerder'. Let er op dat 'ds.b 40*256' niet door '0' wordt gevolgd, zoals bij dcb.b het geval is, want 'ds' betekent altijd nul. DCB daarentegen kan ook iets anders zijn. Nu hebben we het 'stuk papier' waarop we onze text gaan schrijven. Nu ontbreekt alleen nog het font en de PrintRoutine. Laten we eens kijken wat een font eigenlijk is en hoe het opgebouwd is. Een font is een File die aanwijzingen en Data bevat om iets te schrijven op het scherm. Het bestaat in verschillende formaten. Het is eigenlijk niets anders dan een Serie van Karakters (=Letters,Cijfers,Leestekens enz...) die achter elkaar zijn opgeslagen als een rij:"ABCDEFGHI....". Enkele fonts zijn in .iff getekent, dus een Screen met karakters: ------------ |ABCDEFGHIJKL| |MNOPQRSTUVWX| |YZ1234567890| | | | | ------------ Dit beeld wordt dan in RAW omgezet, en de karakters worden dan uit dit beeld genomen (lees: GEKOPIEËRD!) en op de juiste plaats in de bitplane gekopieërd. Als we dan een "A" nodig hebben, weten we waar we deze moeten zoeken. Idem voor de andere letters,tekens enz.. Laten we het eens hebben over het systeem dat we in deze cursus gaan gebruiken om 8x8 fonts af te drukken: De tekens zijn 8 Pixels breed en 8 pixels hoog, vandaar 8*8. Net als een font ui de Kickstart (zoals Topaz). Eigenlijk zijn ze iets smaller dan 8 pixels, maar dit is zo omdat de letters ook nog afstand van elkaar moeten houden. Anders zouden ze allemaal aan elkaar vast staan, op elkaar 'kleven' enz.. De karakters zijn allemaal in de 'juiste' volgorde opgesteld, dus naar de ASCII-Norm. Dat ziet als volgt uit: dc.b $1f,' !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNO' dc.b 'PQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~',$7F De $1f aan het begin en de $7f aan het einde betekenen dat het eerste karakter de SPATIE is dat na $1f staat, dus 20, gevolgd door "1" die waarde $21 inneemt enz.. enz.. tot de laatste tekens, die dan bij $7f aankomen. Dus "hond" mag men ook schrijven als dc.b $68,$6f,$6e,$64 Zoals u misschien al ziet is een cijfer dus NIET altijd een cijfer, maar kan "1" in het geheugen ook $30 zijn i.p.v. $1. Ieder karakter gebruikt 1 byte in het geheugen; dus een text die 5000 bytes lang is heeft ook 5000 tekens. Komen we op ons font terug. Stel u zich een plaatje voor dat 8 pixels breed is, maar lang genoeg om alle karakters onder elkaar te bevatten: <- (Spatie!) ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O enz.. enz.. Het Font dat we in deze cursus gebruiken is niets anders als een plaatje in RAW, dat zo uitziet. In werkelijkheid wordt zo'n Font met speciale EDITORS ontworpen (=Programma's die ervoor zijn gemaakt om fonts te maken). Voor fonts die echter groter of groot zijn, is het handig om ze in een tekenprogramma te tekenen (zeker als ze in kleur zijn!), normaliter 320x256, en een eigen Routine te schrijven om ze 'uit te knippen'. Maar om te beginnen kijken we eens naar het simpelste font en hoe het op het scherm komt: Allereerst moet de STRING (='Teken-ketting') worden voorbereid, waarin staat wat we willen tonen, b.v.: dc.b "Ons eerste woordje!" ; OPMERKING: U kunt '' of "" ; gebruiken. EVEN ; Ofwel : Alles op EVEN adressen ; zetten. Het bevel EVEN (=Eng.) dient ervoor om te zorgen dat de programma-code die na onze zin komt niet op oneven adressen komt te staan (een teken is immers 1 byte lang!). De textstrings bestaan uit aparte (opzichzelf staande) tekens die samen een woord of zin vormen. Om te zorgen dat de volgende bevelen niet op oneven adressen komen kunnen we dus het bevel EVEN gebruiken, OF een nul achter onze string hangen: Bij GfxName heb ik het zo gedaan: GfxName: dc.b "graphics.library",0,0 dit kon men ook als volgt schrijven: GfxName: dc.b "graphics.library",0 even Goed, als we dus hebben vastgesteld wat we willen printen op het scherm, moeten we nog een routine schrijven die de juiste letters op de juiste plek op het scherm zet. Ik stel u vast aan de routine vor die 1 teken afdrukt: PRINT: LEA TEXT(PC),A0 ; Adres van te schrijven text in a0 LEA BITPLANE,A3 ; Adres van doel-bitplane in a3 MOVEQ #0,D2 ; Wis d2 MOVE.B (A0),D2 ; Volgend karakter in d2 SUB.B #$20,D2 ; Trek 32 van de ascii waarde af,waardoor ; we b.v. de spatie (=$20) in $00 krijgen, ; het uitroepteken (=$21) in $01 enz.. MULU.W #8,D2 ; Vermenigvuldig het verkregen getal met 8 ; omdat de karakters 8 pixels hoog zijn MOVE.L D2,A2 ADD.L #FONT,A2 ; Vindt de gewenste letter in het font. ; Druk de letter lijn voor lijn af: MOVE.B (A2)+,(A3) ; Teken lijn 1 van de letter MOVE.B (A2)+,40(A3) ; Teken lijn 2 van de letter MOVE.B (A2)+,40*2(A3) ; Teken lijn 3 van de letter MOVE.B (A2)+,40*3(A3) ; Teken lijn 4 van de letter MOVE.B (A2)+,40*4(A3) ; Teken lijn 5 van de letter MOVE.B (A2)+,40*5(A3) ; Teken lijn 6 van de letter MOVE.B (A2)+,40*6(A3) ; Teken lijn 7 van de letter MOVE.B (A2)+,40*7(A3) ; Teken lijn 8 van de letter RTS Begrepen? Prachtig! Niet begrepen? Pech gehad...Grapje! Laten we het eens stap voor stap gaan bekijken: LEA TEXT(PC),A0 ; Adres van te schrijven text in a0 LEA BITPLANE,A3 ; Adres van doel-bitplane in a3 MOVEQ #0,D2 ; Wis d2 MOVE.B (A0),D2 ; Volgend karakter in d2 Tot hier geen problemen hoop ik. We hebben in d2 de waarde van de letter, dus als het b.v. een "A" zou zijn dan is deze waarde $41. SUB.B #$20,D2 ; Trek 32 van de ascii waarde af,waardoor ; we b.v. de spatie (=$20) in $00 krijgen, ; het uitroepteken (=$21) in $01 enz.. Ook wat hier gebeurt moet duidelijk zijn. Laten we eens kijken waarom we 32 ($20) aftrekken: MULU.W #8,D2 ; Vermenigvuldig het verkregen getal met 8 ; omdat de karakters 8 pixels hoog zijn MOVE.L D2,A2 ADD.L #FONT,A2 ; Vindt de gewenste letter in het font. Deze instructies geeft ons als uitkomst in a2 het adres waar het karakter in het font staat. Dit is dus het adres dat we 'uitknippen' moeten om deze in het 'bitplane' toe te voegen. Wat is er gebeurd? Denk eraan dat het karakter in het FONT in dezelfde volgorde staan als de ASCII-standaard. Als we nu de ascii-waarde kennen, kunnen we onze "A" in het font vinden. Als elk teken 8 pixels maal 8 pixels groot is, dan betekent dat dat het 8 bit lang is, dus 1 byte per lijn. Met 8 lijnen per karakter (= dus de hoogte!) krijgen we dus 8 bytes. Door het aftrekken van $20 (32) van de verkregen waarde krijgt de spatie dus plaats 0, het roepteken plaats $01....,"A" plaats $21,"B" plaats $22 enz.. We hoeven dit cijfer alleen nog maar met 8 te vermenigvuldigen om het juiste adres te vinden vanaf het begin van de RAW file. Nogmaals herhaald: SUB.B #$20,D2 ; Trek 32 van de ascii waarde af,waardoor ; we b.v. de spatie (=$20) in $00 krijgen, ; het uitroepteken (=$21) in $01 enz.. MULU.W #8,D2 ; Vermenigvuldig het verkregen getal met 8 ; omdat de karakters 8 pixels hoog zijn Nu hebben we in d2 de afstand (offset) van het begin van een bepaald karakter vanaf het begin van het font uitgerekend! Om nu het effectieve adres in het geheugen te vinden, tellen we deze offset van het font bij het begin-adres van het font zelf op: MOVE.L D2,A2 ADD.L #FONT,A2 ; Vindt de gewenste letter in het font Nu hebben we in a2 het adres waar zich ons 'gekozen' karakter bevindt; B.v. "A". Nu nog het font op het scherm tonen, dus in het bitplane zetten van 320x256 waarvan elke lijk 40 bytes lang is: ; Druk de letter lijn voor lijn af: MOVE.B (A2)+,(A3) ; Teken lijn 1 van de letter MOVE.B (A2)+,40(A3) ; Teken lijn 2 van de letter MOVE.B (A2)+,40*2(A3) ; Teken lijn 3 van de letter MOVE.B (A2)+,40*3(A3) ; Teken lijn 4 van de letter MOVE.B (A2)+,40*4(A3) ; Teken lijn 5 van de letter MOVE.B (A2)+,40*5(A3) ; Teken lijn 6 van de letter MOVE.B (A2)+,40*6(A3) ; Teken lijn 7 van de letter MOVE.B (A2)+,40*7(A3) ; Teken lijn 8 van de letter De kopie volgt lijn voor lijn. Het karakter is 8 lijnen hoog, en elke bestaat uit 8 bit (1 Byte): 12345678 ...###.. Lijn 1 - 8 bit, 1 byte ..#...#. 2 ..#...#. 3 ..#####. 4 ..#...#. 5 ..#...#. 6 ..#...#. 7 ........ 8 Om dus een Lijn per doorgang te kopieëren moeten we een Byte per doorgang kopieëren. Maar het beeld is 40 bytes per lijn breed. We moeten er dus aan denken dat elke lijn onder elkaar moet komen. Als we dus niet elke keer 40 bytes overslaan, dan zag alles er zo uit: ...###....#...#...#...#...#####...#...#...#...#...#...#......... We moeten echter 1 byte Kopieëren, Lijn wisselen, 1 byte Kopieëren, lijn wisselen enz.. enz.. Als we dan dus 40 bytes verder springen, en het volgende byte kopieëren: MOVE.B (A2)+,(A3) ; Teken lijn 1 van de letter Op de monitor: ...###.. MOVE.B (A2)+,40(A3) ; Teken lijn 2 van de letter Op de monitor: ...###.. ..#...#. MOVE.B (A2)+,40*2(A3) ; Teken lijn 3 van de letter Op de monitor: ...###.. ..#...#. ..#...#. Enzovoorts. Voor een screen dat 80 bytes breed is (640x256 in Hires) moeten we de routine dus als volgt veranderen: ; Druk de letter lijn voor lijn af: MOVE.B (A2)+,(A3) ; Teken lijn 1 van de letter MOVE.B (A2)+,80(A3) ; Teken lijn 2 van de letter MOVE.B (A2)+,80*2(A3) ; Teken lijn 3 van de letter MOVE.B (A2)+,80*3(A3) ; Teken lijn 4 van de letter MOVE.B (A2)+,80*4(A3) ; Teken lijn 5 van de letter MOVE.B (A2)+,80*5(A3) ; Teken lijn 6 van de letter MOVE.B (A2)+,80*6(A3) ; Teken lijn 7 van de letter MOVE.B (A2)+,80*7(A3) ; Teken lijn 8 van de letter Laten we eens in de praktijk kijken hoe we de "A" op het scherm krijgen. Listing6a.s als het u blieft. In Listing6b.s gaan we over op een complete Regel! En tot slot drukken we zoveel regels af als we willen. Daarvoor is er Listing6c.s. Deze routine is de Universele routine die u kunt gebruiken als u nog eens iets wilt afdrukken. Waarom niet ons eigen font tekenen? In Listing6c2.s is het Font in dc.b-Formaat gegeven, zoals dit voorbeeld: ; "B" dc.b %01111110 dc.b %01100011 dc.b %01100011 dc.b %01111110 dc.b %01100011 dc.b %01100011 dc.b %01111110 dc.b %00000000 De karakters zijn met VELE dc.b % in het geheugen gezet (binair). U kunt elk karakter veranderen naar believen. Als u een eigen font maakt, vergeet het dan niet op te slaan! Nu gaan we iets proberen, wat we nog nooit geprobeerd hebben: Op een enkel scherm laten we gelijktijdig een Beeld in LowRes en een in Hires verschijnen! De Amiga kan gelijktijdig meerdere oplossingen tonen ( Wat me van PC's niet bekend is ). Gewoon een Wait zetten, en daaronder met een BPLCON0 een andere oplossing instellen. Precies zo alsof we de kleuren veranderen. We kunnen b.v. tot lijn $50 een beeld in HAM tot 4096 kleuren tonen, daaronder een Hires met 16 kleuren, en daaronder een Lowres met 32 kleuren. In sommige spellen is b.v. het Speelveld (waarin het figuurtje zich beweegt) in Lowres terwijl het bedieningspaneel (met aantal levens e.d.) in Hires wordt weergegeven. Laten we het meteen proberen. In Listing6d.s hebben we een Beeld in Lowres boven een ander in Hires. Komen we nu aan bij een 'truuk' die een Relief-effect oplevert: in Listing6e.s activeren we 2 bitplanes in plaats van 1 en we leggen ze dan 'gewoon' over elkaar. We verschuiven 1 bitplane 1 lijn naar beneden, dat we iets donkerder van kleur maken, waardoor we een 'schaduw' krijgen. Zie Listing6e.s dus! Nu we het over overlappen hebben; waarom niet gewoon over een Plaatje een Bitplane leggen, en daarop schrijven? Dat ziet u in listing6f.s In Listing6g.s zien we het transparant-effect nog eens. Een text beweegt zich nu alleen ook nog over het scherm... In Listing6h.s zien we een methode om text in 3 kleuren te schrijven, als we fe text met twee bitplanes laten overlappen. In Listing6i.s laten we een van de kleuren van de text knipperen, waarbij we een van te voren gedefinieërde tabel gebruiken. We hebben al in les1 over tabellen gesproken, en nu ziet u in de praktijk hoe zoiets gedaan wordt. Verder ziet u in Listing6l.s een variatie van de routine die een Tabel leest om de kleuren te veranderen. De verandering ligt daarin dat we de tabel van het begin tot het einde lezen, en dan terug gaan zonder deze waarden in de tabel zelf te zetten. Tabellen kunnen voor vele doelen Nuttig tot Onontbeerlijk zijn. Om bijvoorbeeld Veer- en Spring effecten te maken. Laten we eens kijken wat het verschil is met simpele sub's en add's. Listing6m.s is het antwoord... Als we het toch over bewegingen hebben; We hebben voor de Horizontale scroll tot nu toe alleen nog maar $dff102 gebruikt, dat een maximale verschuiving geeft van 16 pixels. Maar hoe kunnen we nu het hele scherm op en neer scrollen over de complete lengte (Projext X,Superfrog,Shadow of the Beast,Walker,The Lion King enz.. enz..)? Het antwoord is simpel: We gebruiken gewoon de Bitplane-Pointers. We hebben al gezien dat het met een scroll naar boven en naar beneden mogelijk is. We hoeven alleen maar een/meerdere lijnen erbij te tellen (40 in LowRes, 80 in HiRes). Maar we kunnen ook heen en weer scrollen, maar alleen in stappen van 8 pixels (1 Byte). Hoe? Gewoon bij de BitplanePointers 1 byte optellen of aftrekken. Daardoor krijgen we een scroll van 1 Byte, dus 8 pixels. Dus... (Pieker...Pieker....) Dus...euh.. Als we dan dus.... Hey! Als we dan dus met de bitplanepointers 8 pixels kunnen scrollen en met $dff102 1 pixel, dan kunnen we dus vloeiende bewegingen maken....Toch? We scrollen gewoon met $dff102 1 pixel totdat we er acht hebben gehad, dan met BPLPOINTER een 'grote stap' van 8 pixels en tegelijkertijd BPLCON1 ($dff102) op 0 zetten De grote stap zou er dus als volgt uit zien: subq.l #1,BITPLANEPOINTER Daarmee zijn we dan dus bij de 9e pixel aangekomen. Dan dus weer pixel voor pixel tot we bij 8 zijn, op 0 zetten en een grote stap....Enz...In de voorbeelden laat ik echter de 'grote stap' iedere 16 pixels maken, omdat BPLCON1 ook 16 pixels aankan. Voor 16 pixels moeten we dan ook 2 bij de BitplanePointers optellen/aftrekken (omdat 1 de PIC 8 pixels verschoof). Ik beweeg het beeld dus pixel voor pixel totdat we de maximale verschuiving hebben bereikt (dus 16 pixels), en maak dan een sprong van 16 pixels met de BitplanePointers met een ADDQ of SUBQ #2,BitplanPointers. Hier een Routine die een plaatje zover naar rechts scrollt als we willen, in stappen van 1 pixel. Letop de MIJNBPCON1 als het byte van $dff102. Rechts: CMP.B #$ff,MIJNBPCON1 ; Zijn we bij maximum scroll aangekomen? BNE.s CON1ADDA ; Zo niet, ga 1 verder. ; Gebruik BPLCON1 ; Leest het Adres van het Bitplane LEA BPLPOINTERS,A1 ; Met deze 4 instructies halen we uit de move.w 2(a1),d0 ; Copperlist het Adresse, waar $dff0e0 swap d0 ; momenteel toe point en stoppen het in d0. move.w 6(a1),d0 ; Scrollt naar Rechts over 16 Pixels, met de Bitplanepointer subq.l #2,d0 ; Point 16 Bit verder naar achteren (Het ; plaatje scrollt 16 Pixels verder naar ; Rechts of links...) ; Laat BPLCON1 weer bij 0 starten clr.b MIJNBPCON1 ; Wis de Hardware-scroll BPLCON1 ($dff102) ; We zijn nml. 16 Pixels met de ; Bitplanepointer gesprongen. En nu moeten ; we weer bij 0 beginnen, om met $dff102 ; Pixel voor Pixel naar rechts te scrollen. move.w d0,6(a1) ; Kopieërt het laagw. Word v.h. Adres v.h. Plane swap d0 ; Verwissel de twee Words move.w d0,2(a1) ; Kopieërt het hoogw. Word v.h. Adres v.h. Plane rts ; Spring uit de routine CON1ADDA: add.b #$11,MEINBPCON1 ; scrol het beeld 1 Pixel naar Rechts rts ; Spring uit de routine De routine verhoogt BPLCON1 ($dff102) steeds 1, en laat alle mogelijke posities doorlopen: 00,11,22,33,44,55,66,77,88,99,aa,bb,cc,dd,ee,ff, en dan springt het naar de volgende pixel ff+1, als we 2 dingen doen: 1) 2 Bytes (1 Word, 16 Bits) in de BitplanePointer Terugpointen, om het beeld naar rechts te laten scrollen ( dus 1 pixel na positie $ff, die in het vorige FRAME werd bereikt. 2) $dff102 op NUL zetten, omdat we nml. 16 pixels in 1 stap hebben gedaan. Anders zouden we 16 bij de vorige waarde ($ff) optellen, en een 'schok' in de beweging naar rechts krijgen. Doordat we BPLCON1 wissen, starten we weer bij $00 + 16 = de zestiende pixel. Daarna gaan we verder tot de 15e met BPLCON1, en laten de bitplane-pointers onveranderd. Als dit nu nog niet duidelijk is, dan kijkt u eens naar dit schema: Het '#' stelt het plaatje voor,dat zich naar rechts beweegt: ; WAARDE BPLCON1- BYTES VAN BPLPOINT. AFGETROKKEN: ----------------------------------------------------------------------------- # ; $00 - 0 -tot. pixel: # ; $11 - 0 - 1 # ; $22 - 0 - 2 # ; $33 - 0 - 3 # ; $44 - 0 - 4 # ; $55 - 0 - 5 # ; $66 - 0 - 6 # ; $77 - 0 - 7 # ; $88 - 0 - 8 # ; $99 - 0 - 9 # ; $aa - 0 - 10 # ; $bb - 0 - 11 # ; $cc - 0 - 12 # ; $dd - 0 - 13 # ; $ee - 0 - 14 # ; $ff - 0 - 15 # ; $00 - 2 - 16 # ; $11 - 2 - 17 # ; $22 - 2 - 18 # ; $33 - 2 - 19 # ; $44 - 2 - 20 # ; $55 - 2 - 21 # ; $66 - 2 - 22 # ; $77 - 2 - 23 enzovoorts... Dit schema spreekt voor zich: Als we b.v. 22 pixels naar rechts willen, dan moeten we 2 van de bitplanepointers aftrekken, en BPLCON1 ($dff102) op $66 zetten. (Let erop dat u altijd $11,$22,$33 enz.. gebruikt! Denk eraan dat het eerste getal staat voor de even planes, en het tweede voor de oneven planes!!!). Willen we naar links, dan moeten we iedere 16 pixels 2 bij de Pointers optellen, en met $dff102 achteruit tellen: $ff, $ee, $dd... In Listing6n.s zien we de routine in de Praktijk. U zult vast de storing aan de linkerkant van het scherm opmerken; dat is geen fout in de routine, maar een karakteristiek van de Amiga-Hardware. Om dit te verhelpen hebben we maar een paar kleine veranderingen nodig. In de listing staan ze verklaard (onderaan)... Omdat we nu een bitplane in elke Richting kunnen scrollen, zover we willen, willen we natuurlijk meer. Waarom bewegen we niet een plaatje dat groter is dan het beeld zelf? In Listing6o.s doen we dit: een plaatje, dat 640 Pixels breed is, rolt door een normaal Lowres screen van 320x256 naar links en rechts. We hebben al bij de tabellen het gebruik van een longword als pointer gezien: Pointer: dc.l Tabel In het Longword 'Pointer' wordt het adres van de tabel geassembleerd, waardoor we kunnen vasthouden waar we in de tabel gekomen zijn als we een element erbij tellen of aftrekken. We moeten iedere keer opslaan waar we gebleven zijn, omdat de routine maar 1 keer per FRAME wordt uitgevoerd, en niet constant. Het is dus mogelijk dat in de tussentijd andere routines worden aangeroepen, en daardoor (per ongeluk) onze waarden wissen. Als deze routine dus weer wordt aangeroepen, dan moet deze meteen verder kunnen waar ze de vorige keer gebleven is. Dit kan door een simpele: MOVE.L POINTER(PC),d0 ; In d0 komt het Adres, waarin we de laatste ; keer gekomen zijn. Voordat we uit de routine springen moet alleen nog de actuele postie worden opgeslagen. Dit systeem kan veelvuldig gebruikt worden. B.v. om bij elk FRAME een letter op het scherm te brengen, i.p.v. de text er in 1 keer neer zetten. Daarvoor moet de Print-routine wel een beetje worden aangepast. We hebben 2 pointers nodig waarvan er 1 bijhooudt bij welke letter we zijn gebleven, en 1 waarin het laatste adres staat dat we in ons bitplane hebben veranderd. Daardoor lijkt het alsof we een letter tekenen, de routine 1 frame lang 'bevriezen', en dan weer de volgende printen. Maar in werkelijk- heid 'bevriezen' we de routine niet, maar slaan de bereikte stand op, en gaan later verder. De Listing die deze theorie in de praktijk brengt heet Listing6p.s. In 1 bitplane kunnen we - behalve text printen - ook tekeningen als schaakbord-patronen, balken of voor mijn part spinne-webben tekenen. Gewoon de juiste bits op 1 zetten! In Listing6q.s ziet u een voorbeeld. We zijn bij het einde van les6.txt aangekomen, en er blijft niets anders over dan alle listings samen te gooien (effe roeren...) en TADAAA! Daar is dan de 'Laatste-Mega-Listing', met alles erop en eraan, ook muziek: Listing6r.s please... Nu gaan we naar Sprites over. Les7.txt is het antwoord op alle vragen over sprites. Tot dan!