Exemple #1
0
        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;
            }
        }
Exemple #4
0
        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());
            }
        }