Fixing Startup Crash

Sonic R's startup code attempts to divide a value by the time elapsed for a given function. On reasonably fast computers (basically anything with a CPU newer than Pentium 4), this results in a division by zero. This can be fixed with a simple binary edit.

Toggles rubber band AI (although it seems largely ignored if difficulty is not on hard.) 0 is off. 1 is on.

0x8FD454

Dword

Guide On/Off

Toggles the trail of sparkles in time attack mode showing you where to go. 0 is off, 1 is on.

0x8FD458

Dword

Minimap On/Off

Toggles the minimap in the corner. 0 is off, 1 is on.

0x8FD45C

Dword

2P Split Option

Changes which way the subscreens in 2 player mode are oriented. 0 is Horizontal, 1 is Vertical.

0x8FD468

Dword

Screen Y Resolution Option

The number shown on the resolution option. Does not actually modify the resolution.

0x8FD46A

Dword

Screen X Resolution Option

0x8FD46C

Dword

Color Depth

Number of bits of color information. Can be 8 or 16. Only option in D3D mode is 16.

0x8FD470

Dword

Alpha Blending On/Off

0x8FD474

Dword

Unused Option

Probably unused, but it is saved/loaded like all the other options.

0x8FD478

Dword

Interlace On/Off

Ddraw mode only. Toggles whether or not to skip every other line. 0 is off, 1 is on.

0x8FD480

Dword

Draw Distance

Option for the draw distance. In D3D mode this can go up to the max value, but doing go in Ddraw mode will make frames take years to render.

0x8FD484

Dword

Window

Size of the screen. 4 is full resolution, 0 is smallest size.

0x8FD488

Dword

Track Shading On/Off

Ddraw mode only. Toggles whether or not to tint the track.

0x8FD490

Dword

Unknown Option

No idea what this does, but it seems to be referred to by everything.

0x8FD494

Dword

Stereo On/Off

Toggles stereo sound. Considering all the sound effects are mono, this might be an attempt at 3D sound.

0x8FD498

Dword

Vocals On/Off

Toggles vocals in the soundtrack. This is done by adding 6 to the current sound if it's a song.

0x8FD49C

Dword

SFX Volume

Volume of the sound effects. Range 0-8, 0 being off (or really quiet, not sure) and 8 being maximum.

0x8FD4A0

Dword

Music On/Off

Toggles CD audio in the game.

0x901C10

Dword

Pause Screen Selection

Selection on the Pause menu.

0 - Continue

1 - Retry

2 - Retire

0x901C30

Byte

Game Paused

Whether or not the game is paused. When the game is pause the only thing that happens is that it renders things and checks for input, so it's really useful for debugging.

0x901C44

Dword

Screen Transition Coverage (Maxes out before -255)

How much of the screen the wobbly inverted oval thing covers. In the negative, for some reason.

0x901C48

Dword

Screen Transition State

State of the screen transitions.

0 - not transitioning

1 - fading out

2 - fading in

0x901C70

Dword

No. Characters Tagged/Tokens

Range 0-5.

0x901C78

Dword

Emerald Collected

Number of the last emerald collected by P1.

0x901C84

Dword

Victory screen timer

Time remaining until the victory screen fades out and kicks you to results. Range 1-infinity, 0 being regular gameplay.

0x901CC4

Dword

Time Until Race Start

Time remaining until the game starts. Also controls "READY" "SET" "GO" indicators, etc. Counts down.

0x901CC8

Dword

GO! image size

Size of the "GO" image before the race starts. Setting this too high makes it upside down and small, for some reason.

0x9020D8

Binary(3)

LBrake Pushed

Toggles for which keys are pushed or unpushed.

0x9020D8

Binary(6)

Camera Pushed

0x9020D8

Binary(7)

RBrake Pushed

0x9020D9

Binary(0)

Spindash Pushed

0x9020D9

Binary(1)

Unknown Pushed

0x9020D9

Binary(2)

Jump Pushed

0x9020D9

Binary(3)

Start Pushed

0x9020D9

Binary(4)

Forward Pushed

0x9020D9

Binary(5)

Down Pushed

0x9020D9

Binary(6)

Left Pushed

0x9020D9

Binary(7)

Right Pushed

0x902140

Dword

Camera X Position

X-position of camera.

0x902144

Dword

Camera Elevation

Elevation of camera from water level. Negative values not allowed.

0x902148

Dword

Camera Z Position

Z position of camera

0x90214E

Dword

Camera X-Z Rotation

X-Z Rotation of camera from 0-4096.

0x902152

Word

Camera Tilt

Tilt of camera relative to the player. 0 is forward, - is down. + is up.

0x92528C

Dword

Options Screen Selection

Selection on the Options screen and usually anything else vertical.

0x925298

Dword

Sonic Icon Sprite Sheet Position (Super Sonic Selector)

On Character Select Screen, setting this from 0 is 40 changes the Sonic icon to Super Sonic, but not the actual selected character. Setting to 80 changes the icon to Tails, 120 to Knuckles, 160 to Amy, and 200 to a blank. Cannot change value with arrow keys unless the values are set to exactly 0 (Sonic) or 40 (Super Sonic) though.

0x9252B4

Dword

Main Menu Option

Selection for the Menu screen and usually anything else horizontal.

0x9252B8

Dword

Horis-Menu Screenpos Loc

Current location on screen of the selector on the menu. Range 0 to 320.

0x9252BC

Dword

Horis-Menu Screenpos Dest

Where the selector plans on going.

0x9252C0

Dword

Horis-Menu Screenpos ?

Doesn't seem to effect anything...

0x9252DC

Dword

1P Controller Type

Type of controller used in multiplayer. Format is 0x000A000B, where A is 0 for keyboard and 1 for joystick and B is the port number of joystick or key binding for keyboard.

0x9252E0

Dword

2P Controller Type

0x9252E4

Dword

3P Controller Type

0x9252E8

Dword

4P Controller Type

0x94BCF4

Dword

Weather

Current weather, regardless of option. Ignored in Time Attack mode for some reason.

0 - clear

1 - rain

2 - snow

3+ - clear

0x94BCF8

Dword

Time of Day

Time of day. Mostly effects graphics.

0 - sunrise

1 - day.

2 - sunset.

3 - night.

0x41AD35C

Word

Menu Timer(ms)

Resets to zero when a key is pressed on the menu. Increases to about 25000 and then goes to the Sega intro screen. When at the intro screen, increases to about 30000 then starts the demos. The value is constantly reset to zero during the demos.

Player-Specific Variables

Note: In the event of a discrepancy between the offset and the P1 address, assume the P1 address is the correct value.

The higher this is, the longer it takes Sonic/etc. to sink. Instead they just kind of splash through the top of the water ala the shallow water in Super Mario Kart.

44

0x8FD538

Dword

Forwards Speed RO

Momentum in terms of the character.

4C

0x8FD540

Dword

Distance on Track [?]

Used to calculate race rankings. As such it isn't calculated in Time Attack mode. Goes up by large amounts the further along the track you go. Does not take lap number into account if you've forced it to another number, weirdly enough.

50

0x8FD544

Word

Lap 1 Time

1 is ~1/60 of a second. Causes Game Over once the sum of Laps 1-3 reaches 212400 (1 hour).

54

0x8FD548

Word

Lap 2 Time

58

0x8FD54C

Word

Lap 3 Time

5C

0x8FD550

Word

Current Place (Center/Player)

Range 1-5. Game won't yell at you if it isn't so, but it'll crash on results screen if not in range 0-6.

5E

0x8FD552

Word

Current Lap (Center/Player)

Range 0-3. Setting to 3 instantly loads results screen.

64

0x8FD558

Word

Most Recent Item

Seems to only effect the icons that shows you what item you got.

0 - Nothing

1 - Speed Shoes

2 - 5 Ring

3 - 10 Ring

4 - 20 Ring

5 - Water Shield

6 - Electric Shield

Above - Garbage graphics.

66

0x8FD55A

Word

Item Get Cooldown Time

Affects how long until the item box can be used again, and also how long the icon is on screen.

68

0x8FD55C

Word

Water splash timer [?]

Setting this and water depth to highish values causes a ôburrowingö effect. Strange.

6A

0x8FD55E

Word

Depth into water

Range 0-6. 6 is fully submerged, 0 is on land.

6C

0x8FD560

Word

Pressing Forward

Changes to 0x0000FFFF when the forward key or the accelerate/back key is pressed.

70

0x8FD564

Word

Camera XZ Rotation

Range 0-4096. Not sure what the difference between this and the global one is, as they're both obeyed.

72

0x8FD566

Word

Ground Flag

1 = on ground, 0 = in air.

74

0x8FD568

Word

Tails/Knuckles flight mode

When Tails/(Metal) Knux, set to 0xFFFF when jumping up in air, 2 when flying/gliding, and 0 when falling/on ground.

96

0x8FD58A

Word

Time in air

Time spent flying in air. Tails stops flying around 62.

98

0x8FD58C

Word

Current Animation

Animation sequence being played.

Note that some of these animations crash with Amy, Robotnik and some of the metal characters. Also some animations after 7 crash on the character select screen.

0 - Running

1 - Jumping

2 - Standing

3 - Skid right

4 - Skid left

5 - Hit by bomb/Falling

6 - Victory

7 - Lose

8 - Recover from left skid.

9 - Recover from right skid.

10 - Duck

11 - Recover from duck

12 - Alternate running?

13 - Falling forwards?

14 - Falling forwards?

15 - Falling

16 - Springing

17 - Stretching

18+ - Character specific?

9C

0x8FD590

Dword

Animation Frame (??)

Frame of the animation being played. May or may not be a pointer.

A0

0x8FD594

Dword

Loop Mode

If this is 1 while not on a loop, Sonic will just randomly warp across the terrain until he goes out of bounds and crashes.

A4

0x8FD598

Dword

Current Collision Layer

Determines which floors/walls the character should listen to during collision detection.

B0

0x8FD5A4

Word

Above Geometry

Is 1 if the player is above some sort of level geometry, 0 if on flat ground or water.

Value is usually zero, but setting to max starts a countdown that is set to zero when a balloon is popped.

Total length: 0x71C bytes

Character Models

Model Format

File alternates between vertices, triangles and quads until a vertex count of 0xFFFF is reached. In the event there are no tris or quads in a section, the section is simply skipped. Stored as CHARNAME_?.BIN in /BIN/OBJECTS/CHARNAME

Texture Format

RAW files, PLY files

These files only contain raw image data, in RGB888, without any information about width or height. The file size can be one of the following values.

File Size

Width

Height

21504

32

224

23040

96

80

49152

128

128

196608

256

256

368640

320

384

638976

1664

128

921600

640

480

256 files

These files begin with 256 palette entries, in RGB888. Then there are two 2 byte values indicating the width and height.

Following that is the image data, in 8bpp.

Track Format

Research incomplete.

Geometry File

Stores track geometry, starting position for each character, the finish line location, results screen stuff, the time trials guide path, and presumably the accelerator path as well. Shares same format as 3D icons on menu/title screen.

The geometry portion is split up into two parts: the track parts and the decoration parts. The track parts can contain rings. I'm not entirely sure why this distinction exists.

After all the visible parts come 7 sections of X/Y/Z coordinates used by the game for various purposes.

The first section appears to be every valid path on the track. Might be used for lap-keeping.

The second section is some sort of path. It may be the intro camera path. It does not seem to line up with any course geometry whatsoever vertically, implying that the Y coordinate is time or some other unit.

No clue what the third section is. Made up of 4 points (in Radical City, at least.)

Fourth section is the primary path, excluding shortcuts and ring gate paths. Possibly used for boost and lap-keeping.

Fifth section are the player locations for the start of the race and the victory sequence at the end.

Sixth section appears to be positions for the camera to stay stationary during replay mode.

Seventh section is listed as one byte too long and does not seem to be positional data. It could be some important meta-data like results screen icon.

Description

Length

Length of header

Dword

Header (unused by game)

Length of header * 128 bytes

No. of track parts

Dword

For each track part...

X-position

Dword

Y-position

Dword

Z-position

Dword

Effects viewing angles of parts somehow.

Dword

Number of points

Dword

For each point...

X-position

Word

Y-position

Word

Z-position

Word

Cyan tint

Word

Magenta tint

Word

Yellow tint

Word

Total

12 bytes

Number of faces

For each face...

Texture page (in order loaded by game)

Byte

Null

Byte

Texture Point TA-X

Byte

Texture Point TA-Y

Byte

Texture Point TB-X

Byte

Texture Point TB-Y

Byte

Texture Point TC-X

Byte

Texture Point TC-Y

Byte

Texture Point TD-X

Byte

Texture Point TD-Y

Byte

Unused

Word

Total:

12 bytes

0x0000 (only if rings are on part)

Word

For each ring (if last word was 0x0000)...

X-position

Dword

Y-position

Dword

Z-position

Dword

Total:

12 bytes

Ends with 0xFFFFFFFF

Number of decoration parts

Dword

For each decoration part...

Effects viewing angles of parts somehow.

16 bytes

X position

Dword

Y position

Dword

Z position

Dword

Unknown

6 bytes

Number of triangles

Dword

For each tri...

Point A

Word

Point B

Word

Point C

Word

Texture Point TA-X

Byte

Texture Point TA-Y

Byte

Texture Point TB-X

Byte

Texture Point TB-Y

Byte

Texture Point TC-X

Byte

Texture Point TC-Y

Byte

Texture page

Word

Unknown

Word

Total:

16 bytes

Number of quads

Dword

For each quad...

Point A

Word

Point B

Word

Point C

Word

Point D

Word

Texture Point TA-X

Byte

Texture Point TA-Y

Byte

Texture Point TB-X

Byte

Texture Point TB-Y

Byte

Texture Point TC-X

Byte

Texture Point TC-Y

Byte

Texture Point TD-X

Byte

Texture Point TD-Y

Byte

Texture page

Word

Unknown

Word

Total

20 bytes

Number of points

Word

For each point...

Unknown

Word

X-position

Word

Y-position

Word

Z-position

Word

Unknown

Word

Total

10 bytes

Number of track path points

Dword

For each track path point...

X

Dword

Y

Dword

Z

Dword

Total

12 bytes

Number of intro camera keyframes

Dword

For each intro camera keyframe...

X

Dword

Unknown (possibly time)

Dword

Z

Dword

Total

12 bytes

Number of (Unknown part 3)

Dword

For each (Unknown part 3)...

Unk 1 (Possibly X)

Dword

Unk 2 (Possibly Y)

Dword

Unk 3 (Possibly Z)

Dword

Total

12 bytes

Number of primary path points

Dword

For each primary path point...

X

Dword

Y

Dword

Z

Dword

Total

12 bytes

Number of player start/end locations

Dword

For each player start/end location...

X

Dword

Y

Dword

Z

Dword

Total

12 bytes

Number of replay camera positions

Dword

For each replay camera position...

X

Dword

Y

Dword

Z

Dword

Total

12 bytes

Number of (Unknown part 7) + 1

Dword

For each (Unknown part 7)...

Unk 1

Word

Unk 2

Word

Unk 3

Word

Total

6 bytes

No special ending

Collision File

Contains collision data. Located in /BIN/EXTRAS. Massively over engineered.

Notes

There exist only two types of collision objects (not counting loops, ring gate activation points, etc.): floors and walls. Really steep slopes are just really steep floors. Ceilings are just the bottom of floors you can't walk on. (Best example is the big ramp upwards in Regal Ruin; the same collision data is used when you're on top of the ramp as when you're underneath it jumping up.)

Memory variable 0x8FD598 (for player 1) is a variable that lists the current "collision layer" the player is on. This starts (usually, depends on level) at 0. It increments when you walk or jump onto a floor that is on top of another floor. Likewise, it decrements when you fall or walk off a floor on top of another floor. (Example: Rock overhang in Resort Island. The ramp up to the overhang is layer 0. The overhang itself is layer 1, as it's overtop of layer 0 (the path below). The arrow sign on the overhang is layer 2, as it's over both the overhang and the path.)

Unless otherwise noted, all values are 2 byte word values.

Header

The first 0x5C bytes are reserved for a header. In this header are the offsets to 10 sections and 13 variables (in that order), all stored as 4-byte DWORDS. To reach a certain section, one simply reads the Nth DWORD and jumps ahead to that DWORD's value.

Variables

1-5, 7, and 8 are unused in the game apart from (most likely) leftover dead code.

6 is the number of loop objects in the level. This is used when reading data from section 6.

9 is the number of objects in section 9. This is used when reading data from section 10.

10-13 are hard course limits. It is impossible to pass these.

All maximums are multiplied by 4096 when compared with player XYZ.
Minimums are multiplied by 32, added to maximum, decremented, and then multiples by 4096. (Why?)
Also I may have swapped Minimum and Maximum. As they're not real coordinates, it's hard to tell.
10: Max X
11: Max Z
12: Min X
13: Min Z

Section 1

Main heightmap. This is used to determine what height the character should be at over a certain point.

Note that there exists some sort of mask to determine what is and isn't valid terrain. If you walk off the mask, you will drop to the water level, regardless of any existing heightmap data. Likewise if the heightmap is below the water level (or missing, not tested) the game will attempt to eject you from the floor at the last valid angle you stood on.

Description

Length

X

Word

Height

Word

Z

Word

Total

6 bytes

To get offset from Section 2, you might be able to use raw Section 2 value and add to Section 1 pointer.

Section 4

Undeniably related to walls in some way, shape, or form.

16 bytes (8 words) in length.

The first two words, when edited, seem to cause walls to disappear from some places and reappear (at seemingly intentional places, such as both ends of the high path around Resort Island's volcano thing) in other places.

Section 5

Appears to be a wallmap, but I cannot confirm this. It appears (when rendered) to be the outlines of the higher up portions of the level.

Description

Length

X

Word

Height

Word

Z

Word

Total

6 bytes

To get an offset from Section 4, compute [Sec5 + [Sec4_Val]*6 + 6]. The (+6) may be optional.

Section 6

Loop metadata. Unknown format and structure size.

Section 7

Loop point information. Should be X/Y/Z like the others, but rendering it like that causes a lot of garbage data to appear. (Despite this, the loop fits in perfectly with all the other collision data.) Attemping other structure sizes doesn't make the garbage disappear; garbage is possibly metadata read using information from section 6.

Section 8

Structure size is probably 16 bytes or a factor of 16 bytes.

This is a look-up table that converts player X and Z coordinates to Section 9 offsets.