-
Notifications
You must be signed in to change notification settings - Fork 9
.EMD (Resident Evil 3)
The .EMD file format is used by Resident Evil 3. It contains the description of 3D models of the game (enemies, player, etc...).
The values are stored in Little-Endian order.
The start of the file holds offset and count to a directory:
typedef struct { unsigned long dir_offset; /* Offset to directory */ unsigned long dir_count; /* Number of objects in directory */ } emd_header_t;
The directory is an array of 'unsigned long' offsets to small parts (files), and often resides at the end of the EMD file. Each file in the directory seems to have a specific purpose.
Unknown data.
Unknown data.
This section starts with this header, a certain number of records composed of count and offsets.
emd3_anim_header_t emd3_anim_header[];
Following this array, you'll find another array of unsigned short. Each value (animation frame number?) is an index in the skeleton section.
unsigned short emd3_anim_skel[]; /* Bits 15-8: flags */ /* Bits 7-0: Number of frame to display */
This section starts with a header:
typedef struct { unsigned short relpos_offset;/* Relative offset to emd_skel_relpos[] array */ unsigned short length; /* Relative offset to emd_skel_data[] array, which is also length of relpos+armature+mesh numbers */ unsigned short count; /* Number of objects in relpos,data2,mesh arrays? */ unsigned short size; /* Size of each element in emd_skel_data[] array */ } emd3_skel_header_t;
If offset is more than 8, there are some extra stuff, namely data1,data2 and mesh arrays.
typedef struct { unsigned short mesh_count; /* Number of meshes linked to this one */ unsigned short offset; /* Relative offset to mesh numbers (emc_sec2_mesh[] array) */ } emd3_skel_armature_t; emd3_skel_relpos_t emd3_skel_relpos[count]; emd3_skel_armature_t emd3_skel_armature[count]; unsigned char emd3_skel_mesh[count]; /* Mesh number on which to apply relative position */
Finally an array of elements which have the size specified in the emd3_skel_header.size each.
typedef struct { short x_speed; /* speed at which moving the model */ short y_speed; short z_speed; short y_offset; /* distance from reference point */ unsigned short angles[]; } emd3_skel_anim_data_t; emd3_skel_anim_t emd3_skel_data[];
Same format as section 2.
Same format as section 3.
Same format as section 2.
Same format as section 3.
Unknown data.
Unknown data.
Unknown data.
Unknown data.
Unknown data.
Same format as section 14.
The last object holds the 3D stuff. Maybe the rest of the file is use to store animations, and links between primitives.
The header is different than for RE2.
typedef struct { unsigned long length; /* Section length in bytes */ unsigned long obj_count; /* Number of objects in model */ } emd_model_header_t;
The model is separated in 'obj_count' objects. Following the header is the description of each object, in the form of an array of 'model_object'. Each offset is relative to the first emd_model_object_t.
typedef struct { unsigned short vtx_offset; /* Offset to vertex data */ unsigned short unknown0; unsigned short nor_offset; /* Offset to normal vertex data */ unsigned short unknown1; unsigned short vtx_count; /* Number of vertices */ unsigned short unknown2; unsigned short tri_offset; /* Offset to triangle data */ unsigned short unknown3; unsigned short quad_offset; /* Offset to quad data */ unsigned short unknown4; unsigned short tri_count; /* Number of triangles */ unsigned short quad_count; /* Number of quads */ } emd_model_object_t;
Beware, sometimes tri_count is set to tri_offset and quad_offset. Just assume tri_count = 0 in this case. Or in some models, you have quad_count > 256 (much higher than what is really present). Just assume quad_count = 0 in this case.
Normal and vertex coordinates are saved in same format:
typedef struct { signed short x; /* Coordinates */ signed short y; signed short z; signed short zero; } emd_vertex_t; /* Normals have same format */
A triangle is stored in this format:
unsigned char tu1,tv1; /* u,v texture coordinates of vertex 1 */ unsigned char dummy2,v0; /* v0: index for vertex and normal 0 */ unsigned char tu2,tv2; /* u,v texture coordinates of vertex 2 */ unsigned char v1,v2; /* v1,v2: index for vertex and normal 1,2 */ } emd_triangle_t; /* Triangle */
A quad is stored in this format:
unsigned char tu1,tv1; /* u,v texture coordinates of vertex 1 */ unsigned char dummy2,dummy3; unsigned char tu2,tv2; /* u,v texture coordinates of vertex 2 */ unsigned char v0,v1; /* v0,v1: index for vertex and normal 0,1 */ unsigned char tu3,tv3; /* u,v texture coordinates of vertex 2 */ unsigned char v2,v3; /* v2,v3: index for vertex and normal 2,3 */ } emd_quad_t; /* Quad */
NOTE: For rendering, must be drawn in order v0,v1,v3,v2