static void Main(string[] args) { string directoryName; string FullLine; string texturename; UInt32 GBIX = 0; List <String> textureNames = new List <String>(); List <PvrTexture> finalTextureList = new List <PvrTexture>(); if (args.Length == 0) { Console.WriteLine("Error - no texturelist provided. Provide a path to a texturelist as your first command line argument"); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); return; } String filePath = args[0]; directoryName = Path.GetDirectoryName(filePath); string archiveName = Path.GetFileNameWithoutExtension(filePath); if (File.Exists(filePath)) { StreamReader texlistStream = File.OpenText(filePath); while (!texlistStream.EndOfStream) { textureNames.Add(texlistStream.ReadLine()); } PvmArchive pvmArchive = new PvmArchive(); Stream pvmStream = File.Open(Path.ChangeExtension(filePath, ".pvm"), FileMode.Create); PvmArchiveWriter pvmWriter = (PvmArchiveWriter)pvmArchive.Create(pvmStream); // Reading in textures for (uint imgIndx = 0; imgIndx < textureNames.Count; imgIndx++) { FullLine = textureNames[(int)imgIndx]; if (string.IsNullOrEmpty(FullLine)) { continue; } String[] substrings = FullLine.Split(','); GBIX = UInt32.Parse(substrings[0]); texturename = substrings[1]; Bitmap tempTexture = new Bitmap(8, 8); string texturePath = Path.Combine(directoryName, Path.ChangeExtension(texturename, ".png")); if (File.Exists(texturePath)) { Console.WriteLine("Adding texture:" + (texturePath)); tempTexture = (Bitmap)Bitmap.FromFile(texturePath); tempTexture = tempTexture.Clone(new Rectangle(Point.Empty, tempTexture.Size), System.Drawing.Imaging.PixelFormat.Format32bppArgb); } else { Console.WriteLine(String.Concat("Texture ", textureNames[(int)imgIndx], " not found. Generating a placeholder. Check your files.")); } System.Drawing.Imaging.BitmapData bmpd = tempTexture.LockBits(new Rectangle(Point.Empty, tempTexture.Size), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); int stride = bmpd.Stride; byte[] bits = new byte[Math.Abs(stride) * bmpd.Height]; System.Runtime.InteropServices.Marshal.Copy(bmpd.Scan0, bits, 0, bits.Length); tempTexture.UnlockBits(bmpd); int tlevels = 0; for (int y = 0; y < tempTexture.Height; y++) { int srcaddr = y * Math.Abs(stride); for (int x = 0; x < tempTexture.Width; x++) { Color c = Color.FromArgb(BitConverter.ToInt32(bits, srcaddr + (x * 4))); if (c.A == 0) { tlevels = 1; } else if (c.A < 255) { tlevels = 2; break; } } if (tlevels == 2) { break; } } PvrPixelFormat ppf = PvrPixelFormat.Rgb565; if (tlevels == 1) { ppf = PvrPixelFormat.Argb1555; } else if (tlevels == 2) { ppf = PvrPixelFormat.Argb4444; } PvrDataFormat pdf = PvrDataFormat.Rectangle; if (tempTexture.Width == tempTexture.Height) { pdf = PvrDataFormat.SquareTwiddled; } PvrTextureEncoder encoder = new PvrTextureEncoder(tempTexture, ppf, pdf); encoder.GlobalIndex = GBIX; string pvrPath = Path.ChangeExtension(texturePath, ".pvr"); encoder.Save(pvrPath); pvmWriter.CreateEntryFromFile(pvrPath); } pvmWriter.Flush(); pvmStream.Close(); Console.WriteLine("PVM was compiled successfully!"); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); return; } else // error, supplied path is invalid { Console.WriteLine("Supplied texturelist does not exist!"); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); return; } }
private void SaveTextures() { byte[] data; using (MemoryStream str = new MemoryStream()) { PvmArchiveWriter writer = new PvmArchiveWriter(str); foreach (TextureInfo tex in textures) { if (tex.DataFormat != PvrDataFormat.Index4 && tex.DataFormat != PvrDataFormat.Index8) { System.Drawing.Imaging.BitmapData bmpd = tex.Image.LockBits(new Rectangle(Point.Empty, tex.Image.Size), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); int stride = bmpd.Stride; byte[] bits = new byte[Math.Abs(stride) * bmpd.Height]; System.Runtime.InteropServices.Marshal.Copy(bmpd.Scan0, bits, 0, bits.Length); tex.Image.UnlockBits(bmpd); int tlevels = 0; for (int y = 0; y < tex.Image.Height; y++) { int srcaddr = y * Math.Abs(stride); for (int x = 0; x < tex.Image.Width; x++) { Color c = Color.FromArgb(BitConverter.ToInt32(bits, srcaddr + (x * 4))); if (c.A == 0) { tlevels = 1; } else if (c.A < 255) { tlevels = 2; break; } } if (tlevels == 2) { break; } } if (tlevels == 0) { tex.PixelFormat = PvrPixelFormat.Rgb565; } else if (tlevels == 1) { tex.PixelFormat = PvrPixelFormat.Argb1555; } else if (tlevels == 2) { tex.PixelFormat = PvrPixelFormat.Argb4444; } if (tex.Image.Width == tex.Image.Height) { if (tex.Mipmap) { tex.DataFormat = PvrDataFormat.SquareTwiddledMipmaps; } else { tex.DataFormat = PvrDataFormat.SquareTwiddled; } } else { tex.DataFormat = PvrDataFormat.Rectangle; } } PvrTextureEncoder encoder = new PvrTextureEncoder(tex.Image, tex.PixelFormat, tex.DataFormat); encoder.GlobalIndex = tex.GlobalIndex; MemoryStream pvr = new MemoryStream(); encoder.Save(pvr); pvr.Seek(0, SeekOrigin.Begin); writer.CreateEntry(pvr, tex.Name); } writer.Flush(); data = str.ToArray(); str.Close(); } if (Path.GetExtension(filename).Equals(".prs", StringComparison.OrdinalIgnoreCase)) { FraGag.Compression.Prs.Compress(data, filename); } else { File.WriteAllBytes(filename, data); } }
private void SaveTextures() { byte[] data; using (MemoryStream str = new MemoryStream()) { ArchiveWriter writer = null; switch (format) { case TextureFormat.PVM: writer = new PvmArchiveWriter(str); foreach (PvrTextureInfo tex in textures) { if (tex.DataFormat != PvrDataFormat.Index4 && tex.DataFormat != PvrDataFormat.Index8) { System.Drawing.Imaging.BitmapData bmpd = tex.Image.LockBits(new Rectangle(Point.Empty, tex.Image.Size), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); int stride = bmpd.Stride; byte[] bits = new byte[Math.Abs(stride) * bmpd.Height]; System.Runtime.InteropServices.Marshal.Copy(bmpd.Scan0, bits, 0, bits.Length); tex.Image.UnlockBits(bmpd); int tlevels = 0; for (int y = 0; y < tex.Image.Height; y++) { int srcaddr = y * Math.Abs(stride); for (int x = 0; x < tex.Image.Width; x++) { Color c = Color.FromArgb(BitConverter.ToInt32(bits, srcaddr + (x * 4))); if (c.A == 0) { tlevels = 1; } else if (c.A < 255) { tlevels = 2; break; } } if (tlevels == 2) { break; } } if (tlevels == 0) { tex.PixelFormat = PvrPixelFormat.Rgb565; } else if (tlevels == 1) { tex.PixelFormat = PvrPixelFormat.Argb1555; } else if (tlevels == 2) { tex.PixelFormat = PvrPixelFormat.Argb4444; } if (tex.Image.Width == tex.Image.Height) { if (tex.Mipmap) { tex.DataFormat = PvrDataFormat.SquareTwiddledMipmaps; } else { tex.DataFormat = PvrDataFormat.SquareTwiddled; } } else { tex.DataFormat = PvrDataFormat.Rectangle; } } PvrTextureEncoder encoder = new PvrTextureEncoder(tex.Image, tex.PixelFormat, tex.DataFormat); encoder.GlobalIndex = tex.GlobalIndex; MemoryStream pvr = new MemoryStream(); encoder.Save(pvr); pvr.Seek(0, SeekOrigin.Begin); writer.CreateEntry(pvr, tex.Name); } break; case TextureFormat.GVM: writer = new GvmArchiveWriter(str); foreach (GvrTextureInfo tex in textures) { if (tex.DataFormat != GvrDataFormat.Index4 && tex.DataFormat != GvrDataFormat.Index8) { System.Drawing.Imaging.BitmapData bmpd = tex.Image.LockBits(new Rectangle(Point.Empty, tex.Image.Size), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); int stride = bmpd.Stride; byte[] bits = new byte[Math.Abs(stride) * bmpd.Height]; System.Runtime.InteropServices.Marshal.Copy(bmpd.Scan0, bits, 0, bits.Length); tex.Image.UnlockBits(bmpd); int tlevels = 0; for (int y = 0; y < tex.Image.Height; y++) { int srcaddr = y * Math.Abs(stride); for (int x = 0; x < tex.Image.Width; x++) { Color c = Color.FromArgb(BitConverter.ToInt32(bits, srcaddr + (x * 4))); if (c.A == 0) { tlevels = 1; } else if (c.A < 255) { tlevels = 2; break; } } if (tlevels == 2) { break; } } if (!tex.Mipmap) { tex.DataFormat = GvrDataFormat.Argb8888; } else if (tlevels == 0) { tex.DataFormat = GvrDataFormat.Rgb565; } else { tex.DataFormat = GvrDataFormat.Rgb5a3; } } GvrTextureEncoder encoder = new GvrTextureEncoder(tex.Image, tex.PixelFormat, tex.DataFormat); encoder.GlobalIndex = tex.GlobalIndex; MemoryStream gvr = new MemoryStream(); encoder.Save(gvr); gvr.Seek(0, SeekOrigin.Begin); writer.CreateEntry(gvr, tex.Name); } break; case TextureFormat.PVMX: PvmxArchive.Save(str, textures.Cast <PvmxTextureInfo>()); break; case TextureFormat.PAK: PAKFile pak = new PAKFile(); string filenoext = Path.GetFileNameWithoutExtension(filename).ToLowerInvariant(); string longdir = "..\\..\\..\\sonic2\\resource\\gd_pc\\prs\\" + filenoext; List <byte> inf = new List <byte>(textures.Count * 0x3C); foreach (TextureInfo item in textures) { Stream tex = TextureLoader.SaveToStream(ImageFileFormat.Dds, Texture.FromBitmap(d3ddevice, item.Image, Usage.SoftwareProcessing, Pool.Managed)); byte[] tb = new byte[tex.Length]; tex.Read(tb, 0, tb.Length); string name = item.Name.ToLowerInvariant(); if (name.Length > 0x1C) { name = name.Substring(0, 0x1C); } pak.Files.Add(new PAKFile.File(filenoext + '\\' + name + ".dds", longdir + '\\' + name + ".dds", tb)); inf.AddRange(Encoding.ASCII.GetBytes(name)); if (name.Length != 0x1C) { inf.AddRange(new byte[0x1C - name.Length]); } inf.AddRange(BitConverter.GetBytes(item.GlobalIndex)); inf.AddRange(new byte[0xC]); inf.AddRange(BitConverter.GetBytes(item.Image.Width)); inf.AddRange(BitConverter.GetBytes(item.Image.Height)); inf.AddRange(new byte[4]); inf.AddRange(BitConverter.GetBytes(0x80000000)); } pak.Files.Insert(0, new PAKFile.File(filenoext + '\\' + filenoext + ".inf", longdir + '\\' + filenoext + ".inf", inf.ToArray())); pak.Save(filename); return; } writer?.Flush(); data = str.ToArray(); str.Close(); } if (Path.GetExtension(filename).Equals(".prs", StringComparison.OrdinalIgnoreCase)) { FraGag.Compression.Prs.Compress(data, filename); } else { File.WriteAllBytes(filename, data); } }