예제 #1
0
 public void Unserialize(GMDataReader reader)
 {
     Name        = reader.ReadStringPointerObject();
     DisplayName = reader.ReadStringPointerObject();
     Size        = reader.ReadInt32();
     if (Size < 0)
     {
         reader.Offset -= 4;
         SizeFloat      = -reader.ReadSingle();
     }
     Bold        = reader.ReadWideBoolean();
     Italic      = reader.ReadWideBoolean();
     RangeStart  = reader.ReadUInt16();
     Charset     = reader.ReadByte();
     AntiAlias   = reader.ReadByte();
     RangeEnd    = reader.ReadInt32();
     TextureItem = reader.ReadPointer <GMTextureItem>();
     ScaleX      = reader.ReadSingle();
     ScaleY      = reader.ReadSingle();
     if (reader.VersionInfo.FormatID >= 17)
     {
         AscenderOffset = reader.ReadInt32();
     }
     Glyphs = new GMPointerList <GMGlyph>();
     Glyphs.Unserialize(reader);
 }
예제 #2
0
        public void Unserialize(GMDataReader reader)
        {
            int startOffset = reader.Offset;

            if (!reader.ReadBytes(8).SequenceEqual(new byte[8] {
                137, 80, 78, 71, 13, 10, 26, 10
            }))
            {
                reader.Warnings.Add(new GMWarning("PNG header expected.", GMWarning.WarningLevel.Bad));
            }

            while (true)
            {
                uint   length = (uint)reader.ReadByte() << 24 | (uint)reader.ReadByte() << 16 | (uint)reader.ReadByte() << 8 | (uint)reader.ReadByte();
                string type   = reader.ReadChars(4);
                reader.Offset += (int)length + 4;
                if (type == "IEND")
                {
                    break;
                }
            }

            int texLength = reader.Offset - startOffset;

            reader.Offset = startOffset;
            Data          = reader.ReadBytes(texLength);
        }
예제 #3
0
                public void Unserialize(GMDataReader reader)
                {
                    int start = reader.Offset;

                    reader.Instructions[start] = this;

#if DEBUG
                    if (start % 4 != 0)
                    {
                        throw new Exception("Instruction reading offset");
                    }
#endif

                    // Read opcode
                    reader.Offset += 3;
                    byte opcode = reader.ReadByte();
                    if (reader.VersionInfo.FormatID <= 14)
                    {
                        opcode = OldOpcodeToNew(opcode);
                    }
                    Kind          = (Opcode)opcode;
                    reader.Offset = start;

                    switch (GetInstructionType(Kind))
                    {
                    case InstructionType.SingleType:
                    case InstructionType.DoubleType:
                    case InstructionType.Comparison:
                    {
                        Extra = reader.ReadByte();
#if DEBUG
                        if (Extra != 0 && Kind != Opcode.Dup && Kind != Opcode.CallV)
                        {
                            throw new Exception("Expected 0 byte for opcode " + Kind.ToString());
                        }
#endif
                        ComparisonKind = (ComparisonType)reader.ReadByte();

                        byte types = reader.ReadByte();
                        Type1 = (DataType)(types & 0xf);
                        Type2 = (DataType)(types >> 4);
                        if (Kind == Opcode.Cmp && reader.VersionInfo.FormatID <= 14)
                        {
                            ComparisonKind = (ComparisonType)(reader.ReadByte() - 0x10);
                        }
                        else
                        {
                            reader.Offset += 1;
                        }
                    }
                    break;

                    case InstructionType.Branch:
                    {
                        if (reader.VersionInfo.FormatID <= 14)
                        {
                            JumpOffset = reader.ReadInt24();
                            if (JumpOffset == -1048576)
                            {
                                PopenvExitMagic = true;
                            }
                        }
                        else
                        {
                            uint v = reader.ReadUInt24();

                            PopenvExitMagic = (v & 0x800000) != 0;

                            // The rest is int23 signed value, so make sure
                            uint r = v & 0x003FFFFF;
                            if ((v & 0x00C00000) != 0)
                            {
                                r |= 0xFFC00000;
                            }
                            JumpOffset = (int)r;
                        }

                        reader.Offset += 1;
                    }
                    break;

                    case InstructionType.Pop:
                    {
                        TypeInst = (InstanceType)reader.ReadInt16();

                        byte types = reader.ReadByte();
                        Type1 = (DataType)(types & 0xf);
                        Type2 = (DataType)(types >> 4);

                        reader.Offset += 1;

                        if (Type1 == DataType.Int16)
                        {
                            SwapExtra = (short)TypeInst;
                            TypeInst  = 0;
                        }
                        else
                        {
                            Variable = new Reference <GMVariable>();
                            Variable.Unserialize(reader);
                        }
                    }
                    break;

                    case InstructionType.Push:
                    {
                        short val = reader.ReadInt16();

                        Type1 = (DataType)reader.ReadByte();
                        if (reader.VersionInfo.FormatID <= 14)
                        {
                            // Convert to new opcodes
                            if (Type1 == DataType.Variable)
                            {
                                switch (val)
                                {
                                case -5:
                                    Kind = Opcode.PushGlb;
                                    break;

                                case -6:
                                    Kind = Opcode.PushBltn;
                                    break;

                                case -7:
                                    Kind = Opcode.PushLoc;
                                    break;
                                }
                            }
                            else if (Type1 == DataType.Int16)
                            {
                                Kind = Opcode.PushI;
                            }
                        }

                        reader.Offset += 1;

                        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.ReadWideBoolean();
                            break;

                        case DataType.Variable:
                            TypeInst = (InstanceType)val;
                            Variable = new Reference <GMVariable>();
                            Variable.Unserialize(reader);
                            break;

                        case DataType.String:
                            Value = reader.ReadInt32();             // string ID
                            break;

                        case DataType.Int16:
                            Value = val;
                            break;
                        }
                    }
                    break;

                    case InstructionType.Call:
                    {
                        ArgumentsCount = reader.ReadInt16();
                        Type1          = (DataType)reader.ReadByte();

                        reader.Offset += 1;

                        Function = new Reference <GMFunctionEntry>();
                        Function.Unserialize(reader);
                    }
                    break;

                    case InstructionType.Break:
                    {
                        Value = reader.ReadInt16();
                        Type1 = (DataType)reader.ReadByte();

                        reader.Offset += 1;
                    }
                    break;

                    default:
                        throw new Exception("Unknown opcode " + Kind.ToString());
                    }
                }
예제 #4
0
 public void Unserialize(GMDataReader reader)
 {
     NextOccurrence = reader.ReadInt24();
     Type           = (VariableType)reader.ReadByte();
 }
예제 #5
0
        public override void Unserialize(GMDataReader reader)
        {
            base.Unserialize(reader);

            DisableDebug = reader.ReadBoolean();
            FormatID     = reader.ReadByte();
            reader.VersionInfo.FormatID = FormatID;
            Unknown      = reader.ReadInt16();
            Filename     = reader.ReadStringPointerObject();
            Config       = reader.ReadStringPointerObject();
            LastObjectID = reader.ReadInt32();
            LastTileID   = reader.ReadInt32();
            GameID       = reader.ReadInt32();
            LegacyGUID   = new Guid(reader.ReadBytes(16).Memory.ToArray());
            GameName     = reader.ReadStringPointerObject();
            Major        = reader.ReadInt32();
            Minor        = reader.ReadInt32();
            Release      = reader.ReadInt32();
            Build        = reader.ReadInt32();
            reader.VersionInfo.SetNumber(Major, Minor, Release, Build);
            DefaultWindowWidth  = reader.ReadInt32();
            DefaultWindowHeight = reader.ReadInt32();
            Info                    = (InfoFlags)reader.ReadUInt32();
            LicenseCRC32            = reader.ReadInt32();
            LicenseMD5              = reader.ReadBytes(16);
            Timestamp               = reader.ReadInt64();
            DisplayName             = reader.ReadStringPointerObject();
            ActiveTargets           = reader.ReadInt64();
            FunctionClassifications = (FunctionClassification)reader.ReadUInt64();
            SteamAppID              = reader.ReadInt32();
            if (FormatID >= 14)
            {
                DebuggerPort = reader.ReadInt32();
            }

            int count = reader.ReadInt32();

            RoomOrder = new List <int>(count);
            for (int i = 0; i < count; i++)
            {
                RoomOrder.Add(reader.ReadInt32());
            }

            if (reader.VersionInfo.Major >= 2)
            {
                // Begin parsing random UID, and verify it based on original algorithm
                GMS2_RandomUID = new List <long>();

                Random random      = new Random((int)(Timestamp & 4294967295L));
                long   firstRandom = (long)random.Next() << 32 | (long)random.Next();
                if (reader.ReadInt64() != firstRandom)
                {
                    reader.Warnings.Add(new GMWarning("Unexpected random UID", GMWarning.WarningLevel.Info));
                }
                long  infoNumber = 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 ^= FormatID;
                int infoLocation = 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();
                        GMS2_RandomUID.Add(curr);
                        if (curr != infoNumber)
                        {
                            reader.Warnings.Add(new GMWarning("Unexpected random UID info", GMWarning.WarningLevel.Info));
                        }
                    }
                    else
                    {
                        int first  = reader.ReadInt32();
                        int second = reader.ReadInt32();
                        if (first != random.Next())
                        {
                            reader.Warnings.Add(new GMWarning("Unexpected random UID", GMWarning.WarningLevel.Info));
                        }
                        if (second != random.Next())
                        {
                            reader.Warnings.Add(new GMWarning("Unexpected random UID", GMWarning.WarningLevel.Info));
                        }
                        GMS2_RandomUID.Add((long)(first << 32) | (long)second);
                    }
                }

                // Other GMS2-specific data
                GMS2_FPS             = reader.ReadSingle();
                GMS2_AllowStatistics = reader.ReadWideBoolean();
                GMS2_GameGUID        = new Guid(reader.ReadBytes(16).Memory.ToArray());
            }
        }