private void ParsePlaceObject2Tag(PlaceObject2Tag tag) { uint curTime = (uint)((curFrame * (1 / swf.Header.FrameRate)) * 1000); uint totalTime = GetDuration(this.curTimeline.FrameCount); Vex.Matrix mx = ParseMatrix(tag.Matrix); float alpha = 1; Instance inst; if (tag.HasCharacter && !tag.Move) // a new symbol at this depth, none preexisting { inst = new Instance(); inst.DefinitionId = tag.Character; inst.StartTime = curTime; inst.EndTime = totalTime; inst.Depth = (int)tag.Depth; curDepthChart.Add(tag.Depth, inst); this.curTimeline.AddInstance(inst); } else if (!tag.HasCharacter && tag.Move) // an old symbol is modified { inst = curDepthChart[tag.Depth]; Transform lastT = inst.Transformations[inst.Transformations.Count - 1]; lastT.EndTime = curTime; inst.EndTime = curTime; alpha = lastT.Alpha; } else if (tag.HasCharacter && tag.Move) // a new symbol replaces an old one { Instance old = curDepthChart[tag.Depth]; Transform lastT = old.Transformations[old.Transformations.Count - 1]; lastT.EndTime = curTime; old.EndTime = curTime; curDepthChart.Remove(tag.Depth); inst = new Instance(); // note: when replacing old symbol, the previous matrix is used if (!tag.HasMatrix) { mx = lastT.Matrix; } // as is old color xform if (!tag.HasColorTransform) { alpha = lastT.Alpha; // include rest of xform as it comes } inst.DefinitionId = tag.Character; inst.StartTime = curTime; inst.EndTime = totalTime; inst.Depth = (int)tag.Depth; curDepthChart.Add(tag.Depth, inst); this.curTimeline.AddInstance(inst); } else { throw new ArgumentException("swf error, no character to modify"); } if (tag.HasColorTransform && (tag.ColorTransform.HasAddTerms || tag.ColorTransform.HasMultTerms)) { int addMult = tag.ColorTransform.AMultTerm + tag.ColorTransform.AAddTerm; alpha = addMult < 0 ? 0 : addMult / 256F; } if (tag.HasClipDepth) { inst.IsMask = true; inst.MaskDepth = tag.ClipDepth; } if (tag.HasName) { inst.Name = tag.Name; } ColorTransform c = tag.ColorTransform; Vex.ColorTransform ct = new Vex.ColorTransform(c.RAddTerm, c.RMultTerm, c.GAddTerm, c.GMultTerm, c.BAddTerm, c.BMultTerm, c.AAddTerm, c.AMultTerm); inst.Transformations.Add(new Transform(curTime, totalTime, mx, alpha, ct)); }
private void ParseTags(SwfReader r, byte swfVersion) { bool tagsRemain = true; uint curFrame = 0; while (tagsRemain) { uint b = r.GetUI16(); curTag = (TagType)(b >> 6); curTagLen = b & 0x3F; if (curTagLen == 0x3F) { curTagLen = r.GetUI32(); } uint tagEnd = r.Position + curTagLen; Debug.WriteLine("sprite type: " + ((uint)curTag).ToString("X2") + " -- " + Enum.GetName(typeof(TagType), curTag)); switch (curTag) { case TagType.End: tagsRemain = false; ControlTags.Add(new EndTag(r)); break; case TagType.PlaceObject: PlaceObjectTag pot = new PlaceObjectTag(r, tagEnd); FirstFrameObjects.Add(pot); ControlTags.Add(pot); break; case TagType.PlaceObject2: PlaceObject2Tag po2t = new PlaceObject2Tag(r, swfVersion); if (po2t.HasCharacter) { FirstFrameObjects.Add(po2t); } ControlTags.Add(po2t); break; case TagType.PlaceObject3: PlaceObject3Tag po3t = new PlaceObject3Tag(r); if (po3t.HasCharacter) { FirstFrameObjects.Add(po3t); } ControlTags.Add(po3t); break; case TagType.RemoveObject: ControlTags.Add(new RemoveObjectTag(r)); break; case TagType.RemoveObject2: ControlTags.Add(new RemoveObject2Tag(r)); break; case TagType.ShowFrame: ControlTags.Add(new ShowFrame(r)); curFrame++; break; case TagType.SoundStreamHead: case TagType.SoundStreamHead2: ControlTags.Add(new SoundStreamHeadTag(r)); break; case TagType.FrameLabel: ControlTags.Add(new FrameLabelTag(r)); break; case TagType.DoAction: ControlTags.Add(new DoActionTag(r, curTagLen)); break; case TagType.DoInitAction: ControlTags.Add(new DoActionTag(r, curTagLen, true)); break; default: // skip if unknown Debug.WriteLine("invalid sprite tag: " + ((uint)curTag).ToString("X2") + " -- " + Enum.GetName(typeof(TagType), curTag)); r.SkipBytes(curTagLen); break; } if (tagEnd != r.Position) { Console.WriteLine("bad tag in sprite: " + Enum.GetName(typeof(TagType), curTag)); } } }