private Animation LoadAnimationFromOffset(DSBinaryReader bin, int offset, int animID_ForDebug) { int oldOffset = (int)bin.BaseStream.Position; bin.BaseStream.Seek(offset, SeekOrigin.Begin); var anim = new Animation(); try { int eventCount = bin.ReadInt32(); int eventHeadersOffset = bin.ReadInt32(); bin.BaseStream.Seek(0x10, SeekOrigin.Current); //skip shit we don't need int animFileOffset = bin.ReadInt32(); for (int i = 0; i < eventCount; i++) { //lazily seek to the start of each event manually. bin.BaseStream.Seek(eventHeadersOffset + (EventHeaderSize * i), SeekOrigin.Begin); int startTimeOffset = bin.ReadInt32(); int endTimeOffset = bin.ReadInt32(); int eventBodyOffset = bin.ReadInt32(); bin.BaseStream.Seek(startTimeOffset, SeekOrigin.Begin); float startTime = bin.ReadSingle(); bin.BaseStream.Seek(endTimeOffset, SeekOrigin.Begin); float endTime = bin.ReadSingle(); bin.BaseStream.Seek(eventBodyOffset, SeekOrigin.Begin); int eventTypeValue = bin.ReadInt32(); int eventParamOffset = bin.ReadInt32(); bin.BaseStream.Seek(eventParamOffset, SeekOrigin.Begin); AnimationEventType eventType = (AnimationEventType)eventTypeValue; var nextEvent = new AnimationEvent(i + 1, eventType, animID_ForDebug); nextEvent.StartTime = startTime; nextEvent.EndTime = endTime; for (int j = 0; j < nextEvent.Parameters.Count; j++) { var nextParamVal = new MultiDword() { Int = bin.ReadInt32() }; if (AnimationEvent.CheckIfParamIsUnlikelyToBeFloat(nextParamVal)) { nextEvent.Parameters[j].Value = nextParamVal.Int.ToString(); } else { string convStr = nextParamVal.Float.ToString(); nextEvent.Parameters[j].Value = convStr + (convStr.Contains(".") ? "" : ".0"); } } anim.Events.Add(nextEvent); } bin.BaseStream.Seek(animFileOffset, SeekOrigin.Begin); int fileType = bin.ReadInt32(); if (fileType == 0) { int dataOffset = bin.ReadInt32(); bin.BaseStream.Seek(dataOffset, SeekOrigin.Begin); int nameOffset = bin.ReadInt32(); if (nameOffset == 0) { throw new Exception("Anim file type was that of a named one but the name pointer was NULL."); } bin.BaseStream.Seek(nameOffset, SeekOrigin.Begin); anim.FileName = ReadUnicodeString(bin); } else if (fileType == 1) { anim.FileName = null; } else { throw new Exception($"Unknown anim file type code: {fileType}"); } return(anim); } catch (EndOfStreamException) { MiscUtil.PrintlnDX($"Warning: reached end of file while parsing animation {animID_ForDebug}; data may not be complete.", ConsoleColor.Yellow); //if (!MiscUtil.ConsolePrompYesNo("Would you like to continue loading the file and run the risk of " + // "accidentally outputting a file that might be missing some of its original data?")) //{ // throw new LoadAbortedException(); //} //else //{ // return a; //} return(anim); } finally { bin.BaseStream.Seek(oldOffset, SeekOrigin.Begin); } }