public void Serialize(GMDataWriter writer)
        {
            writer.WritePointerString(Name);
            writer.Write(Occurrences);

            List <int> references;

            if (writer.FunctionReferences.TryGetValue(this, out references))
            {
                Occurrences = references.Count;
            }
            else
            {
                Occurrences = 0;
            }

            if (Occurrences > 0)
            {
                if (writer.VersionInfo.IsNumberAtLeast(2, 3))
                {
                    writer.Write(references[0] + 4);
                }
                else
                {
                    writer.Write(references[0]);
                }

                int returnTo = writer.Offset;
                for (int i = 0; i < references.Count; i++)
                {
                    int curr = references[i];

                    int nextDiff;
                    if (i < references.Count - 1)
                    {
                        nextDiff = references[i + 1] - curr;
                    }
                    else
                    {
                        nextDiff = ((GMChunkSTRG)writer.Data.Chunks["STRG"]).List.IndexOf(Name);
                    }

                    writer.Offset = curr + 4;
                    writer.WriteInt24(nextDiff);
                }
                writer.Offset = returnTo;
            }
            else
            {
                writer.Write((int)-1);
            }
        }
Пример #2
0
                public void Serialize(GMDataWriter writer)
                {
                    if (Variable != null)
                    {
                        if (Variable.Target != null)
                        {
                            List <int> l;
                            if (writer.VariableReferences.TryGetValue(Variable.Target, out l))
                            {
                                l.Add(writer.Offset);
                            }
                            else
                            {
                                writer.VariableReferences.Add(Variable.Target, new List <int> {
                                    writer.Offset
                                });
                            }
                        }
                        else
                        {
                            writer.Warnings.Add(new GMWarning($"Missing variable target at {writer.Offset}"));
                        }
                    }
                    else if (Function != null)
                    {
                        if (Function.Target != null)
                        {
                            List <int> l;
                            if (writer.FunctionReferences.TryGetValue(Function.Target, out l))
                            {
                                l.Add(writer.Offset);
                            }
                            else
                            {
                                writer.FunctionReferences.Add(Function.Target, new List <int> {
                                    writer.Offset
                                });
                            }
                        }
                        else
                        {
                            writer.Warnings.Add(new GMWarning($"Missing function target at {writer.Offset}"));
                        }
                    }

                    switch (GetInstructionType(Kind))
                    {
                    case InstructionType.SingleType:
                    case InstructionType.DoubleType:
                    case InstructionType.Comparison:
                    {
                        writer.Write(Extra);
                        if (writer.VersionInfo.FormatID <= 14 && Kind == Opcode.Cmp)
                        {
                            writer.Write((byte)0);
                        }
                        else
                        {
                            writer.Write((byte)ComparisonKind);
                        }
                        writer.Write((byte)((byte)Type2 << 4 | (byte)Type1));
                        if (writer.VersionInfo.FormatID <= 14)
                        {
                            writer.Write(NewOpcodeToOld((byte)Kind, (byte)ComparisonKind));
                        }
                        else
                        {
                            writer.Write((byte)Kind);
                        }
                    }
                    break;

                    case InstructionType.Branch:
                    {
                        if (writer.VersionInfo.FormatID <= 14)
                        {
                            writer.WriteInt24(JumpOffset);
                        }
                        else if (PopenvExitMagic)
                        {
                            writer.WriteInt24(0xF00000);
                        }
                        else
                        {
                            writer.WriteInt24((int)((uint)JumpOffset & ~0xFF800000));
                        }

                        if (writer.VersionInfo.FormatID <= 14)
                        {
                            writer.Write(NewOpcodeToOld((byte)Kind, 0));
                        }
                        else
                        {
                            writer.Write((byte)Kind);
                        }
                    }
                    break;

                    case InstructionType.Pop:
                    {
                        if (Type1 == DataType.Int16)
                        {
                            writer.Write(SwapExtra);
                            writer.Write((byte)((byte)Type2 << 4 | (byte)Type1));
                            if (writer.VersionInfo.FormatID <= 14)
                            {
                                writer.Write(NewOpcodeToOld((byte)Kind, 0));
                            }
                            else
                            {
                                writer.Write((byte)Kind);
                            }
                        }
                        else
                        {
                            writer.Write((short)TypeInst);
                            writer.Write((byte)((byte)Type2 << 4 | (byte)Type1));
                            if (writer.VersionInfo.FormatID <= 14)
                            {
                                writer.Write(NewOpcodeToOld((byte)Kind, 0));
                            }
                            else
                            {
                                writer.Write((byte)Kind);
                            }
                            Variable.Serialize(writer);
                        }
                    }
                    break;

                    case InstructionType.Push:
                    {
                        if (Type1 == DataType.Int16)
                        {
                            writer.Write((short)Value);
                        }
                        else if (Type1 == DataType.Variable)
                        {
                            writer.Write((short)TypeInst);
                        }
                        else
                        {
                            writer.Write((short)0);
                        }
                        writer.Write((byte)Type1);

                        if (writer.VersionInfo.FormatID <= 14)
                        {
                            writer.Write(NewOpcodeToOld((byte)Kind, 0));
                        }
                        else
                        {
                            writer.Write((byte)Kind);
                        }

                        switch (Type1)
                        {
                        case DataType.Double:
                            writer.Write((double)Value);
                            break;

                        case DataType.Float:
                            writer.Write((float)Value);
                            break;

                        case DataType.Int32:
                            if (Function != null)
                            {
                                Function.Serialize(writer);
                                break;
                            }
                            writer.Write((int)Value);
                            break;

                        case DataType.Int64:
                            writer.Write((long)Value);
                            break;

                        case DataType.Boolean:
                            writer.WriteWideBoolean((bool)Value);
                            break;

                        case DataType.Variable:
                            Variable.Serialize(writer);
                            break;

                        case DataType.String:
                            writer.Write((int)Value);             // string ID
                            break;
                            //case DataType.Int16:
                            //    break;
                        }
                    }
                    break;

                    case InstructionType.Call:
                    {
                        writer.Write(ArgumentsCount);
                        writer.Write((byte)Type1);
                        if (writer.VersionInfo.FormatID <= 14)
                        {
                            writer.Write(NewOpcodeToOld((byte)Kind, 0));
                        }
                        else
                        {
                            writer.Write((byte)Kind);
                        }
                        Function.Serialize(writer);
                    }
                    break;

                    case InstructionType.Break:
                    {
                        writer.Write((short)Value);
                        writer.Write((byte)Type1);
                        if (writer.VersionInfo.FormatID <= 14)
                        {
                            writer.Write(NewOpcodeToOld((byte)Kind, 0));
                        }
                        else
                        {
                            writer.Write((byte)Kind);
                        }
                    }
                    break;

                    default:
                        throw new Exception("Unknown opcode " + Kind.ToString());
                    }
                }
Пример #3
0
 public void Serialize(GMDataWriter writer)
 {
     writer.WriteInt24(0);
     writer.Write((byte)Type);
 }