summaryrefslogtreecommitdiff
path: root/lyt/animation.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--lyt/animation.cpp220
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 &section, 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;
+ }
+ }
+}