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

baardbi

Well-known member
Incrível. Como você fez o personagem se agachar? E as animações de fundo? Eu estava fazendo um jogo na versão 4.1, mas acabei abandonando porque não entendia como fazer essas coisas ... Agora estou estudando a última versão ...
Thanks. The player isn't crouching. He only lifts his feet when he is jumping. The animated background tiles is made using the code in this post. This game is made in NESmaker 4.5.9.
 

JamesNES

Well-known member
Thanks for this @JamesNES ! I managed to get a crowd cheering and speakers blowing in my game with your solution

View attachment 5722

Now I would like to have the same in another level. I've seen that JamesNes said:

we need that lookup table or we can load more AnimTiles without one?
If you use the same number of frames for every screen then you can just adjust the number of loops when you're loading the CHR files, but if you're wanting some screens to have 2 frames, some 3, some 4, then you need to give it a way to look up how many to load. I based it on a the screenbyte I used for the tileset to load, but it got kinda messy. I'd recommend just using 4 frames for every screen unless you're really strapped for space in the extra graphics bank.
 

laurentpb

New member
Not really so much . The only 2 major things 4.5 has is visually 8x8 tile screens,and some better scrolling with major issues. And the many problems that 4.5. has,alot of them weren't problems in 4.1. and sadly,if there's a 5.0,which I highly doubt,youll find that anything 4.5 is out the door,and we'll have to make the same choice.
Start with a broken regressed program? Or stick with what you know that works now that you fixed it?
I stuck with 4.1 because it was the only option when I got here. I spent a year using it, learning it,and fixing it. So the version of 4.1 I have is far less broken than most others,maybe apart from dale_coop,or anyone else sticking with it that has fixed many many things.
I do understand your thought process though,and you could be right in some ways.
Also no, there actually may be more 4.1 on here than you think,it's just a little burried.
I'm not sure if you've ever used 4.1,but it would be a great pain to import some projects,like mine,to 4.5. Just because I did so many little things everywhere and ect.And in the end,wouldn't really help it much,except with a more detailed start screen,maybe easier bankswitching I see....
Have you thought of modifying the scrolling functions' of version 4.1 to the one of 4.5? I'm currently working on my project on the 4.1 version and I'm always wondering if the work to upgrade the scrolling could be done and if it would be worth it.
Btw nice work @JamesNES , I am looking forward to implement your work on my game :D
@mouse spirit I'll tell you if I got any success in my implementation
 
Last edited:

5kids2feed

Well-known member
I'm so close. Anybody know why it goes black and restarts the animated tiles? It doesn't reset the game because the music is still going, but for some reason it does the 3 tiles of animation, entire screen goes black and then resets the animation.
darn.gif

EDIT: NEVERMIND. I got it! This instruction "Add variables animTimer and animFrame. Set animTimer to a default value of 16." I set both to 16 by accident not just the one. Carry on.

darn2.gif
 
Last edited:

5kids2feed

Well-known member
Question now that I got it working. I added AnimTiles03.chr & AnimTiles04.chr in Banks 16 & 17 next to AnimTiles01.chr & AnimTiles02.chr (like JamesNES has setup in post #35).

How would I set it up for userScreenByte6 to activate 03 and 04 instead of 01 and 02 since it would be on a different screen? Thanks!
 

JamesNES

Well-known member
Question now that I got it working. I added AnimTiles03.chr & AnimTiles04.chr in Banks 16 & 17 next to AnimTiles01.chr & AnimTiles02.chr (like JamesNES has setup in post #35).

How would I set it up for userScreenByte6 to activate 03 and 04 instead of 01 and 02 since it would be on a different screen? Thanks!
Been a while but uhhh I think you can just change your screenbyte in screen settings to 3 since load chr data is set to use it as an offset.
 

mouse spirit

Well-known member
Have you thought of modifying the scrolling functions' of version 4.1 to the one of 4.5? I'm currently working on my project on the 4.1 version and I'm always wondering if the work to upgrade the scrolling could be done and if it would be worth it.
Btw nice work @JamesNES , I am looking forward to implement your work on my game :D
@mouse spirit I'll tell you if I got any success in my implementation
Sorry,I didn't see those. No,I'm not that NES savvy myself. More of a workaround ER with nesmaker.
 

5kids2feed

Well-known member
Been a while but uhhh I think you can just change your screenbyte in screen settings to 3 since load chr data is set to use it as an offset.

That sounds right, but didn’t work for me somehow. It just glitches when I change it from 1 to 3. Maybe I forgot something in the code. I’ll go over it and get back to ya. Just so happy I got the initial code working. Thanks, James!

EDIT: Oh wait. I think I figured it out. I applied the userbyte to a second screen but I’m almost sure I didn’t set the second screen to the Main + Screen x 3 tileset. I’ll let you know when I’m around my computer again.
 
Last edited:

5kids2feed

Well-known member
Hmm still not working for the second set of CHR's (even with Main + Screen x 3 tileset setup). If I have the userbyte set to 1 it'll animate the first two CHR's perfectly. If I set it to 3 it's jumbled mess. Even tried to export CHRs 3 & 4 multiple times just to see if they were corrupt.

This is what I have for banks 16 & 17

Code:
AnimTiles01:
.incbin ROOT\Graphics\AnimTiles01.chr

AnimTiles02:
.incbin ROOT\Graphics\AnimTiles02.chr

AnimTiles03:
.incbin ROOT\Graphics\AnimTiles03.chr

AnimTiles04:
.incbin ROOT\Graphics\AnimTiles04.chr

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


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


and the userbyte i switch back from 1 to 3 (tried numbers 1-12 just to see if they show up too lol)
Untitled.jpg
 
Last edited:

5kids2feed

Well-known member
GOT IT! It was in the < > values of my bank 17 code! IT'S PARTY TIME!

I had this:

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

When it should be this:
Code:
AnimTiles_Hi:
.db #$00, #>AnimTiles01, #>AnimTiles02, #>AnimTiles03, #>AnimTiles04
 
Hi, I noticed there wasn't a step-by-step on this anywhere, or even how to do it in a NES Maker-specific way, so I'll share how I did it. The problem is that it's very project specific, what you actually need it to do, but getting it going at all is the hardest part. If you can follow along with this guide you'll be able to do basically whatever you want with it. In the zip I've included my DoScreen16.asm, but it's better to follow along.

Aims:
  • Load our own CHR graphics files rather than using up the pre-assigned tilesets NES Maker sets up
  • Animate the top row of the main tileset on a screen with an additional two frames. We will set it up for the Main + Screen x 3 tileset loadout for my example.
Things you need to have done first:
  • Follow my guide to move half of doLoadScreen to Bank 16 - most of this will take place in the new Bank 16 routine. Link
  • Download the attached zip and put the SwitchCHRBank macro in your BASE_4_5\System\Macros folder.
  • Setup user screenbytes. This method by chronicleoflegends is great.
  • Add a new temp variable in NES Maker's user variables, I'm using tempj in this example. This is so I know there isn't a macro messing with my temp variable.
  • Add variables animTimer and animFrame. Set animTimer to a default value of 16.
  • Set up the Handle Game Timer script. Basically just make a blank asm file and assign it to Handle Game Timer in script settings. It's included by default in NES Maker.
  • Make sure the tile layout for the screen you're trying it on is set to No Path (Main + Screen x 3)

Part 1 - Sideloading more graphics

This part isn't entirely necessary, you can use graphics NES Maker allows you to by default, but you'll quickly run out of room and it's kind of awkward to reference them.

Bank 17 is pretty much empty, so I've been including extra CHR files there. CHR files are the color indexed BMP files that can actually be used by the system.

I've included some graphics as an example in the attached zip, so I'll refer to those specifically. Move BckCHR_17.bmp to your project's graphics assets folder. This will be the base graphics set that we'll animate the top row of. Create a subfolder in your graphics folder called Animated Tiles. Here you can put the animated tile .bmps that are in the zip.

Now we convert them to .chr so that the NES can actually use them. This is easy:

Load each of the AnimTiles bmps up in the pixel editor. At the top of the window, click the Pixel Editor menu and hit Export CHR.

View attachment 4841

Save this in GameEngineData\Routines\BASE_4_5\Graphics as AnimTiles01.chr. You'll need to create the graphics folder, it's not there by default. Do the same with AnimTiles02.bmp.

Now that the graphics are in the right format, we can include them in our code. Open Bank 17 (easy to find from Script Settings) and at the top, add:

Code:
AnimTiles01:
.incbin ROOT\Graphics\AnimTiles01.chr

AnimTiles02:
.incbin ROOT\Graphics\AnimTiles02.chr

So now we have the two new graphics files included with our game, and two labels set up so we can reference them. Next is to make a reference table for them in Bank 16 where the CHR loading actually takes place.

Open up Bank 16 and find a spot near the top. We're going to add two tables for the addresses of the new tilesets:

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

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

This stores the addresses of the high and low bytes of the new tilesets, references that will be needed when loading them into RAM.

And that's it for part one. Extra graphics are loaded, and references are set up. Now the fun part, actually loading them into CHR-RAM during doLoadScreen.

Part 2 - Loading the graphics into CHR-RAM

Mapper30 has 4 CHR-RAM banks, by default NES Maker only loads the first one. Since we have two additional frames of animation, we're going to load up two more banks, and then do a timed switch between them to make the tiles animate.

This will all take place in DoLoadScreen16.asm.

First, at the top of the script under DoLoadScreen16:, add:

Code:
SwitchCHRBank #$00

To make sure we always start in CHR bank 0. Weird things will happen if your animation timer causes screenload to start in a different bank.

Scroll down to LOAD_MSSS:, which is around line 118. We're going to loop through this three times to fill three banks.

Set your temp variable to #$00, and add a label for the loop:

Code:
LOAD_MSSS:

----

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

-----
    LDA backgroundTilesToLoad
    LSR
    LSR
    LSR
    LSR

We're going to use userScreenByte7 to tell each screen which animated tiles it should load. If you leave it at zero, it won't load anything. Since we're using AnimTiles01, we set userScreenByte7 to 1, on the screen info settings in NES Maker.

At the end of the LOAD_MSSS section, we're going to check for two things. First, is userScreenByte7 equal to zero? If it is, we won't bother looping and load more CHR. If it's not, we switch to the next CHR bank, loop back through the CHR loading routine, then do it again until we have banks 0, 1 and 2 loaded up. What bank we're in is tracked by tempj. This is what that looks like (around line 181):

Code:
    LDA userScreenByte7
    BEQ +noAnimatedTiles
        INC tempj
        LDA tempj
        CMP #$03
        BEQ +noAnimatedTiles
            SwitchCHRBank tempj
            JMP MSSS_CHR_LOAD_LOOP
    +noAnimatedTiles
 
    JMP doneLoadingChrs

As a progress check, you can compile it and check the PPU viewer in Mesen. On the second tab you can switch between CHR-RAM banks and make sure that they're loading (the fourth one should still be black).

Now we have three sets of identical background tiles loaded, we have to load the sprite graphics as well. These are loaded separately further down the script, so we'll do basically the same thing for them.

Find doneLoadingChrs: at the bottom of the script, and add these four lines under it:

Code:
doneLoadingChrs:
    SwitchCHRBank #$00
    LDA #$00
    STA tempj
     
    Load_Sprite_CHR_Loop:

and at the end of the script, right before the RTS, add (almost) the same check as the last one:

Code:
    LDA userScreenByte7
    BNE +hasAnimatedTiles
            JMP +noAnimatedTiles
        +hasAnimatedTiles
        INC tempj
        LDA tempj
        CMP #$03
        BEQ +loadAnimatedTiles
            SwitchCHRBank tempj
            JMP Load_Sprite_CHR_Loop
        +loadAnimatedTiles
     
         ;;animated tile loading code will go here
     
    +noAnimatedTiles 
     SwitchCHRBank #$00

Now the last part in this script, actually loading in the extra frames of animation to banks 1 and 2. Replace the comment in the last code with this:

Code:
        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

       SwitchCHRBank #$00  ;;switch back to the first bank

For reference, the first argument for LoadChrData is the bank where the graphics are stored (we included them in Bank 17 at the start of this), the second argument is what row to replace (#$10 is the first row), #$00 is what column to start the replacement at, and the last one to worry about is where we have userScreenByte7 - this is the position of the tileset we want to load in, relative to the start of our AnimTiles_Lo/Hi list in bank 16. That's why we set screenbyte7 to 1. The script then increases it to 2 so we load in AnimTiles02.

Set up the timer

In your handle game timer script, we want to decrement animTimer each frame, then when it hits zero, set it back to the starting interval, increase our animFrame variable, and switch CHR banks to the next frame. It's pretty simple and looks like this:

Code:
LDA userScreenByte7
BEQ +dontUpdateAnimatedTiles ;;making sure that this screen actually has animated tiles set up - thanks CGT
DEC animTimer
LDA animTimer
BNE +dontUpdateAnimatedTiles
    LDA #$10        ;;i'm using 10 as a starting point for animTimer
    STA animTimer
    INC animFrame
    LDA animFrame
    CMP #$03 ;;has it gone over the number of banks we filled?
    BEQ +resetAnimation
        SwitchCHRBank animFrame
        JMP +dontUpdateAnimatedTiles
    +resetAnimation
    LDA #$00
    STA animFrame
    SwitchCHRBank #$00
+dontUpdateAnimatedTiles

And done! The tiles should be animating now.

I wrote this as I went through on a fresh install of NES Maker so hopefully I haven't missed anything.



Extra stuff

Now that you know how to fundamentally do this, you should try customising it so that it fits your project better. Here are a couple of things I did:
  • Make a four frame animation.
  • Use a screenflag to make the loading routine load the animated tiles into one of the screen specific rows, rather than always the top row
  • Make a table in bank 16 that tells the game how many frames individual animations have, so they don't need to be the same number of frames on every screen. You'll need to change the last part of the CHR loading script to be an arbitrary loop for that.
works in meotridvania or scrolling module?
 
Hey, JamesNES it's a wannabee klump (joking of course).
Followed the Tutorial EXACTLY (Triple checked my code)
and the game green screens with no tiles (check on Mesen debug) every boot

My game is like a fire emblem game & I think that might be the cause. (due to the fact you can move tiles with gameplay)

Example Pre-Tutorial/Without your graphics (Skip to Example Demo 2 for the game I'm going for):
View: https://youtu.be/Ij1pAOlDO1s


But yeah I'm Stumped H E L P ?
 

SciNEStist

Well-known member
if it was the tiles moving causing the issue, then it would usually crash when you move the tile, not at startup.

best thing to do is figure out where its breaking. try doing the bank16 stuff first, then test. then do the screenbystes step and test again. then do the rest of it and test every step of the way
 

JamesNES

Well-known member
If you look in the ppu viewer at the different chr banks you can at least see if it's getting that far. Maybe its getting stuck in a loop somewhere
 
If you look in the ppu viewer at the different chr banks you can at least see if it's getting that far. Maybe its getting stuck in a loop somewhere
I did before asking actually! it's actually all green in the PPU viewer:

View: https://imgur.com/a/ShQK2tF


to clarify I think I coded in some of those areas earlier before attempting animated tiles.
I HOPE I AM VERY WRONG
this theory is only unsure because... again if you watched the video I put in my introduction
this one:
(ignore the poor attempts at jokes lol, I like trying to be funni)
View: https://www.youtube.com/watch?v=SGYpeB0wN6c


so yeah still recovering from that.
 
Top Bottom