Tuesday, January 2, 2018

Level Load Block in S3A

Reader kathy asks:
is the emerald shrine that you're warped to for the super emerald special stages the same stage as hidden palace? how's that work?
Well, as I previously mentioned, they're completely separate levels. They just happen to have nearly identical level load blocks and level layouts, only really differing in their object layout and level size, as well as more esoteric aspects such as their background event routines.

Surprisingly enough, entries for these stages exist within S3A's level load block, hinting that their addition wasn't as late as one might think. Which brings me to this question by an anonymous commenter:
I'd be more interested in knowing what happens when a Sonic & Knuckles stage gets loaded in Sonic 3. For example, what tells the game to use Azure Lake graphics in Mushroom Valley Zone?
Well, since the data for the Sonic & Knuckles stages isn't included in the Sonic 3 cartridge, their entries in the level load block had to be replaced with placeholder values. For example, Flying Battery Zone, which occupies the slots between Carnival Night Zone and Icecap Zone, has all of its data pointers replaced with pointers to Icecap Zone's primary 16x16 block definitions:
; ---------------------------------------------------------------------------
    dc.l ICZ_16x16_Primary_Kos+$1A000000
    dc.l ICZ_16x16_Primary_Kos+$1A000000
    dc.l ICZ_16x16_Primary_Kos+$12000000
    dc.l ICZ_16x16_Primary_Kos+$12000000
    dc.l ICZ_16x16_Primary_Kos
    dc.l ICZ_16x16_Primary_Kos
; ---------------------------------------------------------------------------
    dc.l ICZ_16x16_Primary_Kos+$1C000000
    dc.l ICZ_16x16_Primary_Kos+$1C000000
    dc.l ICZ_16x16_Primary_Kos+$13000000
    dc.l ICZ_16x16_Primary_Kos+$13000000
    dc.l ICZ_16x16_Primary_Kos
    dc.l ICZ_16x16_Primary_Kos
; ---------------------------------------------------------------------------
Mushroom Valley Zone and Lava Reef Zone are both pointing at Azure Lake's primary 16x16 block definitions, which is what tells the game to use Azure Lake graphics in Mushroom Valley Zone. Meanwhile, Sandopolis Zone and the rest of the Sonic & Knuckles levels instead contain an unaltered copy of Angel Island Zone's level load block:
; ---------------------------------------------------------------------------
    dc.l ALZ_16x16_Kos+$26000000
    dc.l ALZ_16x16_Kos+$26000000
    dc.l ALZ_16x16_Kos+$18000000
    dc.l ALZ_16x16_Kos+$18000000
    dc.l ALZ_16x16_Kos
    dc.l ALZ_16x16_Kos
; ---------------------------------------------------------------------------
    dc.l ALZ_16x16_Kos+$28000000
    dc.l ALZ_16x16_Kos+$28000000
    dc.l ALZ_16x16_Kos+$19000000
    dc.l ALZ_16x16_Kos+$19000000
    dc.l ALZ_16x16_Kos
    dc.l ALZ_16x16_Kos
; ---------------------------------------------------------------------------
    dc.l AIZ1_8x8_Primary_KosM+$B000000
    dc.l AIZ1_8x8_Secondary_KosM+$B000000
    dc.l AIZ1_16x16_Secondary_Kos+$A000000
    dc.l AIZ1_16x16_Secondary_Kos+$A000000
    dc.l AIZ1_128x128_Kos
    dc.l AIZ1_128x128_Kos
; ---------------------------------------------------------------------------
    dc.l AIZ1_8x8_Primary_KosM+$C000000
    dc.l AIZ1_8x8_Secondary_KosM+$C000000
    dc.l AIZ1_16x16_Secondary_Kos+$B000000
    dc.l AIZ1_16x16_Secondary_Kos+$B000000
    dc.l AIZ1_128x128_Kos
    dc.l AIZ1_128x128_Kos
; ---------------------------------------------------------------------------
    dc.l ALZ_16x16_Kos+$2E000000
    dc.l ALZ_16x16_Kos+$2E000000
    dc.l ALZ_16x16_Kos+$1C000000
    dc.l ALZ_16x16_Kos+$1C000000
    dc.l ALZ_16x16_Kos
    dc.l ALZ_16x16_Kos
; ---------------------------------------------------------------------------
    dc.l ALZ_16x16_Kos+$30000000
    dc.l ALZ_16x16_Kos+$30000000
    dc.l ALZ_16x16_Kos+$1D000000
    dc.l ALZ_16x16_Kos+$1D000000
    dc.l ALZ_16x16_Kos
    dc.l ALZ_16x16_Kos
; ---------------------------------------------------------------------------
That is, except for the Sonic & Knuckles bonus stages, which instead contain pointers to the end of ROM marker!
; ---------------------------------------------------------------------------
    dc.l Gumball_8x8_KosM+$47000000
    dc.l Gumball_8x8_KosM+$47000000
    dc.l Gumball_16x16_Kos+$33000000
    dc.l Gumball_16x16_Kos+$33000000
    dc.l Gumball_128x128_Kos
    dc.l Gumball_128x128_Kos
; ---------------------------------------------------------------------------
    dc.l Gumball_8x8_KosM+$47000000
    dc.l Gumball_8x8_KosM+$47000000
    dc.l Gumball_16x16_Kos+$33000000
    dc.l Gumball_16x16_Kos+$33000000
    dc.l Gumball_128x128_Kos
    dc.l Gumball_128x128_Kos
; ---------------------------------------------------------------------------
    dc.l EndOfROM+$47000000
    dc.l EndOfROM+$47000000
    dc.l EndOfROM+$37000000
    dc.l EndOfROM+$37000000
    dc.l EndOfROM
    dc.l EndOfROM
; ---------------------------------------------------------------------------
    dc.l EndOfROM+$47000000
    dc.l EndOfROM+$47000000
    dc.l EndOfROM+$37000000
    dc.l EndOfROM+$37000000
    dc.l EndOfROM
    dc.l EndOfROM
; ---------------------------------------------------------------------------
    dc.l EndOfROM+$47000000
    dc.l EndOfROM+$47000000
    dc.l EndOfROM+$38000000
    dc.l EndOfROM+$38000000
    dc.l EndOfROM
    dc.l EndOfROM
; ---------------------------------------------------------------------------
    dc.l EndOfROM+$47000000
    dc.l EndOfROM+$47000000
    dc.l EndOfROM+$38000000
    dc.l EndOfROM+$38000000
    dc.l EndOfROM
    dc.l EndOfROM
; ---------------------------------------------------------------------------
So what exactly is going on? Let's take Flying Battery Zone as an example again. What would happen if the developers simply removed all the FBZ level data from the build, without actually touching the level load block? Since the FBZ data now takes up zero bytes, all labels to it should now point at whatever followed FBZ's data when it was still in the ROM.

Assuming that FBZ's data originally came between the data for CNZ and ICZ, what do you suppose follows CNZ's data in the final ROM layout?

NameAddress
CNZ_16x16_Kos1CCC34
CNZ_8x8_KosM1CDC74
CNZ_128x128_Kos1D0E96
ICZ_16x16_Primary_Kos1D3FB6
ICZ_8x8_Primary_KosM1D4296
ICZ_128x128_Primary_Kos1D56A8

Mushroom Valley Zone, Lava Reef Zone, and the Sonic & Knuckles bonus stages follow the same pattern:

NameAddress
LBZ2_16x16_Secondary_Kos1E5F70
LBZ2_8x8_Secondary_KosM1E77D0
LBZ2_128x128_Kos1EAF04
ALZ_16x16_Kos1EE0C4
ALZ_8x8_KosM1EEB84
ALZ_128x128_Kos1F1936
......
Gumball_16x16_Kos1FEA0E
Gumball_8x8_KosM1FEE2E
Gumball_128x128_Kos1FFB80
EndOfROM1FFF20

Okay, but what about Sandopolis Zone and the remaining Sonic & Knuckles level slots? Why are they filled with copies of Angel Island Zone's level load block?

Here's my guess: the developers originally padded the entire table with copies of the AIZ data, before filling in each slot with the actual data as the respective level entered production. The presence of AIZ data in the slots for Sandopolis Zone and the remaining S&K stages is indication that those stages hadn't yet entered production at the time of Sonic 3's release.

Indeed, by digging around in the ROM, we can find unused object layouts for Mushroom Valley Zone as well as unused palette data for Lava Reef Zone and the S&K bonus stages, but seemingly nothing for the remaining levels.

9 comments:

  1. Is there a reason why only Mushroom Valley and Lava Reef use ALZ graphics and not the rest of the S&K zones?

    ReplyDelete
    Replies
    1. Yes. I've just updated the post to address this.

      Delete
    2. That make sense, however there is a bit of code that tells Doomsday zone and Sky Sanctuary zone to not use act numbers.

      Delete
  2. That made more sense than what I thought it was.

    Even then, it doesn't seem like those "misplaced"/placeholder entries in the load block would crash the game, so it has to be something else which does it.

    ReplyDelete
    Replies
    1. Actually, this should be quite enough. Note how 8x8 tiles are compressed using KosM, but the placeholder 16x16 blocks use regular Kosinski compression. On stage load, the game will try to unpack the 16x16 blocks using the KosM unpacker and die a horrible death.

      However, you are correct in assuming there are other elements at play here. I may follow up on this further down the line.

      Delete
  3. The sprite you see when Sonic and Tails are attached to a wall while scaling down towers does exist in the S3A ROM, apparently... but that seems to be it for Sandopolis.

    ReplyDelete
    Replies
    1. Actually, the audio for the S&K zones seems to have been completed as well, including music and sound effects, although Flying Battery Act 1 has an instrument that goes increasingly off-sync. I know you're likely aware of this and I know audio isn't your strong suit, but I thought that pointing that out would at least give an idea on what their priorities were.

      Delete
    2. I'm certain that all the stages were already planned out, which is why the number of level slots is the same as in the final game. As for the music, in the Sonic Jam strategy guide, Iizuka says they had a lot of music to choose from, so the soundtrack was probably decided well in advance.

      Delete
  4. Would it be possible to access the S&K zones without having them crash right at the title card or a few seconds after the start, also why does every level ID after 17 mention an not collectable ring besides being garbage data

    ReplyDelete