Pages: 1
Posted on 07-11-16, 06:20 pm (rev. 2 by  MeroMero on 07-12-16, 08:51 am)
Death by cuteness

Karma: 6564
Posts: 461/598
Since: 05-01-13
This thread is somewhat out of left field considering my latest track record about ASM mods, but this read will be truly worth your time I hope.




Prelude:

First of all I would like to bring your attention about 2 oddities in canon NSMB games: have you ever noticed that there is a chunk of Foreground 5 seemingly missing from its graphics (.ncg)?


And again for Foreground 60?


Then look again, those missing chunks of graphics can be found in the .ncg of Tileset 5 and Background 60 respectively, don't believe me? Have a look by yourselves:
    

It seems that Nintendo devs used a trick to somehow make the graphics able to be shared amongst one same design, which for the Foregrounds (FG) and the Backgrounds (BG) is stored in a .nsc file.
And I would like to call this method the Tile-Share!

I will explain you in detail the core mechanics to use this tactic to its fullest potential!




1: Explanation:

If you decompress a .nsc file in the BG_nsc folder, the filesize will be 8192 bytes.
Now if you remember how FG and BG are designed, you should know that you can choose a 8×8 tile from the graphics with one of 2 palettes, and apply it to a 512×512 template.
How many tiles can you fit then in that template?

Let's do some fancy mathematics:
512²/8² = (512/8)² = 64² = 4096

4096 tiles per .nsc! And the decompressed filesize for a FG/BG .nsc is 8192 bytes… Could it be…
8192/4096 = 2

Would this mean that 2 bytes of data make up 1 tile? Seems plausible so far.
Let's see how… Oh! You know what? I'm just going to tell you the exact data.

Each tile takes 2 bytes, which means that each tile's offset begin at an even address and end with an odd address.
Due to the data being little-endian, you must invert the 2 bytes to read them correctly, ergo instead of reading them as AB CD read them as CD BA.
The tile order in the .nsc matches the tiles from the 512×512 template when read from left to right.

If you don't want the binary details, jump to the next sub-section.
Convert the data from hex to binary, upon conversion the data is laid out as follows:
PPPPVHTT TTTTTTTT

In order:
_T is the Tile Number in 10 bits, it can take a value from 0 to 1023 inclusive.
_H is the Horizontal Flipping bit, which will take effect only when set to 1.
_V is the Vertical Flipping bit, which will take effect only when set to 1.
_P is the Palette Number in 4 bits, it can take a value from 0 to 15 inclusive.


It is totally possible to read the tile data in hex, here's how:
_truncate the word (2 bytes) CDBA as C and then DBA.
C is the palette, and there's DBA:
_If D < 4, then you've already got the Tile Number DBA, HFlip=0 and VFlip=0.
_If D >= 4 and D < 8, then HFlip=1 and thus to retrieve the Tile Number you must subtract 4 to D.
_If D >= 8 and D < 12 (0xC), then VFlip=1 and thus to retrieve the Tile Number you must subtract 8 to D.
_If D >= 12 (0xC), then HFlip=1 and VFlip=1, thus to retrieve the Tile Number you must subtract 12 (0xC) to D.

Now we can enter the second part of the tutorial, what the Palette Number and the Tile Number really refer to!




2: Abuse the palettes:

It's nice to know that the Palette can take a number from 0 to 15 and that the Tile Number can be anything from 0 to 1023, but what good does this do if you don't even know how this data is interpreted?
Which is where DeSmuMe comes to the rescue!

If you open your NSMB ROM with the emulator and play through a level, pause the game and then go to Tools -> View Tiles.
This will open the TILE VIEW window.
Select 256 colors.
In the first combobox beginning from the top, select Main screen ExtPAL 3.
In the second combobox, you can toggle between A-BG - 0x6000000 and A-BG - 0x6010000.
For the palette, select something between 8 and 11 inclusive.

Now look what we have there:


Doesn't this look familiar?
    

It sure does. This is because of several factors:
_the FG .ncg is stored in the VRAM at address 0x600A000.
_the BG .ncg is stored in the VRAM at address 0x6011000.
_the palettes for FG and BG are always loaded in Main screen ExtPAL 3.
_Palette Number for FG is 8 or 9 by default.
_Palette Number for BG is 10 (0xA) or 11 (0xB) by default.
Be careful, the BG is written before the FG, which means that you can completely overwrite the BG with the FG due to the former being written in the VRAM at a later address than the latter.

Look at the palette numbers! Those are the exact same numbers than in the .nsc… is this a hint?
The conclusion is really simple, both FG and BG can read from palettes 0 to 15, which automatically includes palettes 8 to 11.
What does it mean? That you can make the FG read the BG palette on top of its own and vice-versa! Pretty neat, isn't it?

But that's not all, what I actually shown you was just the icing on the cake, but where's the main treat?
If you continue to read you can eat that cake at your heart content!




3: Abuse the tiling:

Remember what I told you about the Tile Number, which can take a value between 0 and 1023.
Now have you noticed that in the FG .nsc, most of the time no Tile Number was under 256 (0x100)?
This is where the VRAM read Tile Number 0x100 (pinpoted thanks to the magenta square):


Which matches the address 0x600C000

In the same vein in the BG .nsc, no Tile Number was under 576 (0x240)?
Tile Number 0x240 is read there in the VRAM:


Which matches the address 0x6011000

So where would Tile Number 0 ends up in the VRAM?
An answer that can be answered mathematically once again:
(0x6011000 - 0x600C000) / (0x240 - 0x100)
= 0x5000 / 0x140
= 0x500 / 0x14
= 0x40 or 64 in decimal

So this means that 1 Tile with a vertex of 8 pixels occupies 64 (0x40) bytes in the VRAM.
If we want to demonstrate with a mathematical reasoning where would Tile Number 0 be read, we need to follow this formula:
V-(T*D)
where:
_V is the VRAM address
_T is the Tile Number who is read at address V
_D is the Tile Number data size, which is always 64 (0x40)

Let's see:
0x600C000 - (0x100 * 0x40)
= 0x600C000 - 0x4000
= 0x6008000

Let's calculate again:
0x6011000 - (0x240 * 0x40)
= 0x6011000 - 0x9000
= 0x6008000

Both results match, and indeed it is the case in a real setting too: Tile Number 0 is written in the VRAM at address 0x6008000.

As an additional proof, FG 5 .nsc has some Tile Numbers as low as 64 (0x40) which in the VRAM points to address 0x6009000.
0x6009000 - (0x40 * 0x40)
= 0x6009000 - 0x1000
= 0x6008000

You get it, Tile Number 0 -> address 0x6008000


But what about the highest Tile Number, the 1023rd one (0x3FF)?
0x6008000 + (0x3FF * 0x40)
= 0x6008000 + 0xFFC0
= 0x6017FC0

Tile Number 1023 -> address 0x6017FC0


All in all it means that the .nsc, by virtue of being able to read up to 1024 Tile Numbers, have an effective range of 65536 bytes (0x10000) from 0x6008000 to 0x6017FFF included!


AND this is how Nintendo did to add what would seem to be additional tiles to FG 5 and FG 60!




Additional notes:

Some more information before you go abusing that trick:
_SubNohara is written at offset 0x600A000 and has a native and max range of 0x2000
_Tileset 1 is written at offset 0x6003000 and has a native range of 0x7000, and a max range of 0x9000 (tiles behaviors have a max range of 0xD000 though, use the FG to your advantage)
_BG is written at offset 0x6011000 and has a native range of 0x5000, and a max range of 0x7000
_FG is written at offset 0x600C000 and has a native range of 0x5000, and a max range of 0xC000
The layers are presented in the order they are written in the RAM, which means that if 2 layers overlap, the latter will overwrite the former.
Also be careful about additional animations for some Tilesets and FG!


Some thoughts for NSMBe:
_due to this new information, I think the way NSMBe open the Top and Bottom Backgrounds should be changed, for example after clicking one of the BG, it should open a window from where you can choose a Tileset and then a FG (or BG if you choose to open a FG), once you have confirmed your choices, it will bring you to the Tilemap editor but with the increased range and 4 palettes.


NOTE 1: You can abuse this trick with the SubNohara V2 ASM-Hack, but Tile Numbers above 895 (0x37F) will fall out of range! This is because Tile Numbers above 255 (0xFF) automatically get added the number 128 (0x80).
NOTE 2: No tummy ache after eating this appetizer? Good, because after all it only was a prelude, or a hype tool if you wish for the next ASM Hack of mine, which will be the main dish if you allow the euphemism!
Pages: 1