Wednesday, October 18, 2017

The S&K alone flag

23 years ago on this very day, Sonic & Knuckles was released worldwide on the Sega Genesis. Happy anniversary!


To mark the occasion, I figured it might be relevant to discuss what happens when Sonic & Knuckles boots up without a second game locked on to the cartridge.

First, how does it detect a cartridge in the lock-on slot? The game's startup routine checks for the presence of a lock-on cartridge's ROM header by comparing the longword at address $200100 with the string "SEGA". If this check fails, then the lock-on slot does not contain a valid cartridge, and control jumps to SonicAndKnucklesStartup, which handles the boot sequence both for Sonic 3 & Knuckles as well as for standalone Sonic & Knuckles:
    moveq   #-1,d1
    move.l  (SegaHeadersText).l,d0          ; test to see if SEGA is at the locked on ROM's $100
    cmp.l   (LockonHeader).l,d0
    bne.w   SonicAndKnucklesStartup
Over at SonicAndKnucklesStartup, the value in the d1 register is written to RAM address $FFAE otherwise known as the SK_alone_flag. This flag is clear when the Sonic 3 cartridge is locked on, and set when the lock-on slot is empty:
SonicAndKnucklesStartup:
    bsr.s   Test_Checksum
    move.w  d1,(SK_alone_flag).w
    ...
So, what does the flag do? Well, perhaps rather obviously, the first thing the flag is responsible for is whether to display the Sonic & Knuckles title screen, or the Sonic 3 & Knuckles one. It also defines the game title used in stage title cards, and which logo appears at the end of the credits sequence.


Recall how I mentioned that Sonic 3 & Knuckles is just a special mode of Sonic & Knuckles that is allowed to reference content from the Sonic 3 cartridge? That is the mode in which the SK_alone_flag is clear. Conversely, when the flag is set, the game cannot be granted access the Sonic 3 cartridge, because it isn't there!

As a result, setting the flag causes a whole bunch of stuff to get skipped:
  • All save functionality is disabled. The battery backup is on the Sonic 3 cartridge, so there would be no point in running the code.
  • Only Sonic & Knuckles stages appear in the demo reel, and in his demos, Sonic isn't accompanied by Tails.
  • Tails also does not appear in Sonic's continue screen.
  • Star posts will only take you to the slot machine and rolling jump bonus stages.
  • The starting positions for Mushroom Hill Zone 1 are adjusted to skip over the first special stage ring.
  • There's only a single set of special stages, since the other one is on the Sonic 3 cartridge. As such, special stage rings will never take you to Hidden Palace, and thus the Super Emeralds are inaccessible.

Interestingly, the scenes added to the ending sequence when you clear the game with all Super Emeralds do not check the flag at all. This includes the scene where Knuckles sees Sonic and Tails off, which is set in Angel Island Zone!


Beyond that, there is a surprising amount of work to prevent you from accessing Sonic 3 content using the level select:
  • If either the Tails alone or the Sonic and Tails player option is chosen, the player mode is set to Sonic alone.
  • If a Sonic 3 level is selected, the current level is forced to Mushroom Hill Zone 1.
  • Even if the first level you select is a special stage, the saved current level is also forced to Mushroom Hill 1, to prevent you from getting sent to Angel Island Zone afterwards.
  • Finally, there's no debug cheat, which prevents you from using an obscure feature that allows the player to select which special stage to play by setting the Sound Test option to the intended stage number, and then holding down the A button during the fade-in.

However, my favorite feature definitely has to be Knuckles' intro sequence, which is a perfect tie-in with Sonic and Tails' post-credits scene when the game is cleared with all Chaos Emeralds. It explains the motivation behind Knuckles' story and makes it abundantly clear that it takes place after Sonic's.


So, next time you feel like playing Sonic 3 & Knuckles, consider playing Sonic 3 and Sonic & Knuckles separately, and keep an eye out for some of these features.

That's it for my series on Lock-on Technology! I have no clue what I'm gonna write about tomorrow.

Tuesday, October 17, 2017

Why no Knuckles in Sonic 1?

When Sonic 1 is locked on to the Sonic & Knuckles cartridge, rather than producing "Knuckles in Sonic 1" as one might expect, we are instead shown the following screen:


Of course, this is actually a splash screen for the "Blue Sphere" bonus game, but more to the point, it suggests there is NO WAY to combine the two games into one, as was previously done with Sonic 2. Is there a technical reason for this?

Takashi Iizuka, senior game designer for Sonic 3 and Sonic & Knuckles, says it's because Sonic 1's level design wasn't conductive to using Knuckles' abilities:
We realized that the construction of the world was really made for [Sonic] and when you started putting other characters into that world, it didn't really work [...] we didn't want people to have a bad experience, so we put them into the special stages.

For Sonic 2, the maps were made so that when you fly around as Super Sonic, you can fly around pretty easily [...] The maps are pretty tall in construction, so because of that we were able to fit Knuckles in and play around with him.
He's not wrong, but I still find that a flimsy excuse. After all, the levels in Sonic 2 are at times not very conductive either, but the developers found a way to work around those issues regardless. Yes, the presence of Super Sonic was a major catalyst in making Knuckles in Sonic 2 possible, but not in the manner described.

I mentioned before how in Sonic 2, the blue colors in the player palette aren't safe for use by anything other than Sonic, because when Sonic turns into Super Sonic, anything using those colors will also start glowing bright yellow.

Super Sonic didn't exist in Sonic 1, though, and as it turns out, quite a few different objects make use of the blue colors, including bumpers, buttons, item boxes and almost every kind of enemy. When Knuckles is introduced to the game, his palette corrupts the appearance of all these objects.


In particular, both Spring Yard Zone and the special stage contain level blocks which are rendered using more than one palette while sharing the same art. The visual integrity of these elements is completely destroyed once the uniform blue gradient is replaced by three shades of red and one shade of green.


So apart from the palette, are there any other issues? Not really. Back in September 2005, Stealth, aka Simon Thomley of Sonic Mania fame, released his Knuckles in Sonic 1 hack, which was considered the "Holy Grail of ROM Hacking" at the time and one of the first ROM hacks to be made through use of a split disassembly.

In this hack, Stealth avoids the palette issues entirely by coercing Knuckles' sprites into the Sonic 1 palette, rather than the other way around. The result is that while Knuckles looks a bit off, the rest of the game remains safely unaltered.

It doesn't even crash when you glide into a conveyor belt!


As a final note, since Stealth ported the Knuckles object from Knuckles in Sonic 2, the same behavioral quirks from the Sonic 2 object are present in this hack. These quirks would later carry over to the Sonic 1 and Sonic 2 mobile remakes, as Stealth would base the Retro Engine implementation on his tested, well-documented code from ten years prior.

Monday, October 16, 2017

Knuckles in Sonic 2: special stage sprites

Just as a quick aside: much like his running animation in Sonic 3, Knuckles' Sonic 2 special stage sprites were created by recoloring Sonic's sprites, then pasting a Knuckles head on top. More specifically, the head from his Sonic 3 special stage sprites, which is why the perspective looks a bit off.


The finalized sprite notoriously gives Knuckles tan arms, but don't be fooled into thinking this is noteworthy. Everybody has tan arms in the Sonic 2 special stage!


Similarly, Knuckles' appearance in the Sonic 2 title screen is based off of his 3D render from the Sonic & Knuckles title:


Note the incorrect transparency on the left fist in both games. Interestingly, the Sonic 2 title screen has more frames of animation than Sonic & Knuckles. I wonder if they were made specifically for Knuckles in Sonic 2, or are they evidence of a longer, scrapped Sonic & Knuckles title animation?

Friday, October 13, 2017

Knuckles in Sonic 2: player palette

Even after reordering Knuckles' colors to match Sonic 2's player palette, some of Sonic 2's graphics come out looking a bit weird, mainly due to the introduction of green in the middle of a previously uniform gradient. For instance, the barrier graphics end up looking disfigured, like so:


The solution is to include a replacement art file within the Knuckles in Sonic 2 patch ROM. Interestingly, the developers chose to make the replacement barrier grey; possibly a red barrier looked too dark.


The patch ROM also includes replacement art for the invincibility stars, as well as item box icons for either power-up:


So why is the green color in the middle of the gradient? My first guess was so that it lines up with the color used for the title card backgrounds, but it turns out that's wrong: without any modification, title cards would use a different color:


Instead, what I found was that the game uses animal graphics from the Sonic 2 cartridge, and the green color seems to have been purposely lined up so it causes minimal disturbance to the Flicky sprite:


Flickies aren't the only sprites without replacement art. As I showed off last time, the water sprites in Aquatic Ruin Zone are rendered using Sonic's blues in Sonic 2, translating into a red and green mess once Knuckles' palette is applied:


However, this was already a problem in Sonic 2, because the blue colors in the player palette aren't safe to use. When Sonic turns into Super Sonic, anything using those colors will also start glowing bright yellow:


Finally, let's look at the lives icon. This one is interesting because everything was remapped to the player palette, even the text which normally uses the ring colors on the enemy palette:


Note how the text also retains the white shine characteristic of Sonic 3's HUD. This leads me to believe that the palette conversions were all done by a programmer, without using graphics editing tools. Note additionally how Knuckles' head in Sonic 2 has a rougher appearance; yet another glimpse into the Knuckles of days past.

Thursday, October 12, 2017

Knuckles in Sonic 2: player sprites

As we've seen before, when playing as Knuckles, a different palette is loaded into the player palette slot. The only real difference between it and the regular Sonic palette is that Sonic's three blues are replaced with Knuckles' three reds:


Now, in order to take advantage of DMA, all player sprites must be stored uncompressed, which takes up a lot of ROM space. In fact, Knuckles' sprites alone use up about 1 of the 16 megabits in the Sonic & Knuckles ROM! That's half the total capacity of the Knuckles in Sonic 2 patch ROM!

Obviously, we would like to reuse Knuckles' sprites from the Sonic & Knuckles ROM in Sonic 2. However, therein lies a problem: although most of them are either similar or exactly the same, the order of the colors in Sonic 2's player palette is completely different from the one in Sonic & Knuckles:


Unfortunately, we can't just apply the Sonic & Knuckles palette directly because a lot of graphics depend on the Sonic 2 colors. For example, all the enemies in Emerald Hill Zone are rendered exclusively using the player palette:


So what's the solution?

Instead of DMAing Knuckles' sprites directly from ROM to VRAM, we first run them through a conversion routine which reads each tile from ROM, swaps all the color indices around to fit the Sonic 2 palette, and writes them to RAM. Finally, the fully-converted sprite then is DMA'd from RAM to VRAM.

The code for this can be found in the LoadKnucklesDynPLC routine of the Knuckles in Sonic 2 disassembly. It uses a lookup table to map each of the 256 byte values that may show up in the source data to their corresponding value once the Sonic 2 palette is applied:
ArtConvTable:   dc.b $00,$06,$05,$03,$02,$04,$0C,$0D,$0E,$0F,$0A,$0B,$07,$08,$09,$01
                dc.b $60,$66,$65,$63,$62,$64,$6C,$6D,$6E,$6F,$6A,$6B,$67,$68,$69,$61
                dc.b $50,$56,$55,$53,$52,$54,$5C,$5D,$5E,$5F,$5A,$5B,$57,$58,$59,$51
                dc.b $30,$36,$35,$33,$32,$34,$3C,$3D,$3E,$3F,$3A,$3B,$37,$38,$39,$31
                dc.b $20,$26,$25,$23,$22,$24,$2C,$2D,$2E,$2F,$2A,$2B,$27,$28,$29,$21
                dc.b $40,$46,$45,$43,$42,$44,$4C,$4D,$4E,$4F,$4A,$4B,$47,$48,$49,$41
                dc.b $C0,$C6,$C5,$C3,$C2,$C4,$CC,$CD,$CE,$CF,$CA,$CB,$C7,$C8,$C9,$C1
                dc.b $D0,$D6,$D5,$D3,$D2,$D4,$DC,$DD,$DE,$DF,$DA,$DB,$D7,$D8,$D9,$D1
                dc.b $E0,$E6,$E5,$E3,$E2,$E4,$EC,$ED,$EE,$EF,$EA,$EB,$E7,$E8,$E9,$E1
                dc.b $F0,$F6,$F5,$F3,$F2,$F4,$FC,$FD,$FE,$FF,$FA,$FB,$F7,$F8,$F9,$F1
                dc.b $A0,$A6,$A5,$A3,$A2,$A4,$AC,$AD,$AE,$AF,$AA,$AB,$A7,$A8,$A9,$A1
                dc.b $B0,$B6,$B5,$B3,$B2,$B4,$BC,$BD,$BE,$BF,$BA,$BB,$B7,$B8,$B9,$B1
                dc.b $70,$76,$75,$73,$72,$74,$7C,$7D,$7E,$7F,$7A,$7B,$77,$78,$79,$71
                dc.b $80,$86,$85,$83,$82,$84,$8C,$8D,$8E,$8F,$8A,$8B,$87,$88,$89,$81
                dc.b $90,$96,$95,$93,$92,$94,$9C,$9D,$9E,$9F,$9A,$9B,$97,$98,$99,$91
                dc.b $10,$16,$15,$13,$12,$14,$1C,$1D,$1E,$1F,$1A,$1B,$17,$18,$19,$11
You might recall how back when the earth was still flat, I mentioned tiles are made up of 4-bit color indices. This means each byte actually represents two separate pixels. As such, the actual pixel conversion function can be seen on the left nybble when going down the table, and the right nybble when going across.

All that's left is to apply the same procedure as in Sonic & Knuckles: take the regular player palette and replace Sonic's four blues with Knuckles' three reds, as well as the green of his socks:


Next time, we'll finish up our look at Knuckles in Sonic 2 by looking at the consequences of modifying those four colors, and the graphical replacements that came as a result.

Wednesday, October 11, 2017

Knuckles in Sonic 2: object layouts

Just as with Sonic 3 before it, Knuckles in Sonic 2 includes its own object layouts for all the Sonic 2 levels. The reasons for this are varied. Sega made sure to flaunt the extra 1-ups in Chemical Plant Zone, but sometimes the additional item boxes are a little bit more subtle.


Sonic 2's levels weren't designed with Knuckles' climbing ability in mind, and as a result, some walls only extend as far as Sonic can reach. Knuckles in Sonic 2 occasionally patches these through clever use of a level's existing obstacles.


Other solutions aren't as elegant. The underside of Hill Top Zone 1's starting area cuts off abruptly, so they just stacked a bunch of invisible blocks on either side of the bottomless pit. Meanwhile, in Wing Fortress Zone, invisible blocks were placed at the end of the level to prevent Knuckles from gliding over the boss area.


Finally, sometimes less is more. In Sonic 2, there's a breakable column right near the start of Aquatic Ruin Zone. It was removed in the Knuckles in Sonic 2 layout because it'd be a bit stupid to start off the level with an obstacle that's too tall to clear with Knuckles' reduced jump height.


Hm, that water looks kind of funky... Oh yeah, we haven't even talked about the consequences of trying to put Knuckles and his palette into a game that wasn't designed for it. That'll be our subject for the next couple of posts.

Tuesday, October 10, 2017

Knuckles in Sonic 2: control quirks

In Knuckles in Sonic 2, if you perform the inputs for a spindash while Knuckles is sliding on the floor after landing from gliding, Knuckles will simply jump out of the sliding pose, completely ignoring the down input:


This is quite annoying because in Sonic 3 & Knuckles, doing the same inputs successfully initiates a spin dash directly from the sliding pose, without having to wait for Knuckles to get back up. This is due to a feature I'll call slow duck:


Here's the code responsible for making the player duck into a roll when they press the down button, as seen in Sonic 3:
Player_Roll:
    tst.b   status_secondary(a0)
    bmi.s   locret_127D0
    move.w  ground_vel(a0),d0
    bpl.s   loc_127B8
    neg.w   d0

loc_127B8:
    cmpi.w  #$80,d0
    blo.s   locret_127D0
    move.b  (Ctrl_1_logical).w,d0
    andi.b  #button_left_mask|button_right_mask,d0
    bne.s   locret_127D0
    btst    #button_down,(Ctrl_1_logical).w
    bne.s   Player_ChkRoll

locret_127D0:
    rts
The breakdown, as usual:
  • First, we check the high bit of the player's status_secondary bitfield. If it's set, do nothing.
  • Next, take the player's ground velocity and calculate its absolute value. If the player is traveling at a speed lower than 0.5 pixels per frame, do nothing.
  • Next, check if the player is pressing either the left or right buttons. If they are, do nothing.
  • Finally, check if the player is pressing the down button. If they are, branch to Player_ChkRoll, which will put the player in their rolling pose and play a sound effect, only if they weren't already rolling.

Now, here's the same function, as seen in Sonic & Knuckles:
SonicKnux_Roll:
    tst.b   status_secondary(a0)
    bmi.s   locret_1177E
    move.b  (Ctrl_1_logical).w,d0
    andi.b  #button_left_mask|button_right_mask,d0  ; is left/right being pressed?
    bne.s   locret_1177E                            ; if yes, branch
    btst    #button_down,(Ctrl_1_logical).w         ; is down being pressed?
    beq.s   Player_ChkWalk                          ; if not, branch
    move.w  ground_vel(a0),d0
    bpl.s   loc_1176A
    neg.w   d0

loc_1176A:
    cmpi.w  #$100,d0                                ; is Sonic moving at $100 speed or faster?
    bhs.s   Player_ChkRoll                          ; if so, branch
    btst    #Status_OnObj,status(a0)
    bne.s   locret_1177E
    move.b  #8,anim(a0)                             ; enter ducking animation

locret_1177E:
    rts
So, what's changed? Here's the breakdown:
  • First, all the button checks have been moved up to the start of the code. The player's speed is only checked when the player presses the down button without also pressing either the left or right buttons.
  • Next, if the player is traveling at a speed higher or equal to 1.0 pixels per frame, branch to Player_ChkRoll, which will put the player in their rolling pose if they weren't already rolling.
  • Finally, check whether the player is standing on an object. If they are, do nothing. Otherwise, put the player in their ducking pose.


And that's the slow duck: a convenience that allows the player to perform a spindash without first coming to a complete stop, which in turn allows Knuckles to spindash directly out of a glide.

Do you see why the slow duck isn't in Knuckles in Sonic 2? At some point during development of Sonic & Knuckles, the code for the Knuckles object was copied over and adapted for Knuckles in Sonic 2. Later, when slow duck got added to Sonic & Knuckles, the Sonic 2 copy didn't receive the update. Once again, Knuckles is a snapshot of days gone by.

Going through all the Sonic & Knuckles prototypes we currently have, we find that the slow duck is present in every last one, all the way back to the 0408 prototype, so the Knuckles object had already been replicated by then. Unfortunately, there's no way to know exactly when this particular feature got added to the game.


There's another quirk about the Knuckles object in Sonic 2 that we can accurately date, though. In Sonic & Knuckles, if the player stops moving while climbing a wall, Knuckles will reset to a specific frame of his climbing animation. In Sonic 2 however, he just remains in whatever frame was being displayed at the time.


Going through the currently available prototypes, we find the Sonic 2 behavior is present all the way up to and including the 0525 prototype, whereas the final Sonic & Knuckles behavior appears starting from the 0606 prototype. This means the feature was introduced at some point in the intervening two weeks.