/// <summary>Deserialize into new object instance</summary> public Animation(AnimationDeserializeContext context) { isLooped = context.br.ReadBoolean(); friendlyName = context.br.ReadNullableString(); int frameCount = context.br.ReadInt32(); Frames = new List <AnimationFrame>(frameCount); for (int i = 0; i < frameCount; i++) { Frames.Add(new AnimationFrame(context)); } if (context.Version >= 35) { 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. isShared = context.br.ReadBoolean(); cue = context.br.ReadNullableString(); preventDropMotion = context.br.ReadBoolean(); }
public OutgoingAttachment(AnimationDeserializeContext context) { position = context.br.ReadPosition(); targetAnimationContext = new TagSet(context.br); targetAttachmentContext = new TagSet(context.br); attachRange = new AABB(context.br); facing = (Facing)context.br.ReadInt32(); }
/// <summary>Deserialize into new object instance</summary> public Cel(AnimationDeserializeContext context) { friendlyName = context.br.ReadNullableString(); spriteRef = new SpriteRef(context); if (context.br.ReadBoolean()) { shadowReceiver = new ShadowReceiver(context); } }
/// <summary>Check that an AnimationSet round-trips through serialization cleanly</summary> public void RoundTripCheck(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(); RegisterImages(firstImageWriter); firstImageWriter.WriteOutAllImages(firstMemoryStream); } var firstSerializeContext = new AnimationSerializeContext(firstBinaryWriter, firstImageWriter); 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 = new AnimationSet(deserializeContext); // 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(); } }
public static AnimationSet ReadFromFile(string path, GraphicsDevice graphicsDevice) { string 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 byte[] 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)); } } } }
/// <summary>Deserialize into new object instance</summary> public Mask(AnimationDeserializeContext context) { if (context.Version < 37) { context.br.ReadNullableString(); // was friendly name } isGeneratedAlphaMask = context.br.ReadBoolean(); if (context.customMaskDataReader != null) { // NOTE: Matches MaskData deserializing constructor: var rect = context.br.ReadRectangle(); data = new MaskData(context.customMaskDataReader.Read(MaskData.WidthToDataWidth(rect.Width) * rect.Height), rect); } else { data = new MaskData(context.br, context.fastReadHack); } }
public AnimationFrame(AnimationDeserializeContext context) { delay = context.br.ReadInt32(); positionDelta = context.br.ReadPosition(); shadowOffset = context.br.ReadPosition(); SnapToGround = context.br.ReadBoolean(); int layersCount = context.br.ReadInt32(); if (layersCount > 0) { Cel currentCel = null; this.firstLayer = currentCel = new Cel(context); for (int i = 1; i < layersCount; i++) { currentCel.next = new Cel(context); currentCel = currentCel.next; } } masks = new TagLookup <Mask>(context, () => new Mask(context)); outgoingAttachments = new TagLookup <OutgoingAttachment>(context, () => new OutgoingAttachment(context)); incomingAttachments = new TagLookup <Position>(context, () => context.br.ReadPosition()); int triggerCount = context.br.ReadInt32(); if (triggerCount > 0) { triggers = new List <string>(triggerCount); for (int i = 0; i < triggerCount; i++) { triggers.Add(context.br.ReadString()); } } attachAtLayer = context.br.ReadInt32(); canDrawLayersAboveSortedAttachees = context.br.ReadBoolean(); cue = context.br.ReadNullableString(); }
/// <summary>Deserialize.</summary> public DepthBounds(AnimationDeserializeContext context) { int heightCount = context.br.ReadInt32(); heights = (heightCount == 0) ? null : context.br.ReadBytes(heightCount); slices = new DepthSlice[heightCount + 1]; for (int i = 0; i < slices.Length; i++) { slices[i] = new DepthSlice() { xOffset = context.br.ReadInt32(), zOffset = context.br.ReadInt32(), depths = new FrontBack[context.br.ReadInt32()], }; for (int j = 0; j < slices[i].depths.Length; j++) { slices[i].depths[j].front = context.br.ReadByte(); slices[i].depths[j].back = context.br.ReadByte(); } } }
public AnimationSet(AnimationDeserializeContext context) { friendlyName = context.br.ReadNullableString(); importOrigin = context.br.ReadPoint(); behaviour = context.br.ReadNullableString(); if (context.br.ReadBoolean()) { Heightmap = new Heightmap(context); } if (Heightmap != null) { physicsStartX = Heightmap.StartX; physicsEndX = Heightmap.EndX; physicsStartZ = Heightmap.StartZ; physicsEndZ = Heightmap.EndZ; // Assume that reading is faster than walking the heightmap: physicsHeight = context.br.ReadInt32(); if (physicsHeight > 0) { depthBounds = new DepthBounds(context); } flatDirection = context.br.ReadOblique(); // <- for the sake of editing, keep this value around } else { physicsStartX = context.br.ReadInt32(); physicsEndX = context.br.ReadInt32(); physicsStartZ = context.br.ReadInt32(); physicsHeight = context.br.ReadInt32(); flatDirection = context.br.ReadOblique(); if (physicsHeight == 0) { physicsEndZ = context.br.ReadInt32(); // physicsEndZ gets auto-set during regen, except for carpets } RegenerateDepthBounds(); // <- Know this is reasonably fast to generate } if (context.Version >= 38) { coplanarPriority = context.br.ReadInt32(); } if (context.Version >= 36) { doAboveCheck = context.br.ReadBoolean(); } if (context.br.ReadBoolean()) { Ceiling = new Heightmap(context); } animations = new TagLookup <Animation>(context, () => new Animation(context)); // Unused Animations { int count = context.br.ReadInt32(); if (count > 0) // unusedAnimations is lazy-initialized { unusedAnimations = new List <Animation>(count); for (int i = 0; i < count; i++) { unusedAnimations.Add(new Animation(context)); } } } cue = context.br.ReadNullableString(); // Shadow layers { int shadowLayerCount = context.br.ReadInt32(); if (shadowLayerCount <= 0) { shadowLayers = null; } else { shadowLayers = new List <ShadowLayer>(); for (int i = 0; i < shadowLayerCount; i++) { shadowLayers.Add(new ShadowLayer( context.br.ReadInt32(), new SpriteRef(context))); } cachedShadowBounds = context.br.ReadBounds(); } } // // FIX-UPS: // // TODO: Commenting this out and seeing if anything breaks (remove it eventually) -AR 7/7/16 //if(physicsStartX == physicsEndX) // <- Why do we have zero width? //{ // Debug.WriteLine("WARNING: AnimationSet \"" + friendlyName + "\" has zero physics width"); // AutoGeneratePhysicsAndDepthBounds(); //} }
public AnimationSet(AnimationDeserializeContext context) { friendlyName = context.br.ReadNullableString(); importOrigin = context.br.ReadPoint(); behaviour = context.br.ReadNullableString(); if (context.br.ReadBoolean()) { Heightmap = new Heightmap(context); } if (Heightmap != null) { physicsStartX = Heightmap.StartX; physicsEndX = Heightmap.EndX; physicsStartZ = Heightmap.StartZ; physicsEndZ = Heightmap.EndZ; // Assume that reading is faster than walking the heightmap: physicsHeight = context.br.ReadInt32(); if (physicsHeight > 0) { depthBounds = new DepthBounds(context); } flatDirection = context.br.ReadOblique(); // <- for the sake of editing, keep this value around } else { physicsStartX = context.br.ReadInt32(); physicsEndX = context.br.ReadInt32(); physicsStartZ = context.br.ReadInt32(); physicsHeight = context.br.ReadInt32(); flatDirection = context.br.ReadOblique(); if (physicsHeight == 0) { physicsEndZ = context.br.ReadInt32(); // physicsEndZ gets auto-set during regen, except for carpets } RegenerateDepthBounds(); // <- Know this is reasonably fast to generate } if (context.Version >= 38) { coplanarPriority = context.br.ReadInt32(); } if (context.Version >= 36) { doAboveCheck = context.br.ReadBoolean(); } if (context.br.ReadBoolean()) { Ceiling = new Heightmap(context); } animations = context.DeserializeTagLookup(() => new Animation(context)); // Unused Animations { int count = context.br.ReadInt32(); if (count > 0) // unusedAnimations is lazy-initialized { unusedAnimations = new List <Animation>(count); for (var i = 0; i < count; i++) { unusedAnimations.Add(new Animation(context)); } } } cue = context.br.ReadNullableString(); // Shadow layers { int shadowLayerCount = context.br.ReadInt32(); if (shadowLayerCount <= 0) { shadowLayers = null; } else { shadowLayers = new List <ShadowLayer>(); for (var i = 0; i < shadowLayerCount; i++) { shadowLayers.Add(new ShadowLayer(context.br.ReadInt32(), new SpriteRef(context))); } cachedShadowBounds = context.br.ReadBounds(); } } // Properties: if (context.Version >= 40) { int count = context.br.ReadInt32(); for (int i = 0; i < count; i++) { properties.Add(context.br.ReadString(), context.br.ReadString()); } } }
public AnimationFrame(AnimationDeserializeContext context) { delay = context.br.ReadInt32(); positionDelta = context.br.ReadPosition(); shadowOffset = context.br.ReadPosition(); SnapToGround = context.br.ReadBoolean(); int layersCount = context.br.ReadInt32(); if (layersCount > 0) { Cel currentCel; firstLayer = currentCel = new Cel(context); for (var i = 1; i < layersCount; i++) { currentCel.next = new Cel(context); currentCel = currentCel.next; } } if (context.Version >= 39) { masks = context.DeserializeOrderedDictionary(() => new Mask(context)); outgoingAttachments = context.DeserializeOrderedDictionary(() => new OutgoingAttachment(context)); } else { // // Masks: { var legacy = context.DeserializeTagLookup(() => new Mask(context)); masks = new OrderedDictionary <string, Mask>(); foreach (var mask in legacy) { Debug.Assert(mask.Key.Count < 2, "we don't support multi-tags yet"); masks.Add(mask.Key.ToString(), mask.Value); } } // // Outgoing Attachments: { var legacy = context.DeserializeTagLookup(() => new OutgoingAttachment(context)); outgoingAttachments = new OrderedDictionary <string, OutgoingAttachment>(); foreach (var outgoingAttachment in legacy) { Debug.Assert(outgoingAttachment.Key.Count < 2, "we don't support multi-tags yet"); outgoingAttachments.Add(outgoingAttachment.Key.ToString(), outgoingAttachment.Value); } } } incomingAttachments = context.DeserializeTagLookup(() => context.br.ReadPosition()); int triggerCount = context.br.ReadInt32(); if (triggerCount > 0) { triggers = new List <string>(triggerCount); for (var i = 0; i < triggerCount; i++) { triggers.Add(context.br.ReadString()); } } attachAtLayer = context.br.ReadInt32(); canDrawLayersAboveSortedAttachees = context.br.ReadBoolean(); cue = context.br.ReadNullableString(); }