MrGuppy |
25 August 2019 22:41 |
Flickering sprites::..
1 Attachment(s)
Hi!
Trying to learn about sprites and how to move them. The problem occurres when I try to move the sprite vertically, it starts to flicker and the data looks messy, horizontally it looks OK?
Sorry for the swedish code comments!
Code:
************************************************
*****************Initiera värden före mainloop***********************
************************************************
********************
* Allokera minne
********************
SECTION Sprite,CODE ; Allokera minne för koden
JUMPPTR init ; Hoppa till init
****************************************
********************** Konstanter ******************************
****************************************
****************************
* Konstanter för skärmen
****************************
bplsize =10240 ; Skärmstorleken på bitplanet -> 320*256/8
****************************************
************************ INIT *************************************
****************************************
init:
*******************************
* Spara undan Default COPPER
*******************************
moveq #0,d7 ; Flagga för spritens rörelse
moveq #9,d6 ; Sprite_flag
move.l 4.w,a6 ; För att kunna öppna ett LIBRARY -> execbase
clr.l d0
move.l #gfxname,a1 ; "gfxname" -> biblioteket vi vill öppna
; "gfxname" är deklarerad längre ned i
; koden
jsr -408(a6) ; Hoppa till "Open Library" i execbase, dvs
; funktionen "oldopenlibrary()"
; Nu har vi hamnat i "Graphics library", start
; adressen läggs i d0
move.l d0,a1
move.l 38(a1),d4 ; Fånga nuvarande "copper pointer" och
; spara i d4
jsr -414(a6) ; Hoppa till "Close Library" i execbase,
; funktionen "closelibray()"
************************
* Hantera interrupts
************************
move.w $dff01c,d5 ; Läs av alla interrupts och lägg i d5,
; dessa behövs senare när vi hoppar ur
; vår demo
move.w $dff002,d3 ; $dff002 -> Läser innehållet från DMACON
; Läs DMACON och lägg i d3
********************************
* "Wait for end of frame"
* Efter detta kan man börja
* läsa in sprites osv
********************************
move.w #$138,d0 ; #$138 ->312
bsr.w waitraster ; Hoppa till "waitraster"
; Waits for end of frame!
; Tar bort "Sprite flickers"!!!
move.w #$7fff,$dff09a ; Stäng av alla interuppts, mus osv!!!
; Disable all bits in INTENA
; $dff01c -> Läser interrupts, PEEK
; $dff09a -> Sätter interrupts, POKE
move.w #$7fff,$dff09c ; Stäng av alla "Interuppts Requests"
move.w #$7fff,$dff09c ; Görs 2 ggr så att demon även funkar på A4000
move.w #$87e0,$dff096 ; Stäng av alla "DMA" inklusive "COPPER DMA"
; (DMACON)
; $dff096 -> Skriver till DMACON
hwinit:
*****************************
* Hardware Init
*****************************
movem.l d0-a6,-(sp) ; Lägg alla variabler på stacken
lea screen,a1 ; lea -> Load the Effective Adress
; a1 kommer att peka på det
; reserverade minnet "screen"
move.w #bplsize-1,d0 ; 10240 -> d0
.l: move.b #0,(a1)+ ; Fyll "screen" med 0
dbf d0,.l ; Upprepa 10240 ggr
************************
* Läs in spritedata
* till sprite pointers
************************
lea SprP,a1 ; Peka på "sprite pointers"
lea spr,a0 ; Peka på "sprite data"
move.l a0,d1
swap d1
move.w d1,2(a1) ; Flytta skärmdata till SprP1, hi word
swap d1
move.w d1,6(a1) ; Flytta skärmdata till SprP1, lo word
************************
* Fyll resterande 7
* sprites med 0
************************
lea Nullspr,a0 ; Peka till adressen "Nullspr"
move.l a0,d1
moveq #7-1,d0 ; Antal loopningar
.sprpl: addq.w #8,a1 ; Hoppa till nästa sprite
swap d1
move.w d1,2(a1) ; Flytta skärmdata till SprP, hi word
swap d1
move.w d1,6(a1) ; Flytta skärmdata till SprP, lo word
DBF d0,.sprpl ; Loopa 7 ggr
*********************
* Enable COPPER DMA ; <- OBS! Super viktig!!!
*********************
move.w #$87e0,$dff096 ; Enable COPPER DMA -> Allt som behövs
; för att göra en demo, sprites, musik osv
************************
* Peka på COPPER
************************
move.l #copper,$dff080 ; $dff080 = "Copper first location register"
; move.l -> #copper = "Long Word" adress
; Ändra COPPER till vår egna modifierade COPPER
*********************************
******************** Mainloop ***************************
*********************************
mainloop:
****************************************
* Avvakta med att gå vidare med koden
* då raster är utanför skärmen, om inte
* detta görs skapas flimmer på sprites
****************************************
waitframe:
btst #0,$dff005 ; Är raster längst till vänster
; på skärmen?
bne.s waitframe
cmp.b #$2a,$dff006 ; Är rastern högst upp på skärmen?
; Vänta till Y-pos $2a eftersom
; copper börjar på $2b
bne.s waitframe
waitframe2:
cmp.b #$2a,$dff006 ; Är rastern högst upp på skärmen?
beq.s waitframe2
****************************************
* Sätt Sprite 1 i rörelse
* Origin x- and y-pos -> $6496,$7400
* Y-pos #$64 ->100
* X-pos #$96 ->150
****************************************
cmp #1,d7 ; Är flaggan för "up" satt?
beq.s up
lea.l spr,a1 ; Peka på spritedata
cmp.b #$e6,(a1) ; Är Y-pos=230?
beq.s up_flagga
down:
;add.w #1,(a1) ; X-pos
addq.b #1,(a1) ; Y-pos
addq.b #1,2(a1) ; Y-pos
bra.s continue
up:
lea.l spr,a1 ; Peka på spritedata
cmp.b #$64,(a1) ; Är Y-pos=100?
beq.s down_flagga
add.b #-1,(a1) ; Y-pos
add.b #-1,2(a1) ; Y-pos
continue:
*******************************
* Vänster musknapp nedtryckt?
*******************************
btst #6,$bfe001 ; Testa om vänster musknapp är nedtryckt
bne.s mainloop ; Om inte gå till "waitmouse"
exit:
************************
* Exit
************************
move.w #$7fff,$dff096 ; Stäng av alla "DMA" inklusive "COPPER DMA"
; (DMACON)
or.w #$8200,d3 ; Bit 9
move.w d3,$dff096 ; Sätt bit 9 i DMACON
move.l d4,$dff080 ; Lägg tillbaks "copper pointer" som
; vi sparade undan i d4
or #$c000,d5 ; Sätt bit 14 o 15 -> ?1<<14+1<<15
; Detta sätter på interruptsen igen!
move d5,$dff09a
rts
**************************************
*********************** ROUTINES *****************************
**************************************
******************************
* Wait for end of frame
* Tar bort sprite flimmer
******************************
waitraster:
move.l #$1ff00,d2 ; Masken läggs i d2
lsl.l #8,d0 ; d0 -> Y-pos($138 = 312)
; lsl -> Shifts bits to the left
and.l d2,d0 ; "Maska" d0 med d2
lea $dff004,a0 ; Read from Vertical
; and horizontal register and put it in a0
.wr move.l (a0),d1
and.l d2,d1 ; Maska även denna
cmp.l d1,d0
bne.s .wr
rts
up_flagga:
moveq #1,d7
bra.s continue
down_flagga:
moveq #0,d7
jmp continue
********************************
**************Deklarera "gfxname"******************
********************************
gfxname:
dc.b "graphics.library",0
*********************************
**************COPPER - CO PROCESSOR*******************
*********************************
SECTION Sprite_Data,DATA_C ; Allokera minne för all grafik(Copper)
spr:
************************
* Sprite Data
* Sprites är endast
* 16 bitar bred
************************
dc.w $6450,$7400 ; Start pos för Y och X -> $6496
; -> $64=Y-pos -> 100
; -> $96=X-pos -> 150
; Stop pos för Y och X -> $7400
; -> $74=Y-pos + sprite hight(16 hög)
; -> $00
; Formel för X-pos: %A0000SEH
; %A0000SEH -> 64 32 16 8 4 2 1
; H=1, E=2, S=4
; S->Start, E->End, H->Horizontal
; -> A = Attach bit, sätts till $00
; om man inte vill kombinera två sprites
dc.w %0000000000000000,%0000000000000000
dc.w %0000000000000000,%0000000000000000
dc.w %0000000000000000,%0000000000000000
dc.w %0000000000000000,%0000000011000000
dc.w %0000000000000000,%0000001111000000
dc.w %0000000000000000,%0000111111000000
dc.w %0000011111110000,%0001100000000000
dc.w %0001111111001000,%1100000000000000
dc.w %0011111111001100,%1100000000000000
dc.w %0011111111110000,%1100000000000000
dc.w %0011111111111100,%0100000000000000
dc.w %0001111111111000,%1100000000000000
dc.w %0000111111100000,%0000000000000000
dc.w %0000000000000000,%0000001111000000
dc.w %0000000000000000,%0000000011000000
dc.w %0000000000000000,%0000000000000000
dc.w 0,0
Nullspr: ; Dummy Sprite
dc.w $2a20,$2b00 ; Outside screen
dc.w 0,0
dc.w 0,0
Copper:
dc.w $1fc,0 ; Slow Fetch Mode -> AGA kompatibel(A1200)
; dc = define constant
dc.w $100,$0200 ; $100 = $dff100
; $dff100 = "Bitplane enable register"
; $100,$0200 -> Stänger av alla Bitplanes
***************************
* Sprite colors
***************************
dc.w $1a2,$f00 ; Dessa tre färgregister används för
dc.w $1a4,$fa0 ; sprite 0($122) och sprite 1($124)
dc.w $1a6,$fff
; För sprite 2($128) och 3($12c) använd
; färgregister $1a8, $1aa och $1ac
; osv.....................
SprP:
***************************
* Deklararera minne
* till sprites
* SpritePointers
***************************
dc.w $120,0 ; Peka på vår sprite data, "high word"
dc.w $122,0 ; Sprite 0($122), "low word"
dc.w $124,0 ; Alla sprites pekare måste sättas,
dc.w $126,0 ; man kan inte bara sätta en
; 8 sprites totalt!
dc.w $128,0
dc.w $12a,0
dc.w $12c,0
dc.w $12e,0
dc.w $130,0
dc.w $132,0
dc.w $134,0
dc.w $136,0
dc.w $138,0
dc.w $13a,0
dc.w $13c,0
dc.w $13e,0
dc.w $180,$000 ; Svart bakgrund
dc.w $100,$1200 ; Aktivera ett bitplan
dc.w $ffdf,$fffe ; Vänta med att sätta bakgrunds färg tills
; vi kommit till Y-pos $ff(256)
; och X-pos $df(223)
; Detta sätter färg "utanför" skärmens
; upplösning
dc.w $ffff,$fffe ; Väntar på en omöjlig rasterlinje, $ffff
SECTION spritebss,BSS_C
Screen:
ds.b bplsize ; Skärmstorleken på bitplanet
; -> 320*256/8, ej "interleaved"
; ds -> "Declare Space"
..::Mr Guppy
|