Beispiel #1
0
        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();
            List <TextureInfo> newtextures;

            if (PvmxArchive.Is(pvmdata))
            {
                format      = TextureFormat.PVMX;
                newtextures = new List <TextureInfo>(PvmxArchive.GetTextures(pvmdata).Cast <TextureInfo>());
            }
            else if (PAKFile.Is(filename))
            {
                format = TextureFormat.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;
                newtextures = new List <TextureInfo>(inf.Length / 0x3C);
                for (int i = 0; i < inf.Length; i += 0x3C)
                {
                    StringBuilder sb = new 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))
                        using (Texture tex = TextureLoader.FromStream(d3ddevice, str))
                            using (Stream bmp = TextureLoader.SaveToStream(ImageFileFormat.Png, tex))
                                newtextures.Add(new PakTextureInfo(sb.ToString(), BitConverter.ToUInt32(inf, i + 0x1C), new Bitmap(bmp)));
                }
            }
            else
            {
                if (pvmfile.Is(pvmdata, filename))
                {
                    format = TextureFormat.PVM;
                }
                else
                {
                    pvmfile = new GvmArchive();
                    if (!pvmfile.Is(pvmdata, filename))
                    {
                        MessageBox.Show(this, "Could not open file \"" + filename + "\".", Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        return(false);
                    }
                    format = TextureFormat.GVM;
                }
                ArchiveEntryCollection pvmentries = pvmfile.Open(pvmdata).Entries;
                newtextures = new List <TextureInfo>(pvmentries.Count);
                switch (format)
                {
                case TextureFormat.PVM:
                    PvpPalette pvp = null;
                    foreach (ArchiveEntry file in pvmentries)
                    {
                        PvrTexture vrfile = new PvrTexture(file.Open());
                        if (vrfile.NeedsExternalPalette)
                        {
                            if (pvp == null)
                            {
                                using (OpenFileDialog a = new 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 PvrTextureInfo(Path.GetFileNameWithoutExtension(file.Name), vrfile));
                    }
                    break;

                case TextureFormat.GVM:
                    GvpPalette gvp = null;
                    foreach (ArchiveEntry file in pvmentries)
                    {
                        GvrTexture vrfile = new GvrTexture(file.Open());
                        if (vrfile.NeedsExternalPalette)
                        {
                            if (gvp == null)
                            {
                                using (OpenFileDialog a = new OpenFileDialog
                                {
                                    DefaultExt = "gvp",
                                    Filter = "GVP Files|*.gvp",
                                    InitialDirectory = Path.GetDirectoryName(filename),
                                    Title = "External palette file"
                                })
                                    if (a.ShowDialog(this) == DialogResult.OK)
                                    {
                                        gvp = new GvpPalette(a.FileName);
                                    }
                                    else
                                    {
                                        MessageBox.Show(this, "Could not open file \"" + Program.Arguments[0] + "\".", Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                                        return(false);
                                    }
                            }
                            vrfile.SetPalette(gvp);
                        }
                        newtextures.Add(new GvrTextureInfo(Path.GetFileNameWithoutExtension(file.Name), vrfile));
                    }
                    break;
                }
            }
            textures.Clear();
            textures.AddRange(newtextures);
            listBox1.Items.Clear();
            listBox1.Items.AddRange(textures.Select((item) => item.Name).ToArray());
            UpdateTextureCount();
            SetFilename(Path.GetFullPath(filename));
            return(true);
        }
Beispiel #2
0
        private void SaveTextures()
        {
            byte[] data;
            using (MemoryStream str = new MemoryStream())
            {
                ArchiveWriter writer = null;
                switch (format)
                {
                case TextureFormat.PVM:
                    writer = new PvmArchiveWriter(str);
                    foreach (PvrTextureInfo tex in textures)
                    {
                        if (tex.DataFormat != PvrDataFormat.Index4 && tex.DataFormat != PvrDataFormat.Index8)
                        {
                            System.Drawing.Imaging.BitmapData bmpd = tex.Image.LockBits(new Rectangle(Point.Empty, tex.Image.Size), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                            int    stride = bmpd.Stride;
                            byte[] bits   = new byte[Math.Abs(stride) * bmpd.Height];
                            System.Runtime.InteropServices.Marshal.Copy(bmpd.Scan0, bits, 0, bits.Length);
                            tex.Image.UnlockBits(bmpd);
                            int tlevels = 0;
                            for (int y = 0; y < tex.Image.Height; y++)
                            {
                                int srcaddr = y * Math.Abs(stride);
                                for (int x = 0; x < tex.Image.Width; x++)
                                {
                                    Color c = Color.FromArgb(BitConverter.ToInt32(bits, srcaddr + (x * 4)));
                                    if (c.A == 0)
                                    {
                                        tlevels = 1;
                                    }
                                    else if (c.A < 255)
                                    {
                                        tlevels = 2;
                                        break;
                                    }
                                }
                                if (tlevels == 2)
                                {
                                    break;
                                }
                            }
                            if (tlevels == 0)
                            {
                                tex.PixelFormat = PvrPixelFormat.Rgb565;
                            }
                            else if (tlevels == 1)
                            {
                                tex.PixelFormat = PvrPixelFormat.Argb1555;
                            }
                            else if (tlevels == 2)
                            {
                                tex.PixelFormat = PvrPixelFormat.Argb4444;
                            }
                            if (tex.Image.Width == tex.Image.Height)
                            {
                                if (tex.Mipmap)
                                {
                                    tex.DataFormat = PvrDataFormat.SquareTwiddledMipmaps;
                                }
                                else
                                {
                                    tex.DataFormat = PvrDataFormat.SquareTwiddled;
                                }
                            }
                            else
                            {
                                tex.DataFormat = PvrDataFormat.Rectangle;
                            }
                        }
                        PvrTextureEncoder encoder = new PvrTextureEncoder(tex.Image, tex.PixelFormat, tex.DataFormat);
                        encoder.GlobalIndex = tex.GlobalIndex;
                        MemoryStream pvr = new MemoryStream();
                        encoder.Save(pvr);
                        pvr.Seek(0, SeekOrigin.Begin);
                        writer.CreateEntry(pvr, tex.Name);
                    }
                    break;

                case TextureFormat.GVM:
                    writer = new GvmArchiveWriter(str);
                    foreach (GvrTextureInfo tex in textures)
                    {
                        if (tex.DataFormat != GvrDataFormat.Index4 && tex.DataFormat != GvrDataFormat.Index8)
                        {
                            System.Drawing.Imaging.BitmapData bmpd = tex.Image.LockBits(new Rectangle(Point.Empty, tex.Image.Size), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                            int    stride = bmpd.Stride;
                            byte[] bits   = new byte[Math.Abs(stride) * bmpd.Height];
                            System.Runtime.InteropServices.Marshal.Copy(bmpd.Scan0, bits, 0, bits.Length);
                            tex.Image.UnlockBits(bmpd);
                            int tlevels = 0;
                            for (int y = 0; y < tex.Image.Height; y++)
                            {
                                int srcaddr = y * Math.Abs(stride);
                                for (int x = 0; x < tex.Image.Width; x++)
                                {
                                    Color c = Color.FromArgb(BitConverter.ToInt32(bits, srcaddr + (x * 4)));
                                    if (c.A == 0)
                                    {
                                        tlevels = 1;
                                    }
                                    else if (c.A < 255)
                                    {
                                        tlevels = 2;
                                        break;
                                    }
                                }
                                if (tlevels == 2)
                                {
                                    break;
                                }
                            }
                            if (!tex.Mipmap)
                            {
                                tex.DataFormat = GvrDataFormat.Argb8888;
                            }
                            else if (tlevels == 0)
                            {
                                tex.DataFormat = GvrDataFormat.Rgb565;
                            }
                            else
                            {
                                tex.DataFormat = GvrDataFormat.Rgb5a3;
                            }
                        }
                        GvrTextureEncoder encoder = new GvrTextureEncoder(tex.Image, tex.PixelFormat, tex.DataFormat);
                        encoder.GlobalIndex = tex.GlobalIndex;
                        MemoryStream gvr = new MemoryStream();
                        encoder.Save(gvr);
                        gvr.Seek(0, SeekOrigin.Begin);
                        writer.CreateEntry(gvr, tex.Name);
                    }
                    break;

                case TextureFormat.PVMX:
                    PvmxArchive.Save(str, textures.Cast <PvmxTextureInfo>());
                    break;

                case TextureFormat.PAK:
                    PAKFile     pak       = new PAKFile();
                    string      filenoext = Path.GetFileNameWithoutExtension(filename).ToLowerInvariant();
                    string      longdir   = "..\\..\\..\\sonic2\\resource\\gd_pc\\prs\\" + filenoext;
                    List <byte> inf       = new List <byte>(textures.Count * 0x3C);
                    foreach (TextureInfo item in textures)
                    {
                        Stream tex = TextureLoader.SaveToStream(ImageFileFormat.Dds, Texture.FromBitmap(d3ddevice, item.Image, Usage.SoftwareProcessing, Pool.Managed));
                        byte[] tb  = new byte[tex.Length];
                        tex.Read(tb, 0, tb.Length);
                        string name = item.Name.ToLowerInvariant();
                        if (name.Length > 0x1C)
                        {
                            name = name.Substring(0, 0x1C);
                        }
                        pak.Files.Add(new PAKFile.File(filenoext + '\\' + name + ".dds", longdir + '\\' + name + ".dds", tb));
                        inf.AddRange(Encoding.ASCII.GetBytes(name));
                        if (name.Length != 0x1C)
                        {
                            inf.AddRange(new byte[0x1C - name.Length]);
                        }
                        inf.AddRange(BitConverter.GetBytes(item.GlobalIndex));
                        inf.AddRange(new byte[0xC]);
                        inf.AddRange(BitConverter.GetBytes(item.Image.Width));
                        inf.AddRange(BitConverter.GetBytes(item.Image.Height));
                        inf.AddRange(new byte[4]);
                        inf.AddRange(BitConverter.GetBytes(0x80000000));
                    }
                    pak.Files.Insert(0, new PAKFile.File(filenoext + '\\' + filenoext + ".inf", longdir + '\\' + filenoext + ".inf", inf.ToArray()));
                    pak.Save(filename);

                    return;
                }
                writer?.Flush();
                data = str.ToArray();
                str.Close();
            }
            if (Path.GetExtension(filename).Equals(".prs", StringComparison.OrdinalIgnoreCase))
            {
                FraGag.Compression.Prs.Compress(data, filename);
            }
            else
            {
                File.WriteAllBytes(filename, data);
            }
        }