Sonic R/Technical information/Windows PC
From Sonic Retro
(Redirected from SCHG:Sonic R (PC))
- Back to: Sonic R/Technical information.
![]() |
This article needs cleanup. This article needs to be edited to conform to a higher standard of article quality. |
Contents
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. [source](Note: This hack assumes you're using the original executable without network support. The network version doesn't seem to work on NT-based Windows systems to begin with.)
In a hex editor, go to offset 0x70584. Replace these bytes:
2e ff 15 8c 05 95 00
with these bytes:
b8 31 00 00 00 90 90
Next, go to offset 0x705A0. Replace these bytes:
2e ff 15 8c 05 95 00
with these bytes:
b8 01 00 00 00 90 90
What this does is it disables the function calls to get the system time and replaces them with known values that are guaranteed to work on modern systems.
RAM locations
These values are absolute from base of RAM; a value of 0x400001 is equal to sonicr.exe+0x000001.
Global variables
TODO: Find and add the remaining 2004 variables.
Address (2004) | Address (1998) | Data Type | Description | Notes |
---|---|---|---|---|
0x504278 | Dword | CD Check | 1 if CD present, 0 if not. Largely useless after game boots. | |
0x540064 | Dword Pointer | AI RAM Location | Memory address of the current level's AI data (copied into RAM from the AI file.) | |
0x625BFC | Word | Current File | Used by fread() | |
0x5EDD24 | 0x630144 | Dword | Windowed | Crashes the game when not 0 on the 1998 release. |
0x630148 | Dword | Native Software Render Mode | Probably related to ancient software 3D drivers for Windows 95. | |
0x675907 | Array (10 bytes) | Function Key States | Array of F1-F10, 0 being unpressed and 0x80 being pressed. | |
0x68AF34 | Dword | Sound Test Selection | Selection for the Sound Test option on the Options menu. | |
0x68AF38 | Dword | Music Test Selection | Selection for the Music Test option on the Options menu. | |
0x68AFB8 | Dword | 1P Ready | Controls whether or not the player has selected their character. If less than 4 players, the unused players are automatically set to 1. | |
0x68AFBC | Dword | 2P Ready | ||
0x68AFC0 | Dword | 3P Ready | ||
0x68AFC4 | Dword | 4P Ready | ||
0x6d9A38 | Dword | Seconds Since Race Start | Used to control camera position, and "READY SET GO!" indicators, among other things. | |
0x75349C | 0x6DD860 | Dword | Render Mode | 0 if ? (makes D3D not load new textures), 1 if standard D3D, 2 if DDraw |
0x461520 | 0x6E9898 | Dword | X Resolution | Sometimes forcing this to a value w/ Cheat Engine and toggling the resolution back and forth will make this resolution stick. It usually does not. |
0x461524 | 0x6E989C | Word | Y Resolution | |
0x6E98B4 | Dword | Color Depth | Possible values 8 and 16. D3D is always 16. | |
0x6E98DC | Dword | Visible Screen Width | Width of screen excluding borders added in options. | |
0x7AF280 | 0x6E9908 | Dword | No. of Game Windows | Number of windows to show. Don't set to higher than there is screen space for; exit level, set, and reenter level instead. |
0x7344EC | 0x6E991C | Dword | 2P HUD Split style | 0 is horizontal, 1 is vertical. Doesn't seem to effect anything besides HUD elements and borders, actual window positions are determined by something else. |
0x6E9958 | Float | Camera Angle Float? | A float of some sort determining some sort of camera angle. | |
0x6E9C90 | Dword | Viewport X | X-position of camera. | |
0x6E9C94 | Dword | Viewport Y | Y-position of camera. | |
0x6E9C98 | Dword | Viewport Z | Z-position of camera. | |
N/A | 0x6E9CDC | Dword | Current FPS | How many frames the game renders in a second. Does not count frames skipped by user choice. (2004 version uses kernel32:sleep() for waiting instead so it doesn't use this.) |
0x6E9D00 | Dword | Frames Rendered Lifetime | Probably the frames rendered since the game first starts. | |
0x6EAD30 | Dword | # Parts in course | Range 0-until it crashes. Tells the game how many level parts it should render. Typical values ~500-~1000, depending on the complexity of the level. | |
0x753504 | 0x713060 | Dword | Model Count | Number of character models. Should be 10 on vanilla copies of the game. |
0x753678 | 0x713064 | Dword | Model Limb Count | Number of movable parts in all character models. Should be 115 in vanilla copies of the game. |
0x7BCB70 | 0x713068 | Dword | Model Vertex Count | Number of vertexes in all character models. Should be 3349 in vanilla copies of the game. |
0x7AF07C | 0x713070 | Dword | Model Polygon Count | Number of polygons (tris and quads) in all character models. Should be 1917 in vanilla copies of the game. |
0x7535DC | 0x713074 | Dword | Model Frame Count | Number of total animation frames for all characters. Should be 15974 in vanilla copies of the game. |
0x8F6C28 | Dword | Footstep/Shadow texture page | Offset for textures used in character footsteps and shadows. | |
0x8F6C38 | Dword | Pause Menu/MP Number Texture Page | Offset for textures used in pause menu and multiplayer-specific HUD elements. | |
0x8F6C3C | Dword | HUD texture page | Offset for textures used in HUD elements. | |
0x8F6C48 | Dword | Menu Texture Page | Offset for textures used in menu screens. | |
0x8FB35C | Dword | Draw Distance 2 | Unknown use | |
0x8FB360 | Dword | Draw Distance 3 | Unknown use | |
0x8FB364 | Float | Draw Distance Fog | Controls fog distance, but not render distance. | |
0x8FB68C | Dword | Frames Rendered Scene | Frames rendered since the start of the race/menu/etc. | |
0x8FB690 | Dword | Frames Rendered Lifetime | Frames rendered since the start of the game. | |
0x8FB80C | Dword | Frame Limiter Multiplier | How many frames to skip before rendering another one. 0 is 30FPS, 1 is 15 FPS, etc. | |
0x8FB8E4 | Dword | Demo Mode | Tells if the game is currently in demo.
| |
0x7AF13C | 0x8FB8EC | Word | Current Course | Current course. Changing during gameplay WILL crash game. Note that Factory and Ruin are swapped from their in-game menu order.
|
0x769F24 | 0x8FB950 | Dword | Game Mode | The current HUD/game mode.
|
0x769F28 | Word | Sum Of Emeralds Collected | The emeralds have an assigned value (1 or 2). The sum of the collected emeralds is stored here. | |
0x7BCB80 | 0x8FB954 | Dword | Time Attack Submode | The current time attack submode
|
0x8FD444 | Dword | Game Difficulty | Difficulty of game. Range 0-2. | |
0x8FD448 | Dword | Ghost On/Off | Toggles time attack ghost saving/loading. 0 is off, 1 is on. | |
0x8FD44C | Dword | Weather Option | Chosen weather conditions.
| |
0x8FD450 | Dword | Catchup On/Off | 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 | DDraw only. Toggles between mesh-style transparency and actual alpha blending | |
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. | |
0x7AF1B4 | 0x8FD4A0 | Dword | Music Volume | Volume of music in the game. Range for 1998 is 0-1. Range for 2004 is 0-8. |
0x901C10 | Dword | Pause Screen Selection | Selection on the Pause menu.
| |
0x7C1BC0 | 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. |
0x5F388C | Dword | Screen Transition Speed | In units of "Screen Transition Coverage"/frame | |
0x7BCB28 | 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.
| |
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. | |
0x4A3608 | 0x9020D8 | 8 bytes (2 bytes * 4 players) | Controls Bitfield |
|
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. | |
0x752828 | 0x92528C | Dword | Options Screen Selection | Selection on the Options screen and usually anything else vertical, also rotation of main screen icon. |
0x925298 | Dword | Character Select Sonic Icon Texture Y Offset | 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. | |
0x7B7D48 | 0x9252B4 | Dword | Main Menu Option | Selection for the Menu screen and usually anything else horizontal. |
0x9252B8 | Dword | Horiz-Menu Screenpos Loc | Current location on screen of the selector on the menu. Range 0 to 320. | |
0x752858 | 0x9252BC | Dword | Horiz-Menu Screenpos Dest | Where the selector plans on going. |
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 | ||
0x8607BC | 0x94BCF4 | Dword | Weather | Current weather, regardless of option. Ignored in Time Attack mode for some reason.
|
0x85EB78 | 0x94BCF8 | Dword | Time of Day | Time of day. Mostly effects graphics.
|
0x5D359C | Array (51 32-bit pointers) | Texture Buffer Pointers | Offsets to malloc'd texture page buffers in RAM. Changes do not effect output until sent to GPU. | |
0x6260A4 | Dword | No. of texture pages loaded | ||
0x752BE0 | Array (10 Dwords) | Character lock array |
|
Player struct
Game keeps an array of 5 structs for each of 5 racers. For the 1998 release, this starts at 0x8FD4F4 For the 2004 release, this starts at 0x7B7388
Offset | P1 Address | Data Type | Description | Notes |
---|---|---|---|---|
0 | Dword | X Position | 0 is center of map. Goes up by large amounts. | |
4 | Dword | Y Position | 0 is water level. To go up, subtract. You can't go down. | |
8 | Dword | Z Position | 0 is center of map. Goes up by large amounts. | |
C | Dword | YZ Rotation | Max is 4096. Slowly reverts itself if not locked into extreme values. | |
10 | Dword | XZ Rotation | ||
14 | Dword | XY Rotation | ||
18 | Dword | Ring Count | Max 999. Adding more makes the game subtract back down. | |
1C | Dword | Animation Frame? | ||
20 | Dword | X Position Mirror [???] | Not sure what these are for. | |
24 | Dword | Y Position Mirror [???] | ||
28 | Dword | Z Position Mirror [???] | ||
2C | Dword | X Speed | Higher values = faster speed. Goes negative, too. Given in relation to world, not player. | |
30 | Dword | Y Speed | ||
34 | Dword | Z Speed | ||
38 | Dword | Ground Height | Y position of ground below you | |
40 | Word | In Water? | 0 = No, 1 = Yes. | |
42 | Word | Time Until Sink | 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 | Dword | Forwards Speed RO | Momentum in terms of the character. | |
4C | 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 | 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 | Word | Lap 2 Time | ||
58 | Word | Lap 3 Time | ||
5C | 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 | Word | Current Lap (Center/Player) | Range 0-3. Setting to 3 instantly loads results screen. | |
64 | Word | Most Recent Item | Seems to only effect the icons that shows you what item you got.
| |
66 | 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 | Word | Water splash timer [?] | Setting this and water depth to highish values causes a ôburrowingö effect. Strange. | |
6A | Word | Depth into water | Range 0-6. 6 is fully submerged, 0 is on land. | |
6C | Word | Pressing Forward | Changes to 0x0000FFFF when the forward key or the accelerate/back key is pressed. | |
70 | 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 | Word | Ground Flag | 1 = on ground, 0 = in air. | |
74 | 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 | Word | Time in air | Time spent flying in air. Tails stops flying around 62. | |
98 | 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.
| |
9C | Dword | Animation Frame (??) | Frame of the animation being played. May or may not be a pointer. | |
A0 | 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 | Dword | Current Collision Layer | Determines which floors/walls the character should listen to during collision detection. | |
B0 | Word | Above Geometry | Is 1 if the player is above some sort of level geometry, 0 if on flat ground or water. | |
B2 | Word | Above Geometry Mirror | ||
B4 | Word | Slope RX | Rotation of the current slope along the global X axis. | |
B6 | Word | Slope Magnitude | Intensity of current slope. Independent of X/Z. | |
B8 | Word | Slope RZ | Rotation of the current slope along the global Z axis. | |
BC | Dword | Loop ? | ||
C0 | Dword | Loop XZ Pos | Location left/right while on a loop. | |
C4 | Dword | Loop Distance | Distance completed on the loop. | |
C8 | Dword | Loop ? | ||
CC | Dword | Loop XZ Momentum | Left/Right movement momemtum. | |
D0 | Dword | Loop Momentum | Forwards/Backwards momentum on the loop. | |
D4 | Word | Drift Direction? | 0xFE00 if drifting right, 0x0200 if drifting left. Unknown purpose. | |
EA | Word | Sound FX | Set this to a SFX ID to play a sound effect only heard by that player | |
F0 | Word | Always 1 | Not sure what this is for. | |
F2 | Word | Identity | Effects everything besides the character model, including animations, icons, control, etc. Range 0-9. | |
11C | 0xA4 (164) Bytes | AI Area Start | Wiped at beginning of each round. Seems to be used by AI. | |
1E0 | Dword | Player Model | Range 0-9, 0 being Sonic, 9 being Super Sonic. | |
1EC | Dword | Running Animation | Animation frame being played. Range 0-maximum frame count for the player. Probably corresponds with the loaded files. | |
1F4 | Word | Number of Balloons | Balloons popped in Time Attack Balloon mode. Range 0-255. Setting to 5 instantly loads results screen. | |
204 | Dword | Last Balloon Timer? | 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
Description | Length |
---|---|
Vertices | |
Number of Vertices in Part | Word |
For each vertex... | |
X | Word |
Y | Word |
Z | Word |
Unknown | 9 bytes |
EOL (always 0x80) | Byte |
Total: | 16 bytes |
Triangles | |
Number of Tris in Part | Word |
For each tri... | |
Vertex No. of Point A | Word |
Vertex No. of Point B | Word |
Vertex No. of 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 |
Null | Dword |
Total: | 16 bytes |
Quads | |
Number of Quads in Part | Word |
For each quad... | |
Vertex No. of Point A | Word |
Vertex No. of Point B | Word |
Vertex No. of Point C | Word |
Vertex No. of 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 |
Null | Dword |
Total: | 20 bytes |
End of File (0xFFFF) | Word |
Animation format
Stored as ?AN#.BIN in /BIN/OBJECTS/CHARNAME
Description | Length |
---|---|
# of parts to move (global) | Dword |
For each part until EOF... | |
Transformation TX | Dword |
Transformation TY | Dword |
Transformation TZ | Dword |
Rotation RX | Dword |
Rotation RY | Dword |
Rotation RZ | Dword |
Total | 24 bytes |
Texture format
Tools for editing textures can be found here, with source code here.
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.
Faces on the track portion seem to simply assume that it uses 4 vertices in order. (EX: Part 1 uses vertices 1-4, Part 2 uses 5-8, etc.)
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 both the intro camera path and the accelerator path. It consists of 360 x/y/z coordinates, where the first 180 are the camera intro keyframes and the last 180 are the accelerator path.
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 |
Red tint | Word |
Green tint | Word |
Blue 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 | Dword |
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 | Dword |
Total | 20 bytes |
Number of points | Word |
For each point... | |
X-position | Word |
Y-position | Word |
Z-position | Word |
Red tint | Byte |
Green tint | Byte |
Blue tint | Byte |
Null byte | Byte |
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
Note: The coordinates have the form [block][major][minor][precise]. The levels are split into blocks labelled -2, -1, 0, 1, 2, which correspond to FE,FF,00,01,and 02, and those blocks are further split into 0-255 (left to right), and those blocks are further split into 0-255 (left to right). A coordinate can look like FF1af44e, which would correspond to block -1 (FF/block), at position 26 (1a/major), sub-position 244 (fa/minor), sub-sub-position 78 (4e/precise).
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 2
Possibly rotation data for the points from section 1. Most likely 4 bytes in length. Unknown contents.
To get offset from Section 3, compute [Sec2 + [Sec3_Val] * 14], where ? is one of 2, 4, or 8.
Section 3
Some sort of 2D point map. Unknown (but important) purpose.
Description | Length |
---|---|
Unk. 1 | Word |
Unk. 2 | Word |
X | Word |
Z | Word |
Total | 6 bytes |
To get this from Section 9, compute [Sec3 + ([Sec9+?] & 0xFFF) * 0x10 + {2, 4, 8}]. (Not sure what ? is. Choose one of 2, 4, or 8.) Only use highest 2 bytes of result. (right-shift 0x10)
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.
3rd word (+04) is 2^(current layer).
+06 and +08 are related to X/4096 and Z/4096, respectively.
+0C is compared to (X-06)^2 + (Z-08)^2 to change code branching path.
To get an offset from Section 9, compute [Sec4 + (Sec9 & 0x0FFF) * 16]
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.
To get a Section 9 offset, compute [Sec8 + ((Z/4096 - MaxZ) / MinZ * 32 + ((X/4096 - MaxX) / MinX))]. Add that value to the Section 9 start.
Section 9
Structure size is 4 bytes.
This is the primary look-up table. Most other non-XZ tables are indexed by the contents of this table.
Typically only the last 3 nybbles (& 0x0FFF) are used.
See the descriptions for the other sections for how this is used.
Section 10
Seems to contain ring gate activation points. Possibly contains points for other objects; this is untested.
(Note: this may be wrong)
Description | Length |
---|---|
X | Word |
Y | Word |
Z | Word |
Index | Word |
Total | 6 bytes |
AI files
Contains path data for the computer opponents. Located in /AI. Does not contain anything needed for time trials/multiplayer.
Split up into 5 sections.
(Reporting segment size as how many calls to fread() the code makes per section loop)
Section 1 is 0x2000 2 byte segments. This appears to be the input sequence for every AI. Replacing just this section with the bytes from another level made the AI appear think it was on the other level.
Section 2 is 0x80 4 byte segments. This may be the time to wait between inputs. Zeroing out this section resulted in the AI taking every action needed to move around a level within a smaller area/quicker time.
Section 3 is 0xE00 1 byte segments.
Section 4 is 0x400 1 byte segments.
If the course is Resort Island, Section 5 is 0x320 * 1 byte. If the course is Radiant Emerald, Section 5 is 0xA0 * 1 byte Otherwise, Section 5 is 0x280 * 1 byte.
Contents need additional research.
Save files
These files can be found in the .\save directory with filenames in the format r##.sav
This is an incomplete listing of the locations inside these files:
Offset | Type | Description |
---|---|---|
4 | Byte | Resort Island Unlocked (def. 1)
|
8 | Byte | Radical City Unlocked (def. 1) |
C | Byte | Reactive Factory Unlocked (def. 1) |
10 | Byte | Regal Ruin Unlocked (def. 1) |
14 | Byte | Radiant Emerald Unlocked (def. 0) |
18 | Byte | Sonic Unlocked (def. 2)
|
1C | Byte | Tails Unlocked (def. 2) |
20 | Byte | Knuckles Unlocked (def. 2) |
24 | Byte | Amy Unlocked (def. 2) |
28 | Byte | Robotnik Unlocked (def. 1) |
2C | Byte | Metal Sonic Unlocked (def. 0) |
30 | Byte | Tails Doll Unlocked (def. 0) |
34 | Byte | Metal Knuckles Unlocked (def. 0) |
38 | Byte | Eggrobo Unlocked (def. 0) |
3C | Byte | Super Sonic Unlocked (def. 0) |
40 | Byte | Blue Emerald Collected
|
44 | Byte | Green Emerald Collected |
48 | Byte | Purple Emerald Collected |
4C | Byte | Yellow Emerald Collected |
50 | Byte | Orange Emerald Collected |
54 | Byte | Red Emerald Collected |
58 | Byte | White Emerald Collected |
sonicr.inf
This file, located in the main folder, stores various settings. Note that despite the extension inf, it is not an actual inf file, and should NOT be opened with Notepad.
Offset | Type | Description |
---|---|---|
0 | Byte | Difficulty
|
4 | Byte | Ghost Toggle
|
8 | Byte | Weather
|
C | Byte | Catch Up Toggle
|
10 | Byte | Guide Toggle
|
14 | Byte | Map Toggle
|
28 | Byte | Color
|
18 | Byte | 2P Split
|
2C | Byte | Alpha Blending
|
34 | Byte | Interlace
|
3C | Byte | Draw Distance
|
40 | Byte | Screen Size
|
44 | Byte | Track Shading
|
50 | Byte | Stereo Toggle
|
54 | Byte | Vocals Toggle
|
58 | Byte | SFX Volume (00-08) |
5C | Byte | Music Toggle
|
References
Sonic R | |
---|---|
Manuals |
show;hide
Books:
Music: Songs: "Super Sonic Racing" | "Can You Feel the Sunshine" | "Living in the City" | "Back in Time" | "Work it Out" | "Diamond in the Sky" | "Number One" |