/// <inheritdoc cref="Load"/> public IEnumerable <Color> Load(byte[] tex, EncodingLoadContext loadContext) { // Initialize PVR Texture var pvrTexture = PvrTexture.Create(tex, (uint)loadContext.Size.Width, (uint)loadContext.Size.Height, 1, (PixelFormat)_format, ChannelType.UnsignedByte, ColorSpace.Linear); // Transcode texture to RGBA8888 var successful = pvrTexture.Transcode(PixelFormat.RGBA8888, ChannelType.UnsignedByteNorm, ColorSpace.Linear, CompressionQuality.PVRTCHigh); if (!successful) { throw new InvalidOperationException("Transcoding with PVRTexLib was not successful."); } // Yield colors // Get colors in unswizzled order, so the framework applies the swizzle correctly var paddedWidth = GetPaddedWidth(loadContext.Size.Width); var swizzle = GetSwizzle(loadContext.Size.Width); var textureData = pvrTexture.GetData(); for (var y = 0; y < loadContext.Size.Height; y++) { for (var x = 0; x < loadContext.Size.Width; x++) { var sourcePoint = swizzle.Get(y * paddedWidth + x); var textureIndex = (sourcePoint.Y * paddedWidth + sourcePoint.X) * 4; yield return(Color.FromArgb(textureData[textureIndex + 3], textureData[textureIndex], textureData[textureIndex + 1], textureData[textureIndex + 2])); } } }
public static void Information(string[] args) { PvrTexture texture; // Initalize the texture try { texture = new PvrTexture(args[1]); } catch (NotAValidTextureException) { Console.WriteLine("Error: This is not a valid PVR texture."); return; } Console.WriteLine("Texture Information"); Console.WriteLine("--------------------"); Console.WriteLine("Format : PVR"); if (texture.HasGlobalIndex) { Console.WriteLine("Global Index : {0}", texture.GlobalIndex); } Console.WriteLine("Dimensions : {0}x{1}", texture.TextureWidth, texture.TextureHeight); Console.WriteLine("Pixel Format : {0}", PixelFormatToString(texture.PixelFormat)); Console.WriteLine("Data Format : {0}", DataFormatToString(texture.DataFormat)); if (texture.CompressionFormat != PvrCompressionFormat.None) { Console.WriteLine("Compression : {0}", CompressionFormatToString(texture.CompressionFormat)); } }
/// <summary> /// This function sets all textures in the archive to use the specified PVP/GVP palette file. /// If the specified palette file exists, the PaletteRequired flag is removed. /// </summary> public void SetPalette(string palettePath) { if (File.Exists(palettePath)) { VpPalette Palette = null; bool gvm = Type == PuyoArchiveType.GVMFile; Palette = gvm ? (VpPalette) new GvpPalette(palettePath) : (VpPalette) new PvpPalette(palettePath); foreach (GenericArchiveEntry entry in Entries) { if (entry is PVMEntry pvme) { PvrTexture pvrt = new PvrTexture(pvme.Data); if (pvrt.NeedsExternalPalette) { pvme.Palette = (PvpPalette)Palette; } } else if (entry is GVMEntry gvme) { GvrTexture gvrt = new GvrTexture(gvme.Data); if (gvrt.NeedsExternalPalette) { gvme.Palette = (GvpPalette)Palette; } } } PaletteRequired = false; } }
private KeyValuePair <string, Bitmap>?BrowseForTexture(string textureName = null) { using (OpenFileDialog dlg = new OpenFileDialog() { DefaultExt = "pvr", Filter = "Texture Files|*.pvr;*.png;*.jpg;*.jpeg;*.gif;*.bmp" }) { if (!String.IsNullOrEmpty(textureName)) { dlg.FileName = textureName; } if (dlg.ShowDialog(this) == DialogResult.OK) { string name = Path.GetFileNameWithoutExtension(dlg.FileName); if (PvrTexture.Is(dlg.FileName)) { return(new KeyValuePair <string, Bitmap>(name, new PvrTexture(dlg.FileName).ToBitmap())); } else { return(new KeyValuePair <string, Bitmap>(name, new Bitmap(dlg.FileName))); } } else { return(null); } } }
public TEX(string path, bool compressed = true) { Stream fs = FileSystem.GetFileReadStream(path); using (Reader reader = new Reader(fs, Settings.s.IsLittleEndian)) { if (compressed) { reader.ReadUInt32(); // "LZSS" List <Texture2D> texturesList = new List <Texture2D>(); while (reader.BaseStream.Position < reader.BaseStream.Length) { uint zsize = reader.ReadUInt32() - 4; byte[] compressedData = reader.ReadBytes((int)zsize); byte[] decompressedData = DecompressLZSS(compressedData); PvrTexture pvr = new PvrTexture(decompressedData); texturesList.Add(pvr.ToTexture2D()); } textures = texturesList.ToArray(); count = (uint)textures.Length; } else { textures = new Texture2D[1]; PvrTexture pvr = new PvrTexture(reader.ReadBytes((int)fs.Length)); textures[0] = pvr.ToTexture2D(); count = 1; } } }
/// <inheritdoc cref="Save"/> public byte[] Save(IEnumerable <Color> colors, EncodingSaveContext saveContext) { // Get colors in unswizzled order, so the framework applies the swizzle correctly var paddedWidth = GetPaddedWidth(saveContext.Size.Width); var swizzle = GetSwizzle(saveContext.Size.Width); var colorData = new byte[saveContext.Size.Width * saveContext.Size.Height * 4]; var index = 0; foreach (var color in colors) { var targetPoint = swizzle.Get(index / 4); var textureIndex = (targetPoint.Y * paddedWidth + targetPoint.X) * 4; colorData[textureIndex] = color.R; colorData[textureIndex + 1] = color.G; colorData[textureIndex + 2] = color.B; colorData[textureIndex + 3] = color.A; index += 4; } // Initialize PVR Texture var pvrTexture = PvrTexture.Create(colorData, (uint)saveContext.Size.Width, (uint)saveContext.Size.Height, 1, PixelFormat.RGBA8888, ChannelType.UnsignedByteNorm, ColorSpace.Linear); // Transcode texture to PVRTC pvrTexture.Transcode((PixelFormat)_format, ChannelType.UnsignedByteNorm, ColorSpace.Linear, CompressionQuality.PVRTCHigh); return(pvrTexture.GetData()); }
public PVMEntry(string filename) { Name = Path.GetFileName(filename); Data = File.ReadAllBytes(filename); PvrTexture pvrt = new PvrTexture(Data); GBIX = pvrt.GlobalIndex; }
public PVMEntry(byte[] pvrdata, string name) { Name = name; Data = pvrdata; PvrTexture pvrt = new PvrTexture(pvrdata); GBIX = pvrt.GlobalIndex; }
public TextureInfo(string name, PvrTexture texture) { Name = name; GlobalIndex = texture.GlobalIndex; DataFormat = texture.DataFormat; Mipmap = DataFormat == PvrDataFormat.SquareTwiddledMipmaps || DataFormat == PvrDataFormat.SquareTwiddledMipmapsAlt; PixelFormat = texture.PixelFormat; Image = texture.ToBitmap(); }
public override Bitmap GetBitmap() { PvrTexture pvrt = new PvrTexture(Data); if (pvrt.NeedsExternalPalette) { pvrt.SetPalette(Palette); } return(pvrt.ToBitmap()); }
private bool GetTextures(string filename) { byte[] pvmdata = File.ReadAllBytes(filename); if (Path.GetExtension(filename).Equals(".prs", StringComparison.OrdinalIgnoreCase)) { pvmdata = FraGag.Compression.Prs.Decompress(pvmdata); } ArchiveBase pvmfile = new PvmArchive(); if (!pvmfile.Is(pvmdata, filename)) { MessageBox.Show(this, "Could not open file \"" + filename + "\".", Text, MessageBoxButtons.OK, MessageBoxIcon.Warning); return(false); } PvpPalette pvp = null; ArchiveEntryCollection pvmentries = pvmfile.Open(pvmdata).Entries; List <TextureInfo> newtextures = new List <TextureInfo>(pvmentries.Count); foreach (ArchiveEntry file in pvmentries) { PvrTexture vrfile = new PvrTexture(file.Open()); if (vrfile.NeedsExternalPalette) { if (pvp == null) { using (System.Windows.Forms.OpenFileDialog a = new System.Windows.Forms.OpenFileDialog { DefaultExt = "pvp", Filter = "PVP Files|*.pvp", InitialDirectory = Path.GetDirectoryName(filename), Title = "External palette file" }) if (a.ShowDialog(this) == DialogResult.OK) { pvp = new PvpPalette(a.FileName); } else { MessageBox.Show(this, "Could not open file \"" + Program.Arguments[0] + "\".", Text, MessageBoxButtons.OK, MessageBoxIcon.Warning); return(false); } } vrfile.SetPalette(pvp); } newtextures.Add(new TextureInfo(Path.GetFileNameWithoutExtension(file.Name), vrfile)); } textures.Clear(); textures.AddRange(newtextures); listBox1.Items.Clear(); listBox1.Items.AddRange(textures.Select((item) => item.Name).ToArray()); SetFilename(Path.GetFullPath(filename)); return(true); }
public void AddPVR(byte[] pvrdata, int index) { int length = BitConverter.ToInt32(pvrdata, 20) - 8; int offset = GetCurrentOffset(index); PvrTexture pvr = new PvrTexture(pvrdata); Headers.Add(new PBTextureHeader(offset, pvr.PixelFormat, pvr.DataFormat, pvr.GlobalIndex, pvr.TextureWidth, pvr.TextureHeight)); byte[] pvrdata_nohdr = new byte[length]; Array.Copy(pvrdata, 32, pvrdata_nohdr, 0, length); //Console.WriteLine("Adding texture {0} at offset {1}, length {2} (original PVR {3})", index, offset, length, pvrdata.Length); Data.Add(pvrdata_nohdr); }
static bool AddTexture(PAKFile pak, string filenoext, string longdir, bool gvm, List <byte> inf, Device d3ddevice, string filename, Stream data) { VrTexture vrfile = gvm ? (VrTexture) new GvrTexture(data) : (VrTexture) new PvrTexture(data); if (vrfile.NeedsExternalPalette) { Console.WriteLine("Cannot convert texture files which require external palettes!"); return(false); } Bitmap bmp; try { bmp = vrfile.ToBitmap(); } catch { bmp = new Bitmap(1, 1); } Stream tex = TextureLoader.SaveToStream(ImageFileFormat.Dds, Texture.FromBitmap(d3ddevice, bmp, Usage.SoftwareProcessing, Pool.Managed)); byte[] tb = new byte[tex.Length]; tex.Read(tb, 0, tb.Length); pak.Files.Add(new PAKFile.File(filenoext + '\\' + Path.ChangeExtension(filename, ".dds"), longdir + '\\' + Path.ChangeExtension(filename, ".dds"), tb)); int i = inf.Count; inf.AddRange(Encoding.ASCII.GetBytes(Path.ChangeExtension(filename, null))); inf.AddRange(new byte[0x1C - (inf.Count - i)]); if (vrfile.HasGlobalIndex) { inf.AddRange(BitConverter.GetBytes(vrfile.GlobalIndex)); } else { inf.AddRange(BitConverter.GetBytes(-1)); } if (gvm) { GvrTexture gvr = (GvrTexture)vrfile; inf.AddRange(BitConverter.GetBytes((int)gvr.DataFormat)); inf.AddRange(BitConverter.GetBytes((int)gvr.PixelFormat)); inf.AddRange(BitConverter.GetBytes((int)gvr.DataFormat)); } else { PvrTexture pvr = (PvrTexture)vrfile; inf.AddRange(BitConverter.GetBytes((int)pvr.DataFormat)); inf.AddRange(BitConverter.GetBytes((int)pvr.PixelFormat)); inf.AddRange(BitConverter.GetBytes((int)pvr.DataFormat)); } inf.AddRange(BitConverter.GetBytes((int)vrfile.TextureWidth)); inf.AddRange(BitConverter.GetBytes((int)vrfile.TextureHeight)); inf.AddRange(BitConverter.GetBytes(vrfile.PvrtOffset)); inf.AddRange(BitConverter.GetBytes(0x80000000)); return(true); }
public PBEntry(string filename, int offset) { Data = File.ReadAllBytes(filename); PvrTexture pvrt = new PvrTexture(Data); byte[] data = GetHeaderless(); Name = Path.GetFileNameWithoutExtension(filename); Offset = offset; PixelFormat = pvrt.PixelFormat; DataFormat = pvrt.DataFormat; GBIX = pvrt.GlobalIndex; Width = pvrt.TextureWidth; Height = pvrt.TextureHeight; }
public Puyo(byte[] pvmdata) { ArchiveBase puyobase; Entries = new List <ArchiveEntry>(); Type = Identify(pvmdata); switch (Type) { case PuyoArchiveType.PVMFile: puyobase = new PvmArchive(); break; case PuyoArchiveType.GVMFile: puyobase = new GvmArchive(); break; default: throw new Exception("Error: Unknown archive format"); } ArchiveReader archiveReader = puyobase.Open(pvmdata); foreach (var puyoentry in archiveReader.Entries) { MemoryStream vrstream = (MemoryStream)(puyoentry.Open()); switch (Type) { case PuyoArchiveType.PVMFile: PvrTexture pvrt = new PvrTexture(vrstream); if (pvrt.NeedsExternalPalette) { PaletteRequired = true; } Entries.Add(new PVMEntry(vrstream.ToArray(), Path.GetFileName(puyoentry.Name))); break; case PuyoArchiveType.GVMFile: GvrTexture gvrt = new GvrTexture(vrstream); if (gvrt.NeedsExternalPalette) { PaletteRequired = true; } Entries.Add(new GVMEntry(vrstream.ToArray(), Path.GetFileName(puyoentry.Name))); break; } } }
public PvrTextureInfo(string name, MemoryStream str, PvpPalette pvp = null) { TextureData = str; PvrTexture texture = new PvrTexture(str); if (pvp != null) { texture.SetPalette(pvp); } Name = name; GlobalIndex = texture.GlobalIndex; DataFormat = texture.DataFormat; Mipmap = DataFormat == PvrDataFormat.SquareTwiddledMipmaps || DataFormat == PvrDataFormat.SquareTwiddledMipmapsAlt; PixelFormat = texture.PixelFormat; Image = texture.ToBitmap(); }
private static List <string> LoadAndExtractTexturePak(Stream texturePakStream, string outDirectory) { var textureNames = new List <string>(); try { var archive = new GvmArchive(); var archiveReader = ( GvmArchiveReader )archive.Open(texturePakStream); foreach (var entry in archiveReader.Entries) { var texture = new GvrTexture(); texture.Read(entry.Open(), out var bitmap); var entryNameClean = Path.ChangeExtension(entry.Name, null); bitmap.Save(Path.Combine(outDirectory, Path.ChangeExtension(entryNameClean, "png"))); textureNames.Add(entryNameClean); } } catch (Exception) { texturePakStream.Position = 0; var archive = new PvmArchive(); var archiveReader = ( PvmArchiveReader )archive.Open(texturePakStream); foreach (var entry in archiveReader.Entries) { var texture = new PvrTexture(); texture.Read(entry.Open(), out var bitmap); var entryNameClean = Path.ChangeExtension(entry.Name, null); try { bitmap.Save(Path.Combine(outDirectory, Path.ChangeExtension(entryNameClean, "png"))); } catch (Exception e) { Console.WriteLine(e); } textureNames.Add(entryNameClean); } } return(textureNames); }
/// <summary> /// 从图片数据中获取图片 /// </summary> /// <param name="byData"></param> /// <returns></returns> public override Image[] ImageDecode(byte[] byData, string fileInfo) { PvrTexture pvrDecode = new PvrTexture(byData); if (pvrDecode.NeedsExternalPalette) { // 取得调色板数据 KeyValuePair <string, byte[]> paletteKeyValue = this.paletteData.FirstOrDefault(p => p.Key.IndexOf(fileInfo) >= 0); if (string.IsNullOrEmpty(paletteKeyValue.Key)) { throw new Exception("没有找到调色板数据"); } PvpPalette palette = new PvpPalette(paletteKeyValue.Value); pvrDecode.SetPalette(palette); } return(new Image[] { pvrDecode.ToBitmap() }); }
public PvrTextureInfo(string name, MemoryStream str) { TextureData = str; PvrTexture texture = new PvrTexture(str); Name = name; GlobalIndex = texture.GlobalIndex; DataFormat = texture.DataFormat; Mipmap = DataFormat == PvrDataFormat.SquareTwiddledMipmaps || DataFormat == PvrDataFormat.SquareTwiddledMipmapsAlt; PixelFormat = texture.PixelFormat; if (texture.NeedsExternalPalette) { Image = new Bitmap(Properties.Resources.error); } else { Image = texture.ToBitmap(); } }
/// <inheritdoc cref="Load"/> public IEnumerable <Color> Load(byte[] tex, EncodingLoadContext loadContext) { // Initialize PVR Texture var pvrTexture = PvrTexture.Create(tex, (uint)loadContext.Size.Width, (uint)loadContext.Size.Height, 1, (PixelFormat)_format, ChannelType.UnsignedByte, ColorSpace.Linear); // Transcode texture to RGBA8888 var successful = pvrTexture.Transcode(PixelFormat.RGBA8888, ChannelType.UnsignedByteNorm, ColorSpace.Linear, CompressionQuality.PVRTCHigh); if (!successful) { throw new InvalidOperationException("Transcoding with PVRTexLib was not successful."); } // Yield colors var textureData = pvrTexture.GetData(); for (var i = 0L; i < textureData.Length; i += 4) { yield return(Color.FromArgb(textureData[i + 3], textureData[i], textureData[i + 1], textureData[i + 2])); } }
/// <inheritdoc cref="Save"/> public byte[] Save(IEnumerable <Color> colors, EncodingSaveContext saveContext) { var colorData = new byte[saveContext.Size.Width * saveContext.Size.Height * 4]; var index = 0; foreach (var color in colors) { colorData[index++] = color.R; colorData[index++] = color.G; colorData[index++] = color.B; colorData[index++] = color.A; } // Initialize PVR Texture var pvrTexture = PvrTexture.Create(colorData, (uint)saveContext.Size.Width, (uint)saveContext.Size.Height, 1, PixelFormat.RGBA8888, ChannelType.UnsignedByteNorm, ColorSpace.Linear); // Transcode texture to PVRTC pvrTexture.Transcode((PixelFormat)_format, ChannelType.UnsignedByteNorm, ColorSpace.Linear, CompressionQuality.PVRTCHigh); return(pvrTexture.GetData()); }
public void AddPalette(string startPath) { VpPalette Palette = null; bool gvm = Type == PuyoArchiveType.GVMFile; using (System.Windows.Forms.OpenFileDialog a = new System.Windows.Forms.OpenFileDialog { DefaultExt = gvm ? "gvp" : "pvp", Filter = gvm ? "GVP Files|*.gvp" : "PVP Files|*.pvp", InitialDirectory = startPath, Title = "External palette file" }) { if (a.ShowDialog() == System.Windows.Forms.DialogResult.OK) { Palette = gvm ? (VpPalette) new GvpPalette(a.FileName) : (VpPalette) new PvpPalette(a.FileName); } } foreach (GenericArchiveEntry entry in Entries) { if (entry is PVMEntry pvme) { PvrTexture pvrt = new PvrTexture(pvme.Data); if (pvrt.NeedsExternalPalette) { pvme.Palette = (PvpPalette)Palette; } } else if (entry is GVMEntry gvme) { GvrTexture gvrt = new GvrTexture(gvme.Data); if (gvrt.NeedsExternalPalette) { gvme.Palette = (GvpPalette)Palette; } } } }
public static BMPInfo[] GetTextures(string filename) { if (!File.Exists(filename)) { return(null); } string ext = Path.GetExtension(filename).ToLowerInvariant(); switch (ext) { case ".pak": PAKFile pak = new PAKFile(filename); string filenoext = Path.GetFileNameWithoutExtension(filename).ToLowerInvariant(); byte[] inf = pak.Files.Single((file) => file.Name.Equals(filenoext + '\\' + filenoext + ".inf", StringComparison.OrdinalIgnoreCase)).Data; List <BMPInfo> newtextures = new List <BMPInfo>(inf.Length / 0x3C); for (int i = 0; i < inf.Length; i += 0x3C) { System.Text.StringBuilder sb = new System.Text.StringBuilder(0x1C); for (int j = 0; j < 0x1C; j++) { if (inf[i + j] != 0) { sb.Append((char)inf[i + j]); } else { break; } } byte[] dds = pak.Files.First((file) => file.Name.Equals(filenoext + '\\' + sb.ToString() + ".dds", StringComparison.OrdinalIgnoreCase)).Data; using (MemoryStream str = new MemoryStream(dds)) { uint check = BitConverter.ToUInt32(dds, 0); if (check == 0x20534444) // DDS header { PixelFormat pxformat; var image = Pfim.Pfim.FromStream(str, new Pfim.PfimConfig()); switch (image.Format) { case Pfim.ImageFormat.Rgba32: pxformat = PixelFormat.Format32bppArgb; break; default: System.Windows.Forms.MessageBox.Show("Unsupported image format."); throw new NotImplementedException(); } var bitmap = new Bitmap(image.Width, image.Height, pxformat); BitmapData bmpData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.WriteOnly, pxformat); System.Runtime.InteropServices.Marshal.Copy(image.Data, 0, bmpData.Scan0, image.DataLen); bitmap.UnlockBits(bmpData); newtextures.Add(new BMPInfo(sb.ToString(), bitmap)); } else { newtextures.Add(new BMPInfo(sb.ToString(), new Bitmap(str))); } } } return(newtextures.ToArray()); case ".pvmx": PVMXFile pvmx = new PVMXFile(File.ReadAllBytes(filename)); List <BMPInfo> textures = new List <BMPInfo>(); for (int i = 0; i < pvmx.GetCount(); i++) { var bmp = new Bitmap(new MemoryStream(pvmx.GetFile(i))); textures.Add(new BMPInfo(pvmx.GetNameWithoutExtension(i), bmp)); } return(textures.ToArray()); case ".txt": string[] files = File.ReadAllLines(filename); List <BMPInfo> txts = new List <BMPInfo>(); for (int s = 0; s < files.Length; s++) { string[] entry = files[s].Split(','); txts.Add(new BMPInfo(entry[1], new System.Drawing.Bitmap(Path.Combine(Path.GetDirectoryName(filename), entry[1])))); } return(txts.ToArray()); case ".pb": PBFile pbdata = new PBFile(File.ReadAllBytes(filename)); List <BMPInfo> txtsp = new List <BMPInfo>(); for (int i = 0; i < pbdata.GetCount(); i++) { PvrTexture pvr = new PvrTexture(pbdata.GetPVR(i)); txtsp.Add(new BMPInfo(i.ToString("D3"), pvr.ToBitmap())); } return(txtsp.ToArray()); case ".pvm": case ".gvm": default: List <BMPInfo> functionReturnValue = new List <BMPInfo>(); bool gvm = false; ArchiveBase pvmfile = null; byte[] pvmdata = File.ReadAllBytes(filename); if (Path.GetExtension(filename).Equals(".prs", StringComparison.OrdinalIgnoreCase)) { pvmdata = FraGag.Compression.Prs.Decompress(pvmdata); } pvmfile = new PvmArchive(); MemoryStream stream = new MemoryStream(pvmdata); if (!PvmArchive.Identify(stream)) { pvmfile = new GvmArchive(); gvm = true; } VrSharp.VpPalette pvp = null; ArchiveEntryCollection pvmentries = pvmfile.Open(pvmdata).Entries; foreach (ArchiveEntry file in pvmentries) { VrTexture vrfile = gvm ? (VrTexture) new GvrTexture(file.Open()) : (VrTexture) new PvrTexture(file.Open()); if (vrfile.NeedsExternalPalette) { using (System.Windows.Forms.OpenFileDialog a = new System.Windows.Forms.OpenFileDialog { DefaultExt = gvm ? "gvp" : "pvp", Filter = gvm ? "GVP Files|*.gvp" : "PVP Files|*.pvp", InitialDirectory = System.IO.Path.GetDirectoryName(filename), Title = "External palette file" }) { if (pvp == null) { if (a.ShowDialog() == System.Windows.Forms.DialogResult.OK) { pvp = gvm ? (VpPalette) new GvpPalette(a.FileName) : (VpPalette) new PvpPalette(a.FileName); } else { return(new BMPInfo[0]); } } } if (gvm) { ((GvrTexture)vrfile).SetPalette((GvpPalette)pvp); } else { ((PvrTexture)vrfile).SetPalette((PvpPalette)pvp); } } try { functionReturnValue.Add(new BMPInfo(Path.GetFileNameWithoutExtension(file.Name), vrfile.ToBitmap())); } catch { functionReturnValue.Add(new BMPInfo(Path.GetFileNameWithoutExtension(file.Name), new Bitmap(1, 1))); } } return(functionReturnValue.ToArray()); } }
static void Main(string[] args) { Queue <string> files = new Queue <string>(args); if (files.Count == 0) { Console.Write("File: "); files.Enqueue(Console.ReadLine()); } while (files.Count > 0) { string filename = files.Dequeue(); PAKFile pak = new PAKFile(); List <byte> inf = new List <byte>(); string filenoext = Path.GetFileNameWithoutExtension(filename).ToLowerInvariant(); string longdir = "..\\..\\..\\sonic2\\resource\\gd_pc\\prs\\" + filenoext; byte[] filedata = File.ReadAllBytes(filename); using (System.Windows.Forms.Panel panel1 = new System.Windows.Forms.Panel()) using (Device d3ddevice = new Device(0, DeviceType.Hardware, panel1, CreateFlags.SoftwareVertexProcessing, new PresentParameters[] { new PresentParameters() { Windowed = true, SwapEffect = SwapEffect.Discard, EnableAutoDepthStencil = true, AutoDepthStencilFormat = DepthFormat.D24X8 } })) { if (PvrTexture.Is(filedata)) { if (!AddTexture(pak, filenoext, longdir, false, inf, d3ddevice, filename, new MemoryStream(filedata))) { continue; } goto end; } else if (GvrTexture.Is(filedata)) { if (!AddTexture(pak, filenoext, longdir, true, inf, d3ddevice, filename, new MemoryStream(filedata))) { continue; } goto end; } bool gvm = false; ArchiveBase pvmfile = null; byte[] pvmdata = File.ReadAllBytes(filename); if (Path.GetExtension(filename).Equals(".prs", StringComparison.OrdinalIgnoreCase)) { pvmdata = FraGag.Compression.Prs.Decompress(pvmdata); } pvmfile = new PvmArchive(); if (!pvmfile.Is(pvmdata, filename)) { pvmfile = new GvmArchive(); gvm = true; if (!pvmfile.Is(pvmdata, filename)) { Console.WriteLine("{0} is not a valid file.", filename); continue; } } ArchiveEntryCollection pvmentries = pvmfile.Open(pvmdata).Entries; bool fail = false; foreach (ArchiveEntry file in pvmentries) { if (!AddTexture(pak, filenoext, longdir, gvm, inf, d3ddevice, file.Name, file.Open())) { fail = true; break; } } if (fail) { continue; } } end: pak.Files.Insert(0, new PAKFile.File(filenoext + '\\' + filenoext + ".inf", longdir + '\\' + filenoext + ".inf", inf.ToArray())); pak.Save(Path.ChangeExtension(filename, "pak")); } }
public static void Main(string[] args) { Console.WriteLine("VrConvert"); Console.WriteLine("Version {0}", Version); Console.WriteLine("--------------------\n"); // Display texture information if (args.Length > 1 && args[0] == "-i") { // Make sure the file exists if (!File.Exists(args[1])) { Console.WriteLine("Error: {0} does not exist.", args[1]); return; } // Determine which texture converter we must use if (GvrTexture.Is(args[1])) { GvrConvert.Information(args); } else if (PvrTexture.Is(args[1])) { PvrConvert.Information(args); } else if (SvrTexture.Is(args[1])) { SvrConvert.Information(args); } else { Console.WriteLine("Error: This is not a GVR, PVR, or SVR texture."); } } // Decode a texture else if (args.Length > 1 && args[0] == "-d") { // Make sure the file exists if (!File.Exists(args[1])) { Console.WriteLine("Error: {0} does not exist.", args[1]); return; } // Determine which texture converter we must use if (GvrTexture.Is(args[1])) { GvrConvert.Decode(args); } else if (PvrTexture.Is(args[1])) { PvrConvert.Decode(args); } else if (SvrTexture.Is(args[1])) { SvrConvert.Decode(args); } else { Console.WriteLine("Error: This is not a GVR, PVR, or SVR texture."); } } // Encode a texture else if (args.Length > 4 && args[0] == "-e") { // Make sure the file exists if (!File.Exists(args[1])) { Console.WriteLine("Error: {0} does not exist.", args[1]); return; } // Determine which texture converter we must use string format = args[2].ToLower(); if (format == "gvr") { GvrConvert.Encode(args); } else if (format == "pvr") { PvrConvert.Encode(args); } else if (format == "svr") { SvrConvert.Encode(args); } else { Console.WriteLine("Error: Unknown format {0}", format); } } // More help else if (args.Length > 0 && args[0] == "/?") { if (args.Length > 1 && args[1].ToLower() == "gvr") { Console.WriteLine("Encode GVR texture:\n"); Console.WriteLine(" VrConvert -e <input> gvr <palette format> <data format> [options]\n"); Console.WriteLine(" <input> : Input file"); Console.WriteLine(" <palette format> : Palette format"); Console.WriteLine(" <data format> : Data format"); Console.WriteLine(" -o <output> : Specify output file"); Console.WriteLine(" -op <palette> : Specify output palette file"); Console.WriteLine(" -nogbix : Do not include a GBIX header"); Console.WriteLine(" -gcix : Use GCIX instead of GBIX"); Console.WriteLine(" -gi <value> : Set global index"); Console.WriteLine(" -mipmaps : Texture will have mipmaps"); Console.WriteLine(" -ep : Texture will have an external palette\n"); Console.WriteLine(" Palette formats:\n"); Console.WriteLine(" none (only for non-palettized formats)"); Console.WriteLine(" ia8"); Console.WriteLine(" rgb565"); Console.WriteLine(" rgb5a3\n"); Console.WriteLine(" Data formats:\n"); Console.WriteLine(" i4"); Console.WriteLine(" i8"); Console.WriteLine(" ia4"); Console.WriteLine(" ia8"); Console.WriteLine(" rgb565"); Console.WriteLine(" rgb5a3"); Console.WriteLine(" argb8888"); Console.WriteLine(" index4"); Console.WriteLine(" index8"); Console.WriteLine(" dxt1"); } else if (args.Length > 1 && args[1].ToLower() == "pvr") { Console.WriteLine("Encode PVR texture:\n"); Console.WriteLine(" VrConvert -e <input> pvr <palette format> <data format> [options]\n"); Console.WriteLine(" <input> : Input file"); Console.WriteLine(" <pixel format> : Pixel format"); Console.WriteLine(" <data format> : Data format"); Console.WriteLine(" -o <output> : Specify output file"); Console.WriteLine(" -op <palette> : Specify output palette file"); Console.WriteLine(" -nogbix : Do not include a GBIX header"); Console.WriteLine(" -gi <value> : Set global index"); Console.WriteLine(" -cmp <format> : Set compression format\n"); Console.WriteLine(" Pixel formats:\n"); Console.WriteLine(" argb1555"); Console.WriteLine(" rgb565"); Console.WriteLine(" argb4444\n"); Console.WriteLine(" Data formats:\n"); Console.WriteLine(" square"); Console.WriteLine(" squaremipmaps"); Console.WriteLine(" index4"); Console.WriteLine(" index8"); Console.WriteLine(" rectangle"); Console.WriteLine(" rectangletwiddled"); Console.WriteLine(" squaretwiddledalt\n"); Console.WriteLine(" Compression formats:\n"); Console.WriteLine(" none"); Console.WriteLine(" rle"); } else if (args.Length > 1 && args[1].ToLower() == "svr") { Console.WriteLine("Encode SVR texture:\n"); Console.WriteLine(" VrConvert -e <input> svr <palette format> <data format> [options]\n"); Console.WriteLine(" <input> : Input file"); Console.WriteLine(" <pixel format> : Pixel format"); Console.WriteLine(" <data format> : Data format"); Console.WriteLine(" -o <output> : Specify output file"); Console.WriteLine(" -op <palette> : Specify output palette file"); Console.WriteLine(" -nogbix : Do not include a GBIX header"); Console.WriteLine(" -gi <value> : Set global index\n"); Console.WriteLine(" Pixel formats:\n"); Console.WriteLine(" rgb5a3"); Console.WriteLine(" argb8888\n"); Console.WriteLine(" Data formats:\n"); Console.WriteLine(" rectangle"); Console.WriteLine(" index4ep"); Console.WriteLine(" index8ep"); Console.WriteLine(" index4"); Console.WriteLine(" index8"); } else { Console.WriteLine("Decode texture:\n"); Console.WriteLine(" VrConvert -d <input> [options]\n"); Console.WriteLine(" <input> : Input file"); Console.WriteLine(" -p <palette> : Specify palette file"); Console.WriteLine(" -o <output> : Specify output file\n"); Console.WriteLine("Encode texture:\n"); Console.WriteLine(" VrConvert -e <input> <vr format> <pixel format> <data format> [options]\n"); Console.WriteLine(" <input> : Input file"); Console.WriteLine(" <vr format> : VR format"); Console.WriteLine(" <pixel format> : Pixel format"); Console.WriteLine(" <data format> : Data format"); Console.WriteLine(" -o <output> : Specify output file"); Console.WriteLine(" -op <palette> : Specify output palette file"); Console.WriteLine(" -nogbix : Do not include a GBIX header"); Console.WriteLine(" -gi <value> : Set global index\n"); Console.WriteLine("Texture information:\n"); Console.WriteLine(" VrConvert -i <input>\n"); Console.WriteLine(" <input> : Input file\n"); Console.WriteLine("More help:\n"); Console.WriteLine(" VrConvert /? gvr"); Console.WriteLine(" VrConvert /? pvr"); Console.WriteLine(" VrConvert /? svr"); } } // Display simple help else { Console.WriteLine("Decode texture:\n"); Console.WriteLine(" VrConvert -d <input> [options]\n"); Console.WriteLine("Encode texture:\n"); Console.WriteLine(" VrConvert -e <input> <vr format> <pixel format> <data format> [options]\n"); Console.WriteLine("Texture information:\n"); Console.WriteLine(" VrConvert -i <input>\n"); Console.WriteLine("More help:\n"); Console.WriteLine(" VrConvert /?\n"); Console.WriteLine(" VrConvert /? gvr"); Console.WriteLine(" VrConvert /? pvr"); Console.WriteLine(" VrConvert /? svr"); } }
public static void Decode(string[] args) { string inPalettePath = Path.ChangeExtension(args[1], ".pvp"); string outPath = Path.ChangeExtension(args[1], ".png"); // Get arguments for (int i = 2; i < args.Length; i++) { string arg = args[i].ToLower(); // Change the output path if (arg == "-o" && args.Length > i + 1) { outPath = args[i + 1]; i++; } // Palette path if (arg == "-p" && args.Length > i + 1) { inPalettePath = args[i + 1]; i++; } } PvrTexture texture; // Initalize the texture try { texture = new PvrTexture(args[1]); } catch (NotAValidTextureException) { Console.WriteLine("Error: This is not a valid PVR texture."); return; } // Does this texture need an external palette file? if (texture.NeedsExternalPalette) { if (!File.Exists(inPalettePath)) { Console.WriteLine("Error: This texture requires an external palette file."); return; } PvpPalette palette = new PvpPalette(inPalettePath); if (!palette.Initalized) { Console.WriteLine("Error: {0} is not a valid PVR palette file.", inPalettePath); } texture.SetPalette(palette); } Console.WriteLine("Texture Information"); Console.WriteLine("--------------------"); Console.WriteLine("Format : PVR"); if (texture.HasGlobalIndex) { Console.WriteLine("Global Index : {0}", texture.GlobalIndex); } Console.WriteLine("Dimensions : {0}x{1}", texture.TextureWidth, texture.TextureHeight); Console.WriteLine("Pixel Format : {0}", PixelFormatToString(texture.PixelFormat)); Console.WriteLine("Data Format : {0}", DataFormatToString(texture.DataFormat)); if (texture.CompressionFormat != PvrCompressionFormat.None) { Console.WriteLine("Compression : {0}", CompressionFormatToString(texture.CompressionFormat)); } // Decode the texture try { texture.Save(outPath); } catch (CannotDecodeTextureException) { Console.WriteLine("Error: Unable to decode this texture. The texture's pixel format or data format may not be supported."); return; } Console.WriteLine("\nTexture decoded successfully."); }
static void Main(string[] args) { Queue <string> files = new Queue <string>(args); if (files.Count == 0) { Console.Write("File: "); files.Enqueue(Console.ReadLine()); } while (files.Count > 0) { string filename = files.Dequeue(); string path = Path.Combine(Path.GetDirectoryName(Path.GetFullPath(filename)), Path.GetFileNameWithoutExtension(filename)); Directory.CreateDirectory(path); byte[] filedata = File.ReadAllBytes(filename); using (TextWriter texList = File.CreateText(Path.Combine(path, "index.txt"))) { try { if (PvrTexture.Is(filedata)) { if (!AddTexture(false, path, Path.GetFileName(filename), new MemoryStream(filedata), texList)) { texList.Close(); Directory.Delete(path, true); } continue; } else if (GvrTexture.Is(filedata)) { if (!AddTexture(true, path, Path.GetFileName(filename), new MemoryStream(filedata), texList)) { texList.Close(); Directory.Delete(path, true); } continue; } bool gvm = false; ArchiveBase pvmfile = null; byte[] pvmdata = File.ReadAllBytes(filename); if (Path.GetExtension(filename).Equals(".prs", StringComparison.OrdinalIgnoreCase)) { pvmdata = FraGag.Compression.Prs.Decompress(pvmdata); } pvmfile = new PvmArchive(); if (!pvmfile.Is(pvmdata, filename)) { pvmfile = new GvmArchive(); gvm = true; } ArchiveEntryCollection pvmentries = pvmfile.Open(pvmdata).Entries; bool fail = false; foreach (ArchiveEntry file in pvmentries) { if (!AddTexture(gvm, path, file.Name, file.Open(), texList)) { texList.Close(); Directory.Delete(path, true); fail = true; break; } } if (fail) { continue; } } catch { Console.WriteLine("Exception thrown. Canceling conversion."); Directory.Delete(path, true); throw; } } } }
static void Main(string[] args) { ArchiveFromFolderMode folderMode; string dir; string filePath; string directoryName; ArchiveBase pvmArchive; ArchiveWriter pvmWriter; string archiveName; string path; byte[] filedata; bool isPRS; bool isBIN = false; string extension; // Usage if (args.Length == 0) { Console.WriteLine("ArchiveTool is a command line tool to extract and create PVM, GVM, PRS, DAT and PB archives.\nIt can also decompress SADX Gamecube 'SaCompGC' REL files.\n"); Console.WriteLine("Usage:\n"); Console.WriteLine("Extracting a PVM/GVM/PRS/PB/PVMX/DAT/REL file:\nArchiveTool <archivefile>\nIf the archive is PRS compressed, it will be decompressed first.\nIf the archive contains textures/sounds, the program will extract them and create a list of files named 'index.txt'.\n"); Console.WriteLine("Extracting an NjUtil archive: ArchiveTool -nju <archivefile>\n"); Console.WriteLine("Converting PVM/GVM to a folder texture pack: ArchiveTool -png <archivefile>\n"); Console.WriteLine("Creating a PB archive from a folder with textures: ArchiveTool -pb <foldername>"); Console.WriteLine("Creating a PVM/GVM/DAT/PVMX from a folder with textures/sounds: ArchiveTool <foldername> [-prs]\nThe program will create an archive from files listed in 'index.txt' in the folder.\nThe -prs option will make the program output a PRS compressed archive.\n"); Console.WriteLine("Creating a PVM from PNG textures: ArchiveTool -pvm <folder> [-prs]\nThe texture list 'index.txt' must contain global indices listed before each texture filename for this option to work.\n"); Console.WriteLine("Converting GVM to PVM (lossy): ArchiveTool -gvm2pvm <file.gvm> [-prs]\n"); Console.WriteLine("Creating a PRS compressed binary: ArchiveTool <file.bin>\nFile extension must be .BIN for this option to work.\n"); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); return; } switch (args[0].ToLowerInvariant()) { // GVM2PVM mode case "-gvm2pvm": filePath = args[1]; isPRS = false; if (args.Length > 2 && args[2] == "-prs") { isPRS = true; } Console.WriteLine("Converting GVM to PVM: {0}", filePath); directoryName = Path.GetDirectoryName(filePath); extension = Path.GetExtension(filePath).ToLowerInvariant(); if (!File.Exists(filePath)) { Console.WriteLine("Supplied GVM archive does not exist!"); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); return; } if (extension != ".gvm") { Console.WriteLine("GVM2PVM mode can only be used with GVM files."); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); return; } path = Path.Combine(directoryName, Path.GetFileNameWithoutExtension(filePath)); Directory.CreateDirectory(path); filedata = File.ReadAllBytes(filePath); using (TextWriter texList = File.CreateText(Path.Combine(path, Path.GetFileName(path) + ".txt"))) { try { ArchiveBase gvmfile = null; byte[] gvmdata = File.ReadAllBytes(filePath); gvmfile = new GvmArchive(); ArchiveReader gvmReader = gvmfile.Open(gvmdata); Stream pvmStream = File.Open(Path.ChangeExtension(filePath, ".pvm"), FileMode.Create); pvmArchive = new PvmArchive(); pvmWriter = pvmArchive.Create(pvmStream); foreach (ArchiveEntry file in gvmReader.Entries) { if (!File.Exists(Path.Combine(path, file.Name))) { gvmReader.ExtractToFile(file, Path.Combine(path, file.Name)); } Stream data = File.Open(Path.Combine(path, file.Name), FileMode.Open); VrTexture vrfile = new GvrTexture(data); Bitmap tempTexture = vrfile.ToBitmap(); 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; archiveName = Path.GetFileNameWithoutExtension(filePath); 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; if (!vrfile.HasMipmaps) { if (tempTexture.Width == tempTexture.Height) { pdf = PvrDataFormat.SquareTwiddled; } else { pdf = PvrDataFormat.Rectangle; } } else { if (tempTexture.Width == tempTexture.Height) { pdf = PvrDataFormat.SquareTwiddledMipmaps; } else { pdf = PvrDataFormat.RectangleTwiddled; } } PvrTextureEncoder encoder = new PvrTextureEncoder(tempTexture, ppf, pdf); encoder.GlobalIndex = vrfile.GlobalIndex; string pvrPath = Path.ChangeExtension(Path.Combine(path, file.Name), ".pvr"); if (!File.Exists(pvrPath)) { encoder.Save(pvrPath); } data.Close(); File.Delete(Path.Combine(path, file.Name)); pvmWriter.CreateEntryFromFile(pvrPath); texList.WriteLine(Path.GetFileName(pvrPath)); Console.WriteLine("Adding texture {0}", pvrPath); } pvmWriter.Flush(); pvmStream.Flush(); pvmStream.Close(); if (isPRS) { Console.WriteLine("Compressing to PRS..."); byte[] pvmdata = File.ReadAllBytes(Path.ChangeExtension(filePath, ".pvm")); pvmdata = FraGag.Compression.Prs.Compress(pvmdata); File.WriteAllBytes(Path.ChangeExtension(filePath, ".PVM.PRS"), pvmdata); File.Delete(Path.ChangeExtension(filePath, ".PVM")); } Console.WriteLine("Archive converted!"); } catch (Exception ex) { Console.WriteLine("Exception thrown: {0}", ex.ToString()); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); return; } } break; // CompilePVM mode case "-pvm": bool IsPRS = false; if (args[args.Length - 1] == "-prs") { IsPRS = true; } filePath = args[1]; string FullLine; string texturename; uint GBIX = 0; List <string> textureNames = new List <String>(); List <PvrTexture> finalTextureList = new List <PvrTexture>(); directoryName = Path.GetDirectoryName(filePath); archiveName = Path.GetFileNameWithoutExtension(filePath); if (Directory.Exists(filePath)) { Console.WriteLine("Converting texture pack to PVM: {0}", filePath); StreamReader texlistStream = File.OpenText(Path.Combine(filePath, "index.txt")); while (!texlistStream.EndOfStream) { textureNames.Add(texlistStream.ReadLine()); } pvmArchive = new PvmArchive(); Stream pvmStream = File.Open(Path.ChangeExtension(filePath, ".pvm"), FileMode.Create); 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(filePath, 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(); if (IsPRS) { Console.WriteLine("Compressing to PRS..."); byte[] pvmdata = File.ReadAllBytes(Path.ChangeExtension(filePath, ".pvm")); pvmdata = FraGag.Compression.Prs.Compress(pvmdata); File.WriteAllBytes(Path.ChangeExtension(filePath, ".prs"), pvmdata); File.Delete(Path.ChangeExtension(filePath, ".pvm")); } Console.WriteLine("Archive was compiled successfully!"); } else { Console.WriteLine("Supplied texture list does not exist!"); Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); return; } break; // Create PB mode case "-pb": filePath = args[1]; Console.WriteLine("Building PB from folder: {0}", filePath); if (Directory.Exists(filePath)) { string indexfilename = Path.Combine(filePath, "index.txt"); if (!File.Exists(indexfilename)) { Console.WriteLine("Supplied path does not have an index file."); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); return; } List <string> filenames = new List <string>(File.ReadAllLines(indexfilename).Where(a => !string.IsNullOrEmpty(a))); PBFile pba = new PBFile(filenames.Count); int l = 0; foreach (string tex in filenames) { byte[] texbytes = File.ReadAllBytes(Path.Combine(filePath, tex)); pba.AddPVR(texbytes, l); l++; } path = Path.Combine(Path.GetDirectoryName(Path.GetFullPath(filePath)), Path.GetFileNameWithoutExtension(filePath)); string filename_full = Path.Combine(Path.GetDirectoryName(Path.GetFullPath(filePath)), Path.GetFileName(filePath) + ".pb"); Console.WriteLine("Output file: {0}", filename_full); File.WriteAllBytes(filename_full, pba.GetBytes()); } else { Console.WriteLine("Supplied path does not exist."); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); return; } break; // Extract NjArchive mode case "-nju": filePath = args[1]; filedata = File.ReadAllBytes(filePath); if (Path.GetExtension(filePath).Equals(".prs", StringComparison.OrdinalIgnoreCase)) { filedata = FraGag.Compression.Prs.Decompress(filedata); } NjArchive njarc = new NjArchive(filedata); Console.WriteLine("Extracting Ninja archive: {0}", filePath); dir = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath)); Console.WriteLine("Output folder: {0}", dir); Directory.CreateDirectory(dir); for (int i = 0; i < njarc.Entries.Count; i++) { byte[] data = njarc.Entries[i]; extension = ".bin"; string desc = "Unknown"; switch (System.Text.Encoding.ASCII.GetString(data, 0, 4)) { case "NJIN": desc = "Ninja Information"; extension = ".nji"; break; case "NJCM": desc = "Ninja Chunk model"; extension = ".nj"; break; case "GJCM": desc = "Ninja Chunk model (GC)"; extension = ".gj"; break; case "NJBM": desc = "Ninja Basic model"; extension = ".nj"; break; case "NMDM": desc = "Ninja Motion"; extension = ".njm"; break; case "NJLI": desc = "Ninja Light"; extension = ".njl"; break; case "NLIM": desc = "Ninja Light Motion"; extension = ".njlm"; break; case "NSSM": desc = "Ninja Simple Shape Motion"; extension = ".njsm"; break; case "NCAM": desc = "Ninja Camera Motion"; extension = ".ncm"; break; case "NJTL": desc = "Ninja Texlist"; extension = ".nj"; break; case "GJTL": desc = "Ninja Texlist (GC)"; extension = ".gj"; break; case "PVMH": desc = "PVM"; extension = ".pvm"; break; case "GVMH": desc = "GVM"; extension = ".gvm"; break; } Console.WriteLine("Entry {0} is {1}", i, desc); string outpath = Path.Combine(dir, i.ToString("D3") + extension); File.WriteAllBytes(outpath, njarc.Entries[i]); } break; // PVM2TexPack mode case "-png": Queue <string> files = new Queue <string>(); for (int u = 1; u < args.Length; u++) { files.Enqueue(args[u]); } if (files.Count == 0) { Console.Write("File: "); files.Enqueue(Console.ReadLine()); } while (files.Count > 0) { string filename = files.Dequeue(); path = Path.Combine(Path.GetDirectoryName(Path.GetFullPath(filename)), Path.GetFileNameWithoutExtension(filename)); string filename_full = Path.Combine(Path.GetDirectoryName(Path.GetFullPath(filename)), Path.GetFileName(filename)); Console.WriteLine("Converting file to texture pack: {0}", filename_full); Directory.CreateDirectory(path); filedata = File.ReadAllBytes(filename_full); using (TextWriter texList = File.CreateText(Path.Combine(path, "index.txt"))) { try { if (PvrTexture.Is(filedata)) { if (!AddTexture(false, path, Path.GetFileName(filename_full), new MemoryStream(filedata), texList)) { texList.Close(); Directory.Delete(path, true); } continue; } else if (GvrTexture.Is(filedata)) { if (!AddTexture(true, path, Path.GetFileName(filename_full), new MemoryStream(filedata), texList)) { texList.Close(); Directory.Delete(path, true); } continue; } bool gvm = false; ArchiveBase pvmfile = null; byte[] pvmdata = File.ReadAllBytes(filename_full); if (Path.GetExtension(filename_full).Equals(".prs", StringComparison.OrdinalIgnoreCase)) { pvmdata = FraGag.Compression.Prs.Decompress(pvmdata); } pvmfile = new PvmArchive(); MemoryStream stream = new MemoryStream(pvmdata); if (!PvmArchive.Identify(stream)) { pvmfile = new GvmArchive(); gvm = true; } ArchiveEntryCollection pvmentries = pvmfile.Open(pvmdata).Entries; bool fail = false; foreach (ArchiveEntry file in pvmentries) { if (!AddTexture(gvm, path, file.Name, file.Open(), texList)) { texList.Close(); Directory.Delete(path, true); fail = true; break; } } if (fail) { continue; } } catch (Exception ex) { Console.WriteLine("Exception thrown: " + ex.ToString() + "\nCanceling conversion."); return; } Console.WriteLine("Conversion complete!"); } } break; // Other modes default: filePath = args[0]; IsPRS = false; if (args.Length > 1 && args[1] == "-prs") { IsPRS = true; } extension = Path.GetExtension(filePath).ToLowerInvariant(); //Folder mode if (Directory.Exists(filePath)) { string indexfilename = Path.Combine(filePath, "index.txt"); List <string> filenames = new List <string>(File.ReadAllLines(indexfilename).Where(a => !string.IsNullOrEmpty(a))); string ext = Path.GetExtension(filenames[0]).ToLowerInvariant(); pvmArchive = new PvmArchive(); switch (ext) { case ".pvr": folderMode = ArchiveFromFolderMode.PVM; break; case ".gvr": pvmArchive = new GvmArchive(); folderMode = ArchiveFromFolderMode.GVM; break; case ".wav": folderMode = ArchiveFromFolderMode.DAT; break; case ".png": case ".jpg": case ".bmp": case ".dds": case ".gif": default: folderMode = ArchiveFromFolderMode.PVMX; break; } Console.WriteLine("Creating {0} archive from folder: {1}", folderMode.ToString(), filePath); switch (folderMode) { case ArchiveFromFolderMode.DAT: // Load index DATFile dat = new DATFile(); TextReader tr = File.OpenText(Path.Combine(filePath, "index.txt")); string line = tr.ReadLine(); while (line != null) { Console.WriteLine("Adding file {0}", Path.Combine(filePath, line)); dat.AddFile(Path.Combine(filePath, line)); line = tr.ReadLine(); } tr.Close(); // Save DAT archive File.WriteAllBytes(filePath + ".DAT", dat.GetBytes()); if (IsPRS) { Console.WriteLine("Compressing to PRS..."); byte[] datdata = File.ReadAllBytes(filePath + ".DAT"); datdata = FraGag.Compression.Prs.Compress(datdata); File.WriteAllBytes(filePath + ".PRS", datdata); File.Delete(filePath + ".DAT"); } Console.WriteLine("Archive compiled successfully!"); return; case ArchiveFromFolderMode.PVM: case ArchiveFromFolderMode.GVM: if (filenames.Any(a => !Path.GetExtension(a).Equals(ext, StringComparison.OrdinalIgnoreCase))) { Console.WriteLine("Cannot create archive from mixed file types."); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); return; } ext = folderMode == ArchiveFromFolderMode.PVM ? ".pvm" : ".gvm"; using (Stream pvmStream = File.Open(Path.ChangeExtension(filePath, ext), FileMode.Create)) { pvmWriter = pvmArchive.Create(pvmStream); // Reading in textures foreach (string tex in filenames) { if (folderMode == ArchiveFromFolderMode.PVM) { pvmWriter.CreateEntryFromFile(Path.Combine(filePath, Path.ChangeExtension(tex, ".pvr"))); } else { pvmWriter.CreateEntryFromFile(Path.Combine(filePath, Path.ChangeExtension(tex, ".gvr"))); } Console.WriteLine("Adding file: {0}", tex); } pvmWriter.Flush(); } if (IsPRS) { Console.WriteLine("Compressing to PRS..."); byte[] pvmdata = File.ReadAllBytes(Path.ChangeExtension(filePath, ext)); pvmdata = FraGag.Compression.Prs.Compress(pvmdata); File.WriteAllBytes(Path.ChangeExtension(filePath, ".prs"), pvmdata); File.Delete(Path.ChangeExtension(filePath, ext)); } Console.WriteLine("Archive was compiled successfully!"); return; case ArchiveFromFolderMode.PVMX: // Load index PVMXFile pvmx = new PVMXFile(); TextReader trp = File.OpenText(Path.Combine(filePath, "index.txt")); foreach (string str in filenames) { string[] split = str.Split(','); string texfile = Path.Combine(Path.GetFullPath(filePath), split[1]); Console.WriteLine("Adding file {0}", texfile); if (split.Length > 2) { string[] dimensions = split[2].Split('x'); pvmx.AddFile(split[1], uint.Parse(split[0]), File.ReadAllBytes(texfile), int.Parse(dimensions[0]), int.Parse(dimensions[1])); } else { pvmx.AddFile(split[1], uint.Parse(split[0]), File.ReadAllBytes(texfile)); } } Console.WriteLine("Output file: {0}", Path.ChangeExtension(filePath, ".pvmx")); File.WriteAllBytes(Path.ChangeExtension(filePath, ".pvmx"), pvmx.GetBytes()); Console.WriteLine("Archive was compiled successfully!"); return; } } //Continue with file mode otherwise if (!File.Exists(filePath)) { Console.WriteLine("Supplied archive/texture list does not exist!"); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); return; } switch (extension) { case ".rel": Console.WriteLine("Decompressing REL file: {0}", filePath); byte[] input = File.ReadAllBytes(args[0]); byte[] output = SA_Tools.HelperFunctions.DecompressREL(input); File.WriteAllBytes(Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath) + "_dec.rel"), output); return; case ".dat": Console.WriteLine("Extracting DAT file: {0}", filePath); DATFile dat = new DATFile(File.ReadAllBytes(filePath)); dir = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath)); if (Directory.Exists(dir)) { Directory.Delete(dir, true); } Directory.CreateDirectory(dir); using (StreamWriter sw = File.CreateText(Path.Combine(dir, "index.txt"))) { dat.Entries.Sort((f1, f2) => StringComparer.OrdinalIgnoreCase.Compare(f1.name, f2.name)); for (int i = 0; i < dat.GetCount(); i++) { string fname = dat.Entries[i].name; sw.WriteLine(fname); if (dat.Steam) { fname = Path.GetFileNameWithoutExtension(fname) + ".adx"; } Console.WriteLine("Extracting file: {0}", fname); File.WriteAllBytes(Path.Combine(dir, fname), dat.GetFile(i)); } sw.Flush(); sw.Close(); } Console.WriteLine("Archive extracted!"); break; case ".pvmx": Console.WriteLine("Extracting PVMX file: {0}", filePath); byte[] pvmxdata = File.ReadAllBytes(filePath); dir = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath)); Directory.CreateDirectory(dir); PVMXFile pvmx = new PVMXFile(pvmxdata); using (TextWriter texList = File.CreateText(Path.Combine(dir, "index.txt"))) { for (int u = 0; u < pvmx.GetCount(); u++) { byte[] tdata = pvmx.GetFile(u); string outpath = Path.Combine(dir, pvmx.GetName(u)); File.WriteAllBytes(outpath, tdata); string entry; string dimensions = string.Join("x", pvmx.GetWidth(u).ToString(), pvmx.GetHeight(u).ToString()); if (pvmx.HasDimensions(u)) { entry = string.Join(",", pvmx.GetGBIX(u).ToString(), pvmx.GetName(u), dimensions); } else { entry = string.Join(",", pvmx.GetGBIX(u).ToString(), pvmx.GetName(u)); } texList.WriteLine(entry); } texList.Flush(); texList.Close(); } Console.WriteLine("Archive extracted!"); break; case ".pb": Console.WriteLine("Extracting PB file: {0}", filePath); byte[] pbdata = File.ReadAllBytes(filePath); dir = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath)); Directory.CreateDirectory(dir); PBFile pba = new PBFile(pbdata); using (TextWriter texList = File.CreateText(Path.Combine(dir, "index.txt"))) { for (int u = 0; u < pba.GetCount(); u++) { byte[] pvrt = pba.GetPVR(u); string outpath = Path.Combine(dir, u.ToString("D3") + ".pvr"); File.WriteAllBytes(outpath, pvrt); texList.WriteLine(u.ToString("D3") + ".pvr"); } texList.Flush(); texList.Close(); } Console.WriteLine("Archive extracted!"); break; case ".bin": Console.WriteLine("Compressing BIN file: {0}", filePath); byte[] bindata = File.ReadAllBytes(Path.ChangeExtension(filePath, ".bin")); bindata = FraGag.Compression.Prs.Compress(bindata); File.WriteAllBytes(Path.ChangeExtension(filePath, ".prs"), bindata); Console.WriteLine("PRS archive was compiled successfully!"); return; case ".prs": case ".pvm": case ".gvm": Console.WriteLine("Extracting archive: {0}", filePath); path = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath)); Directory.CreateDirectory(path); filedata = File.ReadAllBytes(filePath); using (TextWriter texList = File.CreateText(Path.Combine(path, "index.txt"))) { try { ArchiveBase pvmfile = null; byte[] pvmdata = File.ReadAllBytes(filePath); if (extension == ".prs") { pvmdata = FraGag.Compression.Prs.Decompress(pvmdata); } pvmfile = new PvmArchive(); MemoryStream stream = new MemoryStream(pvmdata); if (!PvmArchive.Identify(stream)) { pvmfile = new GvmArchive(); if (!GvmArchive.Identify(stream)) { File.WriteAllBytes(Path.ChangeExtension(filePath, ".bin"), pvmdata); isBIN = true; Console.WriteLine("PRS archive extracted!"); } } if (!isBIN) { ArchiveReader pvmReader = pvmfile.Open(pvmdata); foreach (ArchiveEntry pvmentry in pvmReader.Entries) { Console.WriteLine("Extracting file: {0}", pvmentry.Name); texList.WriteLine(pvmentry.Name); pvmReader.ExtractToFile(pvmentry, Path.Combine(path, pvmentry.Name)); } Console.WriteLine("Archive extracted!"); } } catch { Console.WriteLine("Exception thrown. Canceling conversion."); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); Directory.Delete(path, true); throw; } } if (isBIN) { Directory.Delete(path, true); } break; default: Console.WriteLine("Unknown extension \"{0}\".", extension); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); break; } break; } }
public PuyoFile(byte[] pvmdata) { bool bigendianbk = ByteConverter.BigEndian; Entries = new List <GenericArchiveEntry>(); Type = Identify(pvmdata); switch (Type) { case PuyoArchiveType.PVMFile: ByteConverter.BigEndian = false; break; case PuyoArchiveType.GVMFile: ByteConverter.BigEndian = true; break; default: throw new Exception("Error: Unknown archive format"); } // Get PVM/GVM flags and calculate item size in the entry table ushort numtextures = ByteConverter.ToUInt16(pvmdata, 0x0A); int pvmentrysize = 2; int gbixoffset = 0; int nameoffset = 0; PuyoArchiveFlags flags = (PuyoArchiveFlags)ByteConverter.ToUInt16(pvmdata, 0x08); if (flags.HasFlag(PuyoArchiveFlags.Filenames)) { nameoffset = pvmentrysize; } pvmentrysize += 28; if (flags.HasFlag(PuyoArchiveFlags.PixelDataFormat)) { pvmentrysize += 2; } if (flags.HasFlag(PuyoArchiveFlags.TextureDimensions)) { pvmentrysize += 2; } if (flags.HasFlag(PuyoArchiveFlags.GlobalIndex)) { gbixoffset = pvmentrysize; } pvmentrysize += 4; int offsetfirst = BitConverter.ToInt32(pvmdata, 0x4) + 8; // Always Little Endian int textureaddr = GetPVRTOffset(pvmdata, offsetfirst); // Where texture data begins for (int t = 0; t < numtextures; t++) { int size_gbix = flags.HasFlag(PuyoArchiveFlags.GlobalIndex) ? 16 : 0; int size = BitConverter.ToInt32(pvmdata, textureaddr + 4); // Always Little Endian byte[] pvrchunk = new byte[size + 8 + size_gbix]; // Handle cases when data size in the PVR/GVR header goes beyond the range of the archive (Billy Hatcher) if ((textureaddr + size + 8) > pvmdata.Length) { do { size--; }while ((textureaddr + size + 8) > pvmdata.Length); } Array.Copy(pvmdata, textureaddr, pvrchunk, 0 + size_gbix, size + 8); // Add GBIX header if the PVM/GVM has GBIX enabled if (flags.HasFlag(PuyoArchiveFlags.GlobalIndex)) { Array.Copy(BitConverter.GetBytes(Magic_GBIX), 0, pvrchunk, 0, 4); // Little Endian pvrchunk[4] = 0x08; // Always 8 according to PuyoTools uint gbix = BitConverter.ToUInt32(pvmdata, 0xC + pvmentrysize * t + gbixoffset); byte[] gbixb = BitConverter.GetBytes(gbix); Array.Copy(gbixb, 0, pvrchunk, 8, 4); } // Set filename if the PVM/GVM has filenames string entryfn = t.ToString("D3"); if (flags.HasFlag(PuyoArchiveFlags.Filenames)) { byte[] namestring = new byte[28]; for (int n = 0; n < 28; n++) { // Entry names in some PVMs (e.g. DEMO.PVM in Dream Passport 3) have garbage data after the first 0, so it needs to be truncated byte ndt = pvmdata[0xC + pvmentrysize * t + nameoffset + n]; if (ndt == 0) { break; } namestring[n] = ndt; } entryfn = Encoding.ASCII.GetString(namestring).TrimEnd((char)0); } else { hasNameData = false; } if (t < numtextures - 1) // Get the address of the next PVRT chunk, unless it's the last one { textureaddr = GetPVRTOffset(pvmdata, textureaddr + size + 8); } // Add PVR/GVR texture to the entry list if (Type == PuyoArchiveType.PVMFile) { PvrTexture pvrt = new PvrTexture(pvrchunk); if (pvrt.NeedsExternalPalette) { PaletteRequired = true; } Entries.Add(new PVMEntry(pvrchunk, entryfn + ".pvr")); } else { GvrTexture gvrt = new GvrTexture(pvrchunk); if (gvrt.NeedsExternalPalette) { PaletteRequired = true; } Entries.Add(new GVMEntry(pvrchunk, entryfn + ".gvr")); } } ByteConverter.BigEndian = bigendianbk; }
public override byte[] GetBytes() { bool bigendianbk = ByteConverter.BigEndian; ByteConverter.BigEndian = Type == PuyoArchiveType.GVMFile; List <byte> result = new List <byte>(); result.AddRange(Type == PuyoArchiveType.PVMFile ? BitConverter.GetBytes(Magic_PVM) : BitConverter.GetBytes(Magic_GVM)); // Create entry list List <byte> entrytable = new List <byte>(); uint firstoffset = 12; for (int i = 0; i < Entries.Count; i++) { entrytable.AddRange(ByteConverter.GetBytes((ushort)i)); byte[] namestring = System.Text.Encoding.ASCII.GetBytes(Path.GetFileNameWithoutExtension(Entries[i].Name)); byte[] namefull = new byte[28]; Array.Copy(namestring, namefull, namestring.Length); entrytable.AddRange(namefull); ushort dimensions = 0; uint gbix = 0; if (Entries[i] is PVMEntry pvme) { PvrTexture pvrt = new PvrTexture(pvme.Data); entrytable.Add((byte)pvrt.PixelFormat); entrytable.Add((byte)pvrt.DataFormat); dimensions |= (ushort)(((byte)Math.Log(pvrt.TextureWidth, 2) - 2) & 0xF); dimensions |= (ushort)((((byte)Math.Log(pvrt.TextureHeight, 2) - 2) & 0xF) << 4); gbix = pvrt.GlobalIndex; } else if (Entries[i] is GVMEntry gvme) { GvrTexture gvrt = new GvrTexture(gvme.Data); entrytable.Add((byte)gvrt.PixelFormat); entrytable.Add((byte)gvrt.DataFormat); dimensions |= (ushort)(((byte)Math.Log(gvrt.TextureWidth, 2) - 2) & 0xF); dimensions |= (ushort)((((byte)Math.Log(gvrt.TextureHeight, 2) - 2) & 0xF) << 4); gbix = gvrt.GlobalIndex; } entrytable.AddRange(ByteConverter.GetBytes(dimensions)); entrytable.AddRange(ByteConverter.GetBytes(gbix)); } // Add padding if the data isn't aligned by 16 if ((12 + entrytable.Count) % 16 != 0) { do { entrytable.Add(0); }while ((12 + entrytable.Count) % 16 != 0); } // Write other header stuff result.AddRange(BitConverter.GetBytes((uint)(firstoffset + entrytable.Count - 8))); // Offset of the first texture, Little Endian result.AddRange(ByteConverter.GetBytes((ushort)0xF)); // PVM/GVM flags result.AddRange(ByteConverter.GetBytes((ushort)Entries.Count)); result.AddRange(entrytable); // Write texture data for (int i = 0; i < Entries.Count; i++) { // Align by 16 int length = Entries[i].Data.Length - 16; if (length % 16 != 0) { do { length++; }while (length % 16 != 0); } byte[] nogbix = new byte[length]; Array.Copy(Entries[i].Data, 16, nogbix, 0, Entries[i].Data.Length - 16); result.AddRange(nogbix); } ByteConverter.BigEndian = bigendianbk; return(result.ToArray()); }