// 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] }); * }*/ }
public FTEX(FileData f) { ImageKey = "texture"; SelectedImageKey = "texture"; if (!f.readString(4).Equals("FTEX")) { throw new Exception("Error reading Texture"); } sur = new GTX.GX2Surface() { dim = f.readInt(), width = f.readInt(), height = f.readInt(), depth = f.readInt(), numMips = f.readInt(), format = f.readInt(), aa = f.readInt(), use = f.readInt() }; int datalength = f.readInt(); f.skip(4); // unknown sur.mipSize = f.readInt(); f.skip(4); // unknown sur.tileMode = f.readInt(); sur.swizzle = f.readInt(); sur.alignment = f.readInt(); sur.pitch = f.readInt(); f.skip(0x6C); // unknown int dataOff = f.readOffset(); int mipOff = f.readOffset(); f.skip(8); //unkown sur.data = f.getSection(dataOff, datalength); //Console.WriteLine(sur.data.Length + " " + dataOff.ToString("x") + " " + datalength); byte[] data = GTX.swizzleBC(sur.data, sur.width, sur.height, sur.format, sur.tileMode, sur.pitch, sur.swizzle); tex.mipmaps.Add(data); tex.width = sur.width; tex.height = sur.height; //File.WriteAllBytes(dataOff.ToString("x") + ".bin" ,data); switch (sur.format) { case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC1_UNORM): tex.type = PixelInternalFormat.CompressedRgbaS3tcDxt1Ext; break; case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC1_SRGB): tex.type = PixelInternalFormat.CompressedSrgbAlphaS3tcDxt1Ext; break; case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC2_UNORM): tex.type = PixelInternalFormat.CompressedRgbaS3tcDxt3Ext; break; case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC2_SRGB): tex.type = PixelInternalFormat.CompressedSrgbAlphaS3tcDxt3Ext; break; case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC3_UNORM): tex.type = PixelInternalFormat.CompressedRgbaS3tcDxt5Ext; break; case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC3_SRGB): tex.type = PixelInternalFormat.CompressedSrgbAlphaS3tcDxt5Ext; break; case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC4_UNORM): tex.type = PixelInternalFormat.CompressedRedRgtc1; break; case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC4_SNORM): tex.type = PixelInternalFormat.CompressedSignedRedRgtc1; break; case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC5_UNORM): tex.type = PixelInternalFormat.CompressedRgRgtc2; break; case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC5_SNORM): tex.type = PixelInternalFormat.CompressedSignedRgRgtc2; break; case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM): tex.type = PixelInternalFormat.Rgba; tex.utype = OpenTK.Graphics.OpenGL.PixelFormat.Rgba; break; default: return; } tex.load(); }
public FSKANode(FileData f) { ImageKey = "bone"; SelectedImageKey = "bone"; flags = f.readInt(); Text = f.readString(f.readOffset(), -1); flags2 = f.readInt(); stride = f.readByte(); f.skip(3); // dunno 0 padding? int offTrack = f.readOffset(); int offBase = f.readOffset(); trackCount = (flags2 & 0x0000FF00) >> 8; trackFlag = (flags & 0x0000FF00) >> 8; int temp = f.pos(); // offset 1 is base positions //Console.WriteLine(off1.ToString("x")); f.seek(offBase); sca = new Vector3(f.readFloat(), f.readFloat(), f.readFloat()); rot = new Vector3(f.readFloat(), f.readFloat(), f.readFloat()); f.skip(4); // for quaternion, but 1.0 if eul pos = new Vector3(f.readFloat(), f.readFloat(), f.readFloat()); f.seek(offTrack); for (int tr = 0; tr < trackCount; tr++) { FSKATrack t = (new FSKATrack() { offset = f.pos(), type = (short)f.readShort(), keyCount = (short)f.readShort(), flag = f.readInt(), unk2 = f.readInt(), frameCount = f.readFloat(), scale = f.readFloat(), init = f.readFloat(), unkf3 = f.readFloat(), offtolastKeys = f.readOffset(), offtolastData = f.readOffset() }); tracks.Add(t); if (t.type != 0x2 && t.type != 0x5 && t.type != 0x6 && t.type != 0x9 && t.type != 0xA) { Console.WriteLine(Text + " " + t.type.ToString("x")); } int tem = f.pos(); // bone section f.seek(t.offtolastKeys); int[] frames = new int[t.keyCount]; for (int i = 0; i < t.keyCount; i++) { if (t.type == 0x1 || t.type == 0x5 || t.type == 0x9) { frames[i] = f.readShort() >> 5; } else { frames[i] = f.readByte(); } } f.align(4); float tanscale = t.unkf3; if (tanscale == 0) { tanscale = 1; } f.seek(t.offtolastData); for (int i = 0; i < t.keyCount; i++) { switch (t.type) { case 0x2: t.keys.Add(new FSKAKey() { frame = frames[i], unk1 = t.init + ((f.readFloat() * t.scale)), unk2 = f.readFloat(), unk3 = f.readFloat(), unk4 = f.readFloat(), }); break; case 0x5: t.keys.Add(new FSKAKey() { frame = frames[i], unk1 = t.init + (((short)f.readShort() * t.scale)), unk2 = t.unkf3 + (((short)f.readShort() * t.scale)), unk3 = t.unkf3 + (((short)f.readShort() * t.scale)), unk4 = t.unkf3 + (((short)f.readShort() * t.scale)) }); break; case 0x6: t.keys.Add(new FSKAKey() { frame = frames[i], unk1 = t.init + (((short)f.readShort() * t.scale)), unk2 = t.unkf3 + (((short)f.readShort() / (float)0x7FFF)), unk3 = t.unkf3 + (((short)f.readShort() / (float)0x7FFF)), unk4 = t.unkf3 + (((short)f.readShort() / (float)0x7FFF)) }); break; case 0x9: t.keys.Add(new FSKAKey() { frame = frames[i], unk1 = t.init + (((sbyte)f.readByte() * t.scale)), unk2 = t.unkf3 + (((sbyte)f.readByte() * t.scale)), unk3 = t.unkf3 + (((sbyte)f.readByte() * t.scale)), unk4 = t.unkf3 + (((sbyte)f.readByte() * t.scale)) }); break; case 0xA: t.keys.Add(new FSKAKey() { frame = frames[i], unk1 = t.init + (((sbyte)f.readByte() * t.scale)), unk2 = t.unkf3 + (((sbyte)f.readByte() * t.scale)), unk3 = t.unkf3 + (((sbyte)f.readByte() * t.scale)), unk4 = t.unkf3 + (((sbyte)f.readByte() * t.scale)) }); break; default: break; } } f.seek(tem); } f.seek(temp); }