applied as3name patch from Ricardo Pedroso
[swftools.git] / src / swfc.c
index 3273d65..c8827c1 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,11 +178,13 @@ 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;
    dict_t oldinstances;
@@ -340,22 +343,22 @@ static void free_outline(void* o)
 
 static void freeDictionaries()
 {
-    dict_free_all(&instances, free_instance);
-    dict_free_all(&characters, free);
-    dict_free_all(&images, free);
-    dict_free_all(&textures, free);
-    dict_free_all(&outlines, free_outline);
-    dict_free_all(&gradients, free_gradient);
-    dict_free_all(&filters, free);
-    dict_free_all(&fonts, free_font);
-    dict_free_all(&sounds, free);
-    dict_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()
 {
-    dict_free_all(&fonts, free_font);
+    dict_free_all(&fonts, 1, free_font);
 }
 
 static void incrementid()
@@ -609,15 +612,15 @@ void s_swf(const char*name, SRECT r, int version, int fps, int compress, RGBA ba
     swf->compressed = compress;
     swf_SetRGB(tag,&background);
 
-    dict_init(&characters);
-    dict_init(&images);
-    dict_init(&textures);
-    dict_init(&outlines);
-    dict_init(&gradients);
-    dict_init(&filters);
-    dict_init(&instances);
-    dict_init(&sounds);
-    dict_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;
 
@@ -638,7 +641,7 @@ void s_swf(const char*name, SRECT r, int version, int fps, int compress, RGBA ba
     incrementid();
 }
 
-void s_sprite(const 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
@@ -653,6 +656,7 @@ void s_sprite(const 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 {
@@ -660,7 +664,7 @@ void s_sprite(const char*name, SRECT*scalegrid)
     }
 
     /* FIXME: those four fields should be bundled together */
-    dict_init(&instances);
+    dict_init(&instances, 16);
     currentframe = 0;
     currentdepth = 1;
     memset(&currentrect, 0, sizeof(currentrect));
@@ -686,7 +690,7 @@ typedef struct _button
 
 static button_t mybutton;
 
-void s_button(const char*name)
+void s_button(const char*name, const char*as3name)
 {
     tag = swf_InsertTag(tag, ST_DEFINEBUTTON2);
     swf_SetU16(tag, id); //id
@@ -699,6 +703,7 @@ void s_button(const 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));
 
@@ -815,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);
 }
 
@@ -993,7 +1006,7 @@ static void s_endSprite()
         syntaxerror("internal error(7)");
     /* TODO: before clearing, prepend "<spritename>." to names and
              copy into old instances dict */
-    dict_free_all(&instances, free_instance);
+    dict_free_all(&instances, 1, free_instance);
 
     currentframe = stack[stackpos].oldframe;
     currentrect = stack[stackpos].oldrect;
@@ -1001,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);
 }
 
@@ -1009,6 +1031,7 @@ static void s_endSWF()
     int fi;
     SWF* swf;
     char*filename;
+    char*mc="";
 
     dict_foreach_value(&instances, writeInstance);
 
@@ -1029,6 +1052,26 @@ static void s_endSWF()
     //    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);
@@ -1364,6 +1407,24 @@ void s_quicktime(const char*name, const char*url)
     incrementid();
 }
 
+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;
@@ -1864,19 +1925,20 @@ void s_blur(const char*name, double blurx, double blury, int passes)
 
 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)
@@ -2696,7 +2758,7 @@ float parsePercent(const char*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;
@@ -2770,6 +2832,7 @@ 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;
@@ -3116,7 +3179,7 @@ static int c_define(map_t*args)
     const char*value = lu(args, "value");
     
     if(!defines_initialized) {
-       dict_init(&defines);
+       dict_init(&defines, 16);
        mem_init(&define_values);
        defines_initialized = 1;
     }
@@ -3131,7 +3194,7 @@ static int c_point(map_t*args)
     int pos;
     SPOINT p;
     if(!points_initialized) {
-       dict_init(&points);
+       dict_init(&points, 16);
        mem_init(&mpoints);
        points_initialized = 1;
     }
@@ -3660,12 +3723,13 @@ static int c_sprite(map_t*args)
 {
     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;
 }
@@ -3804,6 +3868,15 @@ static int c_quicktime(map_t*args)
     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)
 {
     const char*command = lu(args, "commandname");
@@ -3841,7 +3914,8 @@ int fakechar(map_t*args)
 static int c_egon(map_t*args) {return fakechar(args);}
 static int c_button(map_t*args) {
     const char*name = lu(args, "name");
-    s_button(name);
+    const char*as3name = lu(args, "as3name");
+    s_button(name, as3name);
     return 0;
 }
 static int current_button_flags = 0;
@@ -4061,7 +4135,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"},
@@ -4073,6 +4147,7 @@ static struct {
  {"font", c_font, "name filename glyphs="},
  {"soundtrack", c_soundtrack, "filename"},
  {"quicktime", c_quicktime, "url"},
+ {"video", c_video, "name width= height="},
 
     // generators of primitives
 
@@ -4098,7 +4173,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"},
@@ -4130,7 +4205,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="},
 
@@ -4410,7 +4485,7 @@ static void analyseArgumentsForCommand(char*command)
            {
                if (strcmp (glyphs_to_include, ""))
                {
-                   swf_FontUseUTF8(font, glyphs_to_include);
+                   swf_FontUseUTF8(font, glyphs_to_include, /*FIXME*/0xffff);
                    font->use->glyphs_specified = 1;
                }
                else
@@ -4434,7 +4509,7 @@ static void analyseArgumentsForCommand(char*command)
                    font->use->glyphs_specified = 1;
                }
                else
-                   swf_FontUseUTF8(font, (U8*)lu(&args, "text"));
+                   swf_FontUseUTF8(font, (U8*)lu(&args, "text"), 0xffff);
             }
     }
     map_clear(&args);
@@ -4469,7 +4544,7 @@ void firstPass()
 {
     pos = 0;
     id = 0;
-    dict_init(&fonts);
+    dict_init(&fonts, 16);
     cleanUp = &freeFontDictionary;
     findFontUsage();
 }