/// <inheritdoc /> public void Unserialize(UndertaleReader reader) { Name = reader.ReadUndertaleString(); DisplayName = reader.ReadUndertaleString(); EmSize = reader.ReadUInt32(); EmSizeIsFloat = false; // since the float is always written negated, it has the first bit set. if ((EmSize & (1 << 31)) != 0) { float fsize = -BitConverter.ToSingle(BitConverter.GetBytes(EmSize), 0); EmSize = (uint)fsize; EmSizeIsFloat = true; } Bold = reader.ReadBoolean(); Italic = reader.ReadBoolean(); RangeStart = reader.ReadUInt16(); Charset = reader.ReadByte(); AntiAliasing = reader.ReadByte(); RangeEnd = reader.ReadUInt32(); Texture = reader.ReadUndertaleObjectPointer <UndertaleTexturePageItem>(); ScaleX = reader.ReadSingle(); ScaleY = reader.ReadSingle(); if (reader.undertaleData.GeneralInfo?.BytecodeVersion >= 17) { AscenderOffset = reader.ReadInt32(); } if (reader.undertaleData.GMS2022_2) { Ascender = reader.ReadUInt32(); } Glyphs = reader.ReadUndertaleObject <UndertalePointerList <Glyph> >(); }
public void Unserialize(UndertaleReader reader) { Name = reader.ReadUndertaleString(); Function = (FunctionType)reader.ReadUInt32(); Iterations = reader.ReadUInt32(); Points = reader.ReadUndertaleObject <UndertaleSimpleList <Point> >(); }
public void Unserialize(UndertaleReader reader) { X = reader.ReadSingle(); Value = reader.ReadSingle(); if (reader.ReadUInt32() != 0) // in 2.3 a int with the value of 0 would be set here, { // it cannot be version 2.3 if this value isn't 0 reader.undertaleData.GMS2_3_1 = true; reader.Position -= 4; } else { if (reader.ReadUInt32() == 0) // At all points (besides the first one) { reader.undertaleData.GMS2_3_1 = true; // if BezierX0 equals to 0 (the above check) } reader.Position -= 8; // then BezierY0 equals to 0 as well (the current check) } if (reader.undertaleData.GMS2_3_1) { BezierX0 = reader.ReadSingle(); BezierY0 = reader.ReadSingle(); BezierX1 = reader.ReadSingle(); BezierY1 = reader.ReadSingle(); } else { reader.Position += 4; } }
internal override void UnserializeChunk(UndertaleReader reader) { if (Length == 0) // YYC, bytecode <= 16, chunk is empty but exists { List = null; return; } if (reader.undertaleData.UnsupportedBytecodeVersion) { return; } uint startPosition = reader.Position; uint varLength; if (!reader.Bytecode14OrLower) { InstanceVarCount = reader.ReadUInt32(); InstanceVarCountAgain = reader.ReadUInt32(); MaxLocalVarCount = reader.ReadUInt32(); varLength = 20; } else { varLength = 12; } List.Clear(); while (reader.Position + varLength <= startPosition + Length) { List.Add(reader.ReadUndertaleObject <UndertaleVariable>()); } }
public void Unserialize(UndertaleReader reader) { Name = reader.ReadUndertaleString(); Playback = (PlaybackType)reader.ReadUInt32(); PlaybackSpeed = reader.ReadSingle(); PlaybackSpeedType = (AnimSpeedType)reader.ReadUInt32(); Length = reader.ReadSingle(); OriginX = reader.ReadInt32(); OriginY = reader.ReadInt32(); Volume = reader.ReadSingle(); BroadcastMessages = reader.ReadUndertaleObject <UndertaleSimpleList <Keyframe <BroadcastMessage> > >(); Tracks = reader.ReadUndertaleObject <UndertaleSimpleList <Track> >(); FunctionIDs = new Dictionary <int, UndertaleString>(); int count = reader.ReadInt32(); for (int i = 0; i < count; i++) { int key = reader.ReadInt32(); FunctionIDs[key] = reader.ReadUndertaleString(); } Moments = reader.ReadUndertaleObject <UndertaleSimpleList <Keyframe <Moment> > >(); }
public void Unserialize(UndertaleReader reader, uint endPosition) { uint count = reader.ReadUInt32(); Clear(); List <uint> pointers = new List <uint>(); for (uint i = 0; i < count; i++) { try { uint ptr = reader.ReadUInt32(); pointers.Add(ptr); Add(reader.GetUndertaleObjectAtAddress <T>(ptr)); } catch (UndertaleSerializationException e) { throw new UndertaleSerializationException(e.Message + "\nwhile reading pointer to item " + (i + 1) + " of " + count + " in a list of " + typeof(T).FullName, e); } } if (Count > 0 && reader.Position != reader.GetAddressForUndertaleObject(this[0])) { int skip = (int)reader.GetAddressForUndertaleObject(this[0]) - (int)reader.Position; if (skip > 0) { //Console.WriteLine("Skip " + skip + " bytes of blobs"); reader.Position = reader.Position + (uint)skip; } else { throw new IOException("First list item starts inside the pointer list?!?!"); } } for (uint i = 0; i < count; i++) { try { (this[(int)i] as PrePaddedObject)?.UnserializePrePadding(reader); if ((i + 1) < count) { reader.ReadUndertaleObject(this[(int)i], (int)(pointers[(int)i + 1] - reader.Position)); } else { reader.ReadUndertaleObject(this[(int)i], (int)(endPosition - reader.Position)); } if (i != count - 1) { (this[(int)i] as PaddedObject)?.UnserializePadding(reader); } } catch (UndertaleSerializationException e) { throw new UndertaleSerializationException(e.Message + "\nwhile reading item " + (i + 1) + " of " + count + " in a list of " + typeof(T).FullName, e); } } }
public void Unserialize(UndertaleReader reader, bool readLength = true) { _PointerLocation = reader.Position; _Position = reader.ReadUInt32(); if (readLength) _Length = reader.ReadUInt32(); IsNull = (_Position == 0x00000000u); }
public void Unserialize(UndertaleReader reader) { Scaled = reader.ReadUInt32(); if (reader.undertaleData.GeneralInfo.Major >= 2) { GeneratedMips = reader.ReadUInt32(); } TextureData = reader.ReadUndertaleObjectPointer <TexData>(); }
public void Unserialize(UndertaleReader reader) { Name = reader.ReadUndertaleString(); ID = reader.ReadUInt32(); Kind = reader.ReadUInt32(); RetType = (UndertaleExtensionVarType)reader.ReadUInt32(); ExtName = reader.ReadUndertaleString(); Arguments = reader.ReadUndertaleObject <UndertaleSimpleList <UndertaleExtensionFunctionArg> >(); }
internal override void UnserializeChunk(UndertaleReader reader) { if (reader.undertaleData.GeneralInfo?.BytecodeVersion >= 17) { /* This code performs four checks to identify GM2022.2. * First, as you've seen, is the bytecode version. * Second, we assume it is. If there are no Glyphs, we are vindicated by the impossibility of null values there. * Third, we check that the Glyph Length is less than the chunk length. If it's going outside the chunk, that means * that the length was misinterpreted. * Fourth, in case of a terrible fluke causing this to appear valid erroneously, we verify that each pointer leads into the next. * And if someone builds their game so the first pointer is absolutely valid length data and the next font is valid glyph data- * screw it, call Jacky720 when someone constructs that and you want to mod it. * Maybe try..catch on the whole shebang? */ uint positionToReturn = reader.Position; if (reader.ReadUInt32() > 0) // Font count { uint firstFontPointer = reader.ReadUInt32(); reader.Position = firstFontPointer + 48; // There are 48 bytes of existing metadata. uint glyphsLength = reader.ReadUInt32(); reader.undertaleData.GMS2022_2 = true; if ((glyphsLength * 4) > this.Length) { reader.undertaleData.GMS2022_2 = false; } else if (glyphsLength != 0) { List <uint> glyphPointers = new List <uint>(); for (uint i = 0; i < glyphsLength; i++) { glyphPointers.Add(reader.ReadUInt32()); } foreach (uint pointer in glyphPointers) { if (reader.Position != pointer) { reader.undertaleData.GMS2022_2 = false; break; } reader.Position += 14; ushort kerningLength = reader.ReadUInt16(); reader.Position += (uint)4 * kerningLength; // combining read/write would apparently break } } } reader.Position = positionToReturn; } base.UnserializeChunk(reader); Padding = reader.ReadBytes(512); }
internal override void UnserializeChunk(UndertaleReader reader) { uint startPosition = reader.Position; InstanceVarCount = reader.ReadUInt32(); InstanceVarCountAgain = reader.ReadUInt32(); MaxLocalVarCount = reader.ReadUInt32(); List.Clear(); while (reader.Position + 20 <= startPosition + Length) { List.Add(reader.ReadUndertaleObject <UndertaleVariable>()); } }
public void Unserialize(UndertaleReader reader) { Clear(); uint count = reader.ReadUInt32(); Util.DebugUtil.Assert(count % 2 == 0); count /= 2; for (int i = 0; i < count; i++) { Add(new DebugInfoPair() { BytecodeOffset = reader.ReadUInt32(), SourceCodeOffset = reader.ReadUInt32() }); } }
/// <inheritdoc /> public void Unserialize(UndertaleReader reader) { uint len = reader.ReadUInt32(); Data = reader.ReadBytes((int)len); Util.DebugUtil.Assert(Data.Length == len); }
internal override void UnserializeChunk(UndertaleReader reader) { Chunks.Clear(); uint startPos = reader.Position; // First, find the last chunk in the file because of padding changes // (also, calculate all present chunks while we're at it) reader.AllChunkNames = new List <string>(); string lastChunk = ""; while (reader.Position < reader.BaseStream.Length) { lastChunk = new string(reader.ReadChars(4)); reader.AllChunkNames.Add(lastChunk); uint length = reader.ReadUInt32(); reader.Position += length; } reader.LastChunkName = lastChunk; reader.Position = startPos; // Now, parse the chunks while (reader.Position < startPos + Length) { UndertaleChunk chunk = reader.ReadUndertaleChunk(); if (chunk != null) { if (Chunks.ContainsKey(chunk.Name)) { throw new IOException("Duplicate chunk " + chunk.Name); } Chunks.Add(chunk.Name, chunk); } } }
public void Unserialize(UndertaleReader reader) { Name = reader.ReadUndertaleString(); Occurrences = reader.ReadUInt32(); if (Occurrences > 0) { if (reader.GMS2_3) { GMS2_3 = true; FirstAddress = reader.GetUndertaleObjectAtAddress <UndertaleInstruction>(reader.ReadUInt32() - 4); } else { FirstAddress = reader.ReadUndertaleObjectPointer <UndertaleInstruction>(); } UndertaleInstruction.Reference <UndertaleFunction> .ParseReferenceChain(reader, this); } else { if (reader.ReadInt32() != -1) { throw new Exception("Function with no occurrences, but still has a first occurrence address"); } FirstAddress = null; } }
public void Unserialize(UndertaleReader reader) { Name = reader.ReadUndertaleString(); Occurrences = reader.ReadUInt32(); if (Occurrences > 0) { FirstAddress = reader.ReadUndertaleObjectPointer <UndertaleInstruction>(); // Parse the chain of references UndertaleInstruction.Reference <UndertaleFunction> reference = null; uint addr = reader.GetAddressForUndertaleObject(FirstAddress); for (int i = 0; i < Occurrences; i++) { reference = reader.GetUndertaleObjectAtAddress <UndertaleInstruction>(addr).GetReference <UndertaleFunction>(); if (reference == null) { throw new IOException("Failed to find reference at " + addr); } reference.Target = this; addr += (uint)reference.NextOccurrenceOffset; } UnknownChainEndingValue = reference.NextOccurrenceOffset; } else { if (reader.ReadInt32() != -1) { throw new Exception("Function with no occurrences, but still has a first occurrence address"); } FirstAddress = null; } }
internal override void UnserializeChunk(UndertaleReader reader) { if (reader.undertaleData.GeneralInfo.Major < 2) { throw new InvalidOperationException(); } // Apparently SEQN can be empty if (Length == 0) { return; } // Padding while (reader.Position % 4 != 0) { if (reader.ReadByte() != 0) { throw new IOException("Padding error!"); } } uint version = reader.ReadUInt32(); if (version != 1) { throw new IOException("Expected SEQN version 1, got " + version.ToString()); } base.UnserializeChunk(reader); }
public void Unserialize(UndertaleReader reader) { Name = reader.ReadUndertaleString(); int momentCount = reader.ReadInt32(); // Read the time points for each moment uint[] timePoints = new uint[momentCount]; int[] unnecessaryPointers = new int[momentCount]; for (int i = 0; i < momentCount; i++) { timePoints[i] = reader.ReadUInt32(); unnecessaryPointers[i] = reader.ReadInt32(); } // Read the actions for each moment for (int i = 0; i < momentCount; i++) { if (reader.Position != unnecessaryPointers[i]) { throw new UndertaleSerializationException("Invalid action list pointer"); } // Read action list and assign time point (put into list) var timeEvent = reader.ReadUndertaleObject <UndertalePointerList <UndertaleGameObject.EventAction> >(); Moments.Add(new UndertaleTimelineMoment(timePoints[i], timeEvent)); } }
public static UndertaleChunk Unserialize(UndertaleReader reader) { string name = "(unknown)"; try { name = new string(reader.ReadChars(4)); uint length = reader.ReadUInt32(); // TODO: I can't think of a cleaner way to do this... Type type = Type.GetType(typeof(UndertaleChunk).FullName + name); if (type == null) { throw new IOException("Unknown chunk " + name + "!!!"); /*Debug.WriteLine("Unknown chunk " + name + "!!!"); * reader.Position = reader.Position + length; * return null;*/ } UndertaleChunk chunk = (UndertaleChunk)Activator.CreateInstance(type); Debug.Assert(chunk.Name == name); chunk.Length = length; Debug.WriteLine("Reading chunk " + chunk.Name); var lenReader = reader.EnsureLengthFromHere(chunk.Length); chunk.UnserializeChunk(reader); if (name != "FORM" && name != "AUDO") // TODO: needs a better way to detect last chunk { UndertaleGeneralInfo generalInfo = name == "GEN8" ? ((UndertaleChunkGEN8)chunk).Object : reader.undertaleData.GeneralInfo; // These versions introduced new padding // all chunks now start on 16-byte boundaries // (but the padding is included with length of previous chunk) if (generalInfo.Major >= 2 || (generalInfo.Major == 1 && generalInfo.Build >= 9999)) { while (reader.Position % 16 != 0) { if (reader.ReadByte() != 0) { throw new Exception("Chunk padding error"); } } } } lenReader.ToHere(); return(chunk); } catch (UndertaleSerializationException e) { throw new UndertaleSerializationException(e.Message + " in chunk " + name); } catch (Exception e) { throw new UndertaleSerializationException(e.Message + "\nat " + reader.Position.ToString("X8") + " while reading chunk " + name, e); } }
public void Unserialize(UndertaleReader reader) { Filename = reader.ReadUndertaleString(); CleanupScript = reader.ReadUndertaleString(); InitScript = reader.ReadUndertaleString(); Kind = (UndertaleExtensionKind)reader.ReadUInt32(); Functions = reader.ReadUndertaleObject <UndertalePointerList <UndertaleExtensionFunction> >(); }
public void Unserialize(UndertaleReader reader) { Name = reader.ReadUndertaleString(); IsSmooth = reader.ReadBoolean(); IsClosed = reader.ReadBoolean(); Precision = reader.ReadUInt32(); Points = reader.ReadUndertaleObject <UndertaleSimpleList <PathPoint> >(); }
public override void Unserialize(UndertaleReader reader) { base.Unserialize(reader); if (reader.ReadUInt32() != 0) { throw new IOException("Expected 0 in Audio keyframe"); } Mode = reader.ReadInt32(); }
/// <summary> /// Deserializes from a specified <see cref="UndertaleReader"/> to the current data file. /// </summary> /// <param name="reader">Where to deserialize from.</param> /// <param name="includeName">Whether to include <see cref="Name"/> in the deserialization.</param> public void Unserialize(UndertaleReader reader, bool includeName) { if (includeName) { Name = reader.ReadUndertaleString(); } GraphType = (GraphTypeEnum)reader.ReadUInt32(); Channels = reader.ReadUndertaleObject <UndertaleSimpleList <Channel> >(); }
public void Unserialize(UndertaleReader reader) { Unknown1 = reader.ReadUInt32(); LanguageCount = reader.ReadUInt32(); EntryCount = reader.ReadUInt32(); // Read the identifiers for each entry for (int i = 0; i < EntryCount; i++) { EntryIDs.Add(reader.ReadUndertaleString()); } // Read the data for each language for (int i = 0; i < LanguageCount; i++) { LanguageData ld = new LanguageData(); ld.Unserialize(reader, EntryCount); Languages.Add(ld); } }
internal override void UnserializeChunk(UndertaleReader reader) { if (reader.undertaleData.GeneralInfo.Major < 2) { throw new InvalidOperationException(); } if (reader.ReadUInt32() != 1) { throw new IOException("Expected TGIN version 1"); } base.UnserializeChunk(reader); }
public void Unserialize(UndertaleReader reader) { uint count = reader.ReadUInt32(); Name = reader.ReadUndertaleString(); Locals.Clear(); for (uint i = 0; i < count; i++) { Locals.Add(reader.ReadUndertaleObject <LocalVar>()); } Debug.Assert(Locals.Count == count); }
internal override void UnserializeChunk(UndertaleReader reader) { if (reader.undertaleData.GeneralInfo.Major < 2) { throw new InvalidOperationException(); } if (reader.ReadUInt32() != 1) { throw new Exception("Should be hardcoded 1"); } base.UnserializeChunk(reader); }
internal override void UnserializeChunk(UndertaleReader reader) { if (Length == 0) { throw new Exception("This game uses YYC (YoYo Compiler). This is currently not supported."); } if (reader.undertaleData.UnsupportedBytecodeVersion) { return; } uint startPosition = reader.Position; InstanceVarCount = reader.ReadUInt32(); InstanceVarCountAgain = reader.ReadUInt32(); MaxLocalVarCount = reader.ReadUInt32(); List.Clear(); while (reader.Position + 20 <= startPosition + Length) { List.Add(reader.ReadUndertaleObject <UndertaleVariable>()); } }
public void Unserialize(UndertaleReader reader) { Unknown1 = reader.ReadUInt32(); Unknown2 = reader.ReadUInt32(); Info = (OptionsFlags)reader.ReadUInt64(); Scale = reader.ReadInt32(); WindowColor = reader.ReadUInt32(); ColorDepth = reader.ReadUInt32(); Resolution = reader.ReadUInt32(); Frequency = reader.ReadUInt32(); VertexSync = reader.ReadUInt32(); Priority = reader.ReadUInt32(); BackImage = reader.ReadUndertaleObject <UndertaleSprite.TextureEntry>(); FrontImage = reader.ReadUndertaleObject <UndertaleSprite.TextureEntry>(); LoadImage = reader.ReadUndertaleObject <UndertaleSprite.TextureEntry>(); LoadAlpha = reader.ReadUInt32(); Constants = reader.ReadUndertaleObject <UndertaleSimpleList <Constant> >(); }
internal override void UnserializeChunk(UndertaleReader reader) { uint count = reader.ReadUInt32(); for (int i = 0; i < count; i++) { Align &= (reader.ReadUInt32() % Alignment == 0); } for (int i = 0; i < count; i++) { if (Align) { while (reader.Position % Alignment != 0) { if (reader.ReadByte() != 0) { throw new IOException("AlignUpdatedListChunk padding error"); } } } List.Add(reader.ReadUndertaleObject <T>()); } }