diff options
Diffstat (limited to 'lyt/animation.cpp')
-rw-r--r-- | lyt/animation.cpp | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/lyt/animation.cpp b/lyt/animation.cpp new file mode 100644 index 0000000..d5e87d3 --- /dev/null +++ b/lyt/animation.cpp @@ -0,0 +1,220 @@ +#include "animation.h" +#include "lyt/binaryfile.h" + +LYTAnimation::~LYTAnimation() { + +} + +LYTAnimation::LYTAnimation(QByteArray data) { + LYTBinaryFile file(data); + + foreach (const LYTBinaryFileSection §ion, file.sections) { + switch (section.magic.value) { + case 'pat1': { + // Info + QDataStream in(section.data); + InitDataStream(in); + + quint16 groupCount; + quint32 nameOffset, groupOffset; + quint8 flag; + + in >> sourceTagNumber; + in >> groupCount; + in >> nameOffset; + in >> groupOffset; + in >> sourceStartFrame; + in >> sourceEndFrame; + in >> flag; + + qDebug() << "Source: Tag:" << sourceTagNumber << "- Frames:" << sourceStartFrame << "to" << sourceEndFrame; + qDebug() << "Groups: Offset" << groupOffset << ", count" << groupCount << "- Name offset:" << nameOffset; + + recursiveBind = ((flag & 1) != 0); + qDebug() << "Flag:" << flag << "; Recursive bind:" << recursiveBind; + + in.device()->seek(nameOffset - 8); + // a royal hack + name = ReadFixedLengthASCII(in, groupOffset-nameOffset); + qDebug() << "Rlan name:" << name; + + groups.reserve(groupCount); + in.device()->seek(groupOffset - 8); + + for (int i = 0; i < groupCount; i++) { + LYTAnimGroupInfo info; + info.name = ReadFixedLengthASCII(in, 17); + in >> info.unusedFlag; + in.skipRawData(2); + groups.append(info); + + qDebug() << "Group name:" << info.name; + } + + break; + } + + case 'pai1': { + // Bits + QDataStream in(section.data); + InitDataStream(in); + + quint8 loop; + quint16 fileCount, blockCount; + quint32 offsetOffset; + + in >> frameSize; + in >> loop; + in.skipRawData(1); + in >> fileCount; + in >> blockCount; + in >> offsetOffset; + + qDebug() << "Loop:" << loop << "- File count:" << fileCount << ", Block count:" << blockCount; + qDebug() << "Offset Offset:" << offsetOffset; + + this->loop = (loop & 1); + + importedFiles.reserve(fileCount); + + for (int i = 0; i < fileCount; i++) { + quint32 offs; + in >> offs; + + qint64 saveMe = in.device()->pos(); + in.device()->seek(offs-8); + importedFiles.append(ReadVariableLengthASCII(in)); + in.device()->seek(saveMe); + + qDebug() << "Imported file:" << importedFiles.last(); + } + + // Now, each block + in.device()->seek(offsetOffset-8); + blocks.reserve(blockCount); + + for (int i = 0; i < blockCount; i++) { + quint32 blockOffs; + in >> blockOffs; + qint64 saveInList = in.device()->pos(); + in.device()->seek(blockOffs - 8); + + // Block. + LYTAnimBlock block; + block.name = ReadFixedLengthASCII(in, 20); + quint8 pieceCount, type; + in >> pieceCount; + in >> type; + in.skipRawData(2); + + block.isMaterial = (type == 1); + + qDebug() << "Block @ " << QString::number(blockOffs,16) << ":" << block.name << "- Piece Count:" << pieceCount << "- Type:" << type << "IsMaterial:" << block.isMaterial; + + // Now, the piece list + block.pieces.reserve(pieceCount); + + for (int j = 0; j < pieceCount; j++) { + quint32 pieceOffs; + in >> pieceOffs; + qint64 saveInList2 = in.device()->pos(); + in.device()->seek(blockOffs + pieceOffs - 8); + + // Piece + LYTAnimPiece piece; + Magic pieceMagic(0); + in >> pieceMagic.value; + + switch (pieceMagic.value) { + case 'RLPA': piece.type = piece.PaneAnim; break; + case 'RLTS': piece.type = piece.TexSRTAnim; break; + case 'RLVI': piece.type = piece.VisAnim; break; + case 'RLVC': piece.type = piece.VtxClrAnim; break; + case 'RLMC': piece.type = piece.MatClrAnim; break; + case 'RLTP': piece.type = piece.TexPatAnim; break; + case 'RLIM': piece.type = piece.IndTexSRTAnim; break; + } + + quint8 entryCount; + in >> entryCount; + in.skipRawData(3); + qDebug("Piece: %c%c%c%c, Entry Count: %d", pieceMagic.str[3], pieceMagic.str[2], pieceMagic.str[1], pieceMagic.str[0], entryCount); + + piece.entries.reserve(entryCount); + + // ANOTHER LIST ARGHHHH + for (int k = 0; k < entryCount; k++) { + quint32 entryOffs; + in >> entryOffs; + qint64 saveInList3 = in.device()->pos(); + in.device()->seek(blockOffs + pieceOffs + entryOffs - 8); + + // Entry + LYTAnimEntry entry; + in >> entry.id; + in >> entry.target; + in >> entry.curveType; + in.skipRawData(1); + + quint16 keyCount; + quint32 keyOffset; + + in >> keyCount; + in.skipRawData(2); + in >> keyOffset; + + qDebug() << "Entry ID:" << entry.id << "Target:" << entry.target << "CurveType:" << entry.curveType << "KeyCount:" << keyCount << "KeyOffset:" << keyOffset; + + in.device()->seek(blockOffs + pieceOffs + entryOffs + keyOffset - 8); + + if (piece.type == piece.TexPatAnim || piece.type == piece.VisAnim) { + entry.stepKeys.reserve(keyCount); + + for (int l = 0; l < keyCount; l++) { + // Step Key + LYTAnimStepKey key; + in >> key.frame; + in >> key.value; + in.skipRawData(2); + qDebug() << "Step Key:" << key.frame << key.value; + + entry.stepKeys.append(key); + } + + } else { + entry.keys.reserve(keyCount); + + for (int l = 0; l < keyCount; l++) { + // Key + LYTAnimHermiteKey key; + in >> key.frame; + in >> key.value; + in >> key.slope; + qDebug() << "Key:" << key.frame << key.value << key.slope; + + entry.keys.append(key); + } + } + + piece.entries.append(entry); + in.device()->seek(saveInList3); + } + + block.pieces.append(piece); + in.device()->seek(saveInList2); + } + + blocks.append(block); + in.device()->seek(saveInList); + } + + break; + } + + case 'pah1': + // Share + qFatal("AnimShare unsupported"); + break; + } + } +} |