public void Rebuild(string fname) { FileOutput o = new FileOutput(); FileOutput h = new FileOutput(); FileOutput d = new FileOutput(); FileOutput s = new FileOutput(); // bfres header o.writeString("FRES"); o.writeByte(verNumA); o.writeByte(verNumB); o.writeByte(verNumC); o.writeByte(verNumD); o.writeShort(0xFEFF); // endianness o.writeShort(0x0010); // version number? 0x0010 int fileSize = o.size(); o.writeInt(0); // file length o.writeInt(0x00002000); // file alignment usuallt 0x00002000 o.writeOffset(s.getStringOffset(Text), s); int stringTableSize = o.size(); o.writeInt(0); int stringTableOffset = o.size(); o.writeInt(0); o.writeInt(0); o.writeInt(0); o.writeInt(0); o.writeInt(0); o.writeInt(0); o.writeInt(0); o.writeInt(0); o.writeInt(0); o.writeInt(0); o.writeInt(0); o.writeInt(0); o.writeInt(0); o.writeShort(0); o.writeShort(0); o.writeShort(0); o.writeShort(0); o.writeShort(0); o.writeShort(0); o.writeShort(0); o.writeShort(0); o.writeShort(0); o.writeShort(0); o.writeShort(0); o.writeShort(0); foreach (TreeNode n in Nodes) { if (n.Text.Equals("FMDLs")) { o.writeIntAt(o.size(), 0x20); o.writeShortAt(n.Nodes.Count, 0x50); IndexGroup group = new IndexGroup(); // create an index group and save it foreach (FMDL mdl in n.Nodes) { group.nodes.Add(mdl); } group.Save(o, h, s, d); } } o.writeOutput(h); o.writeIntAt(o.size(), stringTableOffset); o.writeIntAt(s.size(), stringTableSize); o.writeOutput(s); o.writeOutput(d); o.writeIntAt(o.size(), fileSize); o.save(fname); }
// note: offsets are self relative public void Read(FileData f) { data = f; f.Endian = Endianness.Big; f.seek(4); // magic check high = f.readByte(); low = f.readByte(); overall = f.readShort(); // overall version if (f.readShort() == 0xFEFF) { f.Endian = Endianness.Big; } else { f.Endian = Endianness.Little; } f.skip(2); // version number? 0x0010 f.skip(4); // file length f.skip(4); // file alignment usuallt 0x00002000 /*Note, alignment is for gpu addresses so not important for this*/ Text = f.readString(f.readOffset(), -1); // Console.WriteLine("Reading " + ModelName); f.skip(4); // string table length int stringTableOffset = f.readOffset(); int FMDLOffset = f.readOffset(); int FTEXOffset = f.readOffset(); int FSKAOffset = f.readOffset(); int FSHU0Offset = f.readOffset(); int FSHU1Offset = f.readOffset(); int FSHU2Offset = f.readOffset(); int FTXPOffset = f.readOffset(); int FVIS0Offset = f.readOffset(); int FVIS1Offset = f.readOffset(); int FSHAOffset = f.readOffset(); int FSCNOffset = f.readOffset(); int EMBOffset = f.readOffset(); int FMDLCount = f.readShort(); int FTEXCount = f.readShort(); int FSKACount = f.readShort(); int FSHU0Count = f.readShort(); int FSHU1Count = f.readShort(); int FSHU2Count = f.readShort(); int FTXPCount = f.readShort(); int FVIS0Count = f.readShort(); int FVIS1Count = f.readShort(); int FSHACount = f.readShort(); int FSCNCount = f.readShort(); int EMBCount = f.readShort(); // INDEX GROUPS f.seek(FMDLOffset); IndexGroup fmdlGroup = new IndexGroup(f); TreeNode modelGroup = new TreeNode(); modelGroup.Text = "FMDLs"; modelGroup.ImageKey = "folder"; modelGroup.SelectedImageKey = "folder"; Nodes.Add(modelGroup); for (int i = 0; i < FMDLCount; i++) { f.seek(fmdlGroup.dataOffsets[i]); modelGroup.Nodes.Add(new FMDL(f)); } f.seek(FTEXOffset); IndexGroup ftexGroup = new IndexGroup(f); TreeNode texGroup = new TreeNode(); texGroup.Text = "FTEXs"; texGroup.ImageKey = "folder"; texGroup.SelectedImageKey = "folder"; Nodes.Add(texGroup); for (int i = 0; i < FTEXCount; i++) { f.seek(ftexGroup.dataOffsets[i]); texGroup.Nodes.Add(new FTEX(f) { Text = ftexGroup.names[i] }); } f.seek(FSKAOffset); IndexGroup fskaGroup = new IndexGroup(f); TreeNode animGroup = new TreeNode(); animGroup.Text = "FSKAs"; animGroup.ImageKey = "folder"; animGroup.SelectedImageKey = "folder"; Nodes.Add(animGroup); for (int i = 0; i < FSKACount; i++) { f.seek(fskaGroup.dataOffsets[i]); Console.WriteLine(fskaGroup.names[i] + " 0x" + fskaGroup.dataOffsets[i].ToString("x")); animGroup.Nodes.Add(new FSKA(f)); } f.seek(FSHU0Offset); IndexGroup fshu0Group = new IndexGroup(f); TreeNode shu0Group = new TreeNode(); shu0Group.Text = "FSHU0s"; shu0Group.ImageKey = "folder"; shu0Group.SelectedImageKey = "folder"; Nodes.Add(shu0Group); for (int i = 0; i < FSHU0Count; i++) { //f.seek(fshu0Group.dataOffsets[i]); shu0Group.Nodes.Add(new TreeNode() { Text = fshu0Group.names[i] }); } f.seek(FSHU1Offset); //IndexGroup fshu1Group = new IndexGroup(f); TreeNode shu1Group = new TreeNode(); shu1Group.Text = "FSHU1s"; shu1Group.ImageKey = "folder"; shu1Group.SelectedImageKey = "folder"; Nodes.Add(shu1Group); for (int i = 0; i < FSHU1Count; i++) { //f.seek(fshu1Group.dataOffsets[i]); //shu1Group.Nodes.Add(new TreeNode() { Text = fshu1Group.names[i] }); } f.seek(FSHU2Offset); IndexGroup fshu2Group = new IndexGroup(f); TreeNode shu2Group = new TreeNode(); shu2Group.Text = "FSHU2s"; shu2Group.ImageKey = "folder"; shu2Group.SelectedImageKey = "folder"; Nodes.Add(shu2Group); for (int i = 0; i < FSHU2Count; i++) { //f.seek(fshu2Group.dataOffsets[i]); shu2Group.Nodes.Add(new TreeNode() { Text = fshu2Group.names[i] }); } f.seek(FTXPOffset); IndexGroup ftxpGroup = new IndexGroup(f); TreeNode txpGroup = new TreeNode(); txpGroup.Text = "FTXPs"; txpGroup.ImageKey = "folder"; txpGroup.SelectedImageKey = "folder"; Nodes.Add(txpGroup); for (int i = 0; i < FTXPCount; i++) { //f.seek(ftxpGroup.dataOffsets[i]); txpGroup.Nodes.Add(new TreeNode() { Text = ftxpGroup.names[i] }); } f.seek(FVIS0Offset); IndexGroup fvis0Group = new IndexGroup(f); TreeNode vis0Group = new TreeNode(); vis0Group.Text = "FVIS0s"; vis0Group.ImageKey = "folder"; vis0Group.SelectedImageKey = "folder"; Nodes.Add(vis0Group); for (int i = 0; i < FVIS0Count; i++) { //f.seek(fvis0Group.dataOffsets[i]); vis0Group.Nodes.Add(new TreeNode() { Text = fvis0Group.names[i] }); } f.seek(FVIS1Offset); IndexGroup fvis1Group = new IndexGroup(f); TreeNode vis1Group = new TreeNode(); vis1Group.Text = "FVIS1s"; vis1Group.ImageKey = "folder"; vis1Group.SelectedImageKey = "folder"; Nodes.Add(vis1Group); for (int i = 0; i < FVIS1Count; i++) { //f.seek(fvis1Group.dataOffsets[i]); vis1Group.Nodes.Add(new TreeNode() { Text = fvis1Group.names[i] }); } f.seek(FSHAOffset); //IndexGroup fshaGroup = new IndexGroup(f); TreeNode shaGroup = new TreeNode(); shaGroup.Text = "FSHAs"; shaGroup.ImageKey = "folder"; shaGroup.SelectedImageKey = "folder"; Nodes.Add(shaGroup); for (int i = 0; i < FSHACount; i++) { //f.seek(fshaGroup.dataOffsets[i]); //shaGroup.Nodes.Add(new TreeNode() { Text = fshaGroup.names[i] }); } f.seek(FSCNOffset); IndexGroup fscnGroup = new IndexGroup(f); TreeNode scnGroup = new TreeNode(); scnGroup.Text = "FSCNs"; scnGroup.ImageKey = "folder"; scnGroup.SelectedImageKey = "folder"; Nodes.Add(scnGroup); for (int i = 0; i < FSCNCount; i++) { //f.seek(fscnGroup.dataOffsets[i]); scnGroup.Nodes.Add(new TreeNode() { Text = fscnGroup.names[i] }); } /*f.seek(EMBOffset); * IndexGroup fembGroup = new IndexGroup(f); * TreeNode embGroup = new TreeNode(); * embGroup.Text = "Embedded Files"; * embGroup.ImageKey = "folder"; * embGroup.SelectedImageKey = "folder"; * Nodes.Add(embGroup); * for (int i = 0; i < EMBCount; i++) * { * //f.seek(fembGroup.dataOffsets[i]); * embGroup.Nodes.Add(new TreeNode() { Text = fembGroup.names[i] }); * }*/ }
// note: offsets are self relative public void Read(FileData f) { data = f; f.seek(4); // magic check f.skip(4); // Padding f.Endian = Endianness.Little; verNumD = f.readByte(); verNumC = f.readByte(); verNumB = f.readByte(); verNumA = f.readByte(); f.Endian = Endianness.Big; Console.WriteLine("Version = " + verNumA + "." + verNumB + "." + verNumC + "." + verNumD); if (f.readShort() == 0xFEFF) { f.Endian = Endianness.Big; } else { f.Endian = Endianness.Little; } f.skip(2); // sizHeader f.skip(4); // FileNameOffsetToString f.skip(4); // file alignment usuallt 0x00002000 int RelocationTableOffset = f.readOffset(); int BfresSize = f.readOffset(); /*Note, alignment is for gpu addresses so not important for this*/ Text = f.readString(f.readOffset() + 2, -1); // Console.WriteLine("Reading " + ModelName); f.skip(4); // Padding int FMDLOffset = f.readOffset(); f.skip(4); // Padding int FMDLDict = f.readOffset(); f.skip(4); // Padding int FSKAOffset = f.readOffset(); f.skip(4); // Padding int FSKADict = f.readOffset(); f.skip(4); // Padding int FMAAOffset = f.readOffset(); f.skip(4); // Padding int FMAADict = f.readOffset(); f.skip(4); // Padding int FVISOffset = f.readOffset(); f.skip(4); // Padding int FVISDict = f.readOffset(); f.skip(4); // Padding int FSHUOffset = f.readOffset(); f.skip(4); // Padding int FSHUDict = f.readOffset(); f.skip(4); // Padding int FSCNOffset = f.readOffset(); f.skip(4); // Padding int FSCNDict = f.readOffset(); f.skip(4); // Padding int BuffMemPool = f.readOffset(); f.skip(4); // Padding int BuffMemPoolInfo = f.readOffset(); f.skip(4); // Padding int EMBOffset = f.readOffset(); f.skip(4); // Padding EMBDict = f.readOffset(); f.skip(12); // Padding int StringTableOffset = f.readOffset(); f.skip(4); // Padding int unk11 = f.readOffset(); int FMDLCount = f.readShort(); int FSKACount = f.readShort(); int FMAACount = f.readShort(); int FVISCount = f.readShort(); int FSHUCount = f.readShort(); int FSCNCount = f.readShort(); int EMBCount = f.readShort(); f.skip(12); // Padding Console.WriteLine("EMBDict" + BFRES.EMBDict); // INDEX GROUPS //This is pretty messy atm. Makes sure offsets don't = 0. TreeNode modelGroup = new TreeNode(); modelGroup.Text = "Models"; modelGroup.ImageKey = "folder"; modelGroup.SelectedImageKey = "folder"; Nodes.Add(modelGroup); if (FMDLOffset != 0) { f.seek(FMDLDict); IndexGroup fmdlGroup = new IndexGroup(f); for (int i = 0; i < FMDLCount; i++) { f.seek(FMDLOffset + (i * 120)); modelGroup.Nodes.Add(new FMDL(f)); } } TreeNode animGroup = new TreeNode(); animGroup.Text = "Skeleton Animations"; animGroup.ImageKey = "folder"; animGroup.SelectedImageKey = "folder"; Nodes.Add(animGroup); if (FSKAOffset != 0) { f.seek(FSKADict); IndexGroup fskaGroup = new IndexGroup(f); for (int i = 0; i < FSKACount; i++) { f.seek(FSKAOffset + (i * 96)); animGroup.Nodes.Add(new FSKA(f)); } } TreeNode MAAGroup = new TreeNode(); MAAGroup.Text = "Material Animations"; MAAGroup.ImageKey = "folder"; MAAGroup.SelectedImageKey = "folder"; Nodes.Add(MAAGroup); if (FMAAOffset != 0) { f.seek(FMAAOffset); IndexGroup FMAAGroup = new IndexGroup(f); for (int i = 0; i < FMAACount; i++) { f.seek(FMAAOffset + (i * 120)); MAAGroup.Nodes.Add(new FMAA(f)); } } TreeNode VISGroup = new TreeNode(); VISGroup.Text = "Visual Animations"; VISGroup.ImageKey = "folder"; VISGroup.SelectedImageKey = "folder"; Nodes.Add(VISGroup); if (FVISOffset != 0) { f.seek(FVISDict); IndexGroup FVISGroup = new IndexGroup(f); for (int i = 0; i < FVISCount; i++) { f.seek(FVISOffset + (i * 104)); VISGroup.Nodes.Add(new FVIS(f)); } } TreeNode SHUGroup = new TreeNode(); SHUGroup.Text = "Shape Animations"; SHUGroup.ImageKey = "folder"; SHUGroup.SelectedImageKey = "folder"; Nodes.Add(SHUGroup); if (FSHUOffset != 0) { f.seek(FSHUDict); IndexGroup FSHUGroup = new IndexGroup(f); for (int i = 0; i < FSHUCount; i++) { f.seek(FMAAOffset + (i * 104)); SHUGroup.Nodes.Add(new FSHU(f)); } } TreeNode SCNGroup = new TreeNode(); SCNGroup.Text = "Scene Animations"; SCNGroup.ImageKey = "folder"; SCNGroup.SelectedImageKey = "folder"; Nodes.Add(SCNGroup); if (FSCNOffset != 0) { f.seek(FSCNDict); IndexGroup FSCNGroup = new IndexGroup(f); for (int i = 0; i < FSCNCount; i++) { f.seek(FSCNOffset + (i * 120)); SCNGroup.Nodes.Add(new FSCN(f)); } } TreeNode embGroup = new TreeNode(); embGroup.Text = "Embedded Files"; embGroup.ImageKey = "folder"; embGroup.SelectedImageKey = "folder"; Nodes.Add(embGroup); if (EMBOffset != 0) { f.seek(EMBDict); IndexGroup fembGroup = new IndexGroup(f); for (int i = 0; i < EMBCount; i++) { f.seek(EMBOffset + (i * 16)); embGroup.Nodes.Add(new ExternalFiles(f) { Text = fembGroup.names[i] }); } } }
public FMDL(FileData f) { ImageKey = "model"; SelectedImageKey = "model"; f.skip(4); // MAGIC int fnameOffset = f.readOffset(); Text = f.readString(fnameOffset, -1); f.skip(4); // pointer to end of string table? int FSKLOffset = f.readOffset(); int FVTXOffset = f.readOffset(); int FSHPOffset = f.readOffset(); int FMATOffset = f.readOffset(); int PARAMOffset = f.readOffset(); int FVTXCount = f.readShort(); int FSHPCount = f.readShort(); int FMATCount = f.readShort(); int PARAMCount = f.readShort(); f.skip(4); // unknown possible facecount or something? // firstly Imma do the skeleton f.seek(FSKLOffset); skel = new FSKL(); skel.Read(f); Nodes.Add(skel); // FMAT is obs materials f.seek(FMATOffset); IndexGroup fmatGroup = new IndexGroup(f); for (int i = 0; i < FMATCount; i++) { f.seek(fmatGroup.dataOffsets[i]); mats.Add(new FMAT(f)); } // FVTX is the vertex buffer object attributes f.seek(FVTXOffset); for (int i = 0; i < FVTXCount; i++) { vertattr.Add(new FVTX(f)); } // FSHP is the mesh objects f.seek(FSHPOffset); IndexGroup fmdlGroup = new IndexGroup(f); for (int i = 0; i < FSHPCount; i++) { f.seek(fmdlGroup.dataOffsets[i]); shapes.Add(new FSHP(f)); } Nodes.AddRange(shapes.ToArray()); Nodes.AddRange(vertattr.ToArray()); Nodes.AddRange(mats.ToArray()); GL.GenBuffers(1, out ibo); }