#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); qint64 strTabBegin = in.device()->pos(); for (int i = 0; i < fileCount; i++) { quint32 offs; in >> offs; qint64 saveMe = in.device()->pos(); in.device()->seek(strTabBegin + offs); 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; } } }