Tuesday, December 5, 2017

Hydrocity Zone intro area: the pool

It's immediately apparent that the large pool of water at the start of Hydrocity Zone 1 looks different from all other water in the game. None of the foreground tiles are affected by the water palette, and neither are sprites, for that matter.


Actually, when you put it that way, only the brick pattern in the background takes on different colors below the waterline. The reason for this is made clear if we open up the stage in SonLVL, or just travel all the way to its loopback:


There's no water palette at all! The bricks below the waterline take on different colors because they use different colors.

Normally, the level blocks containing this brick pattern are drawn using the three shades of turquoise from the latter half of palette line 2. However, exclusively within the intro pool such level blocks are instead drawn with palette line 3, which grants the bricks a set of yellow colors otherwise used solely by a candle-lit ornament in the stage's background.


Then, once the camera position approaches the vicinity of the pool, the stage's dynamic resize routines kick in and load the underwater brick colors over the three shades of yellow, thereby completing the effect.


This explains why the bricks appear yellow in the loopback: although the pool blocks are within view, the actual camera position is far beyond the end of the level, outside the range monitored by the resize routines.

Okay, but what's the reason for all this trickery? Why not just a regular water palette like everywhere else in the game?


The reason is the dry tunnel off to the right. We need a way to draw the brick pattern both dry and submerged, side-by-side. The usual scanline tricks aren't going to help us.

All right, so swapping out the colors is indeed a suitable solution. If you take a close look at the underwater brick colors though, you'll notice something's wrong. The highlight color used in the intro pool (left, below) is brighter and more blue than the actual water palette used in the rest of the stage (right):


The reason for this becomes obvious once you look at the dynamic resize routine code: the color values were punched in by hand, rather than being read from the stage's palette files, and the programmer got one of the colors wrong:
loc_1C892:
    cmpi.w  #$360,(Camera_X_pos).w
    bhs.s   locret_1C8B6
    cmpi.w  #$3E0,(Camera_Y_pos).w
    blo.s   locret_1C8B6
    lea     (Normal_palette_line_4+$10).w,a1
    move.w  #$B80,(a1)+
    move.w  #$240,(a1)+
    move.w  #$220,(a1)+
    addq.b  #2,(Dynamic_resize_routine).w

locret_1C8B6:
    rts
Wait, what? B80? That's not even a valid Mega Drive color! In practice, what happens is the low bit of the blue channel gets ignored, and the result is the same as A80. But the actual color is supposed to be 680!

I can almost imagine how this error occurred. Someone wrote down the intended color values on a piece of paper: 680, 240, 220. Then the programmer came along and blindly typed in what he read from the piece of paper.


Admittedly the error isn't as obvious on real hardware, but there was no reason to hammer the values into the code like that. Furthermore, the code itself was later replicated on the Sonic & Knuckles cartridge, so they had another chance to fix their mistake. They missed it again! Aargh.

Okay, one last glitch with the resize routines. Hydrocity Zone 1 has three of them, and they're arranged logically like so:

0

2 → 4

The level starts from routine 0. When the camera dips far enough below, routine 0 loads the underwater brick colors as seen above, and changes the current routine to 2. Conversely, if the camera goes back up, routine 2 reloads the yellow background colors and resets the current routine back to 0.

There's another code path for it to take, though. If the camera remains low and instead leaves the vicinity of the pool to the right, routine 2 again reloads the yellow colors, but instead advances the current routine to 4.

Routine 4 is a stub function: it doesn't have any logic. As such, once it's reached, no more dynamic resize code will run for the remainder of the stage. Which means that as soon as you take the tunnel out of the pool, the underwater bricks become yellow, and then remain stuck that way.


We can confirm this by going the long way around, back to the high path out of the pool. At the location pictured above, a collision change object usually forces the player onto the top walkway, preventing them from returning to the pool.

However, as we've come to expect, shoddy placement of the object allows you to cross it to the right, then vault over it to the left to remain on the lower walkway. With no other obstacles in our way, we can finally dive back in the drink.


Yeah!

No comments:

Post a Comment