Esempio n. 1
0
        public static void Repack(string descFilePath)
        {
            Console.WriteLine("Repacking {0}:", descFilePath);
            if (!File.Exists(descFilePath))
            {
                Console.WriteLine("peg_desc file does not exist: {0}", descFilePath);
                return;
            }

            string extension = Path.GetExtension(descFilePath);

            if (!(extension == ".peg_desc"))
            {
                Console.WriteLine("File is not a peg_desc file: {0}", descFilePath);
                return;
            }

            string descFolder = Path.GetDirectoryName(descFilePath);

            Console.Write("Loading Peg Description... ");
            PegFile pegFile = XmlParser.ParseFile(descFilePath);

            if (pegFile == null)
            {
                Console.WriteLine("An error occurred while loading the peg_desc file.");
                return;
            }
            Console.WriteLine("done.");

            Console.WriteLine("Loading texture data, performing colour space conversions and compressing data:");
            Dictionary <PegFrame, byte[]> rawFrameData = new Dictionary <PegFrame, byte[]>();

            uint   totalSize   = 0;
            ushort totalFrames = 0;

            foreach (PegEntry entry in pegFile.Entries)
            {
                for (int i = 0; i < entry.Frames.Count; i++)
                {
                    PegFrame frame = entry.Frames[i];
                    Console.Write(" - {0} (frame {1})... ", entry.Name, i);
                    frame.Frames = (ushort)((i == 0) ? entry.Frames.Count : 1);
                    frame.Offset = totalSize;
                    PegFormat format  = (PegFormat)frame.Format;
                    byte[]    rawData = null;

                    string rawFilePath = Path.Combine(descFolder, String.Format("{0}_{1}.raw", entry.Name, i));
                    string filePath    = Path.Combine(descFolder, String.Format("{0}_{1}.png", entry.Name, i));

                    if (File.Exists(rawFilePath))
                    {
                        Console.Write("loading from {0}... ", rawFilePath);
                        FileStream rawFileStream = new FileStream(rawFilePath, FileMode.Open, FileAccess.Read, FileShare.None);
                        rawData = new byte[rawFileStream.Length];
                        rawFileStream.Read(rawData, 0, rawData.Length);
                        rawFileStream.Close();
                        Console.WriteLine("done.");
                    }
                    else
                    {
                        Console.Write("importing from {0}... ", filePath);
                        if (!File.Exists(filePath))
                        {
                            Console.WriteLine("Unable to find file: {0}", filePath);
                            Console.WriteLine("Make sure all your texture files are in the correct location and correctly named.");
                            return;
                        }

                        Bitmap srcBitmap = new Bitmap(filePath);
                        switch (format)
                        {
                        case PegFormat.DXT1:
                        case PegFormat.DXT3:
                        case PegFormat.DXT5:
                            rawData = GetRawA8R8G8B8DataFromBitmap(srcBitmap);
                            ImageFormats.SwapRedAndBlue((uint)srcBitmap.Width, (uint)srcBitmap.Height, ref rawData);
                            rawData = ImageFormats.Compress(rawData, (uint)srcBitmap.Width, (uint)srcBitmap.Height, format);
                            break;

                        case PegFormat.A8R8G8B8:
                            rawData = GetRawA8R8G8B8DataFromBitmap(srcBitmap);
                            break;

                        case PegFormat.R5G6B5:
                            Bitmap outBitmap = new Bitmap(srcBitmap.Width, srcBitmap.Height, PixelFormat.Format16bppRgb565);
                            srcBitmap.SetResolution(96, 96);
                            Graphics g = Graphics.FromImage(outBitmap);
                            g.CompositingMode    = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
                            g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                            g.SmoothingMode      = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                            g.DrawImage(srcBitmap, 0, 0, srcBitmap.Width, srcBitmap.Height);
                            g.Dispose();
                            Rectangle  lockArea   = new Rectangle(0, 0, outBitmap.Width, outBitmap.Height);
                            BitmapData bitmapData = outBitmap.LockBits(lockArea, ImageLockMode.ReadOnly, outBitmap.PixelFormat);
                            rawData = new byte[srcBitmap.Width * srcBitmap.Height * 2];
                            Marshal.Copy(bitmapData.Scan0, rawData, 0, rawData.Length);
                            outBitmap.UnlockBits(bitmapData);
                            outBitmap.Dispose();
                            break;

                        default:
                            throw new Exception("Unhandled format: " + format.ToString());
                        }

                        srcBitmap.Dispose();
                        Console.WriteLine("done.");
                    }
                    frame.Size = (uint)rawData.Length;
                    totalSize += frame.Size;
                    if (totalSize % 16 != 0)
                    {
                        uint difference = (uint)(Math.Ceiling((float)totalSize / 16f) * 16) - totalSize;
                        totalSize += difference;
                    }
                    totalFrames++;
                    entry.Frames[i] = frame;
                    rawFrameData.Add(frame, rawData);
                }
            }
            pegFile.DataFileSize = totalSize;
            Console.WriteLine("Finished loading texture data.");

            Console.Write("Writing peg_pc and g_peg_pc files...");
            string pegFilePath     = Path.ChangeExtension(descFilePath, "peg_pc");
            string pegDataFilePath = Path.ChangeExtension(descFilePath, "g_peg_pc");

            FileStream pegFileStream     = new FileStream(pegFilePath, FileMode.Create, FileAccess.Write, FileShare.None);
            FileStream pegDataFileStream = new FileStream(pegDataFilePath, FileMode.Create, FileAccess.Write, FileShare.None);

            pegFileStream.WriteU32(0x564B4547);       // GEKV
            pegFileStream.WriteU16(10);               // Version
            pegFileStream.WriteU16(pegFile.Unknown06);
            pegFileStream.WriteU32(pegFile.FileSize); // Length - we come back and fill this in later
            pegFileStream.WriteU32(pegFile.DataFileSize);
            pegFileStream.WriteU16((ushort)pegFile.Entries.Count);
            pegFileStream.WriteU16(pegFile.Unknown12);
            pegFileStream.WriteU16(totalFrames);
            pegFileStream.WriteU16(pegFile.Unknown16);

            // Write entries
            pegFileStream.Seek(0x18, SeekOrigin.Begin);
            foreach (PegEntry entry in pegFile.Entries)
            {
                for (int i = 0; i < entry.Frames.Count; i++)
                {
                    PegFrame frame     = entry.Frames[i];
                    byte[]   frameData = StructureToByteArray(frame);
                    pegFileStream.Write(frameData, 0, frameData.Length);
                }
            }

            // Write names
            pegFileStream.Seek(0x18 + (0x30 * totalFrames), SeekOrigin.Begin);
            foreach (PegEntry entry in pegFile.Entries)
            {
                pegFileStream.WriteASCIIZ(entry.Name);
            }
            pegFileStream.Seek(0x08, SeekOrigin.Begin);
            pegFileStream.WriteU32((uint)pegFileStream.Length);
            pegFileStream.Flush();
            pegFileStream.Close();

            pegDataFileStream.SetLength(pegFile.DataFileSize);

            foreach (PegEntry entry in pegFile.Entries)
            {
                foreach (PegFrame frame in entry.Frames)
                {
                    pegDataFileStream.Seek(frame.Offset, SeekOrigin.Begin);
                    pegDataFileStream.Write(rawFrameData[frame], 0, (int)frame.Size);
                }
            }
            pegDataFileStream.Flush();
            pegDataFileStream.Close();

            Console.WriteLine("done.");

            Console.WriteLine();
            Console.WriteLine("Finished repacking.");
        }
Esempio n. 2
0
        public static void ParseFrames(XmlNode framesNode, PegEntry entry)
        {
            foreach (XmlNode frameNode in framesNode.ChildNodes)
            {
                switch (frameNode.Name)
                {
                case "Frame":
                    PegFrame frame = new PegFrame();
                    foreach (XmlNode node in frameNode.ChildNodes)
                    {
                        switch (node.Name)
                        {
                        case "Width":
                            ushort.TryParse(node.InnerText, out frame.Width);
                            break;

                        case "Height":
                            ushort.TryParse(node.InnerText, out frame.Height);
                            break;

                        case "Format":
                            PegFormat format = (PegFormat)Enum.Parse(typeof(PegFormat), node.InnerText, true);
                            frame.Format = (ushort)format;
                            break;

                        case "Unknown0A":
                            ushort.TryParse(node.InnerText, out frame.Unknown0A);
                            break;

                        case "Unknown0C":
                            uint.TryParse(node.InnerText, out frame.Unknown0C);
                            break;

                        case "Unknown12":
                            uint.TryParse(node.InnerText, out frame.Unknown12);
                            break;

                        case "Unknown16":
                            uint.TryParse(node.InnerText, out frame.Unknown16);
                            break;

                        case "UnknownFlags1A":
                            ushort.TryParse(node.InnerText, System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out frame.UnknownFlags1A);
                            break;

                        case "Size":
                            uint.TryParse(node.InnerText, out frame.Size);
                            break;

                        case "Unknown20":
                            uint.TryParse(node.InnerText, out frame.Unknown20);
                            break;

                        case "Unknown24":
                            uint.TryParse(node.InnerText, out frame.Unknown24);
                            break;

                        case "Unknown28":
                            uint.TryParse(node.InnerText, out frame.Unknown28);
                            break;

                        case "Unknown2C":
                            uint.TryParse(node.InnerText, out frame.Unknown2C);
                            break;
                            //default:
                            //throw new Exception(String.Format("Encountered unknown XML element: {0}", node.Name));
                        }
                    }
                    entry.Frames.Add(frame);
                    break;

                default:
                    throw new Exception(String.Format("Encountered unknown XML element: {0}", frameNode.Name));
                }
            }
        }
Esempio n. 3
0
        public static void UnpackImages(PegFile pegFile, string path, Stream pegDataFileStream)
        {
            foreach (PegEntry entry in pegFile.Entries)
            {
                Console.WriteLine("Extracting {0} ({1} frame{2}):", entry.Name, entry.Frames.Count, (entry.Frames.Count == 1 ? "" : "s"));
                for (int i = 0; i < entry.Frames.Count; i++)
                {
                    string filePath    = Path.Combine(path, String.Format("{0}_{1}.png", entry.Name, i));
                    string rawFilePath = Path.Combine(path, String.Format("{0}_{1}.raw", entry.Name, i));
                    Console.Write(" - Extracting {0}... ", filePath);

                    PegFrame frame = entry.Frames[i];
                    pegDataFileStream.Seek(frame.Offset, SeekOrigin.Begin);
                    byte[] rawData = new byte[frame.Size];
                    pegDataFileStream.Read(rawData, 0, (int)frame.Size);

                    PegFormat format = (PegFormat)frame.Format;

                    FileStream rawFileStream = new FileStream(rawFilePath, FileMode.Create, FileAccess.Write, FileShare.None);
                    rawFileStream.Write(rawData, 0, rawData.Length);
                    rawFileStream.Flush();
                    rawFileStream.Close();

                    Bitmap bitmap = null;

                    switch (format)
                    {
                    case PegFormat.A8R8G8B8:
                        if (pegFile.BigEndian)
                        {
                            rawData = ImageFormats.ByteSwap(rawData, format);
                        }
                        bitmap = ImageFormats.MakeBitmapFromA8R8G8B8(frame.Width, frame.Height, rawData);
                        break;

                    case PegFormat.R5G6B5:
                        if (pegFile.BigEndian)
                        {
                            rawData = ImageFormats.ByteSwap(rawData, format);
                        }
                        bitmap = ImageFormats.MakeBitmapFromR5G6B5(frame.Width, frame.Height, rawData);
                        break;

                    case PegFormat.DXT1:
                        if (pegFile.BigEndian)
                        {
                            rawData = ImageFormats.ByteSwap(rawData, format);
                        }
                        byte[] decompressedDXT1 = ImageFormats.Decompress(rawData, frame.Width, frame.Height, format);
                        bitmap = ImageFormats.MakeBitmapFromDXT(frame.Width, frame.Height, decompressedDXT1, false);
                        break;

                    case PegFormat.DXT3:
                    case PegFormat.DXT5:
                        byte[] decompressed = ImageFormats.Decompress(rawData, frame.Width, frame.Height, format);
                        bitmap = ImageFormats.MakeBitmapFromDXT(frame.Width, frame.Height, decompressed, true);
                        break;

                    default:
                        throw new Exception("Unhandled format: " + format.ToString());
                    }

                    bitmap.Save(filePath, ImageFormat.Png);
                    bitmap.Dispose();

                    Console.WriteLine("done.");
                }
            }
        }