|
| 1 | +using System; |
| 2 | +using System.Collections.Generic; |
| 3 | +using System.Linq; |
| 4 | +using System.Text; |
| 5 | +using System.Threading.Tasks; |
| 6 | + |
| 7 | +namespace MorcuTool |
| 8 | +{ |
| 9 | + public class MsaAnimation |
| 10 | + { |
| 11 | + |
| 12 | + public class Table1Entry { //setting table 1's count to 1 turns the animation into a T-pose in-game |
| 13 | + |
| 14 | + public uint unk1; //start frame, possibly? |
| 15 | + public uint unk2; //flags? padding? usually 0 |
| 16 | + public uint unk3; //u32 end of this frame's data, relative to the unknown section offset. The start of the frame's data is the end of the previous one (or from the unknown section offset if it's the first frame) |
| 17 | + |
| 18 | + public Table1Entry(byte[] filebytes, int offset) { |
| 19 | + unk1 = Utility.ReadUInt32BigEndian(filebytes, offset); |
| 20 | + unk2 = Utility.ReadUInt32BigEndian(filebytes, offset+4); |
| 21 | + unk3 = Utility.ReadUInt32BigEndian(filebytes, offset+8); |
| 22 | + } |
| 23 | + } |
| 24 | + |
| 25 | + public class Table2Entry //setting table 2's count to 1 doesn't seem to change anything in-game |
| 26 | + { |
| 27 | + public uint unk1; // u32 flags? padding? usually 0x00000001 |
| 28 | + public uint unk2; // u32 offset to something (relative to unknown section 1) |
| 29 | + public uint unk3; // u32 usually 0 ? |
| 30 | + public uint unk4; // u32 offset to float data for bone movement |
| 31 | + |
| 32 | + public Table2Entry(byte[] filebytes, int offset) { |
| 33 | + |
| 34 | + unk1 = Utility.ReadUInt32BigEndian(filebytes, offset); |
| 35 | + unk2 = Utility.ReadUInt32BigEndian(filebytes, offset + 4); |
| 36 | + unk3 = Utility.ReadUInt32BigEndian(filebytes, offset + 8); |
| 37 | + unk4 = Utility.ReadUInt32BigEndian(filebytes, offset + 12); |
| 38 | + } |
| 39 | + } |
| 40 | + |
| 41 | + public class BoneTableEntry |
| 42 | + { |
| 43 | + public uint unk1; |
| 44 | + public uint unk2; |
| 45 | + public uint unk3; |
| 46 | + public uint boneNameHash; |
| 47 | + public uint unk4; //usually 1? |
| 48 | + public uint unk5; |
| 49 | + public uint unk6; |
| 50 | + public uint unk7; |
| 51 | + |
| 52 | + public BoneTableEntry(byte[] filebytes, int offset) |
| 53 | + { |
| 54 | + unk1 = Utility.ReadUInt32BigEndian(filebytes, offset); |
| 55 | + unk2 = Utility.ReadUInt32BigEndian(filebytes, offset+4); |
| 56 | + unk3 = Utility.ReadUInt32BigEndian(filebytes, offset+8); |
| 57 | + boneNameHash = Utility.ReadUInt32BigEndian(filebytes, offset+12); |
| 58 | + unk4 = Utility.ReadUInt32BigEndian(filebytes, offset+16); |
| 59 | + unk5 = Utility.ReadUInt32BigEndian(filebytes, offset+20); |
| 60 | + unk6 = Utility.ReadUInt32BigEndian(filebytes, offset+24); |
| 61 | + unk7 = Utility.ReadUInt32BigEndian(filebytes, offset+28); |
| 62 | + Console.WriteLine("Found bone: " + boneNameHash); |
| 63 | + } |
| 64 | + } |
| 65 | + |
| 66 | + public uint dataSectionOffset; |
| 67 | + public uint boneTableRelativeOffset; |
| 68 | + public uint firstTableOffset; |
| 69 | + public uint firstTableCount; |
| 70 | + public uint secondTableOffset; |
| 71 | + public uint secondTableCount; |
| 72 | + |
| 73 | + public List<Table1Entry> table1 = new List<Table1Entry>(); |
| 74 | + public List<Table2Entry> table2 = new List<Table2Entry>(); |
| 75 | + public List<BoneTableEntry> boneTable = new List<BoneTableEntry>(); |
| 76 | + |
| 77 | + public MsaAnimation(Subfile basis) { |
| 78 | + |
| 79 | + dataSectionOffset = Utility.ReadUInt32BigEndian(basis.filebytes,0x6C); |
| 80 | + boneTableRelativeOffset = Utility.ReadUInt32BigEndian(basis.filebytes, 0x40); |
| 81 | + |
| 82 | + firstTableOffset = Utility.ReadUInt32BigEndian(basis.filebytes, 0x84); |
| 83 | + firstTableCount = Utility.ReadUInt32BigEndian(basis.filebytes, 0x88); |
| 84 | + secondTableOffset = Utility.ReadUInt32BigEndian(basis.filebytes, 0x8C); |
| 85 | + secondTableCount = Utility.ReadUInt32BigEndian(basis.filebytes, 0x90); |
| 86 | + |
| 87 | + for (int i = 0; i < firstTableCount; i++){ |
| 88 | + table1.Add(new Table1Entry(basis.filebytes, (int)(firstTableOffset + (i * 0x0C)))); |
| 89 | + } |
| 90 | + |
| 91 | + for (int i = 0; i < secondTableCount; i++){ |
| 92 | + table2.Add(new Table2Entry(basis.filebytes, (int)(secondTableOffset + (i * 0x0C)))); |
| 93 | + } |
| 94 | + |
| 95 | + uint boneTableCount = Utility.ReadUInt32BigEndian(basis.filebytes, (int)(dataSectionOffset + boneTableRelativeOffset + 0x80)); |
| 96 | + |
| 97 | + for (int i = 0; i < boneTableCount; i++) { |
| 98 | + boneTable.Add(new BoneTableEntry(basis.filebytes, (int)(dataSectionOffset + boneTableRelativeOffset + 0xF0 + (i * 0x20)))); |
| 99 | + } |
| 100 | + } |
| 101 | + } |
| 102 | +} |
0 commit comments