Sonic the hedgehog 2

Sonic the hedgehog 2 & Knuckles

How to restore the lost sprites manually

Submitted by Sonic Hachelle-Bee on June 26 2005.

Here, I will explain how to restore the lost sprites from Sonic 2 Beta to Sonic 2 Final or Sonic 2 & Knuckles.
Instead of using the Esrael patch to restore them, I will explain how to make that manually with an hex editor.
We will restore the batbot, the dinobot, the trycerobot, the crocobot, and the snailbot.

The sprites pointers table

In both Sonic 2 Beta and Sonic 2 Final, you have a sprites pointers table where all pointers for the program of each sprite are stored in order by their sprite ID.

Sonic 2 Beta sprites pointers table: $D01A
Sonic 2 Final sprites pointers table: $1600C
Sonic 2 & Knuckles sprites pointers table: $3128FA
Usually, as Sonic 2 Beta, and as Esrael made it in its hacks, we assume that:

ID $4C is for the batbot.
ID $4D is for the trycerobot.
ID $4E is for the crocobot.
ID $4F is for the dinobot.
ID $62 is for the snailbot.

All these sprites ID are empty, and we will use them for our sprites.
For example, in Sonic 2 Final, the pointer that jumps to the batbot is at $16138 and it's currently 00 01 63 7C (empty).
The one for the trycerobot is next, and it's again 00 01 63 7C. You will have to change these pointers at the end once the program for each sprite is implemented.

Find the program of each sprite

You have to copy the program, for each sprite, from Sonic 2 Beta and paste it somewhere in Sonic 2 Final or Sonic 2 & Knuckles.
Here is the addresses where to copy these sprites from Sonic 2 Beta:

For the most lazy ones, I have done that boring part for you: click here for Sonic 2 or here for Sonic 2 & Knuckles

Batbot: $1EE68-$1F2EE
Trycerobot: $1D984-$1DC52
Crocobot: $1F2F0-$1F5E8
Dinobot: $1DEAC-$1E00E
Snailbot: $1F6E8-$1F99C and $1EAF2-$1EB8C -> Paste the second part (animated fire) after the first (main) part. The result is $34E in size.

Now, you can change your pointers in the sprites pointers table to jump at these sprites programs.

Fix the pointers

Now that you copied all programs for the lost sprites, for now, all pointers refers to routines from Sonic 2 Beta, and then the pointers are wrong. We have to fix some pointers in these programs so that the game uses the right routines from Sonic 2 Final. This is the most boring part! We will assume that for each sprite program, the first byte is at address $0.

For the most lazy ones, if you previously downloaded the archive, you only have to change addresses in blue color. The others are already fixed.
Thanks Sonic Hachelle-Bee! =P
Batbot:
$14 -> 21 7C 00 01 F1 06
Change the pointer to jump to $29E -> 00 1E 00 40 00 62

$1C -> 31 7C 25 30
VRAM address and pallet line to use.
In red, the pallet line to use for the sprite.
In green, the VRAM address. $530x$20=$A600.
Change it to $23B2 instead.

$64 -> 43 F9 00 01 F0 D2
Change the pointer to jump to $26A -> 00 08 00 0C 00 1B

$7C -> 4E B9 00 00 32 0A
Jump to subroutine. Change it to $000033B6 (S2) or $00302F10 (S2&K).

$D0 -> 43 F9 00 01 F0 D2
Same as before. Jump to $26A -> 00 08 00 0C 00 1B

$1C2 -> 4E B9 00 00 32 0A
Same as before.
Change it to $000033B6 (S2) or $00302F10 (S2&K).

$1EC -> 4E B9 00 00 31 E4
Jump to subroutine. Change it to $00003390 (S2) or $00302EEA (S2&K).

$474 -> 4E F9 00 00 D2 A0
Jump. Change it to $000163D2 (S2) or $00312CC0 (S2&K).

$47A -> 4E F9 00 00 D4 12
Jump. Change it to $00016544 (S2) or $00312DD0 (S2&K).

$480 -> 4E F9 00 00 D2 7A
Jump. Change it to $000163AC (S2) or $00312C9A (S2&K).

Trycerobot:
$12 -> 21 7C 00 01 DA EE
Change the pointer to jump to $16A -> 00 10 00 3A 00 64

$1A -> 31 7C 23 C4
VRAM address and pallet line to use.
In red, the pallet line to use for the sprite.
In green, the VRAM address. $3C4x$20=$7880.
Change this to $23A0 instead.

$48 -> 4E B9 00 01 38 98
Jump to subroutine. Change it to $0001EDFA (S2) or $00319102 (S2&K).

$70 -> 43 F9 00 01 DA D2
Change the pointer to jump to $14E -> 00 06 00 14 00 17

$AE -> 4E B9 00 01 38 98
Jump to subroutine. Change it to $0001EDFA (S2) or $00319102 (S2&K).

$2BC -> 4E F9 00 00 D2 A0
Jump. Change it to $000163D2 (S2) or $00312CC0 (S2&K).

$2C2 -> 4E F9 00 00 D4 12
Jump. Change it to $00016544 (S2) or $00312DD0 (S2&K).

$2C8 -> 4E F9 00 00 D2 4E
Jump. Change it to $00016380 (S2) or $00312C6E (S2&K).

Crocobot:
$12 -> 21 7C 00 01 F4 20
Change the pointer to jump to $130 -> 00 18 00 3A 00 5C

$1A -> 31 7C 23 00
VRAM address and pallet line to use.
In red, the pallet line to use for the sprite.
In green, the VRAM address. $300x$20=$6000.
Change this to $2500 instead.

$48 -> 4E B9 00 01 38 98
Jump to subroutine. Change it to $0001EDFA (S2) or $00319102 (S2&K).

$70 -> 43 F9 00 01 F4 06
Change the pointer to jump to $116 -> 00 06 00 0E 00 11

$AE -> 4E B9 00 01 38 98
Jump to subroutine. Change it to $0001EDFA (S2) or $00319102 (S2&K).

$2E0 -> 4E F9 00 00 D2 A0
Jump. Change it to $000163D2 (S2) or $00312CC0 (S2&K).

$2E6 -> 4E F9 00 00 D4 12
Jump. Change it to $00016544 (S2) or $00312DD0 (S2&K).

$2EC -> 4E F9 00 00 D2 4E
Jump. Change it to $00016380 (S2) or $00312C6E (S2&K).

$2F2 -> 4E F9 00 00 D2 7A
Jump. Change it to $000163AC (S2) or $00312C9A (S2&K).

Dinobot:
$14 -> 21 7C 00 01 DF CA
Change the pointer to jump to $11E -> 00 06 00 10 00 1A

$1C -> 31 7C 05 00
VRAM address and pallet line to use.
In red, the pallet line to use for the sprite.
In green, the VRAM address. $500x$20=$A000.
You don't need to change these values this time.

$4A -> 4E B9 00 01 38 98
Jump to subroutine. Change it to $0001EDFA (S2) or $00319102 (S2&K).

$78 -> 43 F9 00 01 DF BC
Change the pointer to jump to $110 -> 00 04 00 07 09 01

$DC -> 4E B9 00 01 38 98
Jump to subroutine. Change it to $0001EDFA (S2) or $00319102 (S2&K).

$144 -> 4E F9 00 00 D3 C2
Jump. Change it to $000164F4 (S2) or $00312D80 (S2&K).

$14A -> 4E F9 00 00 D3 B4
Jump. Change it to $000164E6 (S2) or $00312D72 (S2&K).

$150 -> 4E F9 00 00 D4 12
Jump. Change it to $00016544 (S2) or $00312DD0 (S2&K).

$156 -> 4E F9 00 00 D2 4E
Jump. Change it to $00016380 (S2) or $00312C6E (S2&K).

$15C -> 4E F9 00 00 D2 7A
Jump. Change it to $000163AC (S2) or $00312C9A (S2&K).

Snailbot:
This is the most difficult one. The snailbot contains 3 parts: the body, the shell and the animated fire.
The program for the animated fire is separate. Actually, it uses the one from the wasp sprite, but I adviced before to paste it right after the main program of the sprite. The result should be a program of $34E in size.

$18 -> 21 7C 00 01 F9 38
Change the pointer to jump to $250 -> 00 06 00 18 00 2A

$20 -> 31 7C 04 02
VRAM address and pallet line to use for the body.
In red, the pallet line to use for the sprite.
In green, the VRAM address.
Change this to $054E instead.

$54 -> 13 7C 00 54
This is the old sprite ID of Sonic 2 Beta. Change it to $62 now.

$60 -> 23 7C 00 01 F9 38
Change the pointer to jump to $250 -> 00 06 00 18 00 2A

$68 -> 33 7C 24 02
VRAM address and pallet line to use for the shell.
In red, the pallet line to use for the sprite.
In green, the VRAM address.
Change this to $254E instead.

$C0 -> 4E B9 00 01 38 98
Jump to subroutine. Change it to $0001EDFA (S2) or $00319102 (S2&K).

$D6 -> 43 F9 00 01 F9 2C
Change the pointer to jump to $244 -> 00 04 00 08 05 00

$F2 -> 43 F9 00 01 F9 2C
Change the pointer to jump to $244 -> 00 04 00 08 05 00

$14A -> 13 7C 00 54
This is the old sprite ID of Sonic 2 Beta. Change it to $62 now.

$156 -> 23 7C 00 01 EB 0E
Change the pointer to jump to $2D0 -> 00 0E 00 20 00 3A

$15E -> 33 7C 03 E6
VRAM address and pallet line to use for the animated fire.
In red, the pallet line to use for the sprite.
In green, the VRAM address.
Change this to $03D2 instead.
Beware, for some odd reasons, the fire might be buggy with some emulators with S2&K (like Gens).
If this is the case, change this value to $07A4 and this should work.

$1A6 -> 0C 11 00 54
This is the old sprite ID of Sonic 2 Beta. Change it to $62 now.


$1D6 -> 43 F9 00 01 EA F2
Change the pointer to jump to $2B4 -> 00 08 00 0B 00 0F

$220 -> 0C 11 00 54
This is the old sprite ID of Sonic 2 Beta. Change it to $62 now.

$284 -> 4E F9 00 00 D3 B4
Jump. Change it to $000164E6 (S2) or $00312D72 (S2&K).

$28A -> 4E F9 00 00 E7 88
Jump. Change it to $00017FFA (S2) or $00313D8E (S2&K).

$290 -> 4E F9 00 00 D4 12
Jump. Change it to $00016544 (S2) or $00312DD0 (S2&K).

$296 -> 4E F9 00 00 DC 4C
Jump. Change it to $00016D8A (S2) or $00216D8A (S2&K).

$29C -> 4E F9 00 00 D3 40
Jump. Change it to $00016472 (S2) or $00312D44 (S2&K).

$2A2 -> 4E F9 00 00 DC 30
Jump. Change it to $00016D6E (S2) or $00216D6E (S2&K).

$2A8 -> 4E F9 00 00 D2 4E
Jump. Change it to $00016380 (S2) or $00312C6E (S2&K).

$2AE -> 4E F9 00 00 D2 7A
Jump. Change it to $000163AC (S2) or $00312C9A (S2&K).

Sprites graphics and pattern load cue's

Now that we have the programs, we have to port the graphics for our sprites from Sonic 2 Beta:

For the most lazy ones, here is the archive that contains all graphics for each sprite in Nemesis format: click here

Batbot: $7A6A2
Trycerobot: $7AD18
Crocobot: $7A11A
Dinobot: $7B114
Snailbot: $7C514

Paste these graphics in Sonic 2 Final or in Sonic 2 & Knuckles.

Now, all you need is to add them in the pattern load cue's of your levels. You have already the objects art, and I will tell you their VRAM position they must be loaded at to display them correctly on screen:

Batbot: $7640
Trycerobot: $7400
Crocobot: $A000
Dinobot: $A000
Snailbot: $7A40 -> The wasp must be loaded just before it, for the animated fire.

Now, you can place your sprites in your levels using their specific ID.

That's all! Phew... ^_^

Back to: Sonic the hedgehog 2
Back to: Sonic the hedgehog 2 & Knuckles
Table of contents