Changes

Jump to navigation Jump to search
1,083 bytes added ,  23:36, 25 June 2017
→‎Reading the body: Detailed description of the function "ReadNode"
Line 76: Line 76:  
     {
 
     {
 
         chunkID = ReadUInt32();
 
         chunkID = ReadUInt32();
         if (chunkID == 0xFACADE01)
+
         if (chunkID == 0xFACADE01) // no more chunks
 +
        {
 +
            OnNodLoaded();
 
             return;
 
             return;
 +
        }
 
   
 
   
 
         chunkFlags = GetChunkInfo(chunkID);
 
         chunkFlags = GetChunkInfo(chunkID);
         if (chunkFlags & 0x10)
+
 +
         if (chunkFlags == 0xFACADE01 || (chunkFlags & 0x11) == 0x10)
 
         {
 
         {
 
             skip = ReadUInt32();
 
             skip = ReadUInt32();
 +
            if (skip != 0x534B4950) // "SKIP"
 +
            {
 +
                OnNodLoaded();
 +
                return;
 +
            }
 +
 
             chunkDataSize = ReadUInt32();
 
             chunkDataSize = ReadUInt32();
 +
            SkipData(chunkDataSize); // skip unknown or obsolete chunk
 
         }
 
         }
 
   
 
   
         ReadChunk(chunkID);
+
         if (chunkFlags != 0xFACADE01 && (chunkFlags & 0x11) != 0x10)
 +
        {
 +
            if (chunkFlags & 0x10) // skippable
 +
            {
 +
                skip = ReadUInt32();          // unused
 +
                chunkDataSize = ReadUInt32(); // unused
 +
            }
 +
 +
            ReadChunk(chunkID); // read the chunk
 +
        }
 
     }
 
     }
 
  }
 
  }
   −
GetChunkInfo() doesn't read anything from the file; it provides loading flags for the specified chunk ID. The only important flag is whether or not the chunk is "skippable". If it is, the chunk ID is followed by an uint32 0x50494B53 ("SKIP", shows up as "PIKS" in the file due to little-endian ordering) and an uint32 specifying the size of the chunk data. This allows older versions of TrackMania that don't know how to parse this chunk ID to skip over the chunk data and go to the next chunk. If the chunk is not skippable, the chunk data follows immediately after the chunk ID.
+
The code 0xFACADE01 is used here for two different purposes. As a dummy chunk ID (read from the file), it signifies the end of the chunk list for the current class. As a flag (returned by the function GetChunkInfo), it signifies that the passed chunk ID is unknown. GetChunkInfo() doesn't read anything from the file; it provides loading flags for the specified chunk ID. The flag 0x01 indicates that the chunk must be read. If this flag is not set, the chunk can be skipped (if possible). The second important flag is 0x10 and indicates whether the chunk is "skippable" or not. If it is, the chunk ID is followed by an uint32 0x50494B53 ("SKIP", shows up as "PIKS" in the file due to little-endian ordering) and an uint32 specifying the size of the chunk data. This allows older versions of TrackMania that don't know how to parse this chunk ID to skip over the chunk data and go to the next chunk. If the chunk is not skippable, the chunk data follows immediately after the chunk ID.
   −
A dummy chunk ID of 0xFACADE01 signifies the end of the chunk list for the current class.
+
The function OnNodLoaded() is used by some classes to prepare the read data (e.g., to make them compatible with newer versions of the engine).
    
Chunk data is not self-describing; the program itself has to know how to read each one. In fact, if your program doesn't know a specific chunk ID and the chunk is not skippable, you can't even tell how long the chunk is.
 
Chunk data is not self-describing; the program itself has to know how to read each one. In fact, if your program doesn't know a specific chunk ID and the chunk is not skippable, you can't even tell how long the chunk is.

Navigation menu