renamed png functions
[swftools.git] / src / swfc.c
index 14d5f9a..e34f9fc 100644 (file)
@@ -48,6 +48,7 @@ static int override_outputname = 0;
 static int do_cgi = 0;
 static int change_sets_all = 0;
 static int do_exports = 0;
+static char * mainclass = "";
 
 static struct options_t options[] = {
 {"h", "help"},
@@ -177,14 +178,16 @@ static struct level
    /* for swf (0): */
    SWF*swf;
    char*filename;
+   char as3;
 
    /* for sprites (1): */
    TAG*tag;
    U16 id;
    char*name;
+   char*as3name;
    U16 olddepth;
    int oldframe;
-   dictionary_t oldinstances;
+   dict_t oldinstances;
    SRECT oldrect;
    TAG* cut;
 
@@ -193,13 +196,13 @@ static struct level
 } stack[256];
 static int stackpos = 0;
 
-static dictionary_t characters;
-static dictionary_t images;
-static dictionary_t textures;
-static dictionary_t outlines;
-static dictionary_t gradients;
-static dictionary_t filters;
-static dictionary_t interpolations;
+static dict_t characters;
+static dict_t images;
+static dict_t textures;
+static dict_t outlines;
+static dict_t gradients;
+static dict_t filters;
+static dict_t interpolations;
 static char idmap[65536];
 static TAG*tag = 0; //current tag
 
@@ -207,10 +210,10 @@ static int id; //current character id
 static int currentframe; //current frame in current level
 static SRECT currentrect; //current bounding box in current level
 static U16 currentdepth;
-static dictionary_t instances;
-static dictionary_t fonts;
-static dictionary_t sounds;
-static dictionary_t fontUsage;
+static dict_t instances;
+static dict_t fonts;
+static dict_t sounds;
+static dict_t fontUsage;
 
 typedef struct _parameters {
     int x,y;
@@ -340,43 +343,44 @@ static void free_outline(void* o)
 
 static void freeDictionaries()
 {
-    dictionary_free_all(&instances, free_instance);
-    dictionary_free_all(&characters, free);
-    dictionary_free_all(&images, free);
-    dictionary_free_all(&textures, free);
-    dictionary_free_all(&outlines, free_outline);
-    dictionary_free_all(&gradients, free_gradient);
-    dictionary_free_all(&filters, free);
-    dictionary_free_all(&fonts, free_font);
-    dictionary_free_all(&sounds, free);
-    dictionary_free_all(&interpolations, free);
+    dict_free_all(&instances, 1, free_instance);
+    dict_free_all(&characters, 1, free);
+    dict_free_all(&images, 1, free);
+    dict_free_all(&textures, 1, free);
+    dict_free_all(&outlines, 1, free_outline);
+    dict_free_all(&gradients, 1, free_gradient);
+    dict_free_all(&filters, 1, free);
+    dict_free_all(&fonts, 1, free_font);
+    dict_free_all(&sounds, 1, free);
+    dict_free_all(&interpolations, 1, free);
     cleanUp = 0;
 }
 
 static void freeFontDictionary()
 {
-    dictionary_free_all(&fonts, free_font);
+    dict_free_all(&fonts, 1, free_font);
 }
 
 static void incrementid()
 {
-    while(idmap[++id]) {
-       if(id==65535)
-           syntaxerror("Out of character ids.");
+    while(id<65536 && idmap[id]) {
+        id++;
     }
+    if(id>=65536)
+       syntaxerror("Out of character ids.");
     idmap[id] = 1;
 }
 
-static void s_addcharacter(char*name, U16 id, TAG*ctag, SRECT r)
+static void s_addcharacter(const char*name, U16 id, TAG*ctag, SRECT r)
 {
-    if(dictionary_lookup(&characters, name))
+    if(dict_lookup(&characters, name))
         syntaxerror("character %s defined twice", name);
     character_t* c = character_new();
 
     c->definingTag = ctag;
     c->id = id;
     c->size = r;
-    dictionary_put2(&characters, name, c);
+    dict_put(&characters, name, c);
 
     if(do_exports) {
        tag = swf_InsertTag(tag, ST_NAMECHARACTER);
@@ -388,26 +392,26 @@ static void s_addcharacter(char*name, U16 id, TAG*ctag, SRECT r)
        swf_SetString(tag, name);
     }
 }
-static void s_addimage(char*name, U16 id, TAG*ctag, SRECT r)
+static void s_addimage(const char*name, U16 id, TAG*ctag, SRECT r)
 {
-    if(dictionary_lookup(&images, name))
+    if(dict_lookup(&images, name))
         syntaxerror("image %s defined twice", name);
 
     character_t* c = character_new();
     c->definingTag = ctag;
     c->id = id;
     c->size = r;
-    dictionary_put2(&images, name, c);
+    dict_put(&images, name, c);
 }
-static instance_t* s_addinstance(char*name, character_t*c, U16 depth)
+static instance_t* s_addinstance(const char*name, character_t*c, U16 depth)
 {
-    if(dictionary_lookup(&instances, name))
+    if(dict_lookup(&instances, name))
         syntaxerror("object %s defined twice", name);
     instance_t* i = instance_new();
     i->character = c;
     i->depth = depth;
     //swf_GetMatrix(0, &i->matrix);
-    dictionary_put2(&instances, name, i);
+    dict_put(&instances, name, i);
     return i;
 }
 
@@ -470,89 +474,89 @@ void initBuiltIns()
     interpolation_t* new;
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_LINEAR;
-    dictionary_put2(&interpolations, "linear", new);
+    dict_put(&interpolations, "linear", new);
 
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_QUAD_IN;
     new->slope = 0;
-    dictionary_put2(&interpolations, "quadIn", new);
+    dict_put(&interpolations, "quadIn", new);
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_QUAD_OUT;
     new->slope = 0;
-    dictionary_put2(&interpolations, "quadOut", new);
+    dict_put(&interpolations, "quadOut", new);
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_QUAD_IN_OUT;
     new->slope = 0;
-    dictionary_put2(&interpolations, "quadInOut", new);
+    dict_put(&interpolations, "quadInOut", new);
 
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_CUBIC_IN;
     new->slope = 0;
-    dictionary_put2(&interpolations, "cubicIn", new);
+    dict_put(&interpolations, "cubicIn", new);
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_CUBIC_OUT;
     new->slope = 0;
-    dictionary_put2(&interpolations, "cubicOut", new);
+    dict_put(&interpolations, "cubicOut", new);
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_CUBIC_IN_OUT;
     new->slope = 0;
-    dictionary_put2(&interpolations, "cubicInOut", new);
+    dict_put(&interpolations, "cubicInOut", new);
 
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_QUART_IN;
     new->slope = 0;
-    dictionary_put2(&interpolations, "quartIn", new);
+    dict_put(&interpolations, "quartIn", new);
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_QUART_OUT;
     new->slope = 0;
-    dictionary_put2(&interpolations, "quartOut", new);
+    dict_put(&interpolations, "quartOut", new);
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_QUART_IN_OUT;
     new->slope = 0;
-    dictionary_put2(&interpolations, "quartInOut", new);
+    dict_put(&interpolations, "quartInOut", new);
 
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_QUINT_IN;
     new->slope = 0;
-    dictionary_put2(&interpolations, "quintIn", new);
+    dict_put(&interpolations, "quintIn", new);
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_QUINT_OUT;
     new->slope = 0;
-    dictionary_put2(&interpolations, "quintOut", new);
+    dict_put(&interpolations, "quintOut", new);
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_QUINT_IN_OUT;
     new->slope = 0;
-    dictionary_put2(&interpolations, "quintInOut", new);
+    dict_put(&interpolations, "quintInOut", new);
 
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_CIRCLE_IN;
-    dictionary_put2(&interpolations, "circleIn", new);
+    dict_put(&interpolations, "circleIn", new);
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_CIRCLE_OUT;
-    dictionary_put2(&interpolations, "circleOut", new);
+    dict_put(&interpolations, "circleOut", new);
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_CIRCLE_IN_OUT;
-    dictionary_put2(&interpolations, "circleInOut", new);
+    dict_put(&interpolations, "circleInOut", new);
 
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_EXPONENTIAL_IN;
-    dictionary_put2(&interpolations, "exponentialIn", new);
+    dict_put(&interpolations, "exponentialIn", new);
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_EXPONENTIAL_OUT;
-    dictionary_put2(&interpolations, "exponentialOut", new);
+    dict_put(&interpolations, "exponentialOut", new);
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_EXPONENTIAL_IN_OUT;
-    dictionary_put2(&interpolations, "exponentialInOut", new);
+    dict_put(&interpolations, "exponentialInOut", new);
 
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_SINE_IN;
-    dictionary_put2(&interpolations, "sineIn", new);
+    dict_put(&interpolations, "sineIn", new);
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_SINE_OUT;
-    dictionary_put2(&interpolations, "sineOut", new);
+    dict_put(&interpolations, "sineOut", new);
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_SINE_IN_OUT;
-    dictionary_put2(&interpolations, "sineInOut", new);
+    dict_put(&interpolations, "sineInOut", new);
 
     RGBA c;
     memset(&c, 0, sizeof(RGBA));
@@ -566,32 +570,32 @@ void initBuiltIns()
     noGradient->gradient.ratios[1] = 255;
     noGradient->radial = 0;
     noGradient->rotate = 0;
-    dictionary_put2(&gradients, "no_gradient", noGradient);
+    dict_put(&gradients, "no_gradient", noGradient);
 
     noFilters = 0;
 // put a no_filters entry in the filters dictionary to provoce a message when a user tries
 // to define a no_filters filter. The real filter=no_filters case is handled in parseFilters.
     FILTER* dummy = (FILTER*)malloc(sizeof(FILTER));
-    dictionary_put2(&filters, "no_filters", dummy);
+    dict_put(&filters, "no_filters", dummy);
     noBlur = (FILTER_BLUR*) swf_NewFilter(FILTERTYPE_BLUR);
     noBlur->passes = 1;
-    dictionary_put2(&filters, "no_blur", noBlur);
+    dict_put(&filters, "no_blur", noBlur);
     noBevel = (FILTER_BEVEL*) swf_NewFilter(FILTERTYPE_BEVEL);
     noBevel->passes = 1;
     noBevel->composite = 1;
-    dictionary_put2(&filters, "no_bevel", noBevel);
+    dict_put(&filters, "no_bevel", noBevel);
     noDropshadow = (FILTER_DROPSHADOW*) swf_NewFilter(FILTERTYPE_DROPSHADOW);
     noDropshadow->passes = 1;
     noDropshadow->composite = 1;
-    dictionary_put2(&filters, "no_dropshadow", noDropshadow);
+    dict_put(&filters, "no_dropshadow", noDropshadow);
     noGradientGlow = (FILTER_GRADIENTGLOW*) swf_NewFilter(FILTERTYPE_GRADIENTGLOW);
     noGradientGlow->passes = 1;
     noGradientGlow->composite = 1;
     noGradientGlow->gradient = &noGradient->gradient;
-    dictionary_put2(&filters, "no_gradientglow", noGradientGlow);
+    dict_put(&filters, "no_gradientglow", noGradientGlow);
 }
 
-void s_swf(char*name, SRECT r, int version, int fps, int compress, RGBA background)
+void s_swf(const char*name, SRECT r, int version, int fps, int compress, RGBA background)
 {
     if(stackpos)
         syntaxerror(".swf blocks can't be nested");
@@ -608,15 +612,15 @@ void s_swf(char*name, SRECT r, int version, int fps, int compress, RGBA backgrou
     swf->compressed = compress;
     swf_SetRGB(tag,&background);
 
-    dictionary_init(&characters);
-    dictionary_init(&images);
-    dictionary_init(&textures);
-    dictionary_init(&outlines);
-    dictionary_init(&gradients);
-    dictionary_init(&filters);
-    dictionary_init(&instances);
-    dictionary_init(&sounds);
-    dictionary_init(&interpolations);
+    dict_init(&characters, 16);
+    dict_init(&images, 16);
+    dict_init(&textures, 16);
+    dict_init(&outlines, 16);
+    dict_init(&gradients, 16);
+    dict_init(&filters, 16);
+    dict_init(&instances, 16);
+    dict_init(&sounds, 16);
+    dict_init(&interpolations, 16);
     initBuiltIns();
     cleanUp = &freeDictionaries;
 
@@ -632,10 +636,12 @@ void s_swf(char*name, SRECT r, int version, int fps, int compress, RGBA backgrou
     currentdepth = 1;
 
     memset(idmap, 0, sizeof(idmap));
+    idmap[0]=1; //main movie has ID 0
+
     incrementid();
 }
 
-void s_sprite(char*name, SRECT*scalegrid)
+void s_sprite(const char*name, SRECT*scalegrid, const char*as3name)
 {
     tag = swf_InsertTag(tag, ST_DEFINESPRITE);
     swf_SetU16(tag, id); //id
@@ -650,6 +656,7 @@ void s_sprite(char*name, SRECT*scalegrid)
     stack[stackpos].tag = tag;
     stack[stackpos].id = id;
     stack[stackpos].name = strdup(name);
+    stack[stackpos].as3name = strdup(as3name);
     if(scalegrid) {
        stack[stackpos].scalegrid = *scalegrid;
     } else {
@@ -657,7 +664,7 @@ void s_sprite(char*name, SRECT*scalegrid)
     }
 
     /* FIXME: those four fields should be bundled together */
-    dictionary_init(&instances);
+    dict_init(&instances, 16);
     currentframe = 0;
     currentdepth = 1;
     memset(&currentrect, 0, sizeof(currentrect));
@@ -683,7 +690,7 @@ typedef struct _button
 
 static button_t mybutton;
 
-void s_button(char*name)
+void s_button(const char*name, const char*as3name)
 {
     tag = swf_InsertTag(tag, ST_DEFINEBUTTON2);
     swf_SetU16(tag, id); //id
@@ -696,18 +703,19 @@ void s_button(char*name)
     stack[stackpos].tag = tag;
     stack[stackpos].id = id;
     stack[stackpos].name = strdup(name);
+    stack[stackpos].as3name = strdup(as3name);
     stack[stackpos].oldrect = currentrect;
     memset(&currentrect, 0, sizeof(currentrect));
 
     stackpos++;
     incrementid();
 }
-void s_buttonput(char*character, char*as, parameters_t p)
+void s_buttonput(const char*character, const char*as, parameters_t p)
 {
-    character_t* c = dictionary_lookup(&characters, character);
+    character_t* c = dict_lookup(&characters, character);
     MATRIX m;
     int flags = 0;
-    char*o = as,*s = as;
+    const char*o = as,*s = as;
     buttonrecord_t r;
     if(!stackpos || (stack[stackpos-1].type != 3))  {
        syntaxerror(".show may only appear in .button");
@@ -760,12 +768,16 @@ static void setbuttonrecords(TAG*tag)
     }
 }
 
-void s_buttonaction(int flags, char*action)
+void s_buttonaction(int flags, const char*action)
 {
     ActionTAG* a = 0;
     if(flags==0) {
        return;
     }
+    if(!stackpos || !stack[stackpos-1].tag ||
+            stack[stackpos-1].tag->id != ST_DEFINEBUTTON2) {
+        syntaxerror("Need to be inside a button for .on_* commands");
+    }
     setbuttonrecords(stack[stackpos-1].tag);
 
     a = swf_ActionCompile(text, stack[0].swf->fileVersion);
@@ -808,6 +820,14 @@ static void s_endButton()
     currentrect = stack[stackpos].oldrect;
 
     s_addcharacter(stack[stackpos].name, stack[stackpos].id, stack[stackpos].tag, r);
+
+    if(*stack[stackpos].as3name) {
+        tag = swf_InsertTag(tag, ST_SYMBOLCLASS);
+        swf_SetU16(tag, 1);
+        swf_SetU16(tag, stack[stackpos].id);
+        swf_SetString(tag, stack[stackpos].as3name);
+    }
+
     free(stack[stackpos].name);
 }
 
@@ -816,7 +836,8 @@ TAG* removeFromTo(TAG*from, TAG*to)
     TAG*save = from->prev;
     while(from!=to) {
        TAG*next = from->next;
-       swf_DeleteTag(from);
+       if(swf_isAllowedSpriteTag(from))
+           swf_DeleteTag(0, from);
        from = next;
     }
     save->next = 0;
@@ -856,7 +877,7 @@ static void free_filterlist(FILTERLIST* f_list)
     int i;
     for (i = 0; i < f_list->num; i++)
     {
-        if (f_list->filter[i]->type == FILTERTYPE_GRADIENTGLOW)
+        if(f_list->filter[i]->type == FILTERTYPE_GRADIENTGLOW)
             gradient_free(((FILTER_GRADIENTGLOW*)f_list->filter[i])->gradient);
         free(f_list->filter[i]);
     }
@@ -887,7 +908,7 @@ static void readParameters(history_t* history, parameters_t* p, int frame)
     p->filters = history_filterValue(history, frame);
 }
 
-void setPlacement(TAG*tag, U16 id, U16 depth, MATRIX m, char*name, parameters_t*p, char move)
+void setPlacement(TAG*tag, U16 id, U16 depth, MATRIX m, const char*name, parameters_t*p, char move)
 {
     SWFPLACEOBJECT po;
     FILTERLIST flist;
@@ -896,31 +917,32 @@ void setPlacement(TAG*tag, U16 id, U16 depth, MATRIX m, char*name, parameters_t*
     po.depth = depth;
     po.matrix = m;
     po.cxform = p->cxform;
-    po.name = name;
+    po.name = (char*)name;
     po.move = move;
     if(move)
     po.id = 0;
     if(p->blendmode) {
     po.blendmode = p->blendmode;
     }
-    if (p->filters)
+    if(p->filters)
        po.filters = p->filters;
     swf_SetPlaceObject(tag, &po);
 }
 
-static void writeInstance(instance_t* i)
+static void writeInstance(void* _i)
 {
+    instance_t*i = (instance_t*)_i;
     parameters_t p;
     MATRIX m;
     int frame = i->history->firstFrame;
     TAG* tag = i->history->firstTag;
     history_processFlags(i->history);
-    while (frame < currentframe)
+    while (tag && frame < currentframe)
     {
         frame++;
-        while (tag->id != ST_SHOWFRAME)
+        while (tag && tag->id != ST_SHOWFRAME)
             tag = tag->next;
-        if (parametersChange(i->history, frame))
+        if(parametersChange(i->history, frame))
         {
             readParameters(i->history, &p, frame);
             m = s_instancepos(i->character->size, &p);
@@ -930,11 +952,11 @@ static void writeInstance(instance_t* i)
             else
                tag = swf_InsertTag(tag, ST_PLACEOBJECT2);
             setPlacement(tag, 0, i->depth, m, 0, &p, 1);
-            if (p.filters)
+            if(p.filters)
                free_filterlist(p.filters);
-        }
-        else
+        } else if(tag) {
             tag = tag->next;
+        }
     }
 }
 
@@ -953,22 +975,16 @@ static void s_endSprite()
 {
     SRECT r = currentrect;
 
+    stackpos--;
+    instance_t *i;
+
+    dict_foreach_value(&instances, writeInstance);
+
     if(stack[stackpos].cut)
        tag = removeFromTo(stack[stackpos].cut, tag);
 
-    stackpos--;
-    instance_t *i;
-    stringarray_t* index =dictionary_index(&instances);
-    int num;
-    for (num = 0; num < dictionary_count(&instances); num++)
-    {
-       char* name = stringarray_at(index, num);
-       if (name)
-       {
-            i = dictionary_lookup(&instances, name);
-            writeInstance(i);
-       }
-    }
+    // the writeInstance loop above may have inserted tags after what used to be the current tag,
+    // so let's make sure 'tag' point to the current tag again.
     while (tag->next)
        tag = tag->next;
 
@@ -990,7 +1006,7 @@ static void s_endSprite()
         syntaxerror("internal error(7)");
     /* TODO: before clearing, prepend "<spritename>." to names and
              copy into old instances dict */
-   dictionary_free_all(&instances, free_instance);
+    dict_free_all(&instances, 1, free_instance);
 
     currentframe = stack[stackpos].oldframe;
     currentrect = stack[stackpos].oldrect;
@@ -998,6 +1014,15 @@ static void s_endSprite()
     instances = stack[stackpos].oldinstances;
 
     s_addcharacter(stack[stackpos].name, stack[stackpos].id, stack[stackpos].tag, r);
+
+    if(*stack[stackpos].as3name) {
+        tag = swf_InsertTag(tag, ST_SYMBOLCLASS);
+        swf_SetU16(tag, 1);
+        swf_SetU16(tag, stack[stackpos].id);
+        swf_SetString(tag, stack[stackpos].as3name);
+    }   
+
+
     free(stack[stackpos].name);
 }
 
@@ -1006,19 +1031,9 @@ static void s_endSWF()
     int fi;
     SWF* swf;
     char*filename;
+    char*mc="";
 
-    instance_t *i;
-    stringarray_t* index = dictionary_index(&instances);
-    int num;
-    for (num = 0; num < dictionary_count(&instances); num++)
-    {
-       char* name = stringarray_at(index, num);
-       if (name)
-       {
-            i = dictionary_lookup(&instances, name);
-            writeInstance(i);
-       }
-    }
+    dict_foreach_value(&instances, writeInstance);
 
     if(stack[stackpos].cut)
        tag = removeFromTo(stack[stackpos].cut, tag);
@@ -1028,10 +1043,35 @@ static void s_endSWF()
     swf = stack[stackpos].swf;
     filename = stack[stackpos].filename;
 
+    // the writeInstance loop above may have inserted tags after what used yo be the current tag,
+    // so let's make sure 'tag' point to the current tag again.
+    while (tag->next)
+       tag = tag->next;
+
     //if(tag->prev && tag->prev->id != ST_SHOWFRAME)
     //    tag = swf_InsertTag(tag, ST_SHOWFRAME);
     tag = swf_InsertTag(tag, ST_SHOWFRAME);
 
+    if(stack[0].as3) {
+        TAG*tag = swf->firstTag;
+        tag = swf_InsertTag(tag, ST_DOABC);
+        void*code = as3_getcode();
+        swf_WriteABC(tag, code);
+        if(*mainclass)
+            mc = mainclass;
+        else if(as3_getglobalclass())
+            mc = as3_getglobalclass();
+        if(*mc) {
+            tag = swf_InsertTag(tag, ST_SYMBOLCLASS);
+            swf_SetU16(tag, 1);
+            swf_SetU16(tag, 0);
+            swf_SetString(tag, mc);
+        } else {
+            warning("no global public MovieClip subclass");
+        }
+        as3_destroy();
+    }
+
     tag = swf_InsertTag(tag, ST_END);
 
     swf_OptimizeTagOrder(swf);
@@ -1088,7 +1128,7 @@ int s_getframe()
     return currentframe+1;
 }
 
-void s_frame(int nr, int cut, char*name, char anchor)
+void s_frame(int nr, int cut, const char*name, char anchor)
 {
     int t;
     TAG*now = tag;
@@ -1123,9 +1163,9 @@ void s_frame(int nr, int cut, char*name, char anchor)
     currentframe = nr;
 }
 
-int parseColor2(char*str, RGBA*color);
+int parseColor2(const char*str, RGBA*color);
 
-int addFillStyle(SHAPE*s, SRECT*r, char*name)
+int addFillStyle(SHAPE*s, SRECT*r, const char*name)
 {
     RGBA color;
     character_t*image;
@@ -1134,9 +1174,9 @@ int addFillStyle(SHAPE*s, SRECT*r, char*name)
     if(name[0] == '#') {
        parseColor2(name, &color);
        return swf_ShapeAddSolidFillStyle(s, &color);
-    } else if ((texture = dictionary_lookup(&textures, name))) {
+    } else if((texture = dict_lookup(&textures, name))) {
        return swf_ShapeAddFillStyle2(s, &texture->fs);
-    } else if((image = dictionary_lookup(&images, name))) {
+    } else if((image = dict_lookup(&images, name))) {
        MATRIX m;
        swf_GetMatrix(0, &m);
        m.sx = 65536.0*20.0*(r->xmax - r->xmin)/image->size.xmax;
@@ -1144,7 +1184,7 @@ int addFillStyle(SHAPE*s, SRECT*r, char*name)
        m.tx = r->xmin;
        m.ty = r->ymin;
        return swf_ShapeAddBitmapFillStyle(s, &m, image->id, 0);
-    }  else if ((gradient = dictionary_lookup(&gradients, name))) {
+    }  else if((gradient = dict_lookup(&gradients, name))) {
        SRECT r2;
        MATRIX rot,m;
        double ccos,csin;
@@ -1164,7 +1204,7 @@ int addFillStyle(SHAPE*s, SRECT*r, char*name)
        m.tx = r->xmin + (r->xmax - r->xmin)/2;
        m.ty = r->ymin + (r->ymax - r->ymin)/2;
        return swf_ShapeAddGradientFillStyle(s, &m, &gradient->gradient, gradient->radial);
-    }  else if (parseColor2(name, &color)) {
+    }  else if(parseColor2(name, &color)) {
        return swf_ShapeAddSolidFillStyle(s, &color);
     } else {
        syntaxerror("not a color/fillstyle: %s", name);
@@ -1173,7 +1213,7 @@ int addFillStyle(SHAPE*s, SRECT*r, char*name)
 }
 
 RGBA black={r:0,g:0,b:0,a:0};
-void s_box(char*name, int width, int height, RGBA color, int linewidth, char*texture)
+void s_box(const char*name, int width, int height, RGBA color, int linewidth, const char*texture)
 {
     SRECT r,r2;
     SHAPE* s;
@@ -1210,13 +1250,13 @@ void s_box(char*name, int width, int height, RGBA color, int linewidth, char*tex
     incrementid();
 }
 
-void s_filled(char*name, char*outlinename, RGBA color, int linewidth, char*texture)
+void s_filled(const char*name, const char*outlinename, RGBA color, int linewidth, const char*texture)
 {
     SRECT rect,r2;
     SHAPE* s;
     int ls1,fs1=0;
     outline_t* outline;
-    outline = dictionary_lookup(&outlines, outlinename);
+    outline = dict_lookup(&outlines, outlinename);
     if(!outline) {
        syntaxerror("outline %s not defined", outlinename);
     }
@@ -1250,7 +1290,7 @@ void s_filled(char*name, char*outlinename, RGBA color, int linewidth, char*textu
     incrementid();
 }
 
-void s_circle(char*name, int r, RGBA color, int linewidth, char*texture)
+void s_circle(const char*name, int r, RGBA color, int linewidth, const char*texture)
 {
     SRECT rect,r2;
     SHAPE* s;
@@ -1284,14 +1324,14 @@ void s_circle(char*name, int r, RGBA color, int linewidth, char*texture)
     incrementid();
 }
 
-void s_textshape(char*name, char*fontname, float size, char*_text)
+void s_textshape(const char*name, const char*fontname, float size, const char*_text)
 {
     int g;
     U8*text = (U8*)_text;
     outline_t* outline;
 
     SWFFONT*font;
-    font = dictionary_lookup(&fonts, fontname);
+    font = dict_lookup(&fonts, fontname);
     if(!font)
        syntaxerror("font \"%s\" not known!", fontname);
 
@@ -1310,24 +1350,24 @@ void s_textshape(char*name, char*fontname, float size, char*_text)
     {
        drawer_t draw;
        swf_Shape11DrawerInit(&draw, 0);
-       swf_DrawText(&draw, font, (int)(size*100), _text);
+       swf_DrawText(&draw, font, (int)(size*100), (char*)_text);
        draw.finish(&draw);
        outline->shape = swf_ShapeDrawerToShape(&draw);
        outline->bbox = swf_ShapeDrawerGetBBox(&draw);
        draw.dealloc(&draw);
     }
 
-    if(dictionary_lookup(&outlines, name))
+    if(dict_lookup(&outlines, name))
        syntaxerror("outline %s defined twice", name);
-    dictionary_put2(&outlines, name, outline);
+    dict_put(&outlines, name, outline);
 }
 
-void s_text(char*name, char*fontname, char*text, int size, RGBA color)
+void s_text(const char*name, const char*fontname, const char*text, int size, RGBA color)
 {
     SRECT r;
     MATRIX _m,*m=0;
     SWFFONT*font;
-    font = dictionary_lookup(&fonts, fontname);
+    font = dict_lookup(&fonts, fontname);
     if(!font)
        syntaxerror("font \"%s\" not known!", fontname);
 
@@ -1337,7 +1377,7 @@ void s_text(char*name, char*fontname, char*text, int size, RGBA color)
        s_box(name, 0, 0, black, 20, 0);
        return;
     }
-    r = swf_SetDefineText(tag, font, &color, text, size);
+    r = swf_SetDefineText(tag, font, &color, (char*)text, size);
 
     if(stack[0].swf->fileVersion >= 8) {
        tag = swf_InsertTag(tag, ST_CSMTEXTSETTINGS);
@@ -1352,7 +1392,7 @@ void s_text(char*name, char*fontname, char*text, int size, RGBA color)
     incrementid();
 }
 
-void s_quicktime(char*name, char*url)
+void s_quicktime(const char*name, const char*url)
 {
     SRECT r;
     MATRIX _m,*m=0;
@@ -1367,7 +1407,25 @@ void s_quicktime(char*name, char*url)
     incrementid();
 }
 
-void s_edittext(char*name, char*fontname, int size, int width, int height, char*text, RGBA*color, int maxlength, char*variable, int flags, int align)
+void s_video(const char *name, int width, int height)
+{
+    SRECT r;
+
+    memset(&r, 0, sizeof(r));
+
+    tag = swf_InsertTag(tag, ST_DEFINEVIDEOSTREAM);
+    swf_SetU16(tag, id);
+    swf_SetU16(tag, 0); // numframes
+    swf_SetU16(tag, width);
+    swf_SetU16(tag, height);
+    swf_SetU8(tag, 0); // videoflags
+    swf_SetU8(tag, 0); // codecid
+
+    s_addcharacter(name, id, tag, r);
+    incrementid();
+}
+
+void s_edittext(const char*name, const char*fontname, int size, int width, int height, const char*text, RGBA*color, int maxlength, const char*variable, int flags, int align)
 {
     SWFFONT*font = 0;
     EditTextLayout layout;
@@ -1375,7 +1433,7 @@ void s_edittext(char*name, char*fontname, int size, int width, int height, char*
 
     if(fontname && *fontname) {
        flags |= ET_USEOUTLINES;
-       font = dictionary_lookup(&fonts, fontname);
+       font = dict_lookup(&fonts, fontname);
        if(!font)
            syntaxerror("font \"%s\" not known!", fontname);
     }
@@ -1391,7 +1449,7 @@ void s_edittext(char*name, char*fontname, int size, int width, int height, char*
     r.xmax = width;
     r.ymax = height;
 
-    swf_SetEditText(tag, flags, r, text, color, maxlength, font?font->id:0, size, &layout, variable);
+    swf_SetEditText(tag, flags, r, (char*)text, color, maxlength, font?font->id:0, size, &layout, (char*)variable);
 
     s_addcharacter(name, id, tag, r);
     incrementid();
@@ -1399,7 +1457,7 @@ void s_edittext(char*name, char*fontname, int size, int width, int height, char*
 
 /* type: either "jpeg" or "png"
  */
-void s_image(char*name, char*type, char*filename, int quality)
+void s_image(const char*name, const char*type, const char*filename, int quality)
 {
     /* an image is actually two folded: 1st bitmap, 2nd character.
        Both of them can be used separately */
@@ -1407,7 +1465,7 @@ void s_image(char*name, char*type, char*filename, int quality)
     /* step 1: the bitmap */
     SRECT r;
     int imageID = id;
-    int width, height;
+    unsigned width, height;
     if(!strcmp(type,"jpeg")) {
 #ifndef HAVE_JPEGLIB
        warning("no jpeg support compiled in");
@@ -1417,7 +1475,7 @@ void s_image(char*name, char*type, char*filename, int quality)
        tag = swf_InsertTag(tag, ST_DEFINEBITSJPEG2);
        swf_SetU16(tag, imageID);
 
-       if(swf_SetJPEGBits(tag, filename, quality) < 0) {
+       if(swf_SetJPEGBits(tag, (char*)filename, quality) < 0) {
            syntaxerror("Image \"%s\" not found, or contains errors", filename);
        }
 
@@ -1435,7 +1493,7 @@ void s_image(char*name, char*type, char*filename, int quality)
        RGBA*data = 0;
        swf_SetU16(tag, imageID);
 
-       getPNG(filename, &width, &height, (unsigned char**)&data);
+       png_load(filename, &width, &height, (unsigned char**)&data);
 
        if(!data) {
            syntaxerror("Image \"%s\" not found, or contains errors", filename);
@@ -1468,10 +1526,10 @@ void s_image(char*name, char*type, char*filename, int quality)
     incrementid();
 }
 
-void s_getBitmapSize(char*name, int*width, int*height)
+void s_getBitmapSize(const char*name, int*width, int*height)
 {
-    character_t* image = dictionary_lookup(&images, name);
-    gradient_t* gradient = dictionary_lookup(&gradients,name);
+    character_t* image = dict_lookup(&images, name);
+    gradient_t* gradient = dict_lookup(&gradients,name);
     if(image) {
        *width = image->size.xmax;
        *height = image->size.ymax;
@@ -1491,12 +1549,12 @@ void s_getBitmapSize(char*name, int*width, int*height)
     syntaxerror("No such bitmap/gradient: %s", name);
 }
 
-void s_texture(char*name, char*object, int x, int y, float scalex, float scaley, float rotate, float shear)
+void s_texture(const char*name, const char*object, int x, int y, float scalex, float scaley, float rotate, float shear)
 {
-    if(dictionary_lookup(&textures, name))
+    if(dict_lookup(&textures, name))
         syntaxerror("texture %s defined twice", name);
-    gradient_t* gradient = dictionary_lookup(&gradients, object);
-    character_t* bitmap = dictionary_lookup(&images, object);
+    gradient_t* gradient = dict_lookup(&gradients, object);
+    character_t* bitmap = dict_lookup(&images, object);
     texture_t* texture = (texture_t*)rfx_calloc(sizeof(texture_t));
     parameters_t p;
     FILLSTYLE*fs = &texture->fs;
@@ -1528,31 +1586,58 @@ void s_texture(char*name, char*object, int x, int y, float scalex, float scaley,
        fs->m.sy *= 20;
     }
 
-    dictionary_put2(&textures, name, texture);
+    dict_put(&textures, name, texture);
 }
 
-void s_font(char*name, char*filename)
+void s_createfont(const char*name, const char*filename, const char*glyphs, char flashtype)
 {
-    SWFFONT* font;
-    font = dictionary_lookup(&fonts, name);
-    if(0)
-    {
-       /* fix the layout. Only needed for old fonts */
-       int t;
-       for(t=0;t<font->numchars;t++) {
-           font->glyph[t].advance = 0;
+    if(dict_lookup(&fonts, name))
+       syntaxerror("font %s defined twice", name);
+
+    SWFFONT* font = swf_LoadFont(filename, flashtype);
+    if(font == 0) {
+       warning("Couldn't open font file \"%s\"", filename);
+       font = (SWFFONT*)malloc(sizeof(SWFFONT));
+       memset(font, 0, sizeof(SWFFONT));
+       dict_put(&fonts, name, font);
+       return;
+    }
+    swf_FontPrepareForEditText(font);
+
+    if(!strcmp(glyphs, "all")) {
+       swf_FontUseAll(font);
+       font->use->glyphs_specified = 1;
+    } else {
+       if(!glyphs[0]) {
+           swf_FontInitUsage(font);
+       } else {
+           swf_FontUseUTF8(font, (const U8*)glyphs, 0xffff);
+           font->use->glyphs_specified = 1;
        }
-       font->layout = 0;
-       swf_FontCreateLayout(font);
     }
+    dict_put(&fonts, name, font);
+}
+
+void s_font(const char*name, const char*filename)
+{
+    SWFFONT* font;
+    font = dict_lookup(&fonts, name);
     font->id = id;
     swf_FontReduce_swfc(font);
-    tag = swf_InsertTag(tag, ST_DEFINEFONT2);
+       
+    if(font->version>=3 && stack[0].swf->fileVersion < 8) {
+       warning("flashtype not supported for flash versions 8 and below");
+    }
+
+    tag = swf_InsertTag(tag, font->version==3?ST_DEFINEFONT3:ST_DEFINEFONT2);
     swf_FontSetDefine2(tag, font);
-    tag = swf_InsertTag(tag, ST_EXPORTASSETS);
-    swf_SetU16(tag, 1);
-    swf_SetU16(tag, id);
-    swf_SetString(tag, name);
+
+    if(do_exports) {
+       tag = swf_InsertTag(tag, ST_EXPORTASSETS);
+       swf_SetU16(tag, 1);
+       swf_SetU16(tag, id);
+       swf_SetString(tag, name);
+    }
 
     incrementid();
 }
@@ -1565,7 +1650,7 @@ typedef struct _sound_t
     TAG*tag;
 } sound_t;
 
-void s_sound(char*name, char*filename)
+void s_sound(const char*name, const char*filename)
 {
     struct WAV wav, wav2;
     struct MP3 mp3;
@@ -1575,7 +1660,7 @@ void s_sound(char*name, char*filename)
     unsigned blocksize = 1152;
     int is_mp3 = 0;
 
-    if(dictionary_lookup(&sounds, name))
+    if(dict_lookup(&sounds, name))
         syntaxerror("sound %s defined twice", name);
 
     if(wav_read(&wav, filename))
@@ -1634,23 +1719,25 @@ void s_sound(char*name, char*filename)
     else
         swf_SetSoundDefine(tag, samples, numsamples);
 
-    tag = swf_InsertTag(tag, ST_NAMECHARACTER);
-    swf_SetU16(tag, id);
-    swf_SetString(tag, name);
-    tag = swf_InsertTag(tag, ST_EXPORTASSETS);
-    swf_SetU16(tag, 1);
-    swf_SetU16(tag, id);
-    swf_SetString(tag, name);
+    if(do_exports) {
+       tag = swf_InsertTag(tag, ST_NAMECHARACTER);
+       swf_SetU16(tag, id);
+       swf_SetString(tag, name);
+       tag = swf_InsertTag(tag, ST_EXPORTASSETS);
+       swf_SetU16(tag, 1);
+       swf_SetU16(tag, id);
+       swf_SetString(tag, name);
+    }
 
     sound = (sound_t*)malloc(sizeof(sound_t)); /* mem leak */
     sound->tag = tag;
     sound->id = id;
 
-    dictionary_put2(&sounds, name, sound);
+    dict_put(&sounds, name, sound);
 
     incrementid();
 
-    if (samples)
+    if(samples)
         free(samples);
 }
 
@@ -1671,8 +1758,8 @@ static char* gradient_getToken(const char**p)
     return result;
 }
 
-float parsePercent(char*str);
-RGBA parseColor(char*str);
+float parsePercent(const char*str);
+RGBA parseColor(const char*str);
 
 GRADIENT parseGradient(const char*str)
 {
@@ -1723,7 +1810,7 @@ GRADIENT parseGradient(const char*str)
 
 FILTERLIST* parseFilters(char* list)
 {
-    if (!strcmp(list, "no_filters"))
+    if(!strcmp(list, "no_filters"))
        return 0;
     FILTER* f;
     FILTERLIST* f_list = (FILTERLIST*)malloc(sizeof(FILTERLIST));
@@ -1733,22 +1820,22 @@ FILTERLIST* parseFilters(char* list)
     while (f_start)
     {
        f_end = strchr(f_start, ',');
-       if (f_end)
+       if(f_end)
            *f_end = '\0';
-       f = dictionary_lookup(&filters, f_start);
-       if (!f)
+       f = dict_lookup(&filters, f_start);
+       if(!f)
        {
            free(f_list);
            syntaxerror("unknown filter %s", f_start);
        }
-       if (f_list->num == 8)
+       if(f_list->num == 8)
        {
            warning("too many filters in filterlist, no more than 8 please, rest ignored");
            break;
        }
        f_list->filter[f_list->num] = f;
        f_list->num++;
-       if (f_end)
+       if(f_end)
        {
            *f_end = ',';
            f_start = f_end + 1;
@@ -1759,7 +1846,7 @@ FILTERLIST* parseFilters(char* list)
     return f_list;
 }
 
-void s_gradient(char*name, const char*text, int radial, int rotate)
+void s_gradient(const char*name, const char*text, int radial, int rotate)
 {
     gradient_t* gradient;
     gradient = malloc(sizeof(gradient_t));
@@ -1768,17 +1855,17 @@ void s_gradient(char*name, const char*text, int radial, int rotate)
     gradient->radial = radial;
     gradient->rotate = rotate;
 
-    dictionary_put2(&gradients, name, gradient);
+    dict_put(&gradients, name, gradient);
 }
 
-void s_gradientglow(char*name, char*gradient, float blurx, float blury,
+void s_gradientglow(const char*name, const char*gradient, float blurx, float blury,
                    float angle, float distance, float strength, char innershadow,
                    char knockout, char composite, char ontop, int passes)
 {
-    if(dictionary_lookup(&filters, name))
+    if(dict_lookup(&filters, name))
         syntaxerror("filter %s defined twice", name);
 
-    gradient_t* g = dictionary_lookup(&gradients, gradient);
+    gradient_t* g = dict_lookup(&gradients, gradient);
     if(!g)
        syntaxerror("unknown gradient %s", gradient);
 
@@ -1798,12 +1885,12 @@ void s_gradientglow(char*name, char*gradient, float blurx, float blury,
     filter->ontop = ontop;
     filter->passes = passes;
 
-    dictionary_put2(&filters, name, filter);
+    dict_put(&filters, name, filter);
 }
 
-void s_dropshadow(char*name, RGBA color, double blurx, double blury, double angle, double distance, double strength, char innershadow, char knockout, char composite, int passes)
+void s_dropshadow(const char*name, RGBA color, double blurx, double blury, double angle, double distance, double strength, char innershadow, char knockout, char composite, int passes)
 {
-    if(dictionary_lookup(&filters, name))
+    if(dict_lookup(&filters, name))
         syntaxerror("filter %s defined twice", name);
 
     composite = 1;
@@ -1820,12 +1907,12 @@ void s_dropshadow(char*name, RGBA color, double blurx, double blury, double angl
     filter->composite = composite;
     filter->passes = passes;
 
-    dictionary_put2(&filters, name, filter);
+    dict_put(&filters, name, filter);
 }
 
-void s_bevel(char*name, RGBA shadow, RGBA highlight, double blurx, double blury, double angle, double distance, double strength, char innershadow, char knockout, char composite, char ontop, int passes)
+void s_bevel(const char*name, RGBA shadow, RGBA highlight, double blurx, double blury, double angle, double distance, double strength, char innershadow, char knockout, char composite, char ontop, int passes)
 {
-    if(dictionary_lookup(&filters, name))
+    if(dict_lookup(&filters, name))
         syntaxerror("filter %s defined twice", name);
 
     composite = 1;
@@ -1844,12 +1931,12 @@ void s_bevel(char*name, RGBA shadow, RGBA highlight, double blurx, double blury,
     filter->ontop = ontop;
     filter->passes = passes;
 
-    dictionary_put2(&filters, name, filter);
+    dict_put(&filters, name, filter);
 }
 
-void s_blur(char*name, double blurx, double blury, int passes)
+void s_blur(const char*name, double blurx, double blury, int passes)
 {
-    if(dictionary_lookup(&filters, name))
+    if(dict_lookup(&filters, name))
         syntaxerror("filter %s defined twice", name);
 
     FILTER_BLUR* filter = rfx_calloc(sizeof(FILTER_BLUR));
@@ -1858,24 +1945,25 @@ void s_blur(char*name, double blurx, double blury, int passes)
     filter->blury = blury;
     filter->passes = passes;
 
-    dictionary_put2(&filters, name, filter);
+    dict_put(&filters, name, filter);
 }
 
 void s_action(const char*text)
 {
-    ActionTAG* a = 0;
-    a = swf_ActionCompile(text, stack[0].swf->fileVersion);
-    if(!a)
-    {
+    if(stack[0].swf->fileVersion < 9) {
+        ActionTAG* a = 0;
+        a = swf_ActionCompile(text, stack[0].swf->fileVersion);
+        if(!a) {
+            swf_ActionFree(a);
+            syntaxerror("Couldn't compile ActionScript");
+        }
+        tag = swf_InsertTag(tag, ST_DOACTION);
+        swf_ActionSet(tag, a);
         swf_ActionFree(a);
-        syntaxerror("Couldn't compile ActionScript");
+    } else {
+        as3_parse_bytearray(stack[0].filename, text, strlen(text));
+        stack[0].as3 = 1;
     }
-
-    tag = swf_InsertTag(tag, ST_DOACTION);
-
-    swf_ActionSet(tag, a);
-
-    swf_ActionFree(a);
 }
 
 void s_initaction(const char*character, const char*text)
@@ -1889,7 +1977,7 @@ void s_initaction(const char*character, const char*text)
         syntaxerror("Couldn't compile ActionScript");
     }
 
-    c = (character_t*)dictionary_lookup(&characters, character);
+    c = (character_t*)dict_lookup(&characters, character);
 
     tag = swf_InsertTag(tag, ST_DOINITACTION);
     swf_SetU16(tag, c->id);
@@ -1898,12 +1986,12 @@ void s_initaction(const char*character, const char*text)
     swf_ActionFree(a);
 }
 
-int s_swf3action(char*name, char*action)
+int s_swf3action(const char*name, const char*action)
 {
     ActionTAG* a = 0;
     instance_t* object = 0;
     if(name)
-       object = (instance_t*)dictionary_lookup(&instances, name);
+       object = (instance_t*)dict_lookup(&instances, name);
     if(!object && name && *name) {
        /* we have a name, but couldn't find it. Abort. */
        return 0;
@@ -1922,9 +2010,9 @@ int s_swf3action(char*name, char*action)
     return 1;
 }
 
-void s_outline(char*name, char*format, char*source)
+void s_outline(const char*name, const char*format, const char*source)
 {
-    if(dictionary_lookup(&outlines, name))
+    if(dict_lookup(&outlines, name))
         syntaxerror("outline %s defined twice", name);
 
     outline_t* outline;
@@ -1947,16 +2035,16 @@ void s_outline(char*name, char*format, char*source)
     outline->shape = shape;
     outline->bbox = bounds;
 
-    dictionary_put2(&outlines, name, outline);
+    dict_put(&outlines, name, outline);
 }
 
-int s_playsound(char*name, int loops, int nomultiple, int stop)
+int s_playsound(const char*name, int loops, int nomultiple, int stop)
 {
     sound_t* sound;
     SOUNDINFO info;
     if(!name)
        return 0;
-    sound = dictionary_lookup(&sounds, name);
+    sound = dict_lookup(&sounds, name);
     if(!sound)
        return 0;
 
@@ -1970,7 +2058,7 @@ int s_playsound(char*name, int loops, int nomultiple, int stop)
     return 1;
 }
 
-void s_includeswf(char*name, char*filename)
+void s_includeswf(const char*name, const char*filename)
 {
     int f;
     SWF swf;
@@ -1980,12 +2068,12 @@ void s_includeswf(char*name, char*filename)
     int level = 0;
     U16 cutout[] = {ST_SETBACKGROUNDCOLOR, ST_PROTECT, ST_FREEALL, ST_REFLEX};
     f = open(filename,O_RDONLY|O_BINARY);
-    if (f<0) {
+    if(f<0) {
        warning("Couldn't open file \"%s\": %s", filename, strerror(errno));
        s_box(name, 0, 0, black, 20, 0);
        return;
     }
-    if (swf_ReadSWF(f,&swf)<0) {
+    if(swf_ReadSWF(f,&swf)<0) {
        warning("Only SWF files supported in .shape for now. File \"%s\" wasn't SWF.", filename);
        s_box(name, 0, 0, black, 20, 0);
        return;
@@ -2042,27 +2130,27 @@ void s_includeswf(char*name, char*filename)
     s_addcharacter(name, id, tag, r);
     incrementid();
 }
-SRECT s_getCharBBox(char*name)
+SRECT s_getCharBBox(const char*name)
 {
-    character_t* c = dictionary_lookup(&characters, name);
+    character_t* c = dict_lookup(&characters, name);
     if(!c) syntaxerror("character '%s' unknown(2)", name);
     return c->size;
 }
-SRECT s_getInstanceBBox(char*name)
+SRECT s_getInstanceBBox(const char*name)
 {
-    instance_t * i = dictionary_lookup(&instances, name);
+    instance_t * i = dict_lookup(&instances, name);
     character_t * c;
     if(!i) syntaxerror("instance '%s' unknown(4)", name);
     c = i->character;
     if(!c) syntaxerror("internal error(5)");
     return c->size;
 }
-void s_getParameters(char*name, parameters_t* p)
+void s_getParameters(const char*name, parameters_t* p)
 {
-    instance_t * i = dictionary_lookup(&instances, name);
+    instance_t * i = dict_lookup(&instances, name);
     if(!i)
        syntaxerror("instance '%s' unknown(10)", name);
-    if (change_sets_all)
+    if(change_sets_all)
         readParameters(i->history, p, currentframe);
     else
        *p = i->parameters;
@@ -2093,9 +2181,9 @@ void setStartparameters(instance_t* i, parameters_t* p, TAG* tag)
     history_begin(i->history, "flags", currentframe, tag, 0);
 }
 
-void s_startclip(char*instance, char*character, parameters_t p)
+void s_startclip(const char*instance, const char*character, parameters_t p)
 {
-    character_t* c = dictionary_lookup(&characters, character);
+    character_t* c = dict_lookup(&characters, character);
     instance_t* i;
     MATRIX m;
     if(!c) {
@@ -2123,15 +2211,15 @@ void s_endClip()
     swf_SetTagPos(stack[stackpos].tag, 0);
     swf_GetPlaceObject(stack[stackpos].tag, &p);
     p.clipdepth = currentdepth;
-    p.name = 0;
+    //p.name = 0;
     swf_ClearTag(stack[stackpos].tag);
     swf_SetPlaceObject(stack[stackpos].tag, &p);
     currentdepth++;
 }
 
-void s_put(char*instance, char*character, parameters_t p)
+void s_put(const char*instance, const char*character, parameters_t p)
 {
-    character_t* c = dictionary_lookup(&characters, character);
+    character_t* c = dict_lookup(&characters, character);
     instance_t* i;
     MATRIX m;
     if(!c)
@@ -2161,82 +2249,82 @@ void s_put(char*instance, char*character, parameters_t p)
 
 void recordChanges(history_t* history, parameters_t p, int changeFunction, interpolation_t* inter)
 {
-    if (p.set & SF_X)
+    if(p.set & SF_X)
         history_remember(history, "x", currentframe, changeFunction, p.x, inter);
-    if (p.set & SF_Y)
+    if(p.set & SF_Y)
         history_remember(history, "y", currentframe, changeFunction, p.y, inter);
-    if (p.set & SF_SCALEX)
+    if(p.set & SF_SCALEX)
         history_remember(history, "scalex", currentframe, changeFunction, p.scalex, inter);
-    if (p.set & SF_SCALEY)
+    if(p.set & SF_SCALEY)
         history_remember(history, "scaley", currentframe, changeFunction, p.scaley, inter);
-    if (p.set & SF_CX_R)
+    if(p.set & SF_CX_R)
     {
         history_remember(history, "cxform.r0", currentframe, changeFunction, p.cxform.r0, inter);
         history_remember(history, "cxform.r1", currentframe, changeFunction, p.cxform.r1, inter);
     }
-    if (p.set & SF_CX_G)
+    if(p.set & SF_CX_G)
     {
         history_remember(history, "cxform.g0", currentframe, changeFunction, p.cxform.g0, inter);
         history_remember(history, "cxform.g1", currentframe, changeFunction, p.cxform.g1, inter);
     }
-    if (p.set & SF_CX_B)
+    if(p.set & SF_CX_B)
     {
         history_remember(history, "cxform.b0", currentframe, changeFunction, p.cxform.b0, inter);
         history_remember(history, "cxform.b1", currentframe, changeFunction, p.cxform.b1, inter);
     }
-    if (p.set & SF_CX_A)
+    if(p.set & SF_CX_A)
     {
         history_remember(history, "cxform.a0", currentframe, changeFunction, p.cxform.a0, inter);
         history_remember(history, "cxform.a1", currentframe, changeFunction, p.cxform.a1, inter);
     }
-    if (p.set & SF_ROTATE)
+    if(p.set & SF_ROTATE)
         history_remember(history, "rotate", currentframe, changeFunction, p.rotate, inter);
-    if (p.set & SF_SHEAR)
+    if(p.set & SF_SHEAR)
         history_remember(history, "shear", currentframe, changeFunction, p.shear, inter);
-    if (p.set & SF_PIVOT)
+    if(p.set & SF_PIVOT)
     {
         history_remember(history, "pivot.x", currentframe, changeFunction, p.pivot.x, inter);
         history_remember(history, "pivot.y", currentframe, changeFunction, p.pivot.y, inter);
     }
-    if (p.set & SF_PIN)
+    if(p.set & SF_PIN)
     {
         history_remember(history, "pin.x", currentframe, changeFunction, p.pin.x, inter);
         history_remember(history, "pin.y", currentframe, changeFunction, p.pin.y, inter);
     }
-    if (p.set & SF_BLEND)
+    if(p.set & SF_BLEND)
         history_remember(history, "blendmode", currentframe, changeFunction, p.blendmode, inter);
-    if (p.set & SF_FILTER)
+    if(p.set & SF_FILTER)
         history_rememberFilter(history, currentframe, changeFunction, p.filters, inter);
 }
 
-void s_jump(char* instance, parameters_t p)
+void s_jump(const char* instance, parameters_t p)
 {
-    instance_t* i = dictionary_lookup(&instances, instance);
+    instance_t* i = dict_lookup(&instances, instance);
     if(!i)
         syntaxerror("instance %s not known", instance);
     recordChanges(i->history, p, CF_JUMP, 0);
 }
 
-void s_change(char*instance, parameters_t p, interpolation_t* inter)
+void s_change(const char*instance, parameters_t p, interpolation_t* inter)
 {
-    instance_t* i = dictionary_lookup(&instances, instance);
+    instance_t* i = dict_lookup(&instances, instance);
     if(!i)
         syntaxerror("instance %s not known", instance);
     recordChanges(i->history, p, CF_CHANGE, inter);
 }
 
-void s_sweep(char* instance, parameters_t p, float radius, int clockwise, int short_arc, interpolation_t* inter)
+void s_sweep(const char* instance, parameters_t p, float radius, int clockwise, int short_arc, interpolation_t* inter)
 {
-    instance_t* i = dictionary_lookup(&instances, instance);
+    instance_t* i = dict_lookup(&instances, instance);
     if(!i)
         syntaxerror("instance %s not known", instance);
     history_rememberSweep(i->history, currentframe, p.x, p.y, radius, clockwise, short_arc, inter);
 }
 
-void s_toggle(char* instance, U16 flagsOn, U16 flagsOff)
+void s_toggle(const char* instance, U16 flagsOn, U16 flagsOff)
 {
-    instance_t* i = dictionary_lookup(&instances, instance);
-    if (!i)
+    instance_t* i = dict_lookup(&instances, instance);
+    if(!i)
         syntaxerror("instance %s not known", instance);
     U16 flags = (U16)history_value(i->history, currentframe, "flags");
     flags |= flagsOn;
@@ -2244,20 +2332,21 @@ void s_toggle(char* instance, U16 flagsOn, U16 flagsOff)
     history_remember(i->history, "flags", currentframe, CF_JUMP, flags, 0);
 }
 
-void s_delinstance(char*instance)
+void s_delinstance(const char*instance)
 {
-    instance_t* i = dictionary_lookup(&instances, instance);
+    instance_t* i = dict_lookup(&instances, instance);
     if(!i)
         syntaxerror("instance %s not known", instance);
     writeInstance(i);
     tag = swf_InsertTag(tag, ST_REMOVEOBJECT2);
     swf_SetU16(tag, i->depth);
-    dictionary_del(&instances, instance);
+    dict_del(&instances, instance);
+    free(i);
 }
 
-void s_schange(char*instance, parameters_t p, interpolation_t* inter)
+void s_schange(const char*instance, parameters_t p, interpolation_t* inter)
 {
-    instance_t* i = dictionary_lookup(&instances, instance);
+    instance_t* i = dict_lookup(&instances, instance);
     if(!i)
         syntaxerror("instance %s not known", instance);
     recordChanges(i->history, p, CF_SCHANGE, inter);
@@ -2290,7 +2379,7 @@ void s_end()
 
 typedef int command_func_t(map_t*args);
 
-SRECT parseBox(char*str)
+SRECT parseBox(const char*str)
 {
     SRECT r = {0,0,0,0};
     float xmin, xmax, ymin, ymax;
@@ -2330,11 +2419,11 @@ error:
     syntaxerror("expression %s is not a valid bound Box.\nE.g. 1024x768 or 1024x768:30:30 would have been valid bounding Boxes.", str);
     return r;
 }
-float parseFloat(char*str)
+float parseFloat(const char*str)
 {
     return atof(str);
 }
-int parseInt(char*str)
+int parseInt(const char*str)
 {
     int t;
     int l=strlen(str);
@@ -2347,7 +2436,7 @@ int parseInt(char*str)
            syntaxerror("Not an Integer: \"%s\"", str);
     return atoi(str);
 }
-int parseRawTwip(char*str)
+static double parseRawTwip(const char*str)
 {
     char*dot;
     int sign=1;
@@ -2360,23 +2449,25 @@ int parseRawTwip(char*str)
     if(!dot) {
        int l=strlen(str);
        int t;
-       return sign*parseInt(str)*20;
+       return sign*parseInt(str);
     } else {
        char* old = strdup(str);
        int l=strlen(dot+1);
-       char*s;
+       const char*s;
        *dot++ = 0;
-       for(s=str;s<dot-1;s++)
-        if(*s<'0' || *s>'9')
-        {
-            free(old);
-            syntaxerror("Not a coordinate: \"%s\"", str);
+       for(s=str;s<dot-1;s++) {
+            if(*s<'0' || *s>'9')
+            {
+                free(old);
+                syntaxerror("Not a coordinate: \"%s\"", str);
+            }
         }
-    for(s=dot;*s;s++)
-        if(*s<'0' || *s>'9')
-        {
-            free(old);
-            syntaxerror("Not a coordinate: \"%s\"", str);
+        for(s=dot;*s;s++) {
+            if(*s<'0' || *s>'9')
+            {
+                free(old);
+                syntaxerror("Not a coordinate: \"%s\"", str);
+            }
         }
        if(l>2 || (l==2 && (dot[1]!='0' && dot[1]!='5'))) {
            dot[1] = ((dot[1]-0x30)/5)*5 + 0x30;
@@ -2386,85 +2477,167 @@ int parseRawTwip(char*str)
        }
        free(old);
        if(l==0)
-           return sign*(atoi(str)*20);
+           return sign*(atoi(str));
        if(l==1)
-           return sign*(atoi(str)*20+atoi(dot)*2);
+           return sign*(atoi(str)+0.1*atoi(dot));
        if(l==2)
-           return sign*(atoi(str)*20+atoi(dot)/5);
+           return sign*(atoi(str)+0.01*atoi(dot));
     }
     return 0;
 }
 
-static dictionary_t defines;
+static dict_t defines;
 static int defines_initialized = 0;
 static mem_t define_values;
 
-int parseTwip(char*str)
-{
-    /* TODO: make this a proper expression parser */
-    char*p = str;
-    int val = 0;
-    char ex = 0;
-    char*lastpos = str;
-    while(*p) {
-       if(*p == '+' || *p == '-' || *p == '/' || *p == '*')
-           ex = *p;
-       else if(!lastpos)
-           lastpos = p;
-       p++;
-       if((*p == '+' || *p == '-' || *p == '/' || *p == '*' || *p == 0) && lastpos) {
-           char save = *p;
-           *p = 0;
-
-           int l = 0;
-           int v = 0;
-           if(defines_initialized) {
-               l = (int)dictionary_lookup(&defines, lastpos);
-           }
-           if(l) {
-               v = *(int*)&define_values.buffer[l-1];
-           } else {
-               v = parseRawTwip(lastpos);
-           }
-           *p = save;
-           if(ex == '+') 
-               val += v;
-           else if(ex == '-')
-               val -= v;
-           else if(ex == '/')
-               val = (val*20) / v;
-           else if(ex == '*')
-               val = (val*v) / 20;
-           else
-               val += v;
-           ex = 0;
-           lastpos = 0;
-       }
+static double parseNameOrTwip(const char*s)
+{
+    int l = 0;
+    double v;
+    if(defines_initialized) {
+        l = (int)dict_lookup(&defines, s);
+    }
+    if(l) {
+        return *(int*)&define_values.buffer[l-1];
+    } else {
+        return parseRawTwip(s);
+    }
+}
+
+/* automatically generated by yiyiyacc, http://www.quiss.org/yiyiyacc/ */
+static double parseExpression(char*s)
+{
+    int chr2index[256];
+    memset(chr2index, -1, sizeof(chr2index));
+    chr2index['+'] = 0;
+    chr2index['-'] = 1;
+    chr2index['*'] = 2;
+    chr2index['/'] = 3;
+    chr2index['('] = 5;
+    chr2index[')'] = 6;
+    chr2index['\0'] = 7;
+
+    int stackpos = 1;
+    int stack[256];
+    double values[256];
+    stack[0]=0;
+    values[0]=0;
+    int accept = 18;
+    int left[10]={11,8,8,8,8,9,9,9,10,10}; //production left side
+    int plen[10]={1,3,2,3,1,3,3,1,1,3}; //production size
+    int table[18][12] = {
+        {0, 4, 0, 0, 5, 6, 0, 0, 1, 2, 3, 0},
+        {7, 8, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0},
+        {-4, -4, 9, 10, 0, 0, -4, -4, 0, 0, 0, 0},
+        {-7, -7, -7, -7, 0, 0, -7, -7, 0, 0, 0, 0},
+        {0, 0, 0, 0, 5, 6, 0, 0, 0, 11, 3, 0},
+        {-8, -8, -8, -8, 0, 0, -8, -8, 0, 0, 0, 0},
+        {0, 4, 0, 0, 5, 6, 0, 0, 12, 2, 3, 0},
+        {0, 0, 0, 0, 5, 6, 0, 0, 0, 13, 3, 0},
+        {0, 0, 0, 0, 5, 6, 0, 0, 0, 14, 3, 0},
+        {0, 0, 0, 0, 5, 6, 0, 0, 0, 0, 15, 0},
+        {0, 0, 0, 0, 5, 6, 0, 0, 0, 0, 16, 0},
+        {-2, -2, 9, 10, 0, 0, -2, -2, 0, 0, 0, 0},
+        {7, 8, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0},
+        {-1, -1, 9, 10, 0, 0, -1, -1, 0, 0, 0, 0},
+        {-3, -3, 9, 10, 0, 0, -3, -3, 0, 0, 0, 0},
+        {-5, -5, -5, -5, 0, 0, -5, -5, 0, 0, 0, 0},
+        {-6, -6, -6, -6, 0, 0, -6, -6, 0, 0, 0, 0},
+        {-9, -9, -9, -9, 0, 0, -9, -9, 0, 0, 0, 0}};
+
+    char*p = s;
+    while(1) {
+        char*pnext = p+1;
+        int action;
+        double value = 0;
+        if(!stackpos) {
+            fprintf(stderr, "Error in expression\n");
+            return 0.0;
+        }
+
+        if(chr2index[*p]<0) {
+            action = table[stack[stackpos-1]][4];
+            if(action>0) {
+                while(chr2index[*pnext]<0) 
+                    pnext++;
+                char save = *pnext;
+                *pnext = 0;
+                value = parseNameOrTwip(p);
+                *pnext = save;
+            }
+        } else {
+            action = table[stack[stackpos-1]][chr2index[*p]];
+        }
+
+        if(action == accept) {
+            return values[stack[stackpos-1]];
+        } else if(action>0) { // shift
+            if(stackpos>254) {
+                fprintf(stderr, "Stack overflow while parsing expression\n");
+                return 0.0;
+            }
+            values[stackpos]=value;
+            stack[stackpos++]=action;
+            p=pnext;
+        } else if(action<0) { // reduce
+            stackpos-=plen[-action];
+            stack[stackpos] = table[stack[stackpos-1]][left[-action]];
+            switch(-action) {
+              case 1:
+                values[stackpos] = values[stackpos+0] + values[stackpos+2];
+              break;
+              case 2:
+                values[stackpos] = 0 - values[stackpos+1];
+              break;
+              case 3:
+                values[stackpos] = values[stackpos+0] - values[stackpos+2];
+              break;
+              case 5:
+                values[stackpos] = values[stackpos+0] * values[stackpos+2];
+              break;
+              case 6:
+                values[stackpos] = values[stackpos+0] / values[stackpos+2];
+              break;
+              case 9:
+                values[stackpos] = values[stackpos+1];
+              break;
+            }
+            stackpos++;
+        } else {
+            fprintf(stderr, "Syntax error in expression\n");
+            return 0.0;
+        }
     }
-    return val;
 }
 
-int parseArc(char* str)
+int parseTwip(const char*str)
 {
-    if (!strcmp(str, "short"))
+    char*str2 = (char*)str;
+    int v = (int)(parseExpression(str2)*20);
+    return v;
+}
+
+int parseArc(const char* str)
+{
+    if(!strcmp(str, "short"))
        return 1;
-    if (!strcmp(str, "long"))
+    if(!strcmp(str, "long"))
        return 0;
     syntaxerror("invalid value for the arc parameter: %s", str);
     return 1;
 }
 
-int parseDir(char* str)
+int parseDir(const char* str)
 {
-    if (!strcmp(str, "clockwise"))
+    if(!strcmp(str, "clockwise"))
        return 1;
-    if (!strcmp(str, "counterclockwise"))
+    if(!strcmp(str, "counterclockwise"))
        return 0;
     syntaxerror("invalid value for the dir parameter: %s", str);
     return 1;
 }
 
-int isPoint(char*str)
+int isPoint(const char*str)
 {
     if(strchr(str, '('))
        return 1;
@@ -2472,7 +2645,7 @@ int isPoint(char*str)
        return 0;
 }
 
-SPOINT parsePoint(char*str)
+SPOINT parsePoint(const char*str)
 {
     SPOINT p;
     char tmp[80];
@@ -2487,7 +2660,7 @@ SPOINT parsePoint(char*str)
     return p;
 }
 
-int parseColor2(char*str, RGBA*color)
+int parseColor2(const char*str, RGBA*color)
 {
     int l = strlen(str);
     int r,g,b,a;
@@ -2518,7 +2691,7 @@ int parseColor2(char*str, RGBA*color)
        return 1;
     }
     int len=strlen(str);
-    U8 alpha = 255;
+    int alpha = 255;
     if(strchr(str, '/')) {
        len = strchr(str, '/')-str;
        sscanf(str+len+1,"%02x", &alpha);
@@ -2535,7 +2708,7 @@ int parseColor2(char*str, RGBA*color)
     return 0;
 
 }
-RGBA parseColor(char*str)
+RGBA parseColor(const char*str)
 {
     RGBA c;
     if(!parseColor2(str, &c))
@@ -2548,7 +2721,7 @@ typedef struct _muladd {
     S16 add;
 } MULADD;
 
-MULADD parseMulAdd(char*str)
+MULADD parseMulAdd(const char*str)
 {
     float add, mul;
     char* str2 = (char*)malloc(strlen(str)+5);
@@ -2591,7 +2764,7 @@ MULADD mergeMulAdd(MULADD m1, MULADD m2)
     return r;
 }
 
-float parsePxOrPercent(char*fontname, char*str)
+float parsePxOrPercent(const char*fontname, const char*str)
 {
     int l = strlen(str);
     if(strchr(str, '%'))
@@ -2604,22 +2777,22 @@ float parsePxOrPercent(char*fontname, char*str)
     return 0;
 }
 
-float parsePercent(char*str)
+float parsePercent(const char*str)
 {
     int l = strlen(str);
     if(!l)
        return 1.0;
     if(str[l-1]=='%') {
-       return atoi(str)/100.0;
+       return atof(str)/100.0;
     }
     syntaxerror("Expression '%s' is not a percentage", str);
     return 0;
 }
-int isPercent(char*str)
+int isPercent(const char*str)
 {
     return str[strlen(str)-1]=='%';
 }
-int parseNewSize(char*str, int size)
+int parseNewSize(const char*str, int size)
 {
     if(isPercent(str))
        return parsePercent(str)*size;
@@ -2633,9 +2806,9 @@ int isColor(char*str)
     return parseColor2(str, &c);
 }
 
-static char* lu(map_t* args, char*name)
+static const char* lu(map_t* args, char*name)
 {
-    char* value = map_lookup(args, name);
+    const char* value = map_lookup(args, name);
     if(!value) {
        map_dump(args, stdout, "");
        syntaxerror("internal error 2: value %s should be set", name);
@@ -2645,10 +2818,10 @@ static char* lu(map_t* args, char*name)
 
 static int c_flash(map_t*args)
 {
-    char* filename = map_lookup(args, "filename");
-    char* compressstr = lu(args, "compress");
-    char* change_modestr = lu(args, "change-sets-all");
-    char* exportstr = lu(args, "export");
+    const char* filename = map_lookup(args, "filename");
+    const char* compressstr = lu(args, "compress");
+    const char* change_modestr = lu(args, "change-sets-all");
+    const char* exportstr = lu(args, "export");
     SRECT bbox = parseBox(lu(args, "bbox"));
     int version = parseInt(lu(args, "version"));
     int fps = (int)(parseFloat(lu(args, "fps"))*256);
@@ -2684,16 +2857,17 @@ static int c_flash(map_t*args)
            syntaxerror("value \"%s\" not supported for the change-sets-all argument", change_modestr);
 
     do_exports=atoi(exportstr);
+    mainclass=strdup(lu(args, "mainclass"));
 
     s_swf(filename, bbox, version, fps, compress, color);
     return 0;
 }
-int isRelative(char*str)
+int isRelative(const char*str)
 {
     return !strncmp(str, "<plus>", 6) ||
           !strncmp(str, "<minus>", 7);
 }
-char* getOffset(char*str)
+const char* getOffset(const char*str)
 {
     if(!strncmp(str, "<plus>", 6))
        return str+6;
@@ -2702,7 +2876,7 @@ char* getOffset(char*str)
     syntaxerror("internal error (347)");
     return 0;
 }
-int getSign(char*str)
+int getSign(const char*str)
 {
     if(!strncmp(str, "<plus>", 6))
        return 1;
@@ -2712,27 +2886,27 @@ int getSign(char*str)
     return 0;
 }
 
-static dictionary_t points;
+static dict_t points;
 static mem_t mpoints;
 static int points_initialized = 0;
 
 static int c_interpolation(map_t *args)
 {
     int i;
-    char* name = lu(args, "name");
-    if (dictionary_lookup(&interpolations, name))
+    const char* name = lu(args, "name");
+    if(dict_lookup(&interpolations, name))
         syntaxerror("interpolation %s defined twice", name);
 
     interpolation_t* inter = (interpolation_t*)malloc(sizeof(interpolation_t));
-    char* functionstr = lu(args, "function");
+    const char* functionstr = lu(args, "function");
     inter->function = 0;
     for (i = 0; i < sizeof(interpolationFunctions) / sizeof(interpolationFunctions[0]); i++)
-        if (!strcmp(functionstr,interpolationFunctions[i]))
+        if(!strcmp(functionstr,interpolationFunctions[i]))
         {
             inter->function = i + 1;
             break;
         }
-    if (!inter->function)
+    if(!inter->function)
         syntaxerror("unkown interpolation function %s", functionstr);
     inter->speed = parseFloat(lu(args, "speed"));
     inter->amplitude = parseTwip(lu(args, "amplitude"));
@@ -2741,11 +2915,11 @@ static int c_interpolation(map_t *args)
     inter->damping = parseFloat(lu(args, "damping"));
     inter->slope = parseFloat(lu(args, "slope"));
 
-    dictionary_put2(&interpolations, name, inter);
+    dict_put(&interpolations, name, inter);
     return 0;
 }
 
-SPOINT getPoint(SRECT r, char*name)
+SPOINT getPoint(SRECT r, const char*name)
 {
     int l=0;
     if(!strcmp(name, "center")) {
@@ -2754,49 +2928,49 @@ SPOINT getPoint(SRECT r, char*name)
         p.y = (r.ymin + r.ymax)/2;
         return p;
     }
-    if (!strcmp(name, "bottom-center")) {
+    if(!strcmp(name, "bottom-center")) {
         SPOINT p;
         p.x = (r.xmin + r.xmax)/2;
         p.y = r.ymax;
         return p;
     }
-    if (!strcmp(name, "top-center")) {
+    if(!strcmp(name, "top-center")) {
         SPOINT p;
         p.x = (r.xmin + r.xmax)/2;
         p.y = r.ymin;
         return p;
     }
-    if (!strcmp(name, "top-left")) {
+    if(!strcmp(name, "top-left")) {
         SPOINT p;
         p.x = r.xmin;
         p.y = r.ymin;
         return p;
     }
-    if (!strcmp(name, "top-right")) {
+    if(!strcmp(name, "top-right")) {
         SPOINT p;
         p.x = r.xmax;
         p.y = r.ymin;
         return p;
     }
-    if (!strcmp(name, "bottom-right")) {
+    if(!strcmp(name, "bottom-right")) {
         SPOINT p;
         p.x = r.xmax;
         p.y = r.ymax;
         return p;
     }
-    if (!strcmp(name, "bottom-left")) {
+    if(!strcmp(name, "bottom-left")) {
         SPOINT p;
         p.x = r.xmin;
         p.y = r.ymax;
         return p;
     }
-    if (!strcmp(name, "left-center")) {
+    if(!strcmp(name, "left-center")) {
         SPOINT p;
         p.x = r.xmin;
         p.y = (r.ymin + r.ymax)/2;
         return p;
     }
-    if (!strcmp(name, "right-center")) {
+    if(!strcmp(name, "right-center")) {
         SPOINT p;
         p.x = r.xmax;
         p.y = (r.ymin + r.ymax)/2;
@@ -2805,7 +2979,7 @@ SPOINT getPoint(SRECT r, char*name)
 
 
     if(points_initialized)
-        l = (int)dictionary_lookup(&points, name);
+        l = (int)dict_lookup(&points, name);
     if(l==0) {
         syntaxerror("Invalid point: \"%s\".", name);
     }
@@ -2813,19 +2987,19 @@ SPOINT getPoint(SRECT r, char*name)
 }
 
 
-static int texture2(char*name, char*object, map_t*args, int errors)
+static int texture2(const char*name, const char*object, map_t*args, int errors)
 {
     SPOINT pos,size;
-    char*xstr = map_lookup(args, "x");
-    char*ystr = map_lookup(args, "y");
-    char*widthstr = map_lookup(args, "width");
-    char*heightstr = map_lookup(args, "height");
-    char*scalestr = map_lookup(args, "scale");
-    char*scalexstr = map_lookup(args, "scalex");
-    char*scaleystr = map_lookup(args, "scaley");
-    char*rotatestr = map_lookup(args, "rotate");
-    char* shearstr = map_lookup(args, "shear");
-    char* radiusstr = map_lookup(args, "r");
+    const char*xstr = map_lookup(args, "x");
+    const char*ystr = map_lookup(args, "y");
+    const char*widthstr = map_lookup(args, "width");
+    const char*heightstr = map_lookup(args, "height");
+    const char*scalestr = map_lookup(args, "scale");
+    const char*scalexstr = map_lookup(args, "scalex");
+    const char*scaleystr = map_lookup(args, "scaley");
+    const char*rotatestr = map_lookup(args, "rotate");
+    const char* shearstr = map_lookup(args, "shear");
+    const char* radiusstr = map_lookup(args, "r");
     float x=0,y=0;
     float scalex = 1.0, scaley = 1.0;
     float rotate=0, shear=0;
@@ -2877,14 +3051,14 @@ static int texture2(char*name, char*object, map_t*args, int errors)
 
 static int c_texture(map_t*args)
 {
-    char*name = lu(args, "instance");
-    char*object = lu(args, "character");
+    const char*name = lu(args, "instance");
+    const char*object = lu(args, "character");
     return texture2(name, object, args, 1);
 }
 
 static int c_gradient(map_t*args)
 {
-    char*name = lu(args, "name");
+    const char*name = lu(args, "name");
     int radial= strcmp(lu(args, "radial"), "radial")?0:1;
     int rotate = parseInt(lu(args, "rotate"));
 
@@ -2892,7 +3066,7 @@ static int c_gradient(map_t*args)
     if(type != RAWDATA)
         syntaxerror("colon (:) expected");
 
-    if(dictionary_lookup(&gradients, name))
+    if(dict_lookup(&gradients, name))
         syntaxerror("gradient %s defined twice", name);
 
     s_gradient(name, text, radial, rotate);
@@ -2906,20 +3080,20 @@ static int c_gradient(map_t*args)
     return 0;
 }
 
-static char* checkFiltername(map_t* args)
+static const char* checkFiltername(map_t* args)
 {
-    char* name = lu(args, "name");
-    if (strchr(name, ','))
+    const char* name = lu(args, "name");
+    if(strchr(name, ','))
        syntaxerror("the comma (,) is used to separate filters in filterlists. Please do not use in filternames.");
     return name;
 }
 
 static int c_blur(map_t*args)
 {
-    char*name = checkFiltername(args);
-    char*blurstr = lu(args, "blur");
-    char*blurxstr = lu(args, "blurx");
-    char*blurystr = lu(args, "blury");
+    const char*name = checkFiltername(args);
+    const char*blurstr = lu(args, "blur");
+    const char*blurxstr = lu(args, "blurx");
+    const char*blurystr = lu(args, "blury");
     float blurx=1.0, blury=1.0;
     if(blurstr[0]) {
        blurx = parseFloat(blurstr);
@@ -2936,11 +3110,11 @@ static int c_blur(map_t*args)
 
 static int c_gradientglow(map_t*args)
 {
-    char*name = checkFiltername(args);
-    char*gradient = lu(args, "gradient");
-    char*blurstr = lu(args, "blur");
-    char*blurxstr = lu(args, "blurx");
-    char*blurystr = lu(args, "blury");
+    const char*name = checkFiltername(args);
+    const char*gradient = lu(args, "gradient");
+    const char*blurstr = lu(args, "blur");
+    const char*blurxstr = lu(args, "blurx");
+    const char*blurystr = lu(args, "blury");
     float blurx=1.0, blury=1.0;
     if(blurstr[0]) {
        blurx = parseFloat(blurstr);
@@ -2966,11 +3140,11 @@ static int c_gradientglow(map_t*args)
 
 static int c_dropshadow(map_t*args)
 {
-    char*name = checkFiltername(args);
+    const char*name = checkFiltername(args);
     RGBA color = parseColor(lu(args, "color"));
-    char*blurstr = lu(args, "blur");
-    char*blurxstr = lu(args, "blurx");
-    char*blurystr = lu(args, "blury");
+    const char*blurstr = lu(args, "blur");
+    const char*blurxstr = lu(args, "blurx");
+    const char*blurystr = lu(args, "blury");
     float blurx=1.0, blury=1.0;
     if(blurstr[0]) {
        blurx = parseFloat(blurstr);
@@ -2995,12 +3169,12 @@ static int c_dropshadow(map_t*args)
 
 static int c_bevel(map_t*args)
 {
-    char*name = checkFiltername(args);
+    const char*name = checkFiltername(args);
     RGBA shadow = parseColor(lu(args, "shadow"));
     RGBA highlight = parseColor(lu(args, "highlight"));
-    char*blurstr = lu(args, "blur");
-    char*blurxstr = lu(args, "blurx");
-    char*blurystr = lu(args, "blury");
+    const char*blurstr = lu(args, "blur");
+    const char*blurxstr = lu(args, "blurx");
+    const char*blurystr = lu(args, "blury");
     float blurx=1.0, blury=1.0;
     if(blurstr[0]) {
        blurx = parseFloat(blurstr);
@@ -3026,44 +3200,40 @@ static int c_bevel(map_t*args)
 
 static int c_define(map_t*args)
 {
-    char*name = lu(args, "name");
-    char*value = lu(args, "value");
+    const char*name = lu(args, "name");
+    const char*value = lu(args, "value");
     
     if(!defines_initialized) {
-       dictionary_init(&defines);
+       dict_init(&defines, 16);
        mem_init(&define_values);
        defines_initialized = 1;
     }
     int val = parseTwip(value);
     int pos = mem_put(&define_values, &val, sizeof(val));
-    string_t s;
-    string_set(&s, name);
-    dictionary_put(&defines, s, (void*)(pos+1));
+    dict_put(&defines, name, (void*)(pos+1));
     return 0;
 }
 static int c_point(map_t*args)
 {
-    char*name = lu(args, "name");
+    const char*name = lu(args, "name");
     int pos;
-    string_t s1;
     SPOINT p;
     if(!points_initialized) {
-       dictionary_init(&points);
+       dict_init(&points, 16);
        mem_init(&mpoints);
        points_initialized = 1;
     }
     p.x = parseTwip(lu(args, "x"));
     p.y = parseTwip(lu(args, "y"));
     pos = mem_put(&mpoints, &p, sizeof(p));
-    string_set(&s1, name);
-    dictionary_put(&points, s1, (void*)(pos+1));
+    dict_put(&points, name, (void*)(pos+1));
     return 0;
 }
 static int c_play(map_t*args)
 {
-    char*name = lu(args, "name");
-    char*loop = lu(args, "loop");
-    char*nomultiple = lu(args, "nomultiple");
+    const char*name = lu(args, "name");
+    const char*loop = lu(args, "loop");
+    const char*nomultiple = lu(args, "nomultiple");
     int nm = 0;
     if(!strcmp(nomultiple, "nomultiple"))
        nm = 1;
@@ -3080,7 +3250,7 @@ static int c_play(map_t*args)
 
 static int c_stop(map_t*args)
 {
-    char*name = map_lookup(args, "name");
+    const char*name = map_lookup(args, "name");
 
     if(s_playsound(name, 0,0,1))
         return 0;
@@ -3092,7 +3262,7 @@ static int c_stop(map_t*args)
 
 static int c_nextframe(map_t*args)
 {
-    char*name = lu(args, "name");
+    const char*name = lu(args, "name");
 
     if(s_swf3action(name, "nextframe")) {
        return 0;
@@ -3103,7 +3273,7 @@ static int c_nextframe(map_t*args)
 
 static int c_previousframe(map_t*args)
 {
-    char*name = lu(args, "name");
+    const char*name = lu(args, "name");
 
     if(s_swf3action(name, "previousframe")) {
        return 0;
@@ -3114,10 +3284,10 @@ static int c_previousframe(map_t*args)
 
 static int c_movement(map_t*args, int type)
 {
-    char*instance = lu(args, "name");
+    const char*instance = lu(args, "name");
 
-    char* xstr="";
-    char* ystr="";
+    const char* xstr="";
+    const char* ystr="";
     SRECT oldbbox;
     parameters_t p;
     U16 set = 0x0000;
@@ -3157,7 +3327,7 @@ static int c_movement(map_t*args, int type)
         set = set | SF_Y;
     }
 
-    if (change_sets_all)
+    if(change_sets_all)
        set = SF_ALL;
     p.set = set;
 
@@ -3165,35 +3335,35 @@ static int c_movement(map_t*args, int type)
     {
         case PT_MOVE:
             {
-                char* interstr = lu(args, "interpolation");
-                interpolation_t* inter = (interpolation_t*)dictionary_lookup(&interpolations, interstr);
-                if (!inter)
+                const char* interstr = lu(args, "interpolation");
+                interpolation_t* inter = (interpolation_t*)dict_lookup(&interpolations, interstr);
+                if(!inter)
                     syntaxerror("unkown interpolation %s", interstr);
                 s_change(instance, p, inter);
             }
             break;
         case PT_SMOVE:
             {
-                char* interstr = lu(args, "interpolation");
-                interpolation_t* inter = (interpolation_t*)dictionary_lookup(&interpolations, interstr);
-                if (!inter)
+                const char* interstr = lu(args, "interpolation");
+                interpolation_t* inter = (interpolation_t*)dict_lookup(&interpolations, interstr);
+                if(!inter)
                     syntaxerror("unkown interpolation %s", interstr);
                s_schange(instance, p, inter);
             }
             break;
         case PT_SWEEP:
             {
-               char* rstr = lu(args, "r");
+               const char* rstr = lu(args, "r");
                int radius = parseTwip(rstr);
-               if (radius <= 0)
+               if(radius <= 0)
                        syntaxerror("sweep not possible: radius must be greater than 0.");
-               char* dirstr = lu(args, "dir");
+               const char* dirstr = lu(args, "dir");
                int clockwise = parseDir(dirstr);
-               char* arcstr = lu(args, "arc");
+               const char* arcstr = lu(args, "arc");
                int short_arc = parseArc(arcstr);
-                char* interstr = lu(args, "interpolation");
-                interpolation_t* inter = (interpolation_t*)dictionary_lookup(&interpolations, interstr);
-                if (!inter)
+                const char* interstr = lu(args, "interpolation");
+                interpolation_t* inter = (interpolation_t*)dict_lookup(&interpolations, interstr);
+                if(!inter)
                     syntaxerror("unkown interpolation %s", interstr);
                s_sweep(instance, p, radius, clockwise, short_arc, inter);
             }
@@ -3204,27 +3374,27 @@ static int c_movement(map_t*args, int type)
 
 static int c_placement(map_t*args, int type)
 {
-    char*instance = lu(args, (type==PT_PUT||type==PT_STARTCLIP)?"instance":"name");
-    char*character = 0;
-
-    char* luminancestr = lu(args, "luminance");
-    char* scalestr = lu(args, "scale");
-    char* scalexstr = lu(args, "scalex");
-    char* scaleystr = lu(args, "scaley");
-    char* rotatestr = lu(args, "rotate");
-    char* shearstr = lu(args, "shear");
-    char* xstr="", *pivotstr="";
-    char* ystr="", *anglestr="";
-    char*above = lu(args, "above"); /*FIXME*/
-    char*below = lu(args, "below");
-    char* rstr = lu(args, "red");
-    char* gstr = lu(args, "green");
-    char* bstr = lu(args, "blue");
-    char* astr = lu(args, "alpha");
-    char* pinstr = lu(args, "pin");
-    char* as = map_lookup(args, "as");
-    char* blendmode = lu(args, "blend");
-    char* filterstr = lu(args, "filter");
+    const char*instance = lu(args, (type==PT_PUT||type==PT_STARTCLIP)?"instance":"name");
+    const char*character = 0;
+
+    const char* luminancestr = lu(args, "luminance");
+    const char* scalestr = lu(args, "scale");
+    const char* scalexstr = lu(args, "scalex");
+    const char* scaleystr = lu(args, "scaley");
+    const char* rotatestr = lu(args, "rotate");
+    const char* shearstr = lu(args, "shear");
+    const char* xstr="", *pivotstr="";
+    const char* ystr="", *anglestr="";
+    const char*above = lu(args, "above"); /*FIXME*/
+    const char*below = lu(args, "below");
+    const char* rstr = lu(args, "red");
+    const char* gstr = lu(args, "green");
+    const char* bstr = lu(args, "blue");
+    const char* astr = lu(args, "alpha");
+    const char* pinstr = lu(args, "pin");
+    const char* as = map_lookup(args, "as");
+    const char* blendmode = lu(args, "blend");
+    const char* filterstr = lu(args, "filter");
     U8 blend;
     MULADD r,g,b,a;
     float oldwidth;
@@ -3264,7 +3434,7 @@ static int c_placement(map_t*args, int type)
        // put or startclip
        character = lu(args, "character");
        parameters_clear(&p);
-    } else if (type == PT_BUTTON) {
+    } else if(type == PT_BUTTON) {
        character = lu(args, "name");
        parameters_clear(&p);
        // button's show
@@ -3443,17 +3613,17 @@ static int c_placement(map_t*args, int type)
 
     if(filterstr[0])
     {
-        p.filters = parseFilters(filterstr);
+        p.filters = parseFilters((char*)filterstr);
         set = set | SF_FILTER;
     }
 
-    if (type == PT_CHANGE && set & (SF_X | SF_Y))
+    if(type == PT_CHANGE && set & (SF_X | SF_Y))
        warning("As of version 0.8.2 using the .change command to modify an \
 object's position on the stage is considered deprecated. Future \
 versions may consider x and y parameters for the .change command \
 to be illegal; please use the .move command.");
 
-    if (change_sets_all)
+    if(change_sets_all)
        set = SF_ALL;
     p.set = set;
 
@@ -3464,18 +3634,18 @@ to be illegal; please use the .move command.");
             break;
         case PT_CHANGE:
             {
-                char* interstr = lu(args, "interpolation");
-                interpolation_t* inter = (interpolation_t*)dictionary_lookup(&interpolations, interstr);
-                if (!inter)
+                const char* interstr = lu(args, "interpolation");
+                interpolation_t* inter = (interpolation_t*)dict_lookup(&interpolations, interstr);
+                if(!inter)
                     syntaxerror("unkown interpolation %s", interstr);
                 s_change(instance, p, inter);
             }
             break;
         case PT_SCHANGE:
             {
-                char* interstr = lu(args, "interpolation");
-                interpolation_t* inter = (interpolation_t*)dictionary_lookup(&interpolations, interstr);
-                if (!inter)
+                const char* interstr = lu(args, "interpolation");
+                interpolation_t* inter = (interpolation_t*)dict_lookup(&interpolations, interstr);
+                if(!inter)
                     syntaxerror("unkown interpolation %s", interstr);
                s_schange(instance, p, inter);
             }
@@ -3503,7 +3673,7 @@ static int c_put(map_t*args)
 }
 static int c_change(map_t*args)
 {
-    if (currentframe == 0)
+    if(currentframe == 0)
         warning("change commands in frame 1 will be ignored, please use the put command to set object parameters");
     c_placement(args, PT_CHANGE);
     return 0;
@@ -3550,13 +3720,13 @@ static int c_show(map_t*args)
 }
 static int c_toggle(map_t* args)
 {
-    char*instance = lu(args, "name");
+    const char*instance = lu(args, "name");
     U16 flagsOn = 0x0000, flagsOff = 0xffff;
-    char* alignstr = lu(args, "fixed_alignment");
-    if (!strcmp(alignstr, "on"))
+    const char* alignstr = lu(args, "fixed_alignment");
+    if(!strcmp(alignstr, "on"))
        flagsOn += IF_FIXED_ALIGNMENT;
     else
-       if (!strcmp(alignstr, "off"))
+       if(!strcmp(alignstr, "off"))
            flagsOff -= IF_FIXED_ALIGNMENT;
        else
            syntaxerror("values for toggle must be \"on\" or \"off\". %s is not legal.", alignstr);
@@ -3565,7 +3735,7 @@ static int c_toggle(map_t* args)
 }
 static int c_del(map_t*args)
 {
-    char*instance = lu(args, "name");
+    const char*instance = lu(args, "name");
     s_delinstance(instance);
     return 0;
 }
@@ -3576,24 +3746,25 @@ static int c_end(map_t*args)
 }
 static int c_sprite(map_t*args)
 {
-    char* name = lu(args, "name");
-    char* scalinggrid = lu(args, "scalinggrid");
+    const char* name = lu(args, "name");
+    const char* scalinggrid = lu(args, "scalinggrid");
+    const char* as3name = lu(args, "as3name");
 
     if(scalinggrid && *scalinggrid) {
        SRECT r = parseBox(scalinggrid);
-       s_sprite(name, &r);
+       s_sprite(name, &r, as3name);
     } else {
-       s_sprite(name, 0);
+       s_sprite(name, 0, as3name);
     }
     return 0;
 }
 static int c_frame(map_t*args)
 {
-    char*framestr = lu(args, "n");
-    char*cutstr = lu(args, "cut");
+    const char*framestr = lu(args, "n");
+    const char*cutstr = lu(args, "cut");
 
-    char*name = lu(args, "name");
-    char*anchor = lu(args, "anchor");
+    const char*name = lu(args, "name");
+    const char*anchor = lu(args, "anchor");
     char buf[40];
 
     if(!strcmp(anchor, "anchor") && !*name)
@@ -3620,18 +3791,18 @@ static int c_frame(map_t*args)
 }
 static int c_primitive(map_t*args)
 {
-    char*name = lu(args, "name");
-    char*command = lu(args, "commandname");
+    const char*name = lu(args, "name");
+    const char*command = lu(args, "commandname");
     int width=0, height=0, r=0;
     int linewidth = parseTwip(lu(args, "line"));
-    char*colorstr = lu(args, "color");
+    const char*colorstr = lu(args, "color");
     RGBA color = parseColor(colorstr);
-    char*fillstr = lu(args, "fill");
+    const char*fillstr = lu(args, "fill");
     int dofill = 1;
     int type=0;
-    char* font;
-    char* text;
-    char* outline=0;
+    const char* font;
+    const char* text;
+    const char* outline=0;
     RGBA fill;
     if(!strcmp(command, "circle"))
        type = 1;
@@ -3641,9 +3812,9 @@ static int c_primitive(map_t*args)
     if(type==0) {
        width = parseTwip(lu(args, "width"));
        height = parseTwip(lu(args, "height"));
-    } else if (type==1) {
+    } else if(type==1) {
        r = parseTwip(lu(args, "r"));
-    } else if (type==2) {
+    } else if(type==2) {
        outline = lu(args, "outline");
     }
 
@@ -3662,9 +3833,9 @@ static int c_primitive(map_t*args)
 
 static int c_textshape(map_t*args)
 {
-    char*name = lu(args, "name");
-    char*text = lu(args, "text");
-    char*font = lu(args, "font");
+    const char*name = lu(args, "name");
+    const char*text = lu(args, "text");
+    const char*font = lu(args, "font");
     float size = parsePxOrPercent(font, lu(args, "size"));
 
     s_textshape(name, font, size, text);
@@ -3673,9 +3844,9 @@ static int c_textshape(map_t*args)
 
 static int c_swf(map_t*args)
 {
-    char*name = lu(args, "name");
-    char*filename = lu(args, "filename");
-    char*command = lu(args, "commandname");
+    const char*name = lu(args, "name");
+    const char*filename = lu(args, "filename");
+    const char*command = lu(args, "commandname");
     if(!strcmp(command, "shape"))
        warning("Please use .swf instead of .shape");
     s_includeswf(name, filename);
@@ -3684,25 +3855,25 @@ static int c_swf(map_t*args)
 
 static int c_font(map_t*args)
 {
-    char*name = lu(args, "name");
-    char*filename = lu(args, "filename");
+    const char*name = lu(args, "name");
+    const char*filename = lu(args, "filename");
     s_font(name, filename);
     return 0;
 }
 
 static int c_sound(map_t*args)
 {
-    char*name = lu(args, "name");
-    char*filename = lu(args, "filename");
+    const char*name = lu(args, "name");
+    const char*filename = lu(args, "filename");
     s_sound(name, filename);
     return 0;
 }
 
 static int c_text(map_t*args)
 {
-    char*name = lu(args, "name");
-    char*text = lu(args, "text");
-    char*font = lu(args, "font");
+    const char*name = lu(args, "name");
+    const char*text = lu(args, "text");
+    const char*font = lu(args, "font");
     float size = parsePxOrPercent(font, lu(args, "size"));
     RGBA color = parseColor(lu(args, "color"));
     s_text(name, font, text, (int)(size*100), color);
@@ -3716,17 +3887,26 @@ static int c_soundtrack(map_t*args)
 
 static int c_quicktime(map_t*args)
 {
-    char*name = lu(args, "name");
-    char*url = lu(args, "url");
+    const char*name = lu(args, "name");
+    const char*url = lu(args, "url");
     s_quicktime(name, url);
     return 0;
 }
 
+static int c_video(map_t*args)
+{
+    const char*name = lu(args, "name");
+    int width = parseInt(lu(args, "width"));
+    int height = parseInt(lu(args, "height"));
+    s_video(name, width, height);
+    return 0;
+}
+
 static int c_image(map_t*args)
 {
-    char*command = lu(args, "commandname");
-    char*name = lu(args, "name");
-    char*filename = lu(args, "filename");
+    const char*command = lu(args, "commandname");
+    const char*name = lu(args, "name");
+    const char*filename = lu(args, "filename");
     if(!strcmp(command,"jpeg")) {
        int quality = (int)(parsePercent(lu(args, "quality"))*100);
        s_image(name, "jpeg", filename, quality);
@@ -3738,8 +3918,8 @@ static int c_image(map_t*args)
 
 static int c_outline(map_t*args)
 {
-    char*name = lu(args, "name");
-    char*format = lu(args, "format");
+    const char*name = lu(args, "name");
+    const char*format = lu(args, "format");
 
     readToken();
     if(type != RAWDATA)
@@ -3751,22 +3931,23 @@ static int c_outline(map_t*args)
 
 int fakechar(map_t*args)
 {
-    char*name = lu(args, "name");
+    const char*name = lu(args, "name");
     s_box(name, 0, 0, black, 20, 0);
     return 0;
 }
 
 static int c_egon(map_t*args) {return fakechar(args);}
 static int c_button(map_t*args) {
-    char*name = lu(args, "name");
-    s_button(name);
+    const char*name = lu(args, "name");
+    const char*as3name = lu(args, "as3name");
+    s_button(name, as3name);
     return 0;
 }
 static int current_button_flags = 0;
 static int c_on_press(map_t*args)
 {
-    char*position = lu(args, "position");
-    char*action = "";
+    const char*position = lu(args, "position");
+    const char*action = "";
     if(!strcmp(position, "inside")) {
        current_button_flags |= BC_OVERUP_OVERDOWN;
     } else if(!strcmp(position, "outside")) {
@@ -3787,8 +3968,8 @@ static int c_on_press(map_t*args)
 }
 static int c_on_release(map_t*args)
 {
-    char*position = lu(args, "position");
-    char*action = "";
+    const char*position = lu(args, "position");
+    const char*action = "";
     if(!strcmp(position, "inside")) {
        current_button_flags |= BC_OVERDOWN_OVERUP;
     } else if(!strcmp(position, "outside")) {
@@ -3808,8 +3989,8 @@ static int c_on_release(map_t*args)
 }
 static int c_on_move_in(map_t*args)
 {
-    char*position = lu(args, "state");
-    char*action = "";
+    const char*position = lu(args, "state");
+    const char*action = "";
     if(!strcmp(position, "pressed")) {
        current_button_flags |= BC_OUTDOWN_OVERDOWN;
     } else if(!strcmp(position, "not_pressed")) {
@@ -3829,8 +4010,8 @@ static int c_on_move_in(map_t*args)
 }
 static int c_on_move_out(map_t*args)
 {
-    char*position = lu(args, "state");
-    char*action = "";
+    const char*position = lu(args, "state");
+    const char*action = "";
     if(!strcmp(position, "pressed")) {
        current_button_flags |= BC_OVERDOWN_OUTDOWN;
     } else if(!strcmp(position, "not_pressed")) {
@@ -3850,8 +4031,8 @@ static int c_on_move_out(map_t*args)
 }
 static int c_on_key(map_t*args)
 {
-    char*key = lu(args, "key");
-    char*action = "";
+    const char*key = lu(args, "key");
+    const char*action = "";
     if(strlen(key)==1) {
        /* ascii */
        if(key[0]>=32) {
@@ -3882,24 +4063,24 @@ static int c_on_key(map_t*args)
 static int c_edittext(map_t*args)
 {
  //"name font size width height text="" color=black maxlength=0 variable="" @password=0 @wordwrap=0 @multiline=0 @html=0 @noselect=0 @readonly=0 @autosize=0"},
-    char*name = lu(args, "name");
-    char*font = lu(args, "font");
+    const char*name = lu(args, "name");
+    const char*font = lu(args, "font");
     int size = (int)(1024*parsePxOrPercent(font, lu(args, "size")));
     int width = parseTwip(lu(args, "width"));
     int height = parseTwip(lu(args, "height"));
-    char*text  = lu(args, "text");
+    const char*text  = lu(args, "text");
     RGBA color = parseColor(lu(args, "color"));
     int maxlength = parseInt(lu(args, "maxlength"));
-    char*variable = lu(args, "variable");
-    char*passwordstr = lu(args, "password");
-    char*wordwrapstr = lu(args, "wordwrap");
-    char*multilinestr = lu(args, "multiline");
-    char*htmlstr = lu(args, "html");
-    char*noselectstr = lu(args, "noselect");
-    char*readonlystr = lu(args, "readonly");
-    char*borderstr = lu(args, "border");
-    char*autosizestr = lu(args, "autosize");
-    char*alignstr = lu(args, "align");
+    const char*variable = lu(args, "variable");
+    const char*passwordstr = lu(args, "password");
+    const char*wordwrapstr = lu(args, "wordwrap");
+    const char*multilinestr = lu(args, "multiline");
+    const char*htmlstr = lu(args, "html");
+    const char*noselectstr = lu(args, "noselect");
+    const char*readonlystr = lu(args, "readonly");
+    const char*borderstr = lu(args, "border");
+    const char*autosizestr = lu(args, "autosize");
+    const char*alignstr = lu(args, "align");
     int align = -1;
 
     int flags = 0;
@@ -3924,7 +4105,7 @@ static int c_edittext(map_t*args)
 static int c_morphshape(map_t*args) {return fakechar(args);}
 static int c_movie(map_t*args) {return fakechar(args);}
 
-static char* readfile(const char*filename)
+static char* readfile(char*filename)
 {
     FILE*fi = fopen(filename, "rb");
     int l;
@@ -3943,7 +4124,7 @@ static char* readfile(const char*filename)
 
 static int c_action(map_t*args)
 {
-    char* filename  = map_lookup(args, "filename");
+    const char* filename  = map_lookup(args, "filename");
     if(!filename ||!*filename) {
        readToken();
        if(type != RAWDATA) {
@@ -3951,7 +4132,7 @@ static int c_action(map_t*args)
        }
        s_action(text);
     } else {
-       s_action(readfile(filename));
+       s_action(readfile((char*)filename));
     }
 
     return 0;
@@ -3959,8 +4140,8 @@ static int c_action(map_t*args)
 
 static int c_initaction(map_t*args)
 {
-    char* character = lu(args, "name");
-    char* filename  = map_lookup(args, "filename");
+    const char* character = lu(args, "name");
+    const char* filename  = map_lookup(args, "filename");
     if(!filename ||!*filename) {
        readToken();
        if(type != RAWDATA) {
@@ -3968,7 +4149,7 @@ static int c_initaction(map_t*args)
        }
        s_initaction(character, text);
     } else {
-       s_initaction(character, readfile(filename));
+       s_initaction(character, readfile((char*)filename));
     }
 
     return 0;
@@ -3979,7 +4160,7 @@ static struct {
     command_func_t* func;
     char*arguments;
 } arguments[] =
-{{"flash", c_flash, "bbox=autocrop background=black version=6 fps=50 name= filename= @compress=default @change-sets-all=no @export=1"},
+{{"flash", c_flash, "bbox=autocrop background=black version=6 fps=50 name= filename= @compress=default @change-sets-all=no @export=1 @mainclass="},
  {"frame", c_frame, "n=<plus>1 name= @cut=no @anchor=no"},
  // "import" type stuff
  {"swf", c_swf, "name filename"},
@@ -3988,9 +4169,10 @@ static struct {
  {"png", c_image, "name filename"},
  {"movie", c_movie, "name filename"},
  {"sound", c_sound, "name filename"},
- {"font", c_font, "name filename glyphs="},
+ {"font", c_font, "name filename glyphs= @flashtype="},
  {"soundtrack", c_soundtrack, "filename"},
  {"quicktime", c_quicktime, "url"},
+ {"video", c_video, "name width= height="},
 
     // generators of primitives
 
@@ -4016,7 +4198,7 @@ static struct {
  {"text", c_text, "name text font size=100% color=white"},
  {"edittext", c_edittext, "name font= size=100% width height text="" color=white maxlength=0 variable="" @password=0 @wordwrap=0 @multiline=0 @html=0 @noselect=0 @readonly=0 @border=0 @autosize=0 align="},
  {"morphshape", c_morphshape, "name start end"},
- {"button", c_button, "name"},
+ {"button", c_button, "name as3name="},
     {"show", c_show,             "name x=0 y=0 red=+0 green=+0 blue=+0 alpha=+0 luminance= scale= scalex= scaley= blend= filter= pivot= pin= shear= rotate= ratio= above= below= as="},
     {"on_press", c_on_press, "position=inside"},
     {"on_release", c_on_release, "position=anywhere"},
@@ -4048,7 +4230,7 @@ static struct {
 
     // commands which start a block
 //startclip (see above)
- {"sprite", c_sprite, "name scalinggrid="},
+ {"sprite", c_sprite, "name scalinggrid= as3name="},
  {"action", c_action, "filename="},
  {"initaction", c_initaction, "name filename="},
 
@@ -4247,34 +4429,30 @@ static void parseArgumentsForCommand(char*command)
     if(nr<0)
        syntaxerror("command %s not known", command);
 
+#ifndef EMPTY
     // catch missing .flash directives at the beginning of a file
     if(strcmp(command, "flash") && !stackpos)
     {
-       syntaxerror("No movie defined- use .flash first");
+        syntaxerror("No movie defined- use .flash first");
     }
+#endif
 
 #ifdef DEBUG
     printf(".%s\n", command);fflush(stdout);
     map_dump(&args, stdout, "\t");fflush(stdout);
 #endif
 
+#ifndef EMPTY
     (*arguments[nr].func)(&args);
-
-    /*if(!strcmp(command, "button") ||
-       !strcmp(command, "action")) {
-       while(1) {
-           readToken();
-           if(type == COMMAND) {
-               if(!strcmp(text, "end"))
-                   break;
-               else {
-                   pushBack();
-                   break;
-               }
-           }
+#else
+    if(!strcmp(command, "action")  || !strcmp(command, "initaction") ||
+       !strcmp(command, "outline") || !strcmp(command, "gradient")) {
+       readToken();
+       if(type != RAWDATA) {
+           syntaxerror("colon (:) expected");
        }
-    }*/
-
+    }
+#endif
     map_clear(&args);
     return;
 }
@@ -4287,7 +4465,6 @@ static void analyseArgumentsForCommand(char*command)
 {
     int t;
     map_t args;
-    char* fontfile;
     int nr = -1;
     U8* glyphs_to_include;
     msg("<verbose> analyse Command: %s (line %d)", command, line);
@@ -4305,57 +4482,27 @@ static void analyseArgumentsForCommand(char*command)
     printf(".%s\n", command);fflush(stdout);
     map_dump(&args, stdout, "\t");fflush(stdout);
 #endif
-    char* name = lu(&args, "name");
-    if (!strcmp(command, "font"))
+    const char* name = lu(&args, "name");
+    if(!strcmp(command, "font"))
     {
-       if(dictionary_lookup(&fonts, name))
-            syntaxerror("font %s defined twice", name);
-
-       SWFFONT* font;
-       fontfile = lu(&args, "filename");
-       font = swf_LoadFont(fontfile);
-       if(font == 0) {
-           warning("Couldn't open font file \"%s\"", fontfile);
-           font = (SWFFONT*)malloc(sizeof(SWFFONT));
-           memset(font, 0, sizeof(SWFFONT));
-       }
-       else
-       {
-           swf_FontPrepareForEditText(font);
-           glyphs_to_include = lu(&args, "glyphs");
-           if (!strcmp(glyphs_to_include, "all"))
-           {
-               swf_FontUseAll(font);
-               font->use->glyphs_specified = 1;
-           }
-           else
-           {
-               if (strcmp (glyphs_to_include, ""))
-               {
-                   swf_FontUseUTF8(font, glyphs_to_include);
-                   font->use->glyphs_specified = 1;
-               }
-               else
-                   swf_FontInitUsage(font);
-           }
-       }
-       dictionary_put2(&fonts, name, font);
-    }
-    else
-    {
-        SWFFONT* font = dictionary_lookup(&fonts, lu(&args, "font"));
-        if (!font)
-            syntaxerror("font %s is not known in line %d", lu(&args, "font"), line);
-        else
-            if (font->use && !font->use->glyphs_specified)
-            {
-               if (!strcmp(command, "edittext"))
+       const char* fontfile = lu(&args, "filename");
+       const char* glyphs = lu(&args, "glyphs");
+       const char* flashtype = lu(&args, "flashtype");
+       s_createfont(name, fontfile, glyphs, flashtype[0]);
+    } else {
+        SWFFONT* font = dict_lookup(&fonts, lu(&args, "font"));
+        if(!font) {
+           //that's ok... it might be an edittext with a system font
+            //syntaxerror("font %s is not known in line %d", lu(&args, "font"), line);
+       } else
+            if(font->use && !font->use->glyphs_specified) {
+               if(!strcmp(command, "edittext"))
                {
                    swf_FontUseAll(font);
                    font->use->glyphs_specified = 1;
                }
                else
-                   swf_FontUseUTF8(font, lu(&args, "text"));
+                   swf_FontUseUTF8(font, (U8*)lu(&args, "text"), 0xffff);
             }
     }
     map_clear(&args);
@@ -4378,7 +4525,7 @@ void findFontUsage()
         readToken();
         if(type != COMMAND)
             syntaxerror("command expected");
-        if (strstr(fontRelated, text))
+        if(strstr(fontRelated, text))
             analyseArgumentsForCommand(text);
         else
             if(strcmp(text, "end"))
@@ -4390,7 +4537,7 @@ void firstPass()
 {
     pos = 0;
     id = 0;
-    dictionary_init(&fonts);
+    dict_init(&fonts, 16);
     cleanUp = &freeFontDictionary;
     findFontUsage();
 }