Skip navigation
NintendoAge
Welcome, Guest! Please Login or Join
Loading...

Game Engine Building #8: Sprite Cycling and Attribute Handling NintendoAGE Programming Resources

Jun 4, 2014 at 12:01:37 PM
Mario's Right Nut (352)
avatar
(Cunt Punch) < Bowser >
Posts: 6634 - Joined: 11/21/2008
Texas
Profile
See below.  I'm having trouble pasting today.

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

This is my shiny thing, and if you try to take it off me, I may have to eat you.

Check out my dev blog.


Jun 4, 2014 at 12:02:07 PM
Mario's Right Nut (352)
avatar
(Cunt Punch) < Bowser >
Posts: 6634 - Joined: 11/21/2008
Texas
Profile
6/4/14

ETA:  Forgot to set the clear memory to load $FE to the $0700 page.  Don't forget this.

This tutorial is kind of a side note to the others. It just shows how to do sprite cycling and better attribute handling.

This is fairly involved, so make sure you go slowly and think about stuff. If the position stuff doesn't make sense, it won't end well for you.



First, when you have more than 8 sprites per scanline, some will dissapear. This is pretty simple to fix. You just flip-flop the order in which they are drawn every frame...keeping in mind that ones which are stored lower in RAM are drawn first (i.e. one at $0204 is drawn on top of $0208). So, by flipping the order they are stored in RAM, we can make them flicker so they won't dissapear completely.

Start by reserving the set $0700 to be your working area for your sprites. Keep the set $0200 (or whatever) for your DMA memory. Then simply copy them "forward" one frame and then "backwards" the next...like so:

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

Sprite_Cycling:

LDA Sprite_Rotation
BNE .Backwards

.loop1
LDA sprite_RAM,x ;copy forwards
STA sprite_DMA,x
INX
BNE .loop1

INC Sprite_Rotation
RTS

.Backwards
LDY #$FC
.loop2 ;copy backwards
LDA sprite_RAM,x
STA sprite_DMA,y
INX
INY
LDA sprite_RAM,x
STA sprite_DMA,y
INX
INY
LDA sprite_RAM,x
STA sprite_DMA,y
INX
INY
LDA sprite_RAM,x
STA sprite_DMA,y
TYA
SEC
SBC #$08
TAY
INY
INX
BNE .loop2

LDA #$00
STA Sprite_Rotation

RTS

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

Pretty simple. You can cycle them all (like here) or just some (if you have a sprite zero hit, you don't want that bitch moving around). Or you can make it so your PC is always on top.



Next, we will look at how to better handle attributes, at least in my opinion. If you figure this out, you'll never have to fuck with them again! It will be automatic.

So, first we need to modify our metatiles.

MetaTileSeta00
.db $44,$49,$5F,$7A,%00000000,%00001111

The first 4 bytes are the tiles, like always.
The sixth byte is the collision data, like always.
The fifth byte is the attribute data for that particular metatile. If you want it to draw from pallete "01" you'd use "%01010101", pallete "11", "%11111111", and so on.

Do this for all of them. Note that if you have two tiles that use the same bg tiles but different colors, you'll have to make a duplicate.



It's probably better that you look through the routine as you read. It's pretty simple once you figure it out.

Next, we need to look at our position in the background data table. If you think in hex, you always have $10 meta tiles across the screen. So, row 0 would be $00-$0F, row 1 is $10-$1F, 2 is $20-$2F.

So, the attribute bytes are 2 metatiles across. This means that for each row, we just divide by 2 to get the position in the table...we hope that the NES has a convinent command for this. Just use LSR A!!

Next, there is the same thing with the vertical. Row 0 and 1 use the first 8 attribute bytes, 2 and 3 use the second, and so on. So, to figure out a row, we AND the room table counter with %11100000 and LSR A twice...I'll leave it to you to work this out.

The combo of these two steps will produce your position within the attribute table.

Next, you simply use the table position to work out which quadrant you are within in the attribute byte, and Bob's your uncle.



I kinda glazed over this finding the position thing. So if you can't figure it out, I can delve into it further. But it is important that you work it out and understand what it's doing. Take a pen and paper, draw out a screen, label each metatile (in hex), and manually decode the routine to see what it's doing. It will click and life will be titties and rainbows.

I hope you enjoyed this. Post questions!! See above for the program.

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

This is my shiny thing, and if you try to take it off me, I may have to eat you.

Check out my dev blog.



Edited: 06/04/2014 at 05:45 PM by Mario's Right Nut

Jun 4, 2014 at 12:13:44 PM
Mega Mario Man (63)
avatar
(Tim ) < Ridley Wrangler >
Posts: 2743 - Joined: 02/13/2014
Nebraska
Profile
I blazed through this and it read pretty well. I can't wait to find some time to dig into it a bit further. In fact, I need to find time to dig through all of your tutorials again.

-------------------------
Current Project
Isometric Survival Horror

Older Projects
Tailgate Party, Power Pad Demo, Happy Hour

Links
Store, Facebook, Twitter

Jun 4, 2014 at 3:22:55 PM
Vectrex28 (130)
avatar
(CD-i Kraid) < Master Higgins >
Posts: 7789 - Joined: 07/28/2012
Switzerland
Profile
Thanks for that sprite cycling routine. Also, I like the fact that I'm not the only one that uses labels such as "balls" or "titties"

-------------------------
"Energy Tanks, Missiles, Power Bombs... You want it? It's yours my friend! As long as you have enough credits!"


Jun 4, 2014 at 4:28:14 PM
Vectrex28 (130)
avatar
(CD-i Kraid) < Master Higgins >
Posts: 7789 - Joined: 07/28/2012
Switzerland
Profile
So... I implemented the routine in my game, and it indeed cycles as it should in the $0700 range. However, it doesn't affect my sprites at all (it doesn't cycle in the $0200 range like it does in your ROM). All my code after the setup is in the NMI however, unlike yours, so that may be the problem.
Do you know what I should do?

-------------------------
"Energy Tanks, Missiles, Power Bombs... You want it? It's yours my friend! As long as you have enough credits!"


Jun 4, 2014 at 4:31:41 PM
Mega Mario Man (63)
avatar
(Tim ) < Ridley Wrangler >
Posts: 2743 - Joined: 02/13/2014
Nebraska
Profile
I would say that is your problem. I used to do too much in the NMI and have since adaopted the practice of doing as much as I can outside of NMI and only let the NMI do what is necessary.

You may have to have someone look at your code to give you a suggestion.

-------------------------
Current Project
Isometric Survival Horror

Older Projects
Tailgate Party, Power Pad Demo, Happy Hour

Links
Store, Facebook, Twitter

Jun 4, 2014 at 5:34:29 PM
SoleGooseProductions (129)
avatar
(Beau ) < King Solomon >
Posts: 3504 - Joined: 04/22/2013
Michigan
Profile
Awesome stuff! Glad to see the return of the Game Engine Building series... You know what my vote for #9 is .

-------------------------
"The light that burns twice as bright burns half as long..." ~ Blade Runner

SoleGooseProductions.com


Jun 4, 2014 at 5:44:45 PM
Mario's Right Nut (352)
avatar
(Cunt Punch) < Bowser >
Posts: 6634 - Joined: 11/21/2008
Texas
Profile
^ Remind me!

Also, if you're using $0700 for the sprites, probably should change them to $FE when you clear the memory at the start. Forgot to do that!!

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

This is my shiny thing, and if you try to take it off me, I may have to eat you.

Check out my dev blog.


Jun 4, 2014 at 6:36:35 PM
SoleGooseProductions (129)
avatar
(Beau ) < King Solomon >
Posts: 3504 - Joined: 04/22/2013
Michigan
Profile
Updating sprites by room of course! Still working on it (slowly) thanks to your help so far, but I always enjoy your more lengthy write ups.

-------------------------
"The light that burns twice as bright burns half as long..." ~ Blade Runner

SoleGooseProductions.com


Jun 4, 2014 at 7:16:12 PM
user (6)

< El Ripper >
Posts: 1462 - Joined: 05/30/2014
Profile
Originally posted by: Mario's Right Nut

Next, we will look at how to better handle attributes,
Interesting points. Some could probably be useful for the task I published in the programming question thread.

Cheers!