background redrawing problem

Discussion in 'Discussion and Q&A Archive' started by SpirituInsanum, May 24, 2011.

Thread Status:
Not open for further replies.
  1. SpirituInsanum

    SpirituInsanum Well-Known Member Member

    Joined:
    Feb 11, 2010
    Messages:
    642
    I'm have problems with my redesigned version of Labyrinth background.


    I have some fake multiple parallax patterns designed to make the background look like it has 3 layers, the front layer is made of big blocks, there are holes in it to make the second layer visible, the second layer also has holes and a background layer is visible behind it.


    The effect requires a "classic" deformation. Stripes going from A0 to 3FF and 4A0 to 7FF have to move twice as fast as the ones in 0-9F and 400-49F for the effect to work properly.


    So far, it's ok, although the way I find to achieve this is kind of intricate and probably not optimal, and...


    I'm facing two problems:


    1- there are slowdowns, although I optimized the rev1 wave effect, and I can't really see a reason since what's actually being processed on each frame isn't much longer than it was originally.


    2- the fast moving stripe won't redraw properly. At one point, the background chunks look like they're being redrawn, one background chunk on the left, another background chunk on the right. Oddly enough, it looks like only one row of chunks is affected :/


    Here's my current background deformation:




    Deform_LZ:


    move.w ($FFFFF73A).w,d4


    ext.l d4


    asl.l #6,d4


    move.w ($FFFFF73C).w,d5


    ext.l d5


    asl.l #6,d5


    bsr.w ScrollBlock1


    move.w ($FFFFF70C).w,($FFFFF618).w


    lea (LZ_FG_Wave_Data).l,a3


    lea (LZ_BG_Wave_Data).l,a2


    moveq #0,d2


    moveq #0,d3


    move.b ($FFFFF7D8).w,d2


    move.b d2,d3


    addi.w #$80,($FFFFF7D8).w


    add.w ($FFFFF70C).w,d2


    andi.w #$FF,d2


    add.w ($FFFFF704).w,d3


    andi.w #$FF,d3


    lea ($FFFFCC00).w,a1


    move.w ($FFFFF700).w,d0


    neg.w d0


    move.w d0,d6


    swap d0


    move.w ($FFFFF708).w,d0


    neg.w d0


    move.w ($FFFFF646).w,d4


    move.w ($FFFFF704).w,d5


    add.w d2,d2


    adda.l d2,a2


    add.w d3,d3


    adda.l d3,a3


    move.w ($FFFFF70C).w,d2 ; load background's y position


    andi.w #$3FF,d2 ; mask it within pattern limits


    subi.w #$A0,d2 ; subtract height of the first stripe


    andi.w #$83FF,d2 ; mask within limits and allow negative values


    bpl.s @belowfirststripe ; if positive, branch to simple version


    ; within first stripe code:


    moveq #0,d1


    move.w #$9F,d1 ; load height of the first stripe


    move.w ($FFFFF70C).w,d2 ; load background's y position


    andi.w #$3FF,d2


    sub.w d2,d1 ; subtract position


    move.w d1,d3 ; save d1


    bsr.s Deform_LZ_global


    moveq #0,d1


    move.w #$DF,d1 ; total number of lines on screen


    sub.w d3,d1 ; count remaining lines to deform


    add.w d0,d0 ; double displacement speed


    bra.s Deform_LZ_global


    @belowfirststripe:


    moveq #0,d1


    move.w #$35F,d1 ; load beginning of 2nd slow stripe


    move.w ($FFFFF70C).w,d2 ; load background's y position


    andi.w #$3FF,d2


    sub.w d2,d1 ; count lines to 2nd slow stripe


    bmi.s @within2ndslow ; if it's negative, it's in the 2nd slow stripe


    cmpi.w #$DF,d1 ; is it more than the total number of lines?


    bmi.s @reachingbottom ; if there are less lines than the total number of lines, skip


    moveq #0,d1


    move.w #$DF,d1 ; if it is, set to only 224 lines


    add.w d0,d0 ; double displacement speed


    bra.s Deform_LZ_global


    @reachingbottom:


    move.w d1,d3 ; save line count


    move.l d0,d2 ; save displacement speed


    add.w d0,d0 ; double displacement speed


    bsr.s Deform_LZ_global


    move.l d2,d0 ; restore slow displacement


    moveq #0,d1


    move.w #$DF,d1 ; total number of lines on screen


    sub.w d3,d1 ; remaining lines to deform


    bra.s Deform_LZ_global


    @within2ndslow:


    moveq #0,d1


    move.w ($FFFFF70C).w,d2 ; load background's y position


    andi.w #$3FF,d2


    cmpi.w #$3C0,d2


    bmi.s @nofastlines


    move.w #$49F,d1


    sub.w d2,d1 ; number of lines until fast stripe


    move.w d1,d3 ; save d1


    bsr.s Deform_LZ_global


    move.w #$DF,d1


    sub.w d3,d1 ; remaining lines (fast)


    add.w d0,d0 ; double displacement speed


    bra.s Deform_LZ_global


    @nofastlines:


    move.w #$DF,d1 ; only slow lines


    Deform_LZ_global:


    Deform_LZ_1:


    cmp.w d4,d5


    bge.s Deform_LZ_2


    move.l d0,(a1)+


    addq.w #1,d5


    adda.l #2,a2


    adda.l #2,a3


    dbf d1,Deform_LZ_1


    rts


    Deform_LZ_2:


    move.w (a3)+,d4


    add.w d6,d4


    swap d4


    move.w (a2)+,d4


    add.w d0,d4


    move.l d4,(a1)+


    dbf d1,Deform_LZ_2


    rts



    So the idea is as follow: it first checks where the background is, then counts how many lines have to be updated as moving at the speed of the first one, moves them with "deform_lz_global", then it counts the remaining lines and moves them with the same subroutine but another value in d0.


    So the main question is: how can I make it so the background redraws correctly (loops horizontally)?


    Also, if someone sees a way to optimize it (make it less resource hungry), ideas and suggestions are welcome. :)
     
    Last edited by a moderator: May 25, 2011
  2. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    Here's a quick optimisation of the code (not much to be honest, it was quite well constructed):



    Deform_LZ:
    move.w ($FFFFF73A).w,d4


    ext.l d4


    asl.l #6,d4


    move.w ($FFFFF73C).w,d5


    ext.l d5


    asl.l #6,d5


    bsr.w ScrollBlock1


    move.w ($FFFFF70C).w,($FFFFF618).w


    lea (LZ_FG_Wave_Data).l,a3


    lea (LZ_BG_Wave_Data).l,a2


    moveq #0,d2


    move.b ($FFFFF7D8).w,d2


    move.l d2,d3


    addi.w #$80,($FFFFF7D8).w


    add.w ($FFFFF70C).w,d2


    andi.w #$FF,d2


    add.w ($FFFFF704).w,d3


    andi.w #$FF,d3


    lea ($FFFFCC00).w,a1


    move.w ($FFFFF700).w,d0


    neg.w d0


    move.w d0,d6


    swap d0


    move.w ($FFFFF708).w,d0


    neg.w d0


    move.w ($FFFFF646).w,d4


    move.w ($FFFFF704).w,d5


    add.w d2,d2


    adda.l d2,a2


    add.w d3,d3


    adda.l d3,a3


    move.w ($FFFFF70C).w,d2 ; load background's y position


    andi.w #$3FF,d2 ; mask it within pattern limits


    subi.w #$A0,d2 ; subtract height of the first stripe


    andi.w #$83FF,d2 ; mask within limits and allow negative values


    bpl.s @belowfirststripe ; if positive, branch to simple version


    ; within first stripe code:


    move.w #$9F,d1 ; load height of the first stripe


    move.w ($FFFFF70C).w,d2 ; load background's y position


    andi.w #$3FF,d2


    sub.w d2,d1 ; subtract position


    move.w d1,d3 ; save d1


    bsr.s Deform_LZ_global


    move.w #$DF,d1 ; total number of lines on screen


    sub.w d3,d1 ; count remaining lines to deform


    add.w d0,d0 ; double displacement speed


    bra.s Deform_LZ_global


    @belowfirststripe:


    move.w #$33F,d1 ; load beginning of 2nd slow stripe


    move.w ($FFFFF70C).w,d2 ; load background's y position


    andi.w #$3FF,d2


    sub.w d2,d1 ; count lines to 2nd slow stripe


    bmi.s @within2ndslow ; if it's negative, it's in the 2nd slow stripe


    cmpi.w #$DF,d1 ; is it more than the total number of lines?


    bmi.s @reachingbottom ; if there are less lines than the total number of lines, skip


    move.w #$DF,d1 ; if it is, set to only 224 lines


    add.w d0,d0 ; double displacement speed


    bra.s Deform_LZ_global


    @reachingbottom:


    move.w d1,d3 ; save line count


    move.l d0,d2 ; save displacement speed


    add.w d0,d0 ; double displacement speed


    bsr.s Deform_LZ_global


    move.l d2,d0 ; restore slow displacement


    move.w #$DF,d1 ; total number of lines on screen


    sub.w d3,d1 ; remaining lines to deform


    bra.s Deform_LZ_global


    @within2ndslow:


    move.w ($FFFFF70C).w,d2 ; load background's y position


    andi.w #$3FF,d2


    cmpi.w #$3BF,d2


    bmi.s @nofastlines


    move.w #$49F,d1


    sub.w d2,d1 ; number of lines until fast stripe


    move.w d1,d3 ; save d1


    bsr.s Deform_LZ_global


    move.w #$DF,d1


    sub.w d3,d1 ; remaining lines (fast)


    add.w d0,d0 ; double displacement speed


    bra.s Deform_LZ_global


    @nofastlines:


    move.w #$DF,d1 ; only slow lines


    Deform_LZ_global:


    Deform_LZ_1:


    cmp.w d4,d5


    bge.s Deform_LZ_2


    move.l d0,(a1)+


    addq.w #1,d5


    addq.l #2,a2


    addq.l #2,a3


    dbf d1,Deform_LZ_1


    rts


    Deform_LZ_2:


    move.w (a3)+,d4


    add.w d6,d4


    swap d4


    move.w (a2)+,d4


    add.w d0,d4


    move.l d4,(a1)+


    dbf d1,Deform_LZ_2


    rts



    The only concern I have is the compare and branch check you have right in the middle of the "Deform_LZ_1" loop, the number of cycles for each instruction are:



    Deform_LZ_1:
    cmp.w d4,d5 ; 04


    bge.s Deform_LZ_2 ; 08


    move.l d0,(a1)+ ; 12


    addq.w #1,d5 ; 04


    addq.l #2,a2 ; 08


    addq.l #2,a3 ; 08


    dbf d1,Deform_LZ_1 ; 10



    So that's 04+08+12+04+08+08+10=42xE0(possible scanlines)=39C0, of course without the compare and branch there the number of cycles would be 12+04+08+08+10=36xE0(possible scanlines)=2F40, so might I recommend something on the lines of:



    Deform_LZ_global:
    sub.w d4,d1


    add.w d4,d5


    move.w d4,-(sp)


    add.w d4,d4


    add.l d4,a2


    add.l d4,a3


    move.w (sp)+,d4


    Deform_LZ_1:


    move.l d0,(a1)+


    dbf d4,Deform_LZ_1


    Deform_LZ_2:


    move.w (a3)+,d4


    add.w d6,d4


    swap d4


    move.w (a2)+,d4


    add.w d0,d4


    move.l d4,(a1)+


    dbf d1,Deform_LZ_2


    rts



    Obviously it will need a bit of revising but the principle is there, of course, this won't eliminate lag but it's a start, the animated tiles are likely to be the reason for this heavy lag, although, I can't see how you've constructed that or even how your level is setup (number of objects in a space at a time, shit like that, etc), so I won't assume here.


    The graphical glitch is a hard one to fix without something like a screenshot or video showing this graphical problem in action, sorry, I hope the above is helpful in any case...
     
    Last edited by a moderator: May 24, 2011
  3. SpirituInsanum

    SpirituInsanum Well-Known Member Member

    Joined:
    Feb 11, 2010
    Messages:
    642
    I feel like that one will be even more complicated than the main part, it will probably take some time to get it working. I have to make it check the number of normal and underwater lines within the limit of the amount of lines being processed for the current deformation speed xD


    The background art is not finished, so screenshots would only look confusing, and I think the deformation would make it hard to analyze on a video. So if someone has an idea on this issue and wants to see what it really looks like, pm me and I'll send the file.
     
  4. SpirituInsanum

    SpirituInsanum Well-Known Member Member

    Joined:
    Feb 11, 2010
    Messages:
    642
    Oh well, lock, or trash, or just don't bother please.


    I'll do something else and try to explode the awesome-meter another, better, way xD


    At least now I know why the backgrounds were that simple in looping levels ^^'
     
Thread Status:
Not open for further replies.