Actions

SCHG

Difference between revisions of "Sonic Heroes/Model Format"

From Sonic Retro

(File Format)
Line 1: Line 1:
 
{{SCHG SH}}
 
{{SCHG SH}}
  
Sonic Heroes runs on a modified version of the RenderWare engine. Due to that, much of the model information regarding games created on similar versions of it, such as Tony Hawk's Pro Skater 3 and some games of the Grand Theft Auto franchise applies to it as well. However, Sonic Heroes still has data which is specific for itself. There are currently no public tools that can generate custom models that are fully compatible with Sonic Heroes. The information on this page applies to the PC version only. The Gamecube version of the game uses a slighly different format.
+
Sonic Heroes runs on a version of the RenderWare engine, and most of the game's models are in DFF or BSP format. The information on this page applies to the PC version only.
  
 
== Object Models ==
 
== Object Models ==
Line 7: Line 7:
  
 
== Level Models ==
 
== Level Models ==
Level models in Sonic Heroes are located in little endian BSP (binary space partitioning) files, contained inside .ONE archives in the dvdroot folder. Multiple BSPs are in each ONE archive. The archives can be opened with [[HeroesONE]], and can be converted to OBJ using a modified version of BSP2OBJ.
+
Level models in Sonic Heroes are located in little endian BSP (binary space partitioning) files, contained inside .ONE archives in the dvdroot folder. Multiple BSPs are in each ONE archive. The archives can be opened with [[HeroesONE]]. [[Heroes Power Plant]] has support for viewing and editing the files.
  
 
=== File Names ===
 
=== File Names ===
Line 39: Line 39:
 
=== File Format ===
 
=== File Format ===
  
Each BSP is a stream of binary data, divided into multiple sections, which can have multiple children and sibling sections. Each section starts with an array of three int32: the first one is an identifier for the section type, then there's the total size of the section, then there's 0x1400FFFF, which is the RenderWare engine version identifier (it's little endian so it's displayed FF FF 00 14 in the hex editor).
+
Each BSP is a stream of binary data, divided into multiple sections, which can have multiple children and sibling sections. Each section starts with an array of three int32: the first one is an identifier for the section type, then there's the total size of the section, then there's 0x1400FFFF, which is the RenderWare engine version identifier.
  
The total size of the section, as said above, includes the section itself and all children sections, but does not include this 0x0C byte "header". So get the total number of bytes in the section and subtract 0x0C to put there. Notice where each section starts and ends. All sections included into another one are children. The WORLD section, which includes the entire file, has in its header the total number of bytes in the file minus 0x0C.
+
The total size of the section, as said above, includes the section itself and all children sections, but does not include this 0x0C byte "header". So get the total number of bytes in the section and subtract 0x0C to put there.
  
 
Note that "struct" sections have an identifier of 0x01, "extension" sections have an identifier of 0x03 and all other sections have different identifiers. Most extensions do nothing, except for the Atomic Extension, which contains the Bin Mesh PLG section which contains triangle strips.
 
Note that "struct" sections have an identifier of 0x01, "extension" sections have an identifier of 0x03 and all other sections have different identifiers. Most extensions do nothing, except for the Atomic Extension, which contains the Bin Mesh PLG section which contains triangle strips.
  
The file is little endian. It has the following structure, in order:
+
The file is little endian.
  
  // WORLD SECTION
+
  // WORLD
 
  int32 0x0B // section identifier
 
  int32 0x0B // section identifier
 
  int32 // section size
 
  int32 // section size
 
  int32 0x1400FFFF
 
  int32 0x1400FFFF
 
   
 
   
  // MODEL HEADER STRUCT
+
  // WORLD STRUCT
 
  int32 0x01 // section identifier
 
  int32 0x01 // section identifier
 
  int32 // section size (always 0x40)
 
  int32 // section size (always 0x40)
Line 62: Line 62:
 
  int32 // number of triangles (''numTriangles'')
 
  int32 // number of triangles (''numTriangles'')
 
  int32 // number of vertices (''numVertices'')
 
  int32 // number of vertices (''numVertices'')
  00 00 00 00 // unknown, always this value
+
  int32 // number of planes (''numPlanes'')
  01 00 00 00 // unknown, always this value
+
  int32 // number of atomics (''numAtomics'')
 
  00 00 00 00 // unknown, always this value
 
  00 00 00 00 // unknown, always this value
 
  0D 00 01 40 // unknown, always this value
 
  0D 00 01 40 // unknown, always this value
Line 69: Line 69:
 
  float32[3] // Boundary box minimum // Maximum values must be the bigger than minimum
 
  float32[3] // Boundary box minimum // Maximum values must be the bigger than minimum
 
   
 
   
  // END MODEL HEADER STRUCT
+
  // END WORLD STRUCT
 
   
 
   
  // MATERIAL LIST SECTION
+
  // MATERIAL LIST
 
  int32 0x08 // section identifier
 
  int32 0x08 // section identifier
 
  int32 // section size
 
  int32 // section size
 
  int32 0x1400FFFF
 
  int32 0x1400FFFF
 
   
 
   
  // MATERIAL NUMBER STRUCT
+
  // MATERIAL LIST STRUCT
 
  int32 0x01 // section identifier
 
  int32 0x01 // section identifier
 
  int32 // section size
 
  int32 // section size
 
  int32 0x1400FFFF
 
  int32 0x1400FFFF
 
  int32 // number of materials (''numMaterials''), materials are ordered by a zero-based index
 
  int32 // number of materials (''numMaterials''), materials are ordered by a zero-based index
  ''numMaterials''*int32 0xFFFFFFFF // there is a -1 for each material
+
  int32[''numMaterials''] 0xFFFFFFFF // there is a -1 for each material
 
   
 
   
  // END MATERIAL NUMBER STRUCT
+
  // END MATERIAL LIST STRUCT
 
   
 
   
  // MATERIAL REF SECTION // this section occours ''numMaterials'' times
+
  // MATERIAL // this section occours ''numMaterials'' times
 
  int32 0x07 // section identifier
 
  int32 0x07 // section identifier
 
  int32 // section size
 
  int32 // section size
Line 102: Line 102:
 
  // END MATERIAL STRUCT
 
  // END MATERIAL STRUCT
 
   
 
   
  // TEXTURE SECTION
+
  // TEXTURE
 
  int32 0x06 // section identifier
 
  int32 0x06 // section identifier
 
  int32 // section size
 
  int32 // section size
 
  int32 0x1400FFFF
 
  int32 0x1400FFFF
 
   
 
   
  // TEXTURE FLAG STRUCT
+
  // TEXTURE STRUCT
 
  int32 0x01 // section identifier
 
  int32 0x01 // section identifier
 
  int32 // section size (always 0x04)
 
  int32 // section size (always 0x04)
Line 116: Line 116:
 
  bool16 // byte: use mipmap? (usually 0x01)
 
  bool16 // byte: use mipmap? (usually 0x01)
 
   
 
   
  // END TEXTURE FLAG STRUCT
+
  // END TEXTURE STRUCT
 
   
 
   
  // DIFFUSE TEXTURE NAME SECTION
+
  // DIFFUSE TEXTURE NAME
 
  int32 0x02 // section identifier
 
  int32 0x02 // section identifier
 
  int32 // section size
 
  int32 // section size
Line 124: Line 124:
 
  string // texture name
 
  string // texture name
 
   
 
   
  // END DIFFUSE TEXTURE NAME SECTION
+
  // END DIFFUSE TEXTURE NAME
 
   
 
   
  // ALPHA TEXTURE NAME SECTION // unused section, alphas are set in the TXD
+
  // ALPHA TEXTURE NAME // unused section, alphas are set in the TXD
 
  int32 0x02 // section identifier
 
  int32 0x02 // section identifier
 
  int32 // section size (always 0x04)
 
  int32 // section size (always 0x04)
Line 132: Line 132:
 
  string // alpha texture name (unused, always left blank)
 
  string // alpha texture name (unused, always left blank)
 
   
 
   
  // END ALPHA TEXTURE NAME SECTION
+
  // END ALPHA TEXTURE NAME
 
   
 
   
 
  // TEXTURE EXTENSION // this section does absolutely nothing
 
  // TEXTURE EXTENSION // this section does absolutely nothing
Line 141: Line 141:
 
  // END TEXTURE EXTENSION
 
  // END TEXTURE EXTENSION
 
   
 
   
  // END TEXTURE SECTION
+
  // END TEXTURE
 
   
 
   
 
  // MATERIAL EXTENSION // this section does absolutely nothing
 
  // MATERIAL EXTENSION // this section does absolutely nothing
Line 150: Line 150:
 
  // END MATERIAL EXTENSION
 
  // END MATERIAL EXTENSION
 
   
 
   
  // END MATERIAL REF SECTION
+
  // END MATERIAL
 +
 +
// END MATERIAL LIST
 +
 +
// Here, there's either a Plane Section or an Atomic Section.
 +
 +
// PLANE SECTION
 +
int32 0x0A // section identifier
 +
int32 // section size
 +
int32 0x1400FFFF
 +
 +
// PLANE STRUCT
 +
int32 0x01 // section identifier
 +
int32 // section size
 +
int32 0x1400FFFF
 +
int32 type
 +
int32 value
 +
bool32 leftIsAtomic
 +
bool32 rightIsAtomic
 +
float32 leftValue
 +
float32 rightValue
 +
 
 +
// END PLANE STRUCT
 +
 +
// Plane Sections contain two sub sections (left and right), each which can be either an Atomic Section (which contains model data) or another Plane Section. They are located here.
 
   
 
   
  // END MATERIAL LIST SECTION
+
  // END PLANE SECTION
 
   
 
   
 
  // ATOMIC SECTION
 
  // ATOMIC SECTION
Line 182: Line 206:
 
  int32 0x1400FFFF
 
  int32 0x1400FFFF
 
   
 
   
  // BIN MESH PLG SECTION
+
  // BIN MESH PLG
 
  int32 0x50E // section identifier
 
  int32 0x50E // section identifier
 
  int32 // section size
 
  int32 // section size
 
  int32 0x1400FFFF
 
  int32 0x1400FFFF
  uint32 // flags (0 = triangle lists, 1 = triangle strips; Sonic Heroes always uses tristrips, don't know if it even supports trilists)
+
  uint32 // flags (0 = triangle lists, 1 = triangle strips)
 
  uint32 // number of objects/meshes (''numMeshes''; usually same number of materials)
 
  uint32 // number of objects/meshes (''numMeshes''; usually same number of materials)
 
  uint32 // total number of indices
 
  uint32 // total number of indices
Line 195: Line 219:
 
  )
 
  )
 
   
 
   
  // END BIN MESH PLG SECTION
+
  // END BIN MESH PLG
 
   
 
   
 
  // END ATOMIC EXTENSION
 
  // END ATOMIC EXTENSION
Line 208: Line 232:
 
  // END WORLD EXTENSION
 
  // END WORLD EXTENSION
 
   
 
   
  // END WORLD SECTION
+
  // END WORLD
  
==== Texture Flag Struct Settings ====
+
==== Texture Struct Settings ====
 
  Texture filtering modes (unsure if all of them work in SH)
 
  Texture filtering modes (unsure if all of them work in SH)
 
* 0 - FILTERNAFILTERMODE (filtering is disabled)
 
* 0 - FILTERNAFILTERMODE (filtering is disabled)

Revision as of 02:16, 15 March 2018

SCHG: Sonic Heroes
Main Article
Mechanic Editing

DOL Editing
EXE Editing
Music Pointers
Object Parameter Data
Relocatable Editing (PC)
File Offsets

Model Editing
Collision Format
Model Format
Level Editing

Camera Editing
Event Editing
ID list
Indirect Editing
Light Editing
Level List
Object Editing
Object Porting
Spline Editing
Texture Animation Editing
Visibility Editing

Particle Editing
Particle Editing
Sound Editing
Music List

Sound Editing
Voices

SCHG How-Tos

Custom Object Material Effect Tutorial
Level Editing Tutorial


Sonic Heroes runs on a version of the RenderWare engine, and most of the game's models are in DFF or BSP format. The information on this page applies to the PC version only.

Object Models

Models for objects and characters are located in DFF files, contained inside ONE archives. Those models can be imported and viewed in model editors using existing scripts for other games.

Level Models

Level models in Sonic Heroes are located in little endian BSP (binary space partitioning) files, contained inside .ONE archives in the dvdroot folder. Multiple BSPs are in each ONE archive. The archives can be opened with HeroesONE. Heroes Power Plant has support for viewing and editing the files.

File Names

The BSP files are named in the form of SLL_XX_NN.BSP (or STG instead of S for some levels). LL is the level number, XX are letters that identify which part of the geometry is in that file and NN is the chunk number. All files with the same number make up the same chunk. For the game to know which chunk to display at a given time, it uses the *_blk.bin file. The following letters are accepted for the geometry identifier:

  • A
  • AF
  • AFN
  • AFNS
  • AFS
  • AN
  • ANS
  • AS
  • DA
  • DN
  • K
  • KW
  • O
  • ON
  • ONS
  • ONW
  • ONWS
  • OS
  • P
  • PN
  • PNS
  • PNW
  • PNWS
  • PS

File Format

Each BSP is a stream of binary data, divided into multiple sections, which can have multiple children and sibling sections. Each section starts with an array of three int32: the first one is an identifier for the section type, then there's the total size of the section, then there's 0x1400FFFF, which is the RenderWare engine version identifier.

The total size of the section, as said above, includes the section itself and all children sections, but does not include this 0x0C byte "header". So get the total number of bytes in the section and subtract 0x0C to put there.

Note that "struct" sections have an identifier of 0x01, "extension" sections have an identifier of 0x03 and all other sections have different identifiers. Most extensions do nothing, except for the Atomic Extension, which contains the Bin Mesh PLG section which contains triangle strips.

The file is little endian.

// WORLD
int32 0x0B // section identifier
int32 // section size
int32 0x1400FFFF

// WORLD STRUCT
int32 0x01 // section identifier
int32 // section size (always 0x40)
int32 0x1400FFFF
int32 0x01 // unknown, always this value
00 00 00 80 // unknown, always this value
00 00 00 80 // unknown, always this value
00 00 00 80 // unknown, always this value
int32 // number of triangles (numTriangles)
int32 // number of vertices (numVertices)
int32 // number of planes (numPlanes)
int32 // number of atomics (numAtomics)
00 00 00 00 // unknown, always this value
0D 00 01 40 // unknown, always this value
float32[3] // Boundary box maximum
float32[3] // Boundary box minimum // Maximum values must be the bigger than minimum

// END WORLD STRUCT

// MATERIAL LIST
int32 0x08 // section identifier
int32 // section size
int32 0x1400FFFF

// MATERIAL LIST STRUCT
int32 0x01 // section identifier
int32 // section size
int32 0x1400FFFF
int32 // number of materials (numMaterials), materials are ordered by a zero-based index
int32[numMaterials] 0xFFFFFFFF // there is a -1 for each material

// END MATERIAL LIST STRUCT

// MATERIAL // this section occours numMaterials times
int32 0x07 // section identifier
int32 // section size
int32 0x1400FFFF

// MATERIAL STRUCT
int32 0x01 // section identifier
int32 // section size (always 0x1C)
int32 0x1400FFFF
int32 0x00 // ununsed flags
int8[4] RGBA // Material RGBA (usually 255, 255, 255, 255)
int32 84 3E F5 2D // always this value, unused
bool32 // uses texture? (usually 0x01)
float32[3] // ambient, specular, diffuse // don't know if these are used. always (1, 1, 1)

// END MATERIAL STRUCT

// TEXTURE
int32 0x06 // section identifier
int32 // section size
int32 0x1400FFFF

// TEXTURE STRUCT
int32 0x01 // section identifier
int32 // section size (always 0x04)
int32 0x1400FFFF
int8 // byte, texture filtering mode (usually 0x02)
4bit // half the byte: U adressing mode (usually 0001)
4bit // half the byte: V adressing mode (usually 0001)
bool16 // byte: use mipmap? (usually 0x01)

// END TEXTURE STRUCT

// DIFFUSE TEXTURE NAME
int32 0x02 // section identifier
int32 // section size
int32 0x1400FFFF
string // texture name

// END DIFFUSE TEXTURE NAME

// ALPHA TEXTURE NAME // unused section, alphas are set in the TXD
int32 0x02 // section identifier
int32 // section size (always 0x04)
int32 0x1400FFFF
string // alpha texture name (unused, always left blank)

// END ALPHA TEXTURE NAME

// TEXTURE EXTENSION // this section does absolutely nothing
int32 0x03 // section identifier
int32 // section size (0x00)
int32 0x1400FFFF

// END TEXTURE EXTENSION

// END TEXTURE

// MATERIAL EXTENSION // this section does absolutely nothing
int32 0x03 // section identifier
int32 // section size (0x00)
int32 0x1400FFFF

// END MATERIAL EXTENSION

// END MATERIAL

// END MATERIAL LIST

// Here, there's either a Plane Section or an Atomic Section.

// PLANE SECTION
int32 0x0A // section identifier
int32 // section size
int32 0x1400FFFF

// PLANE STRUCT
int32 0x01 // section identifier
int32 // section size
int32 0x1400FFFF
int32 type
int32 value
bool32 leftIsAtomic
bool32 rightIsAtomic
float32 leftValue
float32 rightValue
// END PLANE STRUCT

// Plane Sections contain two sub sections (left and right), each which can be either an Atomic Section (which contains model data) or another Plane Section. They are located here.

// END PLANE SECTION

// ATOMIC SECTION
int32 0x09 // section identifier
int32 // section size
int32 0x1400FFFF

// ATOMIC STRUCT
int32 0x01 // section identifier
int32 // section size
int32 0x1400FFFF
int32 // model flags (usually 0x00)
int32 // number of triangles (numTriangles)
int32 // number of vertices (numVertices)
float32[3] // Boundary box maximum
float32[3] // Boundary box minimum // These last 4 values are the same ones in the model header
84 D9 50 2F // always this, unknown
int32 0x00 // unknown, always 0x00
numVertices*float32[3] // X, Y, Z position coordinate for each vertex
numVertices*int8[4] // RGBA vertex color for each vertex; In Final Fortress, used for lightning effect normals
numVertices*float32[2] // U, V texture mapping coordinate for each vertex
numTriangles*int16[4] // (materialIndex, vertex1, vertex2, vertex3) index for each triangle, culling is counterclockwise

// END ATOMIC STRUCT

// ATOMIC EXTENSION
int32 0x03 // section identifier
int32 // section size
int32 0x1400FFFF

// BIN MESH PLG
int32 0x50E // section identifier
int32 // section size
int32 0x1400FFFF
uint32 // flags (0 = triangle lists, 1 = triangle strips)
uint32 // number of objects/meshes (numMeshes; usually same number of materials)
uint32 // total number of indices
numMeshes*(
    uint32 // number of vertex indices in this mesh (numIndices)
    uint32 // material index
    uint32[numIndices] // vertex indices
)

// END BIN MESH PLG

// END ATOMIC EXTENSION

// END ATOMIC SECTION

// WORLD EXTENSION // this section does absolutely nothing
int32 0x03 // section identifier
int32 // section size (0x00)
int32 0x1400FFFF

// END WORLD EXTENSION

// END WORLD

Texture Struct Settings

Texture filtering modes (unsure if all of them work in SH)
  • 0 - FILTERNAFILTERMODE (filtering is disabled)
  • 1 - FILTERNEAREST (Point sampled)
  • 2 - FILTERLINEAR (Bilinear)
  • 3 - FILTERMIPNEAREST (Point sampled per pixel mipmap)
  • 4 - FILTERMIPLINEAR (Bilinear per pixel mipmap)
  • 5 - FILTERLINEARMIPNEAREST (Mipmap interp point sampled)
  • 6 - FILTERLINEARMIPLINEAR (Trilinear)
Texture addressing modes (unsure if all of them work in SH)
  • 0 - TEXTUREADDRESSNATEXTUREADDRESS (no tiling)
  • 1 - TEXTUREADDRESSWRAP (tile in U or V direction)
  • 2 - TEXTUREADDRESSMIRROR (mirror in U or V direction)
  • 3 - TEXTUREADDRESSCLAMP
  • 4 - TEXTUREADDRESSBORDER
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