gcc 2.95.3 fixes.
[swftools.git] / src / swfc.c
index e51848f..9d9772a 100644 (file)
@@ -40,6 +40,7 @@
 static char * filename = 0;
 static char * outputname = "output.swf";
 static int verbose = 2;
+static int optimize = 0;
 static int override_outputname = 0;
 
 static struct options_t options[] = {
@@ -47,6 +48,7 @@ static struct options_t options[] = {
 {"V", "version"},
 {"v", "verbose"},
 {"o", "output"},
+{"O", "optimize"},
 {0,0}
 };
     
@@ -61,6 +63,10 @@ int args_callback_option(char*name,char*val)
        override_outputname = 1;
        return 1;
     }
+    else if(!strcmp(name, "O")) {
+       optimize = 1;
+       return 0;
+    }
     else if(!strcmp(name, "v")) {
        verbose ++;
        return 0;
@@ -383,7 +389,7 @@ void s_swf(char*name, SRECT r, int version, int fps, int compress, RGBA backgrou
     swf->firstTag = tag = swf_InsertTag(0, ST_SETBACKGROUNDCOLOR);
     swf->compressed = compress;
     swf_SetRGB(tag,&background);
-    
+
     if(stackpos==sizeof(stack)/sizeof(stack[0]))
        syntaxerror("too many levels of recursion");
     
@@ -612,6 +618,7 @@ static void s_endSprite()
     currentdepth = stack[stackpos].olddepth;
     instances = stack[stackpos].oldinstances;
 
+    tag = swf_InsertTag(tag, ST_SHOWFRAME);
     tag = swf_InsertTag(tag, ST_END);
 
     tag = stack[stackpos].tag;
@@ -633,18 +640,22 @@ static void s_endSWF()
        tag = removeFromTo(stack[stackpos].cut, tag);
 
     stackpos--;
-
+   
     swf = stack[stackpos].swf;
     filename = stack[stackpos].filename;
-   
-    //tag = swf_InsertTag(tag, ST_SHOWFRAME); //?
+  
+    //if(tag->prev && tag->prev->id != ST_SHOWFRAME)
+    //    tag = swf_InsertTag(tag, ST_SHOWFRAME);
+    tag = swf_InsertTag(tag, ST_SHOWFRAME);
 
     tag = swf_InsertTag(tag, ST_END);
 
     swf_OptimizeTagOrder(swf);
+   
+    if(optimize) {
+       swf_Optimize(swf);
+    }
     
-    swf_Optimize(swf);
-
     if(!(swf->movieSize.xmax-swf->movieSize.xmin) || !(swf->movieSize.ymax-swf->movieSize.ymin)) {
        swf->movieSize = currentrect; /* "autocrop" */
     }
@@ -652,8 +663,9 @@ static void s_endSWF()
     if(!(swf->movieSize.xmax-swf->movieSize.xmin) || !(swf->movieSize.ymax-swf->movieSize.ymin)) {
        swf->movieSize.xmax += 20; /* 1 by 1 pixels */
        swf->movieSize.ymax += 20;
+       warning("Empty bounding box for movie");
     }
-
+    
     fi = open(filename, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644);
     if(fi<0) {
        syntaxerror("couldn't create output file %s", filename);
@@ -692,7 +704,7 @@ void s_close()
 
 int s_getframe()
 {
-    return currentframe;
+    return currentframe+1;
 }
 
 void s_frame(int nr, int cut, char*name)
@@ -700,6 +712,10 @@ void s_frame(int nr, int cut, char*name)
     int t;
     TAG*now = tag;
 
+    if(nr<1) 
+       syntaxerror("Illegal frame number");
+    nr--; // internally, frame 1 is frame 0
+
     for(t=currentframe;t<nr;t++) {
        tag = swf_InsertTag(tag, ST_SHOWFRAME);
        if(t==nr-1 && name && *name) {
@@ -774,15 +790,15 @@ void s_box(char*name, int width, int height, RGBA color, int linewidth, char*tex
 {
     SRECT r,r2;
     SHAPE* s;
-    int ls1,fs1=0;
+    int ls1=0,fs1=0;
     r2.xmin = 0;
     r2.ymin = 0;
     r2.xmax = width;
     r2.ymax = height;
     tag = swf_InsertTag(tag, ST_DEFINESHAPE3);
     swf_ShapeNew(&s);
-    ls1 = swf_ShapeAddLineStyle(s,linewidth,&color);
-
+    if(linewidth)
+        ls1 = swf_ShapeAddLineStyle(s,linewidth>=20?linewidth-20:0,&color);
     if(texture)
        fs1 = addFillStyle(s, &r2, texture);
 
@@ -819,11 +835,11 @@ void s_filled(char*name, char*outlinename, RGBA color, int linewidth, char*textu
 
     tag = swf_InsertTag(tag, ST_DEFINESHAPE3);
     swf_ShapeNew(&s);
-    ls1 = swf_ShapeAddLineStyle(s,linewidth,&color);
+    if(linewidth)
+        ls1 = swf_ShapeAddLineStyle(s,linewidth>=20?linewidth-20:0,&color);
     if(texture)
        fs1 = addFillStyle(s, &r2, texture);
-    else 
-       syntaxerror("non filled outlines not yet supported- please supply a fill=<color/texture> argument");
+    
     swf_SetU16(tag,id);
     rect.xmin = r2.xmin-linewidth-linewidth/2;
     rect.ymin = r2.ymin-linewidth-linewidth/2;
@@ -832,8 +848,11 @@ void s_filled(char*name, char*outlinename, RGBA color, int linewidth, char*textu
 
     swf_SetRect(tag,&rect);
     swf_SetShapeStyles(tag, s);
-    swf_SetShapeBits(tag, outline->shape); //does not count bits!
-    swf_SetBlock(tag, outline->shape->data, (outline->shape->bitlen+7)/8);
+    swf_ShapeCountBits(s,0,0);
+    swf_RecodeShapeData(outline->shape->data, outline->shape->bitlen, 1,            1, 
+                        &s->data,             &s->bitlen,             s->bits.fill, s->bits.line);
+    swf_SetShapeBits(tag, s);
+    swf_SetBlock(tag, s->data, (s->bitlen+7)/8);
     swf_ShapeFree(s);
 
     s_addcharacter(name, id, tag, rect);
@@ -844,14 +863,15 @@ void s_circle(char*name, int r, RGBA color, int linewidth, char*texture)
 {
     SRECT rect,r2;
     SHAPE* s;
-    int ls1,fs1=0;
+    int ls1=0,fs1=0;
     r2.xmin = r2.ymin = 0;
     r2.xmax = 2*r;
     r2.ymax = 2*r;
 
     tag = swf_InsertTag(tag, ST_DEFINESHAPE3);
     swf_ShapeNew(&s);
-    ls1 = swf_ShapeAddLineStyle(s,linewidth,&color);
+    if(linewidth)
+        ls1 = swf_ShapeAddLineStyle(s,linewidth>=20?linewidth-20:0,&color);
     if(texture)
        fs1 = addFillStyle(s, &r2, texture);
     swf_SetU16(tag,id);
@@ -947,13 +967,16 @@ void s_quicktime(char*name, char*url)
 
 void s_edittext(char*name, char*fontname, int size, int width, int height, char*text, RGBA*color, int maxlength, char*variable, int flags)
 {
-    SWFFONT*font;
+    SWFFONT*font = 0;
     EditTextLayout layout;
     SRECT r;
 
-    font = dictionary_lookup(&fonts, fontname);
-    if(!font)
-       syntaxerror("font \"%s\" not known!", fontname);
+    if(fontname && *fontname) {
+       flags |= ET_USEOUTLINES;
+       font = dictionary_lookup(&fonts, fontname);
+       if(!font)
+           syntaxerror("font \"%s\" not known!", fontname);
+    }
     tag = swf_InsertTag(tag, ST_DEFINEEDITTEXT);
     swf_SetU16(tag, id);
     layout.align = 0;
@@ -965,7 +988,8 @@ void s_edittext(char*name, char*fontname, int size, int width, int height, char*
     r.ymin = 0;
     r.xmax = width;
     r.ymax = height;
-    swf_SetEditText(tag, flags|ET_USEOUTLINES, r, text, color, maxlength, font->id, size, &layout, variable);
+    
+    swf_SetEditText(tag, flags, r, text, color, maxlength, font?font->id:0, size, &layout, variable);
 
     s_addcharacter(name, id, tag, r);
     incrementid();
@@ -1082,6 +1106,7 @@ void s_sound(char*name, char*filename)
     sound_t* sound;
     U16*samples;
     int numsamples;
+    int t;
 
     if(!readWAV(filename, &wav)) {
        warning("Couldn't read wav file \"%s\"", filename);
@@ -1092,6 +1117,12 @@ void s_sound(char*name, char*filename)
        samples = (U16*)wav2.data;
        numsamples = wav2.size/2;
        free(wav.data);
+#ifdef WORDS_BIGENDIAN
+       /* swap bytes */
+       for(t=0;t<numsamples;t++) {
+           samples[t] = (samples[t]>>8)&0xff | (samples[t]<<8)&0xff00;
+       }
+#endif
     }
 
     tag = swf_InsertTag(tag, ST_DEFINESOUND);
@@ -1193,8 +1224,11 @@ void s_action(const char*text)
 int s_swf3action(char*name, char*action)
 {
     ActionTAG* a = 0;
-    instance_t* object = dictionary_lookup(&instances, name);
-    if(!object) {
+    instance_t* object = 0;
+    if(name) 
+       dictionary_lookup(&instances, name);
+    if(!object && name && *name) {
+       /* we have a name, but couldn't find it. Abort. */
        return 0;
     }
     a = action_SetTarget(0, name);
@@ -1224,14 +1258,10 @@ void s_outline(char*name, char*format, char*source)
     draw_string(&draw, source);
     draw.finish(&draw);
     shape = swf_ShapeDrawerToShape(&draw);
-    //shape2 = swf_ShapeToShape2(shape);
-    //bounds = swf_GetShapeBoundingBox(shape2);
-    //swf_Shape2Free(shape2);
     bounds = swf_ShapeDrawerGetBBox(&draw);
     draw.dealloc(&draw);
     
-    outline = (outline_t*)malloc(sizeof(outline_t));
-    memset(outline, 0, sizeof(outline_t));
+    outline = (outline_t*)rfx_calloc(sizeof(outline_t));
     outline->shape = shape;
     outline->bbox = bounds;
     
@@ -1242,8 +1272,11 @@ void s_outline(char*name, char*format, char*source)
 
 int s_playsound(char*name, int loops, int nomultiple, int stop)
 {
-    sound_t* sound = dictionary_lookup(&sounds, name);
+    sound_t* sound;
     SOUNDINFO info;
+    if(!name)
+       return 0;
+    sound = dictionary_lookup(&sounds, name);
     if(!sound)
        return 0;
 
@@ -1288,7 +1321,7 @@ void s_includeswf(char*name, char*filename)
     
     s = tag = swf_InsertTag(tag, ST_DEFINESPRITE);
     swf_SetU16(tag, id);
-    swf_SetU16(tag, 0);
+    swf_SetU16(tag, swf.frameCount);
 
     swf_Relocate(&swf, idmap);
 
@@ -1617,8 +1650,8 @@ int parseTwip(char*str)
            if(*s<'0' || *s>'9')
                syntaxerror("Not a coordinate: \"%s\"", str);
        }
-       if(l>2 || (l==2 && (dot[1]!='0' || dot[1]!='5'))) {
-           warning("precision loss: %s converted to twip", str);
+       if(l>2 || (l==2 && (dot[1]!='0' && dot[1]!='5'))) {
+           warning("precision loss: %s converted to twip: %s", str, dot);
            dot[2] = 0;
            l=2;
        }
@@ -1794,15 +1827,27 @@ static char* lu(map_t* args, char*name)
 
 static int c_flash(map_t*args) 
 {
-    char* name = lu(args, "name");
+    char* filename = map_lookup(args, "filename");
     char* compressstr = lu(args, "compress");
     SRECT bbox = parseBox(lu(args, "bbox"));
     int version = parseInt(lu(args, "version"));
     int fps = (int)(parseFloat(lu(args, "fps"))*256);
     int compress = 0;
     RGBA color = parseColor(lu(args, "background"));
-    if(!strcmp(name, "!default!") || override_outputname)
-       name = outputname;
+
+    if(!filename || !*filename) {
+       /* for compatibility */
+       filename = map_lookup(args, "name");
+       if(!filename || !*filename) {
+           filename = 0;
+       } else {
+           //msg("<warning> line %d: .flash name=... is deprecated, use .flash filename=...", line);
+           msg("<notice> line %d: .flash name=... is deprecated, use .flash filename=...", line);
+       }
+    }
+
+    if(!filename || override_outputname)
+       filename = outputname;
     
     if(!strcmp(compressstr, "default"))
        compress = version==6;
@@ -1812,7 +1857,7 @@ static int c_flash(map_t*args)
        compress = 0;
     else syntaxerror("value \"%s\" not supported for the compress argument", compressstr);
 
-    s_swf(name, bbox, version, fps, compress, color);
+    s_swf(filename, bbox, version, fps, compress, color);
     return 0;
 }
 int isRelative(char*str)
@@ -1913,7 +1958,7 @@ static int c_play(map_t*args)
 
 static int c_stop(map_t*args) 
 {
-    char*name = lu(args, "name");
+    char*name = map_lookup(args, "name");
 
     if(s_playsound(name, 0,0,1)) {
        return 0;
@@ -2209,7 +2254,7 @@ static int c_frame(map_t*args)
     else {
        frame = parseInt(framestr);
        if(s_getframe() >= frame
-               && !(frame==0 && s_getframe()==frame)) // equality is o.k. for frame 0
+               && !(frame==1 && s_getframe()==frame)) // equality is o.k. for frame 0
            syntaxerror("frame expression must be >%d (is:%s)", s_getframe(), framestr);
     }
     s_frame(frame, cut, name);
@@ -2516,12 +2561,29 @@ static int c_texture(map_t*args) {return 0;}
 
 static int c_action(map_t*args) 
 {
-    readToken();
-    if(type != RAWDATA) {
-       syntaxerror("colon (:) expected");
+    char* filename  = map_lookup(args, "filename");
+    if(!filename ||!*filename) {
+       readToken();
+       if(type != RAWDATA) {
+           syntaxerror("colon (:) expected");
+       }
+       s_action(text);
+    } else {
+       FILE*fi = fopen(filename, "rb");
+       int l;
+       char*text;
+       if(!fi) 
+           syntaxerror("Couldn't find file %s: %s", filename, strerror(errno));
+       fseek(fi, 0, SEEK_END);
+       l = ftell(fi);
+       fseek(fi, 0, SEEK_SET);
+       text = rfx_alloc(l+1);
+       fread(text, l, 1, fi);
+       text[l]=0;
+       fclose(fi);
+
+       s_action(text);
     }
-
-    s_action(text);
    
     return 0;
 }
@@ -2531,7 +2593,7 @@ static struct {
     command_func_t* func;
     char*arguments;
 } arguments[] =
-{{"flash", c_flash, "bbox=autocrop background=black version=5 fps=50 name=!default! @compress=default"},
+{{"flash", c_flash, "bbox=autocrop background=black version=6 fps=50 name= filename= @compress=default"},
  {"frame", c_frame, "n=<plus>1 name= @cut=no"},
  // "import" type stuff
  {"swf", c_swf, "name filename"},
@@ -2558,7 +2620,7 @@ static struct {
 
  {"egon", c_egon, "name vertices color=white line=1 @fill=none"},
  {"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"},
+ {"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"},
  {"morphshape", c_morphshape, "name start end"},
  {"button", c_button, "name"},
     {"show", c_show,             "name x=0 y=0 red=+0 green=+0 blue=+0 alpha=+0 luminance= scale= scalex= scaley= pivot= pin= shear= rotate= ratio= above= below= as="},
@@ -2570,7 +2632,7 @@ static struct {
  
     // control tags
  {"play", c_play, "name loop=0 @nomultiple=0"},
- {"stop", c_stop, "name"},
+ {"stop", c_stop, "name= "},
  {"nextframe", c_nextframe, "name"},
  {"previousframe", c_previousframe, "name"},
 
@@ -2588,7 +2650,7 @@ static struct {
     // commands which start a block
 //startclip (see above)
  {"sprite", c_sprite, "name"},
- {"action", c_action, ""},
+ {"action", c_action, "filename="},
 
  {"end", c_end, ""}
 };
@@ -2727,7 +2789,7 @@ static map_t parseArguments(char*command, char*pattern)
            }
        }
        if(pos==len) {
-           syntaxerror("don't know what to do with \"%s\". (All parameters for .%s already set)", text, command);
+           syntaxerror("Illegal argument \"%s\" to .%s", text, command);
        }
     }
 #if 0//def DEBUG