예제 #1
0
        public PAKResourcePool(Stream stream)
        {
            this.stream      = stream;
            using var reader = new BinaryReader(stream, BinaryIOExtension.Encoding, true);
            if (reader.ReadUInt32() != 0)
            {
                throw new InvalidDataException("Invalid PAKArchive magic");
            }

            var root = new PAKDirectory(this, null, new FilePath(""));

            Root = root;
            uint fileCount   = reader.ReadUInt32();
            var  directories = new Dictionary <FilePath, PAKDirectory>();

            directories.Add(root.Path, root);

            for (uint i = 0; i < fileCount; i++)
            {
                var entry = PAKArchiveEntry.ReadNew(reader);
                var dir   = GetOrCreateDirectoryFor(entry.path.Parent);
                var file  = new PAKFile(this, dir, entry);
                dir.FileList.Add(file);
            }

            PAKDirectory GetOrCreateDirectoryFor(FilePath?path)
            {
                if (path == null || !path.StaysInbound || path == "")
                {
                    return(root !);
                }
                else if (directories !.TryGetValue(path, out var prevDir))
                {
                    return(prevDir);
                }

                var dirsToCreate = new Stack <string>();

                dirsToCreate.Push(path.Parts.Last());
                var          curParentPath = path.Parent;
                PAKDirectory?curParent     = null;

                while (curParentPath != null && curParentPath.StaysInbound)
                {
                    if (directories.TryGetValue(curParentPath, out curParent))
                    {
                        break;
                    }
                    dirsToCreate.Push(curParentPath.Parts.Last());
                    curParentPath = curParentPath.Parent;
                }
                if (curParent == null)
                {
                    curParent = root !;
                }

                while (dirsToCreate.Any())
                {
                    var newPath    = curParent.Path.Combine(dirsToCreate.Pop());
                    var prevParent = curParent;
                    curParent = new PAKDirectory(this, prevParent, newPath);
                    prevParent.DirectoryList.Add(curParent);
                    directories.Add(newPath, curParent);
                }
                return(curParent);
            }

            baseOffset = stream.Position;
        }
예제 #2
0
        static void Main(string[] args)
        {
            Environment.CurrentDirectory = @"C:\SONICADVENTUREDX\Projects\ECPort";

            List <BMPInfo> textures  = new List <BMPInfo>(TextureArchive.GetTextures(@"C:\SONICADVENTUREDX\system\BEACH01.PVM"));
            LandTable      landTable = LandTable.LoadFromFile(@"Levels\Emerald Coast\Act 1\LandTable.sa1lvl");

            texmap = new Dictionary <int, int>();
            BMPInfo[] newtexs = TextureArchive.GetTextures(@"C:\SONICADVENTUREDX\system\BEACH03.PVM");
            for (int i = 0; i < newtexs.Length; i++)
            {
                BMPInfo found = textures.FirstOrDefault(a => a.Name.Equals(newtexs[i].Name));
                if (found == null)
                {
                    texmap[i] = textures.Count;
                    textures.Add(newtexs[i]);
                }
                else
                {
                    texmap[i] = textures.IndexOf(found);
                }
            }
            foreach (COL col in LandTable.LoadFromFile(@"Levels\Emerald Coast\Act 3\LandTable.sa1lvl").COL)
            {
                foreach (NJS_MATERIAL mat in ((BasicAttach)col.Model.Attach).Material)
                {
                    mat.TextureID = texmap[mat.TextureID];
                }
                landTable.COL.Add(col);
            }
            texmap  = new Dictionary <int, int>();
            newtexs = TextureArchive.GetTextures(@"C:\SONICADVENTUREDX\system\BEACH02.PVM");
            for (int i = 0; i < newtexs.Length; i++)
            {
                BMPInfo found = textures.FirstOrDefault(a => a.Name.Equals(newtexs[i].Name));
                if (found == null)
                {
                    texmap[i] = textures.Count;
                    textures.Add(newtexs[i]);
                }
                else
                {
                    texmap[i] = textures.IndexOf(found);
                }
            }
            foreach (COL col in LandTable.LoadFromFile(@"Levels\Emerald Coast\Act 2\LandTable.sa1lvl").COL)
            {
                col.Bounds.Center.Z  -= 2000;
                col.Model.Position.Z -= 2000;
                foreach (NJS_MATERIAL mat in ((BasicAttach)col.Model.Attach).Material)
                {
                    mat.TextureID = texmap[mat.TextureID];
                }
                landTable.COL.Add(col);
            }

            texmap  = new Dictionary <int, int>();
            newtexs = TextureArchive.GetTextures(@"C:\SONICADVENTUREDX\system\OBJ_BEACH.PVM");
            for (int i = 0; i < newtexs.Length; i++)
            {
                BMPInfo found = textures.FirstOrDefault(a => a.Name.Equals(newtexs[i].Name));
                if (found == null)
                {
                    texmap[i] = textures.Count;
                    textures.Add(newtexs[i]);
                }
                else
                {
                    texmap[i] = textures.IndexOf(found);
                }
            }

            PAKFile     pak       = new PAKFile();
            List <byte> inf       = new List <byte>();
            string      filenoext = "beach01";
            string      longdir   = "..\\..\\..\\sonic2\\resource\\gd_pc\\prs\\" + filenoext;

            using (System.Windows.Forms.Panel panel = new System.Windows.Forms.Panel())
                using (Direct3D d3d = new Direct3D())
                    using (Device dev = new Device(d3d, 0, DeviceType.Hardware, panel.Handle, CreateFlags.HardwareVertexProcessing, new PresentParameters(640, 480)))
                    {
                        for (int i = 0; i < textures.Count; i++)
                        {
                            using (Texture tex = textures[i].Image.ToTexture(dev))
                                using (DataStream str = Surface.ToStream(tex.GetSurfaceLevel(0), ImageFileFormat.Dds))
                                    using (MemoryStream ms = new MemoryStream())
                                    {
                                        str.CopyTo(ms);
                                        pak.Files.Add(new PAKFile.File(filenoext + '\\' + Path.ChangeExtension(textures[i].Name, ".dds"), longdir + '\\' + Path.ChangeExtension(textures[i].Name, ".dds"), ms.ToArray()));
                                    }
                            int infsz = inf.Count;
                            inf.AddRange(Encoding.ASCII.GetBytes(Path.ChangeExtension(textures[i].Name, null)));
                            inf.AddRange(new byte[0x1C - (inf.Count - infsz)]);
                            inf.AddRange(BitConverter.GetBytes(i + 200));
                            inf.AddRange(BitConverter.GetBytes(0));
                            inf.AddRange(BitConverter.GetBytes(0));
                            inf.AddRange(BitConverter.GetBytes(0));
                            inf.AddRange(BitConverter.GetBytes(textures[i].Image.Width));
                            inf.AddRange(BitConverter.GetBytes(textures[i].Image.Height));
                            inf.AddRange(BitConverter.GetBytes(0));
                            inf.AddRange(BitConverter.GetBytes(0x80000000));
                        }
                    }
            pak.Files.Insert(0, new PAKFile.File(filenoext + '\\' + filenoext + ".inf", longdir + '\\' + filenoext + ".inf", inf.ToArray()));
            pak.Save(@"C:\Program Files (x86)\Steam\steamapps\common\Sonic Adventure 2\mods\Emerald Coast\gd_PC\PRS\beach01.pak");

            List <COL> newcollist = new List <COL>();
            Dictionary <string, Attach> visitedAttaches = new Dictionary <string, Attach>();

            foreach (COL col in landTable.COL.Where((col) => col.Model != null && col.Model.Attach != null))
            {
                ConvertCOL(newcollist, visitedAttaches, col);
            }
            landTable.COL = newcollist;

            Console.WriteLine("Loading Object Definitions:");
            Console.WriteLine("Parsing...");

            LevelData.ObjDefs = new List <ObjectDefinition>();
            Dictionary <string, ObjectData> objdefini =
                IniSerializer.Deserialize <Dictionary <string, ObjectData> >("objdefs.ini");

            List <ObjectData> objectErrors = new List <ObjectData>();

            ObjectListEntry[] objlstini = ObjectList.Load(@"Levels\Emerald Coast\Object List.ini", false);
            Directory.CreateDirectory("dllcache").Attributes |= FileAttributes.Hidden;

            List <KeyValuePair <string, string> > compileErrors = new List <KeyValuePair <string, string> >();

            for (int ID = 0; ID < objlstini.Length; ID++)
            {
                string codeaddr = objlstini[ID].CodeString;

                if (!objdefini.ContainsKey(codeaddr))
                {
                    codeaddr = "0";
                }

                ObjectData       defgroup = objdefini[codeaddr];
                ObjectDefinition def;

                if (!string.IsNullOrEmpty(defgroup.CodeFile))
                {
                    Console.WriteLine("Compiling: " + defgroup.CodeFile);


                    def = CompileObjectDefinition(defgroup, out bool errorOccured, out string errorText);

                    if (errorOccured)
                    {
                        KeyValuePair <string, string> errorValue = new KeyValuePair <string, string>(
                            defgroup.CodeFile, errorText);

                        compileErrors.Add(errorValue);
                    }
                }
                else
                {
                    def = new DefaultObjectDefinition();
                }

                LevelData.ObjDefs.Add(def);

                // The only reason .Model is checked for null is for objects that don't yet have any
                // models defined for them. It would be annoying seeing that error all the time!
                if (string.IsNullOrEmpty(defgroup.CodeFile) && !string.IsNullOrEmpty(defgroup.Model))
                {
                    Console.WriteLine("Loading: " + defgroup.Model);
                    // Otherwise, if the model file doesn't exist and/or no texture file is defined,
                    // load the "default object" instead ("?").
                    if (!File.Exists(defgroup.Model))
                    {
                        ObjectData error = new ObjectData {
                            Name = defgroup.Name, Model = defgroup.Model, Texture = defgroup.Texture
                        };
                        objectErrors.Add(error);
                        defgroup.Model = null;
                    }
                }

                def.Init(defgroup, objlstini[ID].Name);
                def.SetInternalName(objlstini[ID].Name);
            }

            // Checks if there have been any errors added to the error list and does its thing
            // This thing is a mess. If anyone can think of a cleaner way to do this, be my guest.
            if (objectErrors.Count > 0)
            {
                int           count        = objectErrors.Count;
                List <string> errorStrings = new List <string> {
                    "The following objects failed to load:"
                };

                foreach (ObjectData o in objectErrors)
                {
                    bool texEmpty  = string.IsNullOrEmpty(o.Texture);
                    bool texExists = (!string.IsNullOrEmpty(o.Texture) && LevelData.Textures.ContainsKey(o.Texture));
                    errorStrings.Add("");
                    errorStrings.Add("Object:\t\t" + o.Name);
                    errorStrings.Add("\tModel:");
                    errorStrings.Add("\t\tName:\t" + o.Model);
                    errorStrings.Add("\t\tExists:\t" + File.Exists(o.Model));
                    errorStrings.Add("\tTexture:");
                    errorStrings.Add("\t\tName:\t" + ((texEmpty) ? "(N/A)" : o.Texture));
                    errorStrings.Add("\t\tExists:\t" + texExists);
                }

                // TODO: Proper logging. Who knows where this file may end up
                File.WriteAllLines("SADXLVL2.log", errorStrings.ToArray());
            }

            // Loading SET Layout
            Console.WriteLine("Loading SET items", "Initializing...");

            List <SETItem> setlist = new List <SETItem>();

            SonicRetro.SAModel.SAEditorCommon.UI.EditorItemSelection selection = new SonicRetro.SAModel.SAEditorCommon.UI.EditorItemSelection();
            if (LevelData.ObjDefs.Count > 0)
            {
                string setstr = @"C:\SONICADVENTUREDX\Projects\ECPort\system\SET0100S.BIN";
                if (File.Exists(setstr))
                {
                    Console.WriteLine("SET: " + setstr.Replace(Environment.CurrentDirectory, ""));

                    setlist = SETItem.Load(setstr, selection);
                }
                setstr = @"C:\SONICADVENTUREDX\Projects\ECPort\system\SET0102B.BIN";
                if (File.Exists(setstr))
                {
                    Console.WriteLine("SET: " + setstr.Replace(Environment.CurrentDirectory, ""));

                    setlist.AddRange(SETItem.Load(setstr, selection));
                }
                setstr = @"C:\SONICADVENTUREDX\Projects\ECPort\system\SET0101S.BIN";
                if (File.Exists(setstr))
                {
                    Console.WriteLine("SET: " + setstr.Replace(Environment.CurrentDirectory, ""));

                    List <SETItem> newlist = SETItem.Load(setstr, selection);
                    foreach (SETItem item in newlist)
                    {
                        item.Position.Z -= 2000;
                    }
                    setlist.AddRange(newlist);
                }
            }

            MatrixStack         transform = new MatrixStack();
            List <SETItem>      add       = new List <SETItem>();
            List <SETItem>      del       = new List <SETItem>();
            List <PalmtreeData> trees     = new List <PalmtreeData>();

            foreach (SETItem item in setlist)
            {
                switch (item.ID)
                {
                case 0xD:                         // item box
                    item.ID      = 0xA;
                    item.Scale.X = itemboxmap[(int)item.Scale.X];
                    break;

                case 0x15:                         // ring group to rings
                    for (int i = 0; i < Math.Min(item.Scale.X + 1, 8); i++)
                    {
                        if (item.Scale.Z == 1)                                 // circle
                        {
                            double  v4 = i * 360.0;
                            Vector3 v7 = new Vector3(
                                ObjectHelper.NJSin((int)(v4 / item.Scale.X * 65536.0 * 0.002777777777777778)) * item.Scale.Y,
                                0,
                                ObjectHelper.NJCos((int)(v4 / item.Scale.X * 65536.0 * 0.002777777777777778)) * item.Scale.Y);
                            transform.Push();
                            transform.NJTranslate(item.Position);
                            transform.NJRotateObject(item.Rotation);
                            Vector3 pos = Vector3.TransformCoordinate(v7, transform.Top);
                            transform.Pop();
                            add.Add(new SETItem(0, selection)
                            {
                                Position = pos.ToVertex()
                            });
                        }
                        else                                 // line
                        {
                            transform.Push();
                            transform.NJTranslate(item.Position);
                            transform.NJRotateObject(item.Rotation);
                            double v5;
                            if (i % 2 == 1)
                            {
                                v5 = i * item.Scale.Y * -0.5;
                            }
                            else
                            {
                                v5 = Math.Ceiling(i * 0.5) * item.Scale.Y;
                            }
                            Vector3 pos = Vector3.TransformCoordinate(new Vector3(0, 0, (float)v5), transform.Top);
                            transform.Pop();
                            add.Add(new SETItem(0, selection)
                            {
                                Position = pos.ToVertex()
                            });
                        }
                    }
                    del.Add(item);
                    break;

                case 0x1A:                         // tikal -> omochao
                    item.ID          = 0x19;
                    item.Position.Y += 3;
                    break;

                case 0x1D:                         // kiki
                    item.ID       = 0x5B;
                    item.Rotation = new Rotation();
                    item.Scale    = new Vertex();
                    break;

                case 0x1F:                         // sweep ->beetle
                    item.ID       = 0x38;
                    item.Rotation = new Rotation();
                    item.Scale    = new Vertex(1, 0, 0);
                    break;

                case 0x28:                         // launch ramp
                    item.ID       = 6;
                    item.Scale.X /= 2.75f;
                    item.Scale.Z  = 0.799999952316284f;
                    break;

                case 0x4F:                         // updraft
                    item.ID      = 0x35;
                    item.Scale.X = Math.Max(Math.Min(item.Scale.X, 200), 10) / 2;
                    item.Scale.Y = Math.Max(Math.Min(item.Scale.Y, 200), 10) / 2;
                    item.Scale.Z = Math.Max(Math.Min(item.Scale.Z, 200), 10) / 2;
                    break;

                case 0x52:                         // item box air
                    item.ID      = 0xB;
                    item.Scale.X = itemboxmap[(int)item.Scale.X];
                    break;

                // palm trees
                case 32:
                case 33:
                case 34:
                case 35:
                    trees.Add(new PalmtreeData((byte)(item.ID - 32), item.Position, item.Rotation));
                    del.Add(item);
                    break;

                // nonsolid objects
                case 47:
                case 48:
                case 49:
                case 50:
                case 51:
                case 52:
                case 59:
                case 62:
                case 63:
                case 64:
                case 70:
                    ConvertSETItem(newcollist, item, false, setlist.IndexOf(item));
                    del.Add(item);
                    break;

                // solid objects
                case 36:
                case 37:
                case 39:
                case 41:
                case 42:
                case 43:
                case 44:
                case 45:
                case 46:
                case 54:
                case 58:
                case 66:
                case 71:
                case 72:
                case 73:
                case 74:
                    ConvertSETItem(newcollist, item, true, setlist.IndexOf(item));
                    del.Add(item);
                    break;

                case 81:                         // goal
                    item.ID          = 0xE;
                    item.Position.Y += 30;
                    break;

                default:
                    if (idmap.ContainsKey(item.ID))
                    {
                        item.ID = idmap[item.ID];
                    }
                    else
                    {
                        del.Add(item);
                    }
                    break;
                }
            }
            setlist.AddRange(add);
            foreach (SETItem item in del)
            {
                setlist.Remove(item);
            }
            setlist.Add(new SETItem(0x55, selection)
            {
                Position = new Vertex(6158.6f, -88f, 2384.97f), Scale = new Vertex(3, 0, 0)
            });
            {
                COL col = new COL()
                {
                    Model = new ModelFile(@"E:\Bridge Model.sa1mdl").Model, SurfaceFlags = SurfaceFlags.Visible
                };
                col.Model.Position = new Vertex(2803, -1, 365);
                foreach (NJS_MATERIAL mat in ((BasicAttach)col.Model.Attach).Material)
                {
                    mat.TextureID = texmap[mat.TextureID];
                }
                col.Model.ProcessVertexData();
                col.CalculateBounds();
                ConvertCOL(newcollist, new Dictionary <string, Attach>(), col);
                col = new COL()
                {
                    Model = new ModelFile(@"E:\Bridge Model COL.sa1mdl").Model, SurfaceFlags = SurfaceFlags.Solid
                };
                col.Model.Position = new Vertex(2803, -1, 365);
                col.Model.ProcessVertexData();
                col.CalculateBounds();
                newcollist.Add(col);
                col = new COL()
                {
                    Model = new ModelFile(@"E:\BridgeSegment0.sa1mdl").Model, SurfaceFlags = SurfaceFlags.Solid
                };
                col.Model.ProcessVertexData();
                col.CalculateBounds();
                newcollist.Add(col);
                col = new COL()
                {
                    Model = new ModelFile(@"E:\BridgeSegment1.sa1mdl").Model, SurfaceFlags = SurfaceFlags.Solid
                };
                col.Model.ProcessVertexData();
                col.CalculateBounds();
                newcollist.Add(col);
                col = new COL()
                {
                    Model = new ModelFile(@"E:\BridgeSegment2.sa1mdl").Model, SurfaceFlags = SurfaceFlags.Solid
                };
                col.Model.ProcessVertexData();
                col.CalculateBounds();
                newcollist.Add(col);
                col = new COL()
                {
                    Model = new ModelFile(@"E:\BridgeSegment3.sa1mdl").Model, SurfaceFlags = SurfaceFlags.Solid
                };
                col.Model.ProcessVertexData();
                col.CalculateBounds();
                newcollist.Add(col);
            }
            landTable.SaveToFile(@"C:\Program Files (x86)\Steam\steamapps\common\Sonic Adventure 2\mods\Emerald Coast\LandTable.sa2lvl", LandTableFormat.SA2);
            ByteConverter.BigEndian = true;
            SETItem.Save(setlist, @"C:\Program Files (x86)\Steam\steamapps\common\Sonic Adventure 2\mods\Emerald Coast\gd_PC\set0013_s.bin");
            for (int i = 0; i < 4; i++)
            {
                ModelFile modelFile = new ModelFile($@"C:\SONICADVENTUREDX\Projects\Test\Objects\Levels\Emerald Coast\YASI{i}.sa1mdl");
                foreach (BasicAttach attach in modelFile.Model.GetObjects().Where(a => a.Attach != null).Select(a => a.Attach))
                {
                    foreach (NJS_MATERIAL mat in attach.Material)
                    {
                        mat.TextureID = texmap[mat.TextureID];
                    }
                }
                modelFile.SaveToFile($@"C:\Program Files (x86)\Steam\steamapps\common\Sonic Adventure 2\mods\Emerald Coast\YASI{i}.sa1mdl");
            }
            using (StreamWriter sw = File.CreateText(@"E:\Documents\Visual Studio 2017\Projects\LevelTest\LevelTest\pt.c"))
                sw.WriteLine(string.Join(",\r\n", trees));
        }
예제 #3
0
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                args = new string[] { "/?" }
            }
            ;
            switch (args[0].ToLowerInvariant())
            {
            case "/t":
                Main(ParseCommandLine(File.ReadAllText(args[1])));
                break;

            case "/u":
                try
                {
                    string fn = Path.Combine(Environment.CurrentDirectory, args[1]);
                    Environment.CurrentDirectory = Path.GetDirectoryName(fn);
                    PAKFile pak = new PAKFile(fn);
                    Dictionary <string, PAKInfo> list = new Dictionary <string, PAKInfo>(pak.Files.Count);
                    foreach (PAKFile.File item in pak.Files)
                    {
                        Directory.CreateDirectory(Path.GetDirectoryName(Path.Combine(Environment.CurrentDirectory, item.Name)));
                        File.WriteAllBytes(item.Name, item.Data);
                        list.Add(item.Name, new PAKInfo(item.LongPath));
                    }
                    IniFile.Serialize(list, Path.ChangeExtension(fn, "ini"));
                }
                catch (Exception ex) { Console.WriteLine(ex.ToString()); }
                break;

            case "/p":
                try
                {
                    string fn = Path.Combine(Environment.CurrentDirectory, args[1]);
                    Environment.CurrentDirectory = Path.GetDirectoryName(fn);
                    Dictionary <string, PAKInfo> list = IniFile.Deserialize <Dictionary <string, PAKInfo> >(Path.ChangeExtension(fn, "ini"));
                    PAKFile pak = new PAKFile();
                    foreach (KeyValuePair <string, PAKInfo> item in list)
                    {
                        pak.Files.Add(new PAKFile.File(item.Key, item.Value.LongPath, File.ReadAllBytes(item.Key)));
                    }
                    pak.Save(Path.ChangeExtension(fn, "pak"));
                }
                catch (Exception ex) { Console.WriteLine(ex.ToString()); }
                break;

            case "/?":
                Console.WriteLine("Arguments:");
                Console.WriteLine();
                Console.WriteLine("/?\tShow this help.");
                Console.WriteLine();
                Console.WriteLine("/t filename\tReads text file filename as a commandline.");
                Console.WriteLine();
                Console.WriteLine("/u filename\tExtracts files from an archive.");
                Console.WriteLine();
                Console.WriteLine("/p filename\tPacks files into an archive.");
                Console.WriteLine();
                break;

            default:
                if (args.Length == 0)
                {
                    goto case "/?";
                }
                char arg = '\0';
                while (arg != 'u' & arg != 'p')
                {
                    Console.Write("Type u to unpack or p to pack: ");
                    arg = Console.ReadKey().KeyChar;
                    Console.WriteLine();
                }
                Main(new string[] { "/" + arg, args[0] });
                break;
            }
        }
예제 #4
0
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                args = new string[] { "/?" }
            }
            ;
            switch (args[0].ToLowerInvariant())
            {
            case "/t":
                Main(ParseCommandLine(File.ReadAllText(args[1])));
                break;

            case "/u":
                try
                {
                    string fn = args[1];
                    Console.WriteLine("Extracting PAK file: {0}", Path.GetFullPath(fn));
                    string outputPath = Path.Combine(Path.GetDirectoryName(fn), Path.GetFileNameWithoutExtension(fn));
                    Console.WriteLine("Output folder: {0}", Path.GetFullPath(outputPath));
                    PAKFile pak = new PAKFile(fn);
                    foreach (PAKFile.PAKEntry entry in pak.Entries)
                    {
                        Console.WriteLine("Extracting file: {0}", entry.Name);
                        File.WriteAllBytes(Path.Combine(outputPath, entry.Name), entry.Data);
                    }
                    pak.CreateIndexFile(outputPath);
                    Console.WriteLine("Archive extracted!");
                }
                catch (Exception ex) { Console.WriteLine(ex.ToString()); }
                break;

            case "/p":
                try
                {
                    Console.WriteLine("Building PAK from folder: {0}", Path.GetFullPath(args[1]));
                    string outputPath = Path.Combine(Environment.CurrentDirectory, args[1]);
                    Environment.CurrentDirectory = Path.GetDirectoryName(outputPath);
                    Dictionary <string, PAKFile.PAKIniItem> list = IniSerializer.Deserialize <Dictionary <string, PAKFile.PAKIniItem> >(Path.Combine(Path.GetFileNameWithoutExtension(outputPath), Path.GetFileNameWithoutExtension(outputPath) + ".ini"));
                    PAKFile pak = new PAKFile();
                    foreach (KeyValuePair <string, PAKFile.PAKIniItem> item in list)
                    {
                        Console.WriteLine("Adding file: {0}", item.Key);
                        pak.Entries.Add(new PAKFile.PAKEntry(item.Key, item.Value.LongPath, File.ReadAllBytes(item.Key)));
                    }
                    Console.WriteLine("Output file: {0}", Path.ChangeExtension(outputPath, "pak"));
                    pak.Save(Path.ChangeExtension(outputPath, "pak"));
                }
                catch (Exception ex) { Console.WriteLine(ex.ToString()); }
                break;

            case "/?":
                Console.WriteLine("Arguments:");
                Console.WriteLine();
                Console.WriteLine("/?\tShow this help.");
                Console.WriteLine();
                Console.WriteLine("/t filename\tReads text file filename as a commandline.");
                Console.WriteLine();
                Console.WriteLine("/u filename\tExtracts files from an archive.");
                Console.WriteLine();
                Console.WriteLine("/p filename\tPacks files into an archive.");
                Console.WriteLine();
                break;

            default:
                if (args.Length == 0)
                {
                    goto case "/?";
                }
                char arg = '\0';
                while (arg != 'u' & arg != 'p')
                {
                    Console.Write("Type u to unpack or p to pack: ");
                    arg = Console.ReadKey().KeyChar;
                    Console.WriteLine();
                }
                Main(new string[] { "/" + arg, args[0] });
                break;
            }
        }
예제 #5
0
        /// <summary>
        /// Main function for extracting archives.
        /// </summary>
        static void ExtractArchive(string[] args)
        {
            GenericArchive arc;
            string         arcname = extension.ToUpperInvariant();

            Console.WriteLine("Extracting {0} file: {1}", arcname.Substring(1, arcname.Length - 1), filePath);
            byte[] arcdata = File.ReadAllBytes(filePath);
            outputPath = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath));
            switch (extension.ToLowerInvariant())
            {
            case (".rel"):
                outputPath = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath) + "_dec.rel");
                Console.WriteLine("Output file: {0}", outputPath);
                byte[] inputData  = File.ReadAllBytes(args[0]);
                byte[] outputData = SplitTools.HelperFunctions.DecompressREL(inputData);
                File.WriteAllBytes(outputPath, outputData);
                Console.WriteLine("File extracted!");
                return;

            case (".pvmx"):
                arc = new PVMXFile(arcdata);
                break;

            case (".arcx"):
                arc = new ARCXFile(arcdata);
                break;

            case (".prs"):
                arcdata = FraGag.Compression.Prs.Decompress(arcdata);
                if (ARCXFile.Identify(arcdata))
                {
                    arc = new ARCXFile(arcdata);
                }
                else if (PuyoFile.Identify(arcdata) == PuyoArchiveType.Unknown)
                {
                    outputPath = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath) + ".bin");
                    Console.WriteLine("Output file: {0}", Path.GetFullPath(outputPath));
                    File.WriteAllBytes(outputPath, arcdata);
                    Console.WriteLine("Archive extracted!");
                    return;
                }
                else
                {
                    arc = new PuyoFile(arcdata);
                }
                break;

            case (".pvm"):
            case (".gvm"):
                arc = new PuyoFile(arcdata);
                break;

            case (".xvm"):
                arc = new XVM(arcdata);
                break;

            case (".pb"):
                arc = new PBFile(arcdata);
                break;

            case (".pak"):
                arc = new PAKFile(filePath);
                break;

            case (".dat"):
                arc = new DATFile(arcdata);
                break;

            case (".mdl"):
                arc = new MDLArchive(arcdata);
                break;

            case (".mdt"):
                arc = new MDTArchive(arcdata);
                break;

            case (".mld"):
                arc = new MLDArchive(arcdata);
                break;

            case (".mlt"):
            case (".gcaxmlt"):
                string test = System.Text.Encoding.ASCII.GetString(arcdata, 0, 4);
                if (test == "gcax")
                {
                    arc = new gcaxMLTFile(arcdata, Path.GetFileNameWithoutExtension(filePath));
                }
                else
                {
                    arc = new MLTFile(arcdata, Path.GetFileNameWithoutExtension(filePath));
                }
                break;

            default:
                Console.WriteLine("Unknown archive type");
                return;
            }
            Console.WriteLine("Output folder: {0}", Path.GetFullPath(outputPath));
            Directory.CreateDirectory(outputPath);
            foreach (GenericArchiveEntry entry in arc.Entries)
            {
                if (entry.Data == null)
                {
                    Console.WriteLine("Entry {0} has no data", entry.Name);
                    continue;
                }
                Console.WriteLine("Extracting file: {0}", entry.Name);
                if (arc is ARCXFile)
                {
                    ARCXFile.ARCXEntry ARCXentry = (ARCXFile.ARCXEntry)entry;
                    Directory.CreateDirectory(Path.Combine(outputPath, ARCXentry.Folder));
                    File.WriteAllBytes(Path.Combine(outputPath, ARCXentry.Folder, entry.Name), entry.Data);
                }
                else
                {
                    File.WriteAllBytes(Path.Combine(outputPath, entry.Name), entry.Data);
                }
            }
            arc.CreateIndexFile(outputPath);
            Console.WriteLine("Archive extracted!");
        }
예제 #6
0
        public static BMPInfo[] GetTextures(string filename)
        {
            if (!File.Exists(filename))
            {
                return(null);
            }
            GenericArchive arc;
            List <BMPInfo> textures = new List <BMPInfo>();

            byte[] file = File.ReadAllBytes(filename);
            string ext  = Path.GetExtension(filename).ToLowerInvariant();

            switch (ext)
            {
            // Folder texture pack
            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(Path.GetFileNameWithoutExtension(entry[1]), new System.Drawing.Bitmap(Path.Combine(Path.GetDirectoryName(filename), entry[1]))));
                }
                return(txts.ToArray());

            case ".pak":
                arc = new PAKFile(filename);
                string  filenoext = Path.GetFileNameWithoutExtension(filename).ToLowerInvariant();
                PAKFile pak       = (PAKFile)arc;
                // Get sorted entires from the INF file if it exists
                List <PAKFile.PAKEntry> sorted = pak.GetSortedEntries(filenoext);
                arc.Entries = new List <GenericArchiveEntry>(sorted.Cast <GenericArchiveEntry>());
                break;

            case ".pvmx":
                arc = new PVMXFile(file);
                break;

            case ".pb":
                arc = new PBFile(file);
                break;

            case ".pvr":
            case ".gvr":
                arc = new PuyoFile(ext == ".gvr");
                PuyoFile parcx = (PuyoFile)arc;
                if (ext == ".gvr")
                {
                    arc.Entries.Add(new GVMEntry(filename));
                }
                else
                {
                    arc.Entries.Add(new PVMEntry(filename));
                }
                if (parcx.PaletteRequired)
                {
                    parcx.AddPalette(Path.GetDirectoryName(filename));
                }
                break;

            case ".prs":
                file = FraGag.Compression.Prs.Decompress(file);
                goto default;

            case ".pvm":
            case ".gvm":
            default:
                arc = new PuyoFile(file);
                PuyoFile parc = (PuyoFile)arc;
                if (parc.PaletteRequired)
                {
                    parc.AddPalette(Path.GetDirectoryName(filename));
                }
                break;
            }
            foreach (GenericArchiveEntry entry in arc.Entries)
            {
                textures.Add(new BMPInfo(Path.GetFileNameWithoutExtension(entry.Name), entry.GetBitmap()));
            }
            return(textures.ToArray());
        }
예제 #7
0
        static void Main(string[] args)
        {
            string        directoryName;
            UInt32        startingGBIX = 0;
            List <String> textureNames = new List <String>();

            if (args.Length == 0)
            {
                Console.WriteLine("Error - no texturelist provided. Provide a path to a texturelist as your first command line argument");
                Console.WriteLine("Press ENTER to continue...");
                Console.ReadLine();
                return;
            }

            String filePath = args[0];

            directoryName = Path.GetDirectoryName(filePath);
            string archiveName = Path.GetFileNameWithoutExtension(filePath);

            if (File.Exists(filePath))
            {
                StreamReader texlistStream = File.OpenText(filePath);

                startingGBIX = UInt32.Parse(texlistStream.ReadLine());

                while (!texlistStream.EndOfStream)
                {
                    textureNames.Add(texlistStream.ReadLine());
                }

                string      filenoext = Path.GetFileNameWithoutExtension(filePath).ToLowerInvariant();
                string      longdir   = "..\\..\\..\\sonic2\\resource\\gd_pc\\prs\\" + filenoext;
                PAKFile     pak       = new PAKFile();
                List <byte> inf       = new List <byte>();
                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
                                                                                                                                                         } }))
                    {
                        // Reading in textures
                        for (uint imgIndx = 0; imgIndx < textureNames.Count; imgIndx++)
                        {
                            Bitmap tempTexture = new Bitmap(8, 8);
                            string texturePath = Path.Combine(directoryName, Path.ChangeExtension(textureNames[(int)imgIndx], ".png"));
                            if (File.Exists(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."));
                            }

                            Stream tex = TextureLoader.SaveToStream(ImageFileFormat.Dds, Texture.FromBitmap(d3ddevice, tempTexture, 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(textureNames[(int)imgIndx], ".dds"), longdir + '\\' + Path.ChangeExtension(textureNames[(int)imgIndx], ".dds"), tb));
                            int i = inf.Count;
                            inf.AddRange(Encoding.ASCII.GetBytes(Path.ChangeExtension(textureNames[(int)imgIndx], null)));
                            inf.AddRange(new byte[0x1C - (inf.Count - i)]);
                            inf.AddRange(BitConverter.GetBytes(startingGBIX + imgIndx));
                            inf.AddRange(BitConverter.GetBytes(0));
                            inf.AddRange(BitConverter.GetBytes(0));
                            inf.AddRange(BitConverter.GetBytes(0));
                            inf.AddRange(BitConverter.GetBytes(tempTexture.Width));
                            inf.AddRange(BitConverter.GetBytes(tempTexture.Height));
                            inf.AddRange(BitConverter.GetBytes(0));
                            inf.AddRange(BitConverter.GetBytes(0x80000000));
                        }
                    }
                pak.Files.Insert(0, new PAKFile.File(filenoext + '\\' + filenoext + ".inf", longdir + '\\' + filenoext + ".inf", inf.ToArray()));
                pak.Save(Path.ChangeExtension(filePath, "pak"));

                Console.WriteLine("PAK was compiled successfully!");
                Console.WriteLine("Press ENTER to continue...");
                Console.ReadLine();
                return;
            }
            else             // error, supplied path is invalid
            {
                Console.WriteLine("Supplied texturelist does not exist!");
                Console.WriteLine("Press ENTER to continue...");
                Console.ReadLine();
                return;
            }
        }
예제 #8
0
        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());
            }
        }
예제 #9
0
        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.ToLowerInvariant(), new MemoryStream(filedata)))
                            {
                                continue;
                            }
                            goto end;
                        }
                        else if (GvrTexture.Is(filedata))
                        {
                            if (!AddTexture(pak, filenoext, longdir, true, inf, d3ddevice, filename.ToLowerInvariant(), 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.ToLowerInvariant(), 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"));
            }
        }
예제 #10
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);
        }
예제 #11
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);
            }
        }
예제 #12
0
        void openFile(string projFileString)
        {
            if (projFileString != null)
            {
                Templates.ProjectTemplate projFile = ProjectFunctions.openProjectFileString(projFileString);
                if (projFile.GameInfo.GameName == "SA2PC")
                {
                    string projFolder = projFile.GameInfo.ProjectFolder;
                    string gameFolder = "";
                    if (projFile.GameInfo.GameDataFolder != null)
                    {
                        gameFolder = Path.Combine(ProjectFunctions.GetGamePath(projFile.GameInfo.GameName), projFile.GameInfo.GameDataFolder);
                    }
                    else
                    {
                        gameFolder = Path.Combine(ProjectFunctions.GetGamePath(projFile.GameInfo.GameName), "resource", "gd_PC");
                    }

                    if (File.Exists(Path.Combine(projFolder, "ADVERTISE_data.ini")))
                    {
                        IniData ini = IniSerializer.Deserialize <IniData>(Path.Combine(projFolder, "ADVERTISE_data.ini"));
                        filename = Path.Combine(projFolder, ini.Files.First((item) => item.Value.Type == "stageselectlist").Value.Filename);
                        levels   = new List <StageSelectLevel>(StageSelectLevelList.Load(filename));
                        string socFilePath = "";
                        string prsFilePath = "";

                        if (projFile.GameInfo.GameName == "SA2PC")
                        {
                            if (File.Exists(Path.Combine(projFolder, "gd_PC", "SOC", "stageMapBG.pak")))
                            {
                                socFilePath = Path.Combine(projFolder, "gd_PC", "SOC", "stageMapBG.pak");
                            }
                            else
                            {
                                socFilePath = Path.Combine(gameFolder, "SOC", "stageMapBG.pak");
                            }

                            if (File.Exists(Path.Combine(projFolder, "gd_PC", "PRS", "stageMap.pak")))
                            {
                                prsFilePath = Path.Combine(projFolder, "gd_PC", "PRS", "stageMap.pak");
                            }
                            else
                            {
                                prsFilePath = Path.Combine(gameFolder, "PRS", "stageMap.pak");
                            }
                        }
                        else
                        {
                            socFilePath = Path.Combine(gameFolder, "stageMapBG.prs");
                            prsFilePath = Path.Combine(gameFolder, "stageMap.prs");
                        }

                        PAKFile socpak = new PAKFile(socFilePath);
                        using (MemoryStream str = new MemoryStream(socpak.Entries.Find((a) => a.Name.Equals("stagemap.dds")).Data))
                            bgtex = LoadDDS(str);

                        if (File.Exists(prsFilePath))
                        {
                            PAKFile pakf = new PAKFile(prsFilePath);
                            byte[]  inf  = pakf.Entries.Find((a) => a.Name.Equals("stagemap.inf")).Data;
                            uitexs = new Bitmap[inf.Length / 0x3C];
                            for (int i = 0; i < uitexs.Length; i++)
                            {
                                using (MemoryStream str = new MemoryStream(pakf.Entries.Find(
                                                                               (a) => a.Name.Equals(Encoding.ASCII.GetString(inf, i * 0x3C, 0x1c).TrimEnd('\0') + ".dds")).Data))
                                    uitexs[i] = LoadDDS(str);
                            }
                        }
                        else
                        {
                            uitexs = TextureArchive.GetTextures(prsFilePath, out bool hasNames).Select((tex) => tex.Image).ToArray();
                        }
                        saveToolStripMenuItem.Enabled = panel1.Enabled = panel2.Enabled = true;
                        selected                = 0;
                        level.SelectedIndex     = (int)levels[selected].Level;
                        character.SelectedIndex = (int)levels[selected].Character;
                        column.Value            = levels[selected].Column;
                        row.Value               = levels[selected].Row;
                        DrawLevel();
                    }
                }
                else
                {
                    MessageBox.Show("The opened project file is not ", "Incorrect File", MessageBoxButtons.OK);
                }
            }
            Program.sapFile = "";
        }
예제 #13
0
        /// <summary>
        /// Main function for extracting archives.
        /// </summary>
        static void ExtractArchive(string[] args)
        {
            GenericArchive arc;
            string         arcname = extension.ToUpperInvariant();

            Console.WriteLine("Extracting {0} file: {1}", arcname.Substring(1, arcname.Length - 1), filePath);
            byte[] arcdata = File.ReadAllBytes(filePath);
            outputPath = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath));
            switch (extension.ToLowerInvariant())
            {
            case (".rel"):
                outputPath = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath) + "_dec.rel");
                Console.WriteLine("Output file: {0}", outputPath);
                byte[] inputData  = File.ReadAllBytes(args[0]);
                byte[] outputData = SA_Tools.HelperFunctions.DecompressREL(inputData);
                File.WriteAllBytes(outputPath, outputData);
                Console.WriteLine("File extracted!");
                return;

            case (".pvmx"):
                arc = new PVMXFile(arcdata);
                break;

            case (".prs"):
                arcdata = FraGag.Compression.Prs.Decompress(arcdata);
                if (PuyoFile.Identify(arcdata) == PuyoArchiveType.Unknown)
                {
                    outputPath = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath) + ".bin");
                    Console.WriteLine("Output file: {0}", Path.GetFullPath(outputPath));
                    File.WriteAllBytes(outputPath, arcdata);
                    Console.WriteLine("Archive extracted!");
                    return;
                }
                arc = new PuyoFile(arcdata);
                break;

            case (".pvm"):
            case (".gvm"):
                arc = new PuyoFile(arcdata);
                break;

            case (".pb"):
                arc = new PBFile(arcdata);
                break;

            case (".pak"):
                arc = new PAKFile(filePath);
                break;

            case (".dat"):
                arc = new DATFile(arcdata);
                break;

            case (".mdl"):
                arc = new MDLArchive(arcdata);
                break;

            case (".mdt"):
                arc = new MDTArchive(arcdata);
                break;

            case (".mld"):
                arc = new MLDArchive(arcdata);
                break;

            case (".mlt"):
                arc = new MLTArchive(arcdata);
                break;

            default:
                Console.WriteLine("Unknown archive type");
                return;
            }
            Console.WriteLine("Output folder: {0}", Path.GetFullPath(outputPath));
            Directory.CreateDirectory(outputPath);
            foreach (GenericArchiveEntry entry in arc.Entries)
            {
                Console.WriteLine("Extracting file: {0}", entry.Name);
                File.WriteAllBytes(Path.Combine(outputPath, entry.Name), entry.Data);
            }
            arc.CreateIndexFile(outputPath);
            Console.WriteLine("Archive extracted!");
        }
예제 #14
0
        public static ModelLoadResult LoadModels(IFileAccess access, string name)
        {
            var pak = new PAKFile(access.GetContent(name));

            return(LoadModels(pak));
        }