Actions

SCHG

Difference between revisions of "SCHG:Sonic the Hedgehog 3 & Knuckles"

From Sonic Retro

(Fixed level layout info. Credit to Nemesis for most of the information)
(Fixed mistake)
Line 1,350: Line 1,350:
 
|-
 
|-
 
| $3C
 
| $3C
|Stick to convex surfaces flag (unused in Sonic 2 but fully functional).
+
|Stick to convex surfaces flag.
 
|-
 
|-
 
|$3D||Set if charging a spindash.
 
|$3D||Set if charging a spindash.

Revision as of 05:15, 16 February 2008

Sonicretro-round.svg This short article is in need of work. You can help Sonic Retro by adding to it.

Note: As S3&K is a "lock-on" game, all offsets below $200000 are in the base S&K ROM, and all offsets above $200000 are in the connected S3 ROM.

ROM Hacking

Art Editing

Uncompressed Art Locations

Nemesis Compressed Art Locations

Kosinski Compressed Art Locations

Palette Editing

Usually, it's not really necessary to edit a palette in hex. Palette editors give you instant feedback for each RGB value, and the palette can be easily saved as a separate binary and reimported into the ROM. However, it is sometimes desirable or necessary to do it in hex, and it can't hurt to know how it's done.

These are the ROM offsets of the palettes in Sonic 3 and Knuckles, as listed by HivePal:

Offset Name
291A Angel Island Act 1 Cycle #1
293A Angel Island Act 1 Cycle #2
29BA Angel Island Act 1 Cycle #3
2A1A Angel Island Act 1 Cycle #4
2A4A Angel Island Act 2 Cycle #1
2A6A Angel Island Act 2 Cycle #2
2A9A Angel Island Act 2 Cycle #3
2ACA Angel Island Act 2 Cycle #4
2B32 Hydrocity Act 1 Cycle
2B52 Carnival Night Cycle #1
2BB2 Carnival Night Cycle #2
2C32 Carnival Night Cycle #3
2C66 Carnival Night Cycle #4
2CA6 Carnival Night Cycle #5
2D06 Carnival Night Cycle #6
2D86 Carnival Night Cycle #7
2DFA Icecap Cycle #1
2E3A Icecap Cycle #2
2E82 Icecap Cycle #3
2E9A Icecap Cycle #4
2EDA Launch Base Act 1 Cycle
2EEC Launch Base Act 2 Cycle
2EFE Lost Level 09 Act 1 Cycle #1
2F7E Lost Level 09 Act 1 Cycle #2
2FA2 2P Level - Balloon Park Cycle #1
2FB4 2P Level - Balloon Park Cycle #2
3032 2P Level - Desert Palace Cycle
3082 2P Level - Endless Mine Cycle #1
30BE 2P Level - Endless Mine Cycle #2
31C2 Super Sonic
31FE Super Sonic Underwater
323A Super Sonic Underwater
3C78 Sega Logo #1
3CF8 Sega Logo #2
3D08 Intro Frame #1
3D48 Intro Frame #2
3D88 Intro Frame #3
3DC8 Intro Frame #4
3E08 Intro Frame #5
3E48 Intro Frame #6
3E88 Title Screen
3FD4 Title Screen Cycle
5092 2P Level - Knuckles
70BC Level Select Menu - EHZ Icon
70DC Level Select Menu - MZ Icon
70FC Level Select Menu - HTZ Icon
711C Level Select Menu - HPZ Icon
713C Level Select Menu - OOZ Icon
715C Level Select Menu - MCZ Icon
717C Level Select Menu - CNZ Icon
719C Level Select Menu - CPZ Icon
71BC Level Select Menu - ARZ Icon
71DC Level Select Menu - SCZ Icon
71FC Level Select Menu - WFZ Icon
721C Level Select Menu - DEZ Icon
723C Level Select Menu - Special Stage Icon
725C Level Select Menu - X Icon
727C Level Select Menu - Sound Test Icon
7A26 Special Stage - Sonic and Tails
7A66 Special Stages
7AA6 Special Stage 1
7ACC Special Stage 2
7AF2 Special Stage 3
7B18 Special Stage 4
7B3E Special Stage 5
7B64 Special Stage 6
7B8A Special Stage 7
7BB0 Special Stage 8
A55E 2P Menu - Sonic and Tails
A57E 2P Menu - Knuckles
A59E 2P Menu - Unselected Portraits
A5BE 2P Menu - ALZ Portrait
A5DE 2P Menu - BPZ Portrait
A5FE 2P Menu - CGZ Portrait
A61E 2P Menu - DPZ Portrait
A63E 2P Menu - EMZ Portrait
BBB6 Data Select - Sonic/Tails/Knuckles/Emeralds
BBF6 Data Select - Sonic Portrait
BC16 Data Select - Super Sonic Portrait
BC36 Data Select - AIZ Portrait
BC56 Data Select - HCZ Portrait
BC76 Data Select - MGZ Portrait
BC96 Data Select - CNZ Portrait
BCB6 Data Select - FBZ Portrait (Unused)
BCD6 Data Select - ICZ Portrait
BCF6 Data Select - LBZ Portrait
236AC Red Balls Debug Mode Item
2D3BE Special Stage Results
4160A Ending - Credits
4168A Ending - Knuckles and Eggman
457AE Knuckles
457CE ###
4580E Carnival Night Lights Off
45E86 Angel Island Act 1 Intro - Emeralds
47092 Angel Island Act 1 Boss
47CD6 Angel Island Act 2 Boss
48C9A Hydrocity Act 1 Boss
49D52 Hydrocity Act 2 Boss
4B588 Marble Garden Act 2 Boss
4BF70 Carnival Night Act 1 Boss
4C91E Carnival Night Act 2 Boss
4D520 Flying Battery Act 1 Boss
4DB80 Flying Battery Act 2 Boss
4EBC2 Icecap Act 2 Boss
4F444 Icecap Act 1 Boss
4F98C Launch Base Act 1 Boss
503EE Launch Base Act 2 Triplet Boss
50C8A Launch Base Act 2 Cannonball Boss
520DC Launch Base Act 2 Final Boss
5211C Ending - Sonic
5213C Ending - Tails
5215C Ending - Super Sonic
8C234 Sonic and Tails
8C274 Level Select Menu
8C314 Angel Island Act 1
8C374 Angel Island Act 1 Intro
8C3D4 Angel Island Act 2
8C494 Angel Island Act 1 Underwater
8C434 Angel Island Act 2 FBZ Sequence
8C514 Angel Island Act 2 Underwater
8C594 Hydrocity Act 1
8C654 Hydrocity Act 1 Underwater
8C5F4 Hydrocity Act 2
8C6D4 Hydrocity Act 2 Underwater
8C754 Marble Garden
8C7B4 Carnival Night
8C814 Carnival Night Underwater
8C894 Icecap Act 1
8C8F4 Icecap Act 2
8C954 Icecap Act 2 Underwater
8C9D4 Launch Base Act 1
8CA34 Launch Base Act 2
8CA94 Launch Base Act Underwater
8CB74 2P Level - Azure Lake
8CBD4 2P Level - Balloon Park
8CC94 2P Level - Chrome Gadget
8CC34 2P Level - Desert Palace
8CCF4 2P Level - Endless Mine
8CD54 Bonus Stage
A943C Mushroom Hill Act 1
A949C Mushroom Hill Act 2
A909C Flying Battery Act 1
A90FC Flying Battery Act 2
A94FC Sandopolis Act 1
A955C Sandopolis Act 2
A967C Lava Reef Act 1
A96DC Lava Reef Act 2
A9CDC Lava Reef Act 2 Boss
A9D3C Hidden Palace
A973C Sky Sanctuary Act 1
A979C Sky Sanctuary Act 2
A98BC Death Egg Act 1
A991C Death Egg Act 2
A9D9C Death Egg Act 2 Boss
A997C The Doomsday
164896 Marble Garden Act 2 - Day to Night #1
164916 Marble Garden Act 2 - Day to Night #2
164996 Marble Garden Act 2 - Day to Night #3
164A16 Marble Garden Act 2 - Day to Night #4
19D262 Data Select - Background
19D282 2P Menu - Background

For information about the palette format, see Megadrive palette.

Pattern Load Cues

Object Editing

Object Pointer List

Sprite Mappings

Object Placement

There are six bites in one object definition. The first two bytes are the X position of the object, and the next two bytes are the Y position. The 5th byte is the reference number on the object pointer list (see above), and the 6th byte is an optional declaration to use for defining that object's behavior and/or animation. This will depend on the object. See the level specific hacking info for the locations of the object lists.

The 6th byte, the object subtype, is loaded in the byte $2C of the SST of that object (see below).

Ring Placement

There are four bytes for every ring object. The first 2 bytes are X coordinates, and the next two are the Y coordinates. Sonic 3k uses individual rings, unlike Sonic 2, which uses ring groups that have to be expanded into RAM. The advantage of Sonic 3k's method is that ring position data can be read directly from ROM, meaning that only two bytes are used up in RAM per ring instead of six, saving on RAM space and allowing Sonic 3k levels to have a maximum of 511 rings, as compared to Sonic 2's 255, despite allocating $200 bytes less to the ring status table.

The ring placement data must start with 0000 0000, and must end with FFFF. These prevent the rings position checker subroutine from going over the bounds of the ring placement data, and are necessary for the correct functioning of the rings manager.

Level Layout

Level layouts are stored uncompressed in the ROM, and the format they use differs significantly from the format used in Sonic 2, allowing much larger levels.

The layout starts with an 8 byte header describing the layout. The first word of this header is the number of 128x128 tiles that make one foreground row, and the second word is the number of 128x128 tiles that make one background row. The third word is the number of foreground rows, and the fourth is the number of background rows.

Next is a list of 64 word-sized pointers in RAM. Each row of 128x128 tiles has two pointers - one for the foreground data and one for the background data. The maximum level height is thus (64 / 2 * 128) = $1000 pixels, double the maximum level height for Sonic 2.

The actual rows data (beginning at byte $88) is very simple - there is one byte per 128x128 tile, and the blocks are put together from left to right.

See the level specific hacking info for the locations of level layout data. (Put here for now, will eventually be moved to subpage)

Offset Level Name
2814A8 Angel Island 1
281CF4 Angel Island 2
282A5A Hydrocity 1
283582 Hydrocity 2
28442A Marble Garden 1
2850BA Marble Garden 2
285E6A Carnival Night 1
286A34 Carnival Night 2
2879C2 Icecap 1
28898A Icecap 2
2897DA Launch Base 1
28A786 Launch Base 2
09F43E Mushroom Hill 1
0A0172 Mushroom Hill 2
09D708 Flying Battery 1
09D708 Flying Battery 2
0A0DE2 Sandopolis 1
0A1C4E Sandopolis 2
0A2A66 Lava Reef 1
0A388E Lava Reef 2
0A76F4 Lava Reef 2 (Robotnik)
0A79AC Hidden Palace
0A4616 Sky Sanctuary 1
0A5286 Sky Sanctuary 2
0A5402 Death Egg 1
0A63D0 Death Egg 2
0A7FD4 Death Egg 2 (Robotnik)
0A725E Doomsday

16x16 Block Mappings

Text Editing

RAM Hacking

Main System Memory Locations

This is a map of 68k memory as used by the main gameplay engine. Note that any numbers entered (for example, score or number of rings) will have to be converted to hex first.

These are the offsets in RAM. To convert them to Genecyst savestate offsets, add $2478.

RAM offset Description
$0000-$7FFF 128x128 mappings
$8000-$8FFF Level layout
$9000-$A9FF 16x16 mappings
$AA00-$AFFF Pattern decompression buffer
$AA00-$AFFF Pattern decompression buffer
$B000-$CFCB Object attribute table
$D000-???? Kosinski decompression buffer
$E380 Number of objects currently in collision response list, multiplied by 2.
$E382-$E3FF Collision response list. The format is one word per object, where the word is the starting address of the object's SST. Only objects in this list are processed by the collision response routine.
$E700-$EAFF Ring status table. The format is two bytes per ring, these bytes being 0000 while the ring has yet to be consumed, serving as a ring destruction timer while the ring is being consumed, and being set to FFFF when the ring has been fully consumed.
$EE12 Screen Y end
$EE14 Screen X start
$EE16 Screen X end
$EE18 Screen Y start
$EE1A Screen Y end location for Sonic; the maximum value for camera Y position. Like $EE12, but changes slowly instead of instantly when the level Y boundary changes.
$EE33 Routine counter for Dynamic Screen Resizing. (Dynamic Level Events)
$EE42-$EE45 Address (in the ROM) of the first ring whose X position is greater than or equal to the current camera X value minus 8.
$EE46-$EE49 Address (in the ROM) of the first ring whose X position is greater than or equal to the current camera X value + $148.
$EE4A-$EE4B Address (in the ring status table) of the first ring whose X position is greater than or equal to the current camera X value minus 8.
$EE60 Camera X for the second player in 2p mode
$EE64 Camera Y for the second player in 2p mode
$EE68 Copy of camera X for the second player in 2p mode for rasters
$EE6C Copy of camera Y for the second player in 2p mode for rasters
$EE78 Camera X
$EE7C Camera Y
$EE80 Copy of Camera X for Rasters
$EE84 Copy of Camera Y for Rasters
$EEC6 Level property (like killer wall in HCZ2 or avalanche in ICZ1)
$EF49 Flag which determines whether the second player in a 2P versus game is player-controlled or just a "ghost" of the first player.
$EF80 The number of rings inside the ring consumption table.
$EF82-$EFFF Ring consumption table. Contains the RAM addresses (inside the ring status table) of rings which are currently being consumed. Once consumed, the rings are deleted from this table.
$F000-$F07F Second underwater palette.
$F080-$F0FF Underwater palette.
$F600 Master level trigger. Tells the game what it should be doing.

The MSB is a loading routine flag. It only matters for some game modes. It won't have any effect when changing modes because it's filtered out, but the corresponding routine does pay attention to it...

$F602 In-game Controller 1 held state. Same as F604, but it only updates during the main game loop, and not while paused, or a custcene is running.
$F603 In-game Controller 1 pressed state. Same as F602, but only tells which buttons are being pressed newly this frame.
$F604 This bitfield tells which button(s) on Controller 1, if any, are currently pressed. Format is:
  • Bit 0 - Up
  • Bit 1 - Down
  • Bit 2 - Left
  • Bit 3 - Right
  • Bit 4 - B
  • Bit 5 - C
  • Bit 6 - A
  • Bit 7 - Start

This is updated every frame.

$F605 Same as $F604, but only tells which buttons are being pressed newly this frame.
$F606 Same as $F604, but for Controller 2.
$F607 Same as $F606, but only tells which buttons are being pressed newly this frame for Controller 2.
$F614 Demo time left & Time until demo starts from title screen.
$F636 RNG seed (used for pseudo-random number generation).
$F63A-$F63B Game paused flag.
$F648-$F649 Current water level. Should be a valid Y-axis value. Remember, the top of the level is $0000.
$F64C Water on: seems to be a copy of $F730.
$F65E Super Sonic palette counter. Decremented with every frame. How it works, exactly, is not known.
$F65F Sets the rotating palette for Super Sonic.
$F66A In-game Controller 2 held state. Same as $F602, but for controller 2
$F66B In-game Controller 2 pressed state. Same as $F66A, but only tells which buttons are being pressed newly this frame.
$F670-$F671 Super Sonic ring drain counter. This is updated each frame, so the counter is set to 60 ($3C) on consoles operating in 60Hz mode, or 50 ($32) in consoles operating in 50Hz mode. After each frame, the code subtracts 1. One ring is removed when this counter reaches zero; in other words, each second.
$F680 A buffer for pattern loading cues (requests).
$F700-$F701 Seems to be set to $0001 when in a Sonic & Tails game. Set to $0000 when not a Sonic & Tails game.
$F702-$F703 Tails control counter. Counts how long until the CPU takes control.
$F704-$F705 Tails repawn counter.
$F708-$F709 Tails CPU routine.
$F70A-$F70B Tails CPU target X position. Tells Tails where Sonic's X position is so he can fly back to him.
$F70C-$F70D Tails CPU target Y position. Tells Tails where Sonic's Y position is so he can fly back to him.
$F70E-$F70F Tails interact ID. Object ID of last object Tails stood on.
$F710 Routine counter for the rings manager.
$F711 Level started flag. Set to 1 as soon as the player first gets control in the level.
$F730 Water flag. Must be set for any of the other water variables to have any effect. Note that levels without water don't have an underwater palette; you must set one or everything below the water level will be black.
$F760-$F761 Sonic's top speed
$F762-$F763 Sonic's acceleration
$F764-$F765 Sonic's deceleration
$F766 Sonic's current mapping frame number.
$F7AA Seems to be clear during normal play, but set to some value during a boss fight. That value may be the current Zone number.
$F7C6 Reverse gravity flag. Only in Sonic & Knuckles.
$F7CA Controller lock for controller 1.
$F7CB Controller lock for controller 2.
$F7D0-$F7D1 Bonus counter. Increments upon destruction of a destroyable object, and is used to determine how many points the destruction should give. Resets when the player touches the ground.
$F7D2-$F7D3 Time bonus counter at the end of level result screen
$F7D4-$F7D5 Ring bonus counter at the end of level result screen
$F7DA-$F7DB Counts the number of times the camera has scrolled to the right by one full screen width from its previous position - initial value is $FF80 and then counts up like: $FF80,$0000,$0080,$0100,$0180,etc.
$FC00 - $FC7F Normal palette.
$FC80-$FCFF Second palette.
$FE00 Start of the system stack. Note that the stack grows up rather than down. This means that when something is pushed onto the stack, the SP is decremented, and when something is popped from it, the SP is incremented.
$FE02-$FE03 Level restart flag.
$FE06 Object currently selected in debug mode.
$FE09 Object placement mode flag.
$FE10 The current Zone. This is the value assigned to the Zone, not its position in the level list.
$FE11 Act number
$FE12 Life Count
$FE18 Number of continues.
$FE19 Super Sonic flag. Setting this will load the Super Sonic tiles, adjust Sonic's jump height, and start draining rings, but it will not load the rotating palette, change acceleration, max speed, or deceleration, or make him invincible.
$FE1A Flag which is set when the player has a time over.
$FE1B This bitfield tells the game if the player has collected extra lives from rings. Seems to work differently in S3k than in S2.
$FE1C Flag determines if the lives counter needs to be updated
$FE1D Flag determines if the rings counter needs to be updated
$FE1E Flag determines if the timer needs to be updated
$FE1F Flag determines if the score counter needs to be updated
$FE20-$FE21 Ring count
$FE23 Minutes on clock. Should not go above $09, or the clock will look like shit.
$FE24 Seconds. This one shouldn't go above $3B, for the same reason.
$FE25 Centiseconds. I don't know what'll happen if this goes out of range, but it's probably not good.
$FE26-$FE29 Score (divided by 10)
$FE2A Greatest reference number of passed star poles
$FE2B Starpole ID of the last starpole hit
$FE2C Zone in which the last starpole was hit
$FE2D Act in which the last starpole was hit
$FE2E-$FE2F X position of the last starpole hit
$FE30-$FE31 Y position of the last starpole hit
$FE32-$FE33 The number of the rings the player had when the last starpole was hit
$FE34-$FE37 Copy of the entire clock data when the last starpole was hit
$FE35 Minutes on the clock when the last starpole was hit
$FE36 Seconds on the clock when the last starpole was hit
$FE37 Centiseconds on the clock when the last starpole was hit
$FE38-$FE39 Starting art block of the main character when the last starpole was hit
$FE3A-$FE3B Main character's collision layers data when the last starpole was hit
$FE3C-$FE3D Camera's X position when the last starpole was hit
$FE3E-$FE3F Camera's Y position when the last starpole was hit
$FE40-$FE41 Water level when the last starpole was hit
$FE42 The state of the water movement flag when the last starpole was hit
$FE43 The state of the extra lives from rings bitfield when the last starpole was hit
$FE44-$FE45 Camera's current maximum Y position when the last starpole was hit
$FE46 DSR/DLE routine when the last starpole was hit
$FE48 Flag which is set upon special stage entry and cleared when the data saved on special stage entry is restored
$FE49 Starpole ID of the last starpole hit before the last special stage entry
$FE4A Zone from which the last special stage was entered
$FE4B Act from which the last special stage was entered
$FE50-$FE51 The number of rings the player had when the last special stage was entered
$FE52-$FE55 Copy of the entire clock data when the last special stage was entered
$FE53 Minutes on the clock when the last special stage was entered
$FE54 Seconds on the clock when the last special stage was entered
$FE55 Centiseconds on the clock when the last special stage was entered
$FE56-$FE57 Starting art block of the main character when the last special stage was entered
$FE58-$FE59 Main character's collision layers data when the last special stage was entered
$FE5A-$FE5B Camera's X position when the last special stage was entered
$FE5C-$FE5D Camera's Y position when the last special stage was entered
$FE5E-$FE5F Water level when the last special stage was entered
$FE60 The state of the water movement flag when the last special stage was entered
$FE61 The state of the extra lives from rings bitfield when the last special stage was entered
$FE62-$FE63 Camera's current maximum Y position when the last special stage was entered
$FE64 DSR/DLE routine when the last special stage was entered
$FE6E-$FEAF Oscillating numbers data
$FEB2 Rings animation counter.
$FEB3 Rings animation frame.
$FEB6 Spilling rings animation counter.
$FEB7 Spilling rings animation frame.
$FEC0-$FEC1 Tails's max speed
$FEC2-$FEC3 Tails's acceleration
$FEC4-$FEC5 Tails's deceleration
$FEC6 Tails's lives in 2P mode. Unused in S3K, but its there.
$FEC7 This bitfield tells the game if the player has collected extra lives from rings. Used for Tails in 2P mode. Unused in S3K, but its there.
$FEC8-$FEC9 Rings collected since level load. Resets if you enter Special/Bonus stage. Starts recounting from 0 when level is reentered. Unknown use.
$FF04-$FF05 Perfect counter (leftover from S2). No perfect bonus is given for collecting all the rings, making this variable virtually useless.
$FF08-$FF09 Current character (00 - sonic & tails, 01 - sonic, 02 - tails, 03 - knuckles)
$FF0A-$FF0B Character selected in level select (00 - sonic & tails, 01 - sonic, 02 - tails, 03 - knuckles)
$FF0E Number of kosinski compressed data pieces waiting on the KosToRam queue to be decompressed to RAM
$FF40-$FF5F? The KosArt queue, which is a set of arrays of 2 longwords
  • $00 - the source Kosinski data location
  • $04 - the destination RAM address
$FF60 Number of kosinski art pieces waiting on the queue to be decompressed and DMAed to VRAM (number of modules of the compressed Kosinski art btw)

Bit 7 set to 1 indicates that the art has been already decompressed to the Kosinski art buffer ($D000)

$FF64 Art location of the moduled kosinski data.
$FF96 State of the main character's secondary status bitfield when the last special stage was entered, used to restore any shield the character had when he entered the special stage and cleared once the shield is restored
$FFB0 Number of chaos emeralds
$FFB1 Number of super emeralds
$FFB2-$FFB8 Array of finished special stages. Each byte represents one stage:
  • 0 - special stage not completed
  • 1 - chaos emerald collected
  • 2 - super emerald present but grayed
  • 3 - super emerald present and activated
$FFD2-$FFD3 Demo number
$FFDA Debug mode flag
$FFE8 2P versus mode flag
$FFEA 2p mode player 1's character
$FFEB 2p mode player 2's character

Object Status Table

The starting offset in RAM for this list is $B000. The first object is always player 1; the second is always player 2. Each object is alloted a block of $4A bytes. Note that many of these variables are object-specific - for example, some of them only make sense for Sonic, and some only work on badniks.

Offset Description
$00-$03 Pointer to object code. Note that this pointer does not necessarily remain constant for a single object.
$04 Action flags. The bitfield looks like this:
  • Bit 0 is the horizontal mirror flag. If set, the object will be flipped on its horizontal axis.
  • Bit 1 is the vertical mirror flag.
  • Bit 2 is the coordinate system flag. If clear, the object will be positioned by absolute screen coordinates. This is used for things like the HUD and menu options. If set, the object will be positioned by the playfield coordinates, i.e. where it is in a level. Sonic, Tails and Knuckles use both positioning systems (though I don't know how Tails uses it in a Sonic and Tails game).
  • Bits 3, 4, 5 and 6 are either unused, or their purpose is unknown.
  • Bit 7 is the draw object flag. It will be set if the object was onscreen when it came time to draw things. Otherwise, it is clear. There should be no reason to edit this flag, but it's good to know what it does.
$05 Routine number. This is always an even value (i.e. it goes in units of 2)
$06 Unknown.
$07 Width of the object, in pixels.
$08-$09 Sprite priority, in units of $80 (00 = front).
$0A-$0B Starting art block. This is an index into an array of cells; to get the actual address, multiply by $20.
$0C-$0F Object's mappings offset.
$10-$11 If the object is Sonic, Tails or Knuckles, this is the X playfield coordinate. Otherwise:
  • If in playfield positioning mode, it is the X playfield coordinate.
  • If in screen postioning mode, it is the X screen coordinate.
$12-$13 If the object is Sonic, Tails or Knuckles, this is the X subpixel playfield coordinate. Otherwise:
  • If in playfield positioning mode, it is unused.
  • If in screen positioning mode, it's the Y screen coordinate.
$14-$15 If the object is Sonic, Tails or Knuckles, this is the Y playfield coordinate. Otherwise:
  • If in playfield positioning mode, it is the Y playfield coordinate.
  • If in screen positioning mode, it is unused.
$16-$17 If the object is Sonic, Tails or Knuckles, this is the Y subpixel playfield coordinate. Otherwise:
  • It's unused.
$18-$19 X speed.
$1A-$1B Y speed.
$1C-$1D Potential speed (inertia).
$1E Height/2
$1F Width/2
$20 Animation number.
$21 Restart animation flag (when $21 is not equal to $20, animation restarts)
$22 Current animation frame to display.
$23 Current frame in animation script.
$24 Animation frame duration (time until next frame).
$25 Animation counter.
$26 Angle.
$27 Second angle (different axis).
$28 Collision response bitfield. Tells what the object will do if hit by the character. The bitfield is in the format TTSS SSSS. TT is the type of collision - 00 is enemy, 01 increments the routine counter, 10 is harm, and 11 seems to be a special thing for the starpole. SSSSSS is the size, lifted from a lookup table in the collision response routine.
$29 Custom collision property, for special interaction with Sonic. This is used by bosses, badniks, bumpers and other objects. The way in which this byte is used is different for each object. Bosses use this byte as a hit counter.
$2A Status bitfield.

Counting from the least significant bit:

Bit Hex Description
0 $01 X Orientation. Clear is left and set is right.
1 $02 Y Orientation. Clear is right-side up, and set is upside-down
2 $04 Unknown or unused.
3 $08 Set if Sonic is standing on this object.
4 $10 Set if Tails is standing on this object.
5 $20 Set if Sonic is pushing on this object.
6 $40 Set if Tails is pushing on this object.
7 $80 Unknown or unused.
Note that these bits have different meanings for Sonic (see below).
$2B Object shield reaction bitfield.
Bit Hex Description
3 $08 Bounces off shield.
4 $10 Negated by fire shield.
5 $20 Negated by lightning shield.
6 $40 Negated by bubble shield.
$2C Object subtype. For example, the current monitor selected. Has a different meaning for Sonic, Tails and Knuckles.
$42-$43 Parent. Address of the object that spawned this one. Has a different meaning for orphans like Sonic, Tails and Knuckles.
Variables specific to Sonic, Tails and/or Knuckles
Offset Description
$25
  • If Sonic, it's unused.
  • If Tails, it's the number of flying frames remaining / 2.
  • If Knuckles, it's something gliding related.
$2A Status bitfield. Counting from the least significant bit:
Bit Hex Description
0 $01 Orientation. Clear is right and set is left.
1 $02 Set if in the air (jump counts).
2 $04 Set if jumping or rolling.
3 $08 Set if the character isn't on the ground but shouldn't fall. (Usually when he is on a object that should stop him falling, like a platform or a bridge)
4 $10 Set if jumping after rolling.
5 $20 Set if pushing something.
6 $40 Set if underwater.
7 $80 Unused.

You can add the hex values together to use multiple settings at once. Also notice that bits 1 and 2 are used in the character object as a second routine counter.

$2B Secondary status bitfield.
Bit Hex Description
0 $01 Shield flag. Can be set to create the effect of having a shield, though the graphics will not be loaded.
1 $02 Sets invincibility. Behaves like you would expect. No graphics are loaded when set manually.
2 $04 Speed Shoes flag. (Doesn't have visible effect in game)
3 $08 Unused.
4 $10 Fire shield flag.
5 $20 Lightning shield flag.
6 $40 Bubble shield flag.
7 $80 Sets infinite inertia. While the character is in collision with the ground, he will continue moving in the same direction and at the same speed that he was moving before (even if that speed was zero). You can still jump and control him in midair. (A few movement routines are skipped if it's set, which produces this effect).
$2C Seconds of air left. Usually $1E; it decrements every second while the player is underwater. Beeps on $18, $13, and $0E. Countdown starts on $0B.
$2D Invert flipping flag.
$2E Object control flag. If bit 7 is not set, the character is under control of another object but can jump out (e.g. being carried by Tails), and if it is, the character is under control of another object and cannot jump out (e.g. LBZ tubes).
$2F Double jump flag. For Sonic:
  • 0 - on ground.
  • 1 - performing an instashield, fire dash, bubble bounce or lightning jump, or has performed the latter three.
  • 2 - has performed an instashield.

For Tails:

  • 0 - on ground.
  • 1 - gravity-affected flying.
  • Above 1 - gravity-less flying.

For Knuckles:

  • 0 - on ground.
  • 1 - gliding.
  • 2 - falling after a glide.
  • 3 - sliding across ground.
  • 4 - wall-climbing.
  • 5 - climbing over a wall and onto the ground.
$30 Number of flip revolutions remaining.
$31 Number of flip revolutions per frame divided by 256.
$32-$33 Horizontal control lock. Counts down to 0, left and right control on the ground is locked unless it's 0. Used for springs and bumpers and falling down slopes.
$34 Remaining invunerability time. Starts at $78 after Sonic is hit, and seems to decrement every frame until it reaches $00.
$35 Remaining time of invincibility. Decremented once every eight frames.
$36 Remaining time of Speed Shoes. Decremented once every eight frames.
$38 Character ID:
  • 0 - Sonic
  • 1 - Tails
  • 2 - Knuckles
$3A Angle on ground in front of sprite.
$3B Angle on ground under sprite.
$3C Stick to convex surfaces flag.
$3D Set if charging a spindash.
$3E-$3F Spindash counter. Cleared when the spindash is started. After each subsequent "rev", $200 is added to the counter, which then rapidly decreases (the algorithm is to logically shift the value right by five bits and subtract the results from the

original). It maxes out at $800. The game looks at the high-order byte to determine how fast the character should move after the dash is released.

$40 Set if jumping.
$42-43 RAM address of the last object Sonic stood on.
$44 Default height.
$45 Default width.
$46 Current collision plane/layer, seems to always be $C or $E.
$47 Unknown, seems to always be objstatus($46)+1, affects collision.
Variables specific to dynamically reloaded sprites, excluding Sonic, Tails and Knuckles
$34 Previous frame.
$38-$3B Pointer to uncompressed art.
$3C-3F Pointer to dPLCs.
$40-$41 Address of art in VRAM (the same as starting art block * $20)
Sonic Community Hacking Guide
General
SonED2 Manual | Subroutine Equivalency List
Game-Specific
Sonic the Hedgehog (16-bit) | Sonic the Hedgehog (8-bit) | Sonic CD (prototype 510) | Sonic CD | Sonic CD (PC) | Sonic CD (2011) | Sonic 2 (Simon Wai prototype) | Sonic 2 (16-bit) | Sonic 2 (Master System) | Sonic 3 | Sonic 3 & Knuckles | Chaotix | Sonic Jam | Sonic Jam 6 | Sonic Adventure | Sonic Adventure DX: Director's Cut | Sonic Adventure DX: PC | Sonic Adventure (2010) | Sonic Adventure 2 | Sonic Adventure 2: Battle | Sonic Adventure 2 (PC) | Sonic Heroes | Sonic Riders | Sonic the Hedgehog (2006) | Sonic & Sega All-Stars Racing | Sonic Unleashed (Xbox 360/PS3) | Sonic Colours | Sonic Generations | Sonic Forces
Technical information
Sonic Eraser | Sonic 2 (Nick Arcade prototype) | Sonic CD (prototype; 1992-12-04) | Dr. Robotnik's Mean Bean Machine | Sonic Triple Trouble | Tails Adventures | Sonic Crackers | Sonic 3D: Flickies' Island | Sonic & Knuckles Collection | Sonic R | Sonic Shuffle | Sonic Advance | Sonic Advance 3 | Sonic Battle | Shadow the Hedgehog | Sonic Rush | Sonic Classic Collection | Sonic Free Riders | Sonic Lost World
Legacy Guides
The Nemesis Hacking Guides The Esrael Hacking Guides
ROM: Sonic 1 | Sonic 2 | Sonic 2 Beta | Sonic 3

Savestate: Sonic 1 | Sonic 2 Beta/Final | Sonic 3

Sonic 1 (English / Portuguese) | Sonic 2 Beta (English / Portuguese) | Sonic 2 and Knuckles (English / Portuguese)
Move to Sega Retro
Number Systems (or scrap) | Assembly Hacking Guide | 68000 Instruction Set | 68000 ASM-to-Hex Code Reference | SMPS Music Hacking Guide | Mega Drive technical information