Multiple Giant Sprites on SMW - How it works
The incoming new system for SA-1 Pack v1.40, the OAM MaxTile System automatically pushes the SNES sprite hardware to the limits by compressing all unused entries and discarding the offscreen tiles. With that you can have up to eight banzai bills, six big boos and much more.
SMW has a semi-fixed sprite buffer, where each object has a static mapping to it. This works great on the game, but it always gave a fixed amount of tiles you can render, which always limited each sprite to draw up to four 16x16 tiles (so one 32x32 sprite). It had special settings for some sprites, like the Big Boo or Banzai Bill where they could come to a slot that had more space available for filling the tiles. But using that method, you were able to only have one sprite of each since there was only one memory region that had more tiles available to use.
Keep in mind! Sprite on this article means a complete entity, like "Mario" or "Rex". Tile on this article means a piece of the sprite, like Mario's head or Big Boo's eyes.
Initially, there was a solution for that called NoMoreSpriteTileLimits. It works by transforming the shared general-purpose sprite memory into a stack, so each game would stack several tiles together them, giving a more efficient sprite storage. But still, around 60% of the sprite memory was still free but unusable because it was only possible to access by accessing another memory page and rewriting the rest of sprite types (player, extended, cluster, particles sprites, etc.). So a proper solution was never really made and we sticked with the NMSTL method for years.
The SA-1 MaxTile system however works by giving the entire sprite memory region to the sprite and when the rendering is done, it compresses and moves the rendered content to another much larger region and frees the sprite memory so allowing to all sprites have the entire memory free for rendering. It recycles the memory region so the sprites don't have to be changed internally but at the same time they have the entire space to work on, while the already rendered ones are saved on a separate storage so they won't interfer with the current one being rendered. On the end, everything is merged and compressed together (including the other sprite types, since on the end of the frame you are sure that all of them were rendered already) and sent to the hardware, allowing you to have as much tiles as the hardware allows for, which is 128 tiles. With that, it's possible to fill up to 57% of the entire SNES screen using sprites, while previously, using the NoMoreSpriteTileLimits patch for SMW (which theorically maxed out the tiles on the game for ROM hackers), you were able to fill only 22% of the SNES screen.
Summary on how SMW worked with sprites:
the sprite tile table has 128 entries (hardware limit);
the first 64 entries were reserved for other sprite types and each one had the right to use 2, 4 or 8 tiles: cluster, particles, smokes, etc;
the next 10 or so entries were reserved by Mario, Yoshi and carryable items;
the rest of 50 slots were divided into 12 blocks, that varies from 4 to 20 items, depending on the sprite memory setting;
normally, all other sprites always had a fixed amount of slots available (normally 4 to 8) and one special (like the Big Boo) had 20 reserved;
If there were only four sprites on the screen, the other blocks would remain unused; and
If there was more than one Big Boo, the other one couldn't get rendered correctly because it didn't have enough free slots to render on its own.
Summary on how SMW worked with NoMoreSpriteTileLimits patch (NMSTL):
the sprite tile table has 128 entries;
the first 64 entries were still reserved as expected;
the next 10 or so as well;
the rest of 50 slots is not split into blocks. Instead, it's transformed into a stack;
each sprite would then render their sprite tiles into the stack, filling it; and
if a sprite only needed, for example, four tiles, then the stack would only get filled with four tiles. that means the other slots are free to other sprites uses;
keep doing that until all sprites are done. 2-3 big boos could be rendered normally if the stack had enough space; and
but still all general-purpose SMW sprites would only have 50 slots available while the rest was always reserved for other things.
Summary on how SA-1 MaxTile works:
the sprite tile table has 128 entries;
the first 64 entries are reserved, as well the next 10 ones;
the remaining 50 slots, however, are always marked as free for all sprites;
once a sprite finishes rendering, SA-1 moves the written slots to another RAM region;
so even if you have 20 sprites on the screen, each one will still think that there is 50 slots available for each one. So if you place six big-boos, each one will be rendered normally because the 50 slots are always free for all them;
on the end, SA-1 will take the reserved 64 + 10 reserved slots and analyze them;
since 99% of the time only 3-4 of these reserved slots are used, the other 70 or so are now marked as free;
with the ~70 + 50 slots free, SA-1 will move the previously rendered tiles to the main sprite table and will fill completely including the former reserved ones;
since SA-1 took care of these, the other sprites don't need to access the extended table, keeping compatibility with all existing ones (including custom ones); and
if a custom sprite needs more than 50 slots, the sprite can ask the SA-1 to move the tiles to the temporary region and start drawing again.
Note that since I tried making the explanation a bit simple, there might be some inaccurate information the amount of reserved slots. But this is the summary of how MaxTile work and why it still works with everything. And of course, if 20 sprites attempt drawing 50 tiles each one, the SA-1 would discard the exceeded ones, because the hardware can only render 128 tiles.
Either way, MaxTile was an idea I had several weeks ago, but I only decided to give it a try after I was having trouble converting Contra III to SA-1. The stress I had on Contra III was the insight for me trying something new and that so far people are looking forward for it!
