private static void PatchXPR2Header(byte[] header, int t, int tOffset, int h, int hOffset, int w, int wOffset) { using (AwesomeWriter aw = new AwesomeWriter(new MemoryStream(header), true)) { // Encodes texture size, height, and width aw.Seek(tOffset, SeekOrigin.Begin); aw.Write((int)t); aw.Seek(hOffset, SeekOrigin.Begin); aw.Write((short)((h >> 3) - 1)); aw.Seek(wOffset, SeekOrigin.Begin); aw.Write((short)((w - 1) | 0xE000)); } }
private void WriteToStream(Stream stream) { MagickImage image = new MagickImage(_image); image.Format = MagickFormat.Dxt5; // Header info byte[] header; int hOffset, wOffset, bpp; int textureDataOffset = 2060; switch (image.Format) { case MagickFormat.Dxt1: header = xpr2_dxt1_120x120.ToArray(); image.Resize(120, 120); hOffset = 0x50; wOffset = 0x52; bpp = 4; break; case MagickFormat.Dxt5: header = xpr2_dxt5_2048x2048.ToArray(); image.Resize(2048, 2048); hOffset = 0x60; wOffset = 0x62; bpp = 8; break; default: // This shouldn't happen return; } // Reads raw texture data byte[] textureData = new byte[((image.Height * image.Width) * 8) / bpp]; using (MemoryStream ms = new MemoryStream()) { // Writes DDS to stream image.Write(ms); // Copies raw DXT data ms.Seek(128, SeekOrigin.Begin); // Skips header ms.Read(textureData, 0, textureData.Length); } // Writes xpr2 header PatchXPR2Header(header, textureData.Length, 8, image.Height, hOffset, image.Width, wOffset); // Converts to x360 format textureData = TileCompressedXbox360Texture(textureData, image.Width, image.Width, image.Height, image.Height, 4, 4, (16 * bpp) / 8); SwapBytes(textureData); // Writes to XPR2 stream using (AwesomeWriter aw = new AwesomeWriter(stream, true)) { aw.Write(header); aw.Seek(textureDataOffset, SeekOrigin.Begin); aw.Write(textureData); } }