public static Tex FromStream(Stream input) { using (AwesomeReader ar = new AwesomeReader(input)) { int version; bool valid, useExternal = true; Tex tex = new Tex(""); // Guesses endianess ar.BigEndian = DetermineEndianess(ar.ReadBytes(4), out version, out valid); if (!valid) { return(null); // Probably do something else later } int idk = ar.ReadInt32(); // Skips duplicate width, height, bpp info if (version < 10) { ar.BaseStream.Position += 8; } else if (idk == 0) { ar.BaseStream.Position += 17; } else { ar.BaseStream.Position += 21; } tex.ExternalPath = ar.ReadString(); // Relative path if (version != 5) { ar.BaseStream.Position += 8; // Skips unknown stuff useExternal = ar.ReadBoolean(); } else { ar.BaseStream.Position += 5; // Amp doesn't embed textures? } // Parses hmx image //if (!useExternal) tex.Image = HMXImage.FromStream(ar.BaseStream); tex.BigEndian = ar.BigEndian; return(tex); } }
private static byte[] ADDE_PADDING = { 0xAD, 0xDE, 0xAD, 0xDE }; // Used to pad files private static MiloFile ParseDirectory(AwesomeReader ar, BlockStructure structure, uint offset) { bool origBigEndian = ar.BigEndian; // Used to preserve orig stream MiloFile milo; MiloVersion version; bool valid; string dirName, dirType; string[] entryNames, entryTypes; // Guesses endianess ar.BigEndian = DetermineEndianess(ar.ReadBytes(4), out version, out valid); if (!valid) { return(null); // Maybe do something else later } ParseEntryNames(ar, version, out dirName, out dirType, out entryNames, out entryTypes); milo = new MiloFile(dirName, dirType, ar.BigEndian); milo._structure = structure; milo._offset = offset; milo._version = version; // TODO: Add component parser (Difficult) if (version == MiloVersion.V10) { milo._externalResources = new List <string>(GetExternalResources(ar)); } else if (version == MiloVersion.V24) { /* * if (dirName == "alterna1") // Hacky fix, please remove! * { * ar.BaseStream.Position += 117; * Trans tran = new Trans(dirName); * * // Reads view matrices * tran.Mat1 = Matrix.FromStream(ar); * ar.BaseStream.Position += 4; * tran.Mat2 = Matrix.FromStream(ar); * ar.BaseStream.Position += 4; * * milo.Entries.Add(tran); * } * else if (dirName == "dancer1") // Hacky fix, please remove! * { * ar.BaseStream.Position += 31; * Trans tran = new Trans(dirName); * * // Reads view matrices * tran.Mat1 = Matrix.FromStream(ar); * ar.BaseStream.Position += 4; * tran.Mat2 = Matrix.FromStream(ar); * ar.BaseStream.Position += 4; * * milo.Entries.Add(tran); * }*/ // Skips unknown stuff for now ar.FindNext(ADDE_PADDING); ar.BaseStream.Position += 4; } // Reads each file for (int i = 0; i < entryNames.Length; i++) { long start = ar.BaseStream.Position; int size = (int)(ar.FindNext(ADDE_PADDING)); byte[] bytes; // Reads raw file bytes ar.BaseStream.Position = start; bytes = ar.ReadBytes(size); ar.BaseStream.Position += 4; // Jumps ADDE padding switch (entryTypes[i]) { case "Tex": using (MemoryStream ms = new MemoryStream(bytes)) { AbstractEntry entry = Tex.FromStream(ms); if (entry == null) { goto defaultCase; } entry.Name = entryNames[i]; milo.Entries.Add(entry); } break; case "Mesh": using (MemoryStream ms = new MemoryStream(bytes)) { AbstractEntry entry = Mesh.FromStream(ms); if (entry == null) { goto defaultCase; } entry.Name = entryNames[i]; milo.Entries.Add(entry); } break; case "View": using (MemoryStream ms = new MemoryStream(bytes)) { AbstractEntry entry = View.FromStream(ms); if (entry == null) { goto defaultCase; } entry.Name = entryNames[i]; milo.Entries.Add(entry); } break; case "Group": using (MemoryStream ms = new MemoryStream(bytes)) { AbstractEntry entry = View.FromStreamAsGroup(ms); if (entry == null) { goto defaultCase; } entry.Name = entryNames[i]; milo.Entries.Add(entry); } break; case "Mat": using (MemoryStream ms = new MemoryStream(bytes)) { AbstractEntry entry = Mat.FromStream(ms); if (entry == null) { goto defaultCase; } entry.Name = entryNames[i]; milo.Entries.Add(entry); } break; case "Trans": using (MemoryStream ms = new MemoryStream(bytes)) { AbstractEntry entry = Trans.FromStream(ms); if (entry == null) { goto defaultCase; } entry.Name = entryNames[i]; milo.Entries.Add(entry); } break; default: defaultCase: milo.Entries.Add(new MiloEntry(entryNames[i], entryTypes[i], bytes, milo.BigEndian)); break; } /* TODO: Implement milo files as entries * if (type[i] == "ObjectDir" || type[i] == "MoveDir") * { * // Directory embedded as an entry * // Skips over redundant directory info * ar.BaseStream.Position += 4; * dir.Entries.Add(MiloFile.FromStream(ar)); * } * else * { * // Regular entry * ar.BaseStream.Position = start; * dir.Entries.Add(new MEntry(name[i], type[i], ar.ReadBytes(size))); * ar.BaseStream.Position += 4; * } */ } ar.BigEndian = origBigEndian; return(milo); }