/// <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); }
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; } }
/// <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(); } }
/// <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); }
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); }
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(); } } }
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)); } } } }
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 }
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); }
/// <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)); }
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); }
public TagSet(AnimationDeserializeContext context) : this(context.br) { }
public ShadowReceiver(AnimationDeserializeContext context) : this(new Heightmap(context), context.br.ReadOblique()) { }
/// <summary>Deserialize into new object instance</summary> public ShadowReceiver(AnimationDeserializeContext context) { heightmap = new Heightmap(context); heightmapExtendDirection = context.br.ReadOblique(); }
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); }
/// <summary>Deserialize into new object instance</summary> public TagLookup(AnimationDeserializeContext context, Func <T> deserializeValue) : this(context.br, deserializeValue) { }