Пример #1
0
        /// <summary>Deserialize into new object instance</summary>
        public static Animation DeserializeAnimation(this AnimationDeserializeContext context)
        {
            var animation = new Animation();

            animation.isLooped     = context.br.ReadBoolean();
            animation.friendlyName = context.br.ReadNullableString();

            int frameCount = context.br.ReadInt32();

            animation.Frames = new List <AnimationFrame>(frameCount);
            for (var i = 0; i < frameCount; i++)
            {
                animation.Frames.Add(context.DeserializeAnimationFrame());
            }

            if (context.Version >= 35)
            {
                animation.cachedBounds = context.br.ReadBounds();
            }

            // NOTE: Had to remove call to CalculateGraphicsBounds for old sprites (because we can't get that data at load time in the engine). Time to do a full rewrite.

            animation.isShared          = context.br.ReadBoolean();
            animation.cue               = context.br.ReadNullableString();
            animation.preventDropMotion = context.br.ReadBoolean();

            return(animation);
        }
Пример #2
0
        public SpriteRef(AnimationDeserializeContext context)
        {
            // IMPORTANT: This method is compatible with Sprite's deserializer

            if (context.imageBundle != null)
            {
                this.bundle = context.imageBundle;
                // NOTE: AssetTool depends on us not actually resolving the sprite during load

                this.index = context.br.ReadInt32();
                if (index != -1)
                {
                    this.origin = context.br.ReadPoint();
                }
                else
                {
                    this.origin = default(Point);
                }
            }
            else // In place sprite
            {
                Sprite sprite = new Sprite(context); // Pass through

                this.bundle = new ImageBundle(sprite);
                this.index  = 0;
                this.origin = sprite.origin;
            }
        }
Пример #3
0
        /// <summary>Check that an AnimationSet round-trips through serialization cleanly</summary>
        public static void RoundTripCheck(this AnimationSet animationSet, GraphicsDevice graphicsDevice,
                                          bool useExternalImages)
        {
            // Serialize a first time
            var         firstMemoryStream = new MemoryStream();
            var         firstBinaryWriter = new BinaryWriter(firstMemoryStream);
            ImageWriter firstImageWriter  = null;

            if (useExternalImages)
            {
                firstImageWriter = new ImageWriter();
                animationSet.RegisterImages(firstImageWriter);
                firstImageWriter.WriteOutAllImages(firstMemoryStream);
            }

            var firstSerializeContext = new AnimationSerializeContext(firstBinaryWriter, firstImageWriter);

            animationSet.Serialize(firstSerializeContext);
            var originalData = firstMemoryStream.ToArray();

            // Then deserialize that data
            var         br          = new BinaryReader(new MemoryStream(originalData));
            ImageBundle imageBundle = null;

            if (useExternalImages)
            {
                var helper = new SimpleTextureLoadHelper(graphicsDevice);
                imageBundle            = new ImageBundle();
                br.BaseStream.Position = imageBundle.ReadAllImages(originalData, (int)br.BaseStream.Position, helper);
            }

            var deserializeContext = new AnimationDeserializeContext(br, imageBundle, graphicsDevice);
            var deserialized       = deserializeContext.DeserializeAnimationSet();

            // Then serialize that deserialized data and see if it matches
            // (Ideally we'd recursivly check the AnimationSet to figure out if it matches, but that's a bit too hard)
            var         secondMemoryStream = new MemoryCompareStream(originalData);
            var         secondBinaryWriter = new BinaryWriter(secondMemoryStream);
            ImageWriter secondImageWriter  = null;

            if (useExternalImages)
            {
                secondImageWriter = new ImageWriter();
                deserialized.RegisterImages(secondImageWriter);
                secondImageWriter.WriteOutAllImages(secondMemoryStream);
            }

            var secondSerializeContext = new AnimationSerializeContext(secondBinaryWriter, secondImageWriter);

            deserialized.Serialize(secondSerializeContext);

            // Clean-up:
            if (imageBundle != null)
            {
                imageBundle.Dispose();
            }
        }
Пример #4
0
        /// <summary>Deserialize into a new object instance</summary>
        public HeightmapInstruction(AnimationDeserializeContext context)
        {
            Operation        = (HeightmapOp)context.br.ReadInt32();
            Height           = context.br.ReadByte();
            ObliqueDirection = context.br.ReadOblique();
            FrontEdgeDepth   = context.br.ReadInt32();
            Depth            = context.br.ReadInt32();
            Slope            = context.br.ReadInt32();
            Offset           = context.br.ReadInt32();

            Mask = context.br.ReadBoolean() ? new Mask(context) : null;
        }
 public static List <HeightmapInstruction> DeserializeHeightmapInstructions(this AnimationDeserializeContext context)
 {
     if (context.br.ReadBoolean())
     {
         int count        = context.br.ReadInt32();
         var instructions = new List <HeightmapInstruction>(count);
         for (var i = 0; i < count; i++)
         {
             instructions.Add(new HeightmapInstruction(context));
         }
         return(instructions);
     }
     return(null);
 }
Пример #6
0
        public static OrderedDictionary <string, T> DeserializeOrderedDictionary <T>(this AnimationDeserializeContext context, Func <T> deserializeValue)
        {
            var dictionary = new OrderedDictionary <string, T>();

            int count = context.br.ReadSmallInt32();

            for (var i = 0; i < count; i++)
            {
                var key   = context.br.ReadString();
                var value = deserializeValue();
                dictionary.Add(key, value);
            }

            return(dictionary);
        }
Пример #7
0
        public Sprite(AnimationDeserializeContext context)
        {
            // IMPORTANT: This method is compatible with SpriteRef's deserializer

            if (context.imageBundle != null)
            {
                int index = context.br.ReadInt32();
                if (index == -1)
                {
                    texture         = null;
                    sourceRectangle = default(Rectangle);
                    origin          = default(Point);
                }
                else
                {
                    this = context.imageBundle.GetSprite(index, context.br.ReadPoint());
                }
            }
            else // In place sprite
            {
                int width = context.br.ReadInt32();
                if (width == 0) // A blank texture
                {
                    sourceRectangle = Rectangle.Empty;
                    texture         = null;
                    origin          = default(Point);
                }
                else
                {
                    int height = context.br.ReadInt32();
                    sourceRectangle = new Rectangle(0, 0, width, height);
                    byte[] data = context.br.ReadBytes(width * height * 4);

                    if (context.GraphicsDevice != null) // <- Allow loading headless
                    {
                        texture = new Texture2D(context.GraphicsDevice, width, height);
                        ((Texture2D)texture).SetData(data);
                    }
                    else
                    {
                        texture = null;
                    }

                    origin = context.br.ReadPoint();
                }
            }
        }
Пример #8
0
        public static AnimationSet ReadAnimationSetFromFile(string path, GraphicsDevice graphicsDevice)
        {
            var         texturePath = Path.ChangeExtension(path, ".tex");
            ImageBundle imageBundle = null;

            if (File.Exists(texturePath))
            {
#if false // OLD FORMAT
                using (var stream = File.OpenRead(texturePath))
                {
                    using (var unzip = new GZipStream(stream, CompressionMode.Decompress, true))
                    {
                        using (var br = new BinaryReader(unzip))
                        {
                            imageBundle = new ImageBundle();
                            imageBundle.ReadAllImagesOLD(br, graphicsDevice);
                        }
                    }
                }
#else
#if !WINDOWS
                texturePath = texturePath.Replace('\\', '/');
#endif
                var data = File.ReadAllBytes(texturePath);
                if (data[0] != 0)
                {
                    throw new Exception("Bad version number");
                }

                var helper = new SimpleTextureLoadHelper(graphicsDevice);
                imageBundle = new ImageBundle();
                imageBundle.ReadAllImages(data, 1, helper);
#endif
            }

            using (var stream = File.OpenRead(path))
            {
                using (var unzip = new GZipStream(stream, CompressionMode.Decompress, true))
                {
                    using (var br = new BinaryReader(unzip))
                    {
                        var deserializeContext = new AnimationDeserializeContext(br, imageBundle, graphicsDevice);
                        return(new AnimationSet(deserializeContext));
                    }
                }
            }
        }
Пример #9
0
        public LevelDeserializeContext(BinaryReader br, ImageBundle imageBundle, IAssetProvider assetProvider, GraphicsDevice device)
        {
            this.br            = br;
            this.assetProvider = assetProvider;

            Version = br.ReadInt32();

            if (Version > LevelSerializeContext.formatVersion)
            {
                throw new Exception("Tried to load Level with a version that is too new");
            }
            if (Version < 13)
            {
                throw new Exception("Level version too old!");
            }

            animationDeserializeContext = new AnimationDeserializeContext(br, imageBundle, device); // <- Reads out animation set version
        }
Пример #10
0
        public Heightmap(AnimationDeserializeContext context)
        {
            DefaultHeight = context.br.ReadByte();

            OneWay          = context.br.ReadBoolean();
            OneWayThickness = context.br.ReadByte();

            if (context.br.ReadBoolean())
            {
                Rectangle bounds = context.br.ReadRectangle();
                byte[]    data   = context.br.ReadBytes(bounds.Width * bounds.Height);
                heightmapData = new Data2D <byte>(data, bounds);
            }
            else
            {
                heightmapData = default(Data2D <byte>);
            }

            instructions = HeightmapInstructionExtensions.Deserialize(context);
        }
Пример #11
0
 /// <summary>Deserialize into new object instance</summary>
 public static TagLookup <T> DeserializeTagLookup <T>(this AnimationDeserializeContext context,
                                                      Func <T> deserializeValue)
 {
     return(new TagLookup <T>(context.br, deserializeValue));
 }
Пример #12
0
        public static AnimationFrame DeserializeAnimationFrame(this AnimationDeserializeContext context)
        {
            var animationFrame = new AnimationFrame();

            animationFrame.delay         = context.br.ReadInt32();
            animationFrame.positionDelta = context.br.ReadPosition();
            animationFrame.shadowOffset  = context.br.ReadPosition();

            animationFrame.SnapToGround = context.br.ReadBoolean();

            int layersCount = context.br.ReadInt32();

            if (layersCount > 0)
            {
                Cel currentCel;
                animationFrame.firstLayer = currentCel = new Cel(context);
                for (var i = 1; i < layersCount; i++)
                {
                    currentCel.next = new Cel(context);
                    currentCel      = currentCel.next;
                }
            }

            if (context.Version >= 39)
            {
                animationFrame.masks = context.DeserializeOrderedDictionary(() => new Mask(context));
                animationFrame.outgoingAttachments = context.DeserializeOrderedDictionary(() => new OutgoingAttachment(context));
            }
            else
            {
                //
                // Masks:
                {
                    var legacy = context.DeserializeTagLookup(() => new Mask(context));
                    animationFrame.masks = new OrderedDictionary <string, Mask>();
                    foreach (var mask in legacy)
                    {
                        Debug.Assert(mask.Key.Count < 2, "we don't support multi-tags yet");
                        animationFrame.masks.Add(mask.Key.ToString(), mask.Value);
                    }
                }

                //
                // Outgoing Attachments:
                {
                    var legacy = context.DeserializeTagLookup(() => new OutgoingAttachment(context));
                    animationFrame.outgoingAttachments = new OrderedDictionary <string, OutgoingAttachment>();
                    foreach (var outgoingAttachment in legacy)
                    {
                        Debug.Assert(outgoingAttachment.Key.Count < 2, "we don't support multi-tags yet");
                        animationFrame.outgoingAttachments.Add(outgoingAttachment.Key.ToString(),
                                                               outgoingAttachment.Value);
                    }
                }
            }

            animationFrame.incomingAttachments = context.DeserializeTagLookup(() => context.br.ReadPosition());

            int triggerCount = context.br.ReadInt32();

            if (triggerCount > 0)
            {
                animationFrame.triggers = new List <string>(triggerCount);
                for (var i = 0; i < triggerCount; i++)
                {
                    animationFrame.triggers.Add(context.br.ReadString());
                }
            }

            animationFrame.attachAtLayer = context.br.ReadInt32();
            animationFrame.canDrawLayersAboveSortedAttachees = context.br.ReadBoolean();

            animationFrame.cue = context.br.ReadNullableString();

            return(animationFrame);
        }
Пример #13
0
 public TagSet(AnimationDeserializeContext context) : this(context.br)
 {
 }
Пример #14
0
 public ShadowReceiver(AnimationDeserializeContext context) : this(new Heightmap(context), context.br.ReadOblique())
 {
 }
Пример #15
0
 /// <summary>Deserialize into new object instance</summary>
 public ShadowReceiver(AnimationDeserializeContext context)
 {
     heightmap = new Heightmap(context);
     heightmapExtendDirection = context.br.ReadOblique();
 }
Пример #16
0
        public static AnimationSet DeserializeAnimationSet(this AnimationDeserializeContext context)
        {
            var animationSet = new AnimationSet();

            animationSet.friendlyName = context.br.ReadNullableString();
            animationSet.importOrigin = context.br.ReadPoint();
            animationSet.behaviour    = context.br.ReadNullableString();

            if (context.br.ReadBoolean())
            {
                animationSet.Heightmap = new Heightmap(context);
            }

            if (animationSet.Heightmap != null)
            {
                animationSet.physicsStartX = animationSet.Heightmap.StartX;
                animationSet.physicsEndX   = animationSet.Heightmap.EndX;
                animationSet.physicsStartZ = animationSet.Heightmap.StartZ;
                animationSet.physicsEndZ   = animationSet.Heightmap.EndZ;

                // Assume that reading is faster than walking the heightmap:
                animationSet.physicsHeight = context.br.ReadInt32();
                if (animationSet.physicsHeight > 0)
                {
                    animationSet.depthBounds = new DepthBounds(context);
                }
                animationSet.flatDirection =
                    context.br.ReadOblique();                     // <- for the sake of editing, keep this value around
            }
            else
            {
                animationSet.physicsStartX = context.br.ReadInt32();
                animationSet.physicsEndX   = context.br.ReadInt32();
                animationSet.physicsStartZ = context.br.ReadInt32();
                animationSet.physicsHeight = context.br.ReadInt32();
                animationSet.flatDirection = context.br.ReadOblique();

                if (animationSet.physicsHeight == 0)
                {
                    animationSet.physicsEndZ =
                        context.br.ReadInt32();                       // physicsEndZ gets auto-set during regen, except for carpets
                }
                animationSet.RegenerateDepthBounds();                 // <- Know this is reasonably fast to generate
            }

            if (context.Version >= 38)
            {
                animationSet.coplanarPriority = context.br.ReadInt32();
            }

            if (context.Version >= 36)
            {
                animationSet.doAboveCheck = context.br.ReadBoolean();
            }

            if (context.br.ReadBoolean())
            {
                animationSet.Ceiling = new Heightmap(context);
            }

            animationSet.animations = context.DeserializeTagLookup(() => context.DeserializeAnimation());

            // Unused Animations
            {
                int count = context.br.ReadInt32();
                if (count > 0)                 // unusedAnimations is lazy-initialized
                {
                    animationSet.unusedAnimations = new List <Animation>(count);
                    for (var i = 0; i < count; i++)
                    {
                        animationSet.unusedAnimations.Add(context.DeserializeAnimation());
                    }
                }
            }

            animationSet.cue = context.br.ReadNullableString();

            // Shadow layers
            {
                int shadowLayerCount = context.br.ReadInt32();
                if (shadowLayerCount <= 0)
                {
                    animationSet.shadowLayers = null;
                }
                else
                {
                    animationSet.shadowLayers = new List <ShadowLayer>();
                    for (var i = 0; i < shadowLayerCount; i++)
                    {
                        animationSet.shadowLayers.Add(new ShadowLayer(context.br.ReadInt32(), new SpriteRef(context)));
                    }

                    animationSet.cachedShadowBounds = context.br.ReadBounds();
                }
            }

            // Properties:
            if (context.Version >= 40)
            {
                int count = context.br.ReadInt32();
                for (int i = 0; i < count; i++)
                {
                    animationSet.properties.Add(context.br.ReadString(), context.br.ReadString());
                }
            }

            return(animationSet);
        }
Пример #17
0
 /// <summary>Deserialize into new object instance</summary>
 public TagLookup(AnimationDeserializeContext context, Func <T> deserializeValue) : this(context.br, deserializeValue)
 {
 }