yet more big endian/solaris fixes. (especially the bus error type)
[swftools.git] / lib / modules / swfaction.c
index 4c47d53..c20e491 100644 (file)
@@ -13,6 +13,8 @@
 
 #include "../rfxswf.h"
 
+#define MAX_LOOKUP 1024   // make cross references in dumps
+
 struct Action
 {
     int version;
@@ -229,21 +231,31 @@ int OpAdvance(char c, char*data)
                return 1+4; //int
            } else if (type == 8) {
                return 1+1; //lookup
-           }
+           } else return 1;
            break;
        }
     }
     return 0;
 }
 
-/* TODO: this should be in swfdump.c */
+/* TODO: * this should be in swfdump.c */
 void swf_DumpActions(ActionTAG*atag, char*prefix) 
 {
     int t;
     U8*data;
     char* cp;
-    if(!prefix) 
-       prefix="";
+    int entry = 0;
+
+#ifdef MAX_LOOKUP
+
+    char * lookup[MAX_LOOKUP];
+    memset(lookup,0x00,sizeof(lookup));
+
+#endif
+
+   if (!prefix)
+        prefix="";
+
     while(atag)
     {
        U8 poollen = 0;
@@ -264,8 +276,8 @@ void swf_DumpActions(ActionTAG*atag, char*prefix)
        {
            switch(*cp)
            {
-               case 'f': {
-                   printf(" %d", *(U16*)data); //FIXME: le/be
+               case 'f': { //frame
+                   printf(" %d", data[0]+256*data[1]);
                } break;
                case 'u': {
                    printf(" URL:\"%s\"", data);
@@ -278,9 +290,14 @@ void swf_DumpActions(ActionTAG*atag, char*prefix)
                } break;
                case 'c': {
                    printf(" String:\"%s\"", data);
+#ifdef MAX_LOOKUP
+                    if (entry<MAX_LOOKUP)
+                     lookup[entry++] = strdup(data);
+#endif
                } break;
                case 'C': {
                    poollen = *data;
+                    entry = 0;
                    printf("(%d entries)", poollen);
                } break;
                case 's': {
@@ -291,7 +308,7 @@ void swf_DumpActions(ActionTAG*atag, char*prefix)
                    printf(" %d", *data);
                } break;
                case 'b': {
-                   printf(" %d", *(U16*)data);
+                   printf(" %d", data[0]+256*data[1]);
                } break;
                case 'p': {
                    U8 type = *data;
@@ -299,7 +316,9 @@ void swf_DumpActions(ActionTAG*atag, char*prefix)
                    if(type == 0) {
                        printf(" String:\"%s\"", value);
                    } else if (type == 1) {
-                       printf(" Float:%f", *(float*)value);
+                       U32 f = value[0]+(value[1]<<8)+
+                               (value[2]<<16)+(value[3]<<24);
+                       printf(" Float:%f", *(float*)&f);
                    } else if (type == 2) {
                        printf(" NULL");
                    } else if (type == 4) {
@@ -307,11 +326,24 @@ void swf_DumpActions(ActionTAG*atag, char*prefix)
                    } else if (type == 5) {
                        printf(" bool:%s", *value?"true":"false");
                    } else if (type == 6) {
-                       printf(" float:%f", *(double*)value);
+                       U8 a[8];
+                       int t;
+#ifdef WORDS_BIGENDIAN
+                       for(t=0;t<8;t++)
+                           a[7-t]=value[t];
+#else
+                       memcpy(a,value,8);
+#endif
+                       printf(" double:%f", *(double*)a);
                    } else if (type == 7) {
-                       printf(" int:%d", *(int*)value);
+                       printf(" int:%d", value[0]+(value[1]<<8)+
+                                         (value[2]<<16)+(value[3]<<24));
                    } else if (type == 8) {
                        printf(" Lookup:%d", *value);
+#ifdef MAX_LOOKUP
+                       if (lookup[*value])
+                         printf(" (\"%s\")",lookup[*value]);
+#endif
                    } else {
                        printf(" UNKNOWN[%02x]",type);
                    }
@@ -341,6 +373,10 @@ void swf_DumpActions(ActionTAG*atag, char*prefix)
        printf("\n");
        atag = atag->next;
     }
+
+#ifdef MAX_LOOKUP
+  for (t=0;t<MAX_LOOKUP;t++) if (lookup[t]) free(lookup[t]);
+#endif
 }
 
 static const char TYPE_URL = 1;
@@ -487,6 +523,19 @@ void swf_AddActionTAG(U8 op, U8*data, U16 len)
     currentatag = currentatag->next;
 }
 
+ActionMarker action_setMarker()
+{
+    ActionMarker m;
+    m.atag = currentatag;
+    return m;
+}
+
+int inline ActionTagSize(ActionTAG*atag)
+{
+    return (atag->op&0x80)?3+(atag->len):1+0;
+}
+
+
 #define ACTION_END            0x00
 #define ACTION_NEXTFRAME      0x04
 #define ACTION_PREVIOUSFRAME  0x05
@@ -577,6 +626,55 @@ void swf_AddActionTAG(U8 op, U8*data, U16 len)
 #define ACTION_CALL           0x9e
 #define ACTION_GOTOFRAME2     0x9f
 
+void action_fixjump(ActionMarker m1, ActionMarker m2)
+{
+    ActionTAG* a1 = m1.atag;
+    ActionTAG* a2 = m2.atag;
+    ActionTAG* a;
+    int len = 0;
+    int oplen = 0;
+    a = a1;
+    
+    a = a->next; //first one is free
+    while(a && a!=a2)
+    {
+       len += ActionTagSize(a);
+       oplen ++;
+       a = a->next;
+    }
+    if(!a)
+    { len = 0;
+      oplen = 0;
+      a = a2;
+      while(a && a!=a1) {
+         len -= ActionTagSize(a);
+         oplen --;
+         a = a->next;
+      }
+      if(!a) {
+         fprintf(stderr, "action_fixjump: couldn't find second tag\n");
+         return;
+      }
+      len -= ActionTagSize(a);
+      oplen --;
+    }
+
+    if (a1->op == ACTION_IF || a1->op == ACTION_JUMP) 
+    {
+       *(U16*)(a1->data) = SWAP16(len);
+    }
+    else if(a1->op == ACTION_WAITFORFRAME)
+    {
+       ((U8*)(a1->data))[2] = oplen;
+    }
+    else if(a1->op == ACTION_WAITFORFRAME2)
+    {
+       ((U8*)(a1->data))[0] = oplen;
+    }
+    
+}
+
+
 void action_NextFrame() {swf_AddActionTAG(ACTION_NEXTFRAME, 0, 0);}
 void action_PreviousFrame() {swf_AddActionTAG(ACTION_PREVIOUSFRAME, 0, 0);}
 void action_Play() {swf_AddActionTAG(ACTION_PLAY, 0, 0);}
@@ -653,17 +751,17 @@ void action_Call() {swf_AddActionTAG(ACTION_CALL, 0, 0);}
 void action_End() {swf_AddActionTAG(ACTION_END, 0, 0);}
 void action_GotoFrame(U16 frame) 
 {
-    *(U16*)currentatag->tmp = frame;
+    *(U16*)currentatag->tmp = SWAP16(frame);
     swf_AddActionTAG(ACTION_GOTOFRAME, (U8*)currentatag->tmp, 2);
 }
 void action_Jump(U16 branch) 
 {
-    *(U16*)currentatag->tmp = branch;
+    *(U16*)currentatag->tmp = SWAP16(branch);
     swf_AddActionTAG(ACTION_JUMP, (U8*)currentatag->tmp, 2);
 }
 void action_If(U16 branch) 
 {
-    *(U16*)currentatag->tmp = branch;
+    *(U16*)currentatag->tmp = SWAP16(branch);
     swf_AddActionTAG(ACTION_IF, (U8*)currentatag->tmp, 2);
 }
 void action_StoreRegister(U8 reg) 
@@ -688,7 +786,7 @@ void action_WaitForFrame2(U8 skip)
 }
 void action_WaitForFrame(U16 frame, U8 skip) 
 {
-    *(U16*)currentatag->tmp = frame;
+    *(U16*)currentatag->tmp = SWAP16(frame);
     *(U8*)&currentatag->tmp[2] = skip;
     swf_AddActionTAG(ACTION_WAITFORFRAME, (U8*)currentatag->tmp, 3);
 }
@@ -731,21 +829,39 @@ void action_PushString(char*str)
 void action_PushFloat(float f)
 {
     char*ptr = (char*)malloc(5);
+    U32 fd = *(U32*)&f;
     ptr[0] = 1; //float
-    *(float*)&ptr[1]  = f;
+    ptr[1]  = fd;
+    ptr[2]  = fd>>8;
+    ptr[3]  = fd>>16;
+    ptr[4]  = fd>>24;
     swf_AddActionTAG(ACTION_PUSH, (U8*)ptr, 5);
 }
 void action_PushDouble(double d) 
 {
     char*ptr = (char*)malloc(9);
+    U8*dd = (U8*)&d;
     ptr[0] = 6; //double
-    *(double*)&ptr[1]  = d;
+#ifdef WORDS_BIGENDIAN
+    ptr[1] = dd[7];ptr[2] = dd[6];
+    ptr[3] = dd[5];ptr[4] = dd[4];
+    ptr[5] = dd[3];ptr[6] = dd[2];
+    ptr[7] = dd[1];ptr[8] = dd[0];
+#else
+    ptr[1] = dd[0];ptr[2] = dd[1];
+    ptr[3] = dd[2];ptr[4] = dd[3];
+    ptr[5] = dd[4];ptr[6] = dd[5];
+    ptr[7] = dd[6];ptr[8] = dd[7];
+#endif
     swf_AddActionTAG(ACTION_PUSH, (U8*)ptr, 9);
 }
 void action_PushInt(int i)
 {
     *(U8*)currentatag->tmp = 7; //int
-    *(U8*)&currentatag->tmp[1] = i;
+    currentatag->tmp[1] = i;
+    currentatag->tmp[2] = i>>8;
+    currentatag->tmp[3] = i>>16;
+    currentatag->tmp[4] = i>>24;
     swf_AddActionTAG(ACTION_PUSH, (U8*)currentatag->tmp, 5);
 }
 void action_GotoLabel(char* label)
@@ -766,3 +882,30 @@ void action_GetUrl(char* url, char* label)
 void action_DefineFunction(U8*data, int len) {}
 void action_Constantpool(char* constantpool) {}
 void action_With(char*object) {}
+
+/*
+  Properties:
+
+  _X 0
+  _Y 1
+  _xscale 2
+  _yscale 3
+  _currentframe 4
+  _totalframes 5
+  _alpha 6
+  _visible 7
+  _width 8
+  _height 9
+  _rotation 10
+  _target 11
+  _framesloaded 12
+  _name 13
+  _droptarget 14
+  _url 15
+  _highquality 16
+  _focusrect 17
+  _soundbuftime 18
+  _quality* 19
+  _xmouse* 20
+  _ymouse* 21
+*/