EMD (Resident Evil 1997)
This content was first retrieved from the Internet Archive's Wayback Machine for the date 2016-08-09 from the following URL: https://web.archive.org/web/20160809012215/http://rewiki.regengedanken.de/wiki/.EMD_(Resident_Evil)
The .EMD file format is used by Resident Evil. It contains the description of 3D models of the game (enemies, player, etc...).
Contents |
Structure
The values are stored in Little-Endian order.
Directory
There is a directory, which is stored at the end of the file, it contains 4 offsets. So its position is filesize-4*4 bytes.
File/Section 0, skeleton
This section starts with a header:
typedef struct {
unsigned short relpos_offset;/* Relative offset to emd1_skel_relpos[] array */
unsigned short length; /* Relative offset to emd1_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 emd1_skel_data[] array */
} emd1_skel_header_t;
If offset is more than 8, there are some extra stuff, namely data1,data2 and mesh arrays.
typedef struct {
short x;
short y;
short z;
} emd1_skel_relpos_t; /* Relative position of each mesh in the object */
typedef struct {
unsigned short mesh_count; /* Number of meshes linked to this one */
unsigned short offset; /* Relative offset to mesh numbers (emd1_skel_mesh[] array) */
} emd1_skel_armature_t;
emd1_skel_relpos_t emd1_skel_relpos[count];
emd1_skel_armature_t emd1_skel_armature[count];
unsigned char emd1_skel_mesh[count]; /* Mesh number on which to apply relative position */
Finally an array of elements which have a size of emd1_skel_header.size bytes each.
typedef struct {
short x_offset; /* distance from reference point */
short y_offset;
short z_offset;
short x_speed; /* speed at which moving the model */
short y_speed;
short z_speed;
short angles[3*15]; /* angle for each bone/model around x,y,z axis */
short unknown;
} emd1_skel_anim_t;
emd1_skel_anim_t emd1_skel_anim[];
File/Section 1, animation steps
This section starts with this header, a certain number of records composed of count and offsets.
typedef struct {
unsigned short count; /* Count of indices to process from emd_sec1_data[] array */
unsigned short offset; /* Byte offset to first index in emd_sec1_data[] array */
} emd_anim_header_t;
emd_anim_header_t emd_anim_header[];
Following this array, you'll find another array of unsigned long. Each value (animation frame number?) is an index in emd_sec2_data array in the skeleton section.
unsigned long emd_anim_skel_t[]; /* Bits 31-16: Bitmasks for flags */
/* Bits 15-0: Number of frame to display ? */
Then you'll finally find the 'unsigned long' byte length of the section.
unsigned long length;
File/Section 2, meshes
The last object holds the 3D stuff. Maybe the rest of the file is use to store animations, and links between primitives.
Header
typedef struct {
unsigned long length; /* Section length in bytes */
unsigned long unknown;
unsigned long obj_count; /* Number of objects in model */
} emd_model_header_t;
Objects
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 {
emd_model_triangles_t triangles;
} emd_model_object_t;
typedef struct {
unsigned long vertex_offset; /* Offset to vertex data, array of emd_vertex_t */
unsigned long vertex_count; /* Vertex count */
unsigned long normal_offset; /* Offset to normal data, array of emd_vertex_t */
unsigned long normal_count; /* Normal count */
unsigned long tri_offset; /* Offset to triangle data, array of emd_triangle_t */
unsigned long tri_count; /* Triangle count */
unsigned long dummy;
} emd_model_triangles_t;
Index arrays
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:
typedef struct {
unsigned long unknown; /* id 0x34000609 */
unsigned char tu0; /* u,v texture coordinates of vertex 0 */
unsigned char tv0;
unsigned short clutid; /* Texture clut id, bits 0-5 */
unsigned char tu1;
unsigned char tv1;
unsigned short page; /* Texture page */
unsigned char tu2;
unsigned char tv2;
unsigned short dummy;
unsigned short n0; /* Index of normal data for vertex 0 */
unsigned short v0; /* Index of vertex data for vertex 0 */
unsigned short n1;
unsigned short v1;
unsigned short n2;
unsigned short v2;
} emd_triangle_t; /* Triangle */
File/Section 3, texture
And finally, an embedded TIM image, which is the texture to apply to the model.