/// <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(); 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) { X = reader.ReadSingle(); Value = reader.ReadSingle(); if (reader.ReadInt32() != 0) { throw new Exception("Expected 0 in animation curve point"); // TODO? They might add some "control points" here later it seems } }
public void Unserialize(UndertaleReader reader) { Key = reader.ReadSingle(); Length = reader.ReadSingle(); Stretch = reader.ReadBoolean(); Disabled = reader.ReadBoolean(); int count = reader.ReadInt32(); Channels = new Dictionary <int, T>(); for (int i = 0; i < count; i++) { int channel = reader.ReadInt32(); T data = new T(); data.Unserialize(reader); Channels[channel] = data; } }
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; } }
public void Unserialize(UndertaleReader reader) { DisableDebugger = reader.ReadByte() != 0 ? true : false; BytecodeVersion = reader.ReadByte(); Unknown = reader.ReadUInt16(); Filename = reader.ReadUndertaleString(); Config = reader.ReadUndertaleString(); LastObj = reader.ReadUInt32(); LastTile = reader.ReadUInt32(); GameID = reader.ReadUInt32(); Unknown1 = reader.ReadUInt32(); Unknown2 = reader.ReadUInt32(); Unknown3 = reader.ReadUInt32(); Unknown4 = reader.ReadUInt32(); Name = reader.ReadUndertaleString(); Major = reader.ReadUInt32(); Minor = reader.ReadUInt32(); Release = reader.ReadUInt32(); Build = reader.ReadUInt32(); DefaultWindowWidth = reader.ReadUInt32(); DefaultWindowHeight = reader.ReadUInt32(); Info = (InfoFlags)reader.ReadUInt32(); LicenseMD5 = reader.ReadBytes(16); LicenseCRC32 = reader.ReadUInt32(); Timestamp = reader.ReadUInt64(); DisplayName = reader.ReadUndertaleString(); ActiveTargets1 = reader.ReadUInt32(); ActiveTargets2 = reader.ReadUInt32(); FunctionClassifications1 = reader.ReadUInt32(); FunctionClassifications2 = reader.ReadUInt32(); SteamAppID = reader.ReadInt32(); DebuggerPort = reader.ReadUInt32(); RoomOrder = reader.ReadUndertaleObject <UndertaleSimpleResourcesList <UndertaleRoom, UndertaleChunkROOM> >(); if (Major >= 2) { GMS2RandomUID = reader.ReadBytes(40); GMS2FPS = reader.ReadSingle(); GMS2AllowStatistics = reader.ReadBoolean(); GMS2GameGUID = reader.ReadBytes(16); } reader.undertaleData.UnsupportedBytecodeVersion = BytecodeVersion < 14 || BytecodeVersion > 17; reader.Bytecode14OrLower = BytecodeVersion <= 14; }
public void Unserialize(UndertaleReader reader) { DisableDebugger = reader.ReadByte() != 0 ? true : false; BytecodeVersion = reader.ReadByte(); Unknown = reader.ReadUInt16(); Filename = reader.ReadUndertaleString(); Config = reader.ReadUndertaleString(); LastObj = reader.ReadUInt32(); LastTile = reader.ReadUInt32(); GameID = reader.ReadUInt32(); byte[] GuidData = reader.ReadBytes(16); DirectPlayGuid = new Guid(GuidData); Name = reader.ReadUndertaleString(); Major = reader.ReadUInt32(); Minor = reader.ReadUInt32(); Release = reader.ReadUInt32(); Build = reader.ReadUInt32(); DefaultWindowWidth = reader.ReadUInt32(); DefaultWindowHeight = reader.ReadUInt32(); Info = (InfoFlags)reader.ReadUInt32(); LicenseMD5 = reader.ReadBytes(16); LicenseCRC32 = reader.ReadUInt32(); Timestamp = reader.ReadUInt64(); DisplayName = reader.ReadUndertaleString(); ActiveTargets = reader.ReadUInt64(); FunctionClassifications = (FunctionClassification)reader.ReadUInt64(); SteamAppID = reader.ReadInt32(); DebuggerPort = reader.ReadUInt32(); RoomOrder = reader.ReadUndertaleObject <UndertaleSimpleResourcesList <UndertaleRoom, UndertaleChunkROOM> >(); if (Major >= 2) { // Begin parsing random UID, and verify it based on original algorithm GMS2RandomUID = new List <long>(); Random random = new Random((int)(Timestamp & 4294967295L)); long firstRandom = (long)random.Next() << 32 | (long)random.Next(); if (reader.ReadInt64() != firstRandom) { //throw new IOException("Unexpected random UID"); } long infoNumber = (long)(Timestamp - 1000); ulong temp = (ulong)infoNumber; temp = ((temp << 56 & 18374686479671623680UL) | (temp >> 8 & 71776119061217280UL) | (temp << 32 & 280375465082880UL) | (temp >> 16 & 1095216660480UL) | (temp << 8 & 4278190080UL) | (temp >> 24 & 16711680UL) | (temp >> 16 & 65280UL) | (temp >> 32 & 255UL)); infoNumber = (long)temp; infoNumber ^= firstRandom; infoNumber = ~infoNumber; infoNumber ^= ((long)GameID << 32 | (long)GameID); infoNumber ^= ((long)(DefaultWindowWidth + (int)Info) << 48 | (long)(DefaultWindowHeight + (int)Info) << 32 | (long)(DefaultWindowHeight + (int)Info) << 16 | (long)(DefaultWindowWidth + (int)Info)); infoNumber ^= BytecodeVersion; int infoLocation = (int)(Math.Abs((int)(Timestamp & 65535L) / 7 + (GameID - DefaultWindowWidth) + RoomOrder.Count) % 4); for (int i = 0; i < 4; i++) { if (i == infoLocation) { long curr = reader.ReadInt64(); curr = infoNumber; GMS2RandomUID.Add(curr); } else { int first = reader.ReadInt32(); int second = reader.ReadInt32(); first = random.Next(); second = random.Next(); GMS2RandomUID.Add(((long)first << 32) | (long)second); } } GMS2FPS = reader.ReadSingle(); GMS2AllowStatistics = reader.ReadBoolean(); GMS2GameGUID = reader.ReadBytes(16); } reader.undertaleData.UnsupportedBytecodeVersion = BytecodeVersion < 14 || BytecodeVersion > 17; reader.Bytecode14OrLower = BytecodeVersion <= 14; }
public override void Unserialize(UndertaleReader reader) { Value = reader.ReadSingle(); base.Unserialize(reader); }
public void Unserialize(UndertaleReader reader) { X = reader.ReadSingle(); Y = reader.ReadSingle(); Speed = reader.ReadSingle(); }
public void Unserialize(UndertaleReader reader) { uint instructionStartAddress = reader.Position; reader.ReadByte(); reader.ReadByte(); reader.ReadByte(); // skip for now, we'll read them later Kind = (Opcode)reader.ReadByte(); reader.Position = instructionStartAddress; switch (GetInstructionType(Kind)) { case InstructionType.SingleTypeInstruction: case InstructionType.DoubleTypeInstruction: case InstructionType.ComparisonInstruction: { DupExtra = reader.ReadByte(); if (DupExtra != 0 && Kind != Opcode.Dup) { throw new IOException("Invalid padding in " + Kind.ToString().ToUpper()); } ComparisonKind = (ComparisonType)reader.ReadByte(); if ((Kind == Opcode.Cmp) != ((byte)ComparisonKind != 0)) { throw new IOException("Got unexpected comparison type in " + Kind.ToString().ToUpper() + " (should be only in CMP)"); } byte TypePair = reader.ReadByte(); Type1 = (DataType)(TypePair & 0xf); Type2 = (DataType)(TypePair >> 4); if (GetInstructionType(Kind) == InstructionType.SingleTypeInstruction && Type2 != (byte)0) { throw new IOException("Second type should be 0 in " + Kind.ToString().ToUpper()); } if (reader.ReadByte() != (byte)Kind) { throw new Exception("really shouldn't happen"); } } break; case InstructionType.GotoInstruction: { uint v = reader.ReadUInt24(); // TODO: This is SO WRONG that I don't even believe it. Is that Int24 or Int23?!?! uint r = v & 0x003FFFFF; if ((v & 0x00C00000) != 0) { r |= 0xFFC00000; } JumpOffset = (int)r; JumpOffsetIsWeird = (v & 0x00800000) != 0; if (reader.ReadByte() != (byte)Kind) { throw new Exception("really shouldn't happen"); } } break; case InstructionType.PopInstruction: { TypeInst = (InstanceType)reader.ReadInt16(); byte TypePair = reader.ReadByte(); Type1 = (DataType)(TypePair & 0xf); Type2 = (DataType)(TypePair >> 4); if (reader.ReadByte() != (byte)Kind) { throw new Exception("really shouldn't happen"); } Destination = reader.ReadUndertaleObject <Reference <UndertaleVariable> >(); } break; case InstructionType.PushInstruction: { short val = reader.ReadInt16(); Type1 = (DataType)reader.ReadByte(); if (reader.ReadByte() != (byte)Kind) { throw new Exception("really shouldn't happen"); } switch (Type1) { case DataType.Double: Value = reader.ReadDouble(); break; case DataType.Float: Value = reader.ReadSingle(); break; case DataType.Int32: Value = reader.ReadInt32(); break; case DataType.Int64: Value = reader.ReadInt64(); break; case DataType.Boolean: Value = (reader.ReadUInt32() == 1); // TODO: double check break; case DataType.Variable: TypeInst = (InstanceType)val; Value = reader.ReadUndertaleObject <Reference <UndertaleVariable> >(); break; case DataType.String: UndertaleResourceById <UndertaleString> str = new UndertaleResourceById <UndertaleString>("STRG"); str.Unserialize(reader, reader.ReadInt32()); Value = str; break; case DataType.Int16: Value = val; break; } } break; case InstructionType.CallInstruction: { ArgumentsCount = reader.ReadUInt16(); Type1 = (DataType)reader.ReadByte(); if (reader.ReadByte() != (byte)Kind) { throw new Exception("really shouldn't happen"); } Function = reader.ReadUndertaleObject <Reference <UndertaleFunction> >(); } break; case InstructionType.BreakInstruction: { Value = reader.ReadInt16(); Type1 = (DataType)reader.ReadByte(); if (reader.ReadByte() != (byte)Kind) { throw new Exception("really shouldn't happen"); } } break; default: throw new IOException("Unknown opcode " + Kind.ToString().ToUpper()); } }
public void Unserialize(UndertaleReader reader) { uint instructionStartAddress = reader.Position; reader.ReadByte(); reader.ReadByte(); reader.ReadByte(); // skip for now, we'll read them later Kind = (Opcode)reader.ReadByte(); reader.Position = instructionStartAddress; switch (GetInstructionType(Kind)) { case InstructionType.SingleTypeInstruction: case InstructionType.DoubleTypeInstruction: case InstructionType.ComparisonInstruction: { DupExtra = reader.ReadByte(); if (DupExtra != 0 && Kind != Opcode.Dup) { throw new IOException("Invalid padding in " + Kind.ToString().ToUpper()); } ComparisonKind = (ComparisonType)reader.ReadByte(); if ((Kind == Opcode.Cmp) != ((byte)ComparisonKind != 0)) { throw new IOException("Got unexpected comparison type in " + Kind.ToString().ToUpper() + " (should be only in CMP)"); } byte TypePair = reader.ReadByte(); Type1 = (DataType)(TypePair & 0xf); Type2 = (DataType)(TypePair >> 4); if (GetInstructionType(Kind) == InstructionType.SingleTypeInstruction && Type2 != (byte)0) { throw new IOException("Second type should be 0 in " + Kind.ToString().ToUpper()); } if (reader.ReadByte() != (byte)Kind) { throw new Exception("really shouldn't happen"); } } break; case InstructionType.GotoInstruction: { uint v = reader.ReadUInt24(); JumpOffsetPopenvExitMagic = (v & 0x800000) != 0; // The rest is int23 signed value, so make sure uint r = v & 0x003FFFFF; if (JumpOffsetPopenvExitMagic && v != 0xF00000) { throw new Exception("Popenv magic doesn't work, call issue #90 again"); } else { if ((v & 0x00C00000) != 0) { r |= 0xFFC00000; } JumpOffset = (int)r; } if (reader.ReadByte() != (byte)Kind) { throw new Exception("really shouldn't happen"); } } break; case InstructionType.PopInstruction: { TypeInst = (InstanceType)reader.ReadInt16(); byte TypePair = reader.ReadByte(); Type1 = (DataType)(TypePair & 0xf); Type2 = (DataType)(TypePair >> 4); if (reader.ReadByte() != (byte)Kind) { throw new Exception("really shouldn't happen"); } if (Type1 == DataType.Int16) { // Special scenario - the swap instruction // TODO: Figure out the proper syntax, see #129 SwapExtra = (ushort)TypeInst; TypeInst = 0; } else { Destination = reader.ReadUndertaleObject <Reference <UndertaleVariable> >(); } } break; case InstructionType.PushInstruction: { short val = reader.ReadInt16(); Type1 = (DataType)reader.ReadByte(); if (reader.ReadByte() != (byte)Kind) { throw new Exception("really shouldn't happen"); } switch (Type1) { case DataType.Double: Value = reader.ReadDouble(); break; case DataType.Float: Value = reader.ReadSingle(); break; case DataType.Int32: Value = reader.ReadInt32(); break; case DataType.Int64: Value = reader.ReadInt64(); break; case DataType.Boolean: Value = (reader.ReadUInt32() == 1); // TODO: double check break; case DataType.Variable: TypeInst = (InstanceType)val; Value = reader.ReadUndertaleObject <Reference <UndertaleVariable> >(); break; case DataType.String: Value = reader.ReadUndertaleObject <UndertaleResourceById <UndertaleString, UndertaleChunkSTRG> >(); break; case DataType.Int16: Value = val; break; } } break; case InstructionType.CallInstruction: { ArgumentsCount = reader.ReadUInt16(); Type1 = (DataType)reader.ReadByte(); if (reader.ReadByte() != (byte)Kind) { throw new Exception("really shouldn't happen"); } Function = reader.ReadUndertaleObject <Reference <UndertaleFunction> >(); } break; case InstructionType.BreakInstruction: { Value = reader.ReadInt16(); Type1 = (DataType)reader.ReadByte(); if (reader.ReadByte() != (byte)Kind) { throw new Exception("really shouldn't happen"); } } break; default: throw new IOException("Unknown opcode " + Kind.ToString().ToUpper()); } }