Amiga Dünyası sayı 23, sayfa 37

Bu sayfadaki yazılar

Sayfanın metni

Sayfa 37

Göze çarpan diğer bir konu da program başında ve sonunda iki library fonksiyonu kullanmış olmam. Bunlar Exec library'sinden Forbid ve Permit. Her ikisinin de kullanım şeklini ve amaçlarını bu ayki Amiga ve Assembler köşesinde detaylı olarak açıkladım.

Programın CreateSprites altrutini ilk sprite datalarının sprite'ın görüntüsünü tanımlayan kısmını tüm sprite'lara kopyalamakta. Hemen ardından da 8 sprite'ın adresleri copper listesine yazılmakta. Dilerseniz siz 8 değişik sprite görüntüsü kullanın. Fakat bunun için CreateSprites altrutinin ilk kısmını silerek her sprite datasını ayrı olarak girmeniz gerekmekte. Aynı zamanda sprite renklerini de doğru girmeniz lazım.

Ana döngü içerisinde demin de belirttiğim gibi ufak boş bir döngü ve sprite hareket ettirme rutinine bir dallanma (bsr MoveSprites) bulunmakta. MoveSprites rutinine baktığımızda burada ilk önce SprNo değişkeninin içeriğinin d7 register'ine kopyalandığını görmekteyiz. Bu değer o an hareket ettirilecek sprite numarasıdır ve MoveSprite rutininden çıkmadan hemen önce her seferinde bir artırılmakta. SprNo, 8 olduğunda da tekrar sıfırlanmakta. Bu şekilde her seferinde sadece bir sprite'ı hareket ettirmekteyiz. Tüm 8 sprite'ı da aynı anda hareket ettirmek çok zaman alacaktı. Nedeni de her seferinde sprite y koordinatlarının bir tablodan okunmasından kaynaklanmakta.

Dediğim gibi, sprite y koordinatı bir data tablosundan okunmakta. Fakat tüm y koordinatlarını aynı tablodan okumaya kalkıştığımızda tüm 8 sprite'ın y pozisyonları aynı olur. Bunu engellemenin iki yöntemi var; ilki gayet basit. Her sprite için ayrı bir data tablosu çıkarmak. Fakat bu şekilde bir rutin dergimizde fazla yer kaplayacağından dergimizin editörü Mahmure Abla, kızarak evime gizlice girip source disketlerimi formatlayabilir. Bu yüzden ben ikinci yöntemi kullanmak zorunda kaldım. Bu şekilde siz de yeni bir teknik daha görebilirsiniz.

Tüm sprite'larımız nasıl olsa sinüzoidal bir hareket yapacaklar. Ben de sadece bir sinüs tablosu kullanmaya karar verdim. Fakat bu sinüs tablosunun 8 ayrı yerini gösteren 8 ayrı pointer kullanarak her sprite'ın y koordinatının farklı olmasını sağladım. MoveSprites rutininde de her seferinde sprite numarasına denk düşen pointer'ın gösterdiği değer okunmakta. Eğer bu değer $ff'den farklıysa, direkt olarak VSTART'a yazılmakta. Bu değere 14 (sprite yüksekliği) ekleyerek de VSTOP değerini bulmaktayız. Değer $ff olduğunda ise sprite numarasına denk düşen pointer'ın tekrar sinüs tablosunun başını göstermesi sağlanmakta. HSTART, yani sprite'ın yatay koordinatı da her seferinde 1 artırılmakta. Rutinin sonunda da kullanılan pointer 1 artırılarak bir sonraki kullanım için hazırlanmakta.

Gayet basit, değil mi? Programın açıklaması da burada bittiğine göre bana artık sadece size hoşça kalın demekten başka bir şey kalmıyor.

; >>>>>>>>>>>>><<<<<<<<<<<<<< ; >GELISMIS ASSEMBLER KURSU< ; >>SPRITE DEMO PROGRAMI 02<< ;>> byCemGENCER-1992 << ; >>>>>>>>>>>>><<<<<<<<<<<<<< Q: movem.l d0-d7/a0-a6,-(a7) move.l 4,a6 jsr -132(a6) lea GFXNAME,a1 jsr -408(a6) move.l d0,GFXBASE

move.l #64,d7 lea $45000,a0 CLEAR: clr.b (a0)+ dbf d7,CLEAR bsr.L CREATECOPPERS bsr.L CREATESPRITES LOOP: move.l #800.d2 IRQ: dbf d2,IRQ bsr.L MOVESPRITE MOUSE: btst #6,$bfe001 bne.s LOOP bra.s FİN FIN: move.l GFXBASE,a0 add.l #50,a0 move.l OLDCOPPER,(a0) move.l 4,a6 jsr -138(a6) movem.l (a7)+,d0-d7/a0-a6 rts CREATECOPPERS: lea NEWCOPPER+172,a0 move.l #$4007fffe,d1 move.l #$0180000f,d2 move.l #15,d7 CREATECOPI: move.l d1,(a0)+ move.l d2,(a0)+ add.l #$050000O0,d1 sub.l #$00000001,d2 dbf d7,CREATECOP1 move.l dl,(a0)+ move.l #$01800000,(a0)+ move.l #$a007fffe,d1 move.l #$01800000,d2 move.l #15,d7 CREATECOP2: * move.l d1,(a0)+ move.l d2,(a0)+ add.l #$05000000,d1 add.l #$00000001,d2 dbf d7,CREATECOP2 move.l d1,(a0)+ move.l #$01800000,(a0)+

move.l GFXBASE,a0 add.l #50,a0 move.l (a0),OLDCOPPER move.l #NEWCOPPER,(a0) rts

CREATESPRITES: lea SPRITE1+4,a1 move.l #6,d6 NEXTSPRITE: lea SPRITE0+4,a0 move.l #29,d7 COPYSPRITE: move.w (a0)+,(a1)+ dbf d7,COPYSPRITE add.l #4,al dbf d6,NEXTSPRITE clr.l d5 lea SPRITEO,a0

move.l #7,d7 ASSIGNSPRITLS: lea NEWCOPPER.a1 move.l a0,d0 move.l a0,d1 swap d1 and.l #$ffff.d0 and.l #$ffff.d1 move.w dl,6(al,d5) move.w d0,10(a1.d5) add.l #8,d5 add.l #64,a() dbf d7,ASSIGNSPRITES rts

MOVESPRITE: move.l SPRNO.d7 move.l d7,d6 asl.w #2,d6 clr.l d0 CONT: ^^^ lea SINUSPOINTERS,a0 move.l (a0,d6),a0 move.b (a0),d0 cmp.b #$ff,d0 beq.s SINUSEND lea SPRITES,a1 move.l (a1,d6),a2 move.b d0,0(a2) add.b #14,d0 move.b d0,2(a2) add.b #1,1(a2) lea SINUSPOINTERS,a0 add.l #1,(a0,d6) add.l #1,SPRNO move.l SPRNO,d7 cmp.l #8,d7 blt.s LESS move.l #0,SPRNO LESS: Rts SINUSEND: lea SINUSPOINTERS,a0 lea SINUSTAB,a1 move.l a1,(a0,d6) bra.s CONT ; >>>>>>>>>>>>><<<<<<<<<<<<< ; > Turn dataları buradan sonra ... < ; >>>>>>>>>>>><<<<<<<<<<<<<< NEWCOPPER: dc.w $0100,$1200 dc.w $0120,$0000,$0122,$0000 dc.w $0124,$0000,$0126,$0000 dc.w $0128,$0000,$012a,$0000 dc.w $012c,$0000,$012e,$0000 dc.w $0130,$0000,$0132,$0000 dc.w $0134,$0000,$0136,$0000

Klavyeyle gezinmek için ← ve → tuşları.