We just moved to a different server. Please be patient until all files and pages are restored and the MediaWiki software has been updated. Thank you

.EMD (Resident Evil 3 PC)

From REWiki
Jump to: navigation, search

Contents

Games

The .EMD file format is used by Resident Evil 3. It contains the description of 3D models of the game (enemies, player, etc...).

Structure

The values are stored in Little-Endian order.

Directory

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.

File/section 0

Unknown data.

File/section 1

Unknown data.

File/section 2, animation steps

This section starts with this header, a certain number of records composed of count and offsets.

typedef struct {
	unsigned short count;  /* Number of animation steps */
	unsigned short offset; /* Byte offset to first index in emd3_anim_skel[] array */
	unsigned long unknown;
} emd3_anim_header_t;

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 */

File/section 3, skeleton

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 {
    short x;
    short y;
    short z;
} emd3_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 (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[];

File/section 4, animation steps

Same format as section 2.

File/section 5, skeleton

Same format as section 3.

File/section 6, animation steps

Same format as section 2.

File/section 7, skeleton

Same format as section 3.

File/section 8

Unknown data.

File/section 9

Unknown data.

File/section 10

Unknown data.

File/section 11

Unknown data.

File/section 12

Unknown data.

File/section 13, meshes

Same format as section 14.

File/section 14, meshes

The last object holds the 3D stuff. Maybe the rest of the file is use to store animations, and links between primitives.

Header

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;

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 {
    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.

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 char tu0,tv0; /* u,v texture coordinates of vertex 0 */
    unsigned char dummy0,dummy1;

    unsigned char tu1,tv1; /* u,v texture coordinates of vertex 1 */
    unsigned char dummy2,v0; /* v0: index for vertex 0 */

    unsigned char tu2,tv2; /* u,v texture coordinates of vertex 2 */
    unsigned char v1,v2; /* v1,v2: index for vertex 1,2 */
} emd_triangle_t; /* Triangle */

A quad is stored in this format:

typedef struct {
    unsigned char tu0,tv0; /* u,v texture coordinates of vertex 0 */
    unsigned char dummy0,dummy1;

    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 0,1 */

    unsigned char tu3,tv3; /* u,v texture coordinates of vertex 2 */
    unsigned char v2,v3; /* v2,v3: index for vertex 2,3 */
} emd_quad_t; /* Quad */
Personal tools