added shortcuts for some SWF3 actions (play,stop,previousframe,nextframe)
[swftools.git] / src / swfc.c
index fb3fcc5..05003f8 100644 (file)
@@ -359,7 +359,6 @@ static MATRIX s_instancepos(SRECT rect, parameters_t*p)
     SRECT r;
     makeMatrix(&m, p);
     r = swf_TurnRect(rect, &m);
-    printf("%f %f %f %f\n", r.xmin/20.0, r.ymin/20.0, r.xmax/20.0, r.ymax/20.0);
     if(currentrect.xmin == 0 && currentrect.ymin == 0 && 
        currentrect.xmax == 0 && currentrect.ymax == 0)
        currentrect = r;
@@ -436,11 +435,19 @@ void s_sprite(char*name)
     incrementid();
 }
 
+typedef struct _buttonrecord
+{
+    U16 id;
+    MATRIX matrix;
+    CXFORM cxform;
+    char set;
+} buttonrecord_t;
+
 typedef struct _button
 {
     int endofshapes;
-    int shapes[4];
     int nr_actions;
+    buttonrecord_t records[4];
 } button_t;
 
 static button_t mybutton;
@@ -451,15 +458,15 @@ void s_button(char*name)
     swf_SetU16(tag, id); //id
     swf_ButtonSetFlags(tag, 0); //menu=no
 
-    mybutton.endofshapes = 0;
-    mybutton.shapes[0] = mybutton.shapes[1] = mybutton.shapes[2] = mybutton.shapes[3] = 0;
-    mybutton.nr_actions = 0;
+    memset(&mybutton, 0, sizeof(mybutton));
 
     memset(&stack[stackpos], 0, sizeof(stack[0]));
     stack[stackpos].type = 3;
     stack[stackpos].tag = tag;
     stack[stackpos].id = id;
     stack[stackpos].name = strdup(name);
+    stack[stackpos].oldrect = currentrect;
+    memset(&currentrect, 0, sizeof(currentrect));
 
     stackpos++;
     incrementid();
@@ -472,33 +479,56 @@ void s_buttonput(char*character, char*as, parameters_t p)
     if(!c) {
        syntaxerror("character %s not known (in .shape %s)", character, character);
     }
-    if(strstr(as, "idle")) {flags |= BS_UP;mybutton.shapes[0]=c->id;}
-    if(strstr(as, "hover")) {flags |= BS_OVER;mybutton.shapes[1]=c->id;}
-    if(strstr(as, "pressed")) {flags |= BS_DOWN;mybutton.shapes[2]=c->id;}
-    if(strstr(as, "area")) {flags |= BS_HIT;mybutton.shapes[3]=c->id;}
-    
     if(mybutton.endofshapes) {
        syntaxerror("a .do may not precede a .show", character, character);
     }
    
     m = s_instancepos(c->size, &p);
 
-    swf_ButtonSetRecord(stack[stackpos-1].tag,flags,c->id,1,&m,&p.cxform);
+    buttonrecord_t r;
+    r.id = c->id;
+    r.matrix = m;
+    r.cxform = p.cxform;
+    r.set = 1;
+    
+    if(strstr(as, "idle")) mybutton.records[0]=r;
+    if(strstr(as, "hover")) mybutton.records[1]=r;
+    if(strstr(as, "pressed")) mybutton.records[2]=r;
+    if(strstr(as, "area")) mybutton.records[3]=r;
 }
-void s_buttonaction(int flags, char*action)
+static void setbuttonrecords(TAG*tag)
 {
-    ActionTAG* a = 0;
+    int flags[] = {BS_UP,BS_OVER,BS_DOWN,BS_HIT};
     if(!mybutton.endofshapes) {
-       swf_SetU8(stack[stackpos-1].tag,0); // end of button records
+       int t;
+       
+       if(!mybutton.records[3].set) {
+           memcpy(&mybutton.records[3], &mybutton.records[0], sizeof(buttonrecord_t));
+       }
+
+       for(t=0;t<4;t++) {
+           if(mybutton.records[t].set)
+               swf_ButtonSetRecord(tag,flags[t],mybutton.records[t].id,1,&mybutton.records[t].matrix,&mybutton.records[t].cxform);
+       }
+       swf_SetU8(tag,0); // end of button records
        mybutton.endofshapes = 1;
     }
+}
+
+void s_buttonaction(int flags, char*action)
+{
+    ActionTAG* a = 0;
+    if(flags==0) {
+       return;
+    }
+    setbuttonrecords(stack[stackpos-1].tag);
     
     a = swf_ActionCompile(text, stack[0].swf->fileVersion);
     if(!a) {
        syntaxerror("Couldn't compile ActionScript");
     }
 
-    swf_ButtonSetCondition(stack[stackpos-1].tag, BC_OVERDOWN_OVERUP);
+    swf_ButtonSetCondition(stack[stackpos-1].tag, flags);
     swf_ActionSet(stack[stackpos-1].tag, a);
     mybutton.nr_actions++;
 
@@ -507,16 +537,17 @@ void s_buttonaction(int flags, char*action)
 
 static void s_endButton()
 {
+    setbuttonrecords(stack[stackpos-1].tag);
     stackpos--;
-    if(!mybutton.endofshapes) {
-       swf_SetU8(stack[stackpos].tag,0); // end of button records
-       mybutton.endofshapes = 1;
-    }
-    /* end of actions */
       
     swf_ButtonPostProcess(stack[stackpos].tag, mybutton.nr_actions);
 
+    SRECT r = currentrect;
+
     tag = stack[stackpos].tag;
+    currentrect = stack[stackpos].oldrect;
+
+    s_addcharacter(stack[stackpos].name, stack[stackpos].id, stack[stackpos].tag, r);
     free(stack[stackpos].name);
 }
 
@@ -1062,6 +1093,27 @@ void s_action(const char*text)
     swf_ActionFree(a);
 }
 
+int s_swf3action(char*name, char*action)
+{
+    ActionTAG* a = 0;
+    instance_t* object = dictionary_lookup(&instances, name);
+    if(!object) {
+       return 0;
+    }
+    a = action_SetTarget(0, name);
+    if(!strcmp(action, "nextframe")) a = action_NextFrame(a);
+    else if(!strcmp(action, "previousframe")) a = action_PreviousFrame(a);
+    else if(!strcmp(action, "stop")) a = action_Stop(a);
+    else if(!strcmp(action, "play")) a = action_Play(a);
+    a = action_SetTarget(a, "");
+    a = action_End(a);
+
+    tag = swf_InsertTag(tag, ST_DOACTION);
+    swf_ActionSet(tag, a);
+    swf_ActionFree(a);
+    return 1;
+}
+
 void s_outline(char*name, char*format, char*source)
 {
     outline_t* outline;
@@ -1091,12 +1143,12 @@ void s_outline(char*name, char*format, char*source)
     dictionary_put2(&outlines, name, outline);
 }
 
-void s_playsound(char*name, int loops, int nomultiple, int stop)
+int s_playsound(char*name, int loops, int nomultiple, int stop)
 {
     sound_t* sound = dictionary_lookup(&sounds, name);
     SOUNDINFO info;
     if(!sound)
-       syntaxerror("Don't know anything about sound \"%s\"", name);
+       return 0;
 
     tag = swf_InsertTag(tag, ST_STARTSOUND);
     swf_SetU16(tag, sound->id); //id
@@ -1105,6 +1157,7 @@ void s_playsound(char*name, int loops, int nomultiple, int stop)
     info.loops = loops;
     info.nomultiple = nomultiple;
     swf_SetSoundInfo(tag, &info);
+    return 1;
 }
 
 void s_includeswf(char*name, char*filename)
@@ -1742,7 +1795,7 @@ static int c_point(map_t*args)
 }
 static int c_play(map_t*args) 
 {
-    char*name = lu(args, "sound");
+    char*name = lu(args, "name");
     char*loop = lu(args, "loop");
     char*nomultiple = lu(args, "nomultiple");
     int nm = 0;
@@ -1751,14 +1804,46 @@ static int c_play(map_t*args)
     else
        nm = parseInt(nomultiple);
 
-    s_playsound(name, parseInt(loop), nm, 0);
+    if(s_playsound(name, parseInt(loop), nm, 0)) {
+       return 0;
+    } else if(s_swf3action(name, "play")) {
+       return 0;
+    }
     return 0;
 }
 
 static int c_stop(map_t*args) 
 {
-    char*name = lu(args, "sound");
-    s_playsound(name, 0,0,1);
+    char*name = lu(args, "name");
+
+    if(s_playsound(name, 0,0,1)) {
+       return 0;
+    } else if(s_swf3action(name, "stop")) {
+       return 0;
+    }
+    syntaxerror("I don't know anything about sound/movie \"%s\"", name);
+    return 0;
+}
+
+static int c_nextframe(map_t*args) 
+{
+    char*name = lu(args, "name");
+
+    if(s_swf3action(name, "nextframe")) {
+       return 0;
+    }
+    syntaxerror("I don't know anything about movie \"%s\"", name);
+    return 0;
+}
+
+static int c_previousframe(map_t*args) 
+{
+    char*name = lu(args, "name");
+
+    if(s_swf3action(name, "previousframe")) {
+       return 0;
+    }
+    syntaxerror("I don't know anything about movie \"%s\"", name);
     return 0;
 }
 
@@ -2343,8 +2428,10 @@ static struct {
     {"on_key", c_on_key, "key=any"},
  
     // control tags
- {"play", c_play, "sound loop=0 @nomultiple=0"},
- {"stop", c_stop, "sound"},
+ {"play", c_play, "name loop=0 @nomultiple=0"},
+ {"stop", c_stop, "name"},
+ {"nextframe", c_nextframe, "name"},
+ {"previousframe", c_previousframe, "name"},
 
     // object placement tags
  {"put", c_put,             "<i> x=0 y=0 red=+0 green=+0 blue=+0 alpha=+0 luminance= scale= scalex= scaley= pivot= pin= shear= rotate= ratio= above= below="},