void MREA::StreamReader::writeSecIdxs(athena::io::IStreamWriter& writer) const { for (const std::pair<DNAFourCC, atUint32>& idx : m_secIdxs) { idx.first.write(writer); writer.writeUint32Big(idx.second); } }
void STRG::write(athena::io::IStreamWriter& writer) const { writer.writeUint32Big(0x87654321); writer.writeUint32Big(0); writer.writeUint32Big(langs.size()); atUint32 strCount = STRG::count(); writer.writeUint32Big(strCount); atUint32 offset = 0; for (const std::pair<FourCC, std::vector<std::wstring>>& lang : langs) { DNAFourCC(lang.first).write(writer); writer.writeUint32Big(offset); offset += strCount * 4 + 4; atUint32 langStrCount = lang.second.size(); for (atUint32 s=0 ; s<strCount ; ++s) { atUint32 chCount = lang.second[s].size(); if (s < langStrCount) offset += chCount * 2 + 1; else offset += 1; } } for (const std::pair<FourCC, std::vector<std::wstring>>& lang : langs) { atUint32 langStrCount = lang.second.size(); atUint32 tableSz = strCount * 4; for (atUint32 s=0 ; s<strCount ; ++s) { if (s < langStrCount) tableSz += lang.second[s].size() * 2 + 1; else tableSz += 1; } writer.writeUint32Big(tableSz); offset = strCount * 4; for (atUint32 s=0 ; s<strCount ; ++s) { writer.writeUint32Big(offset); if (s < langStrCount) offset += lang.second[s].size() * 2 + 1; else offset += 1; } for (atUint32 s=0 ; s<strCount ; ++s) { if (s < langStrCount) writer.writeWStringBig(lang.second[s]); else writer.writeUByte(0); } } }
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); }
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 = std::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); }