_______ ___ ___ __ _______ _______ _ _\_____ \_/ Y \_/ \_/ _____/___\_____ \__ _ /X\ _______ __ _ / __/ _ \_/ _ _ \__ _ __/ _///__// \\ // _ / ! l _ ! l _ l _ ! l _ ! l _ \X/ Amiga Power \\\__________///__l____///__///_______///_______/// \\________ __ _ _ _ ___________ _______ __ ___ __ __________ __________ /X\ __\\\_ __ \_/ _ \_/ Y Y \_/ ______/_\___ / __// \\ // / l \ | _ ! ! _ ____/ _ _/ __/_ \\ // / ______/ ! l _ ¡ l _ ! l _ \ l _ \X/ \_____\ sox \_________///___l_____///________///__\_____/// Amiga Power BBS - BBS:en som växer så det knakar! * Senaste AmiNet skivan (#15) * Stor Amigaarea med alla de bästa och nyaste filerna * Ca 2299 C64-spel * Ca 4437 SID-moduler * Ca 100MB MAC-spel att köra i t.ex. ShapeShifter * Stor programmeringsarea * Dessutom finns det bilder, moduler, texter och massa annat * Minst 50MB nya filer varje vecka * Över 100 möten, både lokala och nätmöten ----------> Ring NU! 08-395099 <---------- ; Kommentartecknena i vänsterkanten är till för att man ska kunna ta ; delar av denna text och infoga direkt i sin källkod. ; DOTS - Den kompletta guiden ; av Boki/Defiance ; ; Hej! ; ; Jag heter Anders Tornblad, och kallar mig Boki. Jag är med i gruppen ; Defiance. Jag tänkte att du kanske ville lära dig lite om hur man får ; sina punkter (dottar) att flyta fint. Jag försöker leda dig genom de ; olika stegen i stjärnfält, dottunnlar och andra punkter en bit i taget. ; ; Alla källkodsexempel finns upptagna med 020-optimering, där så är ; möjligt (hej, alla 1200-coders). ; ; Prova att göra så, att en rutin räknar ut "or"-grejerna och en annan ; sätter ut punkterna med hjälp av en tabell med "or"-värden och offseter ; som skapas av den förra. ; ; Det gör inte så mycket om det tar lite tid att räkna ut denna tabel, ; eftersom tiden som skärmrensningen tar kan kortas ner till minimum! ; ; Såhär skulle punkterna sättas ut: setdots: lea.l dottable,a0 lea.l screen,a1 move.w numdots,d7 ;antal punkter minus ett ligger här. .lp movem.w (a0)+,d0/d1 ;d0 = or-värdet d1 = offseten or.b d0,(a1,d1.w) dbra d7,.lp rts ; Nu kan du rensa skärmen genom att bara plöja genom tabellen såhär: clrdots: lea.l dottable,a0 lea.l screen,a1 move.w numdots,d7 ;antal punkter minus ett ligger här. .lp movem.w (a0)+,d0/d1 ;d0 = or-värdet d1 = offseten ;vi behöver inte d0, men jag har för mig att ;en movem.w (ax)+,2rx är det snabbaste sättet ;att hämta vart annat word från en tabell. clr.b (a1,d1.w) dbra d7,.lp rts ; eller kanske såhär: (beror på vad som är snabbast, jag har inte kollat, ; men jag antar att den förra är 2 cykler snabbare per punkt på en 68000, ; ingen av rutinerna använder sig av 68010's 3-words-cache tyvärr, men ; passar perfekt på alla 68020+ med instruktionscache påslagen) clrdots2: lea.l dottable,a0 lea.l screen,a1 moveq.l #2,d2 move.w numdots,d7 ;antal punkter minus ett ligger här. .lp move.w (a0,d2.w),d1 addq.l #4,d2 clr.b (a1,d1.w) dbra d7,.lp rts ; En 68020-optimerad version (kanske snabbare) ser ut såhär: clrdots020: lea.l dottable+2,a0 ;pekar på första offseten lea.l screen,a1 move.w numdots,d7 ;antal punkter minus ett ligger här. .lp move.w (a0,d7.w*4),d1 ;vet inte riktigt om denna är snabbare än ;movem.w (a0)+,d0/d1 men kolla gärna upp detta. clr.b (a1,d1.w) dbra d7,.lp rts ; OBS! Tänk på, att denna (020-optimerade) rutin rensar alla punkterna ; baklänges, alltså sista punkten rensas först. Kan vara bra att veta om ; det är något som inte riktigt ser ut som du tänkt dig när du kollar ; rutinens verkan... ; ; Att rensa skärmen på detta sätt är otroligt mycket snabbare än att ; använda blittern (eller processorn på 020 och uppåt). I alla fall tills ; du kommer upp i en 8-10 tusen stjärnor. Då börjar det bli snabbare att ; tömma hela skärmen med blitter eller processor, beroende på hur stor ; skärmen är, men för "normala" punkt-skärmar är denna metod alltid ; snabbast! ; ; Okej. Nu ska vi snabba upp beräkningen... ; ; Man kan ha en förberäknad beräkningshjälptabell, som bara innehåller ; vilka or-värden och offseter som ett visst x-värde medför. ; Detta snabbar upp själva beräkningen av ovanstående tabell avsevärt om ; man har x- och y-koordinater för sina punkter. Om man räknar ut ; tabellen med utgång av något annat än x- och y-koordinater, kanske inte ; denna metod är snabbast men i de flesta fall borde den slå det mesta! ; Denna förberäknade tabell kan antingen inkluderas i objekt-koden eller ; beräknas med en ultrakort och blixtsnabb rutin och läggas i en ; BSS-sektion. Bra för 40K-intros: precalc: lea.l calctable,a0 move.w #319,d7 ;för en 320 pixels bred skärm. Se till att inga ;koordinater hamnar utanför eller öka bredden ;på denna tabell .lp move.w #319,d0 sub.w d7,d0 moveq.l #7,d1 ;detta är en "byte-or"-version... and.w d0,d1 moveq.l #-128,d2 lsr.w d1,d2 move.w d2,(a0)+ lsr.w #3,d0 move.w d0,(a0)+ dbra d7,.lp rts ; Ovanstående rutin kan snabbas upp marginellt med en 020-optimering, som ; ser ut såhär: precalc02: lea.l calctable,a0 lea.l calctable+2,a0 move.w #319,d7 .lp move.w d7,d0 moveq.l #7,d1 ;detta är en "byte-or"-version... and.w d0,d1 moveq.l #-128,d2 lsr.w d1,d2 move.w d2,(a0,d7.w*4) lsr.w #3,d0 move.w d0,(a1,d7.w*4) dbra d7,.lp rts ; Om du har en tabell med 2D-koordinater (bara x- och y-värden) i minnet, ; kan du räkna ut den nya or- och offsettabellen såhär snabbt: makedottable2d: lea.l xytable,a0 lea.l dottable,a1 lea.l calctable,a2 ;Pekar på första or-värdet lea.l calctable+2,a3 ;Pekar på första x-offseten move.w numdots,d7 ;antal punkter minus ett ligger här. .lp movem.w (a0)+,d0/d1 ;d0=x d1=y lsl.w #6,d1 ;multiplicerar d1 med 64 för att få y-offset add.w d0,d0 ;dessa två rader multiplicerar d0 med 4, för add.w d0,d0 ;att få rätt offset i calctable. add.w (a3,d0.w),d1 ;addera x-offset till y-offset move.w (a2,d0.w),(a1)+ ;kopiera över or-värdet till vår nya tabell move.w d1,(a1)+ ;kopiera över offseten också dbra d7,.lp ;next please... rts ; Och så en 020-optimerad version: makedottable2d020: lea.l xytable,a0 lea.l dottable,a1 lea.l calctable,a2 ;Pekar på första or-värdet lea.l calctable+2,a3 ;Pekar på första x-offseten move.w numdots,d7 ;antal punkter minus ett ligger här. .lp movem.w (a0)+,d0/d1 ;d0=x d1=y lsl.w #6,d1 ;multiplicerar d1 med 64 för att få y-offset add.w (a3,d0.w*4),d1 ;addera x-offset till y-offset move.w (a2,d0.w*4),(a1)+;kopiera över or-värdet till vår nya tabell move.w d1,(a1)+ ;kopiera över offseten också dbra d7,.lp ;next please... rts ; I ovanstående rutiner (2d och 2d020), så ser du på rad 7 att jag ; multiplicerar y-koordinaten med 64 för att få y-offset. Detta ; förutsätter, att skärmen är 64 bytes (512 pixels) bred. Men, kanske du ; tänker, jag vill bara ha en normalbred skärm med 320 pixlar, eller ; kanske med overscan på 336 eller 352 pixlar, så då borde jag ju ; multiplicera med 40, 42 eller 44 istället. ; ; Njaaa... Vi ska hela tiden sträva efter att få bort så många ; tidskrävande instruktioner som möjligt, så en multiplikation är ju ; utesluten! Självklart kan man ju använda följande knep för att ; multiplicera med 40: ; ; lsl.w #3,d1 ;Multiplicerar med 8 (= 8x) 8 cykler ; move.w d1,d2 ;Flyttar över talet 4 cykler ; add.w d2,d2 ;Multiplicerar med 2 (= 16x) 4 cykler ; add.w d2,d2 ;Multiplicerar med 2 (= 32x) 4 cykler ; add.w d2,d1 ;Adderar (= 32x + 8x = 40x) 4 cykler ; ; Detta tar 24 cykler till skillnad från en "mulu #40,d1", som tar upp ; 80-nånting... Vet inte säkert, men många är det. En enda lsl.w #6,d1 ; som jag använder för att multiplicera med 64, tar endast 8 cykler!!! ; ; För att snabbt multiplicera med 42: ; ; add.w d1,d1 ;Multiplicerar med 2 (= 2x) 4 cykler ; move.w d1,d2 ;Flyttar över talet 4 cykler ; add.w d2,d2 ;Multiplicerar med 2 (= 4x) 4 cykler ; add.w d2,d2 ;Multiplicerar med 2 (= 8x) 4 cykler ; move.w d2,d3 ;Flyttar över taler 4 cykler ; add.w d3,d3 ;Multiplicerar med 2 (= 16x) 4 cykler ; add.w d3,d3 ;Multiplicerar med 2 (= 32x) 4 cykler ; add.w d3,d2 ;Adderar (= 32x+8x=40x) 4 cykler ; add.w d2,d1 ;Adderar (=32x+8x+2x=42x) 4 cykler ; Summa: 36 cykler ; För att snabbt multiplicera med 44: ; ; add.w d1,d1 ;Multiplicerar med 2 (= 2x) 4 cykler ; add.w d1,d1 ;Multiplicerar med 2 (= 4x) 4 cykler ; move.w d1,d2 ;Flyttar över talet 4 cykler ; add.w d2,d2 ;Multiplicerar med 2 (= 8x) 4 cykler ; move.w d2,d3 ;Flyttar över taler 4 cykler ; add.w d3,d3 ;Multiplicerar med 2 (= 16x) 4 cykler ; add.w d3,d3 ;Multiplicerar med 2 (= 32x) 4 cykler ; add.w d3,d2 ;Adderar (= 32x+8x=40x) 4 cykler ; add.w d2,d1 ;Adderar (=32x+8x+4x=44x) 4 cykler ; Summa: 36 cykler ; ; Så håll helst dina punkt-skärmar jämna 2-potenser bytes breda, så tar ; alla multiplikationer för y-koordinaten bara 8 cykler. Lämpliga bredder ; är 32 bytes (256 pixels), 64 bytes (512 pixels) eller 128 bytes (1024 ; pixels för högupplösning kanske...) vilka du multiplicerar med en lsl.w ; på respektive #5 #6 och #7. Om du vill ha punkter över hela skärmen, är ; det alltså bara att sätta en bred skärm (512 pixels i lågupplösning) ; och sätta passande värden i modulo-registrena ($dff108 och $dff10a). ; ; Om din tabell är av 3D-varianten (kanske ett stjärnfält eller någon ; form av dottunnel), så måste du (tyvärr) multiplicera dina x- och ; y-koordinater med z-koordinaten (djupet). Multiplikationer är ; mycket tidskrävande. ; ; När du har 3d-koordinater, måste du vanligtvis sätta origo (origo är ; koordinaternas noll-punkt) i mitten av skärmen, för annars kommer alla ; punkter att "utgå" från det övre vänstra hörnet av din skärm. Vissa ; rutiner (som en dottunnel) kräver att en olika grupp av punkter har ; olika origo, men mer om det senare. ; ; Z-värdet (djupet) brukar jag lägga mellan 0 och 65535 (2^16-1). När Z=0 ; är alla punkter samlade i origo, och när Z=65535, är punkterna (nästan) ; där de ska vara (en pixel närmare mitten). För att åstadkomma denna ; djup-effekt, måste du multiplicera både X- och Y-koordinaten med Z och ; sedan dividera med 65536. Division med 65536 sker med hjälp av swap- ; instruktionen. Tänk på, att använda muls och inte mulu vid ; multiplikationen. Om du använder mulu (unsigned), kommer processorn ; inte att ta hänsyn till teckenbiten (bit 15) och därför kommer alla ; negativa koordinater att hamna "fel", så använd muls (signed). ; ; I och med 020 kan du multiplicera 32- och 64-bitars ord i en och samma ; multiplikation, så då kan du använda det för att ta bägge koordinaterna ; i ett svep, men om du vill att det ska funka på en tidig Amiga, måste ; du göra ungefär såhär: makedottable3d: lea.l xyztable,a0 lea.l dottable,a1 lea.l calctable,a2 ;Pekar på första or-värdet lea.l calctable+2,a3 ;Pekar på första x-offseten move.w numdots,d7 ;antal punkter minus ett ligger här. .lp movem.w (a0)+,d0/d1/d2 ;d0=x d1=y d2=z muls d2,d0 ;Här multiplicerar vi X med z. muls d2,d1 ;Här multiplicerar vi Y med z. swap d0 ;Här dividerar vi X med 65536. swap d1 ;Här dividerar vi Y med 65536. add.w #160,d0 ;Adderar med skärmens mittpunkt i X-led add.w #128,d1 ;Adderar med skärmens mittpunkt i Y-led ; Nu har vi "riktiga" 2D-koordinater i d0 och d1, så nu bara fortsätter ; vi enligt den förra (2d) rutinen: lsl.w #6,d1 ;multiplicerar d1 med 64 för att få y-offset add.w d0,d0 ;dessa två rader multiplicerar d0 med 4, för add.w d0,d0 ;att få rätt offset i calctable. add.w (a3,d0.w),d1 ;addera x-offset till y-offset move.w (a2,d0.w),(a1)+;kopiera över or-värdet till vår nya tabell move.w d1,(a1)+ ;kopiera över offseten också dbra d7,.lp ;next please... rts ; Den 020-optimerade versionen kommer att se ut såhär: makedottable3d020: lea.l xyztable,a0 lea.l dottable,a1 lea.l calctable,a2 lea.l calctable+2,a3 move.w numdots,d7 ;antal punkter minus ett ligger här. .lp movem.w (a0)+,d0/d1/d2 ;d0=x d1=y d2=z muls.l d2,d0:d1 ;Här multiplicerar vi X och Y med z. swap d0 ;Här dividerar vi X med 65536 swap d1 ;Här dividerar vi Y med 65536 add.w #160,d0 ;Adderar med skärmens mittpunkt i X-led add.w #128,d1 ;Adderar med skärmens mittpunkt i Y-led lsl.w #6,d1 ;multiplicerar d1 med 64 för att få y-offset add.w (a3,d0.w*4),d1 ;addera x-offset till y-offset move.w (a2,d0.w*4),(a1)+;kopiera över or-värdet till vår nya tabell move.w d1,(a1)+ ;kopiera över offseten också dbra d7,.lp ;next please... rts ; För att göra ett väldigt primitivt stjärnfält (där stjärnorna kommer ; mot skärmen), kan du helt enkelt tillfoga en rutin som ökar varje ; punkts Z-värde med en viss hastighet. Du kan enkelt lägga in två rader ; i själva "makedottable3d"-rutinen precis innan du hämtar värdena: ; move.w hastighet,d3 ;denna rad ligger innan loopen. ;.lp add.w d3,4(a0) ;ökar Z-värdet med hastigheten. ; movem.w (a0)+,d0/d1/d2 ;rutinen fortsätter som vanligt ; Om du gör detta, kommer du att se, att stjärnorna bara "glider" på, ; helt utan 3D-känsla. Detta beror på, att vi inte har lagt till något ; perspektiv till stjärnorna. ; ; Perspektivet ska egentligen (rent matematiskt) gå till som så, att man ; multiplicerar inte med själva Z-värdet, utan med ett speciellt värde, ; som bland annat bygger på bildskärmens storlek och ögats avstånd till ; bildskärmen. ; ; Som du säkert förstår, är det omöjligt att räkna ut hur stor TV eller ; monitor som används och hur långt bort tittaren sitter, så vi helt ; enkelt anta, att han sitter på ett visst avstånd. Självklart räknar vi ; inte ut dessa värden för varje punkt, utan vi förberäknar en tabell som ; innehåller de olika perspektivvärdena för olika Z-värden. ; ; Vi ska ha ett perspektivvärde för varje Z-värde. Hoppsan! Det blev ; visst en hel del värden! Eftersom vi ska multiplicera X och Y med ett ; word (mellan 0 och 65535), kommer varje perspektivvärde att ta upp ; två bytes. Om vi då ska ha 65536 Z-värden, kommer vår perspektivtabell ; att ta upp 131072 bytes (128 kbytes)!!! ; ; Det är alltså ingen praktisk lösning om vi ska ha 65536 Z-värden. Men ; det enda kravet är ju, att X och Y multipliceras med ett värde mellan ; 0 och 65535, och inte att just Z är mellan 0 och 65535. Eftersom vi nu ; inte kommer att multiplicera direkt med Z-värdet, så går istället detta ; krav över till perspektivvärdet. Det är alltså perspektivvärdet, som ; måste ligga mellan 0 och 65535. Z-värdena kan vi istället välja i en ; mindre skala. ; ; En bra skala är mellan 0 och 255. Detta ger lagom upplösning i djupled ; och ger en perspektivvärdestabell på bara 512 bytes. Vill du ha finare ; upplösning i djupled, går det bra med 512, 1024 eller 2048 värden också ; men du får ha minneskapaciteten i bakhuvudet lite grann, särskilt om du ; ska göra ett 40K-intro eller liknande. ; ; Man behöver inte följa de matematiska reglerna slaviskt, men jag har ; förberäknat några tabeller, som du får använda till vad du vill. Jag ; har valt värden, som jag själv tycker ger en snygg stjärnrutin. Filerna ; finns som både källkod och som datafiler och ligger i detta arkiv. ; Filerna heter: ; ; Perspektiv/Pers128.Dat 128 värden datafil ; Perspektiv/Pers256.Dat 256 värden datafil ; Perspektiv/Pers256.S 256 värden källkod ; Perspektiv/Pers512.Dat 512 värden datafil ; Perspektiv/Pers512.S 512 värden källkod ; Perspektiv/Pers1024.Dat 1024 värden datafil ; Perspektiv/Pers2048.Dat 2048 värden datafil ; ; Beräkningsrutinen finns också som källkod, så att du kan göra egna ; perspektivtabeller genom att ändra på några värden i rutinen. Den filen ; heter: ; ; Perspektiv/Perspektiv.S ; ; Nu när vi har ett perspektiv med i bilden, får vi göra följande ; förändringar i våra 3d-rutiner: makedottablepersp: lea.l xyztable,a0 lea.l dottable,a1 lea.l calctable,a2 ;Pekar på första or-värdet lea.l calctable+2,a3 ;Pekar på första x-offseten lea.l persptable,a4 move.w numdots,d7 ;antal punkter minus ett ligger här. .lp movem.w (a0)+,d0/d1/d2 ;d0=x d1=y d2=z add.w d2,d2 ;Multiplicera d2 med 2 eftersom varje värde i ;perspektivtabellen är ett word. move.w (a4,d2.w),d2 ;Hämta det tal vi ska multiplicera med (P) muls d2,d0 ;Här multiplicerar vi X med P. muls d2,d1 ;Här multiplicerar vi Y med P. ; Och så fortsätter rutinen som vanligt. En 020-optimering blir såhär: makedottablepersp020: lea.l xyztable,a0 lea.l dottable,a1 lea.l calctable,a2 lea.l calctable+2,a3 lea.l persptable,a4 move.w numdots,d7 ;antal punkter minus ett ligger här. .lp movem.w (a0)+,d0/d1/d2 ;d0=x d1=y d2=z move.w (a4,d2.w*2),d2 ;Hämta det tal vi ska multiplicera med (P) muls.l d2,d0:d1 ;Här multiplicerar vi X och Y med P. ; Och så vidare... ; När du nu ska addera varje Z-värde med en hastighet, för att få ; stjärnorna att komma närmare, måste du tänka på hur många värden du ; har i din perspektivtabell. Innan behövde du inte detta, eftersom ditt ; Z-värde "fungerade" mellan 0 och 65535. Nu kan Z-värdet bara ligga ; mellan 0 och 255 (om du har 256 värden i perspektivtabellen), så för ; att få dina stjärnor att komma närmare får du nu gör såhär: ; move.w hastighet,d3 ;denna rad ligger innan loopen. ;.lp add.w d3,4(a0) ;ökar Z-värdet med hastigheten. ; and.w #255,4(a0) ;ser till att Z-värdet inte blir "fel" ; movem.w (a0)+,d0/d1/d2 ;rutinen fortsätter som vanligt ; Denna and-instruktion sköter automagiskt om att stjärnorna går tillbaka ; till "längst bort" när de kommit längst fram, och om hastigheten är ; negativ, kommer de till "ytan" igen när de nått "botten". ; Dottunnlar kan åstadkommas med de tekniker som vi har sett ovan, men i ; detta fall använder man samma Z-värde (och alltså samma P-värde) för ; alla punkter i samma ring. ; ; Man behöver sätta upp en tabell med koordinater för en enda ring och ; sedan används dessa koordinater om och om igen, en gång för varje ring. ; Som vanligt har du en rutin som räknar ut or-värden och offseter och en ; som sätter ut punkterna. Du behöver en tabell, som innehåller avståndet ; för varje ring mellan skärmen och ringen. Uträkningen går till såhär: calctunneldots: move.w antalringar,d7 ;antal punktringar i tunneln lea.l dottable,a1 lea.l calctable,a2 ;pekar på första or-värdet lea.l calctable+2,a3 ;pekar på första x-offseten lea.l perptable,a4 lea.l ringtable,a5 ;pekar på en tabell med de olika ringarnas ;avstånd från skärmen .ring move.w numdots,d6 ;antal punkter i ringen minus en ligger nu här. lea.l xyztable,a0 ;pekar på 2d-koordinater move.w (a5)+,d2 ;Hämtar en rings avstånd add.w d2,d2 ;multiplicerar avståndet med två move.w (a4,d2.w),d2 ;hämtar perspektivvärdet för hela ringen .lp movem.w (a0)+,d0/d1 ;behöver inte hämta något Z-värde, eftersom ;det är samma värde för alla punkterna i ringen muls d2,d0 ;Multiplicera X med P. muls d2,d1 ;Multiplicera Y med P. swap d0 ;Dividera X med 65536. swap d1 ;Dividera Y med 65536. add.w #160,d0 ;Adderar med skärmens mittpunkt i X-led add.w #128,d1 ;Adderar med skärmens mittpunkt i Y-led lsl.w #6,d1 ;multiplicerar d1 med 64 för att få y-offset add.w d0,d0 ;dessa två rader multiplicerar d0 med 4, för add.w d0,d0 ;att få rätt offset i calctable. add.w (a3,d0.w),d1 ;addera x-offset till y-offset move.w (a2,d0.w),(a1)+ ;kopiera över or-värdet till vår nya tabell move.w d1,(a1)+ ;kopiera över offseten också dbra d6,.lp ;next dot please... dbra d7,.ring ;next ring please... rts ; Och som vanligt så får du en 020-optimering... calctunneldots020: move.w antalringar,d7 ;antal punktringar i tunneln lea.l dottable,a1 lea.l calctable,a2 ;pekar på första or-värdet lea.l calctable+2,a3 ;pekar på första x-offseten lea.l perptable,a4 lea.l ringtable,a5 ;pekar på en tabell med de olika ringarnas ;avstånd från skärmen .ring move.w numdots,d6 ;antal punkter i ringen minus en ligger nu här. lea.l xyztable,a0 ;pekar på 2d-koordinater move.w (a5)+,d2 ;Hämtar en rings avstånd move.w (a4,d2.w*2),d2 ;hämtar perspektivvärdet för hela ringen .lp movem.w (a0)+,d0/d1 ;behöver inte hämta något Z-värde, eftersom ;det är samma värde för alla punkterna i ringen muls.l d2,d0:d1 ;Multiplicera X och Y med P. swap d0 ;Dividera X med 65536. swap d1 ;Dividera Y med 65536. add.w #160,d0 ;Adderar med skärmens mittpunkt i X-led add.w #128,d1 ;Adderar med skärmens mittpunkt i Y-led lsl.w #6,d1 ;multiplicerar d1 med 64 för att få y-offset add.w (a3,d0.w*4),d1 ;addera x-offset till y-offset move.w (a2,d0.w*4),(a1)+;kopiera över or-värdet till vår nya tabell move.w d1,(a1)+ ;kopiera över offseten också dbra d6,.lp ;next dot please... dbra d7,.ring ;next ring please... rts ; Om du nu lägger till en succesiv ökning av avståndet för varje ring, ; så kommer varje ring att röra sig mot skärmen och skapa en tunnel- ; liknande effekt. Men det liknar fortfarande inte riktigt alla andra ; dottunnlar. Det beror på, att alla ringar utgår från samma origo, ; alltså alla ringar har mittpunkten (160,128). ; ; För att få tunneln att svänga och se bra ut, behöver vi infoga två nya ; värden för varje ring i "ringtable". Nu kommer första värdet att vara ; djupet, andra värdet origos X-del och tredje värdet origos Y-del. ; Såhär blir förändringen: calctunnel2dots: move.w antalringar,d7 ;antal punktringar i tunneln lea.l dottable,a1 lea.l calctable,a2 ;pekar på första or-värdet lea.l calctable+2,a3 ;pekar på första x-offseten lea.l perptable,a4 lea.l ringtable,a5 ;pekar på en tabell med de olika ringarnas ;avstånd från skärmen .ring move.w numdots,d6 ;antal punkter i ringen minus en ligger nu här. lea.l xyztable,a0 ;pekar på 2d-koordinater movem.w (a5)+,d2/d3/d4 ;Hämtar en rings avstånd och origo add.w d2,d2 ;multiplicerar avståndet med två move.w (a4,d2.w),d2 ;hämtar perspektivvärdet för hela ringen .lp movem.w (a0)+,d0/d1 ;behöver inte hämta något Z-värde, eftersom ;det är samma värde för alla punkterna i ringen muls d2,d0 ;Multiplicera X med P. muls d2,d1 ;Multiplicera Y med P. swap d0 ;Dividera X med 65536. swap d1 ;Dividera Y med 65536. add.w d3,d0 ;Adderar med ringens origo i X-led add.w d4,d1 ;Adderar med ringens origo i Y-led ; Här under fortsätter rutinen som vanligt. Jag skriver inte ut 020-optimeringen ; här, därför att det är exakt samma förändringar som ska utföras. ; Sådärja... Nu orkar jag inte skriva så mycket mer! Jag antar att detta ; är allt du behöver kunna för att göra både stjärnfält, dottunnlar och ; andra punkt-rutiner snabbare! ; Med vänliga hälsningar - Boki/Defiance ; Några frågor? Ring Necromica BBS - 0500-435485 Öppen 21.00-11.00 alla ; dagar och till 17.00 på vardagar. Chat-möjlighet finns efter 21.00. @BEGIN_FILE_ID.DIZText om hur man programmerar dotrutiner i assembler för demos och liknande. Skriven på svenska. Av Boki/Defiance @END_FILE_ID.DIZ _______ ___ ___ __ _______ _______ _ _\_____ \_/ Y \_/ \_/ _____/___\_____ \__ _ /X\ _______ __ _ / __/ _ \_/ _ _ \__ _ __/ _///__// \\ // _ / ! l _ ! l _ l _ ! l _ ! l _ \X/ Amiga Power \\\__________///__l____///__///_______///_______/// \\________ __ _ _ _ ___________ _______ __ ___ __ __________ __________ /X\ __\\\_ __ \_/ _ \_/ Y Y \_/ ______/_\___ / __// \\ // / l \ | _ ! ! _ ____/ _ _/ __/_ \\ // / ______/ ! l _ ¡ l _ ! l _ \ l _ \X/ \_____\ sox \_________///___l_____///________///__\_____/// Amiga Power BBS - BBS:en som växer så det knakar! * Senaste AmiNet skivan (#15) * Stor Amigaarea med alla de bästa och nyaste filerna * Ca 2299 C64-spel * Ca 4437 SID-moduler * Ca 100MB MAC-spel att köra i t.ex. ShapeShifter * Stor programmeringsarea * Dessutom finns det bilder, moduler, texter och massa annat * Minst 50MB nya filer varje vecka * Över 100 möten, både lokala och nätmöten ----------> Ring NU! 08-395099 <----------