Compiled Resident Evil Outbreak Research
Oct 10, 2020 15:48:26 GMT 10
EvilLord, Adngel, and 5 more like this
Post by Wakka387 on Oct 10, 2020 15:48:26 GMT 10
For a while, both Fothsid & D-Chaps have been reverse engineering Resident Evil Outbreak and documenting the different files that permeate the game.
Here is a post compiling all that research into a single thread, in case others are interested in joining in.
D-Chaps 3DS Max scripts for Outbreak (Skeleton Importer)
AMO Model Format Research & Decomp by Fothsid (shown in spoiler below)
Here is also an example of a "concept" third person camera hack for Outbreak
Hopefully with more help & awareness, we can be closer to the goal of a model importer (allowing modders to replace the ingame models with their own) and open up the full potential of the long forgotten game
Here is a post compiling all that research into a single thread, in case others are interested in joining in.
D-Chaps 3DS Max scripts for Outbreak (Skeleton Importer)
AMO Model Format Research & Decomp by Fothsid (shown in spoiler below)
/*
AMO model file format, used in Resident Evil Outbreak and Resident Evil Outbreak File 2.
Reversed by Fothsid.
*/
namespace AMO
[
namespace ChunkType
[
enum
[
NonChunkData = 0x0000,
Start = 0x0001, /* size - size of the whole file */
MeshesBegin = 0x0002, /* count - total amount of meshes in the file */
Mesh = 0x0004,
IndicesStart = 0x0005, /* count - amount of chunks the indices are divided into */
MaterialInfoBegin = 0x0009,
TextureInfoBegin = 0x000A, /* Subchunks contain DataType::TextureInfo chunks. */
];
];
namespace DataType
[
enum
[
TextureInfo = 0x0000, /* TextureInfo struct below. */
Unknown1 = 0x0002, /* apparently always contains either 0x2041700 or 0x2040200, some kind of version value perhaps? */
IndicesData1 = 0x0003, /* Look at (struct TriangleStrip) below */
IndicesData2 = 0x0004, /* Indices are divided into two chunks sometimes apparently. */
MaterialIdTable = 0x0005, /* Table that contains ids for used materials in the mesh. */
MaterialIds = 0x0006, /* Contains material ids for each triangle strip. (actual material id is in the MaterialIdTable chunk) */
PositionData = 0x0007, /* 3 floats per vertex - XYZ; count - amount of vertices */
NormalData = 0x0008, /* 3 floats per vertex - XYZ; count - amount of vertices */
TexCoordData = 0x000A, /* 2 floats per vertex - XY; count - amount of vertices */
ColorData = 0x000B, /* 4 floats's per vertex in 0-255 range. Rooms have backed lighting, characters mostly have (0, 0, 0, 255) colors */
WeightData = 0x000C, /* Look at (struct Weight) below */
RenderStates = 0x000F, /* RenderStates struct below. */
JointIdTable = 0x0010, /* Table that contains used joint ids in the mesh. */
MaterialInfo1 = 0x0012, /* MaterialInfo struct below. */
MaterialInfo2 = 0x0013, /* MaterialInfo struct below. */
];
];
/* Chunk notes: */
/*
(for each strip)
struct TriangleStrip
[
uint32_t indexCount; // Warning: sometimes the last bit of the count value
uint32_t indices[indexCount];
];
(for each vertex)
struct Weight [
uint32_t usedJointCount;
struct [
uint32_t jointId; // JointIdTable[jointId] for an actual id
float weight; // in 0-100 range
] joints[jointCount];
];
*/
/*
* Okay, so uhh
* basically if chunkType isn't zero, then the data of that chunk contains more chunks,
* otherwise, dataType is used to determine the type of data in the chunk.
*/
/* Example of a structure of an AMO file (in chunks)
Start
- Unknown1
- MeshesBegin
- Mesh
- IndicesStart
- IndicesData1
- IndicesData2 (not always present)
- MaterialIdTable
- MaterialIds
- PositionData
- NormalData
- TexCoordData
- ColorData
- WeightData (present if it is a model of a character)
- JointIdTable (present if it is a model of a character)
- RenderStates (seems to be present only in room models)
- Mesh
- ...
- MaterialInfoBegin
- MaterialInfo1 or MaterialInfo2
- ...
- TextureInfoBegin
- TextureInfo
- ...
*/
struct ChunkHeader
[
uint16_t chunkType;
uint16_t dataType;
uint32_t count;
uint32_t size;
uint8_t data[];
];
/* Used only in room models */
struct RenderStates
[
int32_t unk0;
int32_t unk1;
int32_t unk2;
int32_t unk3;
int32_t unk4;
int32_t unk5;
int32_t unk6;
int32_t unk7;
int32_t unk8;
int32_t unk9;
int32_t unk10;
int32_t unk11;
int32_t blending; /* Blending; 3 - alpha, 1 - additive */
int32_t unk13;
int32_t unk14;
int32_t writeDepth; /* Set to 1 if it is needed to write to the depth channel for this mesh */
int32_t unk16;
int32_t unk17;
];
struct MaterialInfo
[
/* Not sure about material values, but guessing it would be somewhat like that,
since the models were made in early versions of Wavefront Maya,
according to the videos on the official RE: Outbreak website. */
Vec4 ambient;
Vec4 diffuse;
Vec4 specular;
float shininess;
int32_t illumination;
uint32_t dummy0[50];
uint32_t textureInfoId;
];
struct TextureInfo
[
uint32_t textureId;
uint32_t textureWidth; /* WARNING: Not always matches the actual texture!!! The examples can be found in several rooms in the decisions, decisions scenario. */
uint32_t textureHeight; /* WARNING: Not always matches the actual texture!!! The examples can be found in several rooms in the decisions, decisions scenario. */
];
];
AMO model file format, used in Resident Evil Outbreak and Resident Evil Outbreak File 2.
Reversed by Fothsid.
*/
namespace AMO
[
namespace ChunkType
[
enum
[
NonChunkData = 0x0000,
Start = 0x0001, /* size - size of the whole file */
MeshesBegin = 0x0002, /* count - total amount of meshes in the file */
Mesh = 0x0004,
IndicesStart = 0x0005, /* count - amount of chunks the indices are divided into */
MaterialInfoBegin = 0x0009,
TextureInfoBegin = 0x000A, /* Subchunks contain DataType::TextureInfo chunks. */
];
];
namespace DataType
[
enum
[
TextureInfo = 0x0000, /* TextureInfo struct below. */
Unknown1 = 0x0002, /* apparently always contains either 0x2041700 or 0x2040200, some kind of version value perhaps? */
IndicesData1 = 0x0003, /* Look at (struct TriangleStrip) below */
IndicesData2 = 0x0004, /* Indices are divided into two chunks sometimes apparently. */
MaterialIdTable = 0x0005, /* Table that contains ids for used materials in the mesh. */
MaterialIds = 0x0006, /* Contains material ids for each triangle strip. (actual material id is in the MaterialIdTable chunk) */
PositionData = 0x0007, /* 3 floats per vertex - XYZ; count - amount of vertices */
NormalData = 0x0008, /* 3 floats per vertex - XYZ; count - amount of vertices */
TexCoordData = 0x000A, /* 2 floats per vertex - XY; count - amount of vertices */
ColorData = 0x000B, /* 4 floats's per vertex in 0-255 range. Rooms have backed lighting, characters mostly have (0, 0, 0, 255) colors */
WeightData = 0x000C, /* Look at (struct Weight) below */
RenderStates = 0x000F, /* RenderStates struct below. */
JointIdTable = 0x0010, /* Table that contains used joint ids in the mesh. */
MaterialInfo1 = 0x0012, /* MaterialInfo struct below. */
MaterialInfo2 = 0x0013, /* MaterialInfo struct below. */
];
];
/* Chunk notes: */
/*
(for each strip)
struct TriangleStrip
[
uint32_t indexCount; // Warning: sometimes the last bit of the count value
uint32_t indices[indexCount];
];
(for each vertex)
struct Weight [
uint32_t usedJointCount;
struct [
uint32_t jointId; // JointIdTable[jointId] for an actual id
float weight; // in 0-100 range
] joints[jointCount];
];
*/
/*
* Okay, so uhh
* basically if chunkType isn't zero, then the data of that chunk contains more chunks,
* otherwise, dataType is used to determine the type of data in the chunk.
*/
/* Example of a structure of an AMO file (in chunks)
Start
- Unknown1
- MeshesBegin
- Mesh
- IndicesStart
- IndicesData1
- IndicesData2 (not always present)
- MaterialIdTable
- MaterialIds
- PositionData
- NormalData
- TexCoordData
- ColorData
- WeightData (present if it is a model of a character)
- JointIdTable (present if it is a model of a character)
- RenderStates (seems to be present only in room models)
- Mesh
- ...
- MaterialInfoBegin
- MaterialInfo1 or MaterialInfo2
- ...
- TextureInfoBegin
- TextureInfo
- ...
*/
struct ChunkHeader
[
uint16_t chunkType;
uint16_t dataType;
uint32_t count;
uint32_t size;
uint8_t data[];
];
/* Used only in room models */
struct RenderStates
[
int32_t unk0;
int32_t unk1;
int32_t unk2;
int32_t unk3;
int32_t unk4;
int32_t unk5;
int32_t unk6;
int32_t unk7;
int32_t unk8;
int32_t unk9;
int32_t unk10;
int32_t unk11;
int32_t blending; /* Blending; 3 - alpha, 1 - additive */
int32_t unk13;
int32_t unk14;
int32_t writeDepth; /* Set to 1 if it is needed to write to the depth channel for this mesh */
int32_t unk16;
int32_t unk17;
];
struct MaterialInfo
[
/* Not sure about material values, but guessing it would be somewhat like that,
since the models were made in early versions of Wavefront Maya,
according to the videos on the official RE: Outbreak website. */
Vec4 ambient;
Vec4 diffuse;
Vec4 specular;
float shininess;
int32_t illumination;
uint32_t dummy0[50];
uint32_t textureInfoId;
];
struct TextureInfo
[
uint32_t textureId;
uint32_t textureWidth; /* WARNING: Not always matches the actual texture!!! The examples can be found in several rooms in the decisions, decisions scenario. */
uint32_t textureHeight; /* WARNING: Not always matches the actual texture!!! The examples can be found in several rooms in the decisions, decisions scenario. */
];
];
Here is also an example of a "concept" third person camera hack for Outbreak
Hopefully with more help & awareness, we can be closer to the goal of a model importer (allowing modders to replace the ingame models with their own) and open up the full potential of the long forgotten game
