#include "CFBStreamedCompression.hpp" namespace urde { CFBStreamedCompression::CFBStreamedCompression(CInputStream& in, IObjectStore& objStore) { x0_scratchSize = in.readUint32Big(); x4_evnt = in.readUint32Big(); xc_rotsAndOffs = GetRotationsAndOffsets(x0_scratchSize / 4 + 1, in); if (x4_evnt) x8_evntToken = objStore.GetObj(SObjectTag{FOURCC('EVNT'), x4_evnt}); } std::unique_ptr CFBStreamedCompression::GetRotationsAndOffsets(u32 words, CInputStream& in) { std::unique_ptr ret(new u32[words]); Header head; head.read(in); *reinterpret_cast(ret.get()) = head; u32* bitmapOut = &ret[9]; u32 bitmapBitCount = in.readUint32Big(); bitmapOut[0] = bitmapBitCount; u32 bitmapWordCount = (bitmapBitCount + 31) / 32; for (u32 i=0 ; i(bitmapOut + bitmapWordCount + 1); u8* bs = ReadBoneChannelDescriptors(chans, in); u32 bsWords = ComputeBitstreamWords(chans); u32* bsPtr = reinterpret_cast(bs); for (u32 w=0 ; w(out) = boneChanCount; out += 4; for (int b=0 ; b(out) = in.readUint32Big(); out += 4; *reinterpret_cast(out) = in.readUint16Big(); out += 2; for (int i=0 ; i<3 ; ++i) { *reinterpret_cast(out) = in.readInt16Big(); out += 2; *reinterpret_cast(out) = in.readUByte(); out += 1; } u16 tCount = in.readUint16Big(); *reinterpret_cast(out) = tCount; out += 2; if (tCount) { for (int i=0 ; i<3 ; ++i) { *reinterpret_cast(out) = in.readInt16Big(); out += 2; *reinterpret_cast(out) = in.readUByte(); out += 1; } } } return out; } u32 CFBStreamedCompression::ComputeBitstreamWords(const u8* chans) { u32 boneChanCount = *reinterpret_cast(chans); chans += 4; u16 keyCount = *reinterpret_cast(chans); u32 totalBits = 0; for (u32 c=0 ; c(chans + 0x8); totalBits += *reinterpret_cast(chans + 0xb); totalBits += *reinterpret_cast(chans + 0xe); u16 tKeyCount = *reinterpret_cast(chans + 0xf); chans += 0x11; if (tKeyCount) { totalBits += *reinterpret_cast(chans + 0x2); totalBits += *reinterpret_cast(chans + 0x5); totalBits += *reinterpret_cast(chans + 0x8); chans += 0x9; } } return (totalBits * keyCount + 31) / 32; } }