Bugs
====

* there's a pop when transitioning from textured to mesh-rendered
  glyphs; probably the texture fonts aren't registered exactly right?


Productizing
============

Tasks to make gameswf ready for including in real games.

* pick a version number, post a release

* reduce small allocs, flatten data structures

* for data binding, we have:

  gameswf-push (fscommand)
  host-push (call_method, set_variable)
  host-pull (call_method, get_variable)

  we are missing gameswf-pull.  This would be useful for things like
  looking up localized text in the game engine's translation table,
  among other things.

* fix/finish precompute_cached_data()

* flags to strip extraneous stuff from a SWF source stream.
  I.e. remove all bitmap data, font shape outlines, etc.  This is
  useful for apps that precompile the bitmaps into native formats and
  hook them up at runtime via get_bitmap_info()->... .  Lets the
  stripped stream be used for parsing the rest of the movie info,
  without taking up extra space/bandwidth.

* fontlib support, for explicitly letting the host define global fonts
  that all SWF's can use

* put a FAQ on the web

General
=======

* implement host-app driven text rendering functions

* implement some or all of the HTML-like layout tags in dynamic text
  fields

* sprites as button characters are not working.  (Maybe they are
  now??)

* host-to-gameswf data transfer:

  * DONE set_variable

  * maybe augment this with array element parsing, and more data types?

  * Should the whole ActionScript API be available to the host?
    I.e. let C++ host code and ActionScript code call back and forth?
    Might be really hot for translating slow prototype ActionScripts
    into C++.  Prototype in Flash on a fast machine, convert the
    scripts and deliver a blazing fast executable.

* Helpers for arbitrary tag-processing

* Would be good if one of the log options produced a nice usable
  human-readable parsing of the file.  Or even a SSWF equivalent?

* write GAMESWF_FONT_GLYPH_FINAL_SIZE into the font cache data, and
  check it on read to make sure it matches.  If no match, log error
  (and ignore data???)  If these mismatch, then glyphs get rendered
  with the wrong size, and it's non-obvious why.

* User request: implement SWF files recursively calling other SWF
  files.  Low priority; there are workarounds.

ActionScript
============

* bug:

	onEnterFrame should get called even when sprite is stopped

* bug:

	// If we have a dynamic text instance "inst" that contains a string,
	// doing to_string() or to_tu_string() on it should return its string
	// contents, not "<object xxx>" or whatever we do now.

* bug:

	// In Flash, _visible property returns "true" or "false" when
	// converted to string.  gameswf returns "0" or "1".  In general,
	// gameswf probably needs a specific as_value::BOOL type, instead
	// of using as_value::NUMBER for booleans.

* all event hooks

* arrays, object constructors

* make sure the frame semantics are correct.  I'm not 100% clear on
  the semantics of frame transitions.  I think that "being on frame N"
  means that N's tags and actions have been executed.

* collect a canonical set of test movies and check them into CVS

* generate or collect some game-gui-like movies

* will need some good test programs to make sure VM is doing the right
  thing.  SET UP AUTOMATED REGRESSION TESTS -- can be a shell script
  that runs test movies in verbose mode and compares ActionScript
  logging against expected output.

* implement remaining opcodes and library functions

* _global


Renderer
========

* fix the few tesselator glitches

* optimize tesselator (not super-high priority, caching works pretty
  well)

  * improve naive (mis)use of array<>; use a more statically-allocated
    array to hold intermediate results.

  * examine use of qsort; should probably use pointers to stuff in
    some situations, instead of raw copies

  * coarse clip/cull

  * better tesselation; look at Shewchuck's constrained delaunay stuff
    or the improved trapezoid tesselator that doesn't cut across the
    whole shape

* real lines (low priority)

  I think the way to handle this is to take advantage of a (mipmapped)
  circle texture, say 16x16, and actually draw rectangles.  But then
  it still doesn't seem too easy to get right.  Needs more thinking.
  Not a super high priority; doesn't seem to be a critical feature for
  most movies.

  Update: designers do use lines.  (But Flash MX does have a feature
  that turns lines into shapes.)  The circle texture, connected by
  polys seems like the way to go.  The interior of acute angles is
  still tricky though.  But it can definitely be done.  Something like
  this:

                      -----
                    -/     \-  <--- edge of circle texture
                   /   use   \
                  /\  circle /\
                 /  \  tex  /  \
                /    \ here/    \
               /      \   /      \
              /        \ /        \
             /          o          \
            /           |           \                                                                      o
           /            |            \
          /   use       |     use     \
         /  tris for   /\    tris for  \
        /     this    /  \     this     \
       /             /    \              \
      /             /      \              \
     /             /        \              \
                  /          \              \
                 /            \              \
                /              \              \


* Idea for antialiasing.  I really miss antialiasing; it sure would be
  nice to have it.  (But this is low priority for productizing; it
  should be easy enough for designers to work around gameswf's
  limitations.)  So here's the idea:

  * do full-blown expensive cached tesselation, to generate a "fringe
    mesh" around the outside edges of shapes.  We know the range of
    desired rendering sizes (in pixels), so we can make a fringe mesh
    that will range from 1 to 2 pixels in width when rendered.  I
    believe this involves shrinking the interior of the mesh by the
    equivalent of a half-pixel.

  * render the mesh using the dual-textured modulate thing, to fade
    the edge.  Adjust the U coordinates of the outer edge of the
    fringe according to the actual size in pixels of the fringe;
    i.e. if the fringe is being rendered at 1.27 pixels in size,
    adjust U so that the alpha fades to exactly 0 when the fringe is
    1.0 pixel from the interior; the excess fringe has alpha == 0 so
    doesn't render.

  This sounds pretty foolproof to me.  It's expensive in terms of
  precomputation, but then we have all this precomputation machinery
  anyway, so no big deal.  There could possibly be a pop when
  tesselations switch, although I don't think it would be any worse
  than existing pops, and I haven't noticed any objectionable popping
  with our existing shape rendering.

  Self-intersection of the expanded/shrunk mesh is a bitch.
  E.g. concave vertices, and tiny holes (like in minified text).

  Reasons not to mess with this:

  * sounds like a bunch of work

  * non-antialiased rendering on Xbox does not look that bad.

  * hardware keeps getting better; could just turn on multisample
    rendering

  * artists can work around it

* Instead of using textured lines we could compute the antialiasing
  gradients analitically, although it requires a simple fragment
  program and some per-edge computations:

  http://graphics.csail.mit.edu/~ericchan/articles/prefilter/

* Antialiasing using destination alpha and the edge-coverage alpha
  feature that's commonly available:

  * turn on edge antialiasing; basically this causes the rasterizer to
    generate a source alpha value corresponding to the coverage of the
    primitive on each pixel.  So, edge pixels get a fractional alpha
    value.

	(This feature has been around for a long time on various different
    hardware, under GL_POLYGON_SMOOTH; the big problem with it is that
    the obvious blend mode (SRC_ALPHA, ONE_MINUS_SRC_ALPHA) doesn't
    work right.  Internal edges are slightly transparent, and that
    just looks like crap.  A common hack is to draw an opaque version
    of the mesh over the antialiased version; the problem with that
    trick is it overdraws the darker 50% of the antialiasing, so it
    only looks somewhat better -- still fairly jaggy.  The Red book
    mentions (GL_SRC_ALPHA_SATURATE, GL_ONE) which works correctly if
    you're drawing opaque, sorted front-to-back.  But for transparency
    effects, we must draw back-to-front, so this is incompatible.)

  * Clear destination alpha, then draw into destination alpha only,
    using an additive blend.  This makes a nice antialiased mask of
    our shape.

  * Draw a quad over the shape bounding box, with the desired fill
    mode, using (DST_ALPHA, ONE_MINUS_DST_ALPA).  The parts with
    non-zero alpha will get filled/blended with the shape fill.

  This works; there's a proof-of-concept (but artifacty) implemention,
  #ifdef'd out in gameswf_render_handler_ogl.cpp

  NOTE: this makes thick/thin line drawing much easier, since overdraw
  can be tolerated -- just draw quads for the edges, and circles (or
  semicircles) for the verts, all into the alpha buffer.  Overdraw of
  the quads on the interior of angles is no problem, since things
  drawn multiple times just saturate.  Then fill the bounding box,
  modulating with dest alpha, as usual.

* Idea: alternative polygon rendering method, without requiring any
  true poly triangulation: use two-sided lighting to repeatedly
  add/subtract signed-area triangles into the stencil buffer.

  OK, in more words: the idea is a procedure similar to the polygon
  signed-area test, where you pick an arbitrary reference point in the
  plane, and for each edge in the polygon, compute the signed area of
  the triangle formed by the reference point and the edge.  Total up
  the signed areas, and that gives you the polygon area.  For a
  general polygon, some of the edges are "back-facing" with respect to
  the reference point; those triangles subtract out the extra area
  added by the triangles that are "front-facing" with respect to the
  reference point.

  So anyway, we exploit that same idea, but render the triangles
  instead of computing their area.  Front-facing triangles add into
  the stencil buffer, while back-facing triangles subtract from the
  stencil buffer.  The result should be 1's in the stencil buffer
  where the poly should be filled, and 0's where is shouldn't.

  NOTES:

  * Stencil overflow, for very convoluted polys, should not matter.
    You can overflow as much as you want, but the final result will
    always be in the range [0,1].  So as long as you have modulo
    arithmetic, and at least one bit of stencil, you're OK.  Correct?

  * Those very convoluted polys mentioned above could create excessive
    overdraw.  E.g. let's say you have a very thin line that spirals
    around dozens of times, surrounding a big empty area.  Could be
    murderous on fill rate.  One possibility here would be to somehow
    recognize bad cases, and subdivide the poly, and render each piece
    independently with a local reference point.  Recognizing the bad
    case could be difficult.  Maybe do some kind of
    cheap/partial/sloppy convex decomposition of the poly, to get the
    parts.

  * In theory, this would work fantastically great in combination with
    the edge-antialiasing thing mentioned above, IF there were a way
    to do the alpha blending using values in the stencil buffer (could
    always copy stencil to alpha, but that starts to sound
    expensive!), OR some way to enable modulo arithmetic in
    destination alpha, and a way to pass a negative alpha values (for
    the negative-area triangles).

  * I'm sure someone has mentioned this idea somewhere, need to look
    for more info.

* Idea: render filled quadratic beziers DIRECTLY, without any
  tesselation, nor any subdividing of curves.  This works essentially
  the same way as the above signed-area thing for poly rendering, plus
  a special rendering of the curved segments:

  * take a reference point x

  * for each quadratic bezier curved segment (a0, c, a1) (the a's are
    "anchor" points; the c is a "control" point), we render the signed
    triangle (x, a0, a1) as above.  We also render (a0, c, a1) with a
    special shader (this can also be done easily in the fixed-function
    pipe with a square alpha texture made up of a quarter-circle).
    The texture or shader function looks like:

    a1                      c
     +---------------------+ 
     ......     0 out here |
     |     ....            |
     |         ...         |
     |            ..       |
     |              .      |
     |               ..    |
     |                 .   |
     |                  .  |
     |    1 in here     .  |
     |                   . |
     |                   . |
     |                    .|
     |                    .|
     o--------------------.+ a0

    So this quarter-circular texture (or simple shader function)
    determines the stencil/alpha value to add into the render target.
    We get 1's inside the shape, and 0's outside the shape.  The 1's
    have to be turned into -1's if (a0, c, a1) is backfacing.

    The sum in the render target should be exactly the filled curved
    shape, so then we can do a stencil-masked fill of the bounding
    box, or whatever.

    This might even get us edge antialiasing in the bargain!  I.e the
    texels on the boundary of the circle will be between 0 and 1, so
    they're feathered.

    ISSUE: will mip-mapping foul this up in case of very acute or
    obtuse triangles?  We probably want mip-mapping for two reasons:
    1) for performance, and 2) if we're trying for antialiasing, we
    want the footprint of the soft texture edge to be about one
    rendered pixel wide.  (I suspect the scaling issues will be
    similar to rendering glyphs using textures.)

  * see similar idea explored much more thoroughly by Loop and Blinn
    in this paper:
    http://research.microsoft.com/~cloop/LoopBlinn05.pdf

    (Actually they explore the math etc for the curve outline,
    including cubic curves, but not the signed-area idea; instead they
    do some funky extra tesselation to avoid overlaps.)
