示例#1
0
        public static void ParseEntries(XmlNode entriesNode, PegFile pegFile)
        {
            foreach (XmlNode entryNode in entriesNode.ChildNodes)
            {
                switch (entryNode.Name)
                {
                case "Entry":
                    PegEntry entry = new PegEntry();
                    foreach (XmlNode node in entryNode.ChildNodes)
                    {
                        switch (node.Name)
                        {
                        case "Name":
                            entry.Name = node.InnerText;
                            break;

                        case "Frames":
                            ParseFrames(node, entry);
                            break;
                            //default:
                            //throw new Exception(String.Format("Encountered unknown XML element: {0}", node.Name));
                        }
                    }
                    pegFile.Entries.Add(entry);
                    break;
                    //default:
                    //throw new Exception(String.Format("Encountered unknown XML element: {0}", entryNode.Name));
                }
            }
        }
示例#2
0
        static Stream ProcessPeg(IPackfileEntry pegEntry, string newName)
        {
            textureNameMap.Clear();

            using (Stream pegStream = pegEntry.GetStream())
            {
                PegFile peg = new PegFile(pegStream);

                string sharedPrefix = FilterPegEntryFilename(peg.Entries[0].Filename);
                foreach (PegEntry entry in peg.Entries)
                {
                    while (!FilterPegEntryFilename(entry.Filename).StartsWith(sharedPrefix))
                    {
                        sharedPrefix = sharedPrefix.Substring(0, sharedPrefix.Length - 1);
                    }
                }

                foreach (PegEntry entry in peg.Entries)
                {
                    string newFilename = null;
                    if (sharedPrefix == "")
                    {
                        newFilename = newName + "_" + entry.Filename;
                    }
                    else
                    {
                        newFilename = entry.Filename.Replace(sharedPrefix, newName + "_").ToLowerInvariant();
                        if (newFilename.StartsWith("cf_cf_") || newFilename.StartsWith("cf_cm_") || newFilename.StartsWith("cm_cf_") || newFilename.StartsWith("cm_cm_"))
                        {
                            newFilename = newFilename.Remove(3, 3);
                        }
                    }

                    if (!textureNameMap.ContainsKey(entry.Filename))
                    {
                        textureNameMap.Add(entry.Filename, newFilename);
                    }

                    entry.Filename = newFilename;
                }

                MemoryStream outStream = new MemoryStream();
                peg.Save(outStream);

                return(outStream);
            }
        }
示例#3
0
        public static void Unpack(string pegFilePath)
        {
            Console.WriteLine("Unpacking {0}:", pegFilePath);
            if (!File.Exists(pegFilePath))
            {
                Console.WriteLine("peg_pc file does not exist: {0}", pegFilePath);
                return;
            }
            string extension = Path.GetExtension(pegFilePath).ToLower();
            bool   xbox      = (extension == ".peg_xbox2");

            if (!(extension == ".peg_pc" || extension == ".peg_xbox2"))
            {
                Console.WriteLine("File is not a peg_pc file: {0}", pegFilePath);
                return;
            }

            string pegDataFilePath = xbox ? Path.ChangeExtension(pegFilePath, "g_peg_xbox2") : Path.ChangeExtension(pegFilePath, "g_peg_pc");
            string pegDescFilePath = Path.ChangeExtension(pegFilePath, "peg_desc");

            if (!File.Exists(pegDataFilePath))
            {
                Console.WriteLine("g_peg_pc file does not exist: {0}", pegDataFilePath);
                Console.WriteLine("Did you copy it into the same directory as {0}?", pegFilePath);
                return;
            }

            PegFile    pegFile           = new PegFile(xbox);
            FileStream pegFileStream     = new FileStream(pegFilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
            FileStream pegDataFileStream = new FileStream(pegDataFilePath, FileMode.Open, FileAccess.Read, FileShare.Read);

            pegFile.Read(pegFileStream);

            string extractionPath = Path.GetDirectoryName(pegFilePath);

            Console.Write("Writing peg description to: {0}... ", pegDescFilePath);
            Console.WriteLine(" done.");
            WritePegDescription(pegFile, pegDescFilePath);
            Console.WriteLine("Unpacking images:");
            UnpackImages(pegFile, extractionPath, pegDataFileStream);
            pegFileStream.Close();
            pegDataFileStream.Close();
            Console.WriteLine();
            Console.WriteLine("Finished unpacking.");
        }
示例#4
0
        public void ReadFormatData()
        {
            switch (FileType)
            {
            case RfgFileTypes.None:
                return;

            case RfgFileTypes.Packfile:
                PackfileData = new Packfile(false);
                PackfileData.ReadMetadata(FilePath);
                PackfileData.DirectoryEntries.Sort((entry1, entry2) => string.Compare(entry1.FileName, entry2.FileName, StringComparison.Ordinal));
                PackfileData.ParseAsmFiles($"{CachePath}{Filename}\\");
                break;

            case RfgFileTypes.Container:
                PackfileData = new Packfile(false);
                PackfileData.ReadMetadata(FilePath);
                break;

            case RfgFileTypes.Primitive:
                string extension = Path.GetExtension(Filename);
                if (extension == ".cpeg_pc" || extension == ".cvbm_pc")
                {
                    if (!PathHelpers.TryGetGpuFileNameFromCpuFile(FilePath, out string gpuFileName))
                    {
                        return;
                    }

                    string basePath    = Path.GetDirectoryName(FilePath);
                    string gpuFilePath = $"{basePath}\\{gpuFileName}";

                    //Todo: Change this to check editor or project cache depending on CacheFile location
                    //Ensure gpu file is extracted
                    if (!ProjectManager.TryGetCacheFile(gpuFileName, ParentName, out _, true))
                    {
                        return;
                    }

                    PegData = new PegFile();
                    PegData.Read(FilePath, gpuFilePath);
                }
                //Todo: Add checks for primitive type, and primitive handling code
                break;
            }
        }
        private void OpenTextureFile_OnClick(object sender, RoutedEventArgs e)
        {
            _fileBrowser.IsFolderPicker = false;
            if (_fileBrowser.ShowDialog() == CommonFileDialogResult.Ok)
            {
                string cpuFilePath = _fileBrowser.FileName;
                if (!File.Exists(cpuFilePath))
                {
                    return;
                }

                var cpuFileInfo = new FileInfo(cpuFilePath);

                if (cpuFileInfo.Extension == ".cpeg_pc")
                {
                    var gpuFileInfo = new FileInfo(cpuFileInfo.DirectoryName + "\\" + Path.GetFileNameWithoutExtension(cpuFilePath) + ".gpeg_pc");
                    _peg = new PegFile(cpuFilePath, gpuFileInfo.FullName);
                    _peg.Read();
                }
                else if (cpuFileInfo.Extension == ".cvbm_pc")
                {
                    var gpuFileInfo = new FileInfo(cpuFileInfo.DirectoryName + "\\" + Path.GetFileNameWithoutExtension(cpuFilePath) + ".gvbm_pc");
                    _peg = new PegFile(cpuFilePath, gpuFileInfo.FullName);
                    _peg.Read();
                }
                else
                {
                    throw new Exception($"{cpuFileInfo.Extension} is an invalid file extension for peg files!");
                }

                UpdateWindowTitle();
                PopulateTreeView();
                SetSelectedTexture(0);
                UpdateInfoPanel();
            }
        }
示例#6
0
        private void GenerateTextureData(PegFile pegData)
        {
            //Add peg info
            DataPanel.Children.Add(new TextBlock
            {
                Inlines =
                {
                    new Run
                    {
                        Text     = "Peg info", FontWeight = FontWeights.Bold,
                        FontSize = 14
                    },
                    new LineBreak(),

                    new Run {
                        Text = "Name: ", FontWeight = FontWeights.Bold
                    },
                    new Run {
                        Text = pegData.cpuFileName
                    },
                    new LineBreak(),

                    new Run {
                        Text = "Version: ", FontWeight = FontWeights.Bold
                    },
                    new Run {
                        Text = pegData.Version.ToString()
                    },
                    new LineBreak(),

                    new Run {
                        Text = "Platform: ", FontWeight = FontWeights.Bold
                    },
                    new Run {
                        Text = pegData.Platform.ToString()
                    },
                    new LineBreak(),

                    new Run {
                        Text = "Cpeg size: ", FontWeight = FontWeights.Bold
                    },
                    new Run {
                        Text = pegData.DirectoryBlockSize.ToString()
                    },
                    new LineBreak(),

                    new Run {
                        Text = "Gpeg size: ", FontWeight = FontWeights.Bold
                    },
                    new Run {
                        Text = pegData.DataBlockSize.ToString()
                    },
                    new LineBreak(),

                    new Run {
                        Text = "Number of sub-textures: ", FontWeight = FontWeights.Bold
                    },
                    new Run {
                        Text = pegData.NumberOfBitmaps.ToString()
                    },
                    new LineBreak(),

                    new Run {
                        Text = "Flags: ", FontWeight = FontWeights.Bold
                    },
                    new Run {
                        Text = pegData.Flags.ToString()
                    },
                    new LineBreak(),

                    new Run {
                        Text = "Total entries: ", FontWeight = FontWeights.Bold
                    },
                    new Run {
                        Text = pegData.TotalEntries.ToString()
                    },
                    new LineBreak(),

                    new Run {
                        Text = "Align value: ", FontWeight = FontWeights.Bold
                    },
                    new Run {
                        Text = pegData.AlignValue.ToString()
                    },
                    new LineBreak()
                },
                TextWrapping = TextWrapping.Wrap
            });

            //Add sub-texture info
            var subTextures = new TreeView();
            var rootNode    = new TreeViewItem {
                Header = "Texture info", IsExpanded = true
            };

            foreach (var entry in pegData.Entries)
            {
                var entryNode = new TreeViewItem {
                    Header = entry.Name, IsExpanded = true
                };
                //Add basic values
                entryNode.Items.Add(new TextBlock
                {
                    Margin  = new Thickness(0.0, 0.0, 0.0, -15.0),
                    Inlines =
                    {
                        new Run {
                            Text = "Width: ", FontWeight = FontWeights.Bold
                        },
                        new Run {
                            Text = entry.width.ToString()
                        },
                        new LineBreak(),

                        new Run {
                            Text = "Height: ", FontWeight = FontWeights.Bold
                        },
                        new Run {
                            Text = entry.height.ToString()
                        },
                        new LineBreak(),

                        new Run {
                            Text = "Format: ", FontWeight = FontWeights.Bold
                        },
                        new Run {
                            Text = entry.bitmap_format.ToString()
                        },
                        new LineBreak()
                    }
                });

                //Add advanced values //Todo: Add some helpers to shorten this code
                entryNode.Items.Add(new TreeViewItem
                {
                    Header = "Advanced values",
                    Items  =
                    {
                        new TextBlock
                        {
                            Inlines =
                            {
                                new Run {
                                    Text = "Data offset: ", FontWeight = FontWeights.Bold
                                },
                                new Run {
                                    Text = entry.data.ToString()
                                },
                                new LineBreak(),

                                new Run {
                                    Text = "Source width: ", FontWeight = FontWeights.Bold
                                },
                                new Run {
                                    Text = entry.source_width.ToString()
                                },
                                new LineBreak(),

                                new Run {
                                    Text = "Source height: ", FontWeight = FontWeights.Bold
                                },
                                new Run {
                                    Text = entry.source_height.ToString()
                                },
                                new LineBreak(),

                                new Run {
                                    Text = "Anim tiles width: ", FontWeight = FontWeights.Bold
                                },
                                new Run {
                                    Text = entry.anim_tiles_width.ToString()
                                },
                                new LineBreak(),

                                new Run {
                                    Text = "Anim tiles height: ", FontWeight = FontWeights.Bold
                                },
                                new Run {
                                    Text = entry.anim_tiles_height.ToString()
                                },
                                new LineBreak(),

                                new Run {
                                    Text = "Number of frames: ", FontWeight = FontWeights.Bold
                                },
                                new Run {
                                    Text = entry.num_frames.ToString()
                                },
                                new LineBreak(),

                                new Run {
                                    Text = "Flags: ", FontWeight = FontWeights.Bold
                                },
                                new Run {
                                    Text = entry.flags.ToString()
                                },
                                new LineBreak(),

                                new Run {
                                    Text = "Filename hash: ", FontWeight = FontWeights.Bold
                                },
                                new Run {
                                    Text = entry.filename.ToString()
                                },
                                new LineBreak(),

                                new Run {
                                    Text = "FPS: ", FontWeight = FontWeights.Bold
                                },
                                new Run {
                                    Text = entry.fps.ToString()
                                },
                                new LineBreak(),

                                new Run {
                                    Text = "Mip levels: ", FontWeight = FontWeights.Bold
                                },
                                new Run {
                                    Text = entry.mip_levels.ToString()
                                },
                                new LineBreak(),

                                new Run {
                                    Text = "Frame size: ", FontWeight = FontWeights.Bold
                                },
                                new Run {
                                    Text = entry.frame_size.ToString()
                                },
                                new LineBreak(),

                                new Run {
                                    Text = "Next: ", FontWeight = FontWeights.Bold
                                },
                                new Run {
                                    Text = entry.next.ToString()
                                },
                                new LineBreak(),

                                new Run {
                                    Text = "Previous: ", FontWeight = FontWeights.Bold
                                },
                                new Run {
                                    Text = entry.previous.ToString()
                                },
                                new LineBreak(),

                                new Run {
                                    Text = "Cache 0: ", FontWeight = FontWeights.Bold
                                },
                                new Run {
                                    Text = entry.cache0.ToString()
                                },
                                new LineBreak(),

                                new Run {
                                    Text = "Cache 1: ", FontWeight = FontWeights.Bold
                                },
                                new Run {
                                    Text = entry.cache1.ToString()
                                },
                                new LineBreak(),
                            }
                        }
                    }
                });
                rootNode.Items.Add(entryNode);
            }

            subTextures.Items.Add(rootNode);
            DataPanel.Children.Add(subTextures);
        }
        public static void Main(string[] args)
        {
            var fullAlpha = false;
            var showHelp  = false;
            var mode      = Mode.Unknown;

            var options = new OptionSet()
            {
                // ReSharper disable AccessToModifiedClosure
                { "full-alpha", "when decoding textures, don't force 1-bit alpha", v => fullAlpha = v != null },
                { "a|assemble", "assemble PEG file", v => mode = v != null ? Mode.Assemble : mode },
                { "d|disassemble", "disassemble PEG file", v => mode = v != null ? Mode.Disassemble : mode },
                { "h|help", "show this message and exit", v => showHelp = v != null },
                // ReSharper restore AccessToModifiedClosure
            };

            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 (mode == Mode.Unknown && extras.Count > 0)
            {
                // detect mode
                if (Directory.Exists(extras[0]) == true)
                {
                    mode = Mode.Assemble;
                }
                else if (File.Exists(extras[0]) == true)
                {
                    mode = Mode.Disassemble;
                }
            }

            if (extras.Count < 1 || extras.Count > 2 ||
                showHelp == true || mode == Mode.Unknown)
            {
                Console.WriteLine("Usage: {0} [OPTIONS]+ [-a|-d] input [output]", GetExecutableName());
                Console.WriteLine();
                Console.WriteLine("Options:");
                options.WriteOptionDescriptions(Console.Out);
                return;
            }

            if (mode == Mode.Assemble)
            {
                throw new NotImplementedException();
            }
            else if (mode == Mode.Disassemble)
            {
                var inputPath      = Path.GetFullPath(extras[0]);
                var outputBasePath = extras.Count > 1 ? extras[1] : Path.ChangeExtension(inputPath, null);

                using (var input = File.OpenRead(inputPath))
                {
                    var peg = new PegFile();
                    peg.Deserialize(input);

                    if (peg.Textures.Count == 0)
                    {
                        return;
                    }

                    var info = new PegFileInfo()
                    {
                        Endian   = peg.Endian,
                        Version  = peg.Version,
                        Textures = new List <PegTextureInfo>(),
                    };

                    Directory.CreateDirectory(outputBasePath);

                    for (int i = 0; i < peg.Textures.Count; i++)
                    {
                        var nextDataOffset = i + 1 >= peg.Textures.Count
                                                 ? input.Length
                                                 : peg.Textures[i + 1].DataOffset;

                        var texture        = peg.Textures[i];
                        var rawTextureSize = nextDataOffset - texture.DataOffset;
                        var frameSize      = ComputeFrameSize(texture);
                        var textureSize    = frameSize * texture.FrameCount;
                        if (rawTextureSize < textureSize)
                        {
                            throw new FormatException();
                        }

                        input.Position = texture.DataOffset;

                        var textureInfo = new PegTextureInfo()
                        {
                            Width          = texture.Width,
                            Height         = texture.Height,
                            Format         = texture.Format,
                            FormatArgument = texture.FormatArgument,
                            Flags          = texture.Flags,
                            AnimationDelay = texture.AnimationDelay,
                            MipCount       = texture.MipCount,
                            UnknownA       = texture.UnknownA,
                            UnknownB       = texture.UnknownB,
                            Name           = texture.Name,
                        };

                        if (texture.FrameCount == 1)
                        {
                            textureInfo.Path = texture.Name + ".png";
                            var outputPath = Path.Combine(outputBasePath, textureInfo.Path);
                            var bytes      = input.ReadBytes(textureSize);
                            using (var bitmap = ExportTexture(texture, bytes, fullAlpha == false))
                            {
                                bitmap.Save(outputPath, ImageFormat.Png);
                            }
                        }
                        else
                        {
                            textureInfo.FramePaths = new List <string>();
                            for (int j = 0; j < texture.FrameCount; j++)
                            {
                                var texturePath = texture.Name + "_" + j + ".png";
                                textureInfo.FramePaths.Add(texturePath);
                                var outputPath = Path.Combine(outputBasePath, texturePath);
                                var bytes      = input.ReadBytes(frameSize);
                                using (var bitmap = ExportTexture(texture, bytes, fullAlpha == false))
                                {
                                    bitmap.Save(outputPath, ImageFormat.Png);
                                }
                            }
                        }

                        info.Textures.Add(textureInfo);
                    }

                    using (var output = File.Create(Path.Combine(outputBasePath, "@peg.json")))
                        using (var textWriter = new StreamWriter(output, Encoding.UTF8))
                            using (var writer = new JsonTextWriter(textWriter))
                            {
                                writer.Formatting  = Newtonsoft.Json.Formatting.Indented;
                                writer.Indentation = 2;
                                writer.IndentChar  = ' ';

                                var serializer = new JsonSerializer();
                                serializer.Serialize(writer, info);
                            }
                }
            }
        }
示例#8
0
        public static PegFile ParseFile(string descFilePath)
        {
            XmlDocument document = new XmlDocument();

            document.Load(descFilePath);
            PegFile pegFile  = new PegFile(false);
            XmlNode rootNode = null;

            foreach (XmlNode childNode in document.ChildNodes)
            {
                if (childNode.Name == "PegDescription")
                {
                    rootNode = childNode;
                    break;
                }
            }
            if (rootNode == null)
            {
                Console.WriteLine("This is not a valid peg_desc file: {0}", descFilePath);
                Console.WriteLine("Unable to find PegDescription node.", document.ChildNodes[1].Name);
                return(null);
            }
            foreach (XmlNode node in rootNode.ChildNodes)
            {
                switch (node.Name)
                {
                case "BigEndian":
                    bool.TryParse(node.InnerText, out pegFile.BigEndian);
                    break;

                case "Magic":
                    if (node.InnerText != "GEKV")
                    {
                        Console.WriteLine("This is not a valid peg_desc file: {0}", descFilePath);
                        Console.WriteLine("Bad magic value. Got: {0}, expected: GEKV", node.InnerText);
                        return(null);
                    }
                    break;

                case "Version":
                    int version = 0;
                    int.TryParse(node.InnerText, out version);
                    if (version != 10)
                    {
                        Console.WriteLine("This is not a valid peg_desc file: {0}", descFilePath);
                        Console.WriteLine("Bad version value. Got: {0}, expected: 10", node.InnerText);
                        return(null);
                    }
                    break;

                case "Unknown06":
                    ushort.TryParse(node.InnerText, out pegFile.Unknown06);
                    break;

                case "Unknown12":
                    ushort.TryParse(node.InnerText, out pegFile.Unknown12);
                    break;

                case "Unknown16":
                    ushort.TryParse(node.InnerText, out pegFile.Unknown16);
                    break;

                case "Entries":
                    ParseEntries(node, pegFile);
                    break;
                    //default:
                    //throw new Exception(String.Format("Encountered unknown XML element: {0}", node.Name));
                }
            }

            return(pegFile);
        }
示例#9
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.");
        }
示例#10
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.");
                }
            }
        }
示例#11
0
        public static void WritePegDescription(PegFile pegFile, string pegDescFilePath)
        {
            XmlTextWriter writer = new XmlTextWriter(pegDescFilePath, Encoding.UTF8);

            writer.Formatting  = Formatting.Indented;
            writer.IndentChar  = '\t';
            writer.Indentation = 1;

            writer.WriteStartDocument();
            writer.WriteStartElement("PegDescription");

            // Header data
            writer.WriteElementString("BigEndian", pegFile.BigEndian.ToString());
            writer.WriteElementString("Magic", "GEKV");
            writer.WriteElementString("Version", "10");
            writer.WriteElementString("Unknown06", pegFile.Unknown06.ToString());
            writer.WriteElementString("FileSize", pegFile.FileSize.ToString());
            writer.WriteElementString("DataFileSize", pegFile.DataFileSize.ToString());
            writer.WriteElementString("EntryCount", pegFile.Entries.Count.ToString());
            writer.WriteElementString("Unknown12", pegFile.Unknown12.ToString());
            int frameCount = 0;

            foreach (PegEntry entry in pegFile.Entries)
            {
                frameCount += entry.Frames.Count;
            }
            writer.WriteElementString("FrameCount", frameCount.ToString());
            writer.WriteElementString("Unknown16", pegFile.Unknown16.ToString());

            writer.WriteStartElement("Entries");

            foreach (PegEntry entry in pegFile.Entries)
            {
                writer.WriteStartElement("Entry");
                writer.WriteElementString("Name", entry.Name);
                writer.WriteStartElement("Frames");
                foreach (PegFrame frame in entry.Frames)
                {
                    writer.WriteStartElement("Frame");
                    writer.WriteElementString("Offset", frame.Offset.ToString());
                    writer.WriteElementString("Width", frame.Width.ToString());
                    writer.WriteElementString("Height", frame.Height.ToString());
                    PegFormat frameFormat = (PegFormat)frame.Format;
                    writer.WriteElementString("Format", frameFormat.ToString());
                    writer.WriteElementString("Unknown0A", frame.Unknown0A.ToString());
                    writer.WriteElementString("Unknown0C", frame.Unknown0C.ToString());
                    writer.WriteElementString("Frames", frame.Frames.ToString());
                    writer.WriteElementString("Unknown12", frame.Unknown12.ToString());
                    writer.WriteElementString("Unknown16", frame.Unknown16.ToString());
                    writer.WriteElementString("UnknownFlags1A", frame.UnknownFlags1A.ToString("X4"));
                    writer.WriteElementString("Size", frame.Size.ToString());
                    writer.WriteElementString("Unknown20", frame.Unknown20.ToString());
                    writer.WriteElementString("Unknown24", frame.Unknown24.ToString());
                    writer.WriteElementString("Unknown28", frame.Unknown28.ToString());
                    writer.WriteElementString("Unknown2C", frame.Unknown2C.ToString());
                    writer.WriteEndElement();
                }
                writer.WriteEndElement();
                writer.WriteEndElement();
            }

            writer.WriteEndElement();
            writer.WriteEndElement();
            writer.WriteEndDocument();
            writer.Close();
        }
示例#12
0
        static void Main(string[] args)
        {
            Options options = null;

            try
            {
                options = CommandLine.Parse <Options>();
            }
            catch (CommandLineException exception)
            {
                Console.WriteLine(exception.ArgumentHelp.Message);
                Console.WriteLine();
                Console.WriteLine(exception.ArgumentHelp.GetHelpText(Console.BufferWidth));

#if DEBUG
                Console.ReadLine();
#endif
                return;
            }

            if (options.Output == null)
            {
                options.Output = "output";
            }

            if (!Directory.Exists(options.Output))
            {
                Directory.CreateDirectory(options.Output);
            }

            FontFile font = null;

            using (Stream s = File.OpenRead(options.Source))
            {
                font = new FontFile(s);
            }

            Dictionary <char, char> charMap = new Dictionary <char, char>();
            using (Stream s = File.OpenRead(options.Charmap))
            {
                charMap = LanguageUtility.GetDecodeCharMapFromStream(s);
            }

            string indicatedPegPath = Path.Combine(Path.GetDirectoryName(options.Source), font.Header.BitmapName);

            string[] pegExtensions = new string[]
            {
                ".cpeg_pc",
                ".cvbm_pc"
            };

            string[] gpegExtensions = new string[]
            {
                ".gpeg_pc",
                ".gvbm_pc"
            };

            bool   foundPeg = false;
            string pegPath  = null;
            string gpegPath = null;
            for (int i = 0; i < pegExtensions.Length; i++)
            {
                string pegExtension  = pegExtensions[i];
                string gpegExtension = gpegExtensions[i];
                string candidatePath = Path.ChangeExtension(indicatedPegPath, pegExtension);

                if (File.Exists(candidatePath))
                {
                    foundPeg = true;
                    pegPath  = candidatePath;
                    gpegPath = Path.ChangeExtension(pegPath, gpegExtension);
                    break;
                }
            }

            if (!foundPeg)
            {
                Console.WriteLine("Couldn't find {0}! Extension may be \".cpeg_pc\" or \".cvbm_pc\".", indicatedPegPath);
                return;
            }


            Bitmap fontBitmap = null;


            using (Stream pegStream = File.OpenRead(pegPath))
            {
                PegFile peg = new PegFile(pegStream);

                PegEntry entry = null;

                foreach (PegEntry e in peg.Entries)
                {
                    if (e.Filename == font.Header.BitmapName)
                    {
                        entry = e;
                        break;
                    }
                }

                if (entry == null)
                {
                    Console.WriteLine("Couldn't find bitmap {0} in font peg!", font.Header.BitmapName);
                    return;
                }

                byte[] bitmapData = null;

                using (Stream gpegStream = File.OpenRead(gpegPath))
                {
                    bitmapData = entry.GetData(gpegStream);
                }

                byte[] uncompressed = null;

                switch (entry.Data.BitmapFormat)
                {
                case PegBitmapFormat.D3DFMT_DXT3:
                    uncompressed = ManagedSquish.Squish.DecompressImage(bitmapData, entry.Data.Width, entry.Data.Height, ManagedSquish.SquishFlags.Dxt3);
                    break;

                case PegBitmapFormat.D3DFMT_DXT5:
                    uncompressed = ManagedSquish.Squish.DecompressImage(bitmapData, entry.Data.Width, entry.Data.Height, ManagedSquish.SquishFlags.Dxt5);
                    break;

                default: throw new Exception();
                }

                fontBitmap = new Bitmap(entry.Data.Width, entry.Data.Height, PixelFormat.Format32bppArgb);
                BitmapData data = fontBitmap.LockBits(new Rectangle(0, 0, fontBitmap.Width, fontBitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
                Marshal.Copy(uncompressed, 0, data.Scan0, uncompressed.Length);
                fontBitmap.UnlockBits(data);
            }

            using (StreamWriter sw = new StreamWriter(Path.Combine(options.Output, "out.txt")))
            {
                for (int i = 0; i < font.Characters.Count; i++)
                {
                    FontCharacter c         = font.Characters[i];
                    int           u         = font.U[i];
                    int           v         = font.V[i];
                    int           charValue = font.Header.FirstAscii + i;

                    if (c.ByteWidth == 0)
                    {
                        continue;
                    }

                    char actualChar = '\0';
                    char rawChar    = (char)charValue;
                    if (charMap.ContainsKey(rawChar))
                    {
                        actualChar = charMap[rawChar];
                        sw.WriteLine("{0} \"{1}\"", charValue, actualChar);
                    }
                    else
                    {
                        sw.WriteLine("{0} \"\"", charValue);
                    }



                    using (Bitmap bm = new Bitmap(c.ByteWidth, font.Header.RenderHeight))
                    {
                        using (Graphics g = Graphics.FromImage(bm))
                        {
                            g.Clear(Color.Black);
                            g.DrawImage(fontBitmap, 0, 0, new Rectangle(u, v, c.ByteWidth, font.Header.RenderHeight), GraphicsUnit.Pixel);
                            g.Flush();
                        }
                        string bmName = String.Format("{0}.png", charValue);
                        string bmPath = Path.Combine(options.Output, bmName);
                        bm.Save(bmPath, ImageFormat.Png);
                    }
                }
            }
        }