Skip to content

Commit

Permalink
add mod xE5, xE6
Browse files Browse the repository at this point in the history
  • Loading branch information
PredatorCZ committed Dec 9, 2023
1 parent 95b7659 commit b1b734b
Show file tree
Hide file tree
Showing 7 changed files with 299 additions and 34 deletions.
2 changes: 2 additions & 0 deletions include/revil/mod.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ enum MODVersion : uint16 {
X2CFF = 0x2CFF, // RE6 PS3
XC5 = 0xC5, // LP2 PC
XC3 = 0xC3, // LP2 PS3
XE5 = 0xE6,
XE6 = 0xE6,
};

struct alignas(8) MODMaker {
Expand Down
125 changes: 123 additions & 2 deletions src/mtf_mod/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1010,6 +1010,109 @@ std::map<uint32, MODVertices> formats{
TexCoord,
VertexTangent),
},
{
0xF606F017,
BuildVertices(
VertexPosition,
VertexNormalSigned,
V{F::FLOAT, D::R32G32, U::TextureCoordiante},
V{F::UINT, D::R8G8, U::BoneIndices},
V{F::UNORM, D::R8G8, U::BoneWeights},
VertexTangentSigned,
V{F::UINT, D::R8G8, U::BoneIndices},
V{F::UNORM, D::R8G8, U::BoneWeights}
),
},
{
0x01B36016,
BuildVertices(
VertexPosition,
VertexNormalSigned,
V{F::FLOAT, D::R32G32, U::TextureCoordiante},
V{F::UINT, D::R8G8, U::BoneIndices},
V{F::UNORM, D::R8G8, U::BoneWeights},
VertexTangentSigned, // always zero?
V{F::UINT, D::R8G8, U::BoneIndices},
V{F::UNORM, D::R8G8, U::BoneWeights}
),
},
{
0xD6784014,
BuildVertices(
VertexPosition,
VertexNormalSigned,
V{F::FLOAT, D::R32G32, U::TextureCoordiante},
V{F::UINT, D::R8G8, U::BoneIndices},
V{F::UNORM, D::R8G8, U::BoneWeights}
),
},
{
0x82917009,
BuildVertices(
VertexPosition,
VertexNormalSigned,
V{F::FLOAT, D::R32G32, U::TextureCoordiante}
),
},
{
0x59DC400B,
BuildVertices(
VertexPosition,
VertexNormalSigned,
V{F::FLOAT, D::R32G32, U::TextureCoordiante},
VertexTangentSigned
),
},
{
0x43FB3015,
BuildVertices(
VertexPosition,
VertexNormalSigned,
V{F::FLOAT, D::R32G32, U::TextureCoordiante},
V{F::UINT, D::R8G8, U::BoneIndices},
V{F::UNORM, D::R8G8, U::BoneWeights},
VertexTangentSigned
),
},
{
0x7BA7401B,
BuildVertices(
VertexPosition,
VertexNormalSigned,
V{F::FLOAT, D::R32G32, U::TextureCoordiante},
V{F::UINT, D::R8G8, U::BoneIndices},
V{F::UNORM, D::R8G8, U::BoneWeights},
VertexColor
),
},
{
0xAE252019,
BuildVertices(
VertexPosition,
VertexNormalSigned,
V{F::FLOAT, D::R32G32, U::TextureCoordiante},
V{F::UINT, D::R8G8, U::BoneIndices},
V{F::UNORM, D::R8G8, U::BoneWeights},
VertexTangentSigned,
V{F::UINT, D::R8G8, U::BoneIndices},
V{F::UNORM, D::R8G8, U::BoneWeights},
V{F::UINT, D::R8G8, U::BoneIndices},
V{F::UNORM, D::R8G8, U::BoneWeights},
V{F::UINT, D::R8G8, U::BoneIndices},
V{F::UNORM, D::R8G8, U::BoneWeights}
),
},
{
0x3D62B012,
BuildVertices(
VertexPosition,
VertexNormalSigned,
V{F::FLOAT, D::R32G32, U::TextureCoordiante},
VertexColor,
VertexTangentSigned, // always zero?
V{F::FLOAT, D::R32G32, U::TextureCoordiante}
),
},
};

// clang-format on
Expand Down Expand Up @@ -1072,10 +1175,10 @@ static const auto makeV2 = [](auto &self, revil::MODImpl &main, bool swap,
} else {
main.vertices.storage.emplace_back();

/*if (!edgeModels.contains(self.vertexFormat)) {
if (!edgeModels.contains(self.vertexFormat)) {
throw std::runtime_error("Unregistered vertex format: " +
std::to_string(self.vertexFormat));
}*/
}
}

uint16 *indexBuffer = reinterpret_cast<uint16 *>(
Expand Down Expand Up @@ -1251,6 +1354,24 @@ MODPrimitiveProxy MODMeshX06::ReflectLE(revil::MODImpl &main_) {
return retval;
}

MODPrimitiveProxy MODMeshXE5::ReflectBE(revil::MODImpl &main_) {
auto &main = static_cast<MODInner<MODTraitsXD2> &>(main_);
auto retval = makeV2(*this, main, true, [&](MODVertexDescriptor &d) {
swapBuffers(d, numVertices);
});
retval.skinIndex = numEnvelopes;

return retval;
}

MODPrimitiveProxy MODMeshXE5::ReflectLE(revil::MODImpl &main_) {
auto &main = static_cast<MODInner<MODTraitsXD2> &>(main_);
auto retval = makeV2(*this, main, false, [&](MODVertexDescriptor &) {});
retval.skinIndex = numEnvelopes;

return retval;
}

std::string MODPrimitiveProxy::Name() const { return name; }
size_t MODPrimitiveProxy::SkinIndex() const { return skinIndex; }
int64 MODPrimitiveProxy::LODIndex() const { return lodIndex; }
Expand Down
13 changes: 13 additions & 0 deletions src/mtf_mod/header.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,16 @@ struct MODHeaderX05 : MODHeaderCommon {
struct MODHeaderX06 : MODHeaderX05 {
uint64 dataEnd;
};

struct MODHeaderXE5 : MODHeaderCommon {
uint32 vertexBufferSize;
uint32 numTextures;
uint32 numGroups;
uint32 numSkins;
uint32 bones;
uint32 groups;
uint32 materials;
uint32 meshes;
uint32 vertexBuffer;
uint32 indices;
};
9 changes: 7 additions & 2 deletions src/mtf_mod/mesh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ struct MODMeshXC5 {
using Unk00 = BitMemberDecl<3, 5>;
using Unk01 = BitMemberDecl<4, 8>;
using VertexBufferStride = BitMemberDecl<5, 8>;
using PrimitiveType = BitMemberDecl<6, 5>;
using Unk02 = BitMemberDecl<7, 3>;
using PrimitiveType = BitMemberDecl<6, 6>;
using Unk02 = BitMemberDecl<7, 2>;
using BitField01 = BitFieldType<uint32, Visible, Flag0, Flag1, Unk00, Unk01,
VertexBufferStride, PrimitiveType, Unk02>;

Expand Down Expand Up @@ -165,3 +165,8 @@ struct MODMeshX06 : MODMeshXD2 {
MODPrimitiveProxy ReflectBE(revil::MODImpl &) { return {}; }
void NoSwap();
};

struct MODMeshXE5 : MODMeshXD2 {
MODPrimitiveProxy ReflectLE(revil::MODImpl &);
MODPrimitiveProxy ReflectBE(revil::MODImpl &);
};
80 changes: 77 additions & 3 deletions src/mtf_mod/serialize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,10 @@ template <> void FByteswapper(MODMetaDataV2 &self, bool) {
FByteswapper(self.numEnvelopes);
}

template <> void FByteswapper(MODSkinRemap<24> &self, bool) {
FByteswapper(self.count);
}

template <> void FByteswapper(MODSkinRemap<32> &self, bool) {
FByteswapper(self.count);
}
Expand Down Expand Up @@ -266,6 +270,20 @@ template <> void FByteswapper(MODHeaderX70 &self, bool) {
FByteswapper(self.indices);
}

template <> void FByteswapper(MODHeaderXE5 &self, bool) {
FByteswapper(static_cast<MODHeaderCommon &>(self));
FByteswapper(self.vertexBufferSize);
FByteswapper(self.numTextures);
FByteswapper(self.numGroups);
FByteswapper(self.numSkins);
FByteswapper(self.bones);
FByteswapper(self.groups);
FByteswapper(self.materials);
FByteswapper(self.meshes);
FByteswapper(self.vertexBuffer);
FByteswapper(self.indices);
}

template <> void FByteswapper(MODHeaderX170 &self, bool) {
FByteswapper(static_cast<MODHeaderCommon &>(self));
FByteswapper(self.vertexBufferSize);
Expand Down Expand Up @@ -431,6 +449,10 @@ template <> void FByteswapper(MODMeshXD2 &self, bool way) {
FByteswapper(self.unk);
}

template <> void FByteswapper(MODMeshXE5 &self, bool way) {
FByteswapper<MODMeshXD2>(self, way);
}

#pragma endregion
#pragma region Savers
void SaveMODX99(const MODInner<MODTraitsX99LE> &main, BinWritterRef wr) {
Expand Down Expand Up @@ -795,6 +817,11 @@ template <class Traits> MODImpl::ptr LoadMODXD2x32(BinReaderRef_e rd) {
rd.Read(main.bounds);
rd.Read(main.metadata);

if (header.bones <= 0x80) {
// UMVC3 PS3 uses unique model
throw std::runtime_error("Unsupported model format");
}

if (header.numBones) {
rd.Seek(header.bones);
rd.ReadContainer(main.bones, header.numBones);
Expand Down Expand Up @@ -837,8 +864,7 @@ template <class Traits> MODImpl::ptr LoadMODXD2x32(BinReaderRef_e rd) {
return std::make_unique<decltype(main)>(std::move(main));
}

template<class Traits>
MODImpl::ptr LoadMODXD3x64(BinReaderRef_e rdn) {
template <class Traits> MODImpl::ptr LoadMODXD3x64(BinReaderRef_e rdn) {
MODHeaderXD3X64 header;
MODInner<Traits> main;
BinReaderRef rd(rdn);
Expand Down Expand Up @@ -944,6 +970,49 @@ MODImpl::ptr LoadMODX06(BinReaderRef_e rdn) {
return std::make_unique<decltype(main)>(std::move(main));
}

MODImpl::ptr LoadMODXE5(BinReaderRef_e rd) {
MODHeaderXE5 header;
MODInner<MODTraitsXE5> main;
rd.Push();
rd.Read(header);
rd.ApplyPadding();
rd.Read(main.bounds);
rd.Read(main.metadata);

if (header.numBones) {
rd.Seek(header.bones);
rd.ReadContainer(main.bones, header.numBones);
rd.ReadContainer(main.refPoses, header.numBones);
rd.ReadContainer(main.transforms, header.numBones);
rd.Read(main.remaps);
rd.ReadContainer(main.skinRemaps, header.numSkins);
}

if (header.numGroups) {
rd.Seek(header.groups);
rd.ReadContainer(main.groups, header.numGroups);
}

rd.ReadContainer(main.materials.storage, header.numMaterials);

rd.Seek(header.meshes);
rd.ReadContainer(main.meshes, header.numMeshes);
rd.ReadContainer(main.envelopes);

main.vertexBufferSize = header.vertexBufferSize;
main.indexBufferSize = header.numIndices * sizeof(uint16);

main.buffer.resize(main.vertexBufferSize + main.indexBufferSize);

rd.Seek(header.vertexBuffer);
rd.ReadBuffer(&main.buffer[0], header.vertexBufferSize);

rd.Seek(header.indices);
rd.ReadBuffer(&main.buffer[header.vertexBufferSize], main.indexBufferSize);

return std::make_unique<decltype(main)>(std::move(main));
}

#pragma endregion

bool MODMaker::operator<(const MODMaker &i0) const {
Expand All @@ -960,10 +1029,15 @@ static const std::map<MODMaker, MODImpl::ptr (*)(BinReaderRef_e)> modLoaders{
{{MODVersion::XC5, false}, LoadMODXC5},
{{MODVersion::XD2, true}, LoadMODXD2x32<MODTraitsXD2>},
{{MODVersion::XD3, true}, LoadMODXD2x32<MODTraitsXD2>},
{{MODVersion::XD3, false, false, Platform::PS4}, LoadMODXD3x64<MODTraitsXD3PS4>},
{{MODVersion::XD3, false, false, Platform::PS4},
LoadMODXD3x64<MODTraitsXD3PS4>},
{{MODVersion::XD3, false}, LoadMODXD3x64<MODTraitsXD3x64>},
{{MODVersion::X05, false}, LoadMODX06},
{{MODVersion::X06, false}, LoadMODX06},
{{MODVersion::XE5, true}, LoadMODXE5},
{{MODVersion::XE5, false}, LoadMODXE5},
{{MODVersion::XE6, true}, LoadMODXE5},
{{MODVersion::XE6, false}, LoadMODXE5},
};

template <class C> MODImpl::ptr makeMod() {
Expand Down
11 changes: 11 additions & 0 deletions src/mtf_mod/traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,14 @@ struct MODTraitsX06 {
using mesh = MODMeshX06;
using metadata = MODMetaDataV1;
};

struct MODTraitsXE5 {
static constexpr size_t numSkinRemaps = 24;
static constexpr size_t numRemaps = 0x100;
static constexpr size_t pathSize = 1;
using primitive = MODPrimitiveProxy;
using bone = MODBoneV1_5;
using material = MODMaterialName;
using mesh = MODMeshXE5;
using metadata = MODMetaDataV1;
};
Loading

0 comments on commit b1b734b

Please sign in to comment.