I don't know why I haven't thought about this until now, but it is possible to fit an entire level in vram, as long as you don't make the level too long, and don't use up too many unique tiles. If you use 16x16 tiles, you can have a level that is 32 screens long and 2 screens tall, take up 32kB of VRAM.
As a bonus, since you don't have to upload any nametable data to accomplish scrolling, you can use the extra vblank time to make on-the-fly modifications to the level.
Why would 16x16 tiles matter? How would you get 32 x 2 screens in 32k of vram? Each screen should be 1k, shouldn't you only get 32 screens? Edit: I mistakenly thought we were talking about NES.
At least, what I'm presuming you're talking about is wiring a 32k RAM to the 4 nametables, each with a 5-bit bank selector. Also, with 4 screens at once, you don't have to suffer attribute glitches, and you don't even have to hide a column on the edge!
Each nametable on the Super NES is 2048 bytes. But in 16x16-pixel map mode, each screen covers only 16x14 nametable entries, meaning each nametable covers 2x2.3 screens. So 16 nametables fit in 32 KiB, and they span 32x2.3 screens.
But given that you have to have a copy of your map in WRAM anyway for collision detection, why not just update at the seam like every other game does? That is, unless you're trying to run all your game logic in vblank time like I did with Nibbles for NES.
Keeps code simple and short. Btw, I figured out an easy way of doing destroyable scenery. Everytime part of the background gets destroyed, it updates an entire 1024x512 region. Wasteful, but easy to program.
Oh, I didn't notice this was posted in the SNESdev forum. I thought we were talking about NES.
This thread seems interesting!
When you guys say "Name Table", you mean "tilemap", don't you? I though each tilemap in SNES was always 32x32 tiles (1 screen), and at most, you could have 4 tilemap arranged this way:
Code:
AB
CD
Then, the maximum tilemap is 64x64 tiles, 16 pixels per tile, so a maximum of 1024x1024. Am I wrong?
How could you then get 32 screen long and 2 screens tall?
All of this makes me wonder what scroll registers are useful for... I mean, if I have a standard tilemap, then anytime I scroll the screen, I must "shift" all tilemap data in VRAM and then write the new tilemap for the bit of background is about to appear. To make a smooth scroll, I use the scroll registers to move the screen at most 16 pixels (1 tilemap); so in practice, those registers are "only" useful for this purpose I described... aren't they?
32kB can fit 16 tile maps. Each one of them is 2 screens tall and 2 screens wide. Scrolling would be done with a 13-bit x coordinate. Only the low 9 bits would be used for the actual scrolling, while the top 4 bits would control the name table address.
Quote:
All of this makes me wonder what scroll registers are useful for... I mean, if I have a standard tilemap, then anytime I scroll the screen, I must "shift" all tilemap data in VRAM and then write the new tilemap for the bit of background is about to appear. To make a smooth scroll, I use the scroll registers to move the screen at most 16 pixels (1 tilemap); so in practice, those registers are "only" useful for this purpose I described... aren't they?
Most games only update a column of tiles off-screen as the game scrolls. At least that is the method most often talked about on this website. I know the Mario series use this method.
psycopathicteen wrote:
Most games only update a column of tiles off-screen as the game scrolls. At least that is the method most often talked about on this website. I know the Mario series use this method.
Doesn't most NES/SNES games do this?
You can rewrite the whole tilemap as you scroll, but this will waste VRAM bandwidth for no purpose.
It's also an inheritance from the NES where writing only columns or rows was the ONLY way to do it.
psycopathicteen wrote:
Only the low 9 bits would be used for the actual scrolling, while the top 4 bits would control the name table address.
How does the transition between name tables work?
For what it's worth: updating the off-screen portion is what you're supposed to do, but not the entire screen contents.
You don't need to update the entire background SC data (a.k.a. "nametable" on the NES) contents every time, just the horizontal tiles or the vertical tiles (the SNES, like the NES, can do this easily -- see register $2115 (VMAINC) on the SNES. It lets you change the method of automatic VRAM incrementing when writing data to $2116/2117 (VMADDL/VMADDH). There's an example of how this works in the official developers manual, it's in an appendix titled ADDRESS INCREMENT ORDER and shows you how the different combinations of bits 3-0 of $2115 affect the incrementing methodology. The +32 incremental mode is what's usually used (on both NES and SNES) for updating the left/right screen "edges", while the +1 incremental mode is what's used for the top/bottom "edges". The +128 increment mode is mainly for mode 7.
Yes, your code has to be able to keep track of all that and do things accordingly, but it's really not that big of a deal. Pretty much any 2D console works this way.
But as with anything: it all depends on what you wanna do and what you need. I just happen to think it's a huge waste of time in NMI (VBlank) to be updating the entire BG SC data contents every frame. You only have so much time / so many cycles during VBlank. I can't remember effectively how many CPU cycles there are in the VBlank period.
tokumaru wrote:
psycopathicteen wrote:
Only the low 9 bits would be used for the actual scrolling, while the top 4 bits would control the name table address.
How does the transition between name tables work?
Nametable base address is expressed in 1024-word units from the start of VRAM. Horizontal arrangement uses one nametable and the following nametable. In 16x16 pixel mode, there are 512 horizontal pixels per nametable.
- When horizontal scroll is 0-511, nametable offset is 0, so the nametables at $0000 and $0400 are used.
- When horizontal scroll is 512-1023, nametable offset is 1, so the nametables at $0400 and $0800 are used.
- When horizontal scroll is 1024-1535, nametable offset is 2, so the nametables at $0800 and $0C00 are used.
- ...
- When horizontal scroll is 7168-7936, nametable offset is 14, so the nametables at $3800 and $3C00 are used.
(Apologies if I failed at math.)
tepples wrote:
Horizontal arrangement uses one nametable and the following nametable.
So what about normal circumstances, when only 1 or 2 name tables are used? If rendering goes past the second name table, does the SNES wrap back to the first one, like on the NES?
tokumaru wrote:
So what about normal circumstances, when only 1 or 2 name tables are used? If rendering goes past the second name table, does the SNES wrap back to the first one, like on the NES?
Yes.
I guess this might shine if you're trying to make split-screen multiplayer. You don't have to worry about updating both views of the map; you can just change it once and, should both players' views intersect, have it reflected in both windows.