added gfx2gfx to Makefile, small fix in as3compile
[swftools.git] / src / swfc.c
index 0a1bf11..26e46cd 100644 (file)
@@ -177,6 +177,7 @@ static struct level
    /* for swf (0): */
    SWF*swf;
    char*filename;
+   char as3;
 
    /* for sprites (1): */
    TAG*tag;
@@ -340,22 +341,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()
@@ -377,7 +378,7 @@ static void s_addcharacter(const char*name, U16 id, TAG*ctag, SRECT r)
     c->definingTag = ctag;
     c->id = id;
     c->size = r;
-    dict_put2(&characters, name, c);
+    dict_put(&characters, name, c);
 
     if(do_exports) {
        tag = swf_InsertTag(tag, ST_NAMECHARACTER);
@@ -398,7 +399,7 @@ static void s_addimage(const char*name, U16 id, TAG*ctag, SRECT r)
     c->definingTag = ctag;
     c->id = id;
     c->size = r;
-    dict_put2(&images, name, c);
+    dict_put(&images, name, c);
 }
 static instance_t* s_addinstance(const char*name, character_t*c, U16 depth)
 {
@@ -408,7 +409,7 @@ static instance_t* s_addinstance(const char*name, character_t*c, U16 depth)
     i->character = c;
     i->depth = depth;
     //swf_GetMatrix(0, &i->matrix);
-    dict_put2(&instances, name, i);
+    dict_put(&instances, name, i);
     return i;
 }
 
@@ -471,89 +472,89 @@ void initBuiltIns()
     interpolation_t* new;
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_LINEAR;
-    dict_put2(&interpolations, "linear", new);
+    dict_put(&interpolations, "linear", new);
 
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_QUAD_IN;
     new->slope = 0;
-    dict_put2(&interpolations, "quadIn", new);
+    dict_put(&interpolations, "quadIn", new);
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_QUAD_OUT;
     new->slope = 0;
-    dict_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;
-    dict_put2(&interpolations, "quadInOut", new);
+    dict_put(&interpolations, "quadInOut", new);
 
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_CUBIC_IN;
     new->slope = 0;
-    dict_put2(&interpolations, "cubicIn", new);
+    dict_put(&interpolations, "cubicIn", new);
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_CUBIC_OUT;
     new->slope = 0;
-    dict_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;
-    dict_put2(&interpolations, "cubicInOut", new);
+    dict_put(&interpolations, "cubicInOut", new);
 
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_QUART_IN;
     new->slope = 0;
-    dict_put2(&interpolations, "quartIn", new);
+    dict_put(&interpolations, "quartIn", new);
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_QUART_OUT;
     new->slope = 0;
-    dict_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;
-    dict_put2(&interpolations, "quartInOut", new);
+    dict_put(&interpolations, "quartInOut", new);
 
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_QUINT_IN;
     new->slope = 0;
-    dict_put2(&interpolations, "quintIn", new);
+    dict_put(&interpolations, "quintIn", new);
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_QUINT_OUT;
     new->slope = 0;
-    dict_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;
-    dict_put2(&interpolations, "quintInOut", new);
+    dict_put(&interpolations, "quintInOut", new);
 
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_CIRCLE_IN;
-    dict_put2(&interpolations, "circleIn", new);
+    dict_put(&interpolations, "circleIn", new);
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_CIRCLE_OUT;
-    dict_put2(&interpolations, "circleOut", new);
+    dict_put(&interpolations, "circleOut", new);
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_CIRCLE_IN_OUT;
-    dict_put2(&interpolations, "circleInOut", new);
+    dict_put(&interpolations, "circleInOut", new);
 
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_EXPONENTIAL_IN;
-    dict_put2(&interpolations, "exponentialIn", new);
+    dict_put(&interpolations, "exponentialIn", new);
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_EXPONENTIAL_OUT;
-    dict_put2(&interpolations, "exponentialOut", new);
+    dict_put(&interpolations, "exponentialOut", new);
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_EXPONENTIAL_IN_OUT;
-    dict_put2(&interpolations, "exponentialInOut", new);
+    dict_put(&interpolations, "exponentialInOut", new);
 
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_SINE_IN;
-    dict_put2(&interpolations, "sineIn", new);
+    dict_put(&interpolations, "sineIn", new);
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_SINE_OUT;
-    dict_put2(&interpolations, "sineOut", new);
+    dict_put(&interpolations, "sineOut", new);
     new = (interpolation_t*)malloc(sizeof(interpolation_t));
     new->function = IF_SINE_IN_OUT;
-    dict_put2(&interpolations, "sineInOut", new);
+    dict_put(&interpolations, "sineInOut", new);
 
     RGBA c;
     memset(&c, 0, sizeof(RGBA));
@@ -567,29 +568,29 @@ void initBuiltIns()
     noGradient->gradient.ratios[1] = 255;
     noGradient->radial = 0;
     noGradient->rotate = 0;
-    dict_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));
-    dict_put2(&filters, "no_filters", dummy);
+    dict_put(&filters, "no_filters", dummy);
     noBlur = (FILTER_BLUR*) swf_NewFilter(FILTERTYPE_BLUR);
     noBlur->passes = 1;
-    dict_put2(&filters, "no_blur", noBlur);
+    dict_put(&filters, "no_blur", noBlur);
     noBevel = (FILTER_BEVEL*) swf_NewFilter(FILTERTYPE_BEVEL);
     noBevel->passes = 1;
     noBevel->composite = 1;
-    dict_put2(&filters, "no_bevel", noBevel);
+    dict_put(&filters, "no_bevel", noBevel);
     noDropshadow = (FILTER_DROPSHADOW*) swf_NewFilter(FILTERTYPE_DROPSHADOW);
     noDropshadow->passes = 1;
     noDropshadow->composite = 1;
-    dict_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;
-    dict_put2(&filters, "no_gradientglow", noGradientGlow);
+    dict_put(&filters, "no_gradientglow", noGradientGlow);
 }
 
 void s_swf(const char*name, SRECT r, int version, int fps, int compress, RGBA background)
@@ -609,15 +610,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;
 
@@ -633,6 +634,8 @@ void s_swf(const char*name, SRECT r, int version, int fps, int compress, RGBA ba
     currentdepth = 1;
 
     memset(idmap, 0, sizeof(idmap));
+    idmap[0]=1; //main movie has ID 0
+
     incrementid();
 }
 
@@ -658,7 +661,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));
@@ -991,7 +994,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;
@@ -1027,6 +1030,22 @@ 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(as3_getglobalclass()) {
+            tag = swf_InsertTag(tag, ST_SYMBOLCLASS);
+            swf_SetU16(tag, 1);
+            swf_SetU16(tag, 0);
+            swf_SetString(tag, as3_getglobalclass());
+        } else {
+            warning("no global public MovieClip subclass");
+        }
+        as3_destroy();
+    }
+
     tag = swf_InsertTag(tag, ST_END);
 
     swf_OptimizeTagOrder(swf);
@@ -1314,7 +1333,7 @@ void s_textshape(const char*name, const char*fontname, float size, const char*_t
 
     if(dict_lookup(&outlines, name))
        syntaxerror("outline %s defined twice", name);
-    dict_put2(&outlines, name, outline);
+    dict_put(&outlines, name, outline);
 }
 
 void s_text(const char*name, const char*fontname, const char*text, int size, RGBA color)
@@ -1362,6 +1381,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;
@@ -1523,7 +1560,7 @@ void s_texture(const char*name, const char*object, int x, int y, float scalex, f
        fs->m.sy *= 20;
     }
 
-    dict_put2(&textures, name, texture);
+    dict_put(&textures, name, texture);
 }
 
 void s_font(const char*name, const char*filename)
@@ -1645,7 +1682,7 @@ void s_sound(const char*name, const char*filename)
     sound->tag = tag;
     sound->id = id;
 
-    dict_put2(&sounds, name, sound);
+    dict_put(&sounds, name, sound);
 
     incrementid();
 
@@ -1767,7 +1804,7 @@ void s_gradient(const char*name, const char*text, int radial, int rotate)
     gradient->radial = radial;
     gradient->rotate = rotate;
 
-    dict_put2(&gradients, name, gradient);
+    dict_put(&gradients, name, gradient);
 }
 
 void s_gradientglow(const char*name, const char*gradient, float blurx, float blury,
@@ -1797,7 +1834,7 @@ void s_gradientglow(const char*name, const char*gradient, float blurx, float blu
     filter->ontop = ontop;
     filter->passes = passes;
 
-    dict_put2(&filters, name, filter);
+    dict_put(&filters, name, filter);
 }
 
 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)
@@ -1819,7 +1856,7 @@ void s_dropshadow(const char*name, RGBA color, double blurx, double blury, doubl
     filter->composite = composite;
     filter->passes = passes;
 
-    dict_put2(&filters, name, filter);
+    dict_put(&filters, name, filter);
 }
 
 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)
@@ -1843,7 +1880,7 @@ void s_bevel(const char*name, RGBA shadow, RGBA highlight, double blurx, double
     filter->ontop = ontop;
     filter->passes = passes;
 
-    dict_put2(&filters, name, filter);
+    dict_put(&filters, name, filter);
 }
 
 void s_blur(const char*name, double blurx, double blury, int passes)
@@ -1857,24 +1894,25 @@ void s_blur(const char*name, double blurx, double blury, int passes)
     filter->blury = blury;
     filter->passes = passes;
 
-    dict_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)
@@ -1946,7 +1984,7 @@ void s_outline(const char*name, const char*format, const char*source)
     outline->shape = shape;
     outline->bbox = bounds;
 
-    dict_put2(&outlines, name, outline);
+    dict_put(&outlines, name, outline);
 }
 
 int s_playsound(const char*name, int loops, int nomultiple, int stop)
@@ -2694,7 +2732,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;
@@ -2825,7 +2863,7 @@ static int c_interpolation(map_t *args)
     inter->damping = parseFloat(lu(args, "damping"));
     inter->slope = parseFloat(lu(args, "slope"));
 
-    dict_put2(&interpolations, name, inter);
+    dict_put(&interpolations, name, inter);
     return 0;
 }
 
@@ -3114,33 +3152,29 @@ 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;
     }
     int val = parseTwip(value);
     int pos = mem_put(&define_values, &val, sizeof(val));
-    string_t s;
-    string_set(&s, name);
-    dict_put(&defines, s, (void*)(pos+1));
+    dict_put(&defines, name, (void*)(pos+1));
     return 0;
 }
 static int c_point(map_t*args)
 {
     const char*name = lu(args, "name");
     int pos;
-    string_t s1;
     SPOINT p;
     if(!points_initialized) {
-       dict_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);
-    dict_put(&points, s1, (void*)(pos+1));
+    dict_put(&points, name, (void*)(pos+1));
     return 0;
 }
 static int c_play(map_t*args)
@@ -3806,6 +3840,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");
@@ -4075,6 +4118,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
 
@@ -4419,14 +4463,15 @@ static void analyseArgumentsForCommand(char*command)
                    swf_FontInitUsage(font);
            }
        }
-       dict_put2(&fonts, name, font);
+       dict_put(&fonts, name, font);
     }
     else
     {
         SWFFONT* font = dict_lookup(&fonts, lu(&args, "font"));
-        if (!font)
-            syntaxerror("font %s is not known in line %d", lu(&args, "font"), line);
-        else
+        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"))
@@ -4470,7 +4515,7 @@ void firstPass()
 {
     pos = 0;
     id = 0;
-    dict_init(&fonts);
+    dict_init(&fonts, 16);
     cleanUp = &freeFontDictionary;
     findFontUsage();
 }