예제 #1
0
        public static void Split(string filename)
        {
            nodenames.Clear();
            modelfiles.Clear();
            motionfiles.Clear();

            Console.WriteLine("Splitting file {0}...", filename);
            byte[] fc;
            if (Path.GetExtension(filename).Equals(".prs", StringComparison.OrdinalIgnoreCase))
            {
                fc = Prs.Decompress(filename);
            }
            else
            {
                fc = File.ReadAllBytes(filename);
            }
            MiniEventIniData ini = new MiniEventIniData()
            {
                Name = Path.GetFileNameWithoutExtension(filename)
            };
            string            path = Directory.CreateDirectory(Path.Combine(Path.GetDirectoryName(Path.GetFullPath(filename)), Path.GetFileNameWithoutExtension(filename))).FullName;
            uint              key;
            List <NJS_MOTION> motions = null;

            if (fc[4] == 0x81)
            {
                Console.WriteLine("File is in GC/PC format.");
                ByteConverter.BigEndian = true;
                key      = 0x816DFE60;
                ini.Game = Game.SA2B;
            }
            else
            {
                Console.WriteLine("File is in DC format.");
                ByteConverter.BigEndian = false;
                key      = 0xCB00000;
                ini.Game = Game.SA2;
            }
            int ptr = fc.GetPointer(8, key);

            if (ptr != 0)
            {
                Console.WriteLine("Sonic is in this Mini-Event");
                Directory.CreateDirectory(Path.Combine(path, "Sonic"));
                MiniEventChars data = new MiniEventChars();
                data.BodyAnims = GetMotion(fc, ptr, key, $"Sonic\\Body.saanim", motions, 62);
                int ptr2 = fc.GetPointer(ptr + 4, key);
                if (ptr2 != 0)
                {
                    data.HeadPart = GetModel(fc, ptr + 4, key, $"Sonic\\Head.sa2mdl");
                }
                if (data.HeadPart != null)
                {
                    data.HeadAnims = GetMotion(fc, ptr + 8, key, $"Sonic\\Head.saanim", motions, modelfiles[data.HeadPart].Model.CountAnimated());
                    if (data.HeadAnims != null)
                    {
                        modelfiles[data.HeadPart].Motions.Add($"Head.saanim");
                    }
                    data.HeadShapeMotions = GetMotion(fc, ptr + 0xC, key, $"Sonic\\HeadShape.saanim", motions, modelfiles[data.HeadPart].Model.CountMorph());
                    if (data.HeadShapeMotions != null)
                    {
                        modelfiles[data.HeadPart].Motions.Add($"HeadShape.saanim");
                    }
                }
                ptr2 = fc.GetPointer(ptr + 0x10, key);
                if (ptr2 != 0)
                {
                    data.MouthPart = GetModel(fc, ptr + 0x10, key, $"Sonic\\Mouth.sa2mdl");
                }
                if (data.MouthPart != null)
                {
                    data.MouthAnims = GetMotion(fc, ptr + 0x14, key, $"Sonic\\Mouth.saanim", motions, modelfiles[data.MouthPart].Model.CountAnimated());
                    if (data.MouthAnims != null)
                    {
                        modelfiles[data.MouthPart].Motions.Add($"Mouth.saanim");
                    }
                    data.MouthShapeMotions = GetMotion(fc, ptr + 0x18, key, $"Sonic\\MouthShape.saanim", motions, modelfiles[data.MouthPart].Model.CountMorph());
                    if (data.MouthShapeMotions != null)
                    {
                        modelfiles[data.MouthPart].Motions.Add($"MouthShape.saanim");
                    }
                }
                ptr2 = fc.GetPointer(ptr + 0x1C, key);
                if (ptr2 != 0)
                {
                    data.LHandPart = GetModel(fc, ptr + 0x1C, key, $"Sonic\\LeftHand.sa2mdl");
                }
                if (data.LHandPart != null)
                {
                    data.LHandAnims = GetMotion(fc, ptr + 0x20, key, $"Sonic\\LeftHand.saanim", motions, modelfiles[data.LHandPart].Model.CountAnimated());
                    if (data.LHandAnims != null)
                    {
                        modelfiles[data.LHandPart].Motions.Add($"LeftHand.saanim");
                    }
                    data.LHandShapeMotions = GetMotion(fc, ptr + 0x24, key, $"Sonic\\LeftHandShape.saanim", motions, modelfiles[data.LHandPart].Model.CountMorph());
                    if (data.LHandShapeMotions != null)
                    {
                        modelfiles[data.LHandPart].Motions.Add($"LeftHandShape.saanim");
                    }
                }
                ptr2 = fc.GetPointer(ptr + 0x28, key);
                if (ptr2 != 0)
                {
                    data.RHandPart = GetModel(fc, ptr + 0x28, key, $"Sonic\\RightHand.sa2mdl");
                }
                if (data.RHandPart != null)
                {
                    data.RHandAnims = GetMotion(fc, ptr + 0x2C, key, $"Sonic\\RightHand.saanim", motions, modelfiles[data.RHandPart].Model.CountAnimated());
                    if (data.RHandAnims != null)
                    {
                        modelfiles[data.RHandPart].Motions.Add($"RightHand.saanim");
                    }
                    data.RHandShapeMotions = GetMotion(fc, ptr + 0x30, key, $"Sonic\\RightHandShape.saanim", motions, modelfiles[data.RHandPart].Model.CountMorph());
                    if (data.RHandShapeMotions != null)
                    {
                        modelfiles[data.RHandPart].Motions.Add($"RightHandShape.saanim");
                    }
                }
                ini.Sonic.Add(data);
            }
            ptr = fc.GetPointer(0xC, key);
            if (ptr != 0)
            {
                Console.WriteLine("Shadow is in this Mini-Event");
                Directory.CreateDirectory(Path.Combine(path, "Shadow"));
                MiniEventChars data = new MiniEventChars();
                data.BodyAnims = GetMotion(fc, ptr, key, $"Shadow\\Body.saanim", motions, 62);
                int ptr2 = fc.GetPointer(ptr + 4, key);
                if (ptr2 != 0)
                {
                    data.HeadPart = GetModel(fc, ptr + 4, key, $"Shadow\\Head.sa2mdl");
                }
                if (data.HeadPart != null)
                {
                    data.HeadAnims = GetMotion(fc, ptr + 8, key, $"Shadow\\Head.saanim", motions, modelfiles[data.HeadPart].Model.CountAnimated());
                    if (data.HeadAnims != null)
                    {
                        modelfiles[data.HeadPart].Motions.Add($"Head.saanim");
                    }
                    data.HeadShapeMotions = GetMotion(fc, ptr + 0xC, key, $"Shadow\\HeadShape.saanim", motions, modelfiles[data.HeadPart].Model.CountMorph());
                    if (data.HeadShapeMotions != null)
                    {
                        modelfiles[data.HeadPart].Motions.Add($"HeadShape.saanim");
                    }
                }
                ptr2 = fc.GetPointer(ptr + 0x10, key);
                if (ptr2 != 0)
                {
                    data.MouthPart = GetModel(fc, ptr + 0x10, key, $"Shadow\\Mouth.sa2mdl");
                }
                if (data.MouthPart != null)
                {
                    data.MouthAnims = GetMotion(fc, ptr + 0x14, key, $"Shadow\\Mouth.saanim", motions, modelfiles[data.MouthPart].Model.CountAnimated());
                    if (data.MouthAnims != null)
                    {
                        modelfiles[data.MouthPart].Motions.Add($"Mouth.saanim");
                    }
                    data.MouthShapeMotions = GetMotion(fc, ptr + 0x18, key, $"Shadow\\MouthShape.saanim", motions, modelfiles[data.MouthPart].Model.CountMorph());
                    if (data.MouthShapeMotions != null)
                    {
                        modelfiles[data.MouthPart].Motions.Add($"MouthShape.saanim");
                    }
                }
                ptr2 = fc.GetPointer(ptr + 0x1C, key);
                if (ptr2 != 0)
                {
                    data.LHandPart = GetModel(fc, ptr + 0x1C, key, $"Shadow\\LeftHand.sa2mdl");
                }
                if (data.LHandPart != null)
                {
                    data.LHandAnims = GetMotion(fc, ptr + 0x20, key, $"Shadow\\LeftHand.saanim", motions, modelfiles[data.LHandPart].Model.CountAnimated());
                    if (data.LHandAnims != null)
                    {
                        modelfiles[data.LHandPart].Motions.Add($"LeftHand.saanim");
                    }
                    data.LHandShapeMotions = GetMotion(fc, ptr + 0x24, key, $"Shadow\\LeftHandShape.saanim", motions, modelfiles[data.LHandPart].Model.CountMorph());
                    if (data.LHandShapeMotions != null)
                    {
                        modelfiles[data.LHandPart].Motions.Add($"LeftHandShape.saanim");
                    }
                }
                ptr2 = fc.GetPointer(ptr + 0x28, key);
                if (ptr2 != 0)
                {
                    data.RHandPart = GetModel(fc, ptr + 0x28, key, $"Shadow\\RightHand.sa2mdl");
                }
                if (data.RHandPart != null)
                {
                    data.RHandAnims = GetMotion(fc, ptr + 0x2C, key, $"Shadow\\RightHand.saanim", motions, modelfiles[data.RHandPart].Model.CountAnimated());
                    if (data.RHandAnims != null)
                    {
                        modelfiles[data.RHandPart].Motions.Add($"RightHand.saanim");
                    }
                    data.RHandShapeMotions = GetMotion(fc, ptr + 0x30, key, $"Shadow\\RightHandShape.saanim", motions, modelfiles[data.RHandPart].Model.CountMorph());
                    if (data.RHandShapeMotions != null)
                    {
                        modelfiles[data.RHandPart].Motions.Add($"RightHandShape.saanim");
                    }
                }
                ini.Shadow.Add(data);
            }
            ptr = fc.GetPointer(0x18, key);
            if (ptr != 0)
            {
                Console.WriteLine("Knuckles is in this Mini-Event");
                Directory.CreateDirectory(Path.Combine(path, "Knuckles"));
                MiniEventChars data = new MiniEventChars();
                data.BodyAnims = GetMotion(fc, ptr, key, $"Knuckles\\Body.saanim", motions, 62);
                int ptr2 = fc.GetPointer(ptr + 4, key);
                if (ptr2 != 0)
                {
                    data.HeadPart = GetModel(fc, ptr + 4, key, $"Knuckles\\Head.sa2mdl");
                }
                if (data.HeadPart != null)
                {
                    data.HeadAnims = GetMotion(fc, ptr + 8, key, $"Knuckles\\Head.saanim", motions, modelfiles[data.HeadPart].Model.CountAnimated());
                    if (data.HeadAnims != null)
                    {
                        modelfiles[data.HeadPart].Motions.Add($"Head.saanim");
                    }
                    data.HeadShapeMotions = GetMotion(fc, ptr + 0xC, key, $"Knuckles\\HeadShape.saanim", motions, modelfiles[data.HeadPart].Model.CountMorph());
                    if (data.HeadShapeMotions != null)
                    {
                        modelfiles[data.HeadPart].Motions.Add($"HeadShape.saanim");
                    }
                }
                ptr2 = fc.GetPointer(ptr + 0x10, key);
                if (ptr2 != 0)
                {
                    data.MouthPart = GetModel(fc, ptr + 0x10, key, $"Knuckles\\Mouth.sa2mdl");
                }
                if (data.MouthPart != null)
                {
                    data.MouthAnims = GetMotion(fc, ptr + 0x14, key, $"Knuckles\\Mouth.saanim", motions, modelfiles[data.MouthPart].Model.CountAnimated());
                    if (data.MouthAnims != null)
                    {
                        modelfiles[data.MouthPart].Motions.Add($"Mouth.saanim");
                    }
                    data.MouthShapeMotions = GetMotion(fc, ptr + 0x18, key, $"Knuckles\\MouthShape.saanim", motions, modelfiles[data.MouthPart].Model.CountMorph());
                    if (data.MouthShapeMotions != null)
                    {
                        modelfiles[data.MouthPart].Motions.Add($"MouthShape.saanim");
                    }
                }
                ptr2 = fc.GetPointer(ptr + 0x1C, key);
                if (ptr2 != 0)
                {
                    data.LHandPart = GetModel(fc, ptr + 0x1C, key, $"Knuckles\\LeftHand.sa2mdl");
                }
                if (data.LHandPart != null)
                {
                    data.LHandAnims = GetMotion(fc, ptr + 0x20, key, $"Knuckles\\LeftHand.saanim", motions, modelfiles[data.LHandPart].Model.CountAnimated());
                    if (data.LHandAnims != null)
                    {
                        modelfiles[data.LHandPart].Motions.Add($"LeftHand.saanim");
                    }
                    data.LHandShapeMotions = GetMotion(fc, ptr + 0x24, key, $"Knuckles\\LeftHandShape.saanim", motions, modelfiles[data.LHandPart].Model.CountMorph());
                    if (data.LHandShapeMotions != null)
                    {
                        modelfiles[data.LHandPart].Motions.Add($"LeftHandShape.saanim");
                    }
                }
                ptr2 = fc.GetPointer(ptr + 0x28, key);
                if (ptr2 != 0)
                {
                    data.RHandPart = GetModel(fc, ptr + 0x28, key, $"Knuckles\\RightHand.sa2mdl");
                }
                if (data.RHandPart != null)
                {
                    data.RHandAnims = GetMotion(fc, ptr + 0x2C, key, $"Knuckles\\RightHand.saanim", motions, modelfiles[data.RHandPart].Model.CountAnimated());
                    if (data.RHandAnims != null)
                    {
                        modelfiles[data.RHandPart].Motions.Add($"RightHand.saanim");
                    }
                    data.RHandShapeMotions = GetMotion(fc, ptr + 0x30, key, $"Knuckles\\RightHandShape.saanim", motions, modelfiles[data.RHandPart].Model.CountMorph());
                    if (data.RHandShapeMotions != null)
                    {
                        modelfiles[data.RHandPart].Motions.Add($"RightHandShape.saanim");
                    }
                }
                ini.Knuckles.Add(data);
            }
            ptr = fc.GetPointer(0x1C, key);
            if (ptr != 0)
            {
                Console.WriteLine("Rouge is in this Mini-Event");
                Directory.CreateDirectory(Path.Combine(path, "Rouge"));
                MiniEventChars data = new MiniEventChars();
                data.BodyAnims = GetMotion(fc, ptr, key, $"Rouge\\Body.saanim", motions, 62);
                int ptr2 = fc.GetPointer(ptr + 4, key);
                if (ptr2 != 0)
                {
                    data.HeadPart = GetModel(fc, ptr + 4, key, $"Rouge\\Head.sa2mdl");
                }
                if (data.HeadPart != null)
                {
                    data.HeadAnims = GetMotion(fc, ptr + 8, key, $"Rouge\\Head.saanim", motions, modelfiles[data.HeadPart].Model.CountAnimated());
                    if (data.HeadAnims != null)
                    {
                        modelfiles[data.HeadPart].Motions.Add($"Head.saanim");
                    }
                    data.HeadShapeMotions = GetMotion(fc, ptr + 0xC, key, $"Rouge\\HeadShape.saanim", motions, modelfiles[data.HeadPart].Model.CountMorph());
                    if (data.HeadShapeMotions != null)
                    {
                        modelfiles[data.HeadPart].Motions.Add($"HeadShape.saanim");
                    }
                }
                ptr2 = fc.GetPointer(ptr + 0x10, key);
                if (ptr2 != 0)
                {
                    data.MouthPart = GetModel(fc, ptr + 0x10, key, $"Rouge\\Mouth.sa2mdl");
                }
                if (data.MouthPart != null)
                {
                    data.MouthAnims = GetMotion(fc, ptr + 0x14, key, $"Rouge\\Mouth.saanim", motions, modelfiles[data.MouthPart].Model.CountAnimated());
                    if (data.MouthAnims != null)
                    {
                        modelfiles[data.MouthPart].Motions.Add($"Mouth.saanim");
                    }
                    data.MouthShapeMotions = GetMotion(fc, ptr + 0x18, key, $"Rouge\\MouthShape.saanim", motions, modelfiles[data.MouthPart].Model.CountMorph());
                    if (data.MouthShapeMotions != null)
                    {
                        modelfiles[data.MouthPart].Motions.Add($"MouthShape.saanim");
                    }
                }
                ptr2 = fc.GetPointer(ptr + 0x1C, key);
                if (ptr2 != 0)
                {
                    data.LHandPart = GetModel(fc, ptr + 0x1C, key, $"Rouge\\LeftHand.sa2mdl");
                }
                if (data.LHandPart != null)
                {
                    data.LHandAnims = GetMotion(fc, ptr + 0x20, key, $"Rouge\\LeftHand.saanim", motions, modelfiles[data.LHandPart].Model.CountAnimated());
                    if (data.LHandAnims != null)
                    {
                        modelfiles[data.LHandPart].Motions.Add($"LeftHand.saanim");
                    }
                    data.LHandShapeMotions = GetMotion(fc, ptr + 0x24, key, $"Rouge\\LeftHandShape.saanim", motions, modelfiles[data.LHandPart].Model.CountMorph());
                    if (data.LHandShapeMotions != null)
                    {
                        modelfiles[data.LHandPart].Motions.Add($"LeftHandShape.saanim");
                    }
                }
                ptr2 = fc.GetPointer(ptr + 0x28, key);
                if (ptr2 != 0)
                {
                    data.RHandPart = GetModel(fc, ptr + 0x28, key, $"Rouge\\RightHand.sa2mdl");
                }
                if (data.RHandPart != null)
                {
                    data.RHandAnims = GetMotion(fc, ptr + 0x2C, key, $"Rouge\\RightHand.saanim", motions, modelfiles[data.RHandPart].Model.CountAnimated());
                    if (data.RHandAnims != null)
                    {
                        modelfiles[data.RHandPart].Motions.Add($"RightHand.saanim");
                    }
                    data.RHandShapeMotions = GetMotion(fc, ptr + 0x30, key, $"Rouge\\RightHandShape.saanim", motions, modelfiles[data.RHandPart].Model.CountMorph());
                    if (data.RHandShapeMotions != null)
                    {
                        modelfiles[data.RHandPart].Motions.Add($"RightHandShape.saanim");
                    }
                }
                ini.Rouge.Add(data);
            }
            ptr = fc.GetPointer(0x24, key);
            if (ptr != 0)
            {
                Console.WriteLine("Mech Eggman is in this Mini-Event");
                Directory.CreateDirectory(Path.Combine(path, "Mech Eggman"));
                ini.MechEggmanBodyAnims = GetMotion(fc, ptr, key, $"Mech Eggman\\Body.saanim", motions, 33);
            }
            ptr = fc.GetPointer(4, key);
            if (ptr != 0)
            {
                ini.Camera    = GetMotion(fc, ptr + 0x10, key, $"Camera.saanim", motions, 1);
                ini.CamFrames = ByteConverter.ToInt32(fc, ptr + 4);
            }
            else
            {
                Console.WriteLine("Mini-Event does not contain a camera.");
            }
            foreach (var item in motionfiles.Values)
            {
                string fn = item.Filename;
                string fp = Path.Combine(path, fn);
                item.Motion.Save(fp);
                ini.Files.Add(fn, HelperFunctions.FileHash(fp));
            }
            foreach (var item in modelfiles.Values)
            {
                string fp = Path.Combine(path, item.Filename);
                ModelFile.CreateFile(fp, item.Model, item.Motions.ToArray(), null, null, null, item.Format);
                ini.Files.Add(item.Filename, HelperFunctions.FileHash(fp));
            }
            JsonSerializer js = new JsonSerializer
            {
                Formatting        = Formatting.Indented,
                NullValueHandling = NullValueHandling.Ignore
            };

            using (var tw = File.CreateText(Path.Combine(path, Path.ChangeExtension(Path.GetFileName(filename), ".json"))))
                js.Serialize(tw, ini);
        }
예제 #2
0
        static void Main(string[] args)
        {
            string filename_src;
            string filename_dst;

            if (args.Length == 1)
            {
                string[] filenames = File.ReadAllLines(args[0]);
                for (int f = 0; f < filenames.Length; f++)
                {
                    Console.WriteLine("Sorting file {0}", filenames[f]);
                    ModelFile model = new ModelFile(filenames[f]);
                    SortModel(model.Model, true);
                    model.SaveToFile(filenames[f]);
                }
                return;
            }
            string filename_out = "Result.ini";

            if (args.Length > 1)
            {
                filename_src = Path.GetFullPath(args[0]);
                filename_dst = Path.GetFullPath(args[1]);
                Console.WriteLine("Source file: {0}", filename_src);
                Console.WriteLine("Destination file: {0}", filename_dst);
                for (int a = 0; a < args.Length; a++)
                {
                    if (args[a] == "-s")
                    {
                        savediff = true;
                    }
                    if (args[a] == "-a")
                    {
                        overwrite = false;
                    }
                    if (args[a] == "-o")
                    {
                        filename_out = Path.GetFullPath(args[a + 1]);
                    }
                }
                if (savediff)
                {
                    Console.Write("Output file: {0}, ", filename_out);
                    Console.Write("mode: " + (overwrite ? "Overwrite" : "Append") + "\n");
                }
            }
            else
            {
                Console.WriteLine("This tool compares two levels or models and outputs a list of differences between them.\n");
                Console.WriteLine("Usage:");
                Console.WriteLine("CompareTool <file1> <file2> [-s] [-a] [-o outputfile]\n");
                Console.WriteLine("Arguments:");
                Console.WriteLine("file1: Source level or model");
                Console.WriteLine("file2: Destination level or model");
                //Console.WriteLine("-s: Save the list of differences to an INI file");
                Console.WriteLine("-a: Append to the list of differences instead of overwriting it");
                Console.WriteLine("-o: Output filename (default is Result.ini)\n");
                Console.WriteLine("Example:");
                Console.WriteLine("CompareTool Level_PC.sa1lvl Level_Gamecube.sa1lvl\n");
                Console.WriteLine("Press ENTER to exit.");
                Console.ReadLine();
                return;
            }
            if (!File.Exists(filename_src) || !File.Exists(filename_dst))
            {
                Console.WriteLine("File {0} or {1} doesn't exist.", filename_src, filename_dst);
                Console.ReadLine();
                return;
            }
            string ext = Path.GetExtension(filename_src).ToLowerInvariant();

            //biglist = new Dictionary<int, List<DiffData>>();
            switch (ext)
            {
            case ".sa1lvl":
                LandTable land_src = LandTable.LoadFromFile(filename_src);
                LandTable land_dst = LandTable.LoadFromFile(filename_dst);
                COL[]     arr_src  = land_src.COL.ToArray();
                COL[]     arr_dst  = land_dst.COL.ToArray();
                bool      same     = true;
                for (int co = 0; co < arr_src.Length; co++)
                {
                    if (same && !CompareCOL(arr_src[co], arr_dst[co]))
                    {
                        Console.WriteLine("COL order different at item {0} ({1} / {2} / {3})! Trying manual match.", co, arr_src[co].Bounds.Center.X, arr_src[co].Bounds.Center.Y, arr_src[co].Bounds.Center.Z);
                        same = false;
                    }
                }
                //Compare using identical order
                if (same)
                {
                    for (int c = 0; c < arr_src.Length; c++)
                    {
                        if (arr_src[c].Model.Attach != null)
                        {
                            CompareAttach((BasicAttach)arr_src[c].Model.Attach, (BasicAttach)arr_dst[c].Model.Attach);
                        }
                    }
                }

                //Compare using different order
                else
                {
                    if (arr_dst.Length != arr_src.Length)
                    {
                        Console.WriteLine("COL count different: {0} vs {1}", arr_src.Length, arr_dst.Length);
                    }
                    Dictionary <int, int> matches = new Dictionary <int, int>();
                    for (int c1 = 0; c1 < arr_dst.Length; c1++)
                    {
                        bool found = false;
                        for (int c2 = 0; c2 < arr_dst.Length; c2++)
                        {
                            if (arr_src[c1].Model.Attach != null && CompareCOL(arr_src[c1], arr_dst[c2], 0))
                            {
                                if (!matches.ContainsKey(c2) && !matches.ContainsValue(c1))
                                {
                                    matches.Add(c2, c1);
                                    found = true;
                                    Console.WriteLine("COL item {0} matched with {1}", c1, c2);
                                    CompareAttach((BasicAttach)arr_src[c1].Model.Attach, (BasicAttach)arr_dst[c2].Model.Attach);
                                }
                            }
                        }
                        //Try again but less strict
                        if (!found)
                        {
                            for (int c2 = 0; c2 < arr_dst.Length; c2++)
                            {
                                if (arr_src[c1].Model.Attach != null && CompareCOL(arr_src[c1], arr_dst[c2], 1))
                                {
                                    if (!matches.ContainsKey(c2) && !matches.ContainsValue(c1))
                                    {
                                        matches.Add(c2, c1);
                                        Console.WriteLine("COL item {0} partially matched with {1}", c1, c2);
                                        CompareAttach((BasicAttach)arr_src[c1].Model.Attach, (BasicAttach)arr_dst[c2].Model.Attach);
                                    }
                                }
                            }
                        }
                    }
                    Console.WriteLine("Total COL items in landtables: {0} vs {1}, matches: {2}", arr_src.Length, arr_dst.Length, matches.Count);
                }
                //if (savediff) SerializeDiffList(filename_out);
                break;

            case ".sa1mdl":
                NJS_OBJECT mdl_src = new ModelFile(filename_src).Model;
                NJS_OBJECT mdl_dst = new ModelFile(filename_dst).Model;
                if (mdl_src.Attach != null)
                {
                    CompareAttach((BasicAttach)mdl_src.Attach, (BasicAttach)mdl_dst.Attach);
                }
                if (mdl_src.Children.Count > 0)
                {
                    for (int id = 0; id < mdl_src.Children.Count; id++)
                    {
                        if (mdl_src.Children[id].Attach != null)
                        {
                            CompareAttach((BasicAttach)mdl_src.Children[id].Attach, (BasicAttach)mdl_dst.Children[id].Attach);
                        }
                    }
                }
                if (mdl_src.Sibling != null && mdl_src.Sibling.Attach != null)
                {
                    CompareAttach((BasicAttach)mdl_src.Sibling.Attach, (BasicAttach)mdl_dst.Sibling.Attach);
                }
                //if (savediff) SerializeDiffList(filename_out);
                break;

            default:
                break;
            }
            if (savediff)
            {
                Console.WriteLine("Total UV array differences: {0}", uvcount);
            }
        }
예제 #3
0
        public static void ExportCPP(DllIniData IniData,
                                     Dictionary <string, bool> itemsToExport, string fileName)
        {
            using (TextWriter writer = File.CreateText(fileName))
            {
                bool            SA2      = IniData.Game == SA_Tools.SplitDLL.Game.SA2B;
                ModelFormat     modelfmt = SA2 ? ModelFormat.Chunk : ModelFormat.BasicDX;
                LandTableFormat landfmt  = SA2 ? LandTableFormat.SA2 : LandTableFormat.SADX;
                writer.WriteLine("// Generated by SA Tools DLL Mod Generator");
                writer.WriteLine();
                if (SA2)
                {
                    writer.WriteLine("#include \"SA2ModLoader.h\"");
                }
                else
                {
                    writer.WriteLine("#include \"SADXModLoader.h\"");
                }
                writer.WriteLine();
                List <string>             labels   = new List <string>();
                Dictionary <string, uint> texlists = new Dictionary <string, uint>();
                foreach (KeyValuePair <string, FileTypeHash> item in
                         IniData.Files.Where(i => itemsToExport[i.Key]))
                {
                    switch (item.Value.Type)
                    {
                    case "landtable":
                        LandTable tbl = LandTable.LoadFromFile(item.Key);
                        texlists.Add(tbl.Name, tbl.TextureList);
                        tbl.ToStructVariables(writer, landfmt, new List <string>());
                        labels.AddRange(tbl.GetLabels());
                        break;

                    case "model":
                        NJS_OBJECT mdl = new ModelFile(item.Key).Model;
                        mdl.ToStructVariables(writer, modelfmt == ModelFormat.BasicDX, new List <string>());
                        labels.AddRange(mdl.GetLabels());
                        break;

                    case "basicmodel":
                    case "chunkmodel":
                        mdl = new ModelFile(item.Key).Model;
                        mdl.ToStructVariables(writer, false, new List <string>());
                        labels.AddRange(mdl.GetLabels());
                        break;

                    case "basicdxmodel":
                        mdl = new ModelFile(item.Key).Model;
                        mdl.ToStructVariables(writer, true, new List <string>());
                        labels.AddRange(mdl.GetLabels());
                        break;

                    case "animation":
                        NJS_MOTION ani = NJS_MOTION.Load(item.Key);
                        ani.ToStructVariables(writer);
                        labels.Add(ani.Name);
                        break;
                    }
                    writer.WriteLine();
                }
                foreach (var item in IniData.DataItems.Where(i => itemsToExport[i.Filename]))
                {
                    switch (item.Type)
                    {
                    case "animindexlist":
                    {
                        SortedDictionary <short, NJS_MOTION> anims = new SortedDictionary <short, NJS_MOTION>();
                        foreach (string file in Directory.GetFiles(item.Filename, "*.saanim"))
                        {
                            if (short.TryParse(Path.GetFileNameWithoutExtension(file), NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out short i))
                            {
                                anims.Add(i, NJS_MOTION.Load(file));
                            }
                        }
                        foreach (KeyValuePair <short, NJS_MOTION> obj in anims)
                        {
                            obj.Value.ToStructVariables(writer);
                            writer.WriteLine();
                        }
                        writer.WriteLine("AnimationIndex {0}[] = {{", item.Export);
                        List <string> objs = new List <string>(anims.Count);
                        foreach (KeyValuePair <short, NJS_MOTION> obj in anims)
                        {
                            objs.Add($"{{ {obj.Key}, {obj.Value.ModelParts}, &{obj.Value.Name} }}");
                        }
                        objs.Add("{ -1 }");
                        writer.WriteLine("\t" + string.Join("," + Environment.NewLine + "\t", objs.ToArray()));
                        writer.WriteLine("};");
                    }
                    break;

                    case "charaobjectdatalist":
                    {
                        foreach (string file in Directory.GetFiles(item.Filename, "*.sa2mdl"))
                        {
                            new ModelFile(file).Model.ToStructVariables(writer, false, new List <string>());
                            writer.WriteLine();
                        }
                        foreach (string file in Directory.GetFiles(item.Filename, "*.saanim"))
                        {
                            NJS_MOTION.Load(file).ToStructVariables(writer);
                            writer.WriteLine();
                        }
                        var data = IniSerializer.Deserialize <CharaObjectData[]>(Path.Combine(item.Filename, "info.ini"));
                        writer.WriteLine("CharaObjectData {0}[] = {{", item.Export);
                        List <string> objs = new List <string>(data.Length);
                        foreach (var obj in data)
                        {
                            objs.Add(obj.ToStruct());
                        }
                        writer.WriteLine("\t" + string.Join("," + Environment.NewLine + "\t", objs.ToArray()));
                        writer.WriteLine("};");
                    }
                    break;

                    case "kartspecialinfolist":
                    {
                        foreach (string file in Directory.GetFiles(item.Filename, "*.sa2mdl"))
                        {
                            new ModelFile(file).Model.ToStructVariables(writer, false, new List <string>());
                            writer.WriteLine();
                        }
                        var data = IniSerializer.Deserialize <KartSpecialInfo[]>(Path.Combine(item.Filename, "info.ini"));
                        writer.WriteLine("KartSpecialInfo {0}[] = {{", item.Export);
                        List <string> objs = new List <string>(data.Length);
                        for (int i = 0; i < data.Length; i++)
                        {
                            KartSpecialInfo obj = data[i];
                            objs.Add(obj.ToStruct());
                            texlists.Add($"{item.Export}[{i}]", obj.TexList);
                        }
                        writer.WriteLine("\t" + string.Join("," + Environment.NewLine + "\t", objs.ToArray()));
                        writer.WriteLine("};");
                    }
                    break;

                    case "chaomotiontable":
                    {
                        foreach (string file in Directory.GetFiles(item.Filename, "*.saanim"))
                        {
                            NJS_MOTION.Load(file).ToStructVariables(writer);
                            writer.WriteLine();
                        }
                        var data = IniSerializer.Deserialize <ChaoMotionTableEntry[]>(Path.Combine(item.Filename, "info.ini"));
                        writer.WriteLine("ChaoMotionTableEntry {0}[] = {{", item.Export);
                        List <string> objs = new List <string>(data.Length);
                        foreach (var obj in data)
                        {
                            objs.Add(obj.ToStruct());
                        }
                        writer.WriteLine("\t" + string.Join("," + Environment.NewLine + "\t", objs.ToArray()));
                        writer.WriteLine("};");
                    }
                    break;
                    }
                }
                writer.WriteLine("extern \"C\" __declspec(dllexport) void __cdecl Init(const char *path, const HelperFunctions &helperFunctions)");
                writer.WriteLine("{");
                writer.WriteLine("\tHMODULE handle = GetModuleHandle(L\"{0}\");", IniData.Name);
                List <string> exports = new List <string>(IniData.Items.Where(item => labels.Contains(item.Label)).Select(item => item.Export).Distinct());
                foreach (KeyValuePair <string, string> item in IniData.Exports.Where(item => exports.Contains(item.Key)))
                {
                    writer.WriteLine("\t{0}{1} = ({0})GetProcAddress(handle, \"{1}\");", typemap[item.Value], item.Key);
                }
                foreach (DllItemInfo item in IniData.Items.Where(item => labels.Contains(item.Label)))
                {
                    if (typemap[IniData.Exports[item.Export]].EndsWith("**"))
                    {
                        writer.WriteLine("\t{0} = &{1};", item.ToString(), item.Label);
                    }
                    else
                    {
                        writer.WriteLine("\t*{0} = {1};", item.ToString(), item.Label);
                    }
                }
                foreach (var item in IniData.DataItems.Where(item => itemsToExport[item.Filename]))
                {
                    switch (item.Type)
                    {
                    case "animindexlist":
                    case "charaobjectdatalist":
                    case "kartspecialinfolist":
                        writer.WriteLine("\tHookExport(handle, \"{0}\", {0});", item.Export);
                        break;

                    default:
                        writer.WriteLine("\t{0}{1}_exp = ({0})GetProcAddress(handle, \"{1}\");", typemap[item.Type], item.Export);
                        writer.WriteLine("\t*{0}_exp = {0};", item.Export);
                        break;
                    }
                }
                if (texlists.Count > 0 && IniData.TexLists != null && IniData.TexLists.Items != null)
                {
                    exports = new List <string>(IniData.TexLists.Where(item => texlists.Values.Contains(item.Key)).Select(item => item.Value.Export).Distinct());
                    foreach (KeyValuePair <string, string> item in IniData.Exports.Where(item => exports.Contains(item.Key)))
                    {
                        writer.WriteLine("\t{0}{1} = ({0})GetProcAddress(handle, \"{1}\");", typemap[item.Value], item.Key);
                    }
                    foreach (KeyValuePair <string, uint> item in texlists.Where(item => IniData.TexLists.ContainsKey(item.Value)))
                    {
                        DllTexListInfo tex = IniData.TexLists[item.Value];
                        string         str;
                        if (tex.Index.HasValue)
                        {
                            str = $"{tex.Export}[{tex.Index.Value}]";
                        }
                        else
                        {
                            str = tex.Export;
                        }
                        writer.WriteLine("\t{0}.TexList = {1};", item.Key, str);
                    }
                }
                writer.WriteLine("}");
                writer.WriteLine();
                writer.WriteLine("extern \"C\" __declspec(dllexport) const ModInfo {0}ModInfo = {{ ModLoaderVer }};", SA2 ? "SA2" : "SADX");
            }
        }
예제 #4
0
        public static int SplitFile(string datafilename, string inifilename, string projectFolderName)
        {
            try
            {
                byte[]  datafile = File.ReadAllBytes(datafilename);
                IniData inifile  = IniSerializer.Deserialize <IniData>(inifilename);
                if (inifile.MD5 != null && inifile.MD5.Count > 0)
                {
                    string datahash = HelperFunctions.FileHash(datafile);
                    if (!inifile.MD5.Any(h => h.Equals(datahash, StringComparison.OrdinalIgnoreCase)))
                    {
                        Console.WriteLine("The file {0} is not valid for use with the INI {1}.", datafilename, inifilename);
                        return((int)SplitERRORVALUE.InvalidDataMapping);
                    }
                }
                ByteConverter.BigEndian      = SonicRetro.SAModel.ByteConverter.BigEndian = inifile.BigEndian;
                Environment.CurrentDirectory = Path.Combine(Environment.CurrentDirectory, Path.GetDirectoryName(datafilename));
                if (inifile.Compressed)
                {
                    datafile = FraGag.Compression.Prs.Decompress(datafile);
                }
                uint imageBase = HelperFunctions.SetupEXE(ref datafile) ?? inifile.ImageBase.Value;
                if (Path.GetExtension(datafilename).Equals(".rel", StringComparison.OrdinalIgnoreCase))
                {
                    HelperFunctions.FixRELPointers(datafile);
                }
                bool            SA2      = inifile.Game == Game.SA2 | inifile.Game == Game.SA2B;
                ModelFormat     modelfmt = 0;
                LandTableFormat landfmt  = 0;
                switch (inifile.Game)
                {
                case Game.SA1:
                    modelfmt = ModelFormat.Basic;
                    landfmt  = LandTableFormat.SA1;
                    break;

                case Game.SADX:
                    modelfmt = ModelFormat.BasicDX;
                    landfmt  = LandTableFormat.SADX;
                    break;

                case Game.SA2:
                case Game.SA2B:
                    modelfmt = ModelFormat.Chunk;
                    landfmt  = LandTableFormat.SA2;
                    break;
                }
                int itemcount = 0;
                Dictionary <string, MasterObjectListEntry>     masterobjlist = new Dictionary <string, MasterObjectListEntry>();
                Dictionary <string, Dictionary <string, int> > objnamecounts = new Dictionary <string, Dictionary <string, int> >();
                Stopwatch timer = new Stopwatch();
                timer.Start();
                foreach (KeyValuePair <string, SA_Tools.FileInfo> item in inifile.Files)
                {
                    if (string.IsNullOrEmpty(item.Key))
                    {
                        continue;
                    }
                    string                      filedesc         = item.Key;
                    SA_Tools.FileInfo           data             = item.Value;
                    Dictionary <string, string> customProperties = data.CustomProperties;
                    string                      type             = data.Type;
                    int  address = data.Address;
                    bool nohash  = false;

                    string fileOutputPath = string.Concat(projectFolderName, data.Filename);
                    Console.WriteLine(item.Key + ": " + data.Address.ToString("X") + " → " + fileOutputPath);
                    Directory.CreateDirectory(Path.GetDirectoryName(fileOutputPath));
                    switch (type)
                    {
                    case "landtable":
                        new LandTable(datafile, address, imageBase, landfmt)
                        {
                            Description = item.Key
                        }.SaveToFile(fileOutputPath, landfmt);
                        break;

                    case "model":
                    {
                        NJS_OBJECT mdl     = new NJS_OBJECT(datafile, address, imageBase, modelfmt, new Dictionary <int, Attach>());
                        string[]   mdlanis = new string[0];
                        if (customProperties.ContainsKey("animations"))
                        {
                            mdlanis = customProperties["animations"].Split(',');
                        }
                        string[] mdlmorphs = new string[0];
                        if (customProperties.ContainsKey("morphs"))
                        {
                            mdlmorphs = customProperties["morphs"].Split(',');
                        }
                        ModelFile.CreateFile(fileOutputPath, mdl, mdlanis, null, item.Key, null, modelfmt);
                    }
                    break;

                    case "basicmodel":
                    {
                        NJS_OBJECT mdl     = new NJS_OBJECT(datafile, address, imageBase, ModelFormat.Basic, new Dictionary <int, Attach>());
                        string[]   mdlanis = new string[0];
                        if (customProperties.ContainsKey("animations"))
                        {
                            mdlanis = customProperties["animations"].Split(',');
                        }
                        string[] mdlmorphs = new string[0];
                        if (customProperties.ContainsKey("morphs"))
                        {
                            mdlmorphs = customProperties["morphs"].Split(',');
                        }
                        ModelFile.CreateFile(fileOutputPath, mdl, mdlanis, null, item.Key, null, ModelFormat.Basic);
                    }
                    break;

                    case "basicdxmodel":
                    {
                        NJS_OBJECT mdl     = new NJS_OBJECT(datafile, address, imageBase, ModelFormat.BasicDX, new Dictionary <int, Attach>());
                        string[]   mdlanis = new string[0];
                        if (customProperties.ContainsKey("animations"))
                        {
                            mdlanis = customProperties["animations"].Split(',');
                        }
                        string[] mdlmorphs = new string[0];
                        if (customProperties.ContainsKey("morphs"))
                        {
                            mdlmorphs = customProperties["morphs"].Split(',');
                        }
                        ModelFile.CreateFile(fileOutputPath, mdl, mdlanis, null, item.Key, null, ModelFormat.BasicDX);
                    }
                    break;

                    case "chunkmodel":
                    {
                        NJS_OBJECT mdl     = new NJS_OBJECT(datafile, address, imageBase, ModelFormat.Chunk, new Dictionary <int, Attach>());
                        string[]   mdlanis = new string[0];
                        if (customProperties.ContainsKey("animations"))
                        {
                            mdlanis = customProperties["animations"].Split(',');
                        }
                        string[] mdlmorphs = new string[0];
                        if (customProperties.ContainsKey("morphs"))
                        {
                            mdlmorphs = customProperties["morphs"].Split(',');
                        }
                        ModelFile.CreateFile(fileOutputPath, mdl, mdlanis, null, item.Key, null, ModelFormat.Chunk);
                    }
                    break;

                    case "gcmodel":
                    {
                        NJS_OBJECT mdl     = new NJS_OBJECT(datafile, address, imageBase, ModelFormat.GC, new Dictionary <int, Attach>());
                        string[]   mdlanis = new string[0];
                        if (customProperties.ContainsKey("animations"))
                        {
                            mdlanis = customProperties["animations"].Split(',');
                        }
                        string[] mdlmorphs = new string[0];
                        if (customProperties.ContainsKey("morphs"))
                        {
                            mdlmorphs = customProperties["morphs"].Split(',');
                        }
                        ModelFile.CreateFile(fileOutputPath, mdl, mdlanis, null, item.Key, null, ModelFormat.GC);
                    }
                    break;

                    case "action":
                    {
                        NJS_ACTION ani = new NJS_ACTION(datafile, address, imageBase, modelfmt, new Dictionary <int, Attach>());
                        ani.Animation.Name = filedesc;
                        ani.Animation.Save(fileOutputPath);
                    }
                    break;

                    case "animation":
                        new NJS_MOTION(datafile, address, imageBase, int.Parse(customProperties["numparts"], NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite, NumberFormatInfo.InvariantInfo))
                        {
                            Name = filedesc
                        }
                        .Save(fileOutputPath);
                        break;

                    case "objlist":
                    {
                        ObjectListEntry[] objs = ObjectList.Load(datafile, address, imageBase, SA2);
                        if (inifile.MasterObjectList != null)
                        {
                            foreach (ObjectListEntry obj in objs)
                            {
                                if (!masterobjlist.ContainsKey(obj.CodeString))
                                {
                                    masterobjlist.Add(obj.CodeString, new MasterObjectListEntry(obj));
                                }
                                if (!objnamecounts.ContainsKey(obj.CodeString))
                                {
                                    objnamecounts.Add(obj.CodeString, new Dictionary <string, int>()
                                        {
                                            { obj.Name, 1 }
                                        });
                                }
                                else if (!objnamecounts[obj.CodeString].ContainsKey(obj.Name))
                                {
                                    objnamecounts[obj.CodeString].Add(obj.Name, 1);
                                }
                                else
                                {
                                    objnamecounts[obj.CodeString][obj.Name]++;
                                }
                            }
                        }
                        objs.Save(fileOutputPath);
                    }
                    break;

                    case "startpos":
                        if (SA2)
                        {
                            SA2StartPosList.Load(datafile, address).Save(fileOutputPath);
                        }
                        else
                        {
                            SA1StartPosList.Load(datafile, address).Save(fileOutputPath);
                        }
                        break;

                    case "texlist":
                        TextureList.Load(datafile, address, imageBase).Save(fileOutputPath);
                        break;

                    case "leveltexlist":
                        new LevelTextureList(datafile, address, imageBase).Save(fileOutputPath);
                        break;

                    case "triallevellist":
                        TrialLevelList.Save(TrialLevelList.Load(datafile, address, imageBase), fileOutputPath);
                        break;

                    case "bosslevellist":
                        BossLevelList.Save(BossLevelList.Load(datafile, address), fileOutputPath);
                        break;

                    case "fieldstartpos":
                        FieldStartPosList.Load(datafile, address).Save(fileOutputPath);
                        break;

                    case "soundtestlist":
                        SoundTestList.Load(datafile, address, imageBase).Save(fileOutputPath);
                        break;

                    case "musiclist":
                    {
                        int muscnt = int.Parse(customProperties["length"], NumberStyles.Integer, NumberFormatInfo.InvariantInfo);
                        MusicList.Load(datafile, address, imageBase, muscnt).Save(fileOutputPath);
                    }
                    break;

                    case "soundlist":
                        SoundList.Load(datafile, address, imageBase).Save(fileOutputPath);
                        break;

                    case "stringarray":
                    {
                        int       cnt  = int.Parse(customProperties["length"], NumberStyles.Integer, NumberFormatInfo.InvariantInfo);
                        Languages lang = Languages.Japanese;
                        if (data.CustomProperties.ContainsKey("language"))
                        {
                            lang = (Languages)Enum.Parse(typeof(Languages), data.CustomProperties["language"], true);
                        }
                        StringArray.Load(datafile, address, imageBase, cnt, lang).Save(fileOutputPath);
                    }
                    break;

                    case "nextlevellist":
                        NextLevelList.Load(datafile, address).Save(fileOutputPath);
                        break;

                    case "cutscenetext":
                    {
                        int cnt = int.Parse(customProperties["length"], NumberStyles.Integer, NumberFormatInfo.InvariantInfo);
                        new CutsceneText(datafile, address, imageBase, cnt).Save(fileOutputPath, out string[] hashes);
                        data.MD5Hash = string.Join(",", hashes);
                        nohash       = true;
                    }
                    break;

                    case "recapscreen":
                    {
                        int cnt = int.Parse(customProperties["length"], NumberStyles.Integer, NumberFormatInfo.InvariantInfo);
                        RecapScreenList.Load(datafile, address, imageBase, cnt).Save(fileOutputPath, out string[][] hashes);
                        string[] hash2 = new string[hashes.Length];
                        for (int i = 0; i < hashes.Length; i++)
                        {
                            hash2[i] = string.Join(",", hashes[i]);
                        }
                        data.MD5Hash = string.Join(":", hash2);
                        nohash       = true;
                    }
                    break;

                    case "npctext":
                    {
                        int cnt = int.Parse(customProperties["length"], NumberStyles.Integer, NumberFormatInfo.InvariantInfo);
                        NPCTextList.Load(datafile, address, imageBase, cnt).Save(fileOutputPath, out string[][] hashes);
                        string[] hash2 = new string[hashes.Length];
                        for (int i = 0; i < hashes.Length; i++)
                        {
                            hash2[i] = string.Join(",", hashes[i]);
                        }
                        data.MD5Hash = string.Join(":", hash2);
                        nohash       = true;
                    }
                    break;

                    case "levelclearflags":
                        LevelClearFlagList.Save(LevelClearFlagList.Load(datafile, address), fileOutputPath);
                        break;

                    case "deathzone":
                    {
                        List <DeathZoneFlags> flags = new List <DeathZoneFlags>();
                        string        path          = Path.GetDirectoryName(fileOutputPath);
                        List <string> hashes        = new List <string>();
                        int           num           = 0;
                        while (ByteConverter.ToUInt32(datafile, address + 4) != 0)
                        {
                            flags.Add(new DeathZoneFlags(datafile, address));
                            string file = Path.Combine(path, num++.ToString(NumberFormatInfo.InvariantInfo) + (modelfmt == ModelFormat.Chunk ? ".sa2mdl" : ".sa1mdl"));
                            ModelFile.CreateFile(file, new NJS_OBJECT(datafile, datafile.GetPointer(address + 4, imageBase), imageBase, modelfmt, new Dictionary <int, Attach>()), null, null, null, null, modelfmt);
                            hashes.Add(HelperFunctions.FileHash(file));
                            address += 8;
                        }
                        flags.ToArray().Save(fileOutputPath);
                        hashes.Insert(0, HelperFunctions.FileHash(fileOutputPath));
                        data.MD5Hash = string.Join(",", hashes.ToArray());
                        nohash       = true;
                    }
                    break;

                    case "skyboxscale":
                    {
                        int cnt = int.Parse(customProperties["count"], NumberStyles.Integer, NumberFormatInfo.InvariantInfo);
                        SkyboxScaleList.Load(datafile, address, imageBase, cnt).Save(fileOutputPath);
                    }
                    break;

                    case "stageselectlist":
                    {
                        int cnt = int.Parse(customProperties["count"], NumberStyles.Integer, NumberFormatInfo.InvariantInfo);
                        StageSelectLevelList.Load(datafile, address, cnt).Save(fileOutputPath);
                    }
                    break;

                    case "levelrankscores":
                        LevelRankScoresList.Load(datafile, address).Save(fileOutputPath);
                        break;

                    case "levelranktimes":
                        LevelRankTimesList.Load(datafile, address).Save(fileOutputPath);
                        break;

                    case "endpos":
                        SA2EndPosList.Load(datafile, address).Save(fileOutputPath);
                        break;

                    case "animationlist":
                    {
                        int cnt = int.Parse(customProperties["count"], NumberStyles.Integer, NumberFormatInfo.InvariantInfo);
                        SA2AnimationInfoList.Load(datafile, address, cnt).Save(fileOutputPath);
                    }
                    break;

                    case "levelpathlist":
                    {
                        List <string> hashes = new List <string>();
                        ushort        lvlnum = (ushort)ByteConverter.ToUInt32(datafile, address);
                        while (lvlnum != 0xFFFF)
                        {
                            int ptr = ByteConverter.ToInt32(datafile, address + 4);
                            if (ptr != 0)
                            {
                                ptr = (int)((uint)ptr - imageBase);
                                SA1LevelAct level  = new SA1LevelAct(lvlnum);
                                string      lvldir = Path.Combine(fileOutputPath, level.ToString());
                                PathList.Load(datafile, ptr, imageBase).Save(lvldir, out string[] lvlhashes);
                                hashes.Add(level.ToString() + ":" + string.Join(",", lvlhashes));
                            }
                            address += 8;
                            lvlnum   = (ushort)ByteConverter.ToUInt32(datafile, address);
                        }
                        data.MD5Hash = string.Join("|", hashes.ToArray());
                        nohash       = true;
                    }
                    break;

                    case "pathlist":
                    {
                        PathList.Load(datafile, address, imageBase).Save(fileOutputPath, out string[] hashes);
                        data.MD5Hash = string.Join(",", hashes.ToArray());
                        nohash       = true;
                    }
                    break;

                    case "stagelightdatalist":
                        SA1StageLightDataList.Load(datafile, address).Save(fileOutputPath);
                        break;

                    case "weldlist":
                        WeldList.Load(datafile, address, imageBase).Save(fileOutputPath);
                        break;

                    case "bmitemattrlist":
                        BlackMarketItemAttributesList.Load(datafile, address, imageBase).Save(fileOutputPath);
                        break;

                    case "creditstextlist":
                        CreditsTextList.Load(datafile, address, imageBase).Save(fileOutputPath);
                        break;

                    case "animindexlist":
                    {
                        Directory.CreateDirectory(fileOutputPath);
                        List <string> hashes = new List <string>();
                        int           i      = ByteConverter.ToInt16(datafile, address);
                        while (i != -1)
                        {
                            new NJS_MOTION(datafile, datafile.GetPointer(address + 4, imageBase), imageBase, ByteConverter.ToInt16(datafile, address + 2))
                            .Save(fileOutputPath + "/" + i.ToString(NumberFormatInfo.InvariantInfo) + ".saanim");
                            hashes.Add(i.ToString(NumberFormatInfo.InvariantInfo) + ":" + HelperFunctions.FileHash(fileOutputPath + "/" + i.ToString(NumberFormatInfo.InvariantInfo) + ".saanim"));
                            address += 8;
                            i        = ByteConverter.ToInt16(datafile, address);
                        }
                        data.MD5Hash = string.Join("|", hashes.ToArray());
                        nohash       = true;
                    }
                    break;

                    case "storysequence":
                        SA2StoryList.Load(datafile, address).Save(fileOutputPath);
                        break;

                    default:                             // raw binary
                    {
                        byte[] bin = new byte[int.Parse(customProperties["size"], NumberStyles.HexNumber)];
                        Array.Copy(datafile, address, bin, 0, bin.Length);
                        File.WriteAllBytes(fileOutputPath, bin);
                    }
                    break;
                    }
                    if (!nohash)
                    {
                        data.MD5Hash = HelperFunctions.FileHash(fileOutputPath);
                    }
                    itemcount++;
                }
                if (inifile.MasterObjectList != null)
                {
                    foreach (KeyValuePair <string, MasterObjectListEntry> obj in masterobjlist)
                    {
                        KeyValuePair <string, int> name = new KeyValuePair <string, int>();
                        foreach (KeyValuePair <string, int> it in objnamecounts[obj.Key])
                        {
                            if (it.Value > name.Value)
                            {
                                name = it;
                            }
                        }
                        obj.Value.Name  = name.Key;
                        obj.Value.Names = objnamecounts[obj.Key].Select((it) => it.Key).ToArray();
                    }

                    string masterObjectListOutputPath = string.Concat(projectFolderName, inifile.MasterObjectList);

                    IniSerializer.Serialize(masterobjlist, masterObjectListOutputPath);
                }
                IniSerializer.Serialize(inifile, Path.Combine(projectFolderName, Path.GetFileNameWithoutExtension(datafilename) + "_data.ini"));
                timer.Stop();
                Console.WriteLine("Split " + itemcount + " items in " + timer.Elapsed.TotalSeconds + " seconds.");
                Console.WriteLine();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine(e.StackTrace);
                Console.WriteLine("Press any key to exit.");
                Console.ReadLine();
                return((int)SplitERRORVALUE.UnhandledException);
            }

            return((int)SplitERRORVALUE.Success);
        }
 public ContentModel(Engine engine, ModelVariantIdentifier variant, ModelFile file, ModelQuality quality)
     : this(engine, variant, file.GetModelDefinition(), quality)
 {
 }
예제 #6
0
        static void Main(string[] args)
        {
            Queue <string> argq = new Queue <string>(args);
            string         mdlfilename;

            if (argq.Count > 0)
            {
                mdlfilename = argq.Dequeue();
                Console.WriteLine("New Model File: {0}", mdlfilename);
            }
            else
            {
                Console.Write("New Model File: ");
                mdlfilename = Console.ReadLine().Trim('"');
            }
            ModelFile model = new ModelFile(mdlfilename);

            NJS_OBJECT[] objects = model.Model.GetObjects();
            string       repmdlfilename;

            if (argq.Count > 0)
            {
                repmdlfilename = argq.Dequeue();
                Console.WriteLine("Old Model File: {0}", repmdlfilename);
            }
            else
            {
                Console.Write("Old Model File: ");
                repmdlfilename = Console.ReadLine().Trim('"');
            }
            ModelFile repmodel = new ModelFile(repmdlfilename);

            NJS_OBJECT[] repobjects = repmodel.Model.GetObjects();
            if (model.Format != repmodel.Format)
            {
                Console.WriteLine("Format mismatch between files! Most data will be unable to be relabeled.");
            }
            if (objects.Length != repobjects.Length)
            {
                Console.WriteLine("Models have different structures, the game may crash.");
            }
            for (int i = 0; i < Math.Min(objects.Length, repobjects.Length); i++)
            {
                objects[i].Name = repobjects[i].Name;
                if (objects[i].Attach != null && repobjects[i].Attach != null)
                {
                    objects[i].Attach.Name = repobjects[i].Attach.Name;
                    if (objects[i].Attach is BasicAttach && repobjects[i].Attach is BasicAttach)
                    {
                        BasicAttach attach    = (BasicAttach)objects[i].Attach;
                        BasicAttach repattach = (BasicAttach)repobjects[i].Attach;
                        attach.VertexName = repattach.VertexName;
                        if (repattach.NormalName != null)
                        {
                            attach.NormalName = repattach.NormalName;
                        }
                        if (repattach.MaterialName != null)
                        {
                            attach.MaterialName = repattach.MaterialName;
                        }
                        attach.MeshName = repattach.MeshName;
                        for (int j = 0; j < Math.Min(attach.Mesh.Count, repattach.Mesh.Count); j++)
                        {
                            attach.Mesh[j].PolyName = repattach.Mesh[j].PolyName;
                            if (repattach.Mesh[j].PolyNormalName != null)
                            {
                                attach.Mesh[j].PolyNormalName = repattach.Mesh[j].PolyNormalName;
                            }
                            if (repattach.Mesh[j].UVName != null)
                            {
                                attach.Mesh[j].UVName = repattach.Mesh[j].UVName;
                            }
                            if (repattach.Mesh[j].VColorName != null)
                            {
                                attach.Mesh[j].VColorName = repattach.Mesh[j].VColorName;
                            }
                        }
                    }
                    else if (objects[i].Attach is ChunkAttach && repobjects[i].Attach is ChunkAttach)
                    {
                        ChunkAttach attach    = (ChunkAttach)objects[i].Attach;
                        ChunkAttach repattach = (ChunkAttach)repobjects[i].Attach;
                        if (repattach.VertexName != null)
                        {
                            attach.VertexName = repattach.VertexName;
                        }
                        if (repattach.PolyName != null)
                        {
                            attach.PolyName = repattach.PolyName;
                        }
                    }
                }
            }
            model.SaveToFile(repmdlfilename);
        }
예제 #7
0
        public static int SplitDLLFile(string datafilename, string inifilename, string projectFolderName)
        {
#if !DEBUG
            try
#endif
            {
                byte[]  datafile  = File.ReadAllBytes(datafilename);
                IniData inifile   = IniSerializer.Deserialize <IniData>(inifilename);
                uint    imageBase = HelperFunctions.SetupEXE(ref datafile).Value;
                Dictionary <string, int> exports;
                {
                    int      ptr               = BitConverter.ToInt32(datafile, BitConverter.ToInt32(datafile, 0x3c) + 4 + 20 + 96);
                    GCHandle handle            = GCHandle.Alloc(datafile, GCHandleType.Pinned);
                    IMAGE_EXPORT_DIRECTORY dir = (IMAGE_EXPORT_DIRECTORY)Marshal.PtrToStructure(
                        Marshal.UnsafeAddrOfPinnedArrayElement(datafile, ptr), typeof(IMAGE_EXPORT_DIRECTORY));
                    handle.Free();
                    exports = new Dictionary <string, int>(dir.NumberOfFunctions);
                    int nameaddr = dir.AddressOfNames;
                    int ordaddr  = dir.AddressOfNameOrdinals;
                    for (int i = 0; i < dir.NumberOfNames; i++)
                    {
                        string name = datafile.GetCString(BitConverter.ToInt32(datafile, nameaddr),
                                                          System.Text.Encoding.ASCII);
                        int addr = BitConverter.ToInt32(datafile,
                                                        dir.AddressOfFunctions + (BitConverter.ToInt16(datafile, ordaddr) * 4));
                        exports.Add(name, addr);
                        nameaddr += 4;
                        ordaddr  += 2;
                    }
                }
                ModelFormat     modelfmt = 0;
                LandTableFormat landfmt  = 0;
                string          modelext = null;
                string          landext  = null;
                switch (inifile.Game)
                {
                case Game.SADX:
                    modelfmt = ModelFormat.BasicDX;
                    landfmt  = LandTableFormat.SADX;
                    modelext = ".sa1mdl";
                    landext  = ".sa1lvl";
                    break;

                case Game.SA2B:
                    modelfmt = ModelFormat.Chunk;
                    landfmt  = LandTableFormat.SA2;
                    modelext = ".sa2mdl";
                    landext  = ".sa2lvl";
                    break;
                }
                int                       itemcount = 0;
                List <string>             labels    = new List <string>();
                ModelAnimationsDictionary models    = new ModelAnimationsDictionary();
                DllIniData                output    = new DllIniData()
                {
                    Name = inifile.ModuleName,
                    Game = inifile.Game
                };
                Stopwatch timer = new Stopwatch();
                timer.Start();
                foreach (KeyValuePair <string, FileInfo> item in inifile.Files)
                {
                    if (string.IsNullOrEmpty(item.Key))
                    {
                        continue;
                    }
                    FileInfo data = item.Value;
                    string   type = data.Type;
                    string   name = item.Key;
                    output.Exports[name] = type;
                    int address = exports[name];

                    string fileOutputPath = "";
                    if (data.Filename != null)
                    {
                        fileOutputPath = string.Concat(projectFolderName, data.Filename);

                        Console.WriteLine(name + " -> " + fileOutputPath);
                        Directory.CreateDirectory(Path.GetDirectoryName(fileOutputPath));
                    }
                    else
                    {
                        Console.WriteLine(name);
                    }
                    switch (type)
                    {
                    case "landtable":
                    {
                        LandTable land = new LandTable(datafile, address, imageBase, landfmt)
                        {
                            Description = name
                        };
                        DllItemInfo info = new DllItemInfo()
                        {
                            Export = name,
                            Label  = land.Name
                        };
                        output.Items.Add(info);
                        if (!labels.Contains(land.Name))
                        {
                            land.SaveToFile(fileOutputPath, landfmt);
                            output.Files[data.Filename] = new FileTypeHash("landtable", HelperFunctions.FileHash(fileOutputPath));
                            labels.AddRange(land.GetLabels());
                        }
                    }
                    break;

                    case "battlelandtable":
                    {
                        LandTable land = new LandTable(datafile, address, imageBase, LandTableFormat.SA2B)
                        {
                            Description = name
                        };
                        DllItemInfo info = new DllItemInfo()
                        {
                            Export = name,
                            Label  = land.Name
                        };
                        output.Items.Add(info);
                        if (!labels.Contains(land.Name))
                        {
                            land.SaveToFile(fileOutputPath, LandTableFormat.SA2B);
                            output.Files[data.Filename] = new FileTypeHash("landtable", HelperFunctions.FileHash(fileOutputPath));
                            labels.AddRange(land.GetLabels());
                        }
                    }
                    break;

                    case "landtablearray":
                        for (int i = 0; i < data.Length; i++)
                        {
                            int ptr = BitConverter.ToInt32(datafile, address);
                            if (ptr != 0)
                            {
                                ptr = (int)(ptr - imageBase);
                                string    idx  = name + "[" + i.ToString(NumberFormatInfo.InvariantInfo) + "]";
                                LandTable land = new LandTable(datafile, ptr, imageBase, landfmt)
                                {
                                    Description = idx
                                };
                                DllItemInfo info = new DllItemInfo()
                                {
                                    Export = name,
                                    Index  = i,
                                    Label  = land.Name
                                };
                                output.Items.Add(info);
                                if (!labels.Contains(land.Name))
                                {
                                    string outputFN = Path.Combine(fileOutputPath, i.ToString(NumberFormatInfo.InvariantInfo) + landext);
                                    string fileName = Path.Combine(data.Filename, i.ToString(NumberFormatInfo.InvariantInfo) + landext);

                                    land.SaveToFile(outputFN, landfmt);
                                    output.Files[fileName] = new FileTypeHash("landtable", HelperFunctions.FileHash(outputFN));
                                    labels.AddRange(land.GetLabels());
                                }
                            }
                            address += 4;
                        }
                        break;

                    case "model":
                    {
                        NJS_OBJECT  mdl  = new NJS_OBJECT(datafile, address, imageBase, modelfmt, new Dictionary <int, Attach>());
                        DllItemInfo info = new DllItemInfo()
                        {
                            Export = name,
                            Label  = mdl.Name
                        };
                        output.Items.Add(info);
                        if (!labels.Contains(mdl.Name))
                        {
                            models.Add(new ModelAnimations(data.Filename, name, mdl, modelfmt));
                            labels.AddRange(mdl.GetLabels());
                        }
                    }
                    break;

                    case "morph":
                    {
                        BasicAttach dummy = new BasicAttach(datafile, address, imageBase, modelfmt == ModelFormat.BasicDX);
                        NJS_OBJECT  mdl   = new NJS_OBJECT()
                        {
                            Attach = dummy
                        };
                        DllItemInfo info = new DllItemInfo()
                        {
                            Export = name,
                            Label  = dummy.Name
                        };
                        output.Items.Add(info);
                        if (!labels.Contains(dummy.Name))
                        {
                            models.Add(new ModelAnimations(data.Filename, name, mdl, modelfmt));
                            labels.AddRange(mdl.GetLabels());
                        }
                    }
                    break;

                    case "modelarray":
                        for (int i = 0; i < data.Length; i++)
                        {
                            int ptr = BitConverter.ToInt32(datafile, address);
                            if (ptr != 0)
                            {
                                ptr = (int)(ptr - imageBase);
                                NJS_OBJECT  mdl  = new NJS_OBJECT(datafile, ptr, imageBase, modelfmt, new Dictionary <int, Attach>());
                                string      idx  = name + "[" + i.ToString(NumberFormatInfo.InvariantInfo) + "]";
                                DllItemInfo info = new DllItemInfo()
                                {
                                    Export = name,
                                    Index  = i,
                                    Label  = mdl.Name
                                };
                                output.Items.Add(info);
                                if (!labels.Contains(mdl.Name))
                                {
                                    string fn = Path.Combine(data.Filename, i.ToString(NumberFormatInfo.InvariantInfo) + modelext);
                                    models.Add(new ModelAnimations(fn, idx, mdl, modelfmt));
                                    labels.AddRange(mdl.GetLabels());
                                }
                            }
                            address += 4;
                        }
                        break;

                    case "modelsarray":
                        for (int i = 0; i < data.Length; i++)
                        {
                            int ptr = BitConverter.ToInt32(datafile, address);
                            if (ptr != 0)
                            {
                                ptr = (int)(ptr - imageBase);
                                BasicAttach dummy = new BasicAttach(datafile, ptr, imageBase, modelfmt == ModelFormat.BasicDX);
                                NJS_OBJECT  mdl   = new NJS_OBJECT()
                                {
                                    Attach = dummy
                                };
                                string      idx  = name + "[" + i.ToString(NumberFormatInfo.InvariantInfo) + "]";
                                DllItemInfo info = new DllItemInfo()
                                {
                                    Export = name,
                                    Index  = i,
                                    Label  = dummy.Name
                                };
                                output.Items.Add(info);
                                if (!labels.Contains(dummy.Name))
                                {
                                    string fn = Path.Combine(data.Filename, i.ToString(NumberFormatInfo.InvariantInfo) + modelext);
                                    models.Add(new ModelAnimations(fn, idx, mdl, ModelFormat.BasicDX));
                                    labels.AddRange(mdl.GetLabels());
                                }
                            }
                            address += 4;
                        }
                        break;

                    case "basicmodel":
                    {
                        NJS_OBJECT  mdl  = new NJS_OBJECT(datafile, address, imageBase, ModelFormat.Basic, new Dictionary <int, Attach>());
                        DllItemInfo info = new DllItemInfo()
                        {
                            Export = name,
                            Label  = mdl.Name
                        };
                        output.Items.Add(info);
                        if (!labels.Contains(mdl.Name))
                        {
                            models.Add(new ModelAnimations(data.Filename, name, mdl, ModelFormat.Basic));
                            labels.AddRange(mdl.GetLabels());
                        }
                    }
                    break;

                    case "basicmodelarray":
                        for (int i = 0; i < data.Length; i++)
                        {
                            int ptr = BitConverter.ToInt32(datafile, address);
                            if (ptr != 0)
                            {
                                ptr = (int)(ptr - imageBase);
                                NJS_OBJECT  mdl  = new NJS_OBJECT(datafile, ptr, imageBase, ModelFormat.Basic, new Dictionary <int, Attach>());
                                string      idx  = name + "[" + i.ToString(NumberFormatInfo.InvariantInfo) + "]";
                                DllItemInfo info = new DllItemInfo()
                                {
                                    Export = name,
                                    Index  = i,
                                    Label  = mdl.Name
                                };
                                output.Items.Add(info);
                                if (!labels.Contains(mdl.Name))
                                {
                                    string fn = Path.Combine(data.Filename, i.ToString(NumberFormatInfo.InvariantInfo) + ".sa1mdl");
                                    models.Add(new ModelAnimations(fn, idx, mdl, ModelFormat.Basic));
                                    labels.AddRange(mdl.GetLabels());
                                }
                            }
                            address += 4;
                        }
                        break;

                    case "basicdxmodel":
                    {
                        NJS_OBJECT  mdl  = new NJS_OBJECT(datafile, address, imageBase, ModelFormat.BasicDX, new Dictionary <int, Attach>());
                        DllItemInfo info = new DllItemInfo()
                        {
                            Export = name,
                            Label  = mdl.Name
                        };
                        output.Items.Add(info);
                        if (!labels.Contains(mdl.Name))
                        {
                            models.Add(new ModelAnimations(data.Filename, name, mdl, ModelFormat.BasicDX));
                            labels.AddRange(mdl.GetLabels());
                        }
                    }
                    break;

                    case "basicdxmodelarray":
                        for (int i = 0; i < data.Length; i++)
                        {
                            int ptr = BitConverter.ToInt32(datafile, address);
                            if (ptr != 0)
                            {
                                ptr = (int)(ptr - imageBase);
                                NJS_OBJECT  mdl  = new NJS_OBJECT(datafile, ptr, imageBase, ModelFormat.BasicDX, new Dictionary <int, Attach>());
                                string      idx  = name + "[" + i.ToString(NumberFormatInfo.InvariantInfo) + "]";
                                DllItemInfo info = new DllItemInfo()
                                {
                                    Export = name,
                                    Index  = i,
                                    Label  = mdl.Name
                                };
                                output.Items.Add(info);
                                if (!labels.Contains(mdl.Name))
                                {
                                    string fn = Path.Combine(data.Filename, i.ToString(NumberFormatInfo.InvariantInfo) + ".sa1mdl");
                                    models.Add(new ModelAnimations(fn, idx, mdl, ModelFormat.BasicDX));
                                    labels.AddRange(mdl.GetLabels());
                                }
                            }
                            address += 4;
                        }
                        break;

                    case "chunkmodel":
                    {
                        NJS_OBJECT  mdl  = new NJS_OBJECT(datafile, address, imageBase, ModelFormat.Chunk, new Dictionary <int, Attach>());
                        DllItemInfo info = new DllItemInfo()
                        {
                            Export = name,
                            Label  = mdl.Name
                        };
                        output.Items.Add(info);
                        if (!labels.Contains(mdl.Name))
                        {
                            models.Add(new ModelAnimations(data.Filename, name, mdl, ModelFormat.Chunk));
                            labels.AddRange(mdl.GetLabels());
                        }
                    }
                    break;

                    case "chunkmodelarray":
                        for (int i = 0; i < data.Length; i++)
                        {
                            int ptr = BitConverter.ToInt32(datafile, address);
                            if (ptr != 0)
                            {
                                ptr = (int)(ptr - imageBase);
                                NJS_OBJECT  mdl  = new NJS_OBJECT(datafile, ptr, imageBase, ModelFormat.Chunk, new Dictionary <int, Attach>());
                                string      idx  = name + "[" + i.ToString(NumberFormatInfo.InvariantInfo) + "]";
                                DllItemInfo info = new DllItemInfo()
                                {
                                    Export = name,
                                    Index  = i,
                                    Label  = mdl.Name
                                };
                                output.Items.Add(info);
                                if (!labels.Contains(mdl.Name))
                                {
                                    string fn = Path.Combine(data.Filename, i.ToString(NumberFormatInfo.InvariantInfo) + ".sa2mdl");
                                    models.Add(new ModelAnimations(fn, idx, mdl, ModelFormat.Chunk));
                                    labels.AddRange(mdl.GetLabels());
                                }
                            }
                            address += 4;
                        }
                        break;

                    case "actionarray":
                        for (int i = 0; i < data.Length; i++)
                        {
                            int ptr = BitConverter.ToInt32(datafile, address);
                            if (ptr != 0)
                            {
                                ptr = (int)(ptr - imageBase);
                                NJS_ACTION ani = new NJS_ACTION(datafile, ptr, imageBase, modelfmt, new Dictionary <int, Attach>());
                                string     idx = name + "[" + i.ToString(NumberFormatInfo.InvariantInfo) + "]";
                                ani.Animation.Name = item.Key + "_" + i;
                                DllItemInfo info = new DllItemInfo()
                                {
                                    Export = name,
                                    Index  = i,
                                    Label  = ani.Animation.Name,
                                    Field  = "motion"
                                };
                                output.Items.Add(info);
                                info = new DllItemInfo()
                                {
                                    Export = name,
                                    Index  = i,
                                    Label  = ani.Model.Name,
                                    Field  = "object"
                                };
                                output.Items.Add(info);
                                string outputFN = Path.Combine(fileOutputPath, i.ToString(NumberFormatInfo.InvariantInfo) + ".saanim");
                                string fn       = Path.Combine(data.Filename, i.ToString(NumberFormatInfo.InvariantInfo) + ".saanim");
                                ani.Animation.Save(outputFN);
                                output.Files[fn] = new FileTypeHash("animation", HelperFunctions.FileHash(outputFN));
                                if (models.Contains(ani.Model.Name))
                                {
                                    ModelAnimations           mdl = models[ani.Model.Name];
                                    System.Text.StringBuilder sb  = new System.Text.StringBuilder(260);
                                    PathRelativePathTo(sb, Path.GetFullPath(Path.Combine(projectFolderName, mdl.Filename)), 0, Path.GetFullPath(outputFN), 0);
                                    mdl.Animations.Add(sb.ToString());                                             // this is where the problem is
                                }
                                else
                                {
                                    string mfn           = Path.ChangeExtension(fn, modelext);
                                    string outputmfn     = Path.Combine(projectFolderName, mfn);
                                    string animationName = Path.GetFileName(outputFN);

                                    ModelFile.CreateFile(outputmfn, ani.Model, new[] { animationName }, null, idx + "->object",
                                                         null, modelfmt);
                                    output.Files[mfn] = new FileTypeHash("model", HelperFunctions.FileHash(outputmfn));
                                }
                            }
                            address += 4;
                        }
                        break;

                    case "texlist":
                        if (output.TexLists == null)
                        {
                            output.TexLists = new TexListContainer();
                        }
                        output.TexLists.Add((uint)(address + imageBase), new DllTexListInfo(name, null));
                        break;

                    case "texlistarray":
                        if (output.TexLists == null)
                        {
                            output.TexLists = new TexListContainer();
                        }
                        for (int i = 0; i < data.Length; i++)
                        {
                            uint ptr = BitConverter.ToUInt32(datafile, address);
                            if (ptr != 0 && !output.TexLists.ContainsKey(ptr))
                            {
                                output.TexLists.Add(ptr, new DllTexListInfo(name, i));
                            }
                            address += 4;
                        }
                        break;

                    case "animindexlist":
                    {
                        Directory.CreateDirectory(fileOutputPath);
                        List <string> hashes = new List <string>();
                        int           i      = ByteConverter.ToInt16(datafile, address);
                        while (i != -1)
                        {
                            new NJS_MOTION(datafile, datafile.GetPointer(address + 4, imageBase), imageBase, ByteConverter.ToInt16(datafile, address + 2))
                            .Save(fileOutputPath + "/" + i.ToString(NumberFormatInfo.InvariantInfo) + ".saanim");
                            hashes.Add(i.ToString(NumberFormatInfo.InvariantInfo) + ":" + HelperFunctions.FileHash(fileOutputPath + "/" + i.ToString(NumberFormatInfo.InvariantInfo) + ".saanim"));
                            address += 8;
                            i        = ByteConverter.ToInt16(datafile, address);
                        }
                        output.DataItems.Add(new DllDataItemInfo()
                            {
                                Type = type, Export = name, Filename = data.Filename, MD5Hash = string.Join("|", hashes.ToArray())
                            });
                    }
                    break;

                    case "charaobjectdatalist":
                    {
                        Directory.CreateDirectory(fileOutputPath);
                        List <CharaObjectData> result = new List <CharaObjectData>();
                        List <string>          hashes = new List <string>();
                        for (int i = 0; i < data.Length; i++)
                        {
                            string          chnm  = charaobjectnames[i];
                            CharaObjectData chara = new CharaObjectData();
                            NJS_OBJECT      model = new NJS_OBJECT(datafile, (int)(BitConverter.ToInt32(datafile, address) - imageBase), imageBase, ModelFormat.Chunk, new Dictionary <int, Attach>());
                            chara.MainModel = model.Name;
                            NJS_MOTION anim = new NJS_MOTION(datafile, (int)(BitConverter.ToInt32(datafile, address + 4) - imageBase), imageBase, model.CountAnimated());
                            chara.Animation1 = anim.Name;
                            anim.Save(Path.Combine(fileOutputPath, $"{chnm} Anim 1.saanim"));
                            hashes.Add($"{chnm} Anim 1.saanim:" + HelperFunctions.FileHash(Path.Combine(fileOutputPath, $"{chnm} Anim 1.saanim")));
                            anim             = new NJS_MOTION(datafile, (int)(BitConverter.ToInt32(datafile, address + 8) - imageBase), imageBase, model.CountAnimated());
                            chara.Animation2 = anim.Name;
                            anim.Save(Path.Combine(fileOutputPath, $"{chnm} Anim 2.saanim"));
                            hashes.Add($"{chnm} Anim 2.saanim:" + HelperFunctions.FileHash(Path.Combine(fileOutputPath, $"{chnm} Anim 2.saanim")));
                            anim             = new NJS_MOTION(datafile, (int)(BitConverter.ToInt32(datafile, address + 12) - imageBase), imageBase, model.CountAnimated());
                            chara.Animation3 = anim.Name;
                            anim.Save(Path.Combine(fileOutputPath, $"{chnm} Anim 3.saanim"));
                            hashes.Add($"{chnm} Anim 3.saanim:" + HelperFunctions.FileHash(Path.Combine(fileOutputPath, $"{chnm} Anim 3.saanim")));
                            ModelFile.CreateFile(Path.Combine(fileOutputPath, $"{chnm}.sa2mdl"), model, new[] { $"{chnm} Anim 1.saanim", $"{chnm} Anim 2.saanim", $"{chnm} Anim 3.saanim" }, null, null, null, ModelFormat.Chunk);
                            hashes.Add($"{chnm}.sa2mdl:" + HelperFunctions.FileHash(Path.Combine(fileOutputPath, $"{chnm}.sa2mdl")));
                            int ptr = BitConverter.ToInt32(datafile, address + 16);
                            if (ptr != 0)
                            {
                                model = new NJS_OBJECT(datafile, (int)(ptr - imageBase), imageBase, ModelFormat.Chunk, new Dictionary <int, Attach>());
                                chara.AccessoryModel      = model.Name;
                                chara.AccessoryAttachNode = "object_" + (BitConverter.ToInt32(datafile, address + 20) - imageBase).ToString("X8");
                                ModelFile.CreateFile(Path.Combine(fileOutputPath, $"{chnm} Accessory.sa2mdl"), model, null, null, null, null, ModelFormat.Chunk);
                                hashes.Add($"{chnm} Accessory.sa2mdl:" + HelperFunctions.FileHash(Path.Combine(fileOutputPath, $"{chnm} Accessory.sa2mdl")));
                            }
                            ptr = BitConverter.ToInt32(datafile, address + 24);
                            if (ptr != 0)
                            {
                                model                 = new NJS_OBJECT(datafile, (int)(ptr - imageBase), imageBase, ModelFormat.Chunk, new Dictionary <int, Attach>());
                                chara.SuperModel      = model.Name;
                                anim                  = new NJS_MOTION(datafile, (int)(BitConverter.ToInt32(datafile, address + 28) - imageBase), imageBase, model.CountAnimated());
                                chara.SuperAnimation1 = anim.Name;
                                anim.Save(Path.Combine(fileOutputPath, $"Super {chnm} Anim 1.saanim"));
                                hashes.Add($"Super {chnm} Anim 1.saanim:" + HelperFunctions.FileHash(Path.Combine(fileOutputPath, $"Super {chnm} Anim 1.saanim")));
                                anim = new NJS_MOTION(datafile, (int)(BitConverter.ToInt32(datafile, address + 32) - imageBase), imageBase, model.CountAnimated());
                                chara.SuperAnimation2 = anim.Name;
                                anim.Save(Path.Combine(fileOutputPath, $"Super {chnm} Anim 2.saanim"));
                                hashes.Add($"Super {chnm} Anim 2.saanim:" + HelperFunctions.FileHash(Path.Combine(fileOutputPath, $"Super {chnm} Anim 2.saanim")));
                                anim = new NJS_MOTION(datafile, (int)(BitConverter.ToInt32(datafile, address + 36) - imageBase), imageBase, model.CountAnimated());
                                chara.SuperAnimation3 = anim.Name;
                                anim.Save(Path.Combine(fileOutputPath, $"Super {chnm} Anim 3.saanim"));
                                hashes.Add($"Super {chnm} Anim 3.saanim:" + HelperFunctions.FileHash(Path.Combine(fileOutputPath, $"Super {chnm} Anim 3.saanim")));
                                ModelFile.CreateFile(Path.Combine(fileOutputPath, $"Super {chnm}.sa2mdl"), model, new[] { $"Super {chnm} Anim 1.saanim", $"Super {chnm} Anim 2.saanim", $"Super {chnm} Anim 3.saanim" }, null, null, null, ModelFormat.Chunk);
                                hashes.Add($"Super {chnm}.sa2mdl:" + HelperFunctions.FileHash(Path.Combine(fileOutputPath, $"Super {chnm}.sa2mdl")));
                            }
                            chara.Unknown1        = BitConverter.ToInt32(datafile, address + 40);
                            chara.Rating          = BitConverter.ToInt32(datafile, address + 44);
                            chara.DescriptionID   = BitConverter.ToInt32(datafile, address + 48);
                            chara.TextBackTexture = BitConverter.ToInt32(datafile, address + 52);
                            chara.Unknown5        = BitConverter.ToSingle(datafile, address + 56);
                            result.Add(chara);
                            address += 60;
                        }
                        IniSerializer.Serialize(result, Path.Combine(fileOutputPath, "info.ini"));
                        hashes.Add("info.ini:" + HelperFunctions.FileHash(Path.Combine(fileOutputPath, "info.ini")));
                        output.DataItems.Add(new DllDataItemInfo()
                            {
                                Type = type, Export = name, Filename = data.Filename, MD5Hash = string.Join("|", hashes.ToArray())
                            });
                    }
                    break;

                    case "kartspecialinfolist":
                    {
                        Directory.CreateDirectory(fileOutputPath);
                        List <KartSpecialInfo> result = new List <KartSpecialInfo>();
                        List <string>          hashes = new List <string>();
                        for (int i = 0; i < data.Length; i++)
                        {
                            KartSpecialInfo kart = new KartSpecialInfo
                            {
                                ID = ByteConverter.ToInt32(datafile, address)
                            };
                            NJS_OBJECT model = new NJS_OBJECT(datafile, (int)(BitConverter.ToInt32(datafile, address + 4) - imageBase), imageBase, ModelFormat.Chunk, new Dictionary <int, Attach>());
                            kart.Model = model.Name;
                            ModelFile.CreateFile(Path.Combine(fileOutputPath, $"{i}.sa2mdl"), model, null, null, null, null, ModelFormat.Chunk);
                            hashes.Add($"{i}.sa2mdl:" + HelperFunctions.FileHash(Path.Combine(fileOutputPath, $"{i}.sa2mdl")));
                            int ptr = BitConverter.ToInt32(datafile, address + 8);
                            if (ptr != 0)
                            {
                                model         = new NJS_OBJECT(datafile, (int)(ptr - imageBase), imageBase, ModelFormat.Chunk, new Dictionary <int, Attach>());
                                kart.LowModel = model.Name;
                                ModelFile.CreateFile(Path.Combine(fileOutputPath, $"{i} Low.sa2mdl"), model, null, null, null, null, ModelFormat.Chunk);
                                hashes.Add($"{i} Low.sa2mdl:" + HelperFunctions.FileHash(Path.Combine(fileOutputPath, $"{i} Low.sa2mdl")));
                            }
                            kart.TexList  = ByteConverter.ToUInt32(datafile, address + 12);
                            kart.Unknown1 = ByteConverter.ToInt32(datafile, address + 16);
                            kart.Unknown2 = ByteConverter.ToInt32(datafile, address + 20);
                            kart.Unknown3 = ByteConverter.ToInt32(datafile, address + 24);
                            result.Add(kart);
                            address += 0x1C;
                        }
                        IniSerializer.Serialize(result, Path.Combine(fileOutputPath, "info.ini"));
                        hashes.Add("info.ini:" + HelperFunctions.FileHash(Path.Combine(fileOutputPath, "info.ini")));
                        output.DataItems.Add(new DllDataItemInfo()
                            {
                                Type = type, Export = name, Filename = data.Filename, MD5Hash = string.Join("|", hashes.ToArray())
                            });
                    }
                    break;

                    case "chaomotiontable":
                    {
                        Directory.CreateDirectory(fileOutputPath);
                        List <ChaoMotionTableEntry> result = new List <ChaoMotionTableEntry>();
                        List <string>            hashes    = new List <string>();
                        int                      nodeCount = int.Parse(data.CustomProperties["nodecount"]);
                        Dictionary <int, string> mtns      = new Dictionary <int, string>();
                        for (int i = 0; i < data.Length; i++)
                        {
                            ChaoMotionTableEntry cmte = new ChaoMotionTableEntry();
                            int mtnaddr = (int)(ByteConverter.ToInt32(datafile, address) - imageBase);
                            if (!mtns.ContainsKey(mtnaddr))
                            {
                                NJS_MOTION motion = new NJS_MOTION(datafile, mtnaddr, imageBase, nodeCount, shortrot: true);
                                cmte.Motion = motion.Name;
                                mtns.Add(mtnaddr, motion.Name);
                                motion.Save(Path.Combine(fileOutputPath, $"{i}.saanim"));
                                hashes.Add($"{i}.saanim:" + HelperFunctions.FileHash(Path.Combine(fileOutputPath, $"{i}.saanim")));
                            }
                            else
                            {
                                cmte.Motion = mtns[mtnaddr];
                            }
                            cmte.Flag1        = ByteConverter.ToUInt16(datafile, address + 4);
                            cmte.Pose         = ByteConverter.ToUInt16(datafile, address + 6);
                            cmte.TransitionID = ByteConverter.ToInt32(datafile, address + 8);
                            cmte.Flag2        = ByteConverter.ToUInt32(datafile, address + 12);
                            cmte.StartFrame   = ByteConverter.ToSingle(datafile, address + 16);
                            cmte.EndFrame     = ByteConverter.ToSingle(datafile, address + 20);
                            cmte.PlaySpeed    = ByteConverter.ToSingle(datafile, address + 24);
                            result.Add(cmte);
                            address += 0x1C;
                        }
                        IniSerializer.Serialize(result, Path.Combine(fileOutputPath, "info.ini"));
                        hashes.Add("info.ini:" + HelperFunctions.FileHash(Path.Combine(fileOutputPath, "info.ini")));
                        output.DataItems.Add(new DllDataItemInfo()
                            {
                                Type = type, Export = name, Filename = data.Filename, MD5Hash = string.Join("|", hashes.ToArray())
                            });
                    }
                    break;
                    }
                    itemcount++;
                }
                foreach (ModelAnimations item in models)
                {
                    string modelOutputPath = string.Concat(projectFolderName, item.Filename);
                    //string modelOutputPath = item.Filename;

                    ModelFile.CreateFile(modelOutputPath, item.Model, item.Animations.ToArray(), null, item.Name, null, item.Format);
                    string type = "model";
                    switch (item.Format)
                    {
                    case ModelFormat.Basic:
                        type = "basicmodel";
                        break;

                    case ModelFormat.BasicDX:
                        type = "basicdxmodel";
                        break;

                    case ModelFormat.Chunk:
                        type = "chunkmodel";
                        break;
                    }
                    output.Files[item.Filename] = new FileTypeHash(type, HelperFunctions.FileHash(modelOutputPath));
                }
                IniSerializer.Serialize(output, Path.Combine(projectFolderName, Path.GetFileNameWithoutExtension(datafilename))
                                        + "_data.ini");
                timer.Stop();
                Console.WriteLine("Split " + itemcount + " items in " + timer.Elapsed.TotalSeconds + " seconds.");
                Console.WriteLine();
            }
#if !DEBUG
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine(e.StackTrace);
                Console.WriteLine("Press any key to exit.");
                Console.ReadLine();
                return((int)SA_Tools.Split.SplitERRORVALUE.UnhandledException);
            }
#endif
            return((int)SA_Tools.Split.SplitERRORVALUE.Success);
        }
예제 #8
0
        /// <summary>
        /// Lizenz hochladen Service für den Upload der Lizenz
        /// </summary>
        /// <exception cref="IO.Swagger.Client.ApiException">Thrown when fails to make API call</exception>
        /// <param name="adminEMailAdresse">adminEMailAdresse</param>
        /// <param name="uploadFile">uploadFile</param>
        /// <returns>Task of LicenseUploadResponseDTO</returns>
        public async System.Threading.Tasks.Task <LicenseUploadResponseDTO> V1LicenseUploadAsync(string adminEMailAdresse, ModelFile uploadFile)
        {
            ApiResponse <LicenseUploadResponseDTO> localVarResponse = await V1LicenseUploadAsyncWithHttpInfo(adminEMailAdresse, uploadFile);

            return(localVarResponse.Data);
        }
예제 #9
0
        /// <summary>
        /// Lizenz hochladen Service für den Upload der Lizenz
        /// </summary>
        /// <exception cref="IO.Swagger.Client.ApiException">Thrown when fails to make API call</exception>
        /// <param name="adminEMailAdresse">adminEMailAdresse</param>
        /// <param name="uploadFile">uploadFile</param>
        /// <returns>Task of ApiResponse (LicenseUploadResponseDTO)</returns>
        public async System.Threading.Tasks.Task <ApiResponse <LicenseUploadResponseDTO> > V1LicenseUploadAsyncWithHttpInfo(string adminEMailAdresse, ModelFile uploadFile)
        {
            // verify the required parameter 'adminEMailAdresse' is set
            if (adminEMailAdresse == null)
            {
                throw new ApiException(400, "Missing required parameter 'adminEMailAdresse' when calling LicenseApi->V1LicenseUpload");
            }
            // verify the required parameter 'uploadFile' is set
            if (uploadFile == null)
            {
                throw new ApiException(400, "Missing required parameter 'uploadFile' when calling LicenseApi->V1LicenseUpload");
            }

            var    localVarPath         = "/v1/license/upload";
            var    localVarPathParams   = new Dictionary <String, String>();
            var    localVarQueryParams  = new List <KeyValuePair <String, String> >();
            var    localVarHeaderParams = new Dictionary <String, String>(this.Configuration.DefaultHeader);
            var    localVarFormParams   = new Dictionary <String, String>();
            var    localVarFileParams   = new Dictionary <String, FileParameter>();
            Object localVarPostBody     = null;

            // to determine the Content-Type header
            String[] localVarHttpContentTypes = new String[] {
                "multipart/form-data"
            };
            String localVarHttpContentType = this.Configuration.ApiClient.SelectHeaderContentType(localVarHttpContentTypes);

            // to determine the Accept header
            String[] localVarHttpHeaderAccepts = new String[] {
                "application/json"
            };
            String localVarHttpHeaderAccept = this.Configuration.ApiClient.SelectHeaderAccept(localVarHttpHeaderAccepts);

            if (localVarHttpHeaderAccept != null)
            {
                localVarHeaderParams.Add("Accept", localVarHttpHeaderAccept);
            }

            if (adminEMailAdresse != null)
            {
                localVarQueryParams.AddRange(this.Configuration.ApiClient.ParameterToKeyValuePairs("", "adminEMailAdresse", adminEMailAdresse));                            // query parameter
            }
            if (uploadFile != null)
            {
                localVarFileParams.Add("uploadFile", this.Configuration.ApiClient.ParameterToFile("uploadFile", uploadFile.AbsoluteFile));
            }

            // authentication (bearerToken) required
            if (!String.IsNullOrEmpty(this.Configuration.GetApiKeyWithPrefix("Authorization")))
            {
                localVarHeaderParams["Authorization"] = this.Configuration.GetApiKeyWithPrefix("Authorization");
            }
            // authentication (oauth2) required
            // oauth required
            if (!String.IsNullOrEmpty(this.Configuration.AccessToken))
            {
                localVarHeaderParams["Authorization"] = "Bearer " + this.Configuration.AccessToken;
            }

            // make the HTTP request
            IRestResponse localVarResponse = (IRestResponse)await this.Configuration.ApiClient.CallApiAsync(localVarPath,
                                                                                                            Method.POST, localVarQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarFileParams,
                                                                                                            localVarPathParams, localVarHttpContentType);

            int localVarStatusCode = (int)localVarResponse.StatusCode;

            if (ExceptionFactory != null)
            {
                Exception exception = ExceptionFactory("V1LicenseUpload", localVarResponse);
                if (exception != null)
                {
                    throw exception;
                }
            }

            return(new ApiResponse <LicenseUploadResponseDTO>(localVarStatusCode,
                                                              localVarResponse.Headers.ToDictionary(x => x.Name, x => x.Value.ToString()),
                                                              (LicenseUploadResponseDTO)this.Configuration.ApiClient.Deserialize(localVarResponse, typeof(LicenseUploadResponseDTO))));
        }
예제 #10
0
        //private const string URL = "http://*****:*****@myirent.com";

                    HttpClient client = new HttpClient();
                    client.BaseAddress = new Uri(URL);

                    var myContent   = JsonConvert.SerializeObject(propertyData);
                    var buffer      = System.Text.Encoding.UTF8.GetBytes(myContent);
                    var byteContent = new ByteArrayContent(buffer);
                    byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");

                    var result   = client.PostAsync("", byteContent).Result;
                    var contents = result.Content.ReadAsStringAsync().Result;

                    success = true;
                }
            }
            catch (Exception any)
            {
                Console.Write(any.ToString());

                MailMessage mailMessage = new MailMessage();
                mailMessage.To.Add("*****@*****.**");
                mailMessage.From    = new MailAddress("*****@*****.**");
                mailMessage.Subject = "CoStar XML Feed - Error";
                mailMessage.Body    = any.ToString();

                SmtpClient smtp = new SmtpClient();
                smtp.Host = "smtp.myirent.com"; //Or Your SMTP Server Address
                smtp.Port = 587;
                smtp.UseDefaultCredentials = false;
                smtp.Credentials           = new System.Net.NetworkCredential
                                                 ("*****@*****.**", "iRent4Now!");
                smtp.Send(mailMessage);

                success = false;
            }
        }
예제 #11
0
        /// <summary>
        /// Lizenz hochladen Service für den Upload der Lizenz
        /// </summary>
        /// <exception cref="IO.Swagger.Client.ApiException">Thrown when fails to make API call</exception>
        /// <param name="adminEMailAdresse">adminEMailAdresse</param>
        /// <param name="uploadFile">uploadFile</param>
        /// <returns>LicenseUploadResponseDTO</returns>
        public LicenseUploadResponseDTO V1LicenseUpload(string adminEMailAdresse, ModelFile uploadFile)
        {
            ApiResponse <LicenseUploadResponseDTO> localVarResponse = V1LicenseUploadWithHttpInfo(adminEMailAdresse, uploadFile);

            return(localVarResponse.Data);
        }
예제 #12
0
        private void button2_Click(object sender, EventArgs e)
        {
            if (this.textBox3.Text != null && this.textBox3.Text.Trim() != "")
            {
                MessageBox.Show("該文件已經上傳請勿重複保存!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            if (this.textBox1.Text == null || this.textBox1.Text.Trim() == "")
            {
                MessageBox.Show("請選擇需要上傳的文件!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                this.button1.Focus();
                return;
            }
            if (this.textBox2.Text == null || this.textBox2.Text.Trim() == "")
            {
                MessageBox.Show("文件描述不能為空!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                this.textBox2.Focus();
                return;
            }
            try
            {
                string   filePath = this.textBox1.Text;
                FileInfo fi       = new FileInfo(@filePath);
                //获得文件大小
                long fileSize = fi.Length;
                //提取文件名
                int    lastIndex    = fi.FullName.LastIndexOf(@"\");
                string completeName = fi.FullName.Substring(lastIndex + 1);
                //获得文件扩展名
                string fileType = fi.Extension.Replace(".", "");
                byte[] files    = FileToBytes(filePath);
                if (fileSize > 0)
                {
                    string[] type   = { "png", "lab" };
                    bool     exists = ((IList)type).Contains(fileType.ToLower());

                    if (!exists)
                    {
                        MessageBox.Show("文档格式不对!只能为pdf格式。", "提示对话框", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        return;
                    }
                    ModelFile modelFile = new ModelFile();
                    modelFile.Fileaddress     = files;
                    modelFile.Filename        = completeName;
                    modelFile.Filedescription = this.textBox2.Text;
                    ModelFile reModelFile = printQ.saveModelFile(modelFile);
                    if (reModelFile != null)
                    {
                        this.textBox3.Text = reModelFile.Fileno;
                        MessageBox.Show("上傳文件成功!", "提示对话框", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    else
                    {
                        MessageBox.Show("上傳文件失敗!", "提示对话框", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        return;
                    }
                }
                else
                {
                    MessageBox.Show("請確認是否選擇正確的文件上傳!", "提示对话框", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("选择文件时候发生了  " + ex.Message);
            }
        }
예제 #13
0
        static void Main(string[] args)
        {
            bool          nometa  = false;
            bool          nolabel = false;
            string        mode;
            string        fullpath_out;
            bool          bigendian = false;
            List <string> mdlanimfiles;

            if (args.Length == 0)
            {
                Console.WriteLine("Split any binary files supported by SA Tools.\n");
                Console.WriteLine("Usage:\n");
                Console.WriteLine("-Splitting binary files with INI data-");
                Console.WriteLine("split binary <file> <inifile> [output path] [-nometa] [-nolabel]\n");
                Console.WriteLine("-Splitting SA1/SADX NB files-");
                Console.WriteLine("split nb <file> [output path] -ini [split INI file]\n");
                Console.WriteLine("-Splitting SA2 MDL files-");
                Console.WriteLine("split mdl <file> [output path] -anim [animation files]\n");
                Console.WriteLine("-Splitting SA2B MDL files-");
                Console.WriteLine("split mdl_b <file> [output path] -anim [animation files]\n");
                Console.WriteLine("-Splitting dllexport entries from DLL files-");
                Console.WriteLine("split dllexport <file> <type> <name> [output path] [-p numparts]\n");
                Console.WriteLine("Press ENTER to exit.");
                Console.ReadLine();
                return;
            }
#if DEBUG
            if (SplitExtensions(args) == true)
            {
                return;
            }
#endif
            for (int u = 2; u < args.Length; u++)
            {
                if (args[u] == "-nometa")
                {
                    nometa = true;
                }
                if (args[u] == "-nolabel")
                {
                    nolabel = true;
                }
            }
            mode = args[0];
            switch (mode.ToLowerInvariant())
            {
            case "binary":
                string fullpath_bin = Path.GetFullPath(args[1]);
                if (!File.Exists(fullpath_bin))
                {
                    Console.WriteLine("File {0} doesn't exist.", fullpath_bin);
                    return;
                }
                Console.WriteLine("File: {0}", fullpath_bin);
                string fullpath_ini = Path.GetFullPath(args[2]);
                if (!File.Exists(fullpath_ini))
                {
                    Console.WriteLine("File {0} doesn't exist.", fullpath_ini);
                    return;
                }
                Console.WriteLine("Data mapping: {0}", fullpath_ini);
                fullpath_out = Path.GetDirectoryName(fullpath_bin);
                if (args.Length > 3)
                {
                    fullpath_out = args[3];
                    if (fullpath_out[fullpath_out.Length - 1] != '/')
                    {
                        fullpath_out = string.Concat(fullpath_out, '/');
                    }
                    fullpath_out = Path.GetFullPath(fullpath_out);
                }
                Console.WriteLine("Output folder: {0}", fullpath_out);
                if (nometa)
                {
                    Console.WriteLine("Labels are disabled");
                }
                if (Path.GetExtension(args[1]).ToLowerInvariant() == ".dll")
                {
                    SA_Tools.SplitDLL.SplitDLL.SplitDLLFile(fullpath_bin, fullpath_ini, fullpath_out, nometa, nolabel);
                }
                else
                {
                    SA_Tools.Split.Split.SplitFile(fullpath_bin, fullpath_ini, fullpath_out, nometa, nolabel);
                }
                break;

            case "nb":
            case "nb_b":
                string fullpath_nb = Path.GetFullPath(args[1]);
                string path_ini    = null;
                if (args[args.Length - 2].ToLowerInvariant() == "-ini")
                {
                    path_ini = Path.GetFullPath(args[args.Length - 1]);
                }
                if (!File.Exists(fullpath_nb))
                {
                    Console.WriteLine("File {0} doesn't exist.", fullpath_nb);
                    return;
                }
                Console.WriteLine("File: {0}", fullpath_nb);
                fullpath_out = Path.GetDirectoryName(fullpath_nb);
                if (args.Length > 2)
                {
                    fullpath_out = args[2];
                    if (fullpath_out[fullpath_out.Length - 1] != '/')
                    {
                        fullpath_out = string.Concat(fullpath_out, '/');
                    }
                    fullpath_out = Path.GetFullPath(fullpath_out);
                }
                Console.WriteLine("Output folder: {0}", fullpath_out);
                SA_Tools.Split.SplitNB.SplitNBFile(fullpath_nb, false, fullpath_out, 1, path_ini);
                break;

            case "mdl":
            case "mdl_b":
                string fullpath_mdl = Path.GetFullPath(args[1]);
                if (!File.Exists(fullpath_mdl))
                {
                    Console.WriteLine("File {0} doesn't exist.", fullpath_mdl);
                    return;
                }
                Console.Write("File: {0}", fullpath_mdl);
                if (mode == "mdl_b")
                {
                    bigendian = true;
                    Console.Write(" (Big Endian)\n");
                }
                else
                {
                    Console.Write(System.Environment.NewLine);
                }
                fullpath_out = Path.GetDirectoryName(fullpath_mdl);
                if (args.Length > 2)
                {
                    fullpath_out = args[2];
                    if (fullpath_out[fullpath_out.Length - 1] != '/')
                    {
                        fullpath_out = string.Concat(fullpath_out, '/');
                    }
                    fullpath_out = Path.GetFullPath(fullpath_out);
                }
                Console.WriteLine("Output path: {0}", fullpath_out);
                if (args.Length > 3)
                {
                    mdlanimfiles = new List <string>();
                    Console.WriteLine("Animation files:");
                    for (int u = 3; u < args.Length; u++)
                    {
                        string animpath = Path.GetFullPath(args[u]);
                        if (File.Exists(animpath))
                        {
                            mdlanimfiles.Add(animpath);
                            Console.WriteLine(animpath);
                        }
                        else
                        {
                            Console.WriteLine("File {0} doesn't exist.", animpath);
                        }
                    }
                    SA_Tools.SAArc.sa2MDL.Split(bigendian, fullpath_mdl, fullpath_out, mdlanimfiles.ToArray());
                }
                else
                {
                    SA_Tools.SAArc.sa2MDL.Split(bigendian, fullpath_mdl, fullpath_out, null);
                }
                break;

            case "dllexport":
                string fullpath_dllex = Path.GetFullPath(args[1]);
                string type           = args[2];
                string name           = args[3];
                string fileOutputPath = "";
                if (args.Length > 4)
                {
                    fileOutputPath = args[4];
                }
                if (!File.Exists(fullpath_dllex))
                {
                    Console.WriteLine("File {0} doesn't exist.", fullpath_dllex);
                    return;
                }
                Console.Write("File: {0}", fullpath_dllex);
                byte[] datafile  = File.ReadAllBytes(fullpath_dllex);
                uint   imageBase = SA_Tools.HelperFunctions.SetupEXE(ref datafile).Value;
                Dictionary <string, int> exports;
                Dictionary <int, string> labels = new Dictionary <int, string>();
                {
                    int      ptr               = BitConverter.ToInt32(datafile, BitConverter.ToInt32(datafile, 0x3c) + 4 + 20 + 96);
                    GCHandle handle            = GCHandle.Alloc(datafile, GCHandleType.Pinned);
                    IMAGE_EXPORT_DIRECTORY dir = (IMAGE_EXPORT_DIRECTORY)Marshal.PtrToStructure(
                        Marshal.UnsafeAddrOfPinnedArrayElement(datafile, ptr), typeof(IMAGE_EXPORT_DIRECTORY));
                    handle.Free();
                    exports = new Dictionary <string, int>(dir.NumberOfFunctions);
                    int nameaddr = dir.AddressOfNames;
                    int ordaddr  = dir.AddressOfNameOrdinals;
                    for (int i = 0; i < dir.NumberOfNames; i++)
                    {
                        string namex = datafile.GetCString(BitConverter.ToInt32(datafile, nameaddr),
                                                           System.Text.Encoding.ASCII);
                        int addr = BitConverter.ToInt32(datafile,
                                                        dir.AddressOfFunctions + (BitConverter.ToInt16(datafile, ordaddr) * 4));
                        exports.Add(namex, addr);
                        labels.Add(addr, namex);
                        nameaddr += 4;
                        ordaddr  += 2;
                    }
                    Console.Write(" ({0} exports)\n", exports.Count);
                }
                if (!exports.ContainsKey(name))
                {
                    Console.WriteLine("The export table has no item named {0}", name);
                    return;
                }
                int address = exports[name];
                Console.WriteLine("{0} {1}:{2}", type, name, address.ToString("X8"));
                switch (type)
                {
                // Landtables
                case "landtable":
                case "sa1landtable":
                case "sadxlandtable":
                case "sa2landtable":
                case "sa2blandtable":
                case "battlelandtable":
                    LandTableFormat landfmt_cur;
                    string          landext;
                    switch (type)
                    {
                    case "sa1landtable":
                        landfmt_cur = LandTableFormat.SA1;
                        landext     = ".sa1lvl";
                        break;

                    case "sadxlandtable":
                        landfmt_cur = LandTableFormat.SADX;
                        landext     = ".sa1lvl";
                        break;

                    case "sa2landtable":
                        landfmt_cur = LandTableFormat.SA2;
                        landext     = ".sa2lvl";
                        break;

                    case "sa2blandtable":
                    case "battlelandtable":
                        landfmt_cur = LandTableFormat.SA2B;
                        landext     = ".sa2blvl";
                        break;

                    case "landtable":
                    default:
                        landfmt_cur = LandTableFormat.SADX;
                        landext     = ".sa1lvl";
                        break;
                    }
                    LandTable land = new LandTable(datafile, address, imageBase, landfmt_cur, labels);
                    if (fileOutputPath == "")
                    {
                        fileOutputPath = land.Name + landext;
                    }
                    if (!Directory.Exists(Path.GetDirectoryName(fileOutputPath)))
                    {
                        Directory.CreateDirectory(Path.GetDirectoryName(fileOutputPath));
                    }
                    land.SaveToFile(fileOutputPath, landfmt_cur, nometa);
                    break;

                // NJS_OBJECT
                case "model":
                case "object":
                case "basicmodel":
                case "basicdxmodel":
                case "chunkmodel":
                case "gcmodel":
                {
                    ModelFormat modelfmt_obj;
                    string      modelext;
                    switch (type)
                    {
                    case "basicmodel":
                        modelfmt_obj = ModelFormat.Basic;
                        modelext     = ".sa1mdl";
                        break;

                    case "basicdxmodel":
                        modelfmt_obj = ModelFormat.BasicDX;
                        modelext     = ".sa1mdl";
                        break;

                    case "chunkmodel":
                        modelfmt_obj = ModelFormat.Chunk;
                        modelext     = ".sa2mdl";
                        break;

                    case "gcmodel":
                        modelfmt_obj = ModelFormat.GC;
                        modelext     = ".sa2bmdl";
                        break;

                    default:
                        modelfmt_obj = ModelFormat.BasicDX;
                        modelext     = ".sa1mdl";
                        break;
                    }
                    NJS_OBJECT mdl = new NJS_OBJECT(datafile, address, imageBase, modelfmt_obj, labels, new Dictionary <int, Attach>());
                    if (fileOutputPath == "")
                    {
                        fileOutputPath = mdl.Name + modelext;
                    }
                    if (!Directory.Exists(Path.GetDirectoryName(fileOutputPath)))
                    {
                        Directory.CreateDirectory(Path.GetDirectoryName(fileOutputPath));
                    }
                    ModelFile.CreateFile(fileOutputPath, mdl, null, null, null, null, modelfmt_obj, nometa);
                }
                break;

                // NJS_MOTION
                case "animation":
                case "motion":
                    int numparts = 0;
                    for (int a = 3; a < args.Length; a++)
                    {
                        if (args[a] == "-p")
                        {
                            numparts = int.Parse(args[a + 1], System.Globalization.NumberStyles.Integer);
                        }
                    }
                    NJS_MOTION ani = new NJS_MOTION(datafile, address, imageBase, numparts, labels);
                    if (fileOutputPath == "")
                    {
                        fileOutputPath = ani.Name + "saanim";
                    }
                    if (!Directory.Exists(Path.GetDirectoryName(fileOutputPath)))
                    {
                        Directory.CreateDirectory(Path.GetDirectoryName(fileOutputPath));
                    }
                    ani.Save(fileOutputPath, nometa);
                    break;

                default:
                    Console.WriteLine("Unrecognized export type {0}", type);
                    break;
                }
                break;

            default:
                Console.WriteLine("Incorrect mode specified. Press ENTER to exit.");
                Console.ReadLine();
                return;
            }
        }
예제 #14
0
 public AnimatedModel(Engine engine, Skeleton skeleton, ModelVariantIdentifier variant, ModelFile file, ModelQuality quality) : this(engine, skeleton, variant, file.GetModelDefinition(), quality)
 {
 }
예제 #15
0
        static ExportModel ProcessModel(ModelFile mdl, ResourceManager resources)
        {
            mdl.Path = mdl.Path.Replace(' ', '_');
            var ex = new ExportModel();

            for (int midx = 0; midx < mdl.Levels.Length; midx++)
            {
                var lvl       = mdl.Levels[midx];
                var processed = ProcessRef(lvl, resources);
                var geo       = new CL.geometry();
                geo.name = geo.id = mdl.Path + "-level" + midx;
                var mesh = new CL.mesh();
                geo.Item = mesh;
                CL.source positions;
                CL.source normals = null;
                CL.source colors  = null;
                CL.source tex1    = null;
                CL.source tex2    = null;
                int       idxC    = 1;
                positions = CreateSource(
                    geo.name + "-positions",
                    (k) => new Vector4(processed.Vertices[k].Position, 0),
                    3, processed.Vertices.Length);
                mesh.vertices = new CL.vertices()
                {
                    id    = geo.name + "-vertices",
                    input = new CL.InputLocal[] { new CL.InputLocal()
                                                  {
                                                      semantic = "POSITION", source = "#" + positions.id
                                                  } }
                };
                var sources = new List <CL.source>()
                {
                    positions
                };
                if ((processed.FVF & D3DFVF.NORMAL) == D3DFVF.NORMAL)
                {
                    normals = CreateSource(
                        geo.name + "-normals",
                        (k) => new Vector4(processed.Vertices[k].Normal, 0),
                        3, processed.Vertices.Length);
                    sources.Add(normals);
                    idxC++;
                }
                if ((processed.FVF & D3DFVF.DIFFUSE) == D3DFVF.DIFFUSE)
                {
                    colors = CreateSource(
                        geo.name + "-color",
                        (k) =>
                    {
                        var c = Color4.FromRgba(processed.Vertices[k].Diffuse);
                        return(new Vector4(c.R, c.G, c.B, c.A));
                    }, 4, processed.Vertices.Length);
                    sources.Add(colors);
                    idxC++;
                }
                bool doTex1, doTex2 = false;
                if ((processed.FVF & D3DFVF.TEX2) == D3DFVF.TEX2)
                {
                    doTex1 = doTex2 = true;
                }
                else if ((processed.FVF & D3DFVF.TEX1) == D3DFVF.TEX1)
                {
                    doTex1 = true;
                }
                else
                {
                    doTex1 = doTex2 = false;
                }
                if (doTex1)
                {
                    tex1 = CreateSource(
                        geo.name + "-tex1",
                        (k) => new Vector4(processed.Vertices[k].TextureCoordinate, 0, 0),
                        2, processed.Vertices.Length);
                    sources.Add(tex1);
                    idxC++;
                }
                if (doTex2)
                {
                    tex2 = CreateSource(
                        geo.name + "-tex2",
                        (k) => new Vector4(processed.Vertices[k].TextureCoordinateTwo, 0, 0),
                        2, processed.Vertices.Length);
                    sources.Add(tex2);
                    idxC++;
                }
                mesh.source = sources.ToArray();
                var items = new List <object>();
                foreach (var dc in processed.Drawcalls)
                {
                    if (!ex.Materials.Any((x) => x.Name == dc.Material.Name))
                    {
                        ex.Materials.Add(dc.Material);
                    }
                    var trs = new CL.triangles();
                    trs.count    = (ulong)(dc.Indices.Length / 3);
                    trs.material = dc.Material.Name + "-material";
                    List <int> pRefs = new List <int>(dc.Indices.Length * idxC);
                    List <CL.InputLocalOffset> inputs = new List <CL.InputLocalOffset>()
                    {
                        new CL.InputLocalOffset()
                        {
                            semantic = "VERTEX", source = "#" + geo.id + "-vertices", offset = 0
                        }
                    };
                    ulong off = 1;
                    if (normals != null)
                    {
                        inputs.Add(new CL.InputLocalOffset()
                        {
                            semantic = "NORMAL",
                            source   = "#" + normals.id,
                            offset   = off++
                        });
                    }
                    if (colors != null)
                    {
                        inputs.Add(new CL.InputLocalOffset()
                        {
                            semantic = "COLOR",
                            source   = "#" + colors.id,
                            offset   = off++
                        });
                    }
                    if (tex1 != null)
                    {
                        inputs.Add(new CL.InputLocalOffset()
                        {
                            semantic = "TEXCOORD",
                            source   = "#" + tex1.id,
                            offset   = off++
                        });
                    }
                    if (tex2 != null)
                    {
                        inputs.Add(new CL.InputLocalOffset()
                        {
                            semantic = "TEXCOORD",
                            source   = "#" + tex2.id,
                            offset   = off++
                        });
                    }
                    trs.input = inputs.ToArray();
                    for (int i = 0; i < dc.Indices.Length; i++)
                    {
                        for (int j = 0; j < idxC; j++)
                        {
                            pRefs.Add(dc.Indices[i]);
                        }
                    }
                    trs.p = string.Join(" ", pRefs.ToArray());
                    items.Add(trs);
                }
                mesh.Items = items.ToArray();
                ex.Geometries.Add(geo);
            }
            return(ex);
        }
예제 #16
0
        void DoModel(ModelFile mdl, AbstractConstruct con)
        {
            bool open = ImGui.TreeNode(ImGuiExt.Pad("Hardpoints"));
            var  act  = NewHpMenu(mdl.Path);

            switch (act)
            {
            case ContextActions.NewFixed:
            case ContextActions.NewRevolute:
                newIsFixed   = act == ContextActions.NewFixed;
                addTo        = mdl.Hardpoints;
                addConstruct = con;
                newHpBuffer.Clear();
                popups.OpenPopup("New Hardpoint");
                break;
            }
            Theme.RenderTreeIcon("Hardpoints", "hardpoint", Color4.CornflowerBlue);
            if (open)
            {
                foreach (var hp in mdl.Hardpoints)
                {
                    if (doFilter)
                    {
                        if (hp.Name.IndexOf(currentFilter, StringComparison.OrdinalIgnoreCase) == -1)
                        {
                            continue;
                        }
                    }
                    HardpointGizmo gz = null;
                    foreach (var gizmo in gizmos)
                    {
                        if (gizmo.Definition == hp)
                        {
                            gz = gizmo;
                            break;
                        }
                    }
                    if (hp is RevoluteHardpointDefinition)
                    {
                        Theme.Icon("rev", Color4.LightSeaGreen);
                    }
                    else
                    {
                        Theme.Icon("fix", Color4.Purple);
                    }
                    ImGui.SameLine();
                    if (Theme.IconButton("visible$" + hp.Name, "eye", gz.Enabled ? Color4.White : Color4.Gray))
                    {
                        gz.Enabled = !gz.Enabled;
                    }
                    ImGui.SameLine();
                    ImGui.Selectable(hp.Name);
                    var action = EditDeleteHpMenu(mdl.Path + hp.Name);
                    if (action == ContextActions.Delete)
                    {
                        hpDelete     = hp;
                        hpDeleteFrom = mdl.Hardpoints;
                        popups.OpenPopup("Confirm Delete");
                    }
                    if (action == ContextActions.Edit)
                    {
                        hpEditing = hp;
                    }
                }
                ImGui.TreePop();
            }
        }
예제 #17
0
 public void addFile(ModelFile file)
 {
     this.files.Add(file);
 }
예제 #18
0
 private void LoadFile(string filename)
 {
     loaded = false;
     Environment.CurrentDirectory = Path.GetDirectoryName(filename);
     timer1.Stop();
     modelFile = null;
     animation = null;
     animations = null;
     animnum = -1;
     animframe = 0;
     if (ModelFile.CheckModelFile(filename))
     {
         modelFile = new ModelFile(filename);
         outfmt = modelFile.Format;
         model = modelFile.Model;
         animations = new Animation[modelFile.Animations.Count];
         modelFile.Animations.CopyTo(animations, 0);
     }
     else
     {
         using (FileTypeDialog ftd = new FileTypeDialog())
         {
             if (ftd.ShowDialog(this) != DialogResult.OK)
                 return;
             byte[] file = File.ReadAllBytes(filename);
             if (Path.GetExtension(filename).Equals(".prs", StringComparison.OrdinalIgnoreCase))
                 file = FraGag.Compression.Prs.Decompress(file);
             if (ftd.typBinary.Checked)
             {
                 modelinfo.ShowDialog(this);
                 if (modelinfo.checkBox1.Checked)
                     animations = new Animation[] { Animation.ReadHeader(file, (int)modelinfo.numericUpDown3.Value, (uint)modelinfo.numericUpDown2.Value, (ModelFormat)modelinfo.comboBox2.SelectedIndex) };
                 model = new NJS_OBJECT(file, (int)modelinfo.NumericUpDown1.Value, (uint)modelinfo.numericUpDown2.Value, (ModelFormat)modelinfo.comboBox2.SelectedIndex);
                 switch ((ModelFormat)modelinfo.comboBox2.SelectedIndex)
                 {
                     case ModelFormat.Basic:
                     case ModelFormat.BasicDX:
                         outfmt = ModelFormat.Basic;
                         break;
                     case ModelFormat.Chunk:
                         outfmt = ModelFormat.Chunk;
                         break;
                 }
             }
             else if (ftd.typSA2MDL.Checked | ftd.typSA2BMDL.Checked)
             {
                 ModelFormat fmt = outfmt = ModelFormat.Chunk;
                 ByteConverter.BigEndian = ftd.typSA2BMDL.Checked;
                 using (SA2MDLDialog dlg = new SA2MDLDialog())
                 {
                     int address = 0;
                     SortedDictionary<int, NJS_OBJECT> sa2models = new SortedDictionary<int, NJS_OBJECT>();
                     int i = ByteConverter.ToInt32(file, address);
                     while (i != -1)
                     {
                         sa2models.Add(i, new NJS_OBJECT(file, ByteConverter.ToInt32(file, address + 4), 0, fmt));
                         address += 8;
                         i = ByteConverter.ToInt32(file, address);
                     }
                     foreach (KeyValuePair<int, NJS_OBJECT> item in sa2models)
                         dlg.modelChoice.Items.Add(item.Key + ": " + item.Value.Name);
                     dlg.ShowDialog(this);
                     i = 0;
                     foreach (KeyValuePair<int, NJS_OBJECT> item in sa2models)
                     {
                         if (i == dlg.modelChoice.SelectedIndex)
                         {
                             model = item.Value;
                             break;
                         }
                         i++;
                     }
                     if (dlg.checkBox1.Checked)
                     {
                         using (OpenFileDialog anidlg = new OpenFileDialog()
                         {
                             DefaultExt = "bin",
                             Filter = "Motion Files|*MTN.BIN;*MTN.PRS|All Files|*.*"
                         })
                         {
                             if (anidlg.ShowDialog(this) == DialogResult.OK)
                             {
                                 byte[] anifile = File.ReadAllBytes(anidlg.FileName);
                                 if (Path.GetExtension(anidlg.FileName).Equals(".prs", StringComparison.OrdinalIgnoreCase))
                                     anifile = FraGag.Compression.Prs.Decompress(anifile);
                                 address = 0;
                                 SortedDictionary<int, Animation> anis = new SortedDictionary<int, Animation>();
                                 i = ByteConverter.ToInt32(file, address);
                                 while (i != -1)
                                 {
                                     anis.Add(i, new Animation(file, ByteConverter.ToInt32(file, address + 4), 0, model.CountAnimated()));
                                     address += 8;
                                     i = ByteConverter.ToInt32(file, address);
                                 }
                                 animations = new List<Animation>(anis.Values).ToArray();
                             }
                         }
                     }
                 }
             }
         }
     }
     model.ProcessVertexData();
     NJS_OBJECT[] models = model.GetObjects();
     meshes = new Mesh[models.Length];
     for (int i = 0; i < models.Length; i++)
         if (models[i].Attach != null)
             try { meshes[i] = models[i].Attach.CreateD3DMesh(d3ddevice); }
             catch { }
     treeView1.Nodes.Clear();
     nodeDict = new Dictionary<NJS_OBJECT, TreeNode>();
     AddTreeNode(model, treeView1.Nodes);
     loaded = saveToolStripMenuItem.Enabled = exportToolStripMenuItem.Enabled = findToolStripMenuItem.Enabled = true;
     selectedObject = model;
     SelectedItemChanged();
 }
예제 #19
0
        private void button1_Click(object sender, EventArgs e)
        {
            bool success = false;
            uint address = (uint)numericUpDownBinaryAddress.Value;

            if (checkBoxBinaryMemory.Checked)
            {
                address -= (uint)numericUpDownBinaryKey.Value;
            }
            LandTableFormat format = (LandTableFormat)comboBoxBinaryFormat.SelectedIndex;
            LandTableFormat outfmt = format;

            if (format == LandTableFormat.SADX)
            {
                outfmt = LandTableFormat.SA1;
            }
            ByteConverter.BigEndian = checkBoxBinaryBigEndian.Checked;
            Settings.Author         = textBoxBinaryAuthor.Text;
            Settings.Save();
            SaveFileDialog sd = new SaveFileDialog();

            switch (comboBoxBinaryItemType.SelectedIndex)
            {
            //Level
            case 0:
                sd = new SaveFileDialog()
                {
                    DefaultExt = outfmt.ToString().ToLowerInvariant() + "lvl", Filter = outfmt.ToString().ToUpperInvariant() + "LVL Files|*." + outfmt.ToString().ToLowerInvariant() + "lvl|All Files|*.*"
                };
                if (sd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    new LandTable(file, (int)numericUpDownBinaryAddress.Value, (uint)numericUpDownBinaryKey.Value, format)
                    {
                        Author = textBoxBinaryAuthor.Text, Description = textBoxBinaryDescription.Text
                    }.SaveToFile(sd.FileName, outfmt);
                    if (checkBoxBinaryStructs.Checked)
                    {
                        ConvertToText(sd.FileName);
                    }
                    if (!checkBoxBinarySAModel.Checked)
                    {
                        File.Delete(sd.FileName);
                    }
                    success = true;
                }
                break;

            //Model
            case 1:
                sd = new SaveFileDialog()
                {
                    DefaultExt = outfmt.ToString().ToLowerInvariant() + "mdl", Filter = outfmt.ToString().ToUpperInvariant() + "MDL Files|*." + outfmt.ToString().ToLowerInvariant() + "mdl|All Files|*.*"
                };
                if (sd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    NJS_OBJECT tempmodel = new NJS_OBJECT(file, (int)address, (uint)numericUpDownBinaryKey.Value, (ModelFormat)comboBoxBinaryFormat.SelectedIndex, null);
                    ModelFile.CreateFile(sd.FileName, tempmodel, null, textBoxBinaryAuthor.Text, textBoxBinaryDescription.Text, null, (ModelFormat)comboBoxBinaryFormat.SelectedIndex);
                    ConvertToText(sd.FileName, checkBoxBinaryStructs.Checked, checkBoxBinaryNJA.Checked, false);
                    if (!checkBoxBinarySAModel.Checked)
                    {
                        File.Delete(sd.FileName);
                    }
                    success = true;
                }
                break;

            //Action
            case 2:
                sd = new SaveFileDialog()
                {
                    DefaultExt = outfmt.ToString().ToLowerInvariant() + "mdl", Filter = outfmt.ToString().ToUpperInvariant() + "MDL Files|*." + outfmt.ToString().ToLowerInvariant() + "mdl|All Files|*.*"
                };
                if (sd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    //Model
                    NJS_ACTION tempaction = new NJS_ACTION(file, (int)address, (uint)numericUpDownBinaryKey.Value, (ModelFormat)comboBoxBinaryFormat.SelectedIndex, null);
                    NJS_OBJECT tempmodel  = tempaction.Model;
                    ModelFile.CreateFile(sd.FileName, tempmodel, null, textBoxBinaryAuthor.Text, textBoxBinaryDescription.Text, null, (ModelFormat)comboBoxBinaryFormat.SelectedIndex);
                    ConvertToText(sd.FileName, checkBoxBinaryStructs.Checked, checkBoxBinaryNJA.Checked, false);
                    if (!checkBoxBinarySAModel.Checked)
                    {
                        File.Delete(sd.FileName);
                    }

                    //Action
                    string saanimPath = Path.Combine(Path.GetDirectoryName(sd.FileName), Path.GetFileNameWithoutExtension(sd.FileName) + ".saanim");

                    tempaction.Animation.Save(saanimPath);
                    ConvertToText(saanimPath, checkBoxBinaryStructs.Checked, false, checkBoxBinaryJSON.Checked);

                    if (checkBoxBinarySAModel.Checked)
                    {
                        using (TextWriter twmain = File.CreateText(Path.Combine(Path.GetDirectoryName(sd.FileName), Path.GetFileNameWithoutExtension(sd.FileName) + ".action")))
                        {
                            twmain.WriteLine(Path.GetFileName(saanimPath));
                            twmain.Flush();
                            twmain.Close();
                        }
                    }
                    else
                    {
                        File.Delete(saanimPath);
                    }
                    success = true;
                }
                break;
            }
            if (success)
            {
                MessageBox.Show("Data extracted!", "Binary Data Extractor", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
예제 #20
0
        private static void ExtractWarpGates(List <string> warpList, int mapId, MapDataFile ifo)
        {
            const string warpStb       = "./3DDATA/stb/warp.stb";
            const string zoneStb       = "./3DDATA/stb/list_zone.stb";
            const string warpGateModel = "./3DDATA/special/warp_gate01/warp.zms";

            var zoneDataFile = new DataFile();

            zoneDataFile.Load(zoneStb);

            var warpDataFile = new DataFile();

            warpDataFile.Load(warpStb);
            var destCoords = Vector3.Zero;

            ModelFile modelFile = new ModelFile();

            modelFile.Load(warpGateModel);
            var vertices = modelFile.Vertices;

            foreach (var warpGate in ifo.WarpPoints)
            {
                var destMapId = int.Parse(warpDataFile[warpGate.WarpID][2]);
                if (zoneDataFile[destMapId][2].ToString().Contains(".zon"))
                {
                    ZoneFile zoneFile = new ZoneFile();
                    zoneFile.Load(zoneDataFile[destMapId][2].ToString()); // Load the zon file

                    foreach (var spawnPoint in zoneFile.SpawnPoints)
                    {
                        if (spawnPoint.Name != warpDataFile[warpGate.WarpID][3].ToString())
                        {
                            continue;
                        }

                        // rose is stupid and we need to do this to get the right coords
                        destCoords = new Vector3(((spawnPoint.Position.X + 520000.00f) / 100.0f), ((spawnPoint.Position.Z + 520000.00f) / 100.0f), ((spawnPoint.Position.Y) / 100.0f));
                        break;
                    }
                }

                var position = new Vector3(((warpGate.Position.X + 520000.00f) / 100.0f), ((warpGate.Position.Y + 520000.00f) / 100.0f), ((warpGate.Position.Z) / 100.0f));

                var world = Matrix.Identity;
                var rot   = Matrix.RotationQuaternion(warpGate.Rotation);
                var scale = Matrix.Scaling(warpGate.Scale);
                var trans = Matrix.Translation(position);

                var objectWorld = rot * scale * trans;

                Vector3[] vectorPositions = new Vector3[vertices.Count];
                for (int i = 0; i < vertices.Count; i++)
                {
                    vectorPositions[i] = (Vector3)Vector3.Transform(vertices[i].Position, world * objectWorld);
                }

                var boundingBox = BoundingBox.FromPoints(vectorPositions);

                warpList.Add("warp_gate(\"\", "
                             + warpDataFile[warpGate.WarpID][2].ToString() + ", "
                             + (destCoords.X) + ", "
                             + (destCoords.Y) + ", "
                             + (destCoords.Z) + ", "
                             + mapId.ToString() + ", "
                             + (boundingBox.Minimum.X) + ", "
                             + (boundingBox.Minimum.Y) + ", "
                             + (boundingBox.Minimum.Z) + ", "
                             + (boundingBox.Maximum.X) + ", "
                             + (boundingBox.Maximum.Y) + ", "
                             + (boundingBox.Maximum.Z) + ");\n");
            }
        }
예제 #21
0
        static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                Console.Write("Filename: ");
                args = new string[] { Console.ReadLine().Trim('"') };
            }
            foreach (string filename in args)
            {
                Console.WriteLine("Splitting file {0}...", filename);
                byte[] fc;
                if (Path.GetExtension(filename).Equals(".prs", StringComparison.OrdinalIgnoreCase))
                {
                    fc = Prs.Decompress(filename);
                }
                else
                {
                    fc = File.ReadAllBytes(filename);
                }
                EventIniData ini = new EventIniData()
                {
                    Name = Path.GetFileNameWithoutExtension(filename)
                };
                string            path = Directory.CreateDirectory(Path.Combine(Path.GetDirectoryName(Path.GetFullPath(filename)), Path.GetFileNameWithoutExtension(filename))).FullName;
                uint              key;
                List <NJS_MOTION> motions = null;
                bool              battle;
                if (fc[0] == 0x81)
                {
                    Console.WriteLine("File is in GC/PC format.");
                    ByteConverter.BigEndian = true;
                    key         = 0x8125FE60;
                    ini.Game    = Game.SA2B;
                    battle      = true;
                    motions     = ReadMotionFile(Path.ChangeExtension(filename, null) + "motion.bin");
                    ini.Motions = motions.Select(a => a?.Name).ToList();
                    foreach (var mtn in motions.Where(a => a != null))
                    {
                        motionfiles[mtn.Name] = new MotionInfo(null, mtn);
                    }
                }
                else
                {
                    Console.WriteLine("File is in DC format.");
                    ByteConverter.BigEndian = false;
                    key      = 0xC600000;
                    ini.Game = Game.SA2;
                    battle   = false;
                }
                int ptr = fc.GetPointer(0x20, key);
                if (ptr != 0)
                {
                    for (int i = 0; i < (battle ? 18 : 16); i++)
                    {
                        string upnam = upgradenames[i];
                        string chnam = upnam;
                        switch (i)
                        {
                        case 0:
                            chnam = "Sonic";
                            break;

                        case 4:
                            chnam = "Shadow";
                            break;

                        case 6:
                            chnam = "Knuckles";
                            break;

                        case 12:
                            chnam = "Rouge";
                            break;

                        case 16:
                            chnam = "Mech Tails";
                            break;

                        case 17:
                            chnam = "Mech Eggman";
                            break;
                        }
                        UpgradeInfo info = new UpgradeInfo();
                        info.RootNode = GetModel(fc, ptr, key, $"{chnam} Root.sa2mdl");
                        if (info.RootNode != null)
                        {
                            int ptr2 = fc.GetPointer(ptr + 4, key);
                            if (ptr2 != 0)
                            {
                                info.AttachNode1 = $"object_{ptr2:X8}";
                            }
                            info.Model1 = GetModel(fc, ptr + 8, key, $"{upnam} Model 1.sa2mdl");
                            ptr2        = fc.GetPointer(ptr + 0xC, key);
                            if (ptr2 != 0)
                            {
                                info.AttachNode2 = $"object_{ptr2:X8}";
                            }
                            info.Model2 = GetModel(fc, ptr + 0x10, key, $"{upnam} Model 2.sa2mdl");
                        }
                        ini.Upgrades.Add(info);
                        ptr += 0x14;
                    }
                }
                else
                {
                    Console.WriteLine("Event contains no character upgrades.");
                }
                ptr = fc.GetPointer(0x18, key);
                if (ptr != 0)
                {
                    for (int i = 0; i < 93; i++)
                    {
                        string name = GetModel(fc, ptr, key, $"Mech Part {i + 1}.sa2mdl");
                        if (name != null)
                        {
                            ini.MechParts.Add(i, name);
                        }
                        ptr += 4;
                    }
                }
                else
                {
                    Console.WriteLine("Event contains no mech parts.");
                }
                int gcnt = ByteConverter.ToInt32(fc, 8);
                ptr = fc.GetPointer(0, key);
                if (ptr != 0)
                {
                    Console.WriteLine("Event contains {0} scene(s).", gcnt + 1);
                    for (int gn = 0; gn <= gcnt; gn++)
                    {
                        Directory.CreateDirectory(Path.Combine(path, $"Scene {gn + 1}"));
                        SceneInfo scn  = new SceneInfo();
                        int       ptr2 = fc.GetPointer(ptr, key);
                        int       ecnt = ByteConverter.ToInt32(fc, ptr + 4);
                        if (ptr2 != 0)
                        {
                            Console.WriteLine("Scene {0} contains {1} entit{2}.", gn + 1, ecnt, ecnt == 1 ? "y" : "ies");
                            for (int en = 0; en < ecnt; en++)
                            {
                                EntityInfo ent = new EntityInfo();
                                ent.Model  = GetModel(fc, ptr2, key, $"Scene {gn + 1}\\Entity {en + 1} Model.sa2mdl");
                                ent.Motion = GetMotion(fc, ptr2 + 4, key, $"Scene {gn + 1}\\Entity {en + 1} Motion.saanim", motions, modelfiles[ent.Model].Model.CountAnimated());
                                if (ent.Motion != null)
                                {
                                    modelfiles[ent.Model].Motions.Add(motionfiles[ent.Motion].Filename);
                                }
                                ent.ShapeMotion = GetMotion(fc, ptr2 + 8, key, $"Scene {gn + 1}\\Entity {en + 1} Shape Motion.saanim", motions, modelfiles[ent.Model].Model.CountMorph());
                                if (ent.ShapeMotion != null)
                                {
                                    modelfiles[ent.Model].Motions.Add(motionfiles[ent.ShapeMotion].Filename);
                                }
                                if (battle)
                                {
                                    ent.ShadowModel = GetModel(fc, ptr2 + 16, key, $"Scene {gn + 1}\\Entity {en + 1} Shadow Model.sa2mdl");
                                    ent.Position    = new Vertex(fc, ptr2 + 24);
                                    ent.Flags       = ByteConverter.ToUInt32(fc, ptr2 + 40);
                                }
                                else
                                {
                                    ent.Position = new Vertex(fc, ptr2 + 16);
                                    ent.Flags    = ByteConverter.ToUInt32(fc, ptr2 + 28);
                                }
                                scn.Entities.Add(ent);
                                ptr2 += ini.Game == Game.SA2B ? 0x2C : 0x20;
                            }
                        }
                        else
                        {
                            Console.WriteLine("Scene {0} contains no entities.", gn + 1);
                        }
                        ptr2 = fc.GetPointer(ptr + 8, key);
                        if (ptr2 != 0)
                        {
                            int cnt = ByteConverter.ToInt32(fc, ptr + 12);
                            for (int i = 0; i < cnt; i++)
                            {
                                scn.CameraMotions.Add(GetMotion(fc, ptr2, key, $"Scene {gn + 1}\\Camera Motion {i + 1}.saanim", motions, 1));
                                ptr2 += sizeof(int);
                            }
                        }
                        ptr2 = fc.GetPointer(ptr + 0x18, key);
                        if (ptr2 != 0)
                        {
                            BigInfo big = new BigInfo();
                            big.Model = GetModel(fc, ptr2, key, $"Scene {gn + 1}\\Big Model.sa2mdl");
                            if (big.Model != null)
                            {
                                int anicnt = modelfiles[big.Model].Model.CountAnimated();
                                int ptr3   = fc.GetPointer(ptr2 + 4, key);
                                if (ptr3 != 0)
                                {
                                    int cnt = ByteConverter.ToInt32(fc, ptr2 + 8);
                                    for (int i = 0; i < cnt; i++)
                                    {
                                        big.Motions.Add(new string[] { GetMotion(fc, ptr3, key, $"Scene {gn + 1}\\Big Motion {i + 1}a.saanim", motions, anicnt), GetMotion(fc, ptr3 + 4, key, $"Scene {gn + 1}\\Big Motion {i + 1}b.saanim", motions, anicnt) });
                                        ptr3 += 8;
                                    }
                                }
                            }
                            big.Unknown = ByteConverter.ToInt32(fc, ptr2 + 12);
                            scn.Big     = big;
                        }
                        scn.FrameCount = ByteConverter.ToInt32(fc, ptr + 28);
                        ini.Scenes.Add(scn);
                        ptr += 0x20;
                    }
                }
                else
                {
                    Console.WriteLine("Event contains no scenes.");
                }
                ptr = fc.GetPointer(0x1C, key);
                if (ptr != 0)
                {
                    ini.TailsTails = GetModel(fc, ptr, key, $"Tails' tails.sa2mdl");
                }
                else
                {
                    Console.WriteLine("Event does not contain Tails' tails.");
                }
                foreach (var item in motionfiles.Values)
                {
                    string fn = item.Filename ?? $"Unknown Motion {motions.IndexOf(item.Motion)}.saanim";
                    string fp = Path.Combine(path, fn);
                    item.Motion.Save(fp);
                    ini.Files.Add(fn, HelperFunctions.FileHash(fp));
                }
                foreach (var item in modelfiles.Values)
                {
                    string fp = Path.Combine(path, item.Filename);
                    ModelFile.CreateFile(fp, item.Model, item.Motions.ToArray(), null, null, null, ModelFormat.Chunk);
                    ini.Files.Add(item.Filename, HelperFunctions.FileHash(fp));
                }
                JsonSerializer js = new JsonSerializer
                {
                    Formatting        = Formatting.Indented,
                    NullValueHandling = NullValueHandling.Ignore
                };
                using (var tw = File.CreateText(Path.Combine(path, Path.ChangeExtension(Path.GetFileName(filename), ".json"))))
                    js.Serialize(tw, ini);
            }
        }
예제 #22
0
        private void button5_Click(object sender, EventArgs e)
        {
            using (SaveFileDialog fd = new SaveFileDialog()
            {
                DefaultExt = "cpp", Filter = "C++ source files|*.cpp", InitialDirectory = Environment.CurrentDirectory, RestoreDirectory = true
            })
                if (fd.ShowDialog(this) == DialogResult.OK)
                {
                    using (TextWriter writer = File.CreateText(fd.FileName))
                    {
                        bool            SA2      = IniData.Game == Game.SA2B;
                        ModelFormat     modelfmt = SA2 ? ModelFormat.Chunk : ModelFormat.BasicDX;
                        LandTableFormat landfmt  = SA2 ? LandTableFormat.SA2 : LandTableFormat.SADX;
                        writer.WriteLine("// Generated by SA Tools DLL Mod Generator");
                        writer.WriteLine();
                        if (SA2)
                        {
                            writer.WriteLine("#include \"SA2ModLoader.h\"");
                        }
                        else
                        {
                            writer.WriteLine("#include \"SADXModLoader.h\"");
                        }
                        writer.WriteLine();
                        List <string>             labels   = new List <string>();
                        Dictionary <string, uint> texlists = new Dictionary <string, uint>();
                        foreach (KeyValuePair <string, FileTypeHash> item in IniData.Files.Where((a, i) => listView1.CheckedIndices.Contains(i)))
                        {
                            switch (item.Value.Type)
                            {
                            case "landtable":
                                LandTable tbl = LandTable.LoadFromFile(item.Key);
                                texlists.Add(tbl.Name, tbl.TextureList);
                                tbl.ToStructVariables(writer, landfmt, new List <string>());
                                labels.AddRange(tbl.GetLabels());
                                break;

                            case "model":
                                NJS_OBJECT mdl = new ModelFile(item.Key).Model;
                                mdl.ToStructVariables(writer, modelfmt == ModelFormat.BasicDX, new List <string>());
                                labels.AddRange(mdl.GetLabels());
                                break;

                            case "basicmodel":
                            case "chunkmodel":
                                mdl = new ModelFile(item.Key).Model;
                                mdl.ToStructVariables(writer, false, new List <string>());
                                labels.AddRange(mdl.GetLabels());
                                break;

                            case "basicdxmodel":
                                mdl = new ModelFile(item.Key).Model;
                                mdl.ToStructVariables(writer, true, new List <string>());
                                labels.AddRange(mdl.GetLabels());
                                break;

                            case "animation":
                                Animation ani = Animation.Load(item.Key);
                                ani.ToStructVariables(writer);
                                labels.Add(ani.Name);
                                break;
                            }
                            writer.WriteLine();
                        }
                        writer.WriteLine("extern \"C\" __declspec(dllexport) void __cdecl Init(const char *path, const HelperFunctions &helperFunctions)");
                        writer.WriteLine("{");
                        writer.WriteLine("\tHMODULE handle = GetModuleHandle(L\"{0}\");", IniData.Name);
                        List <string> exports = new List <string>(IniData.Items.Where(item => labels.Contains(item.Label)).Select(item => item.Export).Distinct());
                        foreach (KeyValuePair <string, string> item in IniData.Exports.Where(item => exports.Contains(item.Key)))
                        {
                            writer.WriteLine("\t{0}{1} = ({0})GetProcAddress(handle, \"{1}\");", typemap[item.Value], item.Key);
                        }
                        foreach (DllItemInfo item in IniData.Items.Where(item => labels.Contains(item.Label)))
                        {
                            writer.WriteLine("\t{0} = &{1};", item.ToString(), item.Label);
                        }
                        if (texlists.Count > 0 && IniData.TexLists != null && IniData.TexLists.Items != null)
                        {
                            exports = new List <string>(IniData.TexLists.Where(item => texlists.Values.Contains(item.Key)).Select(item => item.Value.Export).Distinct());
                            foreach (KeyValuePair <string, string> item in IniData.Exports.Where(item => exports.Contains(item.Key)))
                            {
                                writer.WriteLine("\t{0}{1} = ({0})GetProcAddress(handle, \"{1}\");", typemap[item.Value], item.Key);
                            }
                            foreach (KeyValuePair <string, uint> item in texlists.Where(item => IniData.TexLists.ContainsKey(item.Value)))
                            {
                                DllTexListInfo tex = IniData.TexLists[item.Value];
                                string         str;
                                if (tex.Index.HasValue)
                                {
                                    str = $"{tex.Export}[{tex.Index.Value}]";
                                }
                                else
                                {
                                    str = tex.Export;
                                }
                                writer.WriteLine("\t{0}.TexList = {1};", item.Key, str);
                            }
                        }
                        writer.WriteLine("}");
                        writer.WriteLine();
                        writer.WriteLine("extern \"C\" __declspec(dllexport) const ModInfo {0}ModInfo = {{ ModLoaderVer }};", SA2 ? "SA2" : "SADX");
                    }
                }
        }
예제 #23
0
        static void Main(string[] args)
        {
            string datafilename, inifilename;

            if (args.Length > 0)
            {
                datafilename = args[0];
                Console.WriteLine("File: {0}", datafilename);
            }
            else
            {
                Console.Write("File: ");
                datafilename = Console.ReadLine();
            }
            if (args.Length > 1)
            {
                inifilename = args[1];
                Console.WriteLine("INI File: {0}", inifilename);
            }
            else
            {
                Console.Write("INI File: ");
                inifilename = Console.ReadLine();
            }
            byte[]  datafile  = File.ReadAllBytes(datafilename);
            IniData inifile   = IniSerializer.Deserialize <IniData>(inifilename);
            uint    imageBase = HelperFunctions.SetupEXE(ref datafile).Value;
            Dictionary <string, int> exports;
            {
                int      ptr               = BitConverter.ToInt32(datafile, BitConverter.ToInt32(datafile, 0x3c) + 4 + 20 + 96);
                GCHandle handle            = GCHandle.Alloc(datafile, GCHandleType.Pinned);
                IMAGE_EXPORT_DIRECTORY dir = (IMAGE_EXPORT_DIRECTORY)Marshal.PtrToStructure(
                    Marshal.UnsafeAddrOfPinnedArrayElement(datafile, ptr), typeof(IMAGE_EXPORT_DIRECTORY));
                handle.Free();
                exports = new Dictionary <string, int>(dir.NumberOfFunctions);
                int nameaddr = dir.AddressOfNames;
                int ordaddr  = dir.AddressOfNameOrdinals;
                for (int i = 0; i < dir.NumberOfNames; i++)
                {
                    string name = HelperFunctions.GetCString(datafile, BitConverter.ToInt32(datafile, nameaddr),
                                                             System.Text.Encoding.ASCII);
                    int addr = BitConverter.ToInt32(datafile,
                                                    dir.AddressOfFunctions + (BitConverter.ToInt16(datafile, ordaddr) * 4));
                    exports.Add(name, addr);
                    nameaddr += 4;
                    ordaddr  += 2;
                }
            }
            ModelFormat     modelfmt = 0;
            LandTableFormat landfmt  = 0;
            string          modelext = null;
            string          landext  = null;

            switch (inifile.Game)
            {
            case Game.SADX:
                modelfmt = ModelFormat.BasicDX;
                landfmt  = LandTableFormat.SADX;
                modelext = ".sa1mdl";
                landext  = ".sa1lvl";
                break;

            case Game.SA2B:
                modelfmt = ModelFormat.Chunk;
                landfmt  = LandTableFormat.SA2;
                modelext = ".sa2mdl";
                landext  = ".sa2lvl";
                break;
            }
            int                       itemcount = 0;
            List <string>             labels    = new List <string>();
            ModelAnimationsDictionary models    = new ModelAnimationsDictionary();
            DllIniData                output    = new DllIniData()
            {
                Name = inifile.ModuleName,
                Game = inifile.Game
            };
            Stopwatch timer = new Stopwatch();

            timer.Start();
            foreach (KeyValuePair <string, FileInfo> item in inifile.Files)
            {
                if (string.IsNullOrEmpty(item.Key))
                {
                    continue;
                }
                FileInfo data = item.Value;
                string   type = data.Type;
                string   name = item.Key;
                output.Exports[name] = type;
                int address = exports[name];
                if (data.Filename != null)
                {
                    Console.WriteLine(name + " -> " + data.Filename);
                    Directory.CreateDirectory(Path.GetDirectoryName(data.Filename));
                }
                else
                {
                    Console.WriteLine(name);
                }
                switch (type)
                {
                case "landtable":
                {
                    LandTable land = new LandTable(datafile, address, imageBase, landfmt)
                    {
                        Description = name, Tool = "splitDLL"
                    };
                    DllItemInfo info = new DllItemInfo()
                    {
                        Export = name,
                        Label  = land.Name
                    };
                    output.Items.Add(info);
                    if (!labels.Contains(land.Name))
                    {
                        land.SaveToFile(data.Filename, landfmt);
                        output.Files[data.Filename] = new FileTypeHash("landtable", HelperFunctions.FileHash(data.Filename));
                        labels.AddRange(land.GetLabels());
                    }
                }
                break;

                case "landtablearray":
                    for (int i = 0; i < data.Length; i++)
                    {
                        int ptr = BitConverter.ToInt32(datafile, address);
                        if (ptr != 0)
                        {
                            ptr = (int)(ptr - imageBase);
                            string    idx  = name + "[" + i.ToString(NumberFormatInfo.InvariantInfo) + "]";
                            LandTable land = new LandTable(datafile, ptr, imageBase, landfmt)
                            {
                                Description = idx, Tool = "splitDLL"
                            };
                            DllItemInfo info = new DllItemInfo()
                            {
                                Export = name,
                                Index  = i,
                                Label  = land.Name
                            };
                            output.Items.Add(info);
                            if (!labels.Contains(land.Name))
                            {
                                string fn = Path.Combine(data.Filename, i.ToString(NumberFormatInfo.InvariantInfo) + landext);
                                land.SaveToFile(fn, landfmt);
                                output.Files[fn] = new FileTypeHash("landtable", HelperFunctions.FileHash(fn));
                                labels.AddRange(land.GetLabels());
                            }
                        }
                        address += 4;
                    }
                    break;

                case "model":
                {
                    NJS_OBJECT  mdl  = new NJS_OBJECT(datafile, address, imageBase, modelfmt);
                    DllItemInfo info = new DllItemInfo()
                    {
                        Export = name,
                        Label  = mdl.Name
                    };
                    output.Items.Add(info);
                    if (!labels.Contains(mdl.Name))
                    {
                        models.Add(new ModelAnimations(data.Filename, name, mdl, modelfmt));
                        labels.AddRange(mdl.GetLabels());
                    }
                }
                break;

                case "morph":
                {
                    BasicAttach dummy = new BasicAttach(datafile, address, imageBase, modelfmt == ModelFormat.BasicDX);
                    NJS_OBJECT  mdl   = new NJS_OBJECT()
                    {
                        Attach = dummy
                    };
                    DllItemInfo info = new DllItemInfo()
                    {
                        Export = name,
                        Label  = dummy.Name
                    };
                    output.Items.Add(info);
                    if (!labels.Contains(dummy.Name))
                    {
                        models.Add(new ModelAnimations(data.Filename, name, mdl, modelfmt));
                        labels.AddRange(mdl.GetLabels());
                    }
                }
                break;

                case "modelarray":
                    for (int i = 0; i < data.Length; i++)
                    {
                        int ptr = BitConverter.ToInt32(datafile, address);
                        if (ptr != 0)
                        {
                            ptr = (int)(ptr - imageBase);
                            NJS_OBJECT  mdl  = new NJS_OBJECT(datafile, ptr, imageBase, modelfmt);
                            string      idx  = name + "[" + i.ToString(NumberFormatInfo.InvariantInfo) + "]";
                            DllItemInfo info = new DllItemInfo()
                            {
                                Export = name,
                                Index  = i,
                                Label  = mdl.Name
                            };
                            output.Items.Add(info);
                            if (!labels.Contains(mdl.Name))
                            {
                                string fn = Path.Combine(data.Filename, i.ToString(NumberFormatInfo.InvariantInfo) + modelext);
                                models.Add(new ModelAnimations(fn, idx, mdl, modelfmt));
                                labels.AddRange(mdl.GetLabels());
                            }
                        }
                        address += 4;
                    }
                    break;

                case "modelsarray":
                    for (int i = 0; i < data.Length; i++)
                    {
                        int ptr = BitConverter.ToInt32(datafile, address);
                        if (ptr != 0)
                        {
                            ptr = (int)(ptr - imageBase);
                            BasicAttach dummy = new BasicAttach(datafile, ptr, imageBase, modelfmt == ModelFormat.BasicDX);
                            NJS_OBJECT  mdl   = new NJS_OBJECT()
                            {
                                Attach = dummy
                            };
                            string      idx  = name + "[" + i.ToString(NumberFormatInfo.InvariantInfo) + "]";
                            DllItemInfo info = new DllItemInfo()
                            {
                                Export = name,
                                Index  = i,
                                Label  = dummy.Name
                            };
                            output.Items.Add(info);
                            if (!labels.Contains(dummy.Name))
                            {
                                string fn = Path.Combine(data.Filename, i.ToString(NumberFormatInfo.InvariantInfo) + modelext);
                                models.Add(new ModelAnimations(fn, idx, mdl, ModelFormat.BasicDX));
                                labels.AddRange(mdl.GetLabels());
                            }
                        }
                        address += 4;
                    }
                    break;

                case "basicmodel":
                {
                    NJS_OBJECT  mdl  = new NJS_OBJECT(datafile, address, imageBase, ModelFormat.Basic);
                    DllItemInfo info = new DllItemInfo()
                    {
                        Export = name,
                        Label  = mdl.Name
                    };
                    output.Items.Add(info);
                    if (!labels.Contains(mdl.Name))
                    {
                        models.Add(new ModelAnimations(data.Filename, name, mdl, ModelFormat.Basic));
                        labels.AddRange(mdl.GetLabels());
                    }
                }
                break;

                case "basicmodelarray":
                    for (int i = 0; i < data.Length; i++)
                    {
                        int ptr = BitConverter.ToInt32(datafile, address);
                        if (ptr != 0)
                        {
                            ptr = (int)(ptr - imageBase);
                            NJS_OBJECT  mdl  = new NJS_OBJECT(datafile, ptr, imageBase, ModelFormat.Basic);
                            string      idx  = name + "[" + i.ToString(NumberFormatInfo.InvariantInfo) + "]";
                            DllItemInfo info = new DllItemInfo()
                            {
                                Export = name,
                                Index  = i,
                                Label  = mdl.Name
                            };
                            output.Items.Add(info);
                            if (!labels.Contains(mdl.Name))
                            {
                                string fn = Path.Combine(data.Filename, i.ToString(NumberFormatInfo.InvariantInfo) + ".sa1mdl");
                                models.Add(new ModelAnimations(fn, idx, mdl, ModelFormat.Basic));
                                labels.AddRange(mdl.GetLabels());
                            }
                        }
                        address += 4;
                    }
                    break;

                case "basicdxmodel":
                {
                    NJS_OBJECT  mdl  = new NJS_OBJECT(datafile, address, imageBase, ModelFormat.BasicDX);
                    DllItemInfo info = new DllItemInfo()
                    {
                        Export = name,
                        Label  = mdl.Name
                    };
                    output.Items.Add(info);
                    if (!labels.Contains(mdl.Name))
                    {
                        models.Add(new ModelAnimations(data.Filename, name, mdl, ModelFormat.BasicDX));
                        labels.AddRange(mdl.GetLabels());
                    }
                }
                break;

                case "basicdxmodelarray":
                    for (int i = 0; i < data.Length; i++)
                    {
                        int ptr = BitConverter.ToInt32(datafile, address);
                        if (ptr != 0)
                        {
                            ptr = (int)(ptr - imageBase);
                            NJS_OBJECT  mdl  = new NJS_OBJECT(datafile, ptr, imageBase, ModelFormat.BasicDX);
                            string      idx  = name + "[" + i.ToString(NumberFormatInfo.InvariantInfo) + "]";
                            DllItemInfo info = new DllItemInfo()
                            {
                                Export = name,
                                Index  = i,
                                Label  = mdl.Name
                            };
                            output.Items.Add(info);
                            if (!labels.Contains(mdl.Name))
                            {
                                string fn = Path.Combine(data.Filename, i.ToString(NumberFormatInfo.InvariantInfo) + ".sa1mdl");
                                models.Add(new ModelAnimations(fn, idx, mdl, ModelFormat.BasicDX));
                                labels.AddRange(mdl.GetLabels());
                            }
                        }
                        address += 4;
                    }
                    break;

                case "chunkmodel":
                {
                    NJS_OBJECT  mdl  = new NJS_OBJECT(datafile, address, imageBase, ModelFormat.Chunk);
                    DllItemInfo info = new DllItemInfo()
                    {
                        Export = name,
                        Label  = mdl.Name
                    };
                    output.Items.Add(info);
                    if (!labels.Contains(mdl.Name))
                    {
                        models.Add(new ModelAnimations(data.Filename, name, mdl, ModelFormat.Chunk));
                        labels.AddRange(mdl.GetLabels());
                    }
                }
                break;

                case "chunkmodelarray":
                    for (int i = 0; i < data.Length; i++)
                    {
                        int ptr = BitConverter.ToInt32(datafile, address);
                        if (ptr != 0)
                        {
                            ptr = (int)(ptr - imageBase);
                            NJS_OBJECT  mdl  = new NJS_OBJECT(datafile, ptr, imageBase, ModelFormat.Chunk);
                            string      idx  = name + "[" + i.ToString(NumberFormatInfo.InvariantInfo) + "]";
                            DllItemInfo info = new DllItemInfo()
                            {
                                Export = name,
                                Index  = i,
                                Label  = mdl.Name
                            };
                            output.Items.Add(info);
                            if (!labels.Contains(mdl.Name))
                            {
                                string fn = Path.Combine(data.Filename, i.ToString(NumberFormatInfo.InvariantInfo) + ".sa2mdl");
                                models.Add(new ModelAnimations(fn, idx, mdl, ModelFormat.Chunk));
                                labels.AddRange(mdl.GetLabels());
                            }
                        }
                        address += 4;
                    }
                    break;

                case "actionarray":
                    for (int i = 0; i < data.Length; i++)
                    {
                        int ptr = BitConverter.ToInt32(datafile, address);
                        if (ptr != 0)
                        {
                            ptr = (int)(ptr - imageBase);
                            AnimationHeader ani = new AnimationHeader(datafile, ptr, imageBase, modelfmt);
                            string          idx = name + "[" + i.ToString(NumberFormatInfo.InvariantInfo) + "]";
                            ani.Animation.Name = item.Key + "_" + i;
                            DllItemInfo info = new DllItemInfo()
                            {
                                Export = name,
                                Index  = i,
                                Label  = ani.Animation.Name,
                                Field  = "motion"
                            };
                            output.Items.Add(info);
                            info = new DllItemInfo()
                            {
                                Export = name,
                                Index  = i,
                                Label  = ani.Model.Name,
                                Field  = "object"
                            };
                            output.Items.Add(info);
                            string fn = Path.Combine(data.Filename, i.ToString(NumberFormatInfo.InvariantInfo) + ".saanim");
                            ani.Animation.Save(fn);
                            output.Files[fn] = new FileTypeHash("animation", HelperFunctions.FileHash(fn));
                            if (models.Contains(ani.Model.Name))
                            {
                                ModelAnimations           mdl = models[ani.Model.Name];
                                System.Text.StringBuilder sb  = new System.Text.StringBuilder(260);
                                PathRelativePathTo(sb, Path.GetFullPath(mdl.Filename), 0, Path.GetFullPath(fn), 0);
                                mdl.Animations.Add(sb.ToString());
                            }
                            else
                            {
                                string mfn = Path.ChangeExtension(fn, modelext);
                                ModelFile.CreateFile(mfn, ani.Model, new[] { Path.GetFileName(fn) }, null, null,
                                                     idx + "->object", "splitDLL", null, modelfmt);
                                output.Files[mfn] = new FileTypeHash("model", HelperFunctions.FileHash(mfn));
                            }
                        }
                        address += 4;
                    }
                    break;

                case "texlist":
                    if (output.TexLists == null)
                    {
                        output.TexLists = new TexListContainer();
                    }
                    output.TexLists.Add((uint)(address + imageBase), new DllTexListInfo(name, null));
                    break;

                case "texlistarray":
                    if (output.TexLists == null)
                    {
                        output.TexLists = new TexListContainer();
                    }
                    for (int i = 0; i < data.Length; i++)
                    {
                        uint ptr = BitConverter.ToUInt32(datafile, address);
                        if (ptr != 0 && !output.TexLists.ContainsKey(ptr))
                        {
                            output.TexLists.Add(ptr, new DllTexListInfo(name, i));
                        }
                        address += 4;
                    }
                    break;
                }
                itemcount++;
            }
            foreach (ModelAnimations item in models)
            {
                ModelFile.CreateFile(item.Filename, item.Model, item.Animations.ToArray(), null, null, item.Name, "splitDLL",
                                     null, item.Format);
                string type = "model";
                switch (item.Format)
                {
                case ModelFormat.Basic:
                    type = "basicmodel";
                    break;

                case ModelFormat.BasicDX:
                    type = "basicdxmodel";
                    break;

                case ModelFormat.Chunk:
                    type = "chunkmodel";
                    break;
                }
                output.Files[item.Filename] = new FileTypeHash(type, HelperFunctions.FileHash(item.Filename));
            }
            IniSerializer.Serialize(output, Path.Combine(Environment.CurrentDirectory, Path.GetFileNameWithoutExtension(datafilename))
                                    + "_data.ini");
            timer.Stop();
            Console.WriteLine("Split " + itemcount + " items in " + timer.Elapsed.TotalSeconds + " seconds.");
            Console.WriteLine();
        }
    internal IEnumerator LoadMap(string s, Action onError = null, Action onLoaded = null)
    {
        mapLoading = true;
        loadMap    = null;
        unityMap   = "";
        swirl      = 0;
        scale      = 1;
        print(mainSite + s);
        WWW www = new WWW(mainSite + s);

        yield return(www);

        if (!string.IsNullOrEmpty(www.error))
        {
            if (onError != null)
            {
                onError();
            }
            yield break;
        }
        BinaryReader ms = new BinaryReader(www.bytes);

        Debug.LogWarning("Loading Map " + ms.Length + " " + s);
        int version = 0;
        Dictionary <int, CurvySpline2> saveIds = new Dictionary <int, CurvySpline2>();
        //bool ingame = _Game != null;
        //HashSet<KeyValuePair<Vector3, string>> cells = new HashSet<KeyValuePair<Vector3, string>>();
        ModelObject modelObject = null;
        var         enumType    = typeof(LevelPackets);
        //var levelPackets = Enum.GetValues(enumType);
        LevelPackets P, oldP = LevelPackets.Unknown;

        while (ms.Position < ms.Length)
        {
            try
            {
                P = (LevelPackets)ms.ReadInt();
                if (!Enum.IsDefined(enumType, P))
                {
                    ms.Position++;
                    if (isDebug)
                    {
                        Debug.LogError("wrong Levelpacked " + oldP);
                    }
                    else
                    {
                        Loader.errors++;
                    }
                    P = (LevelPackets)ms.ReadInt();
                    if (!Enum.IsDefined(enumType, P))
                    {
                        ms.Position--;
                        continue;
                    }
                }
            }
            catch (Exception e)
            {
                Debug.LogError(e);
                continue;
            }
            oldP = P;

            if (P == LevelPackets.unityMap)
            {
                var map = ms.ReadString();
                yield return(StartCoroutine(LoadUnityMap(map)));
            }

            if (P == LevelPackets.Spline)
            {
                yield return(StartCoroutine(CreateSpline()));
            }


            if (P == LevelPackets.shape)
            {
                yield return(StartCoroutine(CreateSpline(null, true)));

                spline.CreatePivot(ms.ReadVector());
                spline.saveId          = ms.ReadInt();
                saveIds[spline.saveId] = spline;
                spline.tunnel          = ms.ReadBool();
                spline.materialId      = ms.ReadInt();
                spline.color           = ms.readColor();
                spline.name            = ms.ReadString();
            }
            try
            {
                if (P == LevelPackets.flatTerrain)
                {
                    SetFlatTerrain(true);
                }
                if (P == LevelPackets.ClosedSpline)
                {
                    spline.Closed = true;
                }

                if (P == LevelPackets.CheckPoint2)
                {
                    var t = SetCheckPoint(ms.ReadVector());
                    t.eulerAngles = ms.ReadVector();
                }
                if (P == LevelPackets.disableTerrain)
                {
                    hideTerrain = true;
                }
                if (P == LevelPackets.Block)
                {
                    var        readString = ms.ReadString();
                    GameObject go;
                    if (modelLib == null)
                    {
                        Debug.LogWarning("Model lib not loaded");
                        go = GameObject.CreatePrimitive(PrimitiveType.Cube);
                    }
                    else if (modelLib.dict.ContainsKey(readString) && modelLib.dict[readString].gameObj != null)
                    {
                        ModelFile modelFile = modelLib.dict[readString];
                        var       gameObj   = modelFile.gameObj;
                        modelFile.usedCount++;
                        go      = (GameObject)Instantiate(gameObj);
                        go.name = gameObj.name;
                    }
                    else
                    {
                        go = GameObject.CreatePrimitive(PrimitiveType.Cube);
                        Debug.LogWarning(readString + " not found ");
                    }
                    go.name     = readString;
                    modelObject = InitModel(go, readString);
                    modelObject.transform.position    = ms.ReadVector();
                    modelObject.transform.eulerAngles = ms.ReadVector();
                    modelObject.transform.localScale  = ms.ReadVector();

                    //if (!cells.Add(new KeyValuePair<Vector3, string>(g.pos, go.name)))
                    //{
                    //    Debug.Log("Destroy duplicate " + go.name, go);
                    //    Debug.Log("with " + go.name, go);
                    //    if (ingame)
                    //    Destroy(go);
                    //}
                }
                if (P == LevelPackets.FlyingModel && modelObject != null)
                {
                    modelObject.flying = true;
                }
                if (P == LevelPackets.roadtype)
                {
                    spline.roadType = (RoadType)ms.ReadByte2();
                }
                if (P == LevelPackets.Wall)
                {
                    spline.wallTexture = true;
                }
                if (P == LevelPackets.shapeMaterial)
                {
                    string readString = ms.ReadString();
                    spline.thumb = new Thumbnail()
                    {
                        url = Regex.Replace(readString, @"https?://server.critical-missions.com/tm/|https?://tmrace.net/tm/", "")
                    };
                    //Debug.LogWarning(readString);
                }
                if (P == LevelPackets.textureTile)
                {
                    spline.thumb.material.mainTextureScale = ms.ReadVector();
                }
                if (P == LevelPackets.AntiFly)
                {
                    _GameSettings.gravitationAntiFly = ms.ReadFloat();
                    _GameSettings.gravitationFactor  = ms.ReadFloat();
                }
                if (P == LevelPackets.Flying)
                {
                    segment.flying = ms.ReadBool();
                }

                if (P == LevelPackets.heightOffset)
                {
                    spline.heightOffset = ms.ReadFloat();
                }
                if (P == LevelPackets.Version)
                {
                    version = ms.ReadInt();
                    if (version >= 702)
                    {
                        foreach (var a in shapes.ToArray())
                        {
                            print("removing default brush " + a.name);
                            Destroy(a.gameObject);
                        }
                    }
                }
                if (P == LevelPackets.Nitro)
                {
                    Debug.Log("Nitro Loaded " + nitro);
                    nitro = ms.ReadFloat();
                }
                if (P == LevelPackets.Point)
                {
                    var readVector = ms.ReadVector();
                    AddPoint(readVector);
                    if (version >= 702)
                    {
                        segment.spls = new List <CurvySpline2>();
                    }
                    else
                    {
                        segment.spls = new List <CurvySpline2>(new[] { brushShapes[0] });
                    }
                    segment.swirl = ms.ReadFloat();
                }
                if (P == LevelPackets.brush)
                {
                    segment.spls.Add(saveIds[ms.ReadInt()]);
                }
                if (P == LevelPackets.Material)
                {
                    spline.materialId = ms.ReadInt();
                    print("Set Material " + spline.materialId);
                    spline.color = ms.readColor();
                }
                if (P == LevelPackets.Finnish)
                {
                    finnish = true;
                }
                if (P == LevelPackets.CheckPoint)
                {
                    SetCheckPoint(segment);
                }
                if (P == LevelPackets.Start)
                {
                    SetStartPoint(segment);
                    start.transform.parent = segment.transform;
                }
                if (P == LevelPackets.StartPos)
                {
                    SetStartPoint(ms.ReadVector(), ms.ReadVector());
                }
                if (P == LevelPackets.Laps)
                {
                    laps = ms.ReadInt();
                    _GameSettings.laps = laps;
                }
                if (P == LevelPackets.scale)
                {
                    segment.scale = ms.ReadFloat();
                }
                if (P == LevelPackets.levelTime)
                {
                    _GameSettings.levelTime = ms.ReadFloat();
                }
                if (P == LevelPackets.rotateTexture)
                {
                    spline.rotateTexture = true;
                }
                if (P == LevelPackets.disableJump)
                {
                    _Loader.curSceneDef.disableJump = true;
                }
            }
            catch (Exception e) { Debug.LogError(e); }
        }
        print("Map Version " + version);
        if (onLoaded != null)
        {
            onLoaded();
        }
        userMapSucces = true;
        UpdateTerrain(null, true, _Loader.levelEditor == null);
        if (!_Loader.levelEditor)
        {
            Optimize2();
        }

        mapLoading = false;
        if (isDebug && modelLib != null)
        {
            bool parsed = setting.parsedLevels.Contains(_Loader.mapName);
            if (!parsed)
            {
                setting.parsedLevels.Add(_Loader.mapName);
            }
            foreach (var a in modelLib.models)
            {
                if (!parsed)
                {
                    setting.Popularity[a.path] = setting.Popularity.TryGet(a.path, 0) + Mathf.Sqrt(Mathf.Sqrt(a.usedCount));
                }
                //if (a.usedCountSqrt != 0)
                //    print(a.name + ":" + a.usedCountSqrt);
                a.usedCount = 0;
            }
            setting.populartyKeys   = new List <string>(setting.Popularity.Keys);
            setting.populartyValues = new List <float>(setting.Popularity.Values);
            SetDirty(res);
        }
    }
예제 #25
0
 /// <summary>
 /// Process mesh internals<para/>
 /// Обработка данных меша
 /// </summary>
 public void Process(bool needed)
 {
     if (needed)
     {
         if (GroupModel != null)
         {
             if (GroupTextures != null)
             {
                 if (GroupModel.State == Model.ReadyState.Complete && GroupTextures.State == TextureDictionary.ReadyState.Complete)
                 {
                     // Surface is ready to render
                     // Поверхность готова к отрисовке
                     Ready = true;
                     Model.SubMesh[] subs = GroupModel.GetAllSubMeshes();
                     Renderers       = new StaticRenderer[subs.Length];
                     Coords.Position = Coords.Position;
                     for (int i = 0; i < Renderers.Length; i++)
                     {
                         Renderers[i] = new StaticRenderer()
                         {
                             BaseMatrix    = Coords.Matrix,
                             SubmeshMatrix = subs[i].Parent.Matrix,
                             SubMesh       = subs[i],
                             Textures      = GroupTextures,
                             Fading        = false,
                             FadingDelta   = 1
                         };
                     }
                 }
                 else
                 {
                     // Check for model state
                     // Проверка состояния модели
                     if (GroupModel.State != Model.ReadyState.Complete)
                     {
                         if (GroupModel.File.State == Files.RenderWareFile.LoadState.Complete)
                         {
                             if (!ModelManager.IsProcessing(GroupModel))
                             {
                                 ModelManager.ModelProcessQueue.Enqueue(GroupModel);
                             }
                         }
                     }
                     // Check for texture dictionary state
                     // Проверка состояния архива текстур
                     if (GroupTextures.State != TextureDictionary.ReadyState.Complete)
                     {
                         if (GroupTextures.File.State == Files.RenderWareFile.LoadState.Complete)
                         {
                             if (!TextureManager.IsProcessing(GroupTextures))
                             {
                                 TextureManager.TextureProcessQueue.Enqueue(GroupTextures);
                             }
                         }
                     }
                 }
             }
             else
             {
                 // Texture not found - get it
                 // Текстура не найдена - получаем её
                 string tname = ObjectManager.Definitions[Definition.ID].TexDictionary;
                 if (TextureManager.Cached.ContainsKey(tname))
                 {
                     GroupTextures = TextureManager.Cached[tname];
                 }
                 else
                 {
                     TextureFile tf = null;
                     if (TextureManager.CachedFiles.ContainsKey(tname))
                     {
                         tf = TextureManager.CachedFiles[tname];
                     }
                     else
                     {
                         tf = new TextureFile(ArchiveManager.Get(tname + ".txd"), false);
                         TextureManager.CachedFiles.TryAdd(tname, tf);
                         TextureManager.TextureFileProcessQueue.Enqueue(tf);
                     }
                     GroupTextures = new TextureDictionary(tf);
                     TextureManager.Cached.TryAdd(tname, GroupTextures);
                 }
                 GroupTextures.UseCount++;
             }
         }
         else
         {
             // Model not found - get it
             // Модель не найдена - получаем её
             string mname = ObjectManager.Definitions[Definition.ID].ModelName;
             if (ModelManager.Cached.ContainsKey(mname))
             {
                 GroupModel = ModelManager.Cached[mname];
             }
             else
             {
                 ModelFile mf = null;
                 if (ModelManager.CachedFiles.ContainsKey(mname))
                 {
                     mf = ModelManager.CachedFiles[mname];
                 }
                 else
                 {
                     mf = new ModelFile(ArchiveManager.Get(mname + ".dff"), false);
                     ModelManager.CachedFiles.TryAdd(mname, mf);
                     ModelManager.ModelFileProcessQueue.Enqueue(mf);
                 }
                 GroupModel = new Model(mf);
                 ModelManager.Cached.TryAdd(mname, GroupModel);
             }
             GroupModel.UseCount++;
         }
     }
     else
     {
         // Cleaning all the usings
         // Очистка использований
         if (GroupModel != null)
         {
             if (!GroupModel.Important)
             {
                 GroupModel.UseCount--;
             }
             GroupModel = null;
         }
         if (GroupTextures != null)
         {
             if (!GroupTextures.Important)
             {
                 GroupTextures.UseCount--;
             }
             GroupTextures = null;
         }
         if (Renderers != null)
         {
             Renderers = null;
         }
         Ready = false;
     }
 }
예제 #26
0
        public static List <Item> ImportFromFile(string filePath, EditorCamera camera, out bool errorFlag, out string errorMsg, EditorItemSelection selectionManager, OnScreenDisplay osd, bool multiple = false)
        {
            List <Item> createdItems = new List <Item>();

            if (!File.Exists(filePath))
            {
                errorFlag = true;
                errorMsg  = "File does not exist!";
                return(null);
            }

            DirectoryInfo filePathInfo = new DirectoryInfo(filePath);

            bool    importError    = false;
            string  importErrorMsg = "";
            Vector3 pos            = camera.Position + (-20 * camera.Look);

            switch (filePathInfo.Extension)
            {
            case ".sa1mdl":
                ModelFile  mf   = new ModelFile(filePath);
                NJS_OBJECT objm = mf.Model;
                osd.ClearMessageList();
                osd.AddMessage("Importing models, please wait...", 3000);
                osd.ClearMessageList();
                createdItems.AddRange(ImportFromHierarchy(objm, selectionManager, osd, multiple));
                osd.AddMessage("Stage import complete!", 100);
                break;

            case ".obj":
            case ".objf":
                LevelItem item = new LevelItem(filePath, new Vertex(pos.X, pos.Y, pos.Z), new Rotation(), levelItems.Count, selectionManager)
                {
                    Visible = true
                };

                createdItems.Add(item);
                break;

            case ".txt":
                NodeTable.ImportFromFile(filePath, out importError, out importErrorMsg, selectionManager);
                break;

            case ".dae":
            case ".fbx":
                Assimp.AssimpContext context = new Assimp.AssimpContext();
                Assimp.Configs.FBXPreservePivotsConfig conf = new Assimp.Configs.FBXPreservePivotsConfig(false);
                context.SetConfig(conf);
                Assimp.Scene scene = context.ImportFile(filePath, Assimp.PostProcessSteps.Triangulate);
                for (int i = 0; i < scene.RootNode.ChildCount; i++)
                {
                    osd.ClearMessageList();
                    osd.AddMessage("Importing model " + i.ToString() + " of " + scene.RootNode.ChildCount.ToString() + "...", 3000);
                    Assimp.Node        child  = scene.RootNode.Children[i];
                    List <Assimp.Mesh> meshes = new List <Assimp.Mesh>();
                    foreach (int j in child.MeshIndices)
                    {
                        meshes.Add(scene.Meshes[j]);
                    }
                    bool isVisible = true;
                    for (int j = 0; j < child.MeshCount; j++)
                    {
                        if (scene.Materials[meshes[j].MaterialIndex].Name.Contains("Collision"))
                        {
                            isVisible = false;
                            break;
                        }
                    }
                    ModelFormat mfmt = ModelFormat.Basic;
                    if (isVisible)
                    {
                        switch (geo.Format)
                        {
                        case LandTableFormat.SA2:
                            mfmt = ModelFormat.Chunk;
                            break;

                        case LandTableFormat.SA2B:
                            mfmt = ModelFormat.GC;
                            break;
                        }
                    }
                    NJS_OBJECT obj = AssimpStuff.AssimpImport(scene, child, mfmt, TextureBitmaps[leveltexs].Select(a => a.Name).ToArray(), !multiple);
                    {
                        //sa2 collision patch
                        if (obj.Attach.GetType() == typeof(BasicAttach))
                        {
                            BasicAttach ba = obj.Attach as BasicAttach;
                            foreach (NJS_MATERIAL mats in ba.Material)
                            {
                                mats.DoubleSided = true;
                            }
                        }
                        //cant check for transparent texture so i gotta force alpha for now, temporary
                        else if (obj.Attach.GetType() == typeof(ChunkAttach))
                        {
                            ChunkAttach ca = obj.Attach as ChunkAttach;
                            foreach (PolyChunk polys in ca.Poly)
                            {
                                if (polys.GetType() == typeof(PolyChunkMaterial))
                                {
                                    PolyChunkMaterial mat = polys as PolyChunkMaterial;
                                    mat.SourceAlpha      = AlphaInstruction.SourceAlpha;
                                    mat.DestinationAlpha = AlphaInstruction.InverseSourceAlpha;
                                }
                                else if (polys.GetType() == typeof(PolyChunkStrip))
                                {
                                    PolyChunkStrip str = polys as PolyChunkStrip;
                                    //str.UseAlpha = true;
                                }
                            }
                        }
                    }
                    obj.Attach.ProcessVertexData();
                    LevelItem newLevelItem = new LevelItem(obj.Attach, new Vertex(obj.Position.X + pos.X, obj.Position.Y + pos.Y, obj.Position.Z + pos.Z), obj.Rotation, levelItems.Count, selectionManager)
                    {
                        Visible = isVisible
                    };
                    createdItems.Add(newLevelItem);
                }
                osd.ClearMessageList();
                osd.AddMessage("Stage import complete!", 100);
                break;

            default:
                errorFlag = true;
                errorMsg  = "Invalid file format!";
                return(null);
            }

            StateChanged();

            errorFlag = importError;
            errorMsg  = importErrorMsg;

            return(createdItems);
        }
예제 #27
0
        public void ExportModel()
        {
            string defaultex;

            switch (COL.Model.GetModelFormat())
            {
            case ModelFormat.Chunk:
                defaultex = ".sa2mdl";
                break;

            case ModelFormat.GC:
                defaultex = ".sa2bmdl";
                break;

            case ModelFormat.Basic:
            case ModelFormat.BasicDX:
            default:
                defaultex = ".sa1mdl";
                break;
            }

            using (System.Windows.Forms.SaveFileDialog a = new System.Windows.Forms.SaveFileDialog
            {
                FileName = Name + defaultex,
                Filter = "SAModel Files|*.sa?mdl|Collada|*.dae|Wavefront|*.obj"
            })
            {
                if (a.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    string ftype = "collada";
                    switch (System.IO.Path.GetExtension(a.FileName).ToLowerInvariant())
                    {
                    case ".sa1mdl":
                    case ".sa2mdl":
                    case ".sa2bmdl":
                        ModelFile.CreateFile(a.FileName, COL.Model, null, null, null, null, COL.Model.GetModelFormat());
                        return;

                    case ".fbx":
                        ftype = "fbx";
                        break;

                    case ".obj":
                        ftype = "obj";
                        break;
                    }
                    Assimp.AssimpContext context = new Assimp.AssimpContext();
                    Assimp.Scene         scene   = new Assimp.Scene();
                    scene.Materials.Add(new Assimp.Material());
                    Assimp.Node n = new Assimp.Node();
                    n.Name         = "RootNode";
                    scene.RootNode = n;
                    string        rootPath     = System.IO.Path.GetDirectoryName(a.FileName);
                    List <string> texturePaths = new List <string>();
                    int           numSteps     = 0;
                    if (LevelData.TextureBitmaps != null && LevelData.TextureBitmaps.Count > 0)
                    {
                        numSteps = LevelData.TextureBitmaps[LevelData.leveltexs].Length;
                    }
                    for (int i = 0; i < numSteps; i++)
                    {
                        BMPInfo bmp = LevelData.TextureBitmaps[LevelData.leveltexs][i];
                        texturePaths.Add(System.IO.Path.Combine(rootPath, bmp.Name + ".png"));
                        bmp.Image.Save(System.IO.Path.Combine(rootPath, bmp.Name + ".png"));
                    }
                    SAEditorCommon.Import.AssimpStuff.AssimpExport(COL.Model, scene, Matrix.Identity, texturePaths.Count > 0 ? texturePaths.ToArray() : null, scene.RootNode);
                    context.ExportFile(scene, a.FileName, ftype, Assimp.PostProcessSteps.ValidateDataStructure | Assimp.PostProcessSteps.Triangulate | Assimp.PostProcessSteps.FlipUVs);                    //
                }
            }
        }
예제 #28
0
        public static void Split(bool isBigEndian, string filePath, string outputFolder, string[] animationPaths)
        {
            string dir = Environment.CurrentDirectory;

            try
            {
                if (outputFolder[outputFolder.Length - 1] != '/')
                {
                    outputFolder = string.Concat(outputFolder, "/");
                }
                ByteConverter.BigEndian = isBigEndian;

                // get file name, read it from the console if nothing
                string mdlfilename = filePath;

                mdlfilename = Path.GetFullPath(mdlfilename);

                // look through the argumetns for animationfiles
                string[] anifilenames = animationPaths;

                // load model file
                Environment.CurrentDirectory = (outputFolder.Length != 0) ? outputFolder : Path.GetDirectoryName(mdlfilename);
                byte[] mdlfile = File.ReadAllBytes(mdlfilename);
                if (Path.GetExtension(mdlfilename).Equals(".prs", StringComparison.OrdinalIgnoreCase))
                {
                    mdlfile = FraGag.Compression.Prs.Decompress(mdlfile);
                }
                Directory.CreateDirectory(Path.GetFileNameWithoutExtension(mdlfilename));

                // getting model pointers
                int address = 0;
                int i       = ByteConverter.ToInt32(mdlfile, address);
                SortedDictionary <int, int> modeladdrs = new SortedDictionary <int, int>();
                while (i != -1)
                {
                    modeladdrs[i] = ByteConverter.ToInt32(mdlfile, address + 4);
                    address      += 8;
                    i             = ByteConverter.ToInt32(mdlfile, address);
                }

                // load models from pointer list
                Dictionary <int, NJS_OBJECT> models     = new Dictionary <int, NJS_OBJECT>();
                Dictionary <int, string>     modelnames = new Dictionary <int, string>();
                List <string> partnames = new List <string>();
                foreach (KeyValuePair <int, int> item in modeladdrs)
                {
                    NJS_OBJECT obj = new NJS_OBJECT(mdlfile, item.Value, 0, ModelFormat.Chunk);
                    modelnames[item.Key] = obj.Name;
                    if (!partnames.Contains(obj.Name))
                    {
                        List <string> names = new List <string>(obj.GetObjects().Select((o) => o.Name));
                        foreach (int idx in modelnames.Where(a => names.Contains(a.Value)).Select(a => a.Key))
                        {
                            models.Remove(idx);
                        }
                        models[item.Key] = obj;
                        partnames.AddRange(names);
                    }
                }

                // load animations
                Dictionary <int, string>     animfns = new Dictionary <int, string>();
                Dictionary <int, NJS_MOTION> anims   = new Dictionary <int, NJS_MOTION>();
                foreach (string anifilename in anifilenames)
                {
                    Dictionary <int, int>    processedanims = new Dictionary <int, int>();
                    Dictionary <int, string> ini            = new Dictionary <int, string>();
                    byte[] anifile = File.ReadAllBytes(anifilename);
                    if (Path.GetExtension(anifilename).Equals(".prs", StringComparison.OrdinalIgnoreCase))
                    {
                        anifile = FraGag.Compression.Prs.Decompress(anifile);
                    }
                    Directory.CreateDirectory(Path.GetFileNameWithoutExtension(anifilename));
                    address = 0;
                    i       = ByteConverter.ToInt16(anifile, address);
                    while (i != -1)
                    {
                        int aniaddr = ByteConverter.ToInt32(anifile, address + 4);
                        if (!processedanims.ContainsKey(aniaddr))
                        {
                            anims[i]   = new NJS_MOTION(anifile, ByteConverter.ToInt32(anifile, address + 4), 0, ByteConverter.ToInt16(anifile, address + 2));
                            animfns[i] = Path.Combine(Path.GetFileNameWithoutExtension(anifilename), i.ToString(NumberFormatInfo.InvariantInfo) + ".saanim");
                            anims[i].Save(animfns[i]);
                            processedanims[aniaddr] = i;
                        }
                        ini[i]   = "animation_" + aniaddr.ToString("X8");
                        address += 8;
                        i        = ByteConverter.ToInt16(anifile, address);
                    }
                    IniSerializer.Serialize(ini, new IniCollectionSettings(IniCollectionMode.IndexOnly), Path.Combine(Path.GetFileNameWithoutExtension(anifilename), Path.GetFileNameWithoutExtension(anifilename) + ".ini"));
                }

                // save output model files
                foreach (KeyValuePair <int, NJS_OBJECT> model in models)
                {
                    List <string> animlist = new List <string>();
                    foreach (KeyValuePair <int, NJS_MOTION> anim in anims)
                    {
                        if (model.Value.CountAnimated() == anim.Value.ModelParts)
                        {
                            string rel = animfns[anim.Key].Replace(outputFolder, string.Empty);
                            if (rel.Length > 1 && rel[1] != ':')
                            {
                                rel = "../" + rel;
                            }
                            animlist.Add(rel);
                        }
                    }

                    ModelFile.CreateFile(Path.Combine(Path.GetFileNameWithoutExtension(mdlfilename),
                                                      model.Key.ToString(NumberFormatInfo.InvariantInfo) + ".sa2mdl"), model.Value, animlist.ToArray(),
                                         null, null, null, null, ModelFormat.Chunk);
                }

                // save ini file
                IniSerializer.Serialize(modelnames, new IniCollectionSettings(IniCollectionMode.IndexOnly),
                                        Path.Combine(Path.GetFileNameWithoutExtension(mdlfilename), Path.GetFileNameWithoutExtension(mdlfilename) + ".ini"));
            }
            finally
            {
                Environment.CurrentDirectory = dir;
            }
        }
예제 #29
0
        public static void InitGizmo(Device d3dDevice)
        {
            Attach attach = new ModelFile(Resources.x_null).Model.Attach;

            attach.ProcessVertexData();
            XNullMesh = attach.CreateD3DMesh();

            attach = new ModelFile(Resources.y_null).Model.Attach;
            attach.ProcessVertexData();
            YNullMesh = attach.CreateD3DMesh();

            attach = new ModelFile(Resources.z_null).Model.Attach;
            attach.ProcessVertexData();
            ZNullMesh = attach.CreateD3DMesh();

            attach = new ModelFile(Resources.x_move).Model.Attach;
            attach.ProcessVertexData();
            XMoveMesh = attach.CreateD3DMesh();
            XMaterial = ((BasicAttach)attach).Material[0];

            attach = new ModelFile(Resources.y_move).Model.Attach;
            attach.ProcessVertexData();
            YMoveMesh = attach.CreateD3DMesh();
            YMaterial = ((BasicAttach)attach).Material[0];

            attach = new ModelFile(Resources.z_move).Model.Attach;
            attach.ProcessVertexData();
            ZMoveMesh = attach.CreateD3DMesh();
            ZMaterial = ((BasicAttach)attach).Material[0];

            attach = new ModelFile(Resources.xy_move).Model.Attach;
            attach.ProcessVertexData();
            XYMoveMesh         = attach.CreateD3DMesh();
            DoubleAxisMaterial = ((BasicAttach)attach).Material[0];

            attach = new ModelFile(Resources.zx_move).Model.Attach;
            attach.ProcessVertexData();
            ZXMoveMesh = attach.CreateD3DMesh();

            attach = new ModelFile(Resources.zy_move).Model.Attach;
            attach.ProcessVertexData();
            ZYMoveMesh = attach.CreateD3DMesh();

            attach = new ModelFile(Resources.x_rotation).Model.Attach;
            attach.ProcessVertexData();
            XRotateMesh = attach.CreateD3DMesh();

            attach = new ModelFile(Resources.y_rotation).Model.Attach;
            attach.ProcessVertexData();
            YRotateMesh = attach.CreateD3DMesh();

            attach = new ModelFile(Resources.z_rotation).Model.Attach;
            attach.ProcessVertexData();
            ZRotateMesh = attach.CreateD3DMesh();

            attach = new ModelFile(Resources.x_scale).Model.Attach;
            attach.ProcessVertexData();
            XScaleMesh = attach.CreateD3DMesh();

            attach = new ModelFile(Resources.y_scale).Model.Attach;
            attach.ProcessVertexData();
            YScaleMesh = attach.CreateD3DMesh();

            attach = new ModelFile(Resources.z_scale).Model.Attach;
            attach.ProcessVertexData();
            ZScaleMesh = attach.CreateD3DMesh();

            BoxMesh = Mesh.Box(1, 1, 1);

            HighlightMaterial = new NJS_MATERIAL()
            {
                DiffuseColor = Color.LightGoldenrodYellow, Exponent = 0f, UseTexture = false, IgnoreLighting = true, IgnoreSpecular = true
            };

            ATexture         = Resources.PointATexture.ToTexture(d3dDevice);
            BTexture         = Resources.PointBTexture.ToTexture(d3dDevice);
            StandardMaterial = new NJS_MATERIAL()
            {
                DiffuseColor = Color.Gray, IgnoreLighting = true, IgnoreSpecular = true, UseAlpha = false, UseTexture = true, Exponent = 100f
            };
        }
예제 #30
0
        /// <summary>
        /// Exports a single level, model or animation file as text.
        /// </summary>
        /// <param name="source">Source pathname.</param>
        /// <param name="type">Type of text conversion.</param>
        /// <param name="destination">Destination pathname. Leave blank to export in the same folder with a swapped extension.</param>
        /// <param name="basicDX">Use the SADX2004 format for Basic models.</param>
        public static void ConvertFileToText(string source, TextType type, string destination = "", bool basicDX = true, bool overwrite = true)
        {
            string outext    = ".c";
            string extension = Path.GetExtension(source);

            switch (extension.ToLowerInvariant())
            {
            case ".sa2lvl":
            case ".sa1lvl":
                if (type == TextType.CStructs || type == TextType.NJA)
                {
                    if (destination == "")
                    {
                        destination = Path.Combine(Path.GetDirectoryName(source), Path.GetFileNameWithoutExtension(source) + outext);
                    }
                    if (!overwrite && File.Exists(destination))
                    {
                        while (File.Exists(destination))
                        {
                            destination = destination = Path.Combine(Path.GetDirectoryName(destination), Path.GetFileNameWithoutExtension(destination) + "_" + outext);
                        }
                    }
                    LandTable     land   = LandTable.LoadFromFile(source);
                    List <string> labels = new List <string>()
                    {
                        land.Name
                    };
                    LandTableFormat fmt = land.Format;
                    using (StreamWriter sw = File.CreateText(destination))
                    {
                        if (type == TextType.CStructs)
                        {
                            sw.Write("/* Sonic Adventure ");
                            switch (land.Format)
                            {
                            case LandTableFormat.SA1:
                            case LandTableFormat.SADX:
                                if (basicDX)
                                {
                                    sw.Write("DX");
                                    fmt = LandTableFormat.SADX;
                                }
                                else
                                {
                                    sw.Write("1");
                                    fmt = LandTableFormat.SA1;
                                }
                                break;

                            case LandTableFormat.SA2:
                                sw.Write("2");
                                fmt = LandTableFormat.SA2;
                                break;

                            case LandTableFormat.SA2B:
                                sw.Write("2 Battle");
                                fmt = LandTableFormat.SA2B;
                                break;
                            }
                            sw.WriteLine(" LandTable");
                            sw.WriteLine(" * ");
                            sw.WriteLine(" * Generated by DataToolbox");
                            sw.WriteLine(" * ");
                            if (!string.IsNullOrEmpty(land.Description))
                            {
                                sw.Write(" * Description: ");
                                sw.WriteLine(land.Description);
                                sw.WriteLine(" * ");
                            }
                            if (!string.IsNullOrEmpty(land.Author))
                            {
                                sw.Write(" * Author: ");
                                sw.WriteLine(land.Author);
                                sw.WriteLine(" * ");
                            }
                            sw.WriteLine(" */");
                            sw.WriteLine();
                        }
                        land.ToStructVariables(sw, fmt, labels, null, type == TextType.NJA);
                        sw.Flush();
                        sw.Close();
                    }
                }
                break;

            case ".sa1mdl":
            case ".sa2mdl":
                ModelFile         modelFile  = new ModelFile(source);
                NJS_OBJECT        model      = modelFile.Model;
                List <NJS_MOTION> animations = new List <NJS_MOTION>(modelFile.Animations);
                if (type == TextType.CStructs)
                {
                    outext = ".c";
                    if (destination == "")
                    {
                        destination = Path.Combine(Path.GetDirectoryName(source), Path.GetFileNameWithoutExtension(source) + outext);
                    }
                    if (!overwrite && File.Exists(destination))
                    {
                        while (File.Exists(destination))
                        {
                            destination = destination = Path.Combine(Path.GetDirectoryName(destination), Path.GetFileNameWithoutExtension(destination) + "_" + outext);
                        }
                    }
                    using (StreamWriter sw = File.CreateText(destination))
                    {
                        sw.Write("/* NINJA ");
                        switch (modelFile.Format)
                        {
                        case ModelFormat.Basic:
                        case ModelFormat.BasicDX:
                            if (basicDX)
                            {
                                sw.Write("Basic (with Sonic Adventure DX additions)");
                            }
                            else
                            {
                                sw.Write("Basic");
                            }
                            break;

                        case ModelFormat.Chunk:
                            sw.Write("Chunk");
                            break;

                        case ModelFormat.GC:
                            sw.Write("GC");
                            break;
                        }
                        sw.WriteLine(" model");
                        sw.WriteLine(" * ");
                        sw.WriteLine(" * Generated by DataToolbox");
                        sw.WriteLine(" * ");
                        if (modelFile != null)
                        {
                            if (!string.IsNullOrEmpty(modelFile.Description))
                            {
                                sw.Write(" * Description: ");
                                sw.WriteLine(modelFile.Description);
                                sw.WriteLine(" * ");
                            }
                            if (!string.IsNullOrEmpty(modelFile.Author))
                            {
                                sw.Write(" * Author: ");
                                sw.WriteLine(modelFile.Author);
                                sw.WriteLine(" * ");
                            }
                        }
                        sw.WriteLine(" */");
                        sw.WriteLine();
                        List <string> labels_m = new List <string>()
                        {
                            model.Name
                        };
                        model.ToStructVariables(sw, basicDX, labels_m, null);
                        foreach (NJS_MOTION anim in animations)
                        {
                            anim.ToStructVariables(sw);
                        }
                        sw.Flush();
                        sw.Close();
                    }
                }
                else if (type == TextType.NJA)
                {
                    outext = ".nja";
                    bool isDup = destination.ToLowerInvariant().Contains(".dup");
                    if (destination == "")
                    {
                        destination = Path.Combine(Path.GetDirectoryName(source), Path.GetFileNameWithoutExtension(source) + outext);
                    }
                    if (!overwrite && File.Exists(destination))
                    {
                        while (File.Exists(destination))
                        {
                            destination = Path.Combine(Path.GetDirectoryName(destination), Path.GetFileNameWithoutExtension(destination) + "_" + outext);
                        }
                    }
                    using (StreamWriter sw2 = File.CreateText(destination))
                    {
                        List <string> labels_nj = new List <string>()
                        {
                            model.Name
                        };
                        model.ToNJA(sw2, labels_nj, null, isDup);
                        sw2.Flush();
                        sw2.Close();
                    }
                }
                break;

            case ".saanim":
                NJS_MOTION animation = NJS_MOTION.Load(source);
                if (type == TextType.CStructs)
                {
                    outext = ".c";
                    if (destination == "")
                    {
                        destination = Path.Combine(Path.GetDirectoryName(source), Path.GetFileNameWithoutExtension(source) + outext);
                    }
                    if (!overwrite && File.Exists(destination))
                    {
                        while (File.Exists(destination))
                        {
                            destination = destination = Path.Combine(Path.GetDirectoryName(destination), Path.GetFileNameWithoutExtension(destination) + "_" + outext);
                        }
                    }
                    using (StreamWriter sw = File.CreateText(destination))
                    {
                        sw.WriteLine("/* NINJA Motion");
                        sw.WriteLine(" * ");
                        sw.WriteLine(" * Generated by DataToolbox");
                        sw.WriteLine(" * ");
                        sw.WriteLine(" */");
                        sw.WriteLine();
                        animation.ToStructVariables(sw);
                        sw.Flush();
                        sw.Close();
                    }
                }
                else if (type == TextType.JSON)
                {
                    outext = ".json";
                    if (destination == "")
                    {
                        destination = Path.Combine(Path.GetDirectoryName(source), Path.GetFileNameWithoutExtension(source) + outext);
                    }
                    if (!overwrite && File.Exists(destination))
                    {
                        while (File.Exists(destination))
                        {
                            destination = destination = Path.Combine(Path.GetDirectoryName(destination), Path.GetFileNameWithoutExtension(destination) + "_" + outext);
                        }
                    }
                    JsonSerializer js = new JsonSerializer()
                    {
                        Culture = System.Globalization.CultureInfo.InvariantCulture
                    };
                    using (TextWriter tw = File.CreateText(destination))
                        using (JsonTextWriter jtw = new JsonTextWriter(tw)
                        {
                            Formatting = Formatting.Indented
                        })
                            js.Serialize(jtw, animation);
                }
                else if (type == TextType.NJA)
                {
                    outext = animation.IsShapeMotion() ? ".nas" : ".nam";
                    bool isDum = destination.ToLowerInvariant().Contains(".dum");
                    if (destination == "")
                    {
                        destination = Path.Combine(Path.GetDirectoryName(source), Path.GetFileNameWithoutExtension(source) + outext);
                    }
                    if (!overwrite && File.Exists(destination))
                    {
                        while (File.Exists(destination))
                        {
                            destination = destination = Path.Combine(Path.GetDirectoryName(destination), Path.GetFileNameWithoutExtension(destination) + "_" + outext);
                        }
                    }
                    using (StreamWriter sw2 = File.CreateText(destination))
                    {
                        animation.ToNJA(sw2, null, isDum);
                        sw2.Flush();
                        sw2.Close();
                    }
                }
                break;

            case ".satex":
                SplitTools.NJS_TEXLIST texlist = SplitTools.NJS_TEXLIST.Load(source);
                if (type == TextType.CStructs)
                {
                    outext = ".c";
                    if (destination == "")
                    {
                        destination = Path.Combine(Path.GetDirectoryName(source), Path.GetFileNameWithoutExtension(source) + outext);
                    }
                    if (!overwrite && File.Exists(destination))
                    {
                        while (File.Exists(destination))
                        {
                            destination = destination = Path.Combine(Path.GetDirectoryName(destination), Path.GetFileNameWithoutExtension(destination) + "_" + outext);
                        }
                    }
                    using (StreamWriter sw = File.CreateText(destination))
                    {
                        sw.WriteLine("/* NINJA Texlist");
                        sw.WriteLine(" * ");
                        sw.WriteLine(" * Generated by DataToolbox");
                        sw.WriteLine(" * ");
                        sw.WriteLine(" */");
                        sw.WriteLine();
                        texlist.ToStruct(sw);
                        sw.Flush();
                        sw.Close();
                    }
                }
                else if (type == TextType.NJA)
                {
                    outext = ".tls";
                    if (destination == "")
                    {
                        destination = Path.Combine(Path.GetDirectoryName(source), Path.GetFileNameWithoutExtension(source) + outext);
                    }
                    if (!overwrite && File.Exists(destination))
                    {
                        while (File.Exists(destination))
                        {
                            destination = destination = Path.Combine(Path.GetDirectoryName(destination), Path.GetFileNameWithoutExtension(destination) + "_" + outext);
                        }
                    }
                    using (StreamWriter sw2 = File.CreateText(destination))
                    {
                        texlist.ToNJA(sw2);
                        sw2.Flush();
                        sw2.Close();
                    }
                }
                break;
            }
        }
예제 #31
0
        public static void ExportCollada(ModelFile mdl, ResourceManager resources, string output)
        {
            var dae    = NewCollada();
            var mats   = new CL.library_materials();
            var efx    = new CL.library_effects();
            var geos   = new CL.library_geometries();
            var scenes = new CL.library_visual_scenes();
            var vscene = new CL.visual_scene();

            vscene.name                     = vscene.id = "main-scene";
            scenes.visual_scene             = new CL.visual_scene[] { vscene };
            dae.scene                       = new CL.COLLADAScene();
            dae.scene.instance_visual_scene = new CL.InstanceWithExtra()
            {
                url = "#main-scene"
            };
            var exported = ProcessModel(mdl, resources);

            geos.geometry = exported.Geometries.ToArray();
            mats.material = exported.Materials.Select((x) => new CL.material()
            {
                name            = x.Name,
                id              = x.Name + "-material",
                instance_effect = new CL.instance_effect()
                {
                    url = "#" + x.Name + "-effect"
                }
            }).ToArray();
            efx.effect = exported.Materials.Select((x) => new CL.effect()
            {
                id    = x.Name + "-effect",
                Items = new[]
                {
                    new CL.effectFx_profile_abstractProfile_COMMON()
                    {
                        technique = new CL.effectFx_profile_abstractProfile_COMMONTechnique()
                        {
                            id   = "common",
                            Item = new CL.effectFx_profile_abstractProfile_COMMONTechniquePhong()
                            {
                                ambient             = ColladaColor("ambient", Color4.Black),
                                emission            = ColladaColor("emmision", Color4.Black),
                                diffuse             = ColladaColor("diffuse", x.Dc),
                                specular            = ColladaColor("specular", new Color4(0.25f, 0.25f, 0.25f, 1f)),
                                shininess           = ColladaFloat("shininess", 50),
                                index_of_refraction = ColladaFloat("index_of_refraction", 1)
                            }
                        }
                    }
                }
            }).ToArray();
            var nodes = new List <CL.node>();

            for (int i = 0; i < exported.Geometries.Count; i++)
            {
                nodes.Add(exported.GetNode(i, Matrix4x4.Identity, mdl.Path));
            }
            vscene.node = nodes.ToArray();
            dae.Items   = new object[] { efx, mats, geos, scenes };
            using (var stream = File.Create(output))
                ColladaSupport.XML.Serialize(stream, dae);
        }
    private void DrawFile(ModelFile file, bool big = true)
    {
        if (gui.Button(new GUIContent(big ? file.name : null, file.thumb), buttonSetup(skin.button, big ? 130 : 65)))
        {
            selectedGameObject = file.gameObj;
            if (sgo)
                Destroy(sgo.gameObject);

            recent.Remove(file);
            recent.Insert(0, file);
            if (recent.Count > 8)
                recent.RemoveAt(recent.Count - 1);

            lastSgo = null;
            sgo = InitModel((GameObject)Instantiate(selectedGameObject), selectedGameObject.name);
            if (sgo.collider != null)
                sgo.collider.enabled = false;
            sgo.SetColor(Color.white);
            tool2 = Tool2.Draw;
            tool = Tool.Models;
            win.Back();
        }
    }
 public AnimatedModel(Engine engine, Skeleton skeleton, ModelVariantIdentifier variant, ModelFile file, ModelQuality quality)
     : this(engine, skeleton, variant, file.GetModelDefinition(), quality)
 {
 }
예제 #34
0
        public void Load(System.IO.Stream stream)
        {
            CanSave = false;

            using (var reader = new FileReader(stream))
            {
                reader.SetByteOrder(true);

                Text = FileName;
                while (!reader.EndOfStream)
                {
                    ChunkHeader chunk = new ChunkHeader();
                    chunk.Position   = reader.Position;
                    chunk.Identifier = reader.ReadUInt32();
                    uint unk = reader.ReadUInt32();
                    chunk.ChunkSize   = reader.ReadUInt32();
                    chunk.ChunkId     = reader.ReadUInt32();
                    chunk.NextFilePtr = reader.ReadUInt32();
                    chunk.FileSize    = reader.ReadUInt32();
                    uint unk2 = reader.ReadUInt32();
                    uint unk3 = reader.ReadUInt32();
                    Chunks.Add(chunk);

                    var Identifer = chunk.Identifier.Reverse();
                    switch (Identifer)
                    {
                    case ChunkTextureFile:
                        SWUTexture texture = new SWUTexture();
                        reader.SeekBegin(chunk.Position + 72);
                        texture.ImageKey         = "texture";
                        texture.SelectedImageKey = "texture";
                        texture.ReadChunk(reader);
                        chunk.ChunkData = texture;
                        if (chunk.ChunkSize > 244)
                        {
                            reader.Seek(chunk.Position + 244, System.IO.SeekOrigin.Begin);
                            chunk.FileName = reader.ReadString(Syroot.BinaryData.BinaryStringFormat.ZeroTerminated);
                            texture.Text   = chunk.FileName;
                        }
                        Nodes.Add(texture);
                        break;

                    case ChunkMetaInfo:
                        break;

                    case ChunkAnimInfo:
                        if (chunk.ChunkSize > 0xB0)
                        {
                            reader.Seek(chunk.Position + 0xB0, System.IO.SeekOrigin.Begin);
                            chunk.FileName = reader.ReadString(Syroot.BinaryData.BinaryStringFormat.ZeroTerminated);
                        }
                        break;

                    case ChunkAnimData:
                        AnimationFile animFile = new AnimationFile();
                        animFile.Read(reader);
                        chunk.ChunkData = animFile;
                        break;

                    case ChunkSkeletonData:
                        SkeletonFile skelFile = new SkeletonFile();
                        skelFile.Read(reader);
                        chunk.ChunkData = skelFile;
                        break;

                    case ChunkModelData:
                        ModelFile modelFile = new ModelFile();
                        modelFile.Read(reader);
                        chunk.ChunkData = modelFile;
                        break;

                    case ChunkMaterialData:
                        MaterialFile matFile = new MaterialFile();
                        matFile.Read(reader);
                        chunk.ChunkData = matFile;
                        break;
                    }

                    reader.Seek(chunk.Position + chunk.ChunkSize, System.IO.SeekOrigin.Begin);
                }

                ReadGPUFile(FilePath);
            }

            TreeHelper.CreateFileDirectory(this);
        }