Dynamic Sprite Vram Routine Ideas

Discussion of hardware and software development for Super NES and Super Famicom.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Dynamic Sprite Vram Routine Ideas

Post by Drew Sebastino »

Yes, yes I know the title is terrible. :roll: (couldn't think of what to call it) What I mean by this is, what kind of ways can you make it to where vram for sprites is as crammed as possible? On the metasprite code I made (which I got to be 16 bits! :mrgreen: )(oh, and yes, this means I'm still using WLA... I found it had the best starterkit, even if it is a buggy POS.) I wanted to have it to where each metasprite had an offset in vram, that would get added to the character bit number of each individual sprite to where you would get the final number that you would store into vram, much like what I did when I had a "controller" for x and y that everything was based off of, except for vram. The problem is, sprites on the SNES (as you already know) don't use all the different tiles in a strait line (like the GBA and the Genesis?) Instead, they have it in a box like shape, making what I suggested earlier impossible unless you only used one sprite size. The way I would think that would give you maximum vram density (but definatelly not efficiency) would be if you had every tile or tiles (in the case of 16x16, 32x32, and 64x64 sized sprites) have its own register. Every time you add a new sprite, you would look for a register that is 0, meaning that there are no tiles there. If you are uploading a sprite that is 4x larger than the smaller one, you would look every four registers. If you had a large sprite that is 16x larger than the small sprite, then you would look every 16 registers.

Here's a picture to show what I mean:
SpriteVram.png
SpriteVram.png (1.33 KiB) Viewed 4607 times
Oh, (here's a given) this approach is obviously going to be better the larger the small sized sprite is. I personally think 16x16 and 32x32 is the best overall. (Seriously, why did they even consider making 64x64 sized sprites a possibility? Especially when you can only pick two different sprite sizes...)
Last edited by Drew Sebastino on Wed Jan 28, 2015 9:07 pm, edited 2 times in total.
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Dynamic Sprite Vram Routine Ideas

Post by tepples »

I was under the impression that if you had a lot of small projectiles, 8x8 and 16x16 might be the best so as not to exceed the 34-sliver limit on too many lines. It also lets you use 128x16 (1024 bytes) as the unit of sprite tile updates, uploading five different units plus OAM in each vblank if you aren't making any background changes.

The GBA can do both Super NES-style "box" mode and Genesis-style "line" mode.
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: Dynamic Sprite Vram Routine Ideas

Post by Drew Sebastino »

The problem is, if you want a bunch of explosions (like I love) then you are going to want to use a 32x32 tiles. I really wish there was something like a 8x16 and 16x32 tilemode, as all 128 32x32 sprites can't even all fit on screen, but all 128 16x16 sprites only fill it about halfway. :?

Oh, can't the GBA actually do both "box" and "line" modes? (Wait you just said that. I'm an idiot...) (The Genesis would have a really hard time with box mode using 24x24 sized sprites...)
Shonumi
Posts: 332
Joined: Sun Jan 26, 2014 9:31 am

Re: Dynamic Sprite Vram Routine Ideas

Post by Shonumi »

Espozo wrote: Oh, can't the GBA actually do both "box" and "line" modes? (Wait you just said that. I'm an idiot...) (The Genesis would have a really hard time with box mode using 24x24 sized sprites...)
Let's use proper terminology (because I had a hard time figuring out what either you or tepples were talking about). I dunno about the SNES or Genesis, but in GBAland, we call these modes 1 dimensional (sprite tiles are in a "line" in memory) or 2 dimensional (sprite tiles are in a "box" in memory). The GBA could do both, however, you could not mix and match (well you could with HBlanks and some nifty programming, but generally no).
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: Dynamic Sprite Vram Routine Ideas

Post by Drew Sebastino »

I really didn't know there was a "proper" name for them, I was just saying how they looked. Also, why in the world would you even want to use mode 2 (better? :wink: ) If you have mode 1? mode 2 may be easier to look at in a vram viewer, but not much else. (It's even harder to dma tile data using it.) I wonder, is mode 2 easier for the hardware to use, or does the SNES just use it because it was simply built that way? (Mode 2 just really seems more complicated in about every aspect.) Just thinking, having non-square sized sprites on the GBA just seems like it would make mode 2 a complete mess.
Shonumi
Posts: 332
Joined: Sun Jan 26, 2014 9:31 am

Re: Dynamic Sprite Vram Routine Ideas

Post by Shonumi »

Espozo wrote: Also, why in the world would you even want to use mode 2
2D mode is probably meant to be used with graphics tools and a VRAM viewer. For the graphic artists who didn't care about the programming aspects of the game, having a simple grid they could throw up on the screen and know that's how the hardware would see it exactly was probably a decent benefit for them. With 2D mode, you can reserve only some of the sprite tiles (the ones that need to be animated), to occupy something like the first 4 rows or VRAM or something like that, and update them all via DMA while leaving the rest that don't need updates untouched. I've seen that done in a couple of GBA games that use 2D mapping (Super Mario Advance's intro in some parts) so DMAing wouldn't be terrible. You just need careful planning.
Espozo wrote: Just thinking, having non-square sized sprites on the GBA just seems like it would make mode 2 a complete mess.
Nah, not really. You get enough VRAM so that there's plenty of space to mix and match sprite shapes. I believe Mega Man Zero does this quite well in many places (there is even often VRAM to spare/not update). 2D mode, however, seems more common in games Nintendo developed themselves rather than 3rd party developers, from what I've seen. I think Nintendo's internal tools were geared towards this (also, the GBA defaults to 2D mode, so...)

But enough about the GBA. This is SNESdev after all.
psycopathicteen
Posts: 3001
Joined: Wed May 19, 2010 6:12 pm

Re: Dynamic Sprite Vram Routine Ideas

Post by psycopathicteen »

tepples wrote:I was under the impression that if you had a lot of small projectiles, 8x8 and 16x16 might be the best so as not to exceed the 34-sliver limit on too many lines. It also lets you use 128x16 (1024 bytes) as the unit of sprite tile updates, uploading five different units plus OAM in each vblank if you aren't making any background changes.
...and then you'll pull your hair out in frustration having to rearrange every animation frame to fit into a 128x16 block.
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Dynamic Sprite Vram Routine Ideas

Post by tepples »

psycopathicteen wrote:...and then you'll pull your hair out in frustration having to rearrange every animation frame to fit into a 128x16 block.
Which is something software can easily do for you. Say your character is 32x32; you can have your tile sheet converter turn each cel into four 16x16 sprites and have two frames per unit.
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: Dynamic Sprite Vram Routine Ideas

Post by Drew Sebastino »

tepples wrote:
psycopathicteen wrote:...and then you'll pull your hair out in frustration having to rearrange every animation frame to fit into a 128x16 block.
Which is something software can easily do for you. Say your character is 32x32; you can have your tile sheet converter turn each cel into four 16x16 sprites and have two frames per unit.
Wait a minute, wouldn't you need to arrange the tiles in real time? Otherwise, you would waste DMA time on a metasprite that has less than 64x32 pixels.

Edit: You know, one thing I always wondered was how the DKC games managed with this sort of stuff. Has anyone taken DKC apart enough to know?
tomaitheous
Posts: 592
Joined: Thu Aug 28, 2008 1:17 am
Contact:

Re: Dynamic Sprite Vram Routine Ideas

Post by tomaitheous »

I think that's one of the things that is lacking on the sPPU side of the snes; sprite flexibility. Yeah, having to choose between only two sprites is annoying, but layout for sprites (IIRC, it's been awhile for snes dev stuffs) is limiting too. This is where the PCE and Genesis have more flexibility; sprites (and tiles) and exist anywhere in the whole vram range (even inside tilemap areas). Though for your typical average game, I'm sure it's not a huge deal breaker.

I kinda understand your idea. How memory efficient is it, though?


On a related note, the original sharp 68k only had one sprite size: 16x16. And 128 SAT entries. And, IIRC, had 32k of vram for sprites. And 16 sprites per scanline (one site says 32, but a lot say 16. Might be res/mode dependent). Of course, later models up the video specs (supposedly).
__________________________
http://pcedev.wordpress.com
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: Dynamic Sprite Vram Routine Ideas

Post by Drew Sebastino »

tomaitheous wrote:This is where the PCE and Genesis have more flexibility; sprites (and tiles) and exist anywhere in the whole vram range (even inside tilemap areas). Though for your typical average game, I'm sure it's not a huge deal breaker
But they only have about half (5/8 for the Genesis) the amount of sprites, so you with the Genesis, you can have a 32x16 sprite, but with the SNES, you can have two 16x16 sprites for the exact same effect, only loosing slightly more sprites than the Genesis and the exact same amount of the TG16, but it's unlikely you wont have a single sprite that's perfectly square. In fact, explosions and bullets are usually one sprite and are usually take the most sprites, so... (I do wish the SNES had an extra sprite bit for sprite size so you could have all the different sized sprites, but I don't care way too bad. Explosions and bullets, which are usually the largest and the smallest, are usually together so that's a bit of a pain...)
tomaitheous wrote:I kinda understand your idea. How memory efficient is it, though?
If you mean wram, not at all. If you mean vram, yes. There are 512 tiles available for sprites, so you'd have to use 512 different registers with 8x8 tile sprites, and 128 registers with 16x16 tile sprites. You could always have a register represent 8 different tiles because there are 8 different bits, but you'd have to do an AND operation 8 times, but this would waste time, which I'm not sure this could be done because of that, so it would probably be better to use more wram instead of processing time, as the SNES has plenty of ram. The one problem with this, how would you know where to write for animation updates? Maybe every time you successfully find an open place for a new sprite in vram, you store the result and look at what it was for where you are supposed to dma new tiles? This would use even more ram, because you need to store the answer in a register... (The register would actually just be a general offset for where a sprite is in vram. It would be for finding character data, and for seeing what part of vram needs to be updated.)
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: Dynamic Sprite Vram Routine Ideas

Post by Drew Sebastino »

Sorry to double post, but I think this is pretty significant. I think I kind of have a code that would work with 8x8 and 16x16 sprites. (I don't know how it would work using 16x16 and 32x32 sprites because 128 registers doesn't translate well with 512 tiles.) If there's anything that needs to be fixed, please tell me.

The code assumes 8 bit accumulator with 16 bit indexes

Code: Select all

look_for_8x8_vram:
	cpy #$0100		;512, because there are 512 slots for sprites (this number can be anything, just not over 512)
	beq no_slot_found	;no space left for sprite
	lda Vram,y	
	beq slot_found		;there is space for another sprite
	iny
	bra look_for_8x8_vram	;look again if the space is already occupied

look_for_16x16_vram:
	cpy #$0100				;512, because there are 512 slots for sprites (this number can be anything, just not over 512)
	beq no_slot_found			;no space left for sprite
	lda Vram,y				;upper lefthand corner of square
	bne prepare_for_look_for_16x16_vram	;look again if the space is already occupied
	lda Vram+1,y				;upper righthand corner of square	
	bne prepare_for_look_for_16x16_vram	;look again if the space is already occupied
	lda Vram+16,y				;lower lefthand corner of square
	bne prepare_for_look_for_16x16_vram	;look again if the space is already occupied
	lda Vram+17,y				;lower righthand corner of square
	bne prepare_for_look_for_16x16_vram	;look again if the space is already occupied
	bra 16x16_slot_found			;there is space for another sprite			

prepare_for_look_for_16x16_vram:
	inx
	cmx	#$08
	beq	next_row
	iny
   iny
	bra look_for_16x16_vram

next_row:
	tya			;If this is done right, this should skip every other row of tiles
	adc	#$08
	tay
	bra look_for_16x16_vram

8x8_slot_found:
	inc	Vram,y		;say that one of the slots is now taken
	sty	TempY		;TempY holds the vram offset
	rts

16x16_slot_found:
	lda	#$01
	sta	Vram,y		;say that four of the slots are now taken
	sta	Vram+1,y
	sta	Vram+16,y
	sta	Vram+17,y
	sty	TempY		;TempY holds the vram offset
	rts

no_slot_found:
	rts	;nothing else you can really do...
Note: This has not been tested because I cannot currently fit it in with the rest of my code.

Edit: I forgot to make it to where 16x16 sized sprites skipped every row of tiles vertically, so I, if it is correct, I did. I also fixed prepare_for_look_for_16x16_vram, because I accidentally incremented by 4 tiles instead of 2.
psycopathicteen
Posts: 3001
Joined: Wed May 19, 2010 6:12 pm

Re: Dynamic Sprite Vram Routine Ideas

Post by psycopathicteen »

Espozo wrote: Edit: You know, one thing I always wondered was how the DKC games managed with this sort of stuff. Has anyone taken DKC apart enough to know?
DKC has every metasprite crammed into a 128x16 box, like the method Tepples mentioned. It's a pretty VRAM efficient method, but be prepared to make a lot of metasprite tables if you don't have a computer program to automatically generate metasprite tables for you.
tomaitheous
Posts: 592
Joined: Thu Aug 28, 2008 1:17 am
Contact:

Re: Dynamic Sprite Vram Routine Ideas

Post by tomaitheous »

Espozo wrote:
tomaitheous wrote:This is where the PCE and Genesis have more flexibility; sprites (and tiles) and exist anywhere in the whole vram range (even inside tilemap areas). Though for your typical average game, I'm sure it's not a huge deal breaker
But they only have about half (5/8 for the Genesis) the amount of sprites, so you with the Genesis, you can have a 32x16 sprite, but with the SNES, you can have two 16x16 sprites for the exact same effect, only loosing slightly more sprites than the Genesis and the exact same amount of the TG16, but it's unlikely you wont have a single sprite that's perfectly square. In fact, explosions and bullets are usually one sprite and are usually take the most sprites, so... (I do wish the SNES had an extra sprite bit for sprite size so you could have all the different sized sprites, but I don't care way too bad. Explosions and bullets, which are usually the largest and the smallest, are usually together so that's a bit of a pain...)
By half? You mean the size of the SAT (sprite attribute table, or OAM as Nintendo calls it)? Yeah, but I look at it the other way around; you need such a large SAT because of the limited sprite sizes on the SNES. I.e. You need a large SAT especially when using anything 8x8 sprites (meta or otherwise).

Just an observation/off topic:
Even if you limited the PCE and MD to 256 res mode, the 64 entry SAT will easily cover the entire screen because they have access to all their sprite sizes in a single frame and aren't limited to square sizes. For MD, that's up to 32x32 which at 64 entries, covers 65k pixels. A 256x224 screen is only 57k pixels. For PCE, with its max size of 32x64, can cover up to 128k pixels; way more coverage than it can show pixel wise. SAT size isn't a problem, even with the PCE's small sprite size of 16x16. Just watch a Lords of Thunder longplay on the hardest setting; revenge bullets on every enemy kill. 64 sprites is a LOT of sprites onscreen (objects, not metasprites). Same for the MD. And you have direct access to the full 64k range; no banking or name table limitations or wrapping issues, etc.

Of course, MD has its own problems: to get around the limit number of subpalettes, I'd use more metasprite cells to access more than one palette in a sprite (that or limit sprites to 8 colors each). Stef mentioned that there's a part in Contra Hardcores that maxes out the SAT (80 entries for high res mode), and I thought it was for this reason - but I'm not entirely sure. PCE has a huge number of subpalettes for sprites, but all sizes being increments of 16 pixels (16x16,16x32,16x64,32x16,32x32,32x64) - it can waste space if the object is tiny or waste sprite-line-pixel bandwidth on transparent pixels. They all have their drawbacks, but I wouldn't say SAT entry size is one of them.


On topic:

Isn't the sprite wrap on the SNES sprite page/bank/whatever, at 16k?
__________________________
http://pcedev.wordpress.com
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: Dynamic Sprite Vram Routine Ideas

Post by Drew Sebastino »

I see we have different opinions... Well, I respect yours anyway! :P The one thing I do have to say though is that having the whole 64KB range for sprites is cool, but maybe not all that practical because of BG tiles.

About vram though, I think it would have been cool if Nintendo (and Sega, for the Sega Genesis) had offered some sort of vram expansion for the SNES, like they did the N64. (Sprites having access to 64KB of vram would be very useful here.) I heard people have done this on the Genesis, but has it ever been done on the SNES? Is it even easily possible?

Oh, and does anyone have any good ideas on how to make my code use 16x16 and 32x32 sprite sizes? I don't really know how to get 128 slots for sprites to easily match up with 512 tiles...
Post Reply