Changes

Jump to navigation Jump to search
731 bytes added ,  23:10, 10 July 2017
Added references to the actual member functions of the game engine
Line 6: Line 6:  
A .gbx file more specifically stores the serialization of one or more class instances. There is one main instance, and optionally a number of auxiliary instances.
 
A .gbx file more specifically stores the serialization of one or more class instances. There is one main instance, and optionally a number of auxiliary instances.
   −
The serializable classes are organized into 16 ''engines''. Each class is also subdivided into ''chunks''. A class is then not serialized in one go, but rather as a series of chunks. This allows Nadeo to easily extend classes in new TrackMania versions: instead of having to define a new class they can simply add more chunks to an existing one, and have older versions ignore these new chunk types.
+
The serializable classes are organized into ''engines''. Each class is also subdivided into ''chunks''. A class is then not serialized in one go, but rather as a series of chunks. This allows Nadeo to easily extend classes in new TrackMania versions: instead of having to define a new class they can simply add more chunks to an existing one, and have older versions ignore these new chunk types.
    
The data in a .gbx file follows the pattern {{c|<chunk ID> <chunk data>}}. A ''chunk ID'' is a 32-bit number that identifies the engine, the class, and the chunk in that class. If you for example see the bytes <code>07 30 04 03</code> in the file, that would correspond to the integer 0x03043007, and be interpreted as follows:
 
The data in a .gbx file follows the pattern {{c|<chunk ID> <chunk data>}}. A ''chunk ID'' is a 32-bit number that identifies the engine, the class, and the chunk in that class. If you for example see the bytes <code>07 30 04 03</code> in the file, that would correspond to the integer 0x03043007, and be interpreted as follows:
Line 71: Line 71:  
The file body contains further chunks of the main class instance, and may also contain auxiliary class instances. Reading the body is started by creating an in-memory instance of the class corresponding to the main class ID (instances are called ''nodes'' internally), and calling ReadNode on it:
 
The file body contains further chunks of the main class instance, and may also contain auxiliary class instances. Reading the body is started by creating an in-memory instance of the class corresponding to the main class ID (instances are called ''nodes'' internally), and calling ReadNode on it:
   −
  ReadNode()
+
  ReadNode()<ref>[[ManiaPlanet_internals#Object_system|CMwNod::Archive]]</ref>
 
  {
 
  {
 
     while (true)
 
     while (true)
 
     {
 
     {
         chunkID = ReadUInt32();
+
         chunkID = ReadUInt32();<ref>[[ManiaPlanet_internals#CClassicArchive|CClassicArchive::ReadNat32]]</ref>
 
         if (chunkID == 0xFACADE01) // no more chunks
 
         if (chunkID == 0xFACADE01) // no more chunks
 
         {
 
         {
             OnNodLoaded();
+
             OnNodLoaded();<ref>[[ManiaPlanet_internals#Object_system|CMwNod::OnNodLoaded]]</ref>
 
             return;
 
             return;
 
         }
 
         }
 
   
 
   
         chunkFlags = GetChunkInfo(chunkID);
+
         chunkFlags = GetChunkInfo(chunkID);<ref>[[ManiaPlanet_internals#Object_system|CMwNod::GetChunkInfo]]</ref>
 
   
 
   
 
         if (chunkFlags == 0xFACADE01 || (chunkFlags & 0x11) == 0x10)
 
         if (chunkFlags == 0xFACADE01 || (chunkFlags & 0x11) == 0x10)
Line 94: Line 94:  
   
 
   
 
             chunkDataSize = ReadUInt32();
 
             chunkDataSize = ReadUInt32();
             SkipData(chunkDataSize); // skip unknown or obsolete chunk
+
             SkipData(chunkDataSize);<ref>[[ManiaPlanet_internals#CClassicArchive|CClassicArchive::SkipData]]</ref> // skip unknown or obsolete chunk
 
         }
 
         }
 
   
 
   
Line 105: Line 105:  
             }
 
             }
 
   
 
   
             ReadChunk(chunkID); // read the chunk
+
             ReadChunk(chunkID);<ref>[[ManiaPlanet_internals#Object_system|CMwNod::Chunk]]</ref> // read the chunk
 
         }
 
         }
 
     }
 
     }
Line 123: Line 123:  
* '''byte''', '''uint16''', '''int32''', '''uint32''', '''uint64''', '''uint128''', '''float''': regular little-endian encoding.
 
* '''byte''', '''uint16''', '''int32''', '''uint32''', '''uint64''', '''uint128''', '''float''': regular little-endian encoding.
   −
* '''vec2D''':
+
* '''vec2''':
 
** float x
 
** float x
 
** float y
 
** float y
   −
* '''vec3D''':
+
* '''vec3''':
 
** float x
 
** float x
 
** float y
 
** float y
Line 141: Line 141:  
** byte chars[length] ({{wp|UTF-8}}, older files sometimes with {{wp|Byte order mark|BOM}}, not zero-terminated)
 
** byte chars[length] ({{wp|UTF-8}}, older files sometimes with {{wp|Byte order mark|BOM}}, not zero-terminated)
   −
* '''lookbackstring''': a form of compression which allows to avoid repeating the same string multiple times. Every time a new string is encountered, it is added to a string list, and from then on this list entry is referenced instead of repeating the string another time.
+
* '''lookbackstring''':<ref>[[ManiaPlanet_internals#Id|CMwId::Archive]]</ref> a form of compression which allows to avoid repeating the same string multiple times. Every time a new string is encountered, it is added to a string list, and from then on this list entry is referenced instead of repeating the string another time.
 
** if this is the first lookback string encountered:
 
** if this is the first lookback string encountered:
 
*** uint32 version (currently 3)
 
*** uint32 version (currently 3)
Line 152: Line 152:  
''Note'': Virtual Skipper 2 uses version 2 of the lookback strings. In this version, the string is always stored, the index always contains the position within the global name table, and the field with the version is also always present.
 
''Note'': Virtual Skipper 2 uses version 2 of the lookback strings. In this version, the string is always stored, the index always contains the position within the global name table, and the field with the version is also always present.
   −
* '''fileref''': path to an external file, e.g. a skin.
+
* '''meta''':<ref>[[ManiaPlanet_internals#Identifier|SGameCtnIdentifier::Archive]]</ref> contains [[ManiaPlanet_internals#Identifier|meta]] information like the track environment, time of day, and author.
 +
** lookbackstring id
 +
** lookbackstring collection
 +
** lookbackstring author
 +
 
 +
* '''fileref''':<ref>CSystemPackManager::ArchivePackDesc</ref> path to an external file, e.g. a skin.
 
** byte version (currently 3)
 
** byte version (currently 3)
 
** if version >= 3:
 
** if version >= 3:
Line 160: Line 165:  
*** string locatorUrl
 
*** string locatorUrl
   −
* '''meta''': contains [[ManiaPlanet_internals#Identifier|meta]] information like the track environment, time of day, and author.
+
* '''noderef''':<ref>[[ManiaPlanet_internals#CSystemArchiveNod|CSystemArchiveNod::DoNodPtr]]</ref> a reference to an auxiliary class instance.
** lookbackstring field1
  −
** lookbackstring field2
  −
** lookbackstring author
  −
 
  −
* '''noderef''': a reference to an auxiliary class instance.
   
** uint32 index. if this is -1, the node reference is empty (null).
 
** uint32 index. if this is -1, the node reference is empty (null).
 
** if the index is >= 0 and the node at the index has not been read yet:
 
** if the index is >= 0 and the node at the index has not been read yet:
Line 217: Line 217:  
             5: (old)Rounds, 6: InProgress, 7: Campaign, 8: Multi, 9: Solo, 10: Site, 11: SoloNadeo, 12: MultiNadeo)
 
             5: (old)Rounds, 6: InProgress, 7: Campaign, 8: Multi, 9: Solo, 10: Site, 11: SoloNadeo, 12: MultiNadeo)
 
  if version >= 1:
 
  if version >= 1:
     bool locked (used by Virtual Skipper to lock the map parameter)
+
     bool locked (used by Virtual Skipper to lock the map parameters)
 
     string password (weak xor encryption, no longer used in newer track files; see 03043029)
 
     string password (weak xor encryption, no longer used in newer track files; see 03043029)
 
     if version >= 2:
 
     if version >= 2:
 
         meta decoration (timeOfDay, environment, envirAuthor) (decoration envir can be different than collection envir)
 
         meta decoration (timeOfDay, environment, envirAuthor) (decoration envir can be different than collection envir)
 
         if version >= 3:
 
         if version >= 3:
             vec2D mapOrigin
+
             vec2 mapOrigin
 
             if version >= 4:
 
             if version >= 4:
                 vec2D mapTarget
+
                 vec2 mapTarget
 
                 if version >= 5:
 
                 if version >= 5:
 
                     uint128
 
                     uint128
Line 339: Line 339:  
 
 
'''03043025'''
 
'''03043025'''
  vec2D mapCoordOrigin
+
  vec2 mapCoordOrigin
  vec2D mapCoordTarget
+
  vec2 mapCoordTarget
 
 
 
'''03043026'''
 
'''03043026'''
Line 349: Line 349:  
  if archiveGmCamVal:
 
  if archiveGmCamVal:
 
     byte
 
     byte
     GmMat3 (vec3D x 3)
+
     GmMat3 (vec3 x 3)
     vec3D
+
     vec3
 
     float
 
     float
 
     float
 
     float
Line 751: Line 751:     
A sample record looks as follows:
 
A sample record looks as follows:
  vec3D position
+
  vec3 position
 
  uint16 angle      (0..0xFFFF -> 0..pi)
 
  uint16 angle      (0..0xFFFF -> 0..pi)
 
  int16 axisHeading (-0x8000..0x7FFF -> -pi..pi)
 
  int16 axisHeading (-0x8000..0x7FFF -> -pi..pi)
Line 936: Line 936:     
'''0301C012'''
 
'''0301C012'''
  vec3D groundPoint
+
  vec3 groundPoint
 
  float painterGroundMargin
 
  float painterGroundMargin
 
  float orbitalCenterHeightFromGround
 
  float orbitalCenterHeightFromGround
Line 943: Line 943:     
'''301C013'''
 
'''301C013'''
  nodref audioEnvironmentInCar (CPlugAudioEnvironment; used for cars)
+
  noderef audioEnvironmentInCar (CPlugAudioEnvironment; used for cars)
    
'''301C014'''
 
'''301C014'''
Line 964: Line 964:  
'''0301C019'''
 
'''0301C019'''
 
  int version
 
  int version
  nodref phyModel                 // CPlugSurface
+
  noderef phyModel               // CPlugSurface
  nodref visModel                 // CPlugSurface
+
  noderef visModel               // CPlugSurface
 
  if version >= 1:
 
  if version >= 1:
     nodref visModelStatic       // CPlugSolid2Model
+
     noderef visModelStatic     // CPlugSolid2Model
    
===CGameCtnDecoration (03 038 000)===
 
===CGameCtnDecoration (03 038 000)===
Line 1,069: Line 1,069:  
  for each number:
 
  for each number:
 
     string dirName
 
     string dirName
 +
 +
== References to the actual functions ==
 +
<references />
    
== Applications and Libraries that can inspect/modify the file format ==
 
== Applications and Libraries that can inspect/modify the file format ==

Navigation menu