[4.5.x] Animated Tiles with CHR-RAM Switching

Jonny

Well-known member
I'm having a bit of trouble with sprites loading. The first CHR-RAM loads corrupted/garbage graphics but the other two load as they should. Does anyone have any ideas what this could be caused by?

garbage tiles2.gif

This is the code I am using. Apart from omitting all the layouts I'm not using and picking a different layout for the bank switching I can't see that I've done anything different...
Code:
doLoadScreen16:
    SwitchCHRBank #$00
    JSR doWaitFrame

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; DOUBLE MAIN WITH HUD ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    
    LDA tileLayout
    CMP #%00000000
    BEQ Load_MM
    JMP Load_MMSS
    
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   
    
Load_MM:                                        ;; MAIN 1 ;;
    LDA backgroundTilesToLoad               
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad
    AND #%00001111
    STA tempB
LoadChrData tempA, #$10, #$00, #$60, BckCHRAddLo, BckCHRAddHi, tempB
    
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   
    
    LDA backgroundTilesToLoad+1                 ;; MAIN 2 ;;
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+1
    AND #%00001111
    STA tempB
LoadChrData tempA, #$16, #$00, #$60, BckCHRAddLo, BckCHRAddHi, tempB

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  HUD  ;;
    
LoadChrData #$1E, #$1C, #$00, #$40, OtherChrTiles_Lo, OtherChrTiles_Hi, #$00
    
    JMP doneLoadingChrs

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; DOUBLE MAIN / 2 SCREEN SPECIFIC ;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Load_MMSS:                                      ;; MAIN 1 ;;
    ;;
    LDA #$00
    STA tempj                               
    MSSS_CHR_LOAD_LOOP:
    ;;
    LDA backgroundTilesToLoad
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad
    AND #%00001111
    STA tempB
LoadChrData tempA, #$10, #$00, #$60, BckCHRAddLo, BckCHRAddHi, tempB
    
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    
    LDA backgroundTilesToLoad+1                 ;; MAIN 2 ;;
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+1
    AND #%00001111
    STA tempB
LoadChrData tempA, #$16, #$00, #$60, BckCHRAddLo, BckCHRAddHi, tempB

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    JSR doWaitFrame                           ;; SCREEN 1 ;;
    LDA backgroundTilesToLoad+2
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+2
    AND #%00001111
    STA tempB
LoadChrData tempA, #$1C, #$00, #$20, BckSSChrAddLo, BckSSChrAddHi, tempB

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    JSR doWaitFrame                           ;; SCREEN 2 ;;
    LDA backgroundTilesToLoad+3
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+3
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$1E, #$00, #$20, BckSSChrAddLo, BckSSChrAddHi, tempB
    ;;
    LDA userScreenByte7
    BEQ +noAnimatedTiles
    INC tempj
    LDA tempj
    CMP #$03
    BEQ +noAnimatedTiles
    SwitchCHRBank tempj
    JMP MSSS_CHR_LOAD_LOOP
+noAnimatedTiles
    ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   
    
doneLoadingChrs:
    ;;
    SwitchCHRBank #$00
    LDA #$00
    STA tempj
Load_Sprite_CHR_Loop:
    ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   
;;; LOAD GAME OBJECT CHR AND SET MONSTER BANK ;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   
    
LoadChrData #$15, #$00, #$00, #$80, GameObjectCHRAddLo, GameObjectCHRAddHi, #$00
    
    LDA monsterTableOffset
    CMP #$08
    BCC inMonsterBank0
    LDA #$14
    JMP gotMonsterBank
inMonsterBank0:
    LDA #$13
gotMonsterBank:
    STA temp
    
LoadChrData temp, #$08, #$00, #$80, MonsterAddressLo, MonsterAddressHi, monsterTableOffset
    JSR doWaitFrame
    ;;
    LDA userScreenByte7
    BNE +hasAnimatedTiles
    JMP +noAnimatedTiles
+hasAnimatedTiles
    INC tempj
    LDA tempj
    CMP #$03
    BEQ +loadAnimatedTiles
    SwitchCHRBank tempj
    JMP Load_Sprite_CHR_Loop
+loadAnimatedTiles
    ;;
    SwitchCHRBank #$01
LoadChrData #$17, #$10, #$00, #$20, AnimTiles_Lo, AnimTiles_Hi, userScreenByte7
    JSR doWaitFrame
    INC userScreenByte7
    SwitchCHRBank #$02
LoadChrData #$17, #$10, #$00, #$20, AnimTiles_Lo, AnimTiles_Hi, userScreenByte7
    JSR doWaitFrame
    ;;
+noAnimatedTiles 
    SwitchCHRBank #$00
    ;;
    RTS
 

JamesNES

Well-known member
I'm having a bit of trouble with sprites loading. The first CHR-RAM loads corrupted/garbage graphics but the other two load as they should. Does anyone have any ideas what this could be caused by?

I can't see anything different either :/ That's really weird. I went back and checked the version I wrote as I made the guide and it looks like what you've done. Here's the full file, maybe it can help?

Code:
doLoadScreen16:
   
    SwitchCHRBank #$00

LoadObjectSubPalettes spriteSubPal1, #$00
    LoadObjectSubPalettes spriteSubPal2, #$04
    LoadObjectSubPalettes spriteSubPal3, #$08
    LoadObjectSubPalettes spriteSubPal4, #$0C
   
   
   
    JSR doWaitFrame



    LDA tileLayout
    CMP #%01000000
    BEQ LOAD_MSP
    JMP notMSP
LOAD_MSP:   
    LDA backgroundTilesToLoad
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$10, #$00, #$60, BckCHRAddLo, BckCHRAddHi, tempB
        ;arg0 - bank where graphics live
        ;arg1 - row
        ;arg2 - column (by 10s...must end in zero)
        ;arg3 - how many tiles to load.  If 00, will load whole sheet.
        ;arg4 - Label in bank 16 table, low.
        ;arg5 - Label in bank 16 table, hi.
        ;arg6 - Bank 16 table offset
       
        JSR doWaitFrame
    LDA backgroundTilesToLoad+1
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+1
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$16, #$00, #$20, BckSSChrAddLo, BckSSChrAddHi, tempB
    ;;; load paths.
        JSR doWaitFrame
    LDA backgroundTilesToLoad+2
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+2
    AND #%00001111
    STA tempB
   
    LoadChrData tempA, #$18, #$00, #$40, PathCHRAddLo, PathCHRAddHi, tempB

       
    ;; Load Hud
    LoadChrData #$1E, #$1C, #$00, #$40, OtherChrTiles_Lo, OtherChrTiles_Hi, #$00
   
    JMP doneLoadingChrs
notMSP:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;DOUBLE MAIN;;;;;;;;;;;;;;;;;;;;;;;

    CMP #%00000000
    BEQ Load_MM
    JMP notMM
Load_MM:
    LDA backgroundTilesToLoad
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$10, #$00, #$60, BckCHRAddLo, BckCHRAddHi, tempB
   
    LDA backgroundTilesToLoad+1
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+1
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$16, #$00, #$60, BckCHRAddLo, BckCHRAddHi, tempB
   
    ;; Load Hud
    LoadChrData #$1E, #$1C, #$00, #$40, OtherChrTiles_Lo, OtherChrTiles_Hi, #$00
   
   
    JMP doneLoadingChrs
notMM:
    CMP #%01110000
    BEQ LOAD_MSSS
    JMP notMSSS
LOAD_MSSS:
    LDA #$00
    STA tempj
    MSSS_CHR_LOAD_LOOP:
    LDA backgroundTilesToLoad
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$10, #$00, #$60, BckCHRAddLo, BckCHRAddHi, tempB
   
    JSR doWaitFrame
    LDA backgroundTilesToLoad+1
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+1
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$16, #$00, #$20, BckSSChrAddLo, BckSSChrAddHi, tempB
   
            JSR doWaitFrame
    LDA backgroundTilesToLoad+2
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+2
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$18, #$00, #$20, BckSSChrAddLo, BckSSChrAddHi, tempB
   
            JSR doWaitFrame
    LDA backgroundTilesToLoad+3
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+3
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$1A, #$00, #$20, BckSSChrAddLo, BckSSChrAddHi, tempB
   
   
    ;; Load Hud
    LoadChrData #$1E, #$1C, #$00, #$40, OtherChrTiles_Lo, OtherChrTiles_Hi, #$00
   
    LDA userScreenByte7
    BEQ +noAnimatedTiles
        INC tempj
        LDA tempj
        CMP #$03
        BEQ +noAnimatedTiles
            SwitchCHRBank tempj
            JMP MSSS_CHR_LOAD_LOOP
    +noAnimatedTiles
   
    JMP doneLoadingChrs
notMSSS:
    CMP #%01111100
    BEQ doMSSSSS
    JMP notMSSSSS
doMSSSSS
    LDA backgroundTilesToLoad
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$10, #$00, #$60, BckCHRAddLo, BckCHRAddHi, tempB
   
    JSR doWaitFrame
    LDA backgroundTilesToLoad+1
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+1
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$16, #$00, #$20, BckSSChrAddLo, BckSSChrAddHi, tempB
   
            JSR doWaitFrame
    LDA backgroundTilesToLoad+2
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+2
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$18, #$00, #$20, BckSSChrAddLo, BckSSChrAddHi, tempB
   
            JSR doWaitFrame
    LDA backgroundTilesToLoad+3
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+3
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$1A, #$00, #$20, BckSSChrAddLo, BckSSChrAddHi, tempB
   
                JSR doWaitFrame
    LDA backgroundTilesToLoad+4
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+4
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$1C, #$00, #$20, BckSSChrAddLo, BckSSChrAddHi, tempB
   
                JSR doWaitFrame
    LDA backgroundTilesToLoad+5
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+5
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$1E, #$00, #$20, BckSSChrAddLo, BckSSChrAddHi, tempB
    JMP doneLoadingChrs
notMSSSSS
    CMP #%00001100
    BEQ doMMSS
    JMP notMMSS
doMMSS:
    LDA backgroundTilesToLoad
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$10, #$00, #$60, BckCHRAddLo, BckCHRAddHi, tempB
   
    LDA backgroundTilesToLoad+1
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+1
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$16, #$00, #$60, BckCHRAddLo, BckCHRAddHi, tempB
                JSR doWaitFrame
    LDA backgroundTilesToLoad+2
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+2
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$1C, #$00, #$20, BckSSChrAddLo, BckSSChrAddHi, tempB
   
                JSR doWaitFrame
    LDA backgroundTilesToLoad+3
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+3
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$1E, #$00, #$20, BckSSChrAddLo, BckSSChrAddHi, tempB
   
    JMP doneLoadingChrs
notMMSS:
doneLoadingChrs:
    SwitchCHRBank #$00
    LDA #$00
    STA tempj
       
    Load_Sprite_CHR_Loop:   
       
    LoadChrData #$15, #$00, #$00, #$80, GameObjectCHRAddLo, GameObjectCHRAddHi, #$00
        ;arg0 - bank where graphics live
        ;arg1 - row
        ;arg2 - column (by 10s...must end in zero)
        ;arg3 - how many tiles to load.  If 00, will load whole sheet.
        ;arg4 - Label in bank 16 table, low.
        ;arg5 - Label in bank 16 table, hi.
        ;arg6 - Bank 16 table offset
           
        LDA monsterTableOffset
        CMP #$08
        BCC inMonsterBank0
            ;; in monster bank 1
            LDA #$14
            JMP gotMonsterBank
        inMonsterBank0
            LDA #$13
        gotMonsterBank:
            STA temp
       
        LoadChrData temp, #$08, #$00, #$80, MonsterAddressLo, MonsterAddressHi, monsterTableOffset
        ;arg0 - bank where graphics live
        ;arg1 - row
        ;arg2 - column (by 10s...must end in zero)
        ;arg3 - how many tiles to load.  If 00, will load whole sheet.
        ;arg4 - Label in bank 16 table, low.
        ;arg5 - Label in bank 16 table, hi.
        ;arg6 - Bank 16 table offset
            JSR doWaitFrame
    LDA userScreenByte7
    BNE +hasAnimatedTiles
            JMP +noAnimatedTiles
        +hasAnimatedTiles
        INC tempj
        LDA tempj
        CMP #$03
        BEQ +loadAnimatedTiles
            SwitchCHRBank tempj
            JMP Load_Sprite_CHR_Loop
        +loadAnimatedTiles
       
        SwitchCHRBank #$01
        LoadChrData #$17, #$10, #$00, #$20, AnimTiles_Lo, AnimTiles_Hi, userScreenByte7
        jsr doWaitFrame
       
        INC userScreenByte7
       
        SwitchCHRBank #$02
        LoadChrData #$17, #$10, #$00, #$20, AnimTiles_Lo, AnimTiles_Hi, userScreenByte7
        jsr doWaitFrame
       
    +noAnimatedTiles   
    SwitchCHRBank #$00
    RTS
 

Jonny

Well-known member
Thanks. I checked the full file too. Must be something outside of the tutorial I'm doing.
 

Jonny

Well-known member
Hey @JamesNES just a quick update. I found that there's also a doLoadScreen.asm which also has the macro for loading the monster tiles. I don't know if this is only for metroidvania but in my doLoadScreen16.asm I had the code for setting the temp for monster bank but NOT the CHR load macro for monsters after it (which seems wrong because the temp is being set but not used or not in that script at least). I've checked back on some backups for that script and non of them have the monster CHR load macro after setting the temp for monster bank. Kinda odd, if someone can confirm whether or not it should be there in the vanilla metroidvania script that would be great.

Anyway, so I made sure the monster CHR load macro was in doLoadScreen16.asm , commented it out of doLoadScreen and as far as I can tell so far it all works now as it should.
 

vanderblade

Active member
@JamesNES This works great, but I'm having trouble adding another frame of animation.

I went through each step and did what I thought I was supposed to.

Created AnimTiles03.chr using the same method.

Added, "
AnimTiles03:
.incbin ROOT\Graphics\AnimTiles03.chr" to Bank 17.

Added:
AnimTiles_Lo:
.db #$00, #<AnimTiles01, #<AnimTiles02, #<AnimTiles03

AnimTiles_Hi:
.db #$00, #>AnimTiles01, #>AnimTiles02, #<AnimTiles03

Switched the CMP checks to #$04 instead.

And here's my doLoadScreen16

Code:
doLoadScreen16:

SwitchCHRBank #$00

    LoadBackgroundPalettes newPal
    JSR doWaitFrame
        ;; We wait this frame because the LoadBackgroundPalettes routine
        ;; sets bckpal variables and activates the update palette.
        ;; waiting this frame holds up on the next routine until the
        ;; background palettes are loaded into the PPU.
    ;LoadObjectPalettes #$00
    
    LoadObjectSubPalettes spriteSubPal1, #$00
    LoadObjectSubPalettes spriteSubPal2, #$04
    LoadObjectSubPalettes spriteSubPal3, #$08
    LoadObjectSubPalettes spriteSubPal4, #$0C
    
    
    
    JSR doWaitFrame



    LDA tileLayout
    CMP #%01000000
    BEQ LOAD_MSP
    JMP notMSP
LOAD_MSP:   
    LDA backgroundTilesToLoad
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$10, #$00, #$60, BckCHRAddLo, BckCHRAddHi, tempB
        ;arg0 - bank where graphics live
        ;arg1 - row
        ;arg2 - column (by 10s...must end in zero)
        ;arg3 - how many tiles to load.  If 00, will load whole sheet.
        ;arg4 - Label in bank 16 table, low.
        ;arg5 - Label in bank 16 table, hi.
        ;arg6 - Bank 16 table offset
        
        JSR doWaitFrame
    LDA backgroundTilesToLoad+1
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+1
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$16, #$00, #$20, BckSSChrAddLo, BckSSChrAddHi, tempB
    ;;; load paths.
        JSR doWaitFrame
    LDA backgroundTilesToLoad+2
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+2
    AND #%00001111
    STA tempB
    
    LoadChrData tempA, #$18, #$00, #$40, PathCHRAddLo, PathCHRAddHi, tempB

        
    ;; Load Hud
    LoadChrData #$1E, #$1C, #$00, #$40, OtherChrTiles_Lo, OtherChrTiles_Hi, #$00
    
    JMP doneLoadingChrs
notMSP:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;DOUBLE MAIN;;;;;;;;;;;;;;;;;;;;;;;

    CMP #%00000000
    BEQ Load_MM
    JMP notMM
Load_MM:
    LDA backgroundTilesToLoad
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$10, #$00, #$60, BckCHRAddLo, BckCHRAddHi, tempB
    
    LDA backgroundTilesToLoad+1
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+1
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$16, #$00, #$60, BckCHRAddLo, BckCHRAddHi, tempB
    
    ;; Load Hud
    LoadChrData #$1E, #$1C, #$00, #$40, OtherChrTiles_Lo, OtherChrTiles_Hi, #$00
    
    
    JMP doneLoadingChrs
notMM:
    CMP #%01110000
    BEQ LOAD_MSSS
    JMP notMSSS
LOAD_MSSS:

----

    LDA #$00
    STA tempj                                ;;added code
    MSSS_CHR_LOAD_LOOP:

-----

    LDA backgroundTilesToLoad
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$10, #$00, #$60, BckCHRAddLo, BckCHRAddHi, tempB
    
    JSR doWaitFrame
    LDA backgroundTilesToLoad+1
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+1
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$16, #$00, #$20, BckSSChrAddLo, BckSSChrAddHi, tempB
    
            JSR doWaitFrame
    LDA backgroundTilesToLoad+2
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+2
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$18, #$00, #$20, BckSSChrAddLo, BckSSChrAddHi, tempB
    
            JSR doWaitFrame
    LDA backgroundTilesToLoad+3
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+3
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$1A, #$00, #$20, BckSSChrAddLo, BckSSChrAddHi, tempB
    
    
    ;; Load Hud
    LoadChrData #$1E, #$1C, #$00, #$40, OtherChrTiles_Lo, OtherChrTiles_Hi, #$00
    
    
    LDA userScreenByte7
    BEQ +noAnimatedTiles
        INC tempj
        LDA tempj
        CMP #$04
        BEQ +noAnimatedTiles
            SwitchCHRBank tempj
            JMP MSSS_CHR_LOAD_LOOP
    +noAnimatedTiles
 
    JMP doneLoadingChrs
    
    JMP doneLoadingChrs
notMSSS:
    CMP #%01111100
    BEQ doMSSSSS
    JMP notMSSSSS
doMSSSSS
    LDA backgroundTilesToLoad
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$10, #$00, #$60, BckCHRAddLo, BckCHRAddHi, tempB
    
    JSR doWaitFrame
    LDA backgroundTilesToLoad+1
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+1
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$16, #$00, #$20, BckSSChrAddLo, BckSSChrAddHi, tempB
    
            JSR doWaitFrame
    LDA backgroundTilesToLoad+2
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+2
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$18, #$00, #$20, BckSSChrAddLo, BckSSChrAddHi, tempB
    
            JSR doWaitFrame
    LDA backgroundTilesToLoad+3
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+3
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$1A, #$00, #$20, BckSSChrAddLo, BckSSChrAddHi, tempB
    
                JSR doWaitFrame
    LDA backgroundTilesToLoad+4
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+4
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$1C, #$00, #$20, BckSSChrAddLo, BckSSChrAddHi, tempB
    
                JSR doWaitFrame
    LDA backgroundTilesToLoad+5
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+5
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$1E, #$00, #$20, BckSSChrAddLo, BckSSChrAddHi, tempB
    JMP doneLoadingChrs
notMSSSSS
    CMP #%00001100
    BEQ doMMSS
    JMP notMMSS
doMMSS:
    LDA backgroundTilesToLoad
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$10, #$00, #$60, BckCHRAddLo, BckCHRAddHi, tempB
    
    LDA backgroundTilesToLoad+1
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+1
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$16, #$00, #$60, BckCHRAddLo, BckCHRAddHi, tempB
                JSR doWaitFrame
    LDA backgroundTilesToLoad+2
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+2
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$1C, #$00, #$20, BckSSChrAddLo, BckSSChrAddHi, tempB
    
                JSR doWaitFrame
    LDA backgroundTilesToLoad+3
    LSR
    LSR
    LSR
    LSR
    CLC
    ADC #$0F
    STA tempA
    LDA backgroundTilesToLoad+3
    AND #%00001111
    STA tempB
    LoadChrData tempA, #$1E, #$00, #$20, BckSSChrAddLo, BckSSChrAddHi, tempB
    
    JMP doneLoadingChrs
notMMSS:
doneLoadingChrs:
    SwitchCHRBank #$00
    LDA #$00
    STA tempj
      
    Load_Sprite_CHR_Loop:
        
        
        
    LoadChrData #$15, #$00, #$00, #$80, GameObjectCHRAddLo, GameObjectCHRAddHi, #$00
        ;arg0 - bank where graphics live
        ;arg1 - row
        ;arg2 - column (by 10s...must end in zero)
        ;arg3 - how many tiles to load.  If 00, will load whole sheet.
        ;arg4 - Label in bank 16 table, low.
        ;arg5 - Label in bank 16 table, hi.
        ;arg6 - Bank 16 table offset
            
        LDA monsterTableOffset
        CMP #$08
        BCC inMonsterBank0
            ;; in monster bank 1
            LDA #$14
            JMP gotMonsterBank
        inMonsterBank0
            LDA #$13
        gotMonsterBank:
            STA temp
        
        LoadChrData temp, #$08, #$00, #$80, MonsterAddressLo, MonsterAddressHi, monsterTableOffset
        ;arg0 - bank where graphics live
        ;arg1 - row
        ;arg2 - column (by 10s...must end in zero)
        ;arg3 - how many tiles to load.  If 00, will load whole sheet.
        ;arg4 - Label in bank 16 table, low.
        ;arg5 - Label in bank 16 table, hi.
        ;arg6 - Bank 16 table offset
            JSR doWaitFrame
            
    LDA userScreenByte7
    BNE +hasAnimatedTiles
            JMP +noAnimatedTiles
        +hasAnimatedTiles
        INC tempj
        LDA tempj
        CMP #$04
        BEQ +loadAnimatedTiles
            SwitchCHRBank tempj
            JMP Load_Sprite_CHR_Loop
        +loadAnimatedTiles
      
         ;;animated tile loading code will go here
        
        SwitchCHRBank #$01
        LoadChrData #$17, #$10, #$00, #$20, AnimTiles_Lo, AnimTiles_Hi, userScreenByte7
        jsr doWaitFrame
      
        INC userScreenByte7
      
        SwitchCHRBank #$02
        LoadChrData #$17, #$10, #$00, #$20, AnimTiles_Lo, AnimTiles_Hi, userScreenByte7
        jsr doWaitFrame
        
        INC userScreenByte7
        
        SwitchCHRBank #$03
        LoadChrData #$17, #$10, #$00, #$20, AnimTiles_Lo, AnimTiles_Hi, userScreenByte7
        jsr doWaitFrame

       SwitchCHRBank #$00  ;;switch back to the first bank
      
       ;;; end tile loading code
      
    +noAnimatedTiles 
     SwitchCHRBank #$00           

RTS
 

JamesNES

Well-known member
@JamesNES This works great, but I'm having trouble adding another frame of animation.

I went through each step and did what I thought I was supposed to.

Created AnimTiles03.chr using the same method.

Added, "
AnimTiles03:
.incbin ROOT\Graphics\AnimTiles03.chr" to Bank 17.

Added:
AnimTiles_Lo:
.db #$00, #<AnimTiles01, #<AnimTiles02, #<AnimTiles03

AnimTiles_Hi:
.db #$00, #>AnimTiles01, #>AnimTiles02, #<AnimTiles03

Switched the CMP checks to #$04 instead.

And here's my doLoadScreen16
The looping part looks like it should work, but the fourth byte in your AnimTiles_Hi is the low byte instead of the high byte, need to change that #<AnimTiles03 to #>AnimTiles03.

Hopefully that's all that's wrong
 

vanderblade

Active member
The looping part looks like it should work, but the fourth byte in your AnimTiles_Hi is the low byte instead of the high byte, need to change that #<AnimTiles03 to #>AnimTiles03.

Hopefully that's all that's wrong
OMG. That was it. Such a small thing, but that's how it goes. Thanks!
 

vanderblade

Active member
Woohoo! Done the same thing myself multiple times :p
By the way, is there any way to use this method to give animated tiles on the same screen different speeds? I'm using this to create the illusion of movement on a train level, and it would be nice to have a slower perceived speed to the mountain tiles for a kind of parallax. I'm guessing the answer is no, and honestly, before this I just had just static tiles, so I'm happy with the effect at all, albeit imperfect.

neMULEsis_Train_AnimatedRedux2.gif
 

JamesNES

Well-known member
I don't think so, not with this method. Best you could get would be another tile animating at half the speed, but with only two frames.
 

latetera

Member
By the way, is there any way to use this method to give animated tiles on the same screen different speeds? I'm using this to create the illusion of movement on a train level, and it would be nice to have a slower perceived speed to the mountain tiles for a kind of parallax. I'm guessing the answer is no, and honestly, before this I just had just static tiles, so I'm happy with the effect at all, albeit imperfect.

View attachment 5248
This one looks gorgeous i think < 3
 

Subotai

Active member
@JamesNES : It works for me. Question : If I want to have a second set of tileset, Do I need to reproduce the programmation in double ? (using another userScreenByte, etc)
 

Jonny

Well-known member
Sorry to butt in, I set mine up using userScreenByte6 to select "extra tiles". I renamed it that because I'm using it to side load static graphics too for a few extra main tilesets. To get the correct animTiles to load I did a long set of CMP for loading the first set of animTiles and the second... here's a snippet it it helps...
Code:
SwitchCHRBank #$01
    LDA userScreenByte6
    CMP #$01
    BNE checkAnim2a
    LoadChrData #$17, #$10, #$00, #$20, AnimTiles1_Lo, AnimTiles1_Hi, userScreenByte7
    JMP tilesLoadeda
checkAnim2a:
    CMP #$02
    BNE checkAnim3a
    LoadChrData #$17, #$10, #$00, #$20, AnimTiles2_Lo, AnimTiles2_Hi, userScreenByte7
    JMP tilesLoadeda
checkAnim3a:
I didn't want to post the whole thing because its very long. Tbh it might have been better using some sort of lookup table but it works so I thought don't fix it if its not broken.

Obviously you'll need to set up all the graphics, and labels for all of them as described in the tutorial.
 

JamesNES

Well-known member
If you keep loading things in like this:

Code:
AnimTiles01:	;;grass lands frame 2
	.incbin ROOT\Graphics\AnimTiles01.chr
	
AnimTiles02:	;;grass lands frame 3
	.incbin ROOT\Graphics\AnimTiles02.chr

AnimTiles03:	;;boat 2
	.incbin ROOT\Graphics\AnimTiles03.chr
AnimTiles04:	;;boat 3
	.incbin ROOT\Graphics\AnimTiles04.chr	
AnimTiles05:	;;boat 4
	.incbin ROOT\Graphics\AnimTiles05.chr

and the references are done like:

Code:
AnimTiles_Lo:
.db #$00, #<AnimTiles01, #<AnimTiles02, #<AnimTiles03, #<AnimTiles04, #<AnimTiles05

AnimTiles_Hi:
.db #$00, #>AnimTiles01, #>AnimTiles02, #>AnimTiles03, #>AnimTiles04, #>AnimTiles05

Then the screenbyte can just be an offset for which tiles to load without any fuss. So if I set the screenbyte at 3, it'll load in those boat graphics. I have another lookup table for how many frames to load as well, since some screens have more frames, but that's kinda messy and I probably wouldn't bother doing that again.
 

Logana

Well-known member
By the way, is there any way to use this method to give animated tiles on the same screen different speeds? I'm using this to create the illusion of movement on a train level, and it would be nice to have a slower perceived speed to the mountain tiles for a kind of parallax. I'm guessing the answer is no, and honestly, before this I just had just static tiles, so I'm happy with the effect at all, albeit imperfect.

View attachment 5248
You could always split the animation so the faster one plays only 2 frames and repeats for the next two and for the slower one have it use all four frames
 

Subotai

Active member
Thanks James for the solution, I will make a good use with it.
@Jonny Thanks for your answer too, there's so many ways to adapt script for doing the same thing.
 

Jonny

Well-known member
Thanks James for the solution, I will make a good use with it.
@Jonny Thanks for your answer too, there's so many ways to adapt script for doing the same thing.
yes, there's the ridiculously complecated way and the easy way. I really like that you can use the same setup to load other static graphics too. You can't see them in the editor but a couple more main tilesets was really useful for title screens etc. Happy CHR switching! :)
 

Subotai

Active member
I've some display bug when the player warp out of a screen with the CHR-SWITCH enable with the UserScreenByte7 value 1.
I'm using 3 frames animations.

It happens ONLY when the animation is in progress with the second and third frames.
When the player warp out when the animation is in the first frame, main BMP (file BckCHR) it works fine.

In the video below, I've tested 4 times.

1 warp : first frame of animation => works
2 warp : second frame => bug
3 warp : third frame => bug
4 warp : first frame => works

warpbug.gif


here's my warp code to the Pause screen (16X16) (double Main) (userScreenByte7 value 0):

Code:
    ;; set map
    LDA warpMap
    EOR #%00000001
    STA warpToMap

    ;; get player screen and position
    LDX player1_object
   
    LDA Object_screen,x
    ;STA continueScreen
    STA warpToScreen
    STA tempScreen
    ;STA camScreen

    ;; store our X position
    LDA Object_x_hi,x
    STA continueX
    STA newX

    ;; store our Y position
    LDA Object_y_hi,x
    STA continueY
    STA newY
    WarpToScreen #$00, #$E3, #$01
RTS


I've the same problem using a warp tile by pressing UP (warp to 8x8 screen userScreenByte7 value 3) :

Code:
    CPX player1_object
    BNE +notPlayerForWarpTile
    LDA gamepad
    AND #%00010000
    CMP #%00010000
    BNE +notPlayerForWarpTile
    ;PlaySound #sfx_pipe
    WarpToScreen warpToMap, warpToScreen, #$01
   
+notPlayerForWarpTile:


When warping to a 8x8 screen (userScreenbyte7 value 0 or 1, it works fine.

Am I the only one that have this display glitch ?
Or anyone have a solution ?

Thanks
 
Top Bottom