Exemple #1
0
        public GeoAnimData(byte[] file, int address, uint imageBase, LandTableFormat format, Dictionary <int, string> labels, Dictionary <int, Attach> attaches)
        {
            ModelFormat mfmt = 0;

            switch (format)
            {
            case LandTableFormat.SA1:
                mfmt = ModelFormat.Basic;
                break;

            case LandTableFormat.SADX:
                mfmt = ModelFormat.BasicDX;
                break;

            case LandTableFormat.SA2:
                mfmt = ModelFormat.Chunk;
                break;
            }
            Unknown1 = ByteConverter.ToInt32(file, address);
            Unknown2 = ByteConverter.ToSingle(file, address + 4);
            Unknown3 = ByteConverter.ToSingle(file, address + 8);
            Model    = new NJS_OBJECT(file, (int)(ByteConverter.ToUInt32(file, address + 0xC) - imageBase), imageBase, mfmt, labels, attaches);
            int actionaddr = (int)(ByteConverter.ToUInt32(file, address + 0x10) - imageBase);
            int motionaddr = (int)(ByteConverter.ToUInt32(file, actionaddr + 4) - imageBase);

            Animation = NJS_MOTION.ReadDirect(file, Model.CountAnimated(), motionaddr, imageBase, labels, attaches);
            Unknown4  = ByteConverter.ToInt32(file, address + 0x14);
            if (labels.ContainsKey(actionaddr))
            {
                ActionName = labels[actionaddr];
            }
            else
            {
                NJS_ACTION action = new NJS_ACTION(file, actionaddr, imageBase, mfmt, labels, attaches);
                ActionName = action.Name;
                labels.Add(actionaddr + (int)imageBase, ActionName);
            }
        }
Exemple #2
0
        // Scan for Motions
        static void ScanMotions()
        {
            CurrentStep++;
            CurrentScanData = "Motions" + (ModelParts > 0 ? " with " + ModelParts.ToString() + " or more nodes" : "");
            Console.WriteLine("Step {0}: Scanning for motions with at least {1} model parts... ", CurrentStep, ModelParts);
            if (ShortRot)
            {
                Console.WriteLine("Using short rotations");
            }
            ByteConverter.BigEndian = BigEndian;
            if (!SingleOutputFolder)
            {
                Directory.CreateDirectory(Path.Combine(OutputFolder, "actions"));
            }
            for (uint address = StartAddress; address < EndAddress; address += 1)
            {
                if (CancelScan)
                {
                    break;
                }
                if (ConsoleMode && address % 1000 == 0)
                {
                    Console.Write("\r{0} ", address.ToString("X8"));
                }
                CurrentAddress = address;
                // Check for a valid MDATA pointer
                uint mdatap = ByteConverter.ToUInt32(datafile, (int)address);
                if (mdatap < ImageBase || mdatap >= datafile.Length - 12 + ImageBase || mdatap == 0)
                {
                    //Console.WriteLine("Mdatap {0} fail", mdatap.ToString("X8"));
                    continue;
                }
                uint frames = ByteConverter.ToUInt32(datafile, (int)address + 4);
                if (frames > 2000 || frames < 1)
                {
                    //Console.WriteLine("Frames {0} fail", frames.ToString());
                    continue;
                }
                AnimFlags animtype = (AnimFlags)ByteConverter.ToUInt16(datafile, (int)address + 8);
                if (animtype == 0)
                {
                    continue;
                }
                int mdata = 0;
                //Console.WriteLine("Flags: {0}", animtype.ToString());
                if (animtype.HasFlag(AnimFlags.Position))
                {
                    mdata++;
                }
                if (animtype.HasFlag(AnimFlags.Rotation))
                {
                    mdata++;
                }
                if (animtype.HasFlag(AnimFlags.Scale))
                {
                    mdata++;
                }
                if (animtype.HasFlag(AnimFlags.Vector))
                {
                    mdata++;
                }
                if (animtype.HasFlag(AnimFlags.Vertex))
                {
                    mdata++;
                }
                if (animtype.HasFlag(AnimFlags.Normal))
                {
                    mdata++;
                }
                if (animtype.HasFlag(AnimFlags.Color))
                {
                    continue;
                }
                if (animtype.HasFlag(AnimFlags.Intensity))
                {
                    continue;
                }
                if (animtype.HasFlag(AnimFlags.Target))
                {
                    continue;
                }
                if (animtype.HasFlag(AnimFlags.Spot))
                {
                    continue;
                }
                if (animtype.HasFlag(AnimFlags.Point))
                {
                    continue;
                }
                if (animtype.HasFlag(AnimFlags.Roll))
                {
                    continue;
                }
                int  mdatasize = 0;
                bool lost      = false;
                switch (mdata)
                {
                case 1:
                case 2:
                    mdatasize = 16;
                    break;

                case 3:
                    mdatasize = 24;
                    break;

                case 4:
                    mdatasize = 32;
                    break;

                case 5:
                    mdatasize = 40;
                    break;

                default:
                    lost = true;
                    break;
                }
                if (lost)
                {
                    continue;
                }
                // Check MKEY pointers
                int mdatas = 0;
                for (int u = 0; u < 255; u++)
                {
                    for (int m = 0; m < mdata; m++)
                    {
                        if (lost)
                        {
                            continue;
                        }
                        uint pointer = ByteConverter.ToUInt32(datafile, (int)(mdatap - ImageBase) + mdatasize * u + 4 * m);
                        if (pointer < ImageBase || pointer >= datafile.Length - 8 + ImageBase)
                        {
                            if (pointer != 0)
                            {
                                lost = true;
                                //Console.WriteLine("Mkey pointer {0} lost", pointer.ToString("X8"));
                            }
                        }
                        if (!lost)
                        {
                            // Read frame count
                            int framecount = ByteConverter.ToInt32(datafile, (int)(mdatap - ImageBase) + mdatasize * u + 4 * mdata + 4 * m);
                            if (framecount < 0 || framecount > 2000)
                            {
                                //Console.WriteLine("Framecount lost: {0}", framecount.ToString("X8"));
                                lost = true;
                            }
                            if (pointer == 0 && framecount != 0)
                            {
                                //Console.WriteLine("Framecount non zero");
                                lost = true;
                            }
                            //if (!lost) Console.WriteLine("Mdata size: {0}, MkeyP: {1}, Frames: {2}", mdatasize, pointer.ToString("X8"), framecount.ToString());
                        }
                    }
                    if (!lost)
                    {
                        mdatas++;
                        //Console.WriteLine("Mdata {0}, total {1}", u, mdatas);
                    }
                }
                if (mdatas > 0 && mdatas >= ModelParts)
                {
                    try
                    {
                        Console.WriteLine("\rAdding motion at {0}: {1} nodes", address.ToString("X8"), mdatas);
                        //Console.WriteLine("trying Address: {0}, MdataP: {1}, mdatas: {2}", address.ToString("X8"), mdatap.ToString("X8"), mdata);
                        NJS_MOTION mot = NJS_MOTION.ReadDirect(datafile, mdatas, (int)address, ImageBase, new Dictionary <int, Attach>(), ShortRot);
                        if (mot.ModelParts <= 0)
                        {
                            continue;
                        }
                        if (mot.Frames <= 0)
                        {
                            continue;
                        }
                        if (mot.Models.Count == 0)
                        {
                            continue;
                        }
                        string fileOutputPath = Path.Combine(OutputFolder, "actions", address.ToString("X8") + ".saanim");
                        if (SingleOutputFolder)
                        {
                            fileOutputPath = Path.Combine(OutputFolder, address.ToString("X8") + ".saanim");
                        }
                        mot.Save(fileOutputPath, NoMeta);
                        FoundMotions++;
                        addresslist.Add(address, "NJS_MOTION");
                        uint[] arr = new uint[2];
                        arr[0] = address;
                        arr[1] = (uint)mot.ModelParts;
                        actionlist.Add(address, arr);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("\rError adding motion at {0}: {1}", address.ToString("X8"), ex.Message);
                    }
                }
            }
            Console.WriteLine("\rFound {0} motions", FoundMotions);
        }