                          - SEPTIC'S DEMOSKOLA -

                                Lektion 10
                                
                        Skriven av Vicious / Septic

                                 3 Dec 93



                                 Inledning
                                 
Hejsan igen! nnu en spnnande programmeringslektion frdig att lsas! Den
hr gngen tnkte jag g igenom hur blitterns mycket intressanta linje-
ritnings funktion fungerar och ven visa det med ett programexempel (som
jag brukar gra, givetvis...) dr ngra linjer ritas ut.
  Okej, vi kr vl igng!


                                   Teori
                                   
En linje r som bekant en rad med sammanhngande punkter. Den har en start-
punkt och en slutpunkt och med de tv koordinaterna kan man rkna fram
linjens lutning i X och Y-led, plus hur mnga pixlar som behvs fr att
representera linjen.
  Detta r precis vad man fr gra fr att rita en linje med processorn,
och det blir allts en massa strulande hit och dit med berkningar och
pixel-sttningar plus att det krver en massa rastertid vid bara ett ftal
linjer. PC-coders och C64-coders r tvungna att gra p det hr viset, men
Amiga-coders r lyckligt lottade genom den fantastiska lilla blittern som
klarar av linjeritandet mycket smidigt.
  Att rita en linje med blittern kan verka lite kryptiskt och svrt, men
det r faktiskt ganska enkelt nr man kan det (r det inte s med allt,
egentligen?) Precis som vanligt, nr det gller blittern, kan processorn
fortstta att arbeta medan blittern ritar linjen.

Blittern behver en oktant till att brja med, som beskriver linjens
riktning. Hr r en bild ver de olika riktningarna som kan frekomma:

          \ 3 | 1 /
           \  |  /
          7 \ | / 6
          ___\|/___
             /|\
          5 / | \ 4
           /  |  \
          / 2 | 0 \

Numren som str inom de olika flten anger oktant-numret som skall ges till
blittern senare. (De diagonala strecken ska bilda 45 vinkel med bde den
vertikala och den horisontella linjen, givetvis. Det r bara inte s ltt
att rita det i textmode.)
  Sedan mste vi rkna ut ett par variabler, DX och DY, som kan sgas vara
linjens koordinater omrknat till oktant 6 (vilket r flt 0, om vi gtt
efter en vanlig 360 enhetscirkel).

  DX r maxvrdet av (X2-X1) och (Y2-Y1).
  DY r minvrdet av (X2-X1) och (Y2-Y1).

X1 och Y1 r allts linjens startkoordinat, och X2 samt Y2 r slut-
koordinaten.

Det var allt teoretiskt sett...Lt oss g vidare med vad de olika registren
ska innehlla!


                                 Register
                                 
Vid linjeritning anvnds i princip samma register som vid vanlig kopiering
med blittern. Skillnaden r att genom att stta en speciell LINEDRAW-bit i
BLTCON1 ($DFF042) s fr de flesta av registren en helt annan innebrd.
  Till att brja med ska man alltid stta BLTADAT ($DFF074) till $8000. I
BLTBDAT ($DFF072) ska man skriva in linjens mask. Denna mask r 16 bitar
stor, allts ett word, och den anger hur linjen ska se ut. Om alla bitar r
satta och wordet r $FFFF s fr vi en solid linje utan hl, och det r
oftast det man vill ha.
  Vidare mste man stlla BLTAxWM ($DFF044) till $FFFFFFFF fr att inte
maska bort ngot p linjen.
  Sedan ska man anvnda sig av DX och DY och fra in 4*(DX-DY) i BLTAMOD
($DFF064), 4*DY i BLTBMOD ($DFF062) och till sist (4*DY)-(2*DX) i BLTAPT
($DFF074).
  I BLTCMOD ($DFF060) och BLTDMOD ($DFF066) skall bredden p skrmen i
bytes skrivas in.
  BLTCPT ($DFF048) och BLTDPT ($DFF054) ska innehlla linjens frsta pixels
position i ett word. Med det menas egentligen bara de lgsta fyra bitarna i
X-koordinaten. Om X t.ex r 134, %10000110 binrt, ger siffran 6 som r de
fyra lgsta bitarna %0110.

  BLTCON0 ska se ut fljer:

BIT#   BLTCON0   Beskrivning
----   -------   -----------
 15    START3    I bit 12-15 ska de fyra lgsta bitarna i frsta
 14    START2    X-koordinaten skrivas in.
 13    START1
 12    START0
 11      1       Den hr biten r SRCA-biten egentligen. Den ska alltid
                 vara 1 nr man ritar linjer.
 10      0       SRCB ska alltid vara 0
 09      1       SRCC ska alltid vara 1
 08      1       DEST ska ocks alltid vara 1!
 07     LF7      Minterm bit
 06     LF6        "      "
 05     LF5        "      "
 04     LF4        "      "
 03     LF3        "      "
 02     LF2        "      "
 01     LF1        "      "
 00     LF0        "      "

Mintermen brukar oftast vara AB+aC, dvs A och B eller icke A och C. Detta
gr att en helt vanlig linje ritas ut utan ngra modifikationer. Om
mintermen ABc+aC vljs, allts A och B och icke C eller icke A och C,
kommer en EOR-linje ritas ut. EOR betyder att linjen inverteras nr den
skrivs ver redan existerande pixlar. Detta kan vara anvndbart om man vill
plocka bort linjer snabbt. D behver man allts bara rita ut linjen nnu
en gng p samma stlle och s plockas ju linjen automatiskt bort.
  EOR-metoden ska vi anvnda nr vi gr fyllda vektorer. Dr krvs EOR fr
att ytorna ska frglggas rtt, men det kommer i ngon lektion lngre fram.

Okej, i BLTCON1 mste vi skriva in fljande saker:

BIT#   BLTCON1   Beskrivning
----   -------   -----------
 15    TEXTURE3  Start bit i ett word fr linjens mask.
 14    TEXTURE2
 13    TEXTURE1
 12    TEXTURE0
 11       0      Reserverade fr nya funktioner
 10       0
 09       0
 08       0
 07       0
 06      SIGN    Tecken-flagga. Ska sttas om BLTAPT r negativt
 05       0
 04      SUD     De hr tre bitarna (SUD, SUL och AUL) anger oktant-numret
 03      SUL
 02      AUL
 01      SING    Endast en pixel per rad. Anvnds vid areafyllning.
 00      LINE    Ska sttas till 1 vid linjeritning.

Allra sist (som vanligt) ska man skriva in linjens storlek i BLTSIZE
($DFF058) och det fungerar s att blithjden (bit 6-15) r linjens lngd
och blitbredden r alltid 2.
  Sdr, nu ska vi titta p hur programexemplet r konstruerat!


                              Programexemplet
                              
Programmet jag gjort den hr gngen visar hur en linjerutin fungerar, och
det ritar upp tv enkla figurer fr att demonstrera att rutinen funkar.
  Om vi tittar p sourcen s ser vi att den inte bjuder p ngra direkta
nyheter fram till subrutinen DRAW.
  Dr lgger jag in de vrden som krvs av linjeritnings rutinen, dvs
skrmens brjan, dess bredd i bytes och linjens mask eller textur. Sen
skriver jag in linjens start X, start Y och slut X, slut Y i D0, D1, D2 och
D3. Efter det hoppar jag till rutinen DrawLine som ritar ut linjen.
  Detta upprepar jag tre gnger fr att rita triangelns tre sidor.
  Sedan ritar jag ut fyrhrningens sidor p ett smartare stt, som gr ut
p att jag lser frn en tabell istllet och ritar varje linje s att den
hnger ihop med den frra.
  Jag gjorde de olika objekten p dessa stt bara fr att ni skulle frst
hur linjerutinen fungerar, och sen fr att se en enklare metod att rita
linjer p.
  Om vi vandrar vidare ner i sourcen s ser vi snart rutinen DrawLine.
  I brjan av den rutinen kollar vi s att inte linjen brjar och slutar p
samma punkt, fr i s fall kan vi inte rita ut den, och d hoppar vi
istllet ut.
  Sedan rknar vi ut, precis som vid vanlig blitteranvndning, var frsta
Y-koordinaten hamnar i fr byte-rad nr den multiplicerats med
skrmbredden. Vi tar ven fram ett delta Y vrde och ett delta X vrde som
sedan anvnds bde till att ta fram rtt oktant och till variablerna DX och
DY.
  Oktanten tas fram p ett ganska smart stt genom att anvnda sig av
SUB-instruktionens sttning av X-flaggan nr resultatet blir negativt. P
s stt kan man genom tre subtraktioner och tre ROXL-instruktioner (som
skiftar in X-flaggan i registrets lgsta bit) f fram en trebitars
oktant-kombination som pekar p ett visst vrde i en oktant-tabell dr rtt
oktant-vrde finns placerat som en byte.
  Detta r mycket smidigare n att jmfra delta-vrdena och hoppa hit och
dit fr att stta olika vrden p oktanten.

Efter det tar vi reda p vilket av vra delta-vrden som r strst,
eftersom DX ska innehlla det strsta talet.
  Sedan stter jag alla framrknade vrden i blitter-registren. Notera att
jag anvnder mintermen AB+aC fr att rita en vanlig, OR-linje utan
modifikationer.
  Det var nog allt, tror jag. Om ni inte frstr ngot s kan ni alltid
frga mig, s ska jag frklara s gott jag kan.
  I nsta lektion ska jag frklara hur tredimensionell vektor-rotering gr
till! Men tills dess, hll tillgodo med linjeritningen!
