FANDOM


Ian
Modified Content

This article is about modified content. Therefore, it does not reflect upon the standard game and is non-canon.

DisclaimerEdit

This file type's reverse-engineering is currently ongoing. The author (InkySka) has no experience in this, hence any help is appreciated.

Tools Edit

To open and convert .mdb files check this repository.

Meshes and data types - a digressionEdit

Mesh filesEdit

All game objects are meshes. A mesh is a "structure" that provides information on how to represent a particular object.

Treasure Planet: Battle at Procyon stores its meshes in files whose extension is .mdb, which makes them unreadable by specialised applications such as Blender, 3D Studio Max, Maya, etc.

A mesh file is a binary file. This means that its content is not readable by a human (except for a few segments which I will talk about later). Binary files contain a sequence of bytes, made up of 8 bits each. The way we read those bits is very important, in that the same sequence of bits can either represent an integer number, a floating point number, etc.

"Primitive" data typesEdit

Here I will briefly describe some data types we can find in mesh files, so that the reader can understand their structure better.

CharEdit

  • Length: 1 byte (8 bits)
  • Unsigned: supports positive values only

ShortEdit

  • Length: 2 bytes (16 bits)
  • Can be either signed (supports positive and negative values) or unsigned (only supports positive values)

IntEdit

  • Length: 4 bytes (32 bits)
  • Can be either signed (supports positive and negative values) or unsigned (only supports positive values)

FloatEdit

  • Length: 4 bytes (32 bits)
  • Signed: supports both positive and negative values

Compound data types - structuresEdit

It is possible to create new data types that contain "primitive" data types. For example, to keep my file (and my application) tidy, I could create the structure Vertex which would contain three variables: x, y, z. A vertex does in fact need those three values to exist.

struct vertex
 
{
 
 float x;
 
 float y;
 
 float z;
 
};

I will make use of structures in my explaination, for the sake of readability.

The structure Edit

This is roughly the structure:

HeaderEdit

  • int file_structure_offset (4 bytes). There are some human-readable strings at the end of the file, which seem to represent its structure. This value is the offset at which they begin
  • unknown (4 bytes)
  • uint last_four_bytes_before_strings_offset (4 bytes)
  • uint mesh_type (4 bytes) (number of meshes actually stored in the file)
  • uint end_of_first_vertex_mesh_data_offset (4 bytes)

Separator (apparently) Edit

  • int separator (4 bytes) (equals 0x0)

Vertex data (as many as mesh_type)Edit

  • int number_of_vertices (4 bytes)
  • vertex vertex_data (usually 36 bytes in total). There are as many structures as this as number_of_vertices
    • int sizeof_vertex_data (4 bytes). Usually equal to 32 (excluded from the count).
    • float x (4 bytes)
    • float y (4 bytes)
    • float z (4 bytes)
    • float vt_u (4 bytes) (texture coordinates)
    • float vt_v (4 bytes) (texture coordinates) (pivoted. pivot: 0.5. [1])
    • unknown (remaining bytes - usually 8)
    • float transparence (4 bytes) (the vertex's transparence)

This means that the actual vertex data (excluding sizeof_vertex_data and end_of_vertex_data) can be anywhere from 28 to 31 bytes, depending on whether end_of_vertex_data occupies 4 bytes or less. 

Face data (as many as mesh_type)Edit

  • int number_of_faces (4 bytes)
  • face faces_data (usually 12 bytes in total).
    • int sizeof_face_data (4 bytes). Usually equal to 8 (excluded from the count). 
    • short vertex1 (2 bytes) (array, but clearer if written this way) 
    • short vertex2 (2 bytes) 
    • short vertex3 (2 bytes) 
    • short material_id (2 bytes) 

Separator (apparently)Edit

  • int separator (4 bytes) (equals 0x0)
  • IF (mesh_type > 1 AND mesh_n < mesh_type) (a.k.a. in files that have more meshes inside, the "central ones" have an additional 8 bytes, meaning that the first and the last one lack them)
  • THEN
    • uint end_of_vertex_mesh_data_offset (4 bytes)
    • uint submesh_id (4 bytes)

Animation data (in some cases) Edit

  • Work in progress...

Material/texture dataEdit

  • int number_of_textures (4 bytes)
  • textureData texture_data (variable)
    • int sizeof_texture_data (4 bytes) (excluded from the count).
    • int sizeof_string (4 bytes)
    • c_string texture_name (variable) (seemingly not null-terminated) (textures have .tga extension here)
    • unknown (remaining texture data - usually composed by 1s (0x0000803F with something at the end)

Separator (apparently) Edit

  • int separator (4 bytes) (equals 0x0)

Bounding box data Edit

  • float x (4 bytes)
  • float y (4 bytes)
  • float z (4 bytes)
  • float max_x (4 bytes)
  • float max_y (4 bytes)
  • float max_z (4 bytes)

Stuff Edit

  • (16 bytes)
  • uint last_byte_before_four_bytes_before_strings_offset (4 bytes) (in practice points to one byte before last_four_bytes_before_strings_offset) ???

OffsetsEdit

The very last section of each file. It is composed by human-readable strings, which are not null-terminated.

These strings seem to represent the file's structure, but there are seemingly no pointers or offset values that tell the program where the data actually is.

Notes Edit

  1. The Author does not actually know if this is proper term. The value is plotted by "pivoting" it, with pivot 0.5. This means that if the hex data reads 1, the actual value will be 0. If the hex data reads 1.5, the actual value will be -0,5. pivoted_num = 2*pivot - original_num.