public static void Export(string ddscTextureFile, string outputBaseName) { var texture = new TextureFile(); string xmlOutFile = outputBaseName + ".xml"; string hmddscFile = outputBaseName + ".hmddsc"; var settings = new XmlWriterSettings { Indent = true, IndentChars = "\t", CheckCharacters = false, }; bool haveHMDDSCFile = File.Exists(hmddscFile); using (var input = File.OpenRead(ddscTextureFile)) { texture.Deserialize(input); uint biggestIndex = 0; uint biggestSize = 0; // The DDS file (look for the biggest one) for (uint i = 0; i < texture.Elements.Length; ++i) { if (texture.Elements[i].Size == 0) { continue; } if ((haveHMDDSCFile && texture.Elements[i].IsExternal) || (texture.Elements[i].IsExternal == false) && texture.Elements[i].Size > biggestSize) { biggestSize = texture.Elements[i].Size; biggestIndex = i; } } if (texture.Elements[biggestIndex].IsExternal == false) { SaveDDSFile(outputBaseName, biggestIndex, texture, input); // load internal texture } else { SaveDDSFile(outputBaseName, biggestIndex, texture, null); // load external texture (from hmddsc file) } } // the XML metadata using (var xmlOutput = File.Create(xmlOutFile)) using (var writer = XmlWriter.Create(xmlOutput, settings)) { writer.WriteStartDocument(); writer.WriteStartElement("texture"); writer.WriteAttributeString("write-to-hmddsc", haveHMDDSCFile.ToString(CultureInfo.InvariantCulture)); writer.WriteStartElement("header"); writer.WriteAttributeString("unknown-06", texture.Unknown06.ToString("X8")); writer.WriteAttributeString("unknown-1C", texture.Unknown1C.ToString("X8")); writer.WriteAttributeString("dimension", texture.Dimension.ToString(CultureInfo.InvariantCulture)); writer.WriteAttributeString("depth", texture.Depth.ToString(CultureInfo.InvariantCulture)); writer.WriteAttributeString("mip-count", texture.MipCount.ToString(CultureInfo.InvariantCulture)); writer.WriteAttributeString("hdr-mip-count", texture.HeaderMipCount.ToString(CultureInfo.InvariantCulture)); writer.WriteAttributeString("flags", texture.Flags.ToString("X8")); writer.WriteEndElement(); // Will emit a warning (or sometime fail) if not the same writer.WriteStartElement("check"); writer.WriteAttributeString("width", texture.Height.ToString(CultureInfo.InvariantCulture)); writer.WriteAttributeString("height", texture.Width.ToString(CultureInfo.InvariantCulture)); writer.WriteAttributeString("format", texture.Format.ToString(CultureInfo.InvariantCulture)); writer.WriteEndElement(); writer.WriteStartElement("elements"); foreach (var element in texture.Elements) { writer.WriteStartElement("element"); writer.WriteAttributeString("offset", element.Offset.ToString(CultureInfo.InvariantCulture)); writer.WriteAttributeString("size", element.Size.ToString(CultureInfo.InvariantCulture)); writer.WriteAttributeString("external", element.IsExternal.ToString(CultureInfo.InvariantCulture)); writer.WriteAttributeString("unknown8", element.Unknown8.ToString("X8")); writer.WriteAttributeString("unknownA", element.UnknownA.ToString("X8")); writer.WriteEndElement(); } writer.WriteEndElement(); writer.WriteEndElement(); writer.WriteEndDocument(); } }
private static void Main(string[] args) { bool showHelp = false; bool overwriteFiles = false; bool verbose = true; var options = new OptionSet() { { "o|overwrite", "overwrite existing files", v => overwriteFiles = v != null }, { "v|verbose", "be verbose", v => verbose = v != null }, { "h|help", "show this message and exit", v => showHelp = v != null }, }; List <string> extras; try { extras = options.Parse(args); } catch (OptionException e) { Console.Write("{0}: ", GetExecutableName()); Console.WriteLine(e.Message); Console.WriteLine("Try `{0} --help' for more information.", GetExecutableName()); return; } if (extras.Count < 1 || extras.Count > 2 || showHelp == true) { Console.WriteLine("Usage: {0} [OPTIONS]+ input_file.ddsc [output_file.dds]", GetExecutableName()); Console.WriteLine(); Console.WriteLine("Options:"); options.WriteOptionDescriptions(Console.Out); return; } string inputPath = extras[0]; string outputPath = extras.Count > 1 ? extras[1] : Path.ChangeExtension(inputPath, null) + ".dds"; using (var input = File.OpenRead(inputPath)) { var texture = new TextureFile(); texture.Deserialize(input); using (var output = File.Create(outputPath)) { const Endian endian = Endian.Little; var header = new Squish.DDS.Header() { Flags = Squish.DDS.HeaderFlags.Texture | Squish.DDS.HeaderFlags.Mipmap, Width = texture.Width, Height = texture.Height, PitchOrLinearSize = 0, Depth = 0, MipMapCount = texture.MipCount, PixelFormat = GetPixelFormat(texture), SurfaceFlags = 8, CubemapFlags = 0, }; output.WriteValueU32(0x20534444, endian); header.Serialize(output, endian); if (header.PixelFormat.FourCC == 0x30315844) { output.WriteValueU32(texture.Format, endian); output.WriteValueU32(2, endian); output.WriteValueU32(0, endian); output.WriteValueU32(1, endian); output.WriteValueU32(0, endian); } input.Position = texture.Elements[0].Offset; output.WriteFromStream(input, texture.Elements[0].Size); } } }