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; } }
public void Unserialize(UndertaleReader reader) { Name = reader.ReadUndertaleString(); Occurrences = reader.ReadUInt32(); if (Occurrences > 0) { 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; } }
//private static int id = 0; public void Unserialize(UndertaleReader reader) { Name = reader.ReadUndertaleString(); InstanceType = (UndertaleInstruction.InstanceType)reader.ReadInt32(); VarID = reader.ReadInt32(); Occurrences = reader.ReadUInt32(); //Debug.WriteLine("Variable " + (id++) + " at " + reader.GetAddressForUndertaleObject(Name).ToString("X8") + " child of " + Unknown); if (Occurrences > 0) { FirstAddress = reader.ReadUndertaleObjectPointer <UndertaleInstruction>(); // Parse the chain of references UndertaleInstruction.Reference <UndertaleVariable> reference = null; uint addr = reader.GetAddressForUndertaleObject(FirstAddress); for (int i = 0; i < Occurrences; i++) { reference = reader.GetUndertaleObjectAtAddress <UndertaleInstruction>(addr).GetReference <UndertaleVariable>(); if (reference == null) { throw new IOException("Failed to find reference at " + addr); } reference.Target = this; // Debug.WriteLine("* " + addr.ToString("X8")); addr += (uint)reference.NextOccurrenceOffset; } //Debug.WriteLine("* " + reference.NextOccurrenceOffset.ToString() + " (ending value)"); UnknownChainEndingValue = reference.NextOccurrenceOffset; } else { if (reader.ReadInt32() != -1) { throw new Exception("Variable with no occurrences, but still has a first occurrence address"); } FirstAddress = null; } }
public static int CalculateStackDiff(UndertaleInstruction instr) { switch (instr.Kind) { case Opcode.Neg: case Opcode.Not: return(0); case Opcode.Dup: return(1 + instr.DupExtra); case Opcode.Ret: return(-1); case Opcode.Exit: return(0); case Opcode.Popz: return(-1); case Opcode.Conv: return(0); case Opcode.Mul: case Opcode.Div: case Opcode.Rem: case Opcode.Mod: case Opcode.Add: case Opcode.Sub: case Opcode.And: case Opcode.Or: case Opcode.Xor: case Opcode.Shl: case Opcode.Shr: case Opcode.Cmp: return(-2 + 1); case Opcode.B: return(0); case Opcode.Bt: case Opcode.Bf: case Opcode.PushEnv: return(-1); case Opcode.PopEnv: return(0); case Opcode.Pop: if (instr.Destination.Type == VariableType.StackTop) { return(-1 - 1); } if (instr.Destination.Type == VariableType.Array) { return(-1 - 2); } return(-1); case Opcode.Push: case Opcode.PushLoc: case Opcode.PushGlb: case Opcode.PushVar: case Opcode.PushI: if (instr.Value is Reference <UndertaleVariable> ) { if ((instr.Value as Reference <UndertaleVariable>).Type == VariableType.StackTop) { return(1 - 1); } if ((instr.Value as Reference <UndertaleVariable>).Type == VariableType.Array) { return(1 - 2); } } return(1); case Opcode.Call: return(-instr.ArgumentsCount + 1); case Opcode.Break: return(0); default: throw new IOException("Unknown opcode " + instr.Kind.ToString().ToUpper()); } }