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); }
public static Animation Load(string filename) { 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 SAANIM file."); if (version == 0) throw new NotImplementedException("Cannot open version 0 animations without a model!"); int aniaddr = ByteConverter.ToInt32(file, 8); Dictionary<int, string> labels = new Dictionary<int, string>(); int tmpaddr = BitConverter.ToInt32(file, 0xC); if (tmpaddr != 0) labels.Add(aniaddr, file.GetCString(tmpaddr)); if (magic == SAANIM) { Animation anim = new Animation(file, aniaddr, 0, BitConverter.ToInt32(file, 0x10), labels); ByteConverter.BigEndian = be; return anim; } ByteConverter.BigEndian = be; throw new FormatException("Not a valid SAANIM file."); }
static void Main(string[] args) { string dir = Environment.CurrentDirectory; try { Queue<string> argq = new Queue<string>(args); if (argq.Count > 0 && argq.Peek().Equals("/be", StringComparison.OrdinalIgnoreCase)) { ByteConverter.BigEndian = true; argq.Dequeue(); } string mdlfilename; if (argq.Count > 0) { mdlfilename = argq.Dequeue(); Console.WriteLine("File: {0}", mdlfilename); } else { Console.Write("File: "); mdlfilename = Console.ReadLine(); } mdlfilename = Path.GetFullPath(mdlfilename); string[] anifilenames = new string[argq.Count]; for (int j = 0; j < anifilenames.Length; j++) { Console.WriteLine("Animations: {0}", argq.Peek()); anifilenames[j] = Path.GetFullPath(argq.Dequeue()); } Environment.CurrentDirectory = 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)); 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); } Dictionary<int, SonicRetro.SAModel.NJS_OBJECT> models = new Dictionary<int, SonicRetro.SAModel.NJS_OBJECT>(); Dictionary<int, string> modelnames = new Dictionary<int, string>(); List<string> partnames = new List<string>(); foreach (KeyValuePair<int, int> item in modeladdrs) { SonicRetro.SAModel.NJS_OBJECT obj = new SonicRetro.SAModel.NJS_OBJECT(mdlfile, item.Value, 0, ModelFormat.Chunk); modelnames[item.Key] = obj.Name; if (!partnames.Contains(obj.Name)) { models[item.Key] = obj; partnames.AddRange(obj.GetObjects().Select((o) => o.Name)); } } Dictionary<int, string> animfns = new Dictionary<int, string>(); Dictionary<int, Animation> anims = new Dictionary<int, Animation>(); foreach (string anifilename in anifilenames) { 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) { anims[i] = new Animation(anifile, ByteConverter.ToInt32(anifile, address + 4), 0, ByteConverter.ToInt16(anifile, address + 2)); animfns[i] = Path.Combine(Path.GetFileNameWithoutExtension(anifilename), i.ToString(NumberFormatInfo.InvariantInfo) + ".saanim"); address += 8; i = ByteConverter.ToInt16(anifile, address); } } foreach (KeyValuePair<int, SonicRetro.SAModel.NJS_OBJECT> model in models) { List<string> animlist = new List<string>(); foreach (KeyValuePair<int, Animation> anim in anims) if (model.Value.CountAnimated() == anim.Value.ModelParts) animlist.Add("../" + animfns[anim.Key]); ModelFile.CreateFile(Path.Combine(Path.GetFileNameWithoutExtension(mdlfilename), model.Key.ToString(NumberFormatInfo.InvariantInfo) + ".sa2mdl"), model.Value, animlist.ToArray(), null, null, null, "splitMDL", null, ModelFormat.Chunk); } IniSerializer.Serialize(modelnames, new IniCollectionSettings(IniCollectionMode.IndexOnly), Path.Combine(Path.GetFileNameWithoutExtension(mdlfilename), Path.GetFileNameWithoutExtension(mdlfilename) + ".ini")); foreach (KeyValuePair<int, Animation> anim in anims) anim.Value.Save(animfns[anim.Key]); } finally { Environment.CurrentDirectory = dir; } }