mirror of https://github.com/AxioDL/metaforce.git
ANIM fixes and explicit-endian refactor
This commit is contained in:
parent
5b38596595
commit
b5d96f7040
|
@ -58,7 +58,7 @@ bool ReadANCSToBlender(HECL::BlenderConnection& conn,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Establish ANCS blend */
|
/* Establish ANCS blend */
|
||||||
if (!conn.createBlend(outPath.getAbsolutePath() + ".blend"))
|
if (!conn.createBlend(outPath.getAbsolutePath()))
|
||||||
return false;
|
return false;
|
||||||
HECL::BlenderConnection::PyOutStream os = conn.beginPythonOut(true);
|
HECL::BlenderConnection::PyOutStream os = conn.beginPythonOut(true);
|
||||||
|
|
||||||
|
|
|
@ -301,8 +301,6 @@ bool ReadCMDLToBlender(HECL::BlenderConnection& conn,
|
||||||
const HECL::ProjectPath& masterShader,
|
const HECL::ProjectPath& masterShader,
|
||||||
const RIGPAIR* rp=nullptr)
|
const RIGPAIR* rp=nullptr)
|
||||||
{
|
{
|
||||||
reader.setEndian(Athena::BigEndian);
|
|
||||||
|
|
||||||
Header head;
|
Header head;
|
||||||
head.read(reader);
|
head.read(reader);
|
||||||
|
|
||||||
|
@ -523,7 +521,7 @@ bool ReadCMDLToBlender(HECL::BlenderConnection& conn,
|
||||||
/* Positions */
|
/* Positions */
|
||||||
for (size_t i=0 ; i<=maxIdxs.pos ; ++i)
|
for (size_t i=0 ; i<=maxIdxs.pos ; ++i)
|
||||||
{
|
{
|
||||||
atVec3f pos = reader.readVec3f();
|
atVec3f pos = reader.readVec3fBig();
|
||||||
os.format("vert = bm.verts.new((%f,%f,%f))\n",
|
os.format("vert = bm.verts.new((%f,%f,%f))\n",
|
||||||
pos.vec[0], pos.vec[1], pos.vec[2]);
|
pos.vec[0], pos.vec[1], pos.vec[2]);
|
||||||
if (rp)
|
if (rp)
|
||||||
|
@ -541,7 +539,7 @@ bool ReadCMDLToBlender(HECL::BlenderConnection& conn,
|
||||||
for (size_t i=0 ; i<normCount ; ++i)
|
for (size_t i=0 ; i<normCount ; ++i)
|
||||||
{
|
{
|
||||||
os.format("norm_list.append((%f,%f,%f))\n",
|
os.format("norm_list.append((%f,%f,%f))\n",
|
||||||
reader.readInt16(), reader.readInt16(), reader.readInt16());
|
reader.readInt16Big(), reader.readInt16Big(), reader.readInt16Big());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -549,7 +547,7 @@ bool ReadCMDLToBlender(HECL::BlenderConnection& conn,
|
||||||
size_t normCount = head.secSizes[s] / 12;
|
size_t normCount = head.secSizes[s] / 12;
|
||||||
for (size_t i=0 ; i<normCount ; ++i)
|
for (size_t i=0 ; i<normCount ; ++i)
|
||||||
{
|
{
|
||||||
atVec3f norm = reader.readVec3f();
|
atVec3f norm = reader.readVec3fBig();
|
||||||
os.format("norm_list.append((%f,%f,%f))\n",
|
os.format("norm_list.append((%f,%f,%f))\n",
|
||||||
norm.vec[0], norm.vec[1], norm.vec[2]);
|
norm.vec[0], norm.vec[1], norm.vec[2]);
|
||||||
}
|
}
|
||||||
|
@ -568,7 +566,7 @@ bool ReadCMDLToBlender(HECL::BlenderConnection& conn,
|
||||||
size_t uvCount = head.secSizes[s] / 8;
|
size_t uvCount = head.secSizes[s] / 8;
|
||||||
for (size_t i=0 ; i<uvCount ; ++i)
|
for (size_t i=0 ; i<uvCount ; ++i)
|
||||||
{
|
{
|
||||||
atVec2f uv = reader.readVec2f();
|
atVec2f uv = reader.readVec2fBig();
|
||||||
os.format("uv_list.append((%f,%f))\n",
|
os.format("uv_list.append((%f,%f))\n",
|
||||||
uv.vec[0], uv.vec[1]);
|
uv.vec[0], uv.vec[1]);
|
||||||
}
|
}
|
||||||
|
@ -584,7 +582,7 @@ bool ReadCMDLToBlender(HECL::BlenderConnection& conn,
|
||||||
for (size_t i=0 ; i<uvCount ; ++i)
|
for (size_t i=0 ; i<uvCount ; ++i)
|
||||||
{
|
{
|
||||||
os.format("suv_list.append((%f,%f))\n",
|
os.format("suv_list.append((%f,%f))\n",
|
||||||
reader.readInt16(), reader.readInt16());
|
reader.readInt16Big(), reader.readInt16Big());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,9 +48,9 @@ public:
|
||||||
Delete expl;
|
Delete expl;
|
||||||
inline operator bool() const {return m_id != 0xffffffff;}
|
inline operator bool() const {return m_id != 0xffffffff;}
|
||||||
inline void read(Athena::io::IStreamReader& reader)
|
inline void read(Athena::io::IStreamReader& reader)
|
||||||
{m_id = reader.readUint32();}
|
{m_id = reader.readUint32Big();}
|
||||||
inline void write(Athena::io::IStreamWriter& writer) const
|
inline void write(Athena::io::IStreamWriter& writer) const
|
||||||
{writer.writeUint32(m_id);}
|
{writer.writeUint32Big(m_id);}
|
||||||
inline void fromYAML(Athena::io::YAMLDocReader& reader)
|
inline void fromYAML(Athena::io::YAMLDocReader& reader)
|
||||||
{m_id = reader.readUint32(nullptr);}
|
{m_id = reader.readUint32(nullptr);}
|
||||||
inline void toYAML(Athena::io::YAMLDocWriter& writer) const
|
inline void toYAML(Athena::io::YAMLDocWriter& writer) const
|
||||||
|
@ -75,9 +75,9 @@ public:
|
||||||
Delete expl;
|
Delete expl;
|
||||||
inline operator bool() const {return m_id != 0xffffffffffffffff;}
|
inline operator bool() const {return m_id != 0xffffffffffffffff;}
|
||||||
inline void read(Athena::io::IStreamReader& reader)
|
inline void read(Athena::io::IStreamReader& reader)
|
||||||
{m_id = reader.readUint64();}
|
{m_id = reader.readUint64Big();}
|
||||||
inline void write(Athena::io::IStreamWriter& writer) const
|
inline void write(Athena::io::IStreamWriter& writer) const
|
||||||
{writer.writeUint64(m_id);}
|
{writer.writeUint64Big(m_id);}
|
||||||
|
|
||||||
inline bool operator!=(const UniqueID64& other) const {return m_id != other.m_id;}
|
inline bool operator!=(const UniqueID64& other) const {return m_id != other.m_id;}
|
||||||
inline bool operator==(const UniqueID64& other) const {return m_id == other.m_id;}
|
inline bool operator==(const UniqueID64& other) const {return m_id == other.m_id;}
|
||||||
|
@ -107,13 +107,13 @@ public:
|
||||||
{return m_id[0] != 0xffffffffffffffff && m_id[1] != 0xffffffffffffffff;}
|
{return m_id[0] != 0xffffffffffffffff && m_id[1] != 0xffffffffffffffff;}
|
||||||
inline void read(Athena::io::IStreamReader& reader)
|
inline void read(Athena::io::IStreamReader& reader)
|
||||||
{
|
{
|
||||||
m_id[0] = reader.readUint64();
|
m_id[0] = reader.readUint64Big();
|
||||||
m_id[1] = reader.readUint64();
|
m_id[1] = reader.readUint64Big();
|
||||||
}
|
}
|
||||||
inline void write(Athena::io::IStreamWriter& writer) const
|
inline void write(Athena::io::IStreamWriter& writer) const
|
||||||
{
|
{
|
||||||
writer.writeUint64(m_id[0]);
|
writer.writeUint64Big(m_id[0]);
|
||||||
writer.writeUint64(m_id[1]);
|
writer.writeUint64Big(m_id[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator!=(const UniqueID128& other) const
|
inline bool operator!=(const UniqueID128& other) const
|
||||||
|
@ -182,7 +182,7 @@ struct WordBitmap
|
||||||
m_words.clear();
|
m_words.clear();
|
||||||
m_words.reserve(wordCount);
|
m_words.reserve(wordCount);
|
||||||
for (size_t w=0 ; w<wordCount ; ++w)
|
for (size_t w=0 ; w<wordCount ; ++w)
|
||||||
m_words.push_back(reader.readUint32());
|
m_words.push_back(reader.readUint32Big());
|
||||||
}
|
}
|
||||||
void write(Athena::io::IStreamWriter& writer) const
|
void write(Athena::io::IStreamWriter& writer) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,15 +8,14 @@ namespace Retro
|
||||||
|
|
||||||
std::unique_ptr<ISTRG> LoadSTRG(Athena::io::IStreamReader& reader)
|
std::unique_ptr<ISTRG> LoadSTRG(Athena::io::IStreamReader& reader)
|
||||||
{
|
{
|
||||||
reader.setEndian(Athena::BigEndian);
|
uint32_t magic = reader.readUint32Big();
|
||||||
uint32_t magic = reader.readUint32();
|
|
||||||
if (magic != 0x87654321)
|
if (magic != 0x87654321)
|
||||||
{
|
{
|
||||||
LogDNACommon.report(LogVisor::Error, "invalid STRG magic");
|
LogDNACommon.report(LogVisor::Error, "invalid STRG magic");
|
||||||
return std::unique_ptr<ISTRG>();
|
return std::unique_ptr<ISTRG>();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t version = reader.readUint32();
|
uint32_t version = reader.readUint32Big();
|
||||||
switch (version)
|
switch (version)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
|
|
|
@ -481,11 +481,10 @@ static void PNGWarn(png_structp png, png_const_charp msg)
|
||||||
|
|
||||||
bool TXTR::Extract(const SpecBase& dataspec, PAKEntryReadStream& rs, const HECL::ProjectPath& outPath)
|
bool TXTR::Extract(const SpecBase& dataspec, PAKEntryReadStream& rs, const HECL::ProjectPath& outPath)
|
||||||
{
|
{
|
||||||
rs.setEndian(Athena::BigEndian);
|
uint32_t format = rs.readUint32Big();
|
||||||
uint32_t format = rs.readUint32();
|
uint16_t width = rs.readUint16Big();
|
||||||
uint16_t width = rs.readUint16();
|
uint16_t height = rs.readUint16Big();
|
||||||
uint16_t height = rs.readUint16();
|
uint32_t numMips = rs.readUint32Big();
|
||||||
uint32_t numMips = rs.readUint32();
|
|
||||||
|
|
||||||
FILE* fp = HECL::Fopen(outPath.getAbsolutePath().c_str(), _S("wb"));
|
FILE* fp = HECL::Fopen(outPath.getAbsolutePath().c_str(), _S("wb"));
|
||||||
if (!fp)
|
if (!fp)
|
||||||
|
|
|
@ -7,23 +7,23 @@ namespace DNAMP1
|
||||||
|
|
||||||
void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo::read(Athena::io::IStreamReader& reader)
|
void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo::read(Athena::io::IStreamReader& reader)
|
||||||
{
|
{
|
||||||
parmType = reader.readUint32();
|
parmType = reader.readUint32Big();
|
||||||
unk1 = reader.readUint32();
|
unk1 = reader.readUint32Big();
|
||||||
unk2 = reader.readFloat();
|
unk2 = reader.readFloatBig();
|
||||||
switch (DataType(parmType))
|
switch (DataType(parmType))
|
||||||
{
|
{
|
||||||
case DataType::DTInt32:
|
case DataType::DTInt32:
|
||||||
parmVals[0].int32 = reader.readInt32();
|
parmVals[0].int32 = reader.readInt32Big();
|
||||||
parmVals[1].int32 = reader.readInt32();
|
parmVals[1].int32 = reader.readInt32Big();
|
||||||
break;
|
break;
|
||||||
case DataType::DTUInt32:
|
case DataType::DTUInt32:
|
||||||
case DataType::DTEnum:
|
case DataType::DTEnum:
|
||||||
parmVals[0].uint32 = reader.readUint32();
|
parmVals[0].uint32 = reader.readUint32Big();
|
||||||
parmVals[1].uint32 = reader.readUint32();
|
parmVals[1].uint32 = reader.readUint32Big();
|
||||||
break;
|
break;
|
||||||
case DataType::DTFloat:
|
case DataType::DTFloat:
|
||||||
parmVals[0].float32 = reader.readFloat();
|
parmVals[0].float32 = reader.readFloatBig();
|
||||||
parmVals[1].float32 = reader.readFloat();
|
parmVals[1].float32 = reader.readFloatBig();
|
||||||
break;
|
break;
|
||||||
case DataType::DTBool:
|
case DataType::DTBool:
|
||||||
parmVals[0].bool1 = reader.readBool();
|
parmVals[0].bool1 = reader.readBool();
|
||||||
|
@ -34,23 +34,23 @@ void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo::read(A
|
||||||
|
|
||||||
void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo::write(Athena::io::IStreamWriter& writer) const
|
void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo::write(Athena::io::IStreamWriter& writer) const
|
||||||
{
|
{
|
||||||
writer.writeUint32(parmType);
|
writer.writeUint32Big(parmType);
|
||||||
writer.writeUint32(unk1);
|
writer.writeUint32Big(unk1);
|
||||||
writer.writeFloat(unk2);
|
writer.writeFloatBig(unk2);
|
||||||
switch (DataType(parmType))
|
switch (DataType(parmType))
|
||||||
{
|
{
|
||||||
case DataType::DTInt32:
|
case DataType::DTInt32:
|
||||||
writer.writeInt32(parmVals[0].int32);
|
writer.writeInt32Big(parmVals[0].int32);
|
||||||
writer.writeInt32(parmVals[1].int32);
|
writer.writeInt32Big(parmVals[1].int32);
|
||||||
break;
|
break;
|
||||||
case DataType::DTUInt32:
|
case DataType::DTUInt32:
|
||||||
case DataType::DTEnum:
|
case DataType::DTEnum:
|
||||||
writer.writeUint32(parmVals[0].uint32);
|
writer.writeUint32Big(parmVals[0].uint32);
|
||||||
writer.writeUint32(parmVals[0].uint32);
|
writer.writeUint32Big(parmVals[0].uint32);
|
||||||
break;
|
break;
|
||||||
case DataType::DTFloat:
|
case DataType::DTFloat:
|
||||||
writer.writeFloat(parmVals[0].float32);
|
writer.writeFloatBig(parmVals[0].float32);
|
||||||
writer.writeFloat(parmVals[0].float32);
|
writer.writeFloatBig(parmVals[0].float32);
|
||||||
break;
|
break;
|
||||||
case DataType::DTBool:
|
case DataType::DTBool:
|
||||||
writer.writeBool(parmVals[0].bool1);
|
writer.writeBool(parmVals[0].bool1);
|
||||||
|
@ -120,9 +120,9 @@ void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo::toYAML
|
||||||
|
|
||||||
void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::read(Athena::io::IStreamReader& reader)
|
void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::read(Athena::io::IStreamReader& reader)
|
||||||
{
|
{
|
||||||
id = reader.readUint32();
|
id = reader.readUint32Big();
|
||||||
atUint32 parmInfoCount = reader.readUint32();
|
atUint32 parmInfoCount = reader.readUint32Big();
|
||||||
atUint32 animInfoCount = reader.readUint32();
|
atUint32 animInfoCount = reader.readUint32Big();
|
||||||
|
|
||||||
reader.enumerate(parmInfos, parmInfoCount);
|
reader.enumerate(parmInfos, parmInfoCount);
|
||||||
|
|
||||||
|
@ -131,21 +131,21 @@ void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::read(Athena::io:
|
||||||
reader.enumerate<AnimInfo>(animInfos, animInfoCount,
|
reader.enumerate<AnimInfo>(animInfos, animInfoCount,
|
||||||
[this, parmInfoCount](Athena::io::IStreamReader& reader, AnimInfo& ai)
|
[this, parmInfoCount](Athena::io::IStreamReader& reader, AnimInfo& ai)
|
||||||
{
|
{
|
||||||
ai.id = reader.readUint32();
|
ai.id = reader.readUint32Big();
|
||||||
ai.parmVals.reserve(parmInfoCount);
|
ai.parmVals.reserve(parmInfoCount);
|
||||||
for (const ParmInfo& pi : parmInfos)
|
for (const ParmInfo& pi : parmInfos)
|
||||||
{
|
{
|
||||||
switch (ParmInfo::DataType(pi.parmType))
|
switch (ParmInfo::DataType(pi.parmType))
|
||||||
{
|
{
|
||||||
case ParmInfo::DTInt32:
|
case ParmInfo::DTInt32:
|
||||||
ai.parmVals.emplace_back(reader.readInt32());
|
ai.parmVals.emplace_back(reader.readInt32Big());
|
||||||
break;
|
break;
|
||||||
case ParmInfo::DTUInt32:
|
case ParmInfo::DTUInt32:
|
||||||
case ParmInfo::DTEnum:
|
case ParmInfo::DTEnum:
|
||||||
ai.parmVals.emplace_back(reader.readUint32());
|
ai.parmVals.emplace_back(reader.readUint32Big());
|
||||||
break;
|
break;
|
||||||
case ParmInfo::DTFloat:
|
case ParmInfo::DTFloat:
|
||||||
ai.parmVals.emplace_back(reader.readFloat());
|
ai.parmVals.emplace_back(reader.readFloatBig());
|
||||||
break;
|
break;
|
||||||
case ParmInfo::DTBool:
|
case ParmInfo::DTBool:
|
||||||
ai.parmVals.emplace_back(reader.readBool());
|
ai.parmVals.emplace_back(reader.readBool());
|
||||||
|
@ -158,16 +158,16 @@ void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::read(Athena::io:
|
||||||
|
|
||||||
void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::write(Athena::io::IStreamWriter& writer) const
|
void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::write(Athena::io::IStreamWriter& writer) const
|
||||||
{
|
{
|
||||||
writer.writeUint32(id);
|
writer.writeUint32Big(id);
|
||||||
writer.writeUint32(parmInfos.size());
|
writer.writeUint32Big(parmInfos.size());
|
||||||
writer.writeUint32(animInfos.size());
|
writer.writeUint32Big(animInfos.size());
|
||||||
|
|
||||||
for (const ParmInfo& pi : parmInfos)
|
for (const ParmInfo& pi : parmInfos)
|
||||||
pi.write(writer);
|
pi.write(writer);
|
||||||
|
|
||||||
for (const AnimInfo& ai : animInfos)
|
for (const AnimInfo& ai : animInfos)
|
||||||
{
|
{
|
||||||
writer.writeUint32(ai.id);
|
writer.writeUint32Big(ai.id);
|
||||||
auto it = ai.parmVals.begin();
|
auto it = ai.parmVals.begin();
|
||||||
for (const ParmInfo& pi : parmInfos)
|
for (const ParmInfo& pi : parmInfos)
|
||||||
{
|
{
|
||||||
|
@ -177,14 +177,14 @@ void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::write(Athena::io
|
||||||
switch (ParmInfo::DataType(pi.parmType))
|
switch (ParmInfo::DataType(pi.parmType))
|
||||||
{
|
{
|
||||||
case ParmInfo::DTInt32:
|
case ParmInfo::DTInt32:
|
||||||
writer.writeInt32(pVal.int32);
|
writer.writeInt32Big(pVal.int32);
|
||||||
break;
|
break;
|
||||||
case ParmInfo::DTUInt32:
|
case ParmInfo::DTUInt32:
|
||||||
case ParmInfo::DTEnum:
|
case ParmInfo::DTEnum:
|
||||||
writer.writeUint32(pVal.uint32);
|
writer.writeUint32Big(pVal.uint32);
|
||||||
break;
|
break;
|
||||||
case ParmInfo::DTFloat:
|
case ParmInfo::DTFloat:
|
||||||
writer.writeFloat(pVal.float32);
|
writer.writeFloatBig(pVal.float32);
|
||||||
break;
|
break;
|
||||||
case ParmInfo::DTBool:
|
case ParmInfo::DTBool:
|
||||||
writer.writeBool(pVal.bool1);
|
writer.writeBool(pVal.bool1);
|
||||||
|
@ -276,52 +276,52 @@ void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::toYAML(Athena::i
|
||||||
|
|
||||||
void ANCS::CharacterSet::CharacterInfo::read(Athena::io::IStreamReader& reader)
|
void ANCS::CharacterSet::CharacterInfo::read(Athena::io::IStreamReader& reader)
|
||||||
{
|
{
|
||||||
idx = reader.readUint32();
|
idx = reader.readUint32Big();
|
||||||
atUint16 sectionCount = reader.readUint16();
|
atUint16 sectionCount = reader.readUint16Big();
|
||||||
name = reader.readString();
|
name = reader.readString();
|
||||||
cmdl.read(reader);
|
cmdl.read(reader);
|
||||||
cskr.read(reader);
|
cskr.read(reader);
|
||||||
cinf.read(reader);
|
cinf.read(reader);
|
||||||
|
|
||||||
atUint32 animationCount = reader.readUint32();
|
atUint32 animationCount = reader.readUint32Big();
|
||||||
reader.enumerate(animations, animationCount);
|
reader.enumerate(animations, animationCount);
|
||||||
|
|
||||||
pasDatabase.read(reader);
|
pasDatabase.read(reader);
|
||||||
|
|
||||||
atUint32 partCount = reader.readUint32();
|
atUint32 partCount = reader.readUint32Big();
|
||||||
reader.enumerate(partResData.part, partCount);
|
reader.enumerate(partResData.part, partCount);
|
||||||
|
|
||||||
atUint32 swhcCount = reader.readUint32();
|
atUint32 swhcCount = reader.readUint32Big();
|
||||||
reader.enumerate(partResData.swhc, swhcCount);
|
reader.enumerate(partResData.swhc, swhcCount);
|
||||||
|
|
||||||
atUint32 unkCount = reader.readUint32();
|
atUint32 unkCount = reader.readUint32Big();
|
||||||
reader.enumerate(partResData.unk, unkCount);
|
reader.enumerate(partResData.unk, unkCount);
|
||||||
|
|
||||||
partResData.elsc.clear();
|
partResData.elsc.clear();
|
||||||
if (sectionCount > 5)
|
if (sectionCount > 5)
|
||||||
{
|
{
|
||||||
atUint32 elscCount = reader.readUint32();
|
atUint32 elscCount = reader.readUint32Big();
|
||||||
reader.enumerate(partResData.elsc, elscCount);
|
reader.enumerate(partResData.elsc, elscCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
unk1 = reader.readUint32();
|
unk1 = reader.readUint32Big();
|
||||||
if (sectionCount > 9)
|
if (sectionCount > 9)
|
||||||
{
|
{
|
||||||
unk2 = reader.readUint32();
|
unk2 = reader.readUint32Big();
|
||||||
unk3 = reader.readUint32();
|
unk3 = reader.readUint32Big();
|
||||||
}
|
}
|
||||||
|
|
||||||
animAABBs.clear();
|
animAABBs.clear();
|
||||||
if (sectionCount > 1)
|
if (sectionCount > 1)
|
||||||
{
|
{
|
||||||
atUint32 aabbCount = reader.readUint32();
|
atUint32 aabbCount = reader.readUint32Big();
|
||||||
reader.enumerate(animAABBs, aabbCount);
|
reader.enumerate(animAABBs, aabbCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
effects.clear();
|
effects.clear();
|
||||||
if (sectionCount > 2)
|
if (sectionCount > 2)
|
||||||
{
|
{
|
||||||
atUint32 effectCount = reader.readUint32();
|
atUint32 effectCount = reader.readUint32Big();
|
||||||
reader.enumerate(effects, effectCount);
|
reader.enumerate(effects, effectCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,14 +334,14 @@ void ANCS::CharacterSet::CharacterInfo::read(Athena::io::IStreamReader& reader)
|
||||||
animIdxs.clear();
|
animIdxs.clear();
|
||||||
if (sectionCount > 4)
|
if (sectionCount > 4)
|
||||||
{
|
{
|
||||||
atUint32 aidxCount = reader.readUint32();
|
atUint32 aidxCount = reader.readUint32Big();
|
||||||
reader.enumerate(animIdxs, aidxCount);
|
reader.enumerateBig(animIdxs, aidxCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ANCS::CharacterSet::CharacterInfo::write(Athena::io::IStreamWriter& writer) const
|
void ANCS::CharacterSet::CharacterInfo::write(Athena::io::IStreamWriter& writer) const
|
||||||
{
|
{
|
||||||
writer.writeUint32(idx);
|
writer.writeUint32Big(idx);
|
||||||
|
|
||||||
atUint16 sectionCount;
|
atUint16 sectionCount;
|
||||||
if (unk2 || unk3)
|
if (unk2 || unk3)
|
||||||
|
@ -358,49 +358,49 @@ void ANCS::CharacterSet::CharacterInfo::write(Athena::io::IStreamWriter& writer)
|
||||||
sectionCount = 2;
|
sectionCount = 2;
|
||||||
else
|
else
|
||||||
sectionCount = 1;
|
sectionCount = 1;
|
||||||
writer.writeUint16(sectionCount);
|
writer.writeUint16Big(sectionCount);
|
||||||
|
|
||||||
writer.writeString(name);
|
writer.writeString(name);
|
||||||
cmdl.write(writer);
|
cmdl.write(writer);
|
||||||
cskr.write(writer);
|
cskr.write(writer);
|
||||||
cinf.write(writer);
|
cinf.write(writer);
|
||||||
|
|
||||||
writer.writeUint32(animations.size());
|
writer.writeUint32Big(animations.size());
|
||||||
writer.enumerate(animations);
|
writer.enumerate(animations);
|
||||||
|
|
||||||
pasDatabase.write(writer);
|
pasDatabase.write(writer);
|
||||||
|
|
||||||
writer.writeUint32(partResData.part.size());
|
writer.writeUint32Big(partResData.part.size());
|
||||||
writer.enumerate(partResData.part);
|
writer.enumerate(partResData.part);
|
||||||
|
|
||||||
writer.writeUint32(partResData.swhc.size());
|
writer.writeUint32Big(partResData.swhc.size());
|
||||||
writer.enumerate(partResData.swhc);
|
writer.enumerate(partResData.swhc);
|
||||||
|
|
||||||
writer.writeUint32(partResData.unk.size());
|
writer.writeUint32Big(partResData.unk.size());
|
||||||
writer.enumerate(partResData.unk);
|
writer.enumerate(partResData.unk);
|
||||||
|
|
||||||
if (sectionCount > 5)
|
if (sectionCount > 5)
|
||||||
{
|
{
|
||||||
writer.writeUint32(partResData.elsc.size());
|
writer.writeUint32Big(partResData.elsc.size());
|
||||||
writer.enumerate(partResData.elsc);
|
writer.enumerate(partResData.elsc);
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.writeUint32(unk1);
|
writer.writeUint32Big(unk1);
|
||||||
if (sectionCount > 9)
|
if (sectionCount > 9)
|
||||||
{
|
{
|
||||||
writer.writeUint32(unk2);
|
writer.writeUint32Big(unk2);
|
||||||
writer.writeUint32(unk3);
|
writer.writeUint32Big(unk3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sectionCount > 1)
|
if (sectionCount > 1)
|
||||||
{
|
{
|
||||||
writer.writeUint32(animAABBs.size());
|
writer.writeUint32Big(animAABBs.size());
|
||||||
writer.enumerate(animAABBs);
|
writer.enumerate(animAABBs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sectionCount > 2)
|
if (sectionCount > 2)
|
||||||
{
|
{
|
||||||
writer.writeUint32(effects.size());
|
writer.writeUint32Big(effects.size());
|
||||||
writer.enumerate(effects);
|
writer.enumerate(effects);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,9 +412,9 @@ void ANCS::CharacterSet::CharacterInfo::write(Athena::io::IStreamWriter& writer)
|
||||||
|
|
||||||
if (sectionCount > 4)
|
if (sectionCount > 4)
|
||||||
{
|
{
|
||||||
writer.writeUint32(animIdxs.size());
|
writer.writeUint32Big(animIdxs.size());
|
||||||
for (atUint32 idx : animIdxs)
|
for (atUint32 idx : animIdxs)
|
||||||
writer.writeUint32(idx);
|
writer.writeUint32Big(idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -563,7 +563,7 @@ void ANCS::CharacterSet::CharacterInfo::toYAML(Athena::io::YAMLDocWriter& writer
|
||||||
|
|
||||||
void ANCS::AnimationSet::MetaAnimFactory::read(Athena::io::IStreamReader& reader)
|
void ANCS::AnimationSet::MetaAnimFactory::read(Athena::io::IStreamReader& reader)
|
||||||
{
|
{
|
||||||
IMetaAnim::Type type(IMetaAnim::Type(reader.readUint32()));
|
IMetaAnim::Type type(IMetaAnim::Type(reader.readUint32Big()));
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case IMetaAnim::MAPrimitive:
|
case IMetaAnim::MAPrimitive:
|
||||||
|
@ -596,7 +596,7 @@ void ANCS::AnimationSet::MetaAnimFactory::write(Athena::io::IStreamWriter& write
|
||||||
{
|
{
|
||||||
if (!m_anim)
|
if (!m_anim)
|
||||||
return;
|
return;
|
||||||
writer.writeInt32(m_anim->m_type);
|
writer.writeInt32Big(m_anim->m_type);
|
||||||
m_anim->write(writer);
|
m_anim->write(writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -646,7 +646,7 @@ void ANCS::AnimationSet::MetaAnimFactory::toYAML(Athena::io::YAMLDocWriter& writ
|
||||||
|
|
||||||
void ANCS::AnimationSet::MetaTransFactory::read(Athena::io::IStreamReader& reader)
|
void ANCS::AnimationSet::MetaTransFactory::read(Athena::io::IStreamReader& reader)
|
||||||
{
|
{
|
||||||
IMetaTrans::Type type(IMetaTrans::Type(reader.readUint32()));
|
IMetaTrans::Type type(IMetaTrans::Type(reader.readUint32Big()));
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case IMetaTrans::MTMetaAnim:
|
case IMetaTrans::MTMetaAnim:
|
||||||
|
@ -672,10 +672,10 @@ void ANCS::AnimationSet::MetaTransFactory::write(Athena::io::IStreamWriter& writ
|
||||||
{
|
{
|
||||||
if (!m_trans)
|
if (!m_trans)
|
||||||
{
|
{
|
||||||
writer.writeInt32(IMetaTrans::MTNoTrans);
|
writer.writeInt32Big(IMetaTrans::MTNoTrans);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
writer.writeInt32(m_trans->m_type);
|
writer.writeInt32Big(m_trans->m_type);
|
||||||
m_trans->write(writer);
|
m_trans->write(writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -718,35 +718,35 @@ void ANCS::AnimationSet::MetaTransFactory::toYAML(Athena::io::YAMLDocWriter& wri
|
||||||
|
|
||||||
void ANCS::AnimationSet::read(Athena::io::IStreamReader& reader)
|
void ANCS::AnimationSet::read(Athena::io::IStreamReader& reader)
|
||||||
{
|
{
|
||||||
atUint16 sectionCount = reader.readUint16();
|
atUint16 sectionCount = reader.readUint16Big();
|
||||||
|
|
||||||
atUint32 animationCount = reader.readUint32();
|
atUint32 animationCount = reader.readUint32Big();
|
||||||
reader.enumerate(animations, animationCount);
|
reader.enumerate(animations, animationCount);
|
||||||
|
|
||||||
atUint32 transitionCount = reader.readUint32();
|
atUint32 transitionCount = reader.readUint32Big();
|
||||||
reader.enumerate(transitions, transitionCount);
|
reader.enumerate(transitions, transitionCount);
|
||||||
defaultTransition.read(reader);
|
defaultTransition.read(reader);
|
||||||
|
|
||||||
additiveAnims.clear();
|
additiveAnims.clear();
|
||||||
if (sectionCount > 1)
|
if (sectionCount > 1)
|
||||||
{
|
{
|
||||||
atUint32 additiveAnimCount = reader.readUint32();
|
atUint32 additiveAnimCount = reader.readUint32Big();
|
||||||
reader.enumerate(additiveAnims, additiveAnimCount);
|
reader.enumerate(additiveAnims, additiveAnimCount);
|
||||||
floatA = reader.readFloat();
|
floatA = reader.readFloatBig();
|
||||||
floatB = reader.readFloat();
|
floatB = reader.readFloatBig();
|
||||||
}
|
}
|
||||||
|
|
||||||
halfTransitions.clear();
|
halfTransitions.clear();
|
||||||
if (sectionCount > 2)
|
if (sectionCount > 2)
|
||||||
{
|
{
|
||||||
atUint32 halfTransitionCount = reader.readUint32();
|
atUint32 halfTransitionCount = reader.readUint32Big();
|
||||||
reader.enumerate(halfTransitions, halfTransitionCount);
|
reader.enumerate(halfTransitions, halfTransitionCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
animResources.clear();
|
animResources.clear();
|
||||||
if (sectionCount > 3)
|
if (sectionCount > 3)
|
||||||
{
|
{
|
||||||
atUint32 animResourcesCount = reader.readUint32();
|
atUint32 animResourcesCount = reader.readUint32Big();
|
||||||
reader.enumerate(animResources, animResourcesCount);
|
reader.enumerate(animResources, animResourcesCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -763,32 +763,32 @@ void ANCS::AnimationSet::write(Athena::io::IStreamWriter& writer) const
|
||||||
else
|
else
|
||||||
sectionCount = 1;
|
sectionCount = 1;
|
||||||
|
|
||||||
writer.writeUint16(sectionCount);
|
writer.writeUint16Big(sectionCount);
|
||||||
|
|
||||||
writer.writeUint32(animations.size());
|
writer.writeUint32Big(animations.size());
|
||||||
writer.enumerate(animations);
|
writer.enumerate(animations);
|
||||||
|
|
||||||
writer.writeUint32(transitions.size());
|
writer.writeUint32Big(transitions.size());
|
||||||
writer.enumerate(transitions);
|
writer.enumerate(transitions);
|
||||||
defaultTransition.write(writer);
|
defaultTransition.write(writer);
|
||||||
|
|
||||||
if (sectionCount > 1)
|
if (sectionCount > 1)
|
||||||
{
|
{
|
||||||
writer.writeUint32(additiveAnims.size());
|
writer.writeUint32Big(additiveAnims.size());
|
||||||
writer.enumerate(additiveAnims);
|
writer.enumerate(additiveAnims);
|
||||||
writer.writeFloat(floatA);
|
writer.writeFloatBig(floatA);
|
||||||
writer.writeFloat(floatB);
|
writer.writeFloatBig(floatB);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sectionCount > 2)
|
if (sectionCount > 2)
|
||||||
{
|
{
|
||||||
writer.writeUint32(halfTransitions.size());
|
writer.writeUint32Big(halfTransitions.size());
|
||||||
writer.enumerate(halfTransitions);
|
writer.enumerate(halfTransitions);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sectionCount > 3)
|
if (sectionCount > 3)
|
||||||
{
|
{
|
||||||
writer.writeUint32(animResources.size());
|
writer.writeUint32Big(animResources.size());
|
||||||
writer.enumerate(animResources);
|
writer.enumerate(animResources);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -382,14 +382,25 @@ struct ANCS : BigYAML
|
||||||
{
|
{
|
||||||
ANCS ancs;
|
ANCS ancs;
|
||||||
ancs.read(rs);
|
ancs.read(rs);
|
||||||
FILE* fp = HECL::Fopen((outPath.getAbsolutePath() + ".yaml").c_str(), _S("wb"));
|
|
||||||
ancs.toYAMLFile(fp);
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
HECL::BlenderConnection& conn = HECL::BlenderConnection::SharedConnection();
|
HECL::ProjectPath yamlPath = outPath.getWithExtension(_S(".yaml"));
|
||||||
DNAANCS::ReadANCSToBlender<PAKRouter<PAKBridge>, ANCS, MaterialSet, 2>
|
if (force || yamlPath.getPathType() == HECL::ProjectPath::PT_NONE)
|
||||||
(conn, ancs, outPath, pakRouter, entry, dataSpec.getMasterShaderPath(), force);
|
{
|
||||||
return conn.saveBlend();
|
FILE* fp = HECL::Fopen(yamlPath.getAbsolutePath().c_str(), _S("wb"));
|
||||||
|
ancs.toYAMLFile(fp);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
HECL::ProjectPath blendPath = outPath.getWithExtension(_S(".blend"));
|
||||||
|
if (force || blendPath.getPathType() == HECL::ProjectPath::PT_NONE)
|
||||||
|
{
|
||||||
|
HECL::BlenderConnection& conn = HECL::BlenderConnection::SharedConnection();
|
||||||
|
DNAANCS::ReadANCSToBlender<PAKRouter<PAKBridge>, ANCS, MaterialSet, 2>
|
||||||
|
(conn, ancs, blendPath, pakRouter, entry, dataSpec.getMasterShaderPath(), force);
|
||||||
|
return conn.saveBlend();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ void ANIM::ANIM0::read(Athena::io::IStreamReader& reader)
|
||||||
boneMap[idx] = b;
|
boneMap[idx] = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
atUint32 boneCount = reader.readUint32();
|
atUint32 boneCount = reader.readUint32Big();
|
||||||
bones.clear();
|
bones.clear();
|
||||||
bones.reserve(boneCount);
|
bones.reserve(boneCount);
|
||||||
channels.clear();
|
channels.clear();
|
||||||
|
@ -109,7 +109,7 @@ void ANIM::ANIM0::read(Athena::io::IStreamReader& reader)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
reader.readUint32();
|
reader.readUint32Big();
|
||||||
chanKeys.clear();
|
chanKeys.clear();
|
||||||
chanKeys.reserve(channels.size());
|
chanKeys.reserve(channels.size());
|
||||||
for (const std::pair<atUint32, bool>& bone : bones)
|
for (const std::pair<atUint32, bool>& bone : bones)
|
||||||
|
@ -117,13 +117,13 @@ void ANIM::ANIM0::read(Athena::io::IStreamReader& reader)
|
||||||
chanKeys.emplace_back();
|
chanKeys.emplace_back();
|
||||||
std::vector<DNAANIM::Value>& keys = chanKeys.back();
|
std::vector<DNAANIM::Value>& keys = chanKeys.back();
|
||||||
for (size_t k=0 ; k<head.keyCount ; ++k)
|
for (size_t k=0 ; k<head.keyCount ; ++k)
|
||||||
keys.emplace_back(reader.readVec4f());
|
keys.emplace_back(reader.readVec4fBig());
|
||||||
|
|
||||||
if (bone.second)
|
if (bone.second)
|
||||||
chanKeys.emplace_back();
|
chanKeys.emplace_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
reader.readUint32();
|
reader.readUint32Big();
|
||||||
auto kit = chanKeys.begin();
|
auto kit = chanKeys.begin();
|
||||||
for (const std::pair<atUint32, bool>& bone : bones)
|
for (const std::pair<atUint32, bool>& bone : bones)
|
||||||
{
|
{
|
||||||
|
@ -132,7 +132,7 @@ void ANIM::ANIM0::read(Athena::io::IStreamReader& reader)
|
||||||
{
|
{
|
||||||
std::vector<DNAANIM::Value>& keys = *kit++;
|
std::vector<DNAANIM::Value>& keys = *kit++;
|
||||||
for (size_t k=0 ; k<head.keyCount ; ++k)
|
for (size_t k=0 ; k<head.keyCount ; ++k)
|
||||||
keys.emplace_back(reader.readVec3f());
|
keys.emplace_back(reader.readVec3fBig());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ void ANIM::ANIM0::write(Athena::io::IStreamWriter& writer) const
|
||||||
writer.writeUByte(0xff);
|
writer.writeUByte(0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.writeUint32(bones.size());
|
writer.writeUint32Big(bones.size());
|
||||||
size_t boneIdx = 0;
|
size_t boneIdx = 0;
|
||||||
for (const std::pair<atUint32, bool>& bone : bones)
|
for (const std::pair<atUint32, bool>& bone : bones)
|
||||||
{
|
{
|
||||||
|
@ -184,7 +184,7 @@ void ANIM::ANIM0::write(Athena::io::IStreamWriter& writer) const
|
||||||
++boneIdx;
|
++boneIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.writeUint32(bones.size() * head.keyCount);
|
writer.writeUint32Big(bones.size() * head.keyCount);
|
||||||
auto cit = chanKeys.begin();
|
auto cit = chanKeys.begin();
|
||||||
atUint32 transKeyCount = 0;
|
atUint32 transKeyCount = 0;
|
||||||
for (const std::pair<atUint32, bool>& bone : bones)
|
for (const std::pair<atUint32, bool>& bone : bones)
|
||||||
|
@ -192,7 +192,7 @@ void ANIM::ANIM0::write(Athena::io::IStreamWriter& writer) const
|
||||||
const std::vector<DNAANIM::Value>& keys = *cit++;
|
const std::vector<DNAANIM::Value>& keys = *cit++;
|
||||||
auto kit = keys.begin();
|
auto kit = keys.begin();
|
||||||
for (size_t k=0 ; k<head.keyCount ; ++k)
|
for (size_t k=0 ; k<head.keyCount ; ++k)
|
||||||
writer.writeVec4f((*kit++).v4);
|
writer.writeVec4fBig((*kit++).v4);
|
||||||
if (bone.second)
|
if (bone.second)
|
||||||
{
|
{
|
||||||
transKeyCount += head.keyCount;
|
transKeyCount += head.keyCount;
|
||||||
|
@ -200,7 +200,7 @@ void ANIM::ANIM0::write(Athena::io::IStreamWriter& writer) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.writeUint32(transKeyCount);
|
writer.writeUint32Big(transKeyCount);
|
||||||
cit = chanKeys.begin();
|
cit = chanKeys.begin();
|
||||||
for (const std::pair<atUint32, bool>& bone : bones)
|
for (const std::pair<atUint32, bool>& bone : bones)
|
||||||
{
|
{
|
||||||
|
@ -210,7 +210,7 @@ void ANIM::ANIM0::write(Athena::io::IStreamWriter& writer) const
|
||||||
const std::vector<DNAANIM::Value>& keys = *cit++;
|
const std::vector<DNAANIM::Value>& keys = *cit++;
|
||||||
auto kit = keys.begin();
|
auto kit = keys.begin();
|
||||||
for (size_t k=0 ; k<head.keyCount ; ++k)
|
for (size_t k=0 ; k<head.keyCount ; ++k)
|
||||||
writer.writeVec3f((*kit++).v3);
|
writer.writeVec3fBig((*kit++).v3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,8 +316,8 @@ void ANIM::ANIM2::write(Athena::io::IStreamWriter& writer) const
|
||||||
|
|
||||||
head.write(writer);
|
head.write(writer);
|
||||||
keyBmp.write(writer);
|
keyBmp.write(writer);
|
||||||
writer.writeUint32(head.boneChannelCount);
|
writer.writeUint32Big(head.boneChannelCount);
|
||||||
writer.writeUint32(head.boneChannelCount);
|
writer.writeUint32Big(head.boneChannelCount);
|
||||||
auto cit = qChannels.begin();
|
auto cit = qChannels.begin();
|
||||||
for (const std::pair<atUint32, bool>& bone : bones)
|
for (const std::pair<atUint32, bool>& bone : bones)
|
||||||
{
|
{
|
||||||
|
|
|
@ -43,9 +43,9 @@ struct ANIM : BigDNA
|
||||||
Value<atUint32> unk0;
|
Value<atUint32> unk0;
|
||||||
Value<float> interval;
|
Value<float> interval;
|
||||||
Value<atUint32> unk1;
|
Value<atUint32> unk1;
|
||||||
Value<atUint32> boneSlotCount;
|
|
||||||
Value<atUint32> unk2;
|
|
||||||
Value<atUint32> keyCount;
|
Value<atUint32> keyCount;
|
||||||
|
Value<atUint32> unk2;
|
||||||
|
Value<atUint32> boneSlotCount;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -92,43 +92,43 @@ struct ANIM : BigDNA
|
||||||
|
|
||||||
void read(Athena::io::IStreamReader& reader)
|
void read(Athena::io::IStreamReader& reader)
|
||||||
{
|
{
|
||||||
id = reader.readUint32();
|
id = reader.readUint32Big();
|
||||||
keyCount1 = reader.readUint16();
|
keyCount1 = reader.readUint16Big();
|
||||||
initRX = reader.readUint16();
|
initRX = reader.readUint16Big();
|
||||||
qRX = reader.readUByte();
|
qRX = reader.readUByte();
|
||||||
initRY = reader.readUint16();
|
initRY = reader.readUint16Big();
|
||||||
qRY = reader.readUByte();
|
qRY = reader.readUByte();
|
||||||
initRZ = reader.readUint16();
|
initRZ = reader.readUint16Big();
|
||||||
qRZ = reader.readUByte();
|
qRZ = reader.readUByte();
|
||||||
keyCount2 = reader.readUint16();
|
keyCount2 = reader.readUint16Big();
|
||||||
if (keyCount2)
|
if (keyCount2)
|
||||||
{
|
{
|
||||||
initTX = reader.readUint16();
|
initTX = reader.readUint16Big();
|
||||||
qTX = reader.readUByte();
|
qTX = reader.readUByte();
|
||||||
initTY = reader.readUint16();
|
initTY = reader.readUint16Big();
|
||||||
qTY = reader.readUByte();
|
qTY = reader.readUByte();
|
||||||
initTZ = reader.readUint16();
|
initTZ = reader.readUint16Big();
|
||||||
qTZ = reader.readUByte();
|
qTZ = reader.readUByte();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void write(Athena::io::IStreamWriter& writer) const
|
void write(Athena::io::IStreamWriter& writer) const
|
||||||
{
|
{
|
||||||
writer.writeUint32(id);
|
writer.writeUint32Big(id);
|
||||||
writer.writeUint16(keyCount1);
|
writer.writeUint16Big(keyCount1);
|
||||||
writer.writeUint16(initRX);
|
writer.writeUint16Big(initRX);
|
||||||
writer.writeUByte(qRX);
|
writer.writeUByte(qRX);
|
||||||
writer.writeUint16(initRY);
|
writer.writeUint16Big(initRY);
|
||||||
writer.writeUByte(qRY);
|
writer.writeUByte(qRY);
|
||||||
writer.writeUint16(initRZ);
|
writer.writeUint16Big(initRZ);
|
||||||
writer.writeUByte(qRZ);
|
writer.writeUByte(qRZ);
|
||||||
writer.writeUint16(keyCount2);
|
writer.writeUint16Big(keyCount2);
|
||||||
if (keyCount2)
|
if (keyCount2)
|
||||||
{
|
{
|
||||||
writer.writeUint16(initTX);
|
writer.writeUint16Big(initTX);
|
||||||
writer.writeUByte(qTX);
|
writer.writeUByte(qTX);
|
||||||
writer.writeUint16(initTY);
|
writer.writeUint16Big(initTY);
|
||||||
writer.writeUByte(qTY);
|
writer.writeUByte(qTY);
|
||||||
writer.writeUint16(initTZ);
|
writer.writeUint16Big(initTZ);
|
||||||
writer.writeUByte(qTZ);
|
writer.writeUByte(qTZ);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,8 +138,7 @@ struct ANIM : BigDNA
|
||||||
std::unique_ptr<IANIM> m_anim;
|
std::unique_ptr<IANIM> m_anim;
|
||||||
void read(Athena::io::IStreamReader& reader)
|
void read(Athena::io::IStreamReader& reader)
|
||||||
{
|
{
|
||||||
reader.setEndian(Athena::BigEndian);
|
atUint32 version = reader.readUint32Big();
|
||||||
atUint32 version = reader.readUint32();
|
|
||||||
switch (version)
|
switch (version)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -158,8 +157,7 @@ struct ANIM : BigDNA
|
||||||
|
|
||||||
void write(Athena::io::IStreamWriter& writer) const
|
void write(Athena::io::IStreamWriter& writer) const
|
||||||
{
|
{
|
||||||
writer.setEndian(Athena::BigEndian);
|
writer.writeUint32Big(m_anim->m_version);
|
||||||
writer.writeUint32(m_anim->m_version);
|
|
||||||
m_anim->write(writer);
|
m_anim->write(writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -250,8 +250,7 @@ struct MaterialSet : BigDNA
|
||||||
float vals[4];
|
float vals[4];
|
||||||
void read(Athena::io::IStreamReader& reader)
|
void read(Athena::io::IStreamReader& reader)
|
||||||
{
|
{
|
||||||
reader.setEndian(Athena::BigEndian);
|
mode = Mode(reader.readUint32Big());
|
||||||
mode = Mode(reader.readUint32());
|
|
||||||
switch (mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
case ANIM_MV_INV_NOTRANS:
|
case ANIM_MV_INV_NOTRANS:
|
||||||
|
@ -261,22 +260,21 @@ struct MaterialSet : BigDNA
|
||||||
case ANIM_SCROLL:
|
case ANIM_SCROLL:
|
||||||
case ANIM_HSTRIP:
|
case ANIM_HSTRIP:
|
||||||
case ANIM_VSTRIP:
|
case ANIM_VSTRIP:
|
||||||
vals[0] = reader.readFloat();
|
vals[0] = reader.readFloatBig();
|
||||||
vals[1] = reader.readFloat();
|
vals[1] = reader.readFloatBig();
|
||||||
vals[2] = reader.readFloat();
|
vals[2] = reader.readFloatBig();
|
||||||
vals[3] = reader.readFloat();
|
vals[3] = reader.readFloatBig();
|
||||||
break;
|
break;
|
||||||
case ANIM_ROTATION:
|
case ANIM_ROTATION:
|
||||||
case ANIM_MODE_WHO_MUST_NOT_BE_NAMED:
|
case ANIM_MODE_WHO_MUST_NOT_BE_NAMED:
|
||||||
vals[0] = reader.readFloat();
|
vals[0] = reader.readFloatBig();
|
||||||
vals[1] = reader.readFloat();
|
vals[1] = reader.readFloatBig();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void write(Athena::io::IStreamWriter& writer) const
|
void write(Athena::io::IStreamWriter& writer) const
|
||||||
{
|
{
|
||||||
writer.setEndian(Athena::BigEndian);
|
writer.writeUint32Big(mode);
|
||||||
writer.writeUint32(mode);
|
|
||||||
switch (mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
case ANIM_MV_INV_NOTRANS:
|
case ANIM_MV_INV_NOTRANS:
|
||||||
|
@ -286,15 +284,15 @@ struct MaterialSet : BigDNA
|
||||||
case ANIM_SCROLL:
|
case ANIM_SCROLL:
|
||||||
case ANIM_HSTRIP:
|
case ANIM_HSTRIP:
|
||||||
case ANIM_VSTRIP:
|
case ANIM_VSTRIP:
|
||||||
writer.writeFloat(vals[0]);
|
writer.writeFloatBig(vals[0]);
|
||||||
writer.writeFloat(vals[1]);
|
writer.writeFloatBig(vals[1]);
|
||||||
writer.writeFloat(vals[2]);
|
writer.writeFloatBig(vals[2]);
|
||||||
writer.writeFloat(vals[3]);
|
writer.writeFloatBig(vals[3]);
|
||||||
break;
|
break;
|
||||||
case ANIM_ROTATION:
|
case ANIM_ROTATION:
|
||||||
case ANIM_MODE_WHO_MUST_NOT_BE_NAMED:
|
case ANIM_MODE_WHO_MUST_NOT_BE_NAMED:
|
||||||
writer.writeFloat(vals[0]);
|
writer.writeFloatBig(vals[0]);
|
||||||
writer.writeFloat(vals[1]);
|
writer.writeFloatBig(vals[1]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,13 +10,12 @@ namespace DNAMP1
|
||||||
|
|
||||||
void PAK::read(Athena::io::IStreamReader& reader)
|
void PAK::read(Athena::io::IStreamReader& reader)
|
||||||
{
|
{
|
||||||
reader.setEndian(Athena::BigEndian);
|
atUint32 version = reader.readUint32Big();
|
||||||
atUint32 version = reader.readUint32();
|
|
||||||
if (version != 0x00030005)
|
if (version != 0x00030005)
|
||||||
Log.report(LogVisor::FatalError, "unexpected PAK magic");
|
Log.report(LogVisor::FatalError, "unexpected PAK magic");
|
||||||
reader.readUint32();
|
reader.readUint32Big();
|
||||||
|
|
||||||
atUint32 nameCount = reader.readUint32();
|
atUint32 nameCount = reader.readUint32Big();
|
||||||
m_nameEntries.clear();
|
m_nameEntries.clear();
|
||||||
m_nameEntries.reserve(nameCount);
|
m_nameEntries.reserve(nameCount);
|
||||||
for (atUint32 n=0 ; n<nameCount ; ++n)
|
for (atUint32 n=0 ; n<nameCount ; ++n)
|
||||||
|
@ -25,7 +24,7 @@ void PAK::read(Athena::io::IStreamReader& reader)
|
||||||
m_nameEntries.back().read(reader);
|
m_nameEntries.back().read(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
atUint32 count = reader.readUint32();
|
atUint32 count = reader.readUint32Big();
|
||||||
m_entries.clear();
|
m_entries.clear();
|
||||||
m_entries.reserve(count);
|
m_entries.reserve(count);
|
||||||
m_idMap.clear();
|
m_idMap.clear();
|
||||||
|
@ -53,18 +52,17 @@ void PAK::read(Athena::io::IStreamReader& reader)
|
||||||
|
|
||||||
void PAK::write(Athena::io::IStreamWriter& writer) const
|
void PAK::write(Athena::io::IStreamWriter& writer) const
|
||||||
{
|
{
|
||||||
writer.setEndian(Athena::BigEndian);
|
writer.writeUint32Big(0x00030005);
|
||||||
writer.writeUint32(0x00030005);
|
writer.writeUint32Big(0);
|
||||||
writer.writeUint32(0);
|
|
||||||
|
|
||||||
writer.writeUint32((atUint32)m_nameEntries.size());
|
writer.writeUint32Big((atUint32)m_nameEntries.size());
|
||||||
for (const NameEntry& entry : m_nameEntries)
|
for (const NameEntry& entry : m_nameEntries)
|
||||||
{
|
{
|
||||||
((NameEntry&)entry).nameLen = entry.name.size();
|
((NameEntry&)entry).nameLen = entry.name.size();
|
||||||
entry.write(writer);
|
entry.write(writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.writeUint32(m_entries.size());
|
writer.writeUint32Big(m_entries.size());
|
||||||
for (const Entry& entry : m_entries)
|
for (const Entry& entry : m_entries)
|
||||||
{
|
{
|
||||||
Entry tmp = entry;
|
Entry tmp = entry;
|
||||||
|
|
|
@ -8,8 +8,8 @@ namespace DNAMP1
|
||||||
|
|
||||||
void STRG::_read(Athena::io::IStreamReader& reader)
|
void STRG::_read(Athena::io::IStreamReader& reader)
|
||||||
{
|
{
|
||||||
atUint32 langCount = reader.readUint32();
|
atUint32 langCount = reader.readUint32Big();
|
||||||
atUint32 strCount = reader.readUint32();
|
atUint32 strCount = reader.readUint32Big();
|
||||||
|
|
||||||
std::vector<FourCC> readLangs;
|
std::vector<FourCC> readLangs;
|
||||||
readLangs.reserve(langCount);
|
readLangs.reserve(langCount);
|
||||||
|
@ -28,7 +28,7 @@ void STRG::_read(Athena::io::IStreamReader& reader)
|
||||||
std::vector<std::wstring> strs;
|
std::vector<std::wstring> strs;
|
||||||
reader.seek(strCount * 4 + 4);
|
reader.seek(strCount * 4 + 4);
|
||||||
for (atUint32 s=0 ; s<strCount ; ++s)
|
for (atUint32 s=0 ; s<strCount ; ++s)
|
||||||
strs.emplace_back(reader.readWString());
|
strs.emplace_back(reader.readWStringBig());
|
||||||
langs.emplace_back(lang, strs);
|
langs.emplace_back(lang, strs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,12 +40,11 @@ void STRG::_read(Athena::io::IStreamReader& reader)
|
||||||
|
|
||||||
void STRG::read(Athena::io::IStreamReader& reader)
|
void STRG::read(Athena::io::IStreamReader& reader)
|
||||||
{
|
{
|
||||||
reader.setEndian(Athena::BigEndian);
|
atUint32 magic = reader.readUint32Big();
|
||||||
atUint32 magic = reader.readUint32();
|
|
||||||
if (magic != 0x87654321)
|
if (magic != 0x87654321)
|
||||||
Log.report(LogVisor::Error, "invalid STRG magic");
|
Log.report(LogVisor::Error, "invalid STRG magic");
|
||||||
|
|
||||||
atUint32 version = reader.readUint32();
|
atUint32 version = reader.readUint32Big();
|
||||||
if (version != 0)
|
if (version != 0)
|
||||||
Log.report(LogVisor::Error, "invalid STRG version");
|
Log.report(LogVisor::Error, "invalid STRG version");
|
||||||
|
|
||||||
|
@ -54,18 +53,17 @@ void STRG::read(Athena::io::IStreamReader& reader)
|
||||||
|
|
||||||
void STRG::write(Athena::io::IStreamWriter& writer) const
|
void STRG::write(Athena::io::IStreamWriter& writer) const
|
||||||
{
|
{
|
||||||
writer.setEndian(Athena::BigEndian);
|
writer.writeUint32Big(0x87654321);
|
||||||
writer.writeUint32(0x87654321);
|
writer.writeUint32Big(0);
|
||||||
writer.writeUint32(0);
|
writer.writeUint32Big(langs.size());
|
||||||
writer.writeUint32(langs.size());
|
|
||||||
atUint32 strCount = STRG::count();
|
atUint32 strCount = STRG::count();
|
||||||
writer.writeUint32(strCount);
|
writer.writeUint32Big(strCount);
|
||||||
|
|
||||||
atUint32 offset = 0;
|
atUint32 offset = 0;
|
||||||
for (const std::pair<FourCC, std::vector<std::wstring>>& lang : langs)
|
for (const std::pair<FourCC, std::vector<std::wstring>>& lang : langs)
|
||||||
{
|
{
|
||||||
lang.first.write(writer);
|
lang.first.write(writer);
|
||||||
writer.writeUint32(offset);
|
writer.writeUint32Big(offset);
|
||||||
offset += strCount * 4 + 4;
|
offset += strCount * 4 + 4;
|
||||||
atUint32 langStrCount = lang.second.size();
|
atUint32 langStrCount = lang.second.size();
|
||||||
for (atUint32 s=0 ; s<strCount ; ++s)
|
for (atUint32 s=0 ; s<strCount ; ++s)
|
||||||
|
@ -89,12 +87,12 @@ void STRG::write(Athena::io::IStreamWriter& writer) const
|
||||||
else
|
else
|
||||||
tableSz += 1;
|
tableSz += 1;
|
||||||
}
|
}
|
||||||
writer.writeUint32(tableSz);
|
writer.writeUint32Big(tableSz);
|
||||||
|
|
||||||
offset = strCount * 4;
|
offset = strCount * 4;
|
||||||
for (atUint32 s=0 ; s<strCount ; ++s)
|
for (atUint32 s=0 ; s<strCount ; ++s)
|
||||||
{
|
{
|
||||||
writer.writeUint32(offset);
|
writer.writeUint32Big(offset);
|
||||||
if (s < langStrCount)
|
if (s < langStrCount)
|
||||||
offset += lang.second[s].size() * 2 + 1;
|
offset += lang.second[s].size() * 2 + 1;
|
||||||
else
|
else
|
||||||
|
@ -104,7 +102,7 @@ void STRG::write(Athena::io::IStreamWriter& writer) const
|
||||||
for (atUint32 s=0 ; s<strCount ; ++s)
|
for (atUint32 s=0 ; s<strCount ; ++s)
|
||||||
{
|
{
|
||||||
if (s < langStrCount)
|
if (s < langStrCount)
|
||||||
writer.writeWString(lang.second[s]);
|
writer.writeWStringBig(lang.second[s]);
|
||||||
else
|
else
|
||||||
writer.writeUByte(0);
|
writer.writeUByte(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
#ifndef _DNAMP2_ANCS_HPP_
|
||||||
|
#define _DNAMP2_ANCS_HPP_
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include "../DNACommon/DNACommon.hpp"
|
||||||
|
#include "../DNACommon/ANCS.hpp"
|
||||||
|
#include "CMDLMaterials.hpp"
|
||||||
|
#include "BlenderConnection.hpp"
|
||||||
|
#include "CINF.hpp"
|
||||||
|
#include "CSKR.hpp"
|
||||||
|
#include "ANIM.hpp"
|
||||||
|
#include "../DNAMP1/ANCS.hpp"
|
||||||
|
|
||||||
|
namespace Retro
|
||||||
|
{
|
||||||
|
namespace DNAMP2
|
||||||
|
{
|
||||||
|
|
||||||
|
struct ANCS : BigYAML
|
||||||
|
{
|
||||||
|
using CINFType = CINF;
|
||||||
|
using CSKRType = CSKR;
|
||||||
|
using ANIMType = ANIM;
|
||||||
|
|
||||||
|
DECL_YAML
|
||||||
|
Value<atUint16> version;
|
||||||
|
|
||||||
|
DNAMP1::ANCS::CharacterSet characterSet;
|
||||||
|
DNAMP1::ANCS::AnimationSet animationSet;
|
||||||
|
|
||||||
|
void getCharacterResInfo(std::vector<DNAANCS::CharacterResInfo<UniqueID32>>& out) const
|
||||||
|
{
|
||||||
|
out.clear();
|
||||||
|
out.reserve(characterSet.characters.size());
|
||||||
|
for (const DNAMP1::ANCS::CharacterSet::CharacterInfo& ci : characterSet.characters)
|
||||||
|
{
|
||||||
|
out.emplace_back();
|
||||||
|
DNAANCS::CharacterResInfo<UniqueID32>& chOut = out.back();
|
||||||
|
chOut.name = ci.name;
|
||||||
|
chOut.cmdl = ci.cmdl;
|
||||||
|
chOut.cskr = ci.cskr;
|
||||||
|
chOut.cinf = ci.cinf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void getAnimationResInfo(std::map<atUint32, std::pair<std::string, UniqueID32>>& out) const
|
||||||
|
{
|
||||||
|
out.clear();
|
||||||
|
for (const DNAMP1::ANCS::AnimationSet::Animation& ai : animationSet.animations)
|
||||||
|
ai.metaAnim.m_anim->gatherPrimitives(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool Extract(const SpecBase& dataSpec,
|
||||||
|
PAKEntryReadStream& rs,
|
||||||
|
const HECL::ProjectPath& outPath,
|
||||||
|
PAKRouter<PAKBridge>& pakRouter,
|
||||||
|
const DNAMP1::PAK::Entry& entry,
|
||||||
|
bool force)
|
||||||
|
{
|
||||||
|
ANCS ancs;
|
||||||
|
ancs.read(rs);
|
||||||
|
|
||||||
|
HECL::ProjectPath yamlPath = outPath.getWithExtension(_S(".yaml"));
|
||||||
|
if (force || yamlPath.getPathType() == HECL::ProjectPath::PT_NONE)
|
||||||
|
{
|
||||||
|
FILE* fp = HECL::Fopen(yamlPath.getAbsolutePath().c_str(), _S("wb"));
|
||||||
|
ancs.toYAMLFile(fp);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
HECL::ProjectPath blendPath = outPath.getWithExtension(_S(".blend"));
|
||||||
|
if (force || blendPath.getPathType() == HECL::ProjectPath::PT_NONE)
|
||||||
|
{
|
||||||
|
HECL::BlenderConnection& conn = HECL::BlenderConnection::SharedConnection();
|
||||||
|
DNAANCS::ReadANCSToBlender<PAKRouter<PAKBridge>, ANCS, MaterialSet, 4>
|
||||||
|
(conn, ancs, blendPath, pakRouter, entry, dataSpec.getMasterShaderPath(), force);
|
||||||
|
return conn.saveBlend();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _DNAMP2_ANCS_HPP_
|
|
@ -0,0 +1,352 @@
|
||||||
|
#include "ANIM.hpp"
|
||||||
|
|
||||||
|
namespace Retro
|
||||||
|
{
|
||||||
|
namespace DNAMP2
|
||||||
|
{
|
||||||
|
|
||||||
|
void ANIM::IANIM::sendANIMToBlender(HECL::BlenderConnection::PyOutStream& os, const CINF& cinf) const
|
||||||
|
{
|
||||||
|
os.format("act.hecl_fps = round(%f)\n", (1.0f / mainInterval));
|
||||||
|
|
||||||
|
auto kit = chanKeys.begin();
|
||||||
|
for (const std::pair<atUint32, bool>& bone : bones)
|
||||||
|
{
|
||||||
|
os.format("bone_string = '%s'\n", cinf.getBoneNameFromId(bone.first)->c_str());
|
||||||
|
os << "action_group = act.groups.new(bone_string)\n"
|
||||||
|
"\n"
|
||||||
|
"rotCurves = []\n"
|
||||||
|
"rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=0, action_group=bone_string))\n"
|
||||||
|
"rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=1, action_group=bone_string))\n"
|
||||||
|
"rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=2, action_group=bone_string))\n"
|
||||||
|
"rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=3, action_group=bone_string))\n"
|
||||||
|
"\n";
|
||||||
|
|
||||||
|
if (bone.second)
|
||||||
|
os << "bone_trans_head = (0.0,0.0,0.0)\n"
|
||||||
|
"if arm_obj.data.bones[bone_string].parent is not None:\n"
|
||||||
|
" bone_trans_head = Vector(arm_obj.data.bones[bone_string].head_local) - Vector(arm_obj.data.bones[bone_string].parent.head_local)\n"
|
||||||
|
"transCurves = []\n"
|
||||||
|
"transCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].location', index=0, action_group=bone_string))\n"
|
||||||
|
"transCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].location', index=1, action_group=bone_string))\n"
|
||||||
|
"transCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].location', index=2, action_group=bone_string))\n"
|
||||||
|
"\n";
|
||||||
|
|
||||||
|
os << "crv = act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_mode', action_group=bone_string)\n"
|
||||||
|
"crv.keyframe_points.add()\n"
|
||||||
|
"crv.keyframe_points[-1].co = (0, 0)\n"
|
||||||
|
"crv.keyframe_points[-1].interpolation = 'LINEAR'\n"
|
||||||
|
"\n";
|
||||||
|
|
||||||
|
const std::vector<DNAANIM::Value>& rotKeys = *kit++;
|
||||||
|
auto frameit = frames.begin();
|
||||||
|
for (const DNAANIM::Value& val : rotKeys)
|
||||||
|
{
|
||||||
|
atUint32 frame = *frameit++;
|
||||||
|
for (int c=0 ; c<4 ; ++c)
|
||||||
|
os.format("crv = rotCurves[%d]\n"
|
||||||
|
"crv.keyframe_points.add()\n"
|
||||||
|
"crv.keyframe_points[-1].interpolation = 'LINEAR'\n"
|
||||||
|
"crv.keyframe_points[-1].co = (%u, %f)\n",
|
||||||
|
c, frame, val.v4.vec[c]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bone.second)
|
||||||
|
{
|
||||||
|
const std::vector<DNAANIM::Value>& transKeys = *kit++;
|
||||||
|
auto frameit = frames.begin();
|
||||||
|
for (const DNAANIM::Value& val : transKeys)
|
||||||
|
{
|
||||||
|
atUint32 frame = *frameit++;
|
||||||
|
for (int c=0 ; c<3 ; ++c)
|
||||||
|
os.format("crv = transCurves[%d]\n"
|
||||||
|
"crv.keyframe_points.add()\n"
|
||||||
|
"crv.keyframe_points[-1].interpolation = 'LINEAR'\n"
|
||||||
|
"crv.keyframe_points[-1].co = (%u, %f - bone_trans_head[%d])\n",
|
||||||
|
c, frame, val.v4.vec[c], c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ANIM::ANIM0::read(Athena::io::IStreamReader& reader)
|
||||||
|
{
|
||||||
|
Header head;
|
||||||
|
head.read(reader);
|
||||||
|
mainInterval = head.interval;
|
||||||
|
|
||||||
|
frames.clear();
|
||||||
|
frames.reserve(head.keyCount);
|
||||||
|
for (size_t k=0 ; k<head.keyCount ; ++k)
|
||||||
|
frames.push_back(k);
|
||||||
|
|
||||||
|
std::map<atUint8, atUint32> boneMap;
|
||||||
|
for (size_t b=0 ; b<head.boneSlotCount ; ++b)
|
||||||
|
{
|
||||||
|
atUint8 idx = reader.readUByte();
|
||||||
|
if (idx == 0xff)
|
||||||
|
continue;
|
||||||
|
boneMap[idx] = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
atUint32 boneCount = reader.readUint32Big();
|
||||||
|
bones.clear();
|
||||||
|
bones.reserve(boneCount);
|
||||||
|
channels.clear();
|
||||||
|
for (size_t b=0 ; b<boneCount ; ++b)
|
||||||
|
{
|
||||||
|
bones.emplace_back(boneMap[b], false);
|
||||||
|
atUint8 idx = reader.readUByte();
|
||||||
|
channels.emplace_back();
|
||||||
|
DNAANIM::Channel& chan = channels.back();
|
||||||
|
chan.type = DNAANIM::Channel::ROTATION;
|
||||||
|
if (idx != 0xff)
|
||||||
|
{
|
||||||
|
bones.back().second = true;
|
||||||
|
channels.emplace_back();
|
||||||
|
DNAANIM::Channel& chan = channels.back();
|
||||||
|
chan.type = DNAANIM::Channel::TRANSLATION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.readUint32Big();
|
||||||
|
chanKeys.clear();
|
||||||
|
chanKeys.reserve(channels.size());
|
||||||
|
for (const std::pair<atUint32, bool>& bone : bones)
|
||||||
|
{
|
||||||
|
chanKeys.emplace_back();
|
||||||
|
std::vector<DNAANIM::Value>& keys = chanKeys.back();
|
||||||
|
for (size_t k=0 ; k<head.keyCount ; ++k)
|
||||||
|
keys.emplace_back(reader.readVec4fBig());
|
||||||
|
|
||||||
|
if (bone.second)
|
||||||
|
chanKeys.emplace_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.readUint32Big();
|
||||||
|
auto kit = chanKeys.begin();
|
||||||
|
for (const std::pair<atUint32, bool>& bone : bones)
|
||||||
|
{
|
||||||
|
++kit;
|
||||||
|
if (bone.second)
|
||||||
|
{
|
||||||
|
std::vector<DNAANIM::Value>& keys = *kit++;
|
||||||
|
for (size_t k=0 ; k<head.keyCount ; ++k)
|
||||||
|
keys.emplace_back(reader.readVec3fBig());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
evnt.read(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ANIM::ANIM0::write(Athena::io::IStreamWriter& writer) const
|
||||||
|
{
|
||||||
|
Header head;
|
||||||
|
head.unk0 = 0;
|
||||||
|
head.unk1 = 0;
|
||||||
|
head.unk2 = 0;
|
||||||
|
head.keyCount = frames.size();
|
||||||
|
head.duration = head.keyCount * mainInterval;
|
||||||
|
head.interval = mainInterval;
|
||||||
|
|
||||||
|
atUint32 maxId = 0;
|
||||||
|
for (const std::pair<atUint32, bool>& bone : bones)
|
||||||
|
maxId = MAX(maxId, bone.first);
|
||||||
|
head.boneSlotCount = maxId + 1;
|
||||||
|
head.write(writer);
|
||||||
|
|
||||||
|
for (size_t s=0 ; s<head.boneSlotCount ; ++s)
|
||||||
|
{
|
||||||
|
size_t boneIdx = 0;
|
||||||
|
bool found = false;
|
||||||
|
for (const std::pair<atUint32, bool>& bone : bones)
|
||||||
|
{
|
||||||
|
if (s == bone.first)
|
||||||
|
{
|
||||||
|
writer.writeUByte(boneIdx);
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++boneIdx;
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
writer.writeUByte(0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.writeUint32Big(bones.size());
|
||||||
|
size_t boneIdx = 0;
|
||||||
|
for (const std::pair<atUint32, bool>& bone : bones)
|
||||||
|
{
|
||||||
|
if (bone.second)
|
||||||
|
writer.writeUByte(boneIdx);
|
||||||
|
else
|
||||||
|
writer.writeUByte(0xff);
|
||||||
|
++boneIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.writeUint32Big(bones.size() * head.keyCount);
|
||||||
|
auto cit = chanKeys.begin();
|
||||||
|
atUint32 transKeyCount = 0;
|
||||||
|
for (const std::pair<atUint32, bool>& bone : bones)
|
||||||
|
{
|
||||||
|
const std::vector<DNAANIM::Value>& keys = *cit++;
|
||||||
|
auto kit = keys.begin();
|
||||||
|
for (size_t k=0 ; k<head.keyCount ; ++k)
|
||||||
|
writer.writeVec4fBig((*kit++).v4);
|
||||||
|
if (bone.second)
|
||||||
|
{
|
||||||
|
transKeyCount += head.keyCount;
|
||||||
|
++cit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.writeUint32Big(transKeyCount);
|
||||||
|
cit = chanKeys.begin();
|
||||||
|
for (const std::pair<atUint32, bool>& bone : bones)
|
||||||
|
{
|
||||||
|
++cit;
|
||||||
|
if (bone.second)
|
||||||
|
{
|
||||||
|
const std::vector<DNAANIM::Value>& keys = *cit++;
|
||||||
|
auto kit = keys.begin();
|
||||||
|
for (size_t k=0 ; k<head.keyCount ; ++k)
|
||||||
|
writer.writeVec3fBig((*kit++).v3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
evnt.write(writer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ANIM::ANIM2::read(Athena::io::IStreamReader& reader)
|
||||||
|
{
|
||||||
|
Header head;
|
||||||
|
head.read(reader);
|
||||||
|
evnt = head.evnt;
|
||||||
|
mainInterval = head.interval;
|
||||||
|
|
||||||
|
WordBitmap keyBmp;
|
||||||
|
keyBmp.read(reader, head.keyBitmapBitCount);
|
||||||
|
frames.clear();
|
||||||
|
atUint32 frameAccum = 0;
|
||||||
|
for (bool bit : keyBmp)
|
||||||
|
{
|
||||||
|
if (bit)
|
||||||
|
frames.push_back(frameAccum);
|
||||||
|
++frameAccum;
|
||||||
|
}
|
||||||
|
reader.seek(8);
|
||||||
|
|
||||||
|
bones.clear();
|
||||||
|
bones.reserve(head.boneChannelCount);
|
||||||
|
channels.clear();
|
||||||
|
channels.reserve(head.boneChannelCount);
|
||||||
|
size_t keyframeCount = 0;
|
||||||
|
for (size_t b=0 ; b<head.boneChannelCount ; ++b)
|
||||||
|
{
|
||||||
|
ChannelDesc desc;
|
||||||
|
desc.read(reader);
|
||||||
|
bones.emplace_back(desc.id, desc.keyCount2);
|
||||||
|
|
||||||
|
if (desc.keyCount1)
|
||||||
|
{
|
||||||
|
channels.emplace_back();
|
||||||
|
DNAANIM::Channel& chan = channels.back();
|
||||||
|
chan.type = DNAANIM::Channel::ROTATION;
|
||||||
|
chan.i[0] = desc.initRX;
|
||||||
|
chan.q[0] = desc.qRX;
|
||||||
|
chan.i[1] = desc.initRY;
|
||||||
|
chan.q[1] = desc.qRY;
|
||||||
|
chan.i[2] = desc.initRZ;
|
||||||
|
chan.q[2] = desc.qRZ;
|
||||||
|
}
|
||||||
|
keyframeCount = MAX(keyframeCount, desc.keyCount1);
|
||||||
|
|
||||||
|
if (desc.keyCount2)
|
||||||
|
{
|
||||||
|
channels.emplace_back();
|
||||||
|
DNAANIM::Channel& chan = channels.back();
|
||||||
|
chan.type = DNAANIM::Channel::TRANSLATION;
|
||||||
|
chan.i[0] = desc.initTX;
|
||||||
|
chan.q[0] = desc.qTX;
|
||||||
|
chan.i[1] = desc.initTY;
|
||||||
|
chan.q[1] = desc.qTY;
|
||||||
|
chan.i[2] = desc.initTZ;
|
||||||
|
chan.q[2] = desc.qTZ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t bsSize = DNAANIM::ComputeBitstreamSize(keyframeCount, channels);
|
||||||
|
std::unique_ptr<atUint8[]> bsData = reader.readUBytes(bsSize);
|
||||||
|
DNAANIM::BitstreamReader bsReader;
|
||||||
|
chanKeys = bsReader.read(bsData.get(), keyframeCount, channels, head.rotDiv, head.translationMult);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ANIM::ANIM2::write(Athena::io::IStreamWriter& writer) const
|
||||||
|
{
|
||||||
|
Header head;
|
||||||
|
head.evnt = evnt;
|
||||||
|
head.unk0 = 1;
|
||||||
|
head.interval = mainInterval;
|
||||||
|
head.unk1 = 3;
|
||||||
|
head.unk2 = 0;
|
||||||
|
head.unk3 = 1;
|
||||||
|
|
||||||
|
WordBitmap keyBmp;
|
||||||
|
size_t frameCount = 0;
|
||||||
|
for (atUint32 frame : frames)
|
||||||
|
{
|
||||||
|
while (keyBmp.getBit(frame))
|
||||||
|
++frame;
|
||||||
|
keyBmp.setBit(frame);
|
||||||
|
frameCount = frame + 1;
|
||||||
|
}
|
||||||
|
head.keyBitmapBitCount = frameCount;
|
||||||
|
head.duration = frameCount * mainInterval;
|
||||||
|
head.boneChannelCount = bones.size();
|
||||||
|
|
||||||
|
size_t keyframeCount = frames.size();
|
||||||
|
std::vector<DNAANIM::Channel> qChannels = channels;
|
||||||
|
DNAANIM::BitstreamWriter bsWriter;
|
||||||
|
size_t bsSize;
|
||||||
|
std::unique_ptr<atUint8[]> bsData = bsWriter.write(chanKeys, keyframeCount, qChannels,
|
||||||
|
head.rotDiv, head.translationMult, bsSize);
|
||||||
|
|
||||||
|
/* TODO: Figure out proper scratch size computation */
|
||||||
|
head.scratchSize = keyframeCount * channels.size() * 16;
|
||||||
|
|
||||||
|
head.write(writer);
|
||||||
|
keyBmp.write(writer);
|
||||||
|
writer.writeUint32Big(head.boneChannelCount);
|
||||||
|
writer.writeUint32Big(head.boneChannelCount);
|
||||||
|
auto cit = qChannels.begin();
|
||||||
|
for (const std::pair<atUint32, bool>& bone : bones)
|
||||||
|
{
|
||||||
|
ChannelDesc desc;
|
||||||
|
desc.id = bone.first;
|
||||||
|
DNAANIM::Channel& chan = *cit++;
|
||||||
|
desc.keyCount1 = keyframeCount;
|
||||||
|
desc.initRX = chan.i[0];
|
||||||
|
desc.qRX = chan.q[0];
|
||||||
|
desc.initRY = chan.i[1];
|
||||||
|
desc.qRY = chan.q[1];
|
||||||
|
desc.initRZ = chan.i[2];
|
||||||
|
desc.qRZ = chan.q[2];
|
||||||
|
if (bone.second)
|
||||||
|
{
|
||||||
|
DNAANIM::Channel& chan = *cit++;
|
||||||
|
desc.keyCount2 = keyframeCount;
|
||||||
|
desc.initTX = chan.i[0];
|
||||||
|
desc.qTX = chan.q[0];
|
||||||
|
desc.initTY = chan.i[1];
|
||||||
|
desc.qTY = chan.q[1];
|
||||||
|
desc.initTZ = chan.i[2];
|
||||||
|
desc.qTZ = chan.q[2];
|
||||||
|
}
|
||||||
|
desc.write(writer);
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.writeUBytes(bsData.get(), bsSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,174 @@
|
||||||
|
#ifndef _DNAMP2_ANIM_HPP_
|
||||||
|
#define _DNAMP2_ANIM_HPP_
|
||||||
|
|
||||||
|
#include "BlenderConnection.hpp"
|
||||||
|
#include "DNAMP2.hpp"
|
||||||
|
#include "../DNACommon/ANIM.hpp"
|
||||||
|
#include "CINF.hpp"
|
||||||
|
|
||||||
|
namespace Retro
|
||||||
|
{
|
||||||
|
namespace DNAMP2
|
||||||
|
{
|
||||||
|
|
||||||
|
struct ANIM : BigDNA
|
||||||
|
{
|
||||||
|
Delete expl;
|
||||||
|
|
||||||
|
struct IANIM : BigDNA
|
||||||
|
{
|
||||||
|
Delete expl;
|
||||||
|
atUint32 m_version;
|
||||||
|
IANIM(atUint32 version) : m_version(version) {}
|
||||||
|
|
||||||
|
std::vector<std::pair<atUint32, bool>> bones;
|
||||||
|
std::vector<atUint32> frames;
|
||||||
|
std::vector<DNAANIM::Channel> channels;
|
||||||
|
std::vector<std::vector<DNAANIM::Value>> chanKeys;
|
||||||
|
float mainInterval = 0.0;
|
||||||
|
UniqueID32 evnt;
|
||||||
|
|
||||||
|
void sendANIMToBlender(HECL::BlenderConnection::PyOutStream&, const CINF&) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ANIM0 : IANIM
|
||||||
|
{
|
||||||
|
DECL_EXPLICIT_DNA
|
||||||
|
ANIM0() : IANIM(0) {}
|
||||||
|
|
||||||
|
struct Header : BigDNA
|
||||||
|
{
|
||||||
|
DECL_DNA
|
||||||
|
Value<float> duration;
|
||||||
|
Value<atUint32> unk0;
|
||||||
|
Value<float> interval;
|
||||||
|
Value<atUint32> unk1;
|
||||||
|
Value<atUint32> keyCount;
|
||||||
|
Value<atUint32> unk2;
|
||||||
|
Value<atUint32> boneSlotCount;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ANIM2 : IANIM
|
||||||
|
{
|
||||||
|
DECL_EXPLICIT_DNA
|
||||||
|
ANIM2() : IANIM(2) {}
|
||||||
|
|
||||||
|
struct Header : BigDNA
|
||||||
|
{
|
||||||
|
DECL_DNA
|
||||||
|
Value<atUint32> scratchSize;
|
||||||
|
UniqueID32 evnt;
|
||||||
|
Value<atUint32> unk0;
|
||||||
|
Value<float> duration;
|
||||||
|
Value<float> interval;
|
||||||
|
Value<atUint32> unk1;
|
||||||
|
Value<atUint32> unk2;
|
||||||
|
Value<atUint32> rotDiv;
|
||||||
|
Value<float> translationMult;
|
||||||
|
Value<atUint32> boneChannelCount;
|
||||||
|
Value<atUint32> unk3;
|
||||||
|
Value<atUint32> keyBitmapBitCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ChannelDesc : BigDNA
|
||||||
|
{
|
||||||
|
Delete expl;
|
||||||
|
Value<atUint32> id = 0;
|
||||||
|
Value<atUint16> keyCount1 = 0;
|
||||||
|
Value<atUint16> initRX = 0;
|
||||||
|
Value<atUint8> qRX = 0;
|
||||||
|
Value<atUint16> initRY = 0;
|
||||||
|
Value<atUint8> qRY = 0;
|
||||||
|
Value<atUint16> initRZ = 0;
|
||||||
|
Value<atUint8> qRZ = 0;
|
||||||
|
Value<atUint16> keyCount2 = 0;
|
||||||
|
Value<atUint16> initTX = 0;
|
||||||
|
Value<atUint8> qTX = 0;
|
||||||
|
Value<atUint16> initTY = 0;
|
||||||
|
Value<atUint8> qTY = 0;
|
||||||
|
Value<atUint16> initTZ = 0;
|
||||||
|
Value<atUint8> qTZ = 0;
|
||||||
|
|
||||||
|
void read(Athena::io::IStreamReader& reader)
|
||||||
|
{
|
||||||
|
id = reader.readUint32Big();
|
||||||
|
keyCount1 = reader.readUint16Big();
|
||||||
|
initRX = reader.readUint16Big();
|
||||||
|
qRX = reader.readUByte();
|
||||||
|
initRY = reader.readUint16Big();
|
||||||
|
qRY = reader.readUByte();
|
||||||
|
initRZ = reader.readUint16Big();
|
||||||
|
qRZ = reader.readUByte();
|
||||||
|
keyCount2 = reader.readUint16Big();
|
||||||
|
if (keyCount2)
|
||||||
|
{
|
||||||
|
initTX = reader.readUint16Big();
|
||||||
|
qTX = reader.readUByte();
|
||||||
|
initTY = reader.readUint16Big();
|
||||||
|
qTY = reader.readUByte();
|
||||||
|
initTZ = reader.readUint16Big();
|
||||||
|
qTZ = reader.readUByte();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void write(Athena::io::IStreamWriter& writer) const
|
||||||
|
{
|
||||||
|
writer.writeUint32Big(id);
|
||||||
|
writer.writeUint16Big(keyCount1);
|
||||||
|
writer.writeUint16Big(initRX);
|
||||||
|
writer.writeUByte(qRX);
|
||||||
|
writer.writeUint16Big(initRY);
|
||||||
|
writer.writeUByte(qRY);
|
||||||
|
writer.writeUint16Big(initRZ);
|
||||||
|
writer.writeUByte(qRZ);
|
||||||
|
writer.writeUint16Big(keyCount2);
|
||||||
|
if (keyCount2)
|
||||||
|
{
|
||||||
|
writer.writeUint16Big(initTX);
|
||||||
|
writer.writeUByte(qTX);
|
||||||
|
writer.writeUint16Big(initTY);
|
||||||
|
writer.writeUByte(qTY);
|
||||||
|
writer.writeUint16Big(initTZ);
|
||||||
|
writer.writeUByte(qTZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unique_ptr<IANIM> m_anim;
|
||||||
|
void read(Athena::io::IStreamReader& reader)
|
||||||
|
{
|
||||||
|
atUint32 version = reader.readUint32Big();
|
||||||
|
switch (version)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
m_anim.reset(new struct ANIM0);
|
||||||
|
m_anim->read(reader);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
m_anim.reset(new struct ANIM2);
|
||||||
|
m_anim->read(reader);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Log.report(LogVisor::Error, "unrecognized ANIM version");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void write(Athena::io::IStreamWriter& writer) const
|
||||||
|
{
|
||||||
|
writer.writeUint32Big(m_anim->m_version);
|
||||||
|
m_anim->write(writer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendANIMToBlender(HECL::BlenderConnection::PyOutStream& os, const CINF& cinf) const
|
||||||
|
{
|
||||||
|
m_anim->sendANIMToBlender(os, cinf);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _DNAMP2_ANIM_HPP_
|
|
@ -1,10 +1,13 @@
|
||||||
make_dnalist(liblist
|
make_dnalist(liblist
|
||||||
MLVL
|
MLVL
|
||||||
|
ANIM
|
||||||
|
ANCS
|
||||||
CMDLMaterials
|
CMDLMaterials
|
||||||
CINF
|
CINF
|
||||||
CSKR)
|
CSKR)
|
||||||
add_library(DNAMP2
|
add_library(DNAMP2
|
||||||
DNAMP2.hpp DNAMP2.cpp
|
DNAMP2.hpp DNAMP2.cpp
|
||||||
${liblist}
|
${liblist}
|
||||||
|
ANIM.cpp
|
||||||
CMDL.hpp
|
CMDL.hpp
|
||||||
STRG.hpp STRG.cpp)
|
STRG.hpp STRG.cpp)
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "STRG.hpp"
|
#include "STRG.hpp"
|
||||||
#include "MLVL.hpp"
|
#include "MLVL.hpp"
|
||||||
#include "CMDL.hpp"
|
#include "CMDL.hpp"
|
||||||
|
#include "ANCS.hpp"
|
||||||
#include "../DNACommon/TXTR.hpp"
|
#include "../DNACommon/TXTR.hpp"
|
||||||
|
|
||||||
namespace Retro
|
namespace Retro
|
||||||
|
@ -188,7 +189,9 @@ ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const DNAMP1::PAK::Entry& ent
|
||||||
case SBIG('TXTR'):
|
case SBIG('TXTR'):
|
||||||
return {TXTR::Extract, nullptr, ".png"};
|
return {TXTR::Extract, nullptr, ".png"};
|
||||||
case SBIG('CMDL'):
|
case SBIG('CMDL'):
|
||||||
return {nullptr, CMDL::Extract, ".blend", 1};
|
return {nullptr, CMDL::Extract, ".blend", 2};
|
||||||
|
case SBIG('ANCS'):
|
||||||
|
return {nullptr, ANCS::Extract, nullptr, 1};
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,8 @@ namespace DNAMP2
|
||||||
|
|
||||||
void STRG::_read(Athena::io::IStreamReader& reader)
|
void STRG::_read(Athena::io::IStreamReader& reader)
|
||||||
{
|
{
|
||||||
atUint32 langCount = reader.readUint32();
|
atUint32 langCount = reader.readUint32Big();
|
||||||
atUint32 strCount = reader.readUint32();
|
atUint32 strCount = reader.readUint32Big();
|
||||||
|
|
||||||
std::vector<FourCC> readLangs;
|
std::vector<FourCC> readLangs;
|
||||||
readLangs.reserve(langCount);
|
readLangs.reserve(langCount);
|
||||||
|
@ -21,8 +21,8 @@ void STRG::_read(Athena::io::IStreamReader& reader)
|
||||||
reader.seek(8);
|
reader.seek(8);
|
||||||
}
|
}
|
||||||
|
|
||||||
atUint32 nameCount = reader.readUint32();
|
atUint32 nameCount = reader.readUint32Big();
|
||||||
atUint32 nameTableSz = reader.readUint32();
|
atUint32 nameTableSz = reader.readUint32Big();
|
||||||
std::unique_ptr<uint8_t[]> nameTableBuf(new uint8_t[nameTableSz]);
|
std::unique_ptr<uint8_t[]> nameTableBuf(new uint8_t[nameTableSz]);
|
||||||
reader.readUBytesToBuf(nameTableBuf.get(), nameTableSz);
|
reader.readUBytesToBuf(nameTableBuf.get(), nameTableSz);
|
||||||
struct NameIdxEntry
|
struct NameIdxEntry
|
||||||
|
@ -43,7 +43,7 @@ void STRG::_read(Athena::io::IStreamReader& reader)
|
||||||
std::vector<std::wstring> strs;
|
std::vector<std::wstring> strs;
|
||||||
reader.seek(strCount * 4);
|
reader.seek(strCount * 4);
|
||||||
for (atUint32 s=0 ; s<strCount ; ++s)
|
for (atUint32 s=0 ; s<strCount ; ++s)
|
||||||
strs.emplace_back(reader.readWString());
|
strs.emplace_back(reader.readWStringBig());
|
||||||
langs.emplace_back(lang, strs);
|
langs.emplace_back(lang, strs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,12 +55,11 @@ void STRG::_read(Athena::io::IStreamReader& reader)
|
||||||
|
|
||||||
void STRG::read(Athena::io::IStreamReader& reader)
|
void STRG::read(Athena::io::IStreamReader& reader)
|
||||||
{
|
{
|
||||||
reader.setEndian(Athena::BigEndian);
|
atUint32 magic = reader.readUint32Big();
|
||||||
atUint32 magic = reader.readUint32();
|
|
||||||
if (magic != 0x87654321)
|
if (magic != 0x87654321)
|
||||||
Log.report(LogVisor::Error, "invalid STRG magic");
|
Log.report(LogVisor::Error, "invalid STRG magic");
|
||||||
|
|
||||||
atUint32 version = reader.readUint32();
|
atUint32 version = reader.readUint32Big();
|
||||||
if (version != 1)
|
if (version != 1)
|
||||||
Log.report(LogVisor::Error, "invalid STRG version");
|
Log.report(LogVisor::Error, "invalid STRG version");
|
||||||
|
|
||||||
|
@ -69,18 +68,17 @@ void STRG::read(Athena::io::IStreamReader& reader)
|
||||||
|
|
||||||
void STRG::write(Athena::io::IStreamWriter& writer) const
|
void STRG::write(Athena::io::IStreamWriter& writer) const
|
||||||
{
|
{
|
||||||
writer.setEndian(Athena::BigEndian);
|
writer.writeUint32Big(0x87654321);
|
||||||
writer.writeUint32(0x87654321);
|
writer.writeUint32Big(1);
|
||||||
writer.writeUint32(1);
|
writer.writeUint32Big(langs.size());
|
||||||
writer.writeUint32(langs.size());
|
|
||||||
atUint32 strCount = STRG::count();
|
atUint32 strCount = STRG::count();
|
||||||
writer.writeUint32(strCount);
|
writer.writeUint32Big(strCount);
|
||||||
|
|
||||||
atUint32 offset = 0;
|
atUint32 offset = 0;
|
||||||
for (const std::pair<FourCC, std::vector<std::wstring>>& lang : langs)
|
for (const std::pair<FourCC, std::vector<std::wstring>>& lang : langs)
|
||||||
{
|
{
|
||||||
lang.first.write(writer);
|
lang.first.write(writer);
|
||||||
writer.writeUint32(offset);
|
writer.writeUint32Big(offset);
|
||||||
offset += strCount * 4 + 4;
|
offset += strCount * 4 + 4;
|
||||||
atUint32 langStrCount = lang.second.size();
|
atUint32 langStrCount = lang.second.size();
|
||||||
atUint32 tableSz = strCount * 4;
|
atUint32 tableSz = strCount * 4;
|
||||||
|
@ -98,19 +96,19 @@ void STRG::write(Athena::io::IStreamWriter& writer) const
|
||||||
tableSz += 1;
|
tableSz += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
writer.writeUint32(tableSz);
|
writer.writeUint32Big(tableSz);
|
||||||
}
|
}
|
||||||
|
|
||||||
atUint32 nameTableSz = names.size() * 8;
|
atUint32 nameTableSz = names.size() * 8;
|
||||||
for (const std::pair<std::string, int32_t>& name : names)
|
for (const std::pair<std::string, int32_t>& name : names)
|
||||||
nameTableSz += name.first.size() + 1;
|
nameTableSz += name.first.size() + 1;
|
||||||
writer.writeUint32(names.size());
|
writer.writeUint32Big(names.size());
|
||||||
writer.writeUint32(nameTableSz);
|
writer.writeUint32Big(nameTableSz);
|
||||||
offset = names.size() * 8;
|
offset = names.size() * 8;
|
||||||
for (const std::pair<std::string, int32_t>& name : names)
|
for (const std::pair<std::string, int32_t>& name : names)
|
||||||
{
|
{
|
||||||
writer.writeUint32(offset);
|
writer.writeUint32Big(offset);
|
||||||
writer.writeInt32(name.second);
|
writer.writeInt32Big(name.second);
|
||||||
offset += name.first.size() + 1;
|
offset += name.first.size() + 1;
|
||||||
}
|
}
|
||||||
for (const std::pair<std::string, int32_t>& name : names)
|
for (const std::pair<std::string, int32_t>& name : names)
|
||||||
|
@ -122,7 +120,7 @@ void STRG::write(Athena::io::IStreamWriter& writer) const
|
||||||
atUint32 langStrCount = lang.second.size();
|
atUint32 langStrCount = lang.second.size();
|
||||||
for (atUint32 s=0 ; s<strCount ; ++s)
|
for (atUint32 s=0 ; s<strCount ; ++s)
|
||||||
{
|
{
|
||||||
writer.writeUint32(offset);
|
writer.writeUint32Big(offset);
|
||||||
if (s < langStrCount)
|
if (s < langStrCount)
|
||||||
offset += lang.second[s].size() * 2 + 1;
|
offset += lang.second[s].size() * 2 + 1;
|
||||||
else
|
else
|
||||||
|
@ -132,7 +130,7 @@ void STRG::write(Athena::io::IStreamWriter& writer) const
|
||||||
for (atUint32 s=0 ; s<strCount ; ++s)
|
for (atUint32 s=0 ; s<strCount ; ++s)
|
||||||
{
|
{
|
||||||
if (s < langStrCount)
|
if (s < langStrCount)
|
||||||
writer.writeWString(lang.second[s]);
|
writer.writeWStringBig(lang.second[s]);
|
||||||
else
|
else
|
||||||
writer.writeUByte(0);
|
writer.writeUByte(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,20 +10,19 @@ const HECL::FourCC CMPD("CMPD");
|
||||||
|
|
||||||
void PAK::read(Athena::io::IStreamReader& reader)
|
void PAK::read(Athena::io::IStreamReader& reader)
|
||||||
{
|
{
|
||||||
reader.setEndian(Athena::BigEndian);
|
|
||||||
m_header.read(reader);
|
m_header.read(reader);
|
||||||
if (m_header.version != 2)
|
if (m_header.version != 2)
|
||||||
Log.report(LogVisor::FatalError, "unexpected PAK magic");
|
Log.report(LogVisor::FatalError, "unexpected PAK magic");
|
||||||
|
|
||||||
reader.seek(8, Athena::Current);
|
reader.seek(8, Athena::Current);
|
||||||
atUint32 strgSz = reader.readUint32();
|
atUint32 strgSz = reader.readUint32Big();
|
||||||
reader.seek(4, Athena::Current);
|
reader.seek(4, Athena::Current);
|
||||||
atUint32 rshdSz = reader.readUint32();
|
atUint32 rshdSz = reader.readUint32Big();
|
||||||
reader.seek(44, Athena::Current);
|
reader.seek(44, Athena::Current);
|
||||||
atUint32 dataOffset = 128 + strgSz + rshdSz;
|
atUint32 dataOffset = 128 + strgSz + rshdSz;
|
||||||
|
|
||||||
atUint64 strgBase = reader.position();
|
atUint64 strgBase = reader.position();
|
||||||
atUint32 nameCount = reader.readUint32();
|
atUint32 nameCount = reader.readUint32Big();
|
||||||
m_nameEntries.clear();
|
m_nameEntries.clear();
|
||||||
m_nameEntries.reserve(nameCount);
|
m_nameEntries.reserve(nameCount);
|
||||||
for (atUint32 n=0 ; n<nameCount ; ++n)
|
for (atUint32 n=0 ; n<nameCount ; ++n)
|
||||||
|
@ -36,7 +35,7 @@ void PAK::read(Athena::io::IStreamReader& reader)
|
||||||
atUint64 end = reader.position();
|
atUint64 end = reader.position();
|
||||||
atUint64 diff = end - start;
|
atUint64 diff = end - start;
|
||||||
|
|
||||||
atUint32 count = reader.readUint32();
|
atUint32 count = reader.readUint32Big();
|
||||||
m_entries.clear();
|
m_entries.clear();
|
||||||
m_entries.reserve(count);
|
m_entries.reserve(count);
|
||||||
m_idMap.clear();
|
m_idMap.clear();
|
||||||
|
@ -61,7 +60,6 @@ void PAK::read(Athena::io::IStreamReader& reader)
|
||||||
}
|
}
|
||||||
void PAK::write(Athena::io::IStreamWriter& writer) const
|
void PAK::write(Athena::io::IStreamWriter& writer) const
|
||||||
{
|
{
|
||||||
writer.setEndian(Athena::BigEndian);
|
|
||||||
m_header.write(writer);
|
m_header.write(writer);
|
||||||
|
|
||||||
FourCC("STRG").write(writer);
|
FourCC("STRG").write(writer);
|
||||||
|
@ -70,13 +68,13 @@ void PAK::write(Athena::io::IStreamWriter& writer) const
|
||||||
strgSz += (atUint32)entry.name.size() + 13;
|
strgSz += (atUint32)entry.name.size() + 13;
|
||||||
atUint32 strgPad = ((strgSz + 63) & ~63) - strgSz;
|
atUint32 strgPad = ((strgSz + 63) & ~63) - strgSz;
|
||||||
strgSz += strgPad;
|
strgSz += strgPad;
|
||||||
writer.writeUint32(strgSz);
|
writer.writeUint32Big(strgSz);
|
||||||
|
|
||||||
FourCC("RSHD").write(writer);
|
FourCC("RSHD").write(writer);
|
||||||
atUint32 rshdSz = 4 + 24 * m_entries.size();
|
atUint32 rshdSz = 4 + 24 * m_entries.size();
|
||||||
atUint32 rshdPad = ((rshdSz + 63) & ~63) - rshdSz;
|
atUint32 rshdPad = ((rshdSz + 63) & ~63) - rshdSz;
|
||||||
rshdSz += rshdPad;
|
rshdSz += rshdPad;
|
||||||
writer.writeUint32(rshdSz);
|
writer.writeUint32Big(rshdSz);
|
||||||
atUint32 dataOffset = 128 + strgSz + rshdSz;
|
atUint32 dataOffset = 128 + strgSz + rshdSz;
|
||||||
|
|
||||||
FourCC("DATA").write(writer);
|
FourCC("DATA").write(writer);
|
||||||
|
@ -85,15 +83,15 @@ void PAK::write(Athena::io::IStreamWriter& writer) const
|
||||||
dataSz += (entry.size + 63) & ~63;
|
dataSz += (entry.size + 63) & ~63;
|
||||||
atUint32 dataPad = ((dataSz + 63) & ~63) - dataSz;
|
atUint32 dataPad = ((dataSz + 63) & ~63) - dataSz;
|
||||||
dataSz += dataPad;
|
dataSz += dataPad;
|
||||||
writer.writeUint32(dataSz);
|
writer.writeUint32Big(dataSz);
|
||||||
writer.seek(36, Athena::Current);
|
writer.seek(36, Athena::Current);
|
||||||
|
|
||||||
writer.writeUint32((atUint32)m_nameEntries.size());
|
writer.writeUint32Big((atUint32)m_nameEntries.size());
|
||||||
for (const NameEntry& entry : m_nameEntries)
|
for (const NameEntry& entry : m_nameEntries)
|
||||||
entry.write(writer);
|
entry.write(writer);
|
||||||
writer.seek(strgPad, Athena::Current);
|
writer.seek(strgPad, Athena::Current);
|
||||||
|
|
||||||
writer.writeUint32((atUint32)m_entries.size());
|
writer.writeUint32Big((atUint32)m_entries.size());
|
||||||
for (const Entry& entry : m_entries)
|
for (const Entry& entry : m_entries)
|
||||||
{
|
{
|
||||||
Entry copy = entry;
|
Entry copy = entry;
|
||||||
|
|
|
@ -8,11 +8,11 @@ namespace DNAMP3
|
||||||
|
|
||||||
void STRG::_read(Athena::io::IStreamReader& reader)
|
void STRG::_read(Athena::io::IStreamReader& reader)
|
||||||
{
|
{
|
||||||
atUint32 langCount = reader.readUint32();
|
atUint32 langCount = reader.readUint32Big();
|
||||||
atUint32 strCount = reader.readUint32();
|
atUint32 strCount = reader.readUint32Big();
|
||||||
|
|
||||||
atUint32 nameCount = reader.readUint32();
|
atUint32 nameCount = reader.readUint32Big();
|
||||||
atUint32 nameTableSz = reader.readUint32();
|
atUint32 nameTableSz = reader.readUint32Big();
|
||||||
if (nameTableSz)
|
if (nameTableSz)
|
||||||
{
|
{
|
||||||
std::unique_ptr<uint8_t[]> nameTableBuf(new uint8_t[nameTableSz]);
|
std::unique_ptr<uint8_t[]> nameTableBuf(new uint8_t[nameTableSz]);
|
||||||
|
@ -40,9 +40,9 @@ void STRG::_read(Athena::io::IStreamReader& reader)
|
||||||
std::unique_ptr<atUint32[]> strOffs(new atUint32[langCount * strCount]);
|
std::unique_ptr<atUint32[]> strOffs(new atUint32[langCount * strCount]);
|
||||||
for (atUint32 l=0 ; l<langCount ; ++l)
|
for (atUint32 l=0 ; l<langCount ; ++l)
|
||||||
{
|
{
|
||||||
reader.readUint32();
|
reader.readUint32Big();
|
||||||
for (atUint32 s=0 ; s<strCount ; ++s)
|
for (atUint32 s=0 ; s<strCount ; ++s)
|
||||||
strOffs[l*strCount+s] = reader.readUint32();
|
strOffs[l*strCount+s] = reader.readUint32Big();
|
||||||
}
|
}
|
||||||
|
|
||||||
atUint64 strBase = reader.position();
|
atUint64 strBase = reader.position();
|
||||||
|
@ -54,7 +54,7 @@ void STRG::_read(Athena::io::IStreamReader& reader)
|
||||||
for (atUint32 s=0 ; s<strCount ; ++s)
|
for (atUint32 s=0 ; s<strCount ; ++s)
|
||||||
{
|
{
|
||||||
reader.seek(strBase + strOffs[l*strCount+s], Athena::Begin);
|
reader.seek(strBase + strOffs[l*strCount+s], Athena::Begin);
|
||||||
atUint32 len = reader.readUint32();
|
atUint32 len = reader.readUint32Big();
|
||||||
strs.emplace_back(reader.readString(len));
|
strs.emplace_back(reader.readString(len));
|
||||||
}
|
}
|
||||||
langs.emplace_back(readLangs[l], strs);
|
langs.emplace_back(readLangs[l], strs);
|
||||||
|
@ -68,15 +68,14 @@ void STRG::_read(Athena::io::IStreamReader& reader)
|
||||||
|
|
||||||
void STRG::read(Athena::io::IStreamReader& reader)
|
void STRG::read(Athena::io::IStreamReader& reader)
|
||||||
{
|
{
|
||||||
reader.setEndian(Athena::BigEndian);
|
atUint32 magic = reader.readUint32Big();
|
||||||
atUint32 magic = reader.readUint32();
|
|
||||||
if (magic != 0x87654321)
|
if (magic != 0x87654321)
|
||||||
{
|
{
|
||||||
Log.report(LogVisor::Error, "invalid STRG magic");
|
Log.report(LogVisor::Error, "invalid STRG magic");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
atUint32 version = reader.readUint32();
|
atUint32 version = reader.readUint32Big();
|
||||||
if (version != 3)
|
if (version != 3)
|
||||||
{
|
{
|
||||||
Log.report(LogVisor::Error, "invalid STRG version");
|
Log.report(LogVisor::Error, "invalid STRG version");
|
||||||
|
@ -154,23 +153,22 @@ void STRG::fromYAML(Athena::io::YAMLDocReader& reader)
|
||||||
|
|
||||||
void STRG::write(Athena::io::IStreamWriter& writer) const
|
void STRG::write(Athena::io::IStreamWriter& writer) const
|
||||||
{
|
{
|
||||||
writer.setEndian(Athena::BigEndian);
|
writer.writeUint32Big(0x87654321);
|
||||||
writer.writeUint32(0x87654321);
|
writer.writeUint32Big(3);
|
||||||
writer.writeUint32(3);
|
writer.writeUint32Big(langs.size());
|
||||||
writer.writeUint32(langs.size());
|
|
||||||
atUint32 strCount = STRG::count();
|
atUint32 strCount = STRG::count();
|
||||||
writer.writeUint32(strCount);
|
writer.writeUint32Big(strCount);
|
||||||
|
|
||||||
atUint32 nameTableSz = names.size() * 8;
|
atUint32 nameTableSz = names.size() * 8;
|
||||||
for (const auto& name : names)
|
for (const auto& name : names)
|
||||||
nameTableSz += name.first.size() + 1;
|
nameTableSz += name.first.size() + 1;
|
||||||
writer.writeUint32(names.size());
|
writer.writeUint32Big(names.size());
|
||||||
writer.writeUint32(nameTableSz);
|
writer.writeUint32Big(nameTableSz);
|
||||||
atUint32 offset = names.size() * 8;
|
atUint32 offset = names.size() * 8;
|
||||||
for (const auto& name : names)
|
for (const auto& name : names)
|
||||||
{
|
{
|
||||||
writer.writeUint32(offset);
|
writer.writeUint32Big(offset);
|
||||||
writer.writeInt32(name.second);
|
writer.writeInt32Big(name.second);
|
||||||
offset += name.first.size() + 1;
|
offset += name.first.size() + 1;
|
||||||
}
|
}
|
||||||
for (const auto& name : names)
|
for (const auto& name : names)
|
||||||
|
@ -185,11 +183,11 @@ void STRG::write(Athena::io::IStreamWriter& writer) const
|
||||||
atUint32 langSz = 0;
|
atUint32 langSz = 0;
|
||||||
for (const std::string& str : lang.second)
|
for (const std::string& str : lang.second)
|
||||||
langSz += str.size() + 5;
|
langSz += str.size() + 5;
|
||||||
writer.writeUint32(langSz);
|
writer.writeUint32Big(langSz);
|
||||||
|
|
||||||
for (const std::string& str : lang.second)
|
for (const std::string& str : lang.second)
|
||||||
{
|
{
|
||||||
writer.writeUint32(offset);
|
writer.writeUint32Big(offset);
|
||||||
offset += str.size() + 5;
|
offset += str.size() + 5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,13 +198,13 @@ void STRG::write(Athena::io::IStreamWriter& writer) const
|
||||||
{
|
{
|
||||||
if (s >= lang.second.size())
|
if (s >= lang.second.size())
|
||||||
{
|
{
|
||||||
writer.writeUint32(1);
|
writer.writeUint32Big(1);
|
||||||
writer.writeUByte(0);
|
writer.writeUByte(0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const std::string& str = lang.second[s];
|
const std::string& str = lang.second[s];
|
||||||
writer.writeUint32(str.size() + 1);
|
writer.writeUint32Big(str.size() + 1);
|
||||||
writer.writeString(str);
|
writer.writeString(str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue