The player keeps a display list: the objects on the stage, each at a depth, a UI16, with higher depths drawn on top. A depth holds one object. Each frame’s control tags change the list, by placing, changing and removing objects, and a ShowFrame tag draws it. From SWF 3 a sprite has a display list and timeline of its own.
ShowFrame (1)
No body. Draws the display list as the tags before it have left it, and starts the next frame. The main timeline’s frame count in the header is the number of ShowFrame tags in its run.
PlaceObject (4)
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 0 | 2 | UI16 | CharacterId | The character to place |
| 2 | 2 | UI16 | Depth | Where to place it |
| 4 | varies | MATRIX | Matrix | Its position, scale and rotation |
| … | varies | CXFORM | ColorTransform | Only if bytes remain in the tag |
Puts a new object at the depth.
RemoveObject (5)
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 0 | 2 | UI16 | CharacterId | The character to remove |
| 2 | 2 | UI16 | Depth | Its depth |
PlaceObject2 (26, SWF 3)
Places a new object or changes the one at a depth. A flags byte says which fields follow. Read most significant bit first:
| Bit | Value | Name | Meaning |
|---|---|---|---|
| 7 | 0x80 | PlaceFlagHasClipActions | Clip actions follow (SWF 5; 0 before) |
| 6 | 0x40 | PlaceFlagHasClipDepth | A clip depth follows |
| 5 | 0x20 | PlaceFlagHasName | An instance name follows |
| 4 | 0x10 | PlaceFlagHasRatio | A ratio follows |
| 3 | 0x08 | PlaceFlagHasColorTransform | A colour transform follows |
| 2 | 0x04 | PlaceFlagHasMatrix | A matrix follows |
| 1 | 0x02 | PlaceFlagHasCharacter | A character ID follows |
| 0 | 0x01 | PlaceFlagMove | Change the object already at the depth |
Then, in this order, each only when flagged except the depth:
| Type | Name | Meaning |
|---|---|---|
| UI16 | Depth | Always present |
| UI16 | CharacterId | The character to place |
| MATRIX | Matrix | Position, scale and rotation |
| CXFORMWITHALPHA | ColorTransform | Colour and alpha transform |
| UI16 | Ratio | For a morph shape, the morph position, 0 to 65,535 |
| STRING | Name | The instance name, used by actions |
| UI16 | ClipDepth | This object is a mask for every depth above it up to ClipDepth |
| CLIPACTIONS | ClipActions | Event handlers (SWF 5) |
Move and HasCharacter together decide what happens:
- Move 0, with a character: place a new object; the depth should be empty.
- Move 1, no character: change the object at the depth, only the fields given.
- Move 1, with a character: replace the object’s character, keeping its other properties unless they are given.
000010C2 BF 06 12 00 00 00 26 01 00 04 00 1C AA 49 EC 80
000010D2 6F 62 6A 65 63 74 31 00
26:
name, matrix and character. Depth 1, character 4, the matrix (to 272.45, 197 pixels)
and the instance name “object1”RemoveObject2 (28, SWF 3)
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 0 | 2 | UI16 | Depth | Removes whatever is at this depth |
FrameLabel (43, SWF 3)
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 0 | varies | STRING | Name | The label of the current frame |
Actions go to a label with ActionGoToLabel.
DefineSprite (39, SWF 3)
| Offset | Size | Type | Name | Meaning |
|---|---|---|---|---|
| 0 | 2 | UI16 | SpriteID | The character ID |
| 2 | 2 | UI16 | FrameCount | The frames in the sprite |
| 4 | varies | tags | ControlTags | A tag run of its own, ending with End |
A sprite is a movie clip: it plays its own timeline wherever it is placed. Its tags are walked like the movie’s; see the tag run for which tags may appear inside, and an example.
Clip actions (SWF 5)
A PlaceObject2 with HasClipActions ends with event handlers for the placed movie
clip: what onClipEvent (…) on an instance compiles to in Flash 5. The
event flags are 16 bits in this format.
| Type | Name | Meaning |
|---|---|---|
| UI16 | Reserved | 0 |
| UI16 | AllEventFlags | Every event any handler below uses |
| CLIPACTIONRECORD[] | ClipActionRecords | One per handler |
| UI16 | ClipActionEndFlag | 0: the end of the list |
Each CLIPACTIONRECORD:
| Type | Name | Meaning |
|---|---|---|
| UI16 | EventFlags | The events this handler runs on |
| UI32 | ActionRecordSize | The bytes of actions that follow |
| ACTIONRECORD[] | Actions | Actions ending with an End action (0) |
Event flags
Two bytes, read as bits most significant first, byte by byte:
| Byte | Bits, from the top |
|---|---|
| 1 | KeyUp, KeyDown, MouseUp, MouseDown, MouseMove, Unload, EnterFrame, Load |
| 2 | seven bits used only from SWF 6, then Data |
Read as a little-endian UI16 instead, the values are: Load 0x01, EnterFrame 0x02,
Unload 0x04, MouseMove 0x08, MouseDown 0x10, MouseUp 0x20, KeyDown 0x40, KeyUp 0x80,
Data 0x100. These are the nine events of Flash 5’s onClipEvent. The
other bits of the second byte became the button-like events and Initialize in
SWF 6, which also widened the flags to 32 bits; so a reader must know the version to
read clip actions at all.
How the explorer draws a frame
The explorer replays the control tags up to the frame and draws the display list: shapes, morph shapes at the placed ratio, sprites at the frame they reach (stopping where a frame’s actions hold ActionStop), buttons in their up state, static text and text fields drawn with their embedded outlines, with matrices, colour transforms and clip-depth masks. It does not run the actions, so anything a script creates or moves is missing.
Tags and records from later versions
These came with SWF 8 and 9 and have no place in a SWF 1 to 5 movie. Where one turns up, the explorer reads it with the fields below.
| Name | SWF | Fields |
|---|---|---|
| PlaceObject3 (70) | 8 | PlaceObject2’s flags, a second flags byte (OpaqueBackground, HasVisible, HasImage, HasClassName, HasCacheAsBitmap, HasBlendMode, HasFilterList), Depth, an optional class name, then PlaceObject2’s fields, a filter list, blend mode, bitmap cache, visibility and background colour, and 32-bit clip actions |
| Filter list | 8 | UI8 NumberOfFilters, then each a UI8 FilterID (0 DropShadow, 1 Blur, 2 Glow, 3 Bevel, 4 GradientGlow, 5 Convolution, 6 ColorMatrix, 7 GradientBevel) and its data |
| DefineScalingGrid (78) | 8 | UI16 CharacterId, RECT Splitter: a 9-slice scaling grid |
| DefineSceneAndFrameLabelData (86) | 9 | EncodedU32 SceneCount, then each scene’s EncodedU32 frame and STRING name; EncodedU32 FrameLabelCount, then each label’s EncodedU32 frame and STRING label |