Example #1
0
        public static Animation ReadHeader(byte[] file, int address, uint imageBase, ModelFormat format,
                                           Dictionary <int, string> labels)
        {
            NJS_OBJECT Model = new NJS_OBJECT(file, (int)(ByteConverter.ToUInt32(file, address) - imageBase), imageBase, format);

            return(new Animation(file, (int)(ByteConverter.ToUInt32(file, address + 4) - imageBase), imageBase,
                                 Model.CountAnimated(), labels));
        }
Example #2
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);
            }
        }
Example #3
0
        public ModelFile(string filename)
        {
            int  tmpaddr;
            bool be = ByteConverter.BigEndian;

            ByteConverter.BigEndian = false;
            byte[] file    = File.ReadAllBytes(filename);
            ulong  magic   = ByteConverter.ToUInt64(file, 0) & FormatMask;
            byte   version = file[7];

            if (version > CurrentVersion)
            {
                throw new FormatException("Not a valid SA1MDL/SA2MDL file.");
            }
            Metadata = new Dictionary <uint, byte[]>();
            Dictionary <int, string> labels = new Dictionary <int, string>();

            if (version < 2)
            {
                if (version == 1)
                {
                    tmpaddr = ByteConverter.ToInt32(file, 0x14);
                    if (tmpaddr != 0)
                    {
                        int addr = ByteConverter.ToInt32(file, tmpaddr);
                        while (addr != -1)
                        {
                            labels.Add(addr, file.GetCString(ByteConverter.ToInt32(file, tmpaddr + 4)));
                            tmpaddr += 8;
                            addr     = ByteConverter.ToInt32(file, tmpaddr);
                        }
                    }
                }
                switch (magic)
                {
                case SA1MDL:
                    Format = ModelFormat.Basic;
                    break;

                case SA2MDL:
                    Format = ModelFormat.Chunk;
                    break;

                default:
                    throw new FormatException("Not a valid SA1MDL/SA2MDL file.");
                }
                Model   = new NJS_OBJECT(file, ByteConverter.ToInt32(file, 8), 0, Format, labels);
                tmpaddr = ByteConverter.ToInt32(file, 0xC);
                if (tmpaddr != 0)
                {
                    List <string> animfiles = new List <string>();
                    int           addr      = ByteConverter.ToInt32(file, tmpaddr);
                    while (addr != -1)
                    {
                        animfiles.Add(file.GetCString(addr));
                        tmpaddr += 4;
                        addr     = ByteConverter.ToInt32(file, tmpaddr);
                    }
                    animationFiles = animfiles.ToArray();
                }
                else
                {
                    animationFiles = new string[0];
                }
                string           path  = Path.GetDirectoryName(filename);
                List <Animation> anims = new List <Animation>();
                foreach (string item in animationFiles)
                {
                    anims.Add(Animation.Load(Path.Combine(path, item), Model.CountAnimated()));
                }
                Animations = anims.AsReadOnly();
                if (version == 1)
                {
                    tmpaddr = ByteConverter.ToInt32(file, 0x10);
                    if (tmpaddr != 0)
                    {
                        List <string> morphfiles = new List <string>();
                        int           addr       = ByteConverter.ToInt32(file, tmpaddr);
                        while (addr != -1)
                        {
                            morphfiles.Add(file.GetCString(addr));
                            tmpaddr += 4;
                            addr     = ByteConverter.ToInt32(file, tmpaddr);
                        }
                        morphFiles = morphfiles.ToArray();
                    }
                    else
                    {
                        morphFiles = new string[0];
                    }
                    List <Animation> morphs = new List <Animation>();
                    foreach (string item in morphFiles)
                    {
                        morphs.Add(Animation.Load(Path.Combine(path, item), Model.CountMorph()));
                    }
                    Morphs = morphs.AsReadOnly();
                }
                else
                {
                    morphFiles = new string[0];
                    Morphs     = new ReadOnlyCollection <Animation>(new List <Animation>());
                }
            }
            else
            {
                animationFiles = new string[0];
                morphFiles     = new string[0];
                tmpaddr        = ByteConverter.ToInt32(file, 0xC);
                if (tmpaddr != 0)
                {
                    bool finished = false;
                    while (!finished)
                    {
                        ChunkTypes type      = (ChunkTypes)ByteConverter.ToUInt32(file, tmpaddr);
                        int        chunksz   = ByteConverter.ToInt32(file, tmpaddr + 4);
                        int        nextchunk = tmpaddr + 8 + chunksz;
                        tmpaddr += 8;
                        if (version == 2)
                        {
                            switch (type)
                            {
                            case ChunkTypes.Label:
                                while (ByteConverter.ToInt64(file, tmpaddr) != -1)
                                {
                                    labels.Add(ByteConverter.ToInt32(file, tmpaddr), file.GetCString(ByteConverter.ToInt32(file, tmpaddr + 4)));
                                    tmpaddr += 8;
                                }
                                break;

                            case ChunkTypes.Animation:
                                List <string> animfiles = new List <string>();
                                while (ByteConverter.ToInt32(file, tmpaddr) != -1)
                                {
                                    animfiles.Add(file.GetCString(ByteConverter.ToInt32(file, tmpaddr)));
                                    tmpaddr += 4;
                                }
                                animationFiles = animfiles.ToArray();
                                break;

                            case ChunkTypes.Morph:
                                List <string> morphfiles = new List <string>();
                                while (ByteConverter.ToInt32(file, tmpaddr) != -1)
                                {
                                    morphfiles.Add(file.GetCString(ByteConverter.ToInt32(file, tmpaddr)));
                                    tmpaddr += 4;
                                }
                                morphFiles = morphfiles.ToArray();
                                break;

                            case ChunkTypes.Author:
                                Author = file.GetCString(tmpaddr);
                                break;

                            case ChunkTypes.Tool:
                                Tool = file.GetCString(tmpaddr);
                                break;

                            case ChunkTypes.Description:
                                Description = file.GetCString(tmpaddr);
                                break;

                            case ChunkTypes.Texture:
                                break;

                            case ChunkTypes.End:
                                finished = true;
                                break;
                            }
                        }
                        else
                        {
                            byte[] chunk = new byte[chunksz];
                            Array.Copy(file, tmpaddr, chunk, 0, chunksz);
                            int chunkaddr = 0;
                            switch (type)
                            {
                            case ChunkTypes.Label:
                                while (ByteConverter.ToInt64(chunk, chunkaddr) != -1)
                                {
                                    labels.Add(ByteConverter.ToInt32(chunk, chunkaddr),
                                               chunk.GetCString(ByteConverter.ToInt32(chunk, chunkaddr + 4)));
                                    chunkaddr += 8;
                                }
                                break;

                            case ChunkTypes.Animation:
                                List <string> animchunks = new List <string>();
                                while (ByteConverter.ToInt32(chunk, chunkaddr) != -1)
                                {
                                    animchunks.Add(chunk.GetCString(ByteConverter.ToInt32(chunk, chunkaddr)));
                                    chunkaddr += 4;
                                }
                                animationFiles = animchunks.ToArray();
                                break;

                            case ChunkTypes.Morph:
                                List <string> morphchunks = new List <string>();
                                while (ByteConverter.ToInt32(chunk, chunkaddr) != -1)
                                {
                                    morphchunks.Add(chunk.GetCString(ByteConverter.ToInt32(chunk, chunkaddr)));
                                    chunkaddr += 4;
                                }
                                morphFiles = morphchunks.ToArray();
                                break;

                            case ChunkTypes.Author:
                                Author = chunk.GetCString(chunkaddr);
                                break;

                            case ChunkTypes.Tool:
                                Tool = chunk.GetCString(chunkaddr);
                                break;

                            case ChunkTypes.Description:
                                Description = chunk.GetCString(chunkaddr);
                                break;

                            case ChunkTypes.End:
                                finished = true;
                                break;

                            default:
                                Metadata.Add((uint)type, chunk);
                                break;
                            }
                        }
                        tmpaddr = nextchunk;
                    }
                }
                switch (magic)
                {
                case SA1MDL:
                    Format = ModelFormat.Basic;
                    break;

                case SA2MDL:
                    Format = ModelFormat.Chunk;
                    break;

                default:
                    throw new FormatException("Not a valid SA1MDL/SA2MDL file.");
                }
                Model = new NJS_OBJECT(file, ByteConverter.ToInt32(file, 8), 0, Format, labels);
                string           path  = Path.GetDirectoryName(filename);
                List <Animation> anims = new List <Animation>();
                foreach (string item in animationFiles)
                {
                    anims.Add(Animation.Load(Path.Combine(path, item), Model.CountAnimated()));
                }
                Animations = anims.AsReadOnly();
                List <Animation> morphs = new List <Animation>();
                foreach (string item in morphFiles)
                {
                    morphs.Add(Animation.Load(Path.Combine(path, item), Model.CountMorph()));
                }
                Morphs = morphs.AsReadOnly();
            }
            ByteConverter.BigEndian = be;
        }
Example #4
0
 public AnimationHeader(byte[] file, int address, uint imageBase, ModelFormat format, Dictionary<int, string> labels)
 {
     Model = new NJS_OBJECT(file, (int)(ByteConverter.ToUInt32(file, address) - imageBase), imageBase, format);
     Animation = new Animation(file, (int)(ByteConverter.ToUInt32(file, address + 4) - imageBase), imageBase,
         Model.CountAnimated(), labels);
 }
Example #5
0
 public ModelFile(string filename)
 {
     int tmpaddr;
     bool be = ByteConverter.BigEndian;
     ByteConverter.BigEndian = false;
     byte[] file = File.ReadAllBytes(filename);
     ulong magic = ByteConverter.ToUInt64(file, 0) & FormatMask;
     byte version = file[7];
     if (version > CurrentVersion)
         throw new FormatException("Not a valid SA1MDL/SA2MDL file.");
     Metadata = new Dictionary<uint, byte[]>();
     Dictionary<int, string> labels = new Dictionary<int, string>();
     if (version < 2)
     {
         if (version == 1)
         {
             tmpaddr = ByteConverter.ToInt32(file, 0x14);
             if (tmpaddr != 0)
             {
                 int addr = ByteConverter.ToInt32(file, tmpaddr);
                 while (addr != -1)
                 {
                     labels.Add(addr, file.GetCString(ByteConverter.ToInt32(file, tmpaddr + 4)));
                     tmpaddr += 8;
                     addr = ByteConverter.ToInt32(file, tmpaddr);
                 }
             }
         }
         switch (magic)
         {
             case SA1MDL:
                 Format = ModelFormat.Basic;
                 break;
             case SA2MDL:
                 Format = ModelFormat.Chunk;
                 break;
             default:
                 throw new FormatException("Not a valid SA1MDL/SA2MDL file.");
         }
         Model = new NJS_OBJECT(file, ByteConverter.ToInt32(file, 8), 0, Format, labels);
         tmpaddr = ByteConverter.ToInt32(file, 0xC);
         if (tmpaddr != 0)
         {
             List<string> animfiles = new List<string>();
             int addr = ByteConverter.ToInt32(file, tmpaddr);
             while (addr != -1)
             {
                 animfiles.Add(file.GetCString(addr));
                 tmpaddr += 4;
                 addr = ByteConverter.ToInt32(file, tmpaddr);
             }
             animationFiles = animfiles.ToArray();
         }
         else
             animationFiles = new string[0];
         string path = Path.GetDirectoryName(filename);
         List<Animation> anims = new List<Animation>();
         foreach (string item in animationFiles)
             anims.Add(Animation.Load(Path.Combine(path, item), Model.CountAnimated()));
         Animations = anims.AsReadOnly();
         if (version == 1)
         {
             tmpaddr = ByteConverter.ToInt32(file, 0x10);
             if (tmpaddr != 0)
             {
                 List<string> morphfiles = new List<string>();
                 int addr = ByteConverter.ToInt32(file, tmpaddr);
                 while (addr != -1)
                 {
                     morphfiles.Add(file.GetCString(addr));
                     tmpaddr += 4;
                     addr = ByteConverter.ToInt32(file, tmpaddr);
                 }
                 morphFiles = morphfiles.ToArray();
             }
             else
                 morphFiles = new string[0];
             List<Animation> morphs = new List<Animation>();
             foreach (string item in morphFiles)
                 morphs.Add(Animation.Load(Path.Combine(path, item), Model.CountMorph()));
             Morphs = morphs.AsReadOnly();
         }
         else
         {
             morphFiles = new string[0];
             Morphs = new ReadOnlyCollection<Animation>(new List<Animation>());
         }
     }
     else
     {
         animationFiles = new string[0];
         morphFiles = new string[0];
         tmpaddr = ByteConverter.ToInt32(file, 0xC);
         if (tmpaddr != 0)
         {
             bool finished = false;
             while (!finished)
             {
                 ChunkTypes type = (ChunkTypes)ByteConverter.ToUInt32(file, tmpaddr);
                 int chunksz = ByteConverter.ToInt32(file, tmpaddr + 4);
                 int nextchunk = tmpaddr + 8 + chunksz;
                 tmpaddr += 8;
                 if (version == 2)
                 {
                     switch (type)
                     {
                         case ChunkTypes.Label:
                             while (ByteConverter.ToInt64(file, tmpaddr) != -1)
                             {
                                 labels.Add(ByteConverter.ToInt32(file, tmpaddr), file.GetCString(ByteConverter.ToInt32(file, tmpaddr + 4)));
                                 tmpaddr += 8;
                             }
                             break;
                         case ChunkTypes.Animation:
                             List<string> animfiles = new List<string>();
                             while (ByteConverter.ToInt32(file, tmpaddr) != -1)
                             {
                                 animfiles.Add(file.GetCString(ByteConverter.ToInt32(file, tmpaddr)));
                                 tmpaddr += 4;
                             }
                             animationFiles = animfiles.ToArray();
                             break;
                         case ChunkTypes.Morph:
                             List<string> morphfiles = new List<string>();
                             while (ByteConverter.ToInt32(file, tmpaddr) != -1)
                             {
                                 morphfiles.Add(file.GetCString(ByteConverter.ToInt32(file, tmpaddr)));
                                 tmpaddr += 4;
                             }
                             morphFiles = morphfiles.ToArray();
                             break;
                         case ChunkTypes.Author:
                             Author = file.GetCString(tmpaddr);
                             break;
                         case ChunkTypes.Tool:
                             Tool = file.GetCString(tmpaddr);
                             break;
                         case ChunkTypes.Description:
                             Description = file.GetCString(tmpaddr);
                             break;
                         case ChunkTypes.Texture:
                             break;
                         case ChunkTypes.End:
                             finished = true;
                             break;
                     }
                 }
                 else
                 {
                     byte[] chunk = new byte[chunksz];
                     Array.Copy(file, tmpaddr, chunk, 0, chunksz);
                     int chunkaddr = 0;
                     switch (type)
                     {
                         case ChunkTypes.Label:
                             while (ByteConverter.ToInt64(chunk, chunkaddr) != -1)
                             {
                                 labels.Add(ByteConverter.ToInt32(chunk, chunkaddr),
                                     chunk.GetCString(ByteConverter.ToInt32(chunk, chunkaddr + 4)));
                                 chunkaddr += 8;
                             }
                             break;
                         case ChunkTypes.Animation:
                             List<string> animchunks = new List<string>();
                             while (ByteConverter.ToInt32(chunk, chunkaddr) != -1)
                             {
                                 animchunks.Add(chunk.GetCString(ByteConverter.ToInt32(chunk, chunkaddr)));
                                 chunkaddr += 4;
                             }
                             animationFiles = animchunks.ToArray();
                             break;
                         case ChunkTypes.Morph:
                             List<string> morphchunks = new List<string>();
                             while (ByteConverter.ToInt32(chunk, chunkaddr) != -1)
                             {
                                 morphchunks.Add(chunk.GetCString(ByteConverter.ToInt32(chunk, chunkaddr)));
                                 chunkaddr += 4;
                             }
                             morphFiles = morphchunks.ToArray();
                             break;
                         case ChunkTypes.Author:
                             Author = chunk.GetCString(chunkaddr);
                             break;
                         case ChunkTypes.Tool:
                             Tool = chunk.GetCString(chunkaddr);
                             break;
                         case ChunkTypes.Description:
                             Description = chunk.GetCString(chunkaddr);
                             break;
                         case ChunkTypes.End:
                             finished = true;
                             break;
                         default:
                             Metadata.Add((uint)type, chunk);
                             break;
                     }
                 }
                 tmpaddr = nextchunk;
             }
         }
         switch (magic)
         {
             case SA1MDL:
                 Format = ModelFormat.Basic;
                 break;
             case SA2MDL:
                 Format = ModelFormat.Chunk;
                 break;
             default:
                 throw new FormatException("Not a valid SA1MDL/SA2MDL file.");
         }
         Model = new NJS_OBJECT(file, ByteConverter.ToInt32(file, 8), 0, Format, labels);
         string path = Path.GetDirectoryName(filename);
         List<Animation> anims = new List<Animation>();
         foreach (string item in animationFiles)
             anims.Add(Animation.Load(Path.Combine(path, item), Model.CountAnimated()));
         Animations = anims.AsReadOnly();
         List<Animation> morphs = new List<Animation>();
         foreach (string item in morphFiles)
             morphs.Add(Animation.Load(Path.Combine(path, item), Model.CountMorph()));
         Morphs = morphs.AsReadOnly();
     }
     ByteConverter.BigEndian = be;
 }
Example #6
0
        public ModelFile(byte[] file, string filename = null)
        {
            int  tmpaddr;
            bool be = ByteConverter.BigEndian;

            ByteConverter.BigEndian = false;
            ulong magic   = ByteConverter.ToUInt64(file, 0) & FormatMask;
            byte  version = file[7];

            if (version > CurrentVersion)
            {
                throw new FormatException("Not a valid SA1MDL/SA2MDL file.");
            }
            Metadata = new Dictionary <uint, byte[]>();
            Dictionary <int, string> labels   = new Dictionary <int, string>();
            Dictionary <int, Attach> attaches = new Dictionary <int, Attach>();

            if (version < 2)
            {
                if (version == 1)
                {
                    tmpaddr = ByteConverter.ToInt32(file, 0x14);
                    if (tmpaddr != 0)
                    {
                        int addr = ByteConverter.ToInt32(file, tmpaddr);
                        while (addr != -1)
                        {
                            labels.Add(addr, file.GetCString(ByteConverter.ToInt32(file, tmpaddr + 4)));
                            tmpaddr += 8;
                            addr     = ByteConverter.ToInt32(file, tmpaddr);
                        }
                    }
                }
                switch (magic)
                {
                case SA1MDL:
                    Format = ModelFormat.Basic;
                    break;

                case SA2MDL:
                    Format = ModelFormat.Chunk;
                    break;

                default:
                    throw new FormatException("Not a valid SA1MDL/SA2MDL file.");
                }
                Model = new NJS_OBJECT(file, ByteConverter.ToInt32(file, 8), 0, Format, labels, attaches);
                if (filename != null)
                {
                    tmpaddr = ByteConverter.ToInt32(file, 0xC);
                    if (tmpaddr != 0)
                    {
                        List <string> animfiles = new List <string>();
                        int           addr      = ByteConverter.ToInt32(file, tmpaddr);
                        while (addr != -1)
                        {
                            animfiles.Add(file.GetCString(addr));
                            tmpaddr += 4;
                            addr     = ByteConverter.ToInt32(file, tmpaddr);
                        }
                        animationFiles = animfiles.ToArray();
                    }
                    else
                    {
                        animationFiles = new string[0];
                    }
                    string            path  = Path.GetDirectoryName(filename);
                    List <NJS_MOTION> anims = new List <NJS_MOTION>();
                    try
                    {
                        foreach (string item in animationFiles)
                        {
                            anims.Add(NJS_MOTION.Load(Path.Combine(path, item), Model.CountAnimated()));
                        }
                    }
                    catch
                    {
                        anims.Clear();
                    }
                    Animations = anims.AsReadOnly();
                }
            }
            else
            {
                animationFiles = new string[0];
                tmpaddr        = ByteConverter.ToInt32(file, 0xC);
                if (tmpaddr != 0)
                {
                    bool finished = false;
                    while (!finished)
                    {
                        ChunkTypes type      = (ChunkTypes)ByteConverter.ToUInt32(file, tmpaddr);
                        int        chunksz   = ByteConverter.ToInt32(file, tmpaddr + 4);
                        int        nextchunk = tmpaddr + 8 + chunksz;
                        tmpaddr += 8;
                        if (version == 2)
                        {
                            switch (type)
                            {
                            case ChunkTypes.Label:
                                while (ByteConverter.ToInt64(file, tmpaddr) != -1)
                                {
                                    labels.Add(ByteConverter.ToInt32(file, tmpaddr), file.GetCString(ByteConverter.ToInt32(file, tmpaddr + 4)));
                                    tmpaddr += 8;
                                }
                                break;

                            case ChunkTypes.Animation:
                                List <string> animfiles = new List <string>();
                                while (ByteConverter.ToInt32(file, tmpaddr) != -1)
                                {
                                    animfiles.Add(file.GetCString(ByteConverter.ToInt32(file, tmpaddr)));
                                    tmpaddr += 4;
                                }
                                animationFiles = animfiles.ToArray();
                                break;

                            case ChunkTypes.Morph:
                                break;

                            case ChunkTypes.Author:
                                Author = file.GetCString(tmpaddr);
                                break;

                            case ChunkTypes.Tool:
                                break;

                            case ChunkTypes.Description:
                                Description = file.GetCString(tmpaddr);
                                break;

                            case ChunkTypes.Texture:
                                break;

                            case ChunkTypes.End:
                                finished = true;
                                break;
                            }
                        }
                        else
                        {
                            byte[] chunk = new byte[chunksz];
                            Array.Copy(file, tmpaddr, chunk, 0, chunksz);
                            int chunkaddr = 0;
                            switch (type)
                            {
                            case ChunkTypes.Label:
                                while (ByteConverter.ToInt64(chunk, chunkaddr) != -1)
                                {
                                    labels.Add(ByteConverter.ToInt32(chunk, chunkaddr),
                                               chunk.GetCString(ByteConverter.ToInt32(chunk, chunkaddr + 4)));
                                    chunkaddr += 8;
                                }
                                break;

                            case ChunkTypes.Animation:
                                List <string> animchunks = new List <string>();
                                while (ByteConverter.ToInt32(chunk, chunkaddr) != -1)
                                {
                                    animchunks.Add(chunk.GetCString(ByteConverter.ToInt32(chunk, chunkaddr)));
                                    chunkaddr += 4;
                                }
                                animationFiles = animchunks.ToArray();
                                break;

                            case ChunkTypes.Morph:
                                break;

                            case ChunkTypes.Author:
                                Author = chunk.GetCString(chunkaddr);
                                break;

                            case ChunkTypes.Tool:
                                break;

                            case ChunkTypes.Description:
                                Description = chunk.GetCString(chunkaddr);
                                break;

                            case ChunkTypes.End:
                                finished = true;
                                break;

                            default:
                                Metadata.Add((uint)type, chunk);
                                break;
                            }
                        }
                        tmpaddr = nextchunk;
                    }
                }
                switch (magic)
                {
                case SA1MDL:
                    Format = ModelFormat.Basic;
                    break;

                case SA2MDL:
                    Format = ModelFormat.Chunk;
                    break;

                case SA2BMDL:
                    Format = ModelFormat.GC;
                    break;

                default:
                    throw new FormatException("Not a valid SA1MDL/SA2MDL file.");
                }
                Model = new NJS_OBJECT(file, ByteConverter.ToInt32(file, 8), 0, Format, labels, attaches);
                if (filename != null)
                {
                    string path = Path.GetDirectoryName(filename);
                    if (File.Exists(Path.GetFileNameWithoutExtension(filename) + ".action"))
                    {
                        using (TextReader tr = File.OpenText(Path.GetFileNameWithoutExtension(filename) + ".action"))
                        {
                            List <string> animlist = new List <string>();
                            int           count    = File.ReadLines(Path.GetFileNameWithoutExtension(filename) + ".action").Count();
                            for (int i = 0; i < count; i++)
                            {
                                string line = tr.ReadLine();
                                if (File.Exists(Path.Combine(path, line)))
                                {
                                    animlist.Add(line);
                                }
                            }
                            animationFiles = animlist.ToArray();
                        }
                    }
                    List <NJS_MOTION> anims = new List <NJS_MOTION>();
                    try
                    {
                        foreach (string item in animationFiles)
                        {
                            if (Path.GetExtension(item).ToLowerInvariant() == ".json")
                            {
                                JsonSerializer js = new JsonSerializer()
                                {
                                    Culture = System.Globalization.CultureInfo.InvariantCulture
                                };
                                using (TextReader tr = File.OpenText(Path.Combine(path, item)))
                                {
                                    using (JsonTextReader jtr = new JsonTextReader(tr))
                                        anims.Add(js.Deserialize <NJS_MOTION>(jtr));
                                }
                            }
                            else
                            {
                                anims.Add(NJS_MOTION.Load(Path.Combine(path, item), Model.CountAnimated()));
                            }
                        }
                    }
                    catch
                    {
                        anims.Clear();
                    }
                    Animations = anims.AsReadOnly();
                }
            }
            ByteConverter.BigEndian = be;
        }