English Amiga Board

English Amiga Board (https://eab.abime.net/index.php)
-   Coders. Asm / Hardware (https://eab.abime.net/forumdisplay.php?f=112)
-   -   Flickering sprites::.. (https://eab.abime.net/showthread.php?t=98585)

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

phx 26 August 2019 12:11

Quote:

Originally Posted by MrGuppy (Post 1341215)
The problem occurres when I try to move the sprite vertically, it starts to flicker and the data looks messy, horizontally it looks OK?

Hmm. The only real bug that I see is that you don't set BPL1PT in your copper list, although you did enable one bitplane. When I assemble and test your code I see the background flicker, because the bitplane pointer runs wild through Chip RAM. No idea why it should flicker on vetical movement only. Don't see that here.

Quote:

Sorry for the swedish code comments!
I understand danish. So not a big problem.

MrGuppy 27 August 2019 00:54

Do I add the BPL1PT like this?:
Code:


        ****************************
        * Konstanter för skärmen
        ****************************
bplsize        =10240                ; Skärmstorleken på bitplanet -> 320*256/8
screen_m  =$60000               

--------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------

copperBplP:

        dc.w $e0,(Screen_m>>16)&$ffff
        dc.w $e2,(Screen_m)&$ffff

        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


roondar 27 August 2019 09:05

That should work, yes :great

...though it's probably best to make sure the memory used is actually allocated for when you want to start drawing stuff :D...

For tests like this, I'd use an extra section of type chip (usually anyway, sometimes it's data_c - it depends a bit on assembler used). For bigger programs launched from the OS, I normally just allocate the memory using the OS.

ross 27 August 2019 12:11

And alway remember to reset stack if you want a clean exit ;)
Code:

        movem.l d0-a6,-(sp)        ; Lägg alla variabler på stacken

phx 27 August 2019 17:36

Quote:

Originally Posted by MrGuppy (Post 1341457)
Do I add the BPL1PT like this?:

You already had your bitplane defined under the label "screen" in a Chip-RAM BSS section, which is absolutely correct. I would use this area by patching the address of screen into your copper list, like you did with sprP for the sprites.

Quote:

Originally Posted by ross (Post 1341505)
And alway remember to reset stack if you want a clean exit ;)

Wow... missed that. Good catch!

roondar 27 August 2019 18:14

Quote:

Originally Posted by phx (Post 1341560)
You already had your bitplane defined under the label "screen" in a Chip-RAM BSS section, which is absolutely correct. I would use this area by patching the address of screen into your copper list, like you did with sprP for the sprites.

I completely missed that in the original source. Turns out you need to scroll down to the bottom. Not a skill I have it seems.

Forget my comments about allocating then.

MrGuppy 27 August 2019 21:28

As mentioned I had forgot to restore the variabels when exit!
Code:

movem.l (sp)+,d0-a6

MrGuppy 28 August 2019 00:02

phx, is this the right way?

Code:

lea copperBplP,a1
lea screen,a0

move.l a0,d1
swap d1
move.w d1,2(a1)
swap d1
move.w d1,6(a1)

-----------------------------------------------------------------------------------
-----------------------------------------------------------------------------------

copperBplP:
          dc.w $e0,0
          dc.w $e2,0


phx 28 August 2019 15:14

Looking good.
Hint: You can save one "swap d1" when you write to 6(a1) first. ;)

MrGuppy 28 August 2019 21:12

Nice, thanks for the help! :)


All times are GMT +2. The time now is 16:07.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.

Page generated in 0.06625 seconds with 11 queries