Jump to content
IGNORED

The completely underappreciated possibilities of Mode 0 on SNES. . . .


Recommended Posts

2 hours ago, JurassicDope said:

Back on the wrapping, I just realized wouldn't a 64x64 sprite not completely go off screen vertically since Y position is just a byte?

I'll disgregard overscan for this discussion to keep things brief.

 

The SNES normally gives you a resolution of 224 rows of pixels to draw stuff on.  There is no dedicated "hide/show this sprite" feature that you'd expect in a modern engine - the way you hide sprites on the SNES is by moving them offscreen.  So, 256 - 224 = 32 invisible rows at the bottom.

 

I didn't test what happens with 64x64 sprites, but now that I think about this, the best way to hide sprites is probably to move them offscreen horizontally to x=-128, not vertically - because we know that will work no matter how big they are.

 

Look at the caution on OBSEL here:

https://problemkaputt.de/fullsnes.htm#snesppuspritesobjs

 

I suspect the word "may" is in there because whether wrapping occurs depends on the 64x64 sprite's Y position, but that could be clearer.

Edited by jeffythedragonslayer
Link to comment
Share on other sites

On 5/29/2023 at 3:48 PM, Creamhoven said:

Yes, that should be possible. As far as I understand the format the Msu1 uses is pcm. Not sure if it is as efficient as FLAC or even compressed at all.

Evidently not:

 

Quote

The audio tracks are 44.1 kilohertz, 16-bit stereo uncompressed unsigned PCM files in little-endian order, left channel first, with a simple eight-byte header.

source: https://helmet.kafuka.org/msu1.htm

Edited by jeffythedragonslayer
Link to comment
Share on other sites

10 hours ago, Creamhoven said:

Thanks for the information. That doesnt suprise me the decoding would be alot of heavy lifting on the system. 4gb 44.1kHz 16bit ubcompressed audio would be around 7 hours.

Heavy indeed.  Although the official manual vaguely states that a single block of BRR data is "the minimum unit the sound IC can handle" (see page 3-2-1), the fact that ares has a file called brr.cpp (~60 lines) who's sole function is called DSP::brrDecode reveals to me that the BRR decoding is done by specialized hardware and not the sound driver running on the SPC700.

  • Like 1
Link to comment
Share on other sites

10 hours ago, Kirk_Johnston said:

Am I right in thinking the SNES can update 360 2bpp background tiles per frame in Mode 0 (not including how many you can squeeze in per scanline during HDMA)?

I don't think your BGMODE setting has anything to do with it.  (Did you hear it does somewhere?)

 

According to https://snes.nesdev.org/wiki/Timing#Vertical_Blank, you have time to DMA at least 3.5 kb during vblank.  So that's a little more than 3,500 bytes, 3,584 bytes to be exact, if you use the traditional kilobyte, which is 1024 bytes, like I do.

 

So with 8x8 tiles at 2bpp:

 

360 * 2 * 8 * 8 = 46,080 bits

 

Then dividing by 8 because 8 bits in a byte...

 

5,5760 bytes

 

That's too much for NTSC configured to use 22 vblank lines, but it looks like it will just barely work when overscan mode is configured to 37 lines.  And it looks like there is plently of bandwith on PAL.

Edited by jeffythedragonslayer
  • Like 2
Link to comment
Share on other sites

2 hours ago, jeffythedragonslayer said:

I don't think your BGMODE setting has anything to do with it.  (Did you hear it does somewhere?)

 

According to https://snes.nesdev.org/wiki/Timing#Vertical_Blank, you have time to DMA at least 3.5 kb during vblank.  So that's a little more than 3,500 bytes, 3,584 bytes to be exact, if you use the traditional kilobyte, which is 1024 bytes, like I do.

 

So with 8x8 tiles at 2bpp:

 

360 * 2 * 8 * 8 = 46,080 bits

 

Then dividing by 8 because 8 bits in a byte...

 

5,5760 bytes

 

That's too much for NTSC configured to use 22 vblank lines, but it looks like it will just barely work when overscan mode is configured to 37 lines.  And it looks like there is plently of bandwith on PAL.

Well, I hardly understand this stuff at that level, but I thought that was what this thread was talking about in some of the replies, that you can swap in more tiles per frame in the lower-colour background modes since each tile now takes up less memory than it would in the higher-colour background mode: https://forums.nesdev.org/viewtopic.php?p=282127#p282127 and specifically this reply: https://forums.nesdev.org/viewtopic.php?p=282131#p282131 (where it says "You can change even more CHR per frame if you use mode 1 instead [of Mode 3].")

 

And, if that's correct, my follow up question would then be: If you switch to the 16x16 background tile mode rather than the 8x8 background tile mode, would that mean you could update the same size of image with less tiles swaps because of the fact each tile is now technically four times the size, so less tiles used to make that same sized image, yet doesn't take up as much memory to store its various data if it were actually four 8x8 tiles per 16x16 chunk of the image rather than one 16x16 tile making up each 16x16 chunk of the image, I think?

Edited by Kirk_Johnston
Link to comment
Share on other sites

23 minutes ago, Kirk_Johnston said:

Well, I hardly understand this stuff at that level, but I thought that was what this thread was talking about in some of the replies, that you can swap in more tiles per frame in the lower-colour background modes since each tile now takes up less memory than it would in the higher-colour background mode: https://forums.nesdev.org/viewtopic.php?p=282127#p282127 and specifically this reply: https://forums.nesdev.org/viewtopic.php?p=282131#p282131 (where it says "You can change even more CHR per frame if you use mode 1 instead [of Mode 3].")

Oh, ok.  I can't access the NESdev forums right now, but I'll clarify: I don't need to know which BG Mode you're using to figure out how much memory a tile takes.  All I need to know is the answer to these questions:

 

1) How many bits per pixel (bpp) is the tile?
2) How many pixels wide is the tile?
3) How many pixels tall is the tile?

 

Then I just multiply those three things together, divide by 8, and that's how many bytes the tile takes up.

 

In Mode 0, the answer to question #1 is always 2.
In Mode 3, the answer to question #1 is 8 on BG1 and 4 on BG2.

 

So that's the reason Mode 0 can change tiles faster than Mode 3 - because the bpp is forced to be lower, the tiles in Mode 0 take up less space.

Edited by jeffythedragonslayer
  • Like 2
Link to comment
Share on other sites

24 minutes ago, jeffythedragonslayer said:

Oh, ok.  I can't access the NESdev forums right now, but I'll clarify: I don't need to know which BG Mode you're using to figure out how much memory a tile takes.  All I need to know is the answer to these questions:

 

1) How many bits per pixel (bpp) is the tile?
2) How many pixels wide is the tile?
3) How many pixels tall is the tile?

 

Then I just multiply those three things together, divide by 8, and that's how many bytes the tile takes up.

 

In Mode 0, the answer to question #1 is always 2.
In Mode 3, the answer to question #1 is 8 on BG1 and 4 on BG2.

 

So that's the reason Mode 0 can change tiles faster than Mode 3 - because the bpp is forced to be lower, the tiles in Mode 0 take up less space.

Cool, so that sounds like what I'm thinking of. Now, I dunno what the max number is (I'm terrible at math), but at least I know I could use Mode 0 to swap in/out way more BG tiles than in the other background modes, which give me some new ideas to think about of ways to really take advantage of that. And the first thing I'm thinking of is a Mode 0 fighting game with huge fighters that use a background layer each and can switch in/out way more tiles for the fighters than any other SNES fighting game ever has with still having two backgrounds left for the stages along with all the sprites too for whatever other use, which could result in something potentially very impressive if done right. And how impressive it is in terms of the size of the fighters all depends on just how many 2bpp background tiles can be swapped in/out each frame, especially if I use the 16x16 tile mode for the backgrounds (if there's an advantage to that) and also HDMA during HBlank and so on to switch in/out even more tiles and push that max number I can switch in/out every frame even higher (presuming I understand these things somewhat correctly). :)

Edited by Kirk_Johnston
Link to comment
Share on other sites

53 minutes ago, Kirk_Johnston said:

Cool, so that sounds like what I'm thinking of. Now, I dunno what the max number is (I'm terrible at math), but at least I know I could use Mode 0 to swap in/out way more BG tiles than in the other background modes, which give me some new ideas to think about of ways to really take advantage of that. And the first thing I'm thinking of is a Mode 0 fighting game with huge fighters that use a background layer each and can switch in/out way more tiles for the fighters than any other SNES fighting game ever has with still having two backgrounds left for the stages along with all the sprites too for whatever other use, which could result in something potentially very impressive if done right. And how impressive it is in terms of the size of the fighters all depends on just how many 2bpp background tiles can be swapped in/out each frame, especially if I use the 16x16 tile mode for the backgrounds (if there's an advantage to that)

Don't worry, that's why community is important - I'll try to show my work if you have any more math questions, that way the answer doesn't seem like have magically appeared out of nowhere for others who want to verify its correct more easily.

53 minutes ago, Kirk_Johnston said:

and also HDMA during HBlank and so on to switch in/out even more tiles and push that max number I can switch in/out every frame even higher (presuming I understand these things somewhat correctly). :)

I'm pretty sure that doesn't work for backgrounds.  The Uniracer's trick allows you to write to OAM during hblank, but officially CGRAM (and not OAM or VRAM) is what Nintendo says you can change during hblank (see page 2-24-1, caution #2)

  • Like 2
Link to comment
Share on other sites

7 hours ago, jeffythedragonslayer said:

Don't worry, that's why community is important - I'll try to show my work if you have any more math questions, that way the answer doesn't seem like have magically appeared out of nowhere for others who want to verify its correct more easily.

I'm pretty sure that doesn't work for backgrounds.  The Uniracer's trick allows you to write to OAM during hblank, but officially CGRAM (and not OAM or VRAM) is what Nintendo says you can change during hblank (see page 2-24-1, caution #2)

Ah, I'm sure I read somewhere that you could change a few BG tiles [and/or sprite tiles] during each HBlank period, but I guess it was something else, maybe just palette colours or something like that.

 

Side point: It sounds like that Uniracers trick allows you to change a sprite's position on-screen during HBlank, so wouldn't that effectively allow a form of sprite multiplexing where you can display a single sprite at multiple positions down the screen during one frame and therefore visually have multiple instances of the one sprite on-screen, much like the snow in Stone Protectors on Genesis (https://rasterscroll.com/mdgraphics/graphical-effects/sprite-raster-effects/)?

 

If this works in principle basically as in the example above to allow the same end visual result effect on SNES (just using some version of the Uniracers HDMA trick in SNES' case), that's definitely something working looking into more to see how it could be used for some cool effects. :)

Edited by Kirk_Johnston
Link to comment
Share on other sites

32 minutes ago, Kirk_Johnston said:

Ah, I'm sure I read somewhere that you could swap in a few BG tiles [and/or sprite tiles] during HBlank, but I guess it was something else, maybe just palette colours or something like that.

https://forums.nesdev.org/viewtopic.php?t=19896

 

Might it be this one?  One more trick for me to document - fblank during hblank.

32 minutes ago, Kirk_Johnston said:

 

Side point: It sounds like that Uniracers trick allows you to change a sprite's position on-screen during HBlank, so wouldn't that effectively allow a form of sprite multiplexing where you can display a single sprite at multiple positions down the screen during one frame and therefore visually have multiple instances of the one sprites on-screen, much like the snow in that Stone Protectors game on Genesis (https://rasterscroll.com/mdgraphics/graphical-effects/sprite-raster-effects/)?

 

If this works in principle basically as in the example above to allow the same end visual result effect on SNES (just using the Uniracers HDMA in SNES' case), that's definitely something working looking into more to see how it could be used for some cool effect. :)

I don't see any reason why that wouldn't work.

  • Like 1
Link to comment
Share on other sites

20 minutes ago, jeffythedragonslayer said:

https://forums.nesdev.org/viewtopic.php?t=19896

 

Might it be this one?  One more trick for me to document - fblank during hblank.

I don't see any reason why that wouldn't work.

It's crazy how this kind of stuff wasn't used more often on SNES, and certainly today in the SNES indie/homebrew scene at least to show off what can be done there in some actual games. I'm sure there's a lot that can be done with these little tricks, like I could presumably do the snow in my own shmup example using this trick now rather than wasting maybe 32 sprites for basically the same visual result:

 

 

That's a lot of sprites saved and potential issues with hitting sprites per scanline limits once more enemies and such start appearing avoided more easily too. :)

Edited by Kirk_Johnston
Link to comment
Share on other sites

14 hours ago, Kirk_Johnston said:

It's crazy how this kind of stuff wasn't used more often on SNES, and certainly today in the SNES indie/homebrew scene at least to show off what can be done there in some actual games. I'm sure there's a lot that can be done with these little tricks, like I could presumably do the snow in my own shmup example using this trick now rather than wasting maybe 32 sprites for basically the same visual result:

 

 

That's a lot of sprites saved and potential issues with hitting sprites per scanline limits once more enemies and such start appearing avoided more easily too. :)

I decided to document it as "TmEE's trick" for short, since that's the first person I found doing it.  Another name for it seems to be "hvdma," after the test rom.  The earliest I've seen it mentioned is 2019, and I think the reason why it took so long is that it's difficult to time the transfer precisely.

 

https://sneslab.net/wiki/TmEE's_trick

Edited by jeffythedragonslayer
  • Like 1
Link to comment
Share on other sites

On 5/24/2023 at 4:23 AM, Kirk_Johnston said:

I'll have a look. But if it's a major pain in the butt like almost all the other SNES dev stuff I've tried to use to date, I'll skip the sound stuff for now. 😅

I tested out the brr_encoder on a WAV file and then tried to play the outputted BRR file in Vitor's BRR player.  The player has a bug that causes the pitch to come out wrong.  So I can't recommend this workflow yet.  I will investigate the bug next.

Link to comment
Share on other sites

  • 2 weeks later...

Just adding in the tile sheet here again as I made an error before by saying the smaller objects sizes that make up the sprites were 8x8 when I meant 16x16:

GuideObjectTilesGrid.thumb.png.dbc8939954c7be8495aa82956b18cbc0.png

 

And here are the boss background images, just in case someone wants to check if they really do fit within the SNES' 2bpp colours per tile, total colour per layer, and max unique tiles per layer limits of Mode 0:

2004253137_BossReducedColour.png.f7e6ecf3503b43fec2b90a01c595aeca.png

MechBoss_2bpp.png.bc01b0679b1af186bccf7d6a99e3808e.png

Robotnic_2bpp.png.64c615b97398814a86278575ee30dd6d.png

Edited by Kirk_Johnston
Link to comment
Share on other sites

Oh, and the main background too:

BG_Shinobi.png.6d17eef5e1590df337da12b7aeda737a.png

 

Note: There's roughly 1000 unique tiles total used across the main background and all three of the large bosses above that also use background layers, which, even accounting for tile maps and sprite tiles and so on, is well within the SNES' VRAM and unique tile limits in Mode 0. This is just one more bonus of using Mode 0, where all the backgrounds are 2bpp, so take up much less memory than in say Mode 1 where two of them are 4bpp and the third 2bpp.

Edited by Kirk_Johnston
Link to comment
Share on other sites

Guys, did you know that Mode 0 is so powerful, it can even run... on the sound chip too?  Check out the SPC700 IPL boot rom, as described by anomie:

 

Start:  MOVW YA,$F6    ; *** MAIN LOOP ***
        MOVW $00,YA    ; Get address from 5A22's $2142-3,
        MOVW YA,$F4    ; mode from $2141, and echo $2140 back
        MOV $F4,A
        MOV A,Y
        MOV X,A
        BNE Trans      ; Mode non-0: begin transfer
        JMP [$0000+X]  ; Mode 0: jump to address
        .DW $FFC0      ; RESET vector


(just kidding!)  fullsnes calls the $00 value coming in to the SPC through $2141 "command=entry"

Edited by jeffythedragonslayer
  • Haha 1
Link to comment
Share on other sites

14 hours ago, jeffythedragonslayer said:

Guys, did you know that Mode 0 is so powerful, it can even run... on the sound chip too?  Check out the SPC700 IPL boot rom, as described by anomie:

 

Start:  MOVW YA,$F6    ; *** MAIN LOOP ***
        MOVW $00,YA    ; Get address from 5A22's $2142-3,
        MOVW YA,$F4    ; mode from $2141, and echo $2140 back
        MOV $F4,A
        MOV A,Y
        MOV X,A
        BNE Trans      ; Mode non-0: begin transfer
        JMP [$0000+X]  ; Mode 0: jump to address
        .DW $FFC0      ; RESET vector


(just kidding!)  fullsnes calls the $00 value coming in to the SPC through $2141 "command=entry"

Well, that would have made the sound chip so powerful that it can run Mode 0, rather than Mode 0 being so powerful that it can run on the sound chip. :-o

Link to comment
Share on other sites

18 hours ago, jeffythedragonslayer said:

Guys, did you know that Mode 0 is so powerful, it can even run... on the sound chip too?  Check out the SPC700 IPL boot rom, as described by anomie:

 

Start:  MOVW YA,$F6    ; *** MAIN LOOP ***
        MOVW $00,YA    ; Get address from 5A22's $2142-3,
        MOVW YA,$F4    ; mode from $2141, and echo $2140 back
        MOV $F4,A
        MOV A,Y
        MOV X,A
        BNE Trans      ; Mode non-0: begin transfer
        JMP [$0000+X]  ; Mode 0: jump to address
        .DW $FFC0      ; RESET vector


(just kidding!)  fullsnes calls the $00 value coming in to the SPC through $2141 "command=entry"

You had me for a moment...

Link to comment
Share on other sites

  • 2 weeks later...
Guest
This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...