Skip to content

Commit

Permalink
Implemented "UnserializeChildObjectCount()" for more models, and othe…
Browse files Browse the repository at this point in the history
…r changes.

1) Removed leftover variables in "UndertaleCode".
2) Renamed "UndertaleListBase<T>.AddDirect()" to "...InternalAdd()".
3) More improvements of count unserialization error handling.
4) Fixed "UndertaleReader.GetUnserializeCountFunc()" for generic types.
5) Fixed count unserialization of some chunks and lists.
6) Moved GMS 2.3.1 check from "UndertaleAnimationCurve.Point" to the "ACRV" chunk.
7) More of little optimizations of some models unserialization.
8) Reorganized track keyframes related code of "UndertaleSequence".
  • Loading branch information
VladiStep committed Feb 13, 2023
1 parent 9359326 commit ce4ac18
Show file tree
Hide file tree
Showing 14 changed files with 875 additions and 356 deletions.
43 changes: 27 additions & 16 deletions UndertaleModLib/Models/UndertaleAnimationCurve.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,24 @@ public void Unserialize(UndertaleReader reader, bool includeName)
Channels = reader.ReadUndertaleObject<UndertaleSimpleList<Channel>>();
}

/// <inheritdoc cref="UndertaleObject.UnserializeChildObjectCount(UndertaleReader)"/>
public static uint UnserializeChildObjectCount(UndertaleReader reader)
{
return UnserializeChildObjectCount(reader, true);
}

/// <inheritdoc cref="UndertaleObject.UnserializeChildObjectCount(UndertaleReader)"/>
/// <param name="reader">Where to deserialize from.</param>
/// <param name="includeName">Whether to include <see cref="Name"/> in the deserialization.</param>
public static uint UnserializeChildObjectCount(UndertaleReader reader, bool includeName)
{
if (includeName)
reader.Position += 4; // "Name"
reader.Position += 4; // "GraphType"

return 1 + UndertaleSimpleList<Channel>.UnserializeChildObjectCount(reader);
}

/// <inheritdoc />
public override string ToString()
{
Expand Down Expand Up @@ -122,7 +140,14 @@ public static uint UnserializeChildObjectCount(UndertaleReader reader)
{
reader.Position += 12;

return reader.ReadUInt32();
// "Points"
uint count = reader.ReadUInt32();
if (reader.undertaleData.GMS2_3_1)
reader.Position += 24 * count;
else
reader.Position += 12 * count;

return count;
}

/// <inheritdoc/>
Expand All @@ -134,10 +159,8 @@ public void Dispose()
Points = null;
}

public class Point : UndertaleObject, IStaticChildObjectsSize
public class Point : UndertaleObject
{
public static readonly uint ChildObjectsSize = 0;

public float X;
public float Value;

Expand Down Expand Up @@ -169,18 +192,6 @@ 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();
Expand Down
4 changes: 0 additions & 4 deletions UndertaleModLib/Models/UndertaleCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1194,12 +1194,8 @@ public static uint UnserializeChildObjectCount(UndertaleReader reader)

// Get instructions count
uint instrCount = 0;
int instrCount1 = 0;
while (reader.Position < bytecodeAbsoluteAddress + length)
{
instrCount1++;
instrCount += 1 + UndertaleInstruction.UnserializeChildObjectCount(reader);
}

reader.Position = here;
reader.Position += 4; // "Offset"
Expand Down
56 changes: 54 additions & 2 deletions UndertaleModLib/Models/UndertaleExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,11 @@ public enum UndertaleExtensionVarType : uint
/// A class representing an argument for <see cref="UndertaleExtensionFunction"/>s.
/// </summary>
[PropertyChanged.AddINotifyPropertyChangedInterface]
public class UndertaleExtensionFunctionArg : UndertaleObject
public class UndertaleExtensionFunctionArg : UndertaleObject, IStaticChildObjectsSize
{
/// <inheritdoc cref="IStaticChildObjectsSize.ChildObjectsSize" />
public static readonly uint ChildObjectsSize = 4;

/// <summary>
/// The variable type of this argument.
/// </summary>
Expand Down Expand Up @@ -140,6 +143,18 @@ public void Unserialize(UndertaleReader reader)
Arguments = reader.ReadUndertaleObject<UndertaleSimpleList<UndertaleExtensionFunctionArg>>();
}

/// <inheritdoc cref="UndertaleObject.UnserializeChildObjectCount(UndertaleReader)"/>
public static uint UnserializeChildObjectCount(UndertaleReader reader)
{
uint count = 0;

reader.Position += 20;

count += 1 + UndertaleSimpleList<UndertaleExtensionFunctionArg>.UnserializeChildObjectCount(reader);

return count;
}

/// <inheritdoc />
public override string ToString()
{
Expand Down Expand Up @@ -186,6 +201,18 @@ public void Unserialize(UndertaleReader reader)
Functions = reader.ReadUndertaleObject<UndertalePointerList<UndertaleExtensionFunction>>();
}

/// <inheritdoc cref="UndertaleObject.UnserializeChildObjectCount(UndertaleReader)"/>
public static uint UnserializeChildObjectCount(UndertaleReader reader)
{
uint count = 0;

reader.Position += 16;

count += 1 + UndertalePointerList<UndertaleExtensionFunction>.UnserializeChildObjectCount(reader);

return count;
}

/// <inheritdoc />
public override string ToString()
{
Expand Down Expand Up @@ -218,8 +245,11 @@ public void Dispose()


[PropertyChanged.AddINotifyPropertyChangedInterface]
public class UndertaleExtensionOption : UndertaleObject, IDisposable
public class UndertaleExtensionOption : UndertaleObject, IStaticChildObjectsSize, IDisposable
{
/// <inheritdoc cref="IStaticChildObjectsSize.ChildObjectsSize" />
public static readonly uint ChildObjectsSize = 12;

public enum OptionKind : uint
{
Boolean = 0,
Expand Down Expand Up @@ -344,4 +374,26 @@ public void Unserialize(UndertaleReader reader)
Files = reader.ReadUndertaleObject<UndertalePointerList<UndertaleExtensionFile>>();
}
}

/// <inheritdoc cref="UndertaleObject.UnserializeChildObjectCount(UndertaleReader)"/>
public static uint UnserializeChildObjectCount(UndertaleReader reader)
{
uint count = 0;

reader.Position += 12;
if (reader.undertaleData.GM2022_6)
{
uint filesPtr = reader.ReadUInt32();
uint optionsPtr = reader.ReadUInt32();

reader.Position = filesPtr;
count += 1 + UndertalePointerList<UndertaleExtensionFile>.UnserializeChildObjectCount(reader);
reader.Position = optionsPtr;
count += 1 + UndertalePointerList<UndertaleExtensionOption>.UnserializeChildObjectCount(reader);
}
else
count += 1 + UndertalePointerList<UndertaleExtensionFile>.UnserializeChildObjectCount(reader);

return count;
}
}
21 changes: 19 additions & 2 deletions UndertaleModLib/Models/UndertaleFunction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ namespace UndertaleModLib.Models;
/// A function entry as it's used in a GameMaker data file.
/// </summary>
[PropertyChanged.AddINotifyPropertyChangedInterface]
public class UndertaleFunction : UndertaleNamedResource, UndertaleInstruction.ReferencedObject, IDisposable
public class UndertaleFunction : UndertaleNamedResource, UndertaleInstruction.ReferencedObject, IStaticChildObjectsSize, IDisposable
{
/// <inheritdoc cref="IStaticChildObjectsSize.ChildObjectsSize" />
public static readonly uint ChildObjectsSize = 12;

public FunctionClassification Classification { get; set; }

/// <summary>
Expand Down Expand Up @@ -120,14 +123,28 @@ public void Unserialize(UndertaleReader reader)
Util.DebugUtil.Assert(Locals.Count == count);
}

/// <inheritdoc cref="UndertaleObject.UnserializeChildObjectCount(UndertaleReader)"/>
public static uint UnserializeChildObjectCount(UndertaleReader reader)
{
uint count = reader.ReadUInt32();
reader.Position += 4; // "Name"

reader.Position += count * LocalVar.ChildObjectsSize;

return count;
}

public bool HasLocal(string varName)
{
return Locals.Any(local=>local.Name.Content == varName);
}

// TODO: INotifyPropertyChanged
public class LocalVar : UndertaleObject, IDisposable
public class LocalVar : UndertaleObject, IStaticChildObjectsSize, IDisposable
{
/// <inheritdoc cref="IStaticChildObjectsSize.ChildObjectsSize" />
public static readonly uint ChildObjectsSize = 8;

public uint Index { get; set; }
public UndertaleString Name { get; set; }

Expand Down
2 changes: 1 addition & 1 deletion UndertaleModLib/Models/UndertaleGameObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ public UndertaleGameObject()
{
Events.SetCapacity(eventTypesLength);
for (int i = 0; i < eventTypesLength; i++)
Events.AddDirect(new UndertalePointerList<Event>());
Events.InternalAdd(new UndertalePointerList<Event>());
}

/// <inheritdoc />
Expand Down
4 changes: 2 additions & 2 deletions UndertaleModLib/Models/UndertaleRoom.cs
Original file line number Diff line number Diff line change
Expand Up @@ -258,9 +258,9 @@ public UndertaleRoom()
Backgrounds.SetCapacity(8);
Views.SetCapacity(8);
for (int i = 0; i < 8; i++)
Backgrounds.AddDirect(new Background());
Backgrounds.InternalAdd(new Background());
for (int i = 0; i < 8; i++)
Views.AddDirect(new View());
Views.InternalAdd(new View());
if (Flags.HasFlag(RoomEntryFlags.EnableViews))
Views[0].Enabled = true;
}
Expand Down
Loading

0 comments on commit ce4ac18

Please sign in to comment.