Flirt
an open source extensible Flash™ runtime

Example

Here I'll step through the test.c example code that's in the root of the Flirt source. It's a simple command-line app that takes an SWF file name for an argument, runs it for 100 frames, and then renders out to a PNG file. As usual, we need to include a header:

#include "flirt-debug.h"

The flirt-debug.h header includes the normal flirt.h API along with a number of functions that expose more of the guts of the Flirt runtime. These are only available when Flirt is built with DD_INCLUDE_DEBUGGER defined—that's currently set (along with a bunch of other handy defines) in src/dd.h.

Oh, what's all this DD stuff about? It's a 2-D library! (Yeah, yeah, I know..) I just needed a short and simple prefix for my data types, and it was the first thing that came to mind. Maybe I'll go back and change "dd" to "fl".

These are the only Flirt data types we'll use in this example:

ddPlayer* player;
ddImage* image;

The ddPlayer object represents the entire active "universe" for running an SWF file. It's the player. ddImage is the bitmap we'll render into.

The dd_init() function sets up some stuff used for debug logging. It will go away in the near future, because we don't want any globals here.

if ( !dd_init() )
  bail("dd_init() failed!\n");

The dd_newImage() function creates the image buffer

image = dd_newImage(WIDTH, HEIGHT);

while the dd_newPlayer_file() function creates a new ddPlayer object, ready to read the SWF file from the given FILE* and use the given image as its target bitmap:

player = dd_newPlayer_file(f, image);

The dd_setActionTraceFunction() function tells the actionscript environment what function to use for its "trace" opcode. (It should take another void* user data arg that gets passed back into the user trace function..) Here, we'll just dump anything to stdout:

dd_setActionTraceFunction(player, (void*)puts);

Now we tell the player to parse the input file:

if ( ddPlayer_readMovie(player) != 0 )
  bail("ddPlayer_readMovie() failed");

Once that's done, we step through 100 frames of the movie. Here's how it's done when Flirt is built with DD_INCLUDE_DEBUGGER:

for ( i = 0; i < 100; ++i )
{
  ddPlayer_step(player);

  while ( ddPlayer_executeFrameActions(player, STEP_FRAME) )
    ;

  ddPlayer_updateDisplay(player, NULL, NULL);
}

ddPlayer_step() updates all of the active movie clips; ddPlayer_executeFrameActions() runs all of the active actions, either from the timelines of active clips or in enterFrame handlers; and ddPlayer_updateDisplay() renders the updated shapes into the player's image buffer. The last two arguments of ddPlayer_updateDisplay() are used to return the list and count of ddRect rectangles that have been updated in the image so that you can blit those to screen. Here, though, we'll just dump the entire image out to a PNG file (savePNG() is in test.c):

savePNG("test.png", image, WIDTH, HEIGHT);

Finally, we clean up the objects we've allocated:

dd_destroyPlayer(player);
dd_destroyImage(image);

All content copyright (C) 2004 Dave Hayden except where noted otherwise.
Macromedia and Flash are registered trademarks of Macromedia, Inc. in the United States and/or other countries.