3427436e2afd891c14bb26d44bbdee6019a56689
[swftools.git] / lib / modules / swftools.c
1 /* swftools.c
2
3    Math and matrix functions, misc tools
4
5    Extension module for the rfxswf library.
6    Part of the swftools package.
7
8    Copyright (c) 2000, 2001 Rainer Böhme <rfxswf@reflex-studio.de>
9  
10    This file is distributed under the GPL, see file COPYING for details 
11
12 */
13
14 // Matrix & Math tools for SWF files
15
16 #define S64 long long
17 SFIXED RFXSWF_SP(SFIXED a1,SFIXED a2,SFIXED b1,SFIXED b2)
18 { S64 a;
19   a = (S64)a1*(S64)b1+(S64)a2*(S64)b2;
20   return (SFIXED)(a>>16);
21 }
22 SFIXED RFXSWF_QFIX(int zaehler,int nenner) // bildet Quotient von zwei INTs in SFIXED
23 { S64 z = zaehler<<16;
24   S64 a = z/(S64)nenner;
25   return (SFIXED)a;
26 }
27 #undef S64
28
29 MATRIX * swf_MatrixJoin(MATRIX * d,MATRIX * s1,MATRIX * s2)
30 {        
31   if (!d) return NULL;
32   if (!s1) return (s2)?(MATRIX *)memcpy(d,s2,sizeof(MATRIX)):NULL;
33   if (!s2) return (MATRIX *)memcpy(d,s1,sizeof(MATRIX));
34   
35   d->tx = s1->tx + s2->tx;
36   d->ty = s1->ty + s2->ty;
37   
38   d->sx = RFXSWF_SP(s1->sx,s1->r1,s2->sx,s2->r0);
39   d->sy = RFXSWF_SP(s1->r0,s1->sy,s2->r1,s2->sy);
40   d->r0 = RFXSWF_SP(s1->r0,s1->sy,s2->sx,s2->r0);
41   d->r1 = RFXSWF_SP(s1->sx,s1->r1,s2->r1,s2->sy);
42
43   //DumpMatrix(NULL,d);
44   
45   return d;
46 }
47
48 MATRIX * swf_MatrixMapTriangle(MATRIX * m,int dx,int dy,int x0,int y0,
49                                int x1,int y1,int x2,int y2)
50 { int dx1 = x1 - x0;
51   int dy1 = y1 - y0;
52   int dx2 = x2 - x0;
53   int dy2 = y2 - y0;
54   
55   if (!m) return NULL;
56   if ((!dx)||(!dy)) return NULL; // check DIV by zero
57
58   m->tx = x0;
59   m->ty = y0;
60   m->sx = RFXSWF_QFIX(dx1,dx);
61   m->sy = RFXSWF_QFIX(dy2,dy);
62   m->r0 = RFXSWF_QFIX(dy1,dx);
63   m->r1 = RFXSWF_QFIX(dx2,dy);
64   
65   return m;
66 }
67
68 U16 swf_GetDefineID(TAG * t)
69 // up to SWF 4.0
70 { U32 oldTagPos;
71   U16 id = 0;
72
73   oldTagPos = swf_GetTagPos(t);
74   swf_SetTagPos(t,0);
75
76   switch (swf_GetTagID(t))
77   { case ST_DEFINESHAPE:
78     case ST_DEFINESHAPE2:
79     case ST_DEFINESHAPE3:
80     case ST_DEFINEMORPHSHAPE:
81     case ST_DEFINEEDITTEXT:
82     case ST_DEFINEBITS:
83     case ST_DEFINEBITSJPEG2:
84     case ST_DEFINEBITSJPEG3:
85     case ST_DEFINEBITSLOSSLESS:
86     case ST_DEFINEBITSLOSSLESS2:
87     case ST_DEFINEBUTTON:
88     case ST_DEFINEBUTTON2:
89     case ST_DEFINEBUTTONCXFORM:
90     case ST_DEFINEBUTTONSOUND:
91     case ST_DEFINEFONT:
92     case ST_DEFINEFONT2:
93     case ST_DEFINEFONTINFO:
94     case ST_DEFINETEXT:
95     case ST_DEFINETEXT2:
96     case ST_DEFINESOUND:
97     case ST_DEFINESPRITE:
98       id = swf_GetU16(t);
99       break;
100   }
101
102   swf_SetTagPos(t,oldTagPos);
103
104   return id;
105 }
106
107 U16 swf_GetPlaceID(TAG * t)
108 // up to SWF 4.0
109 { U32 oldTagPos;
110   U16 id = 0;
111
112   oldTagPos = swf_GetTagPos(t);
113   swf_SetTagPos(t,0);
114
115   switch (swf_GetTagID(t))
116   { case ST_PLACEOBJECT:
117     case ST_REMOVEOBJECT:
118     case ST_STARTSOUND:
119       id = swf_GetU16(t);
120       break;
121
122     case ST_PLACEOBJECT2:
123     { U8 flags = swf_GetU8(t);
124       U16 d = swf_GetU16(t);
125       id = (flags&PF_CHAR)?swf_GetU16(t):id;
126     } break;
127
128   }
129
130   swf_SetTagPos(t,oldTagPos);
131
132   return id;
133 }
134
135 int definingtagids[] =
136 {ST_DEFINESHAPE,
137  ST_DEFINESHAPE2,
138  ST_DEFINESHAPE3,
139  ST_DEFINEMORPHSHAPE,
140  ST_DEFINEFONT,
141  ST_DEFINEFONT2,
142  ST_DEFINETEXT,
143  ST_DEFINETEXT2,
144  ST_DEFINEEDITTEXT,
145  ST_DEFINEBITS,
146  ST_DEFINEBITSJPEG2,
147  ST_DEFINEBITSJPEG3,
148  ST_DEFINEBITSLOSSLESS,
149  ST_DEFINEBITSLOSSLESS2,
150  ST_DEFINEMOVIE,
151  ST_DEFINESPRITE,
152  ST_DEFINEBUTTON,
153  ST_DEFINEBUTTON2,
154  ST_DEFINESOUND,
155  -1
156 };
157
158 // tags which may be used inside a sprite definition
159 int spritetagids[] =
160 {ST_SHOWFRAME,
161  ST_PLACEOBJECT,
162  ST_PLACEOBJECT2,
163  ST_REMOVEOBJECT,
164  ST_REMOVEOBJECT2, //?
165  ST_DOACTION,
166  ST_STARTSOUND,
167  ST_FRAMELABEL,
168  ST_SOUNDSTREAMHEAD,
169  ST_SOUNDSTREAMHEAD2,
170  ST_SOUNDSTREAMBLOCK,
171  ST_END,
172  -1
173 };
174
175 U8 swf_isAllowedSpriteTag(TAG * tag)
176 {
177     int id = tag->id;
178     int t=0;
179     while(spritetagids[t]>=0)
180     {
181         if(spritetagids[t] == id) 
182             return 1;
183         t++;
184     }
185     return 0; 
186 }
187
188 U8 swf_isDefiningTag(TAG * tag)
189 {
190     int id = tag->id;
191     int t=0;
192     while(definingtagids[t]>=0)
193     {
194         if(definingtagids[t] == id) 
195             return 1;
196         t++;
197     }
198     return 0; 
199 }
200
201 U16 swf_GetDepth(TAG * t)
202 // up to SWF 4.0
203
204   U16 depth = 0;
205   U32 oldTagPos;
206   oldTagPos = swf_GetTagPos(t);
207   swf_SetTagPos(t,0);
208
209   switch (swf_GetTagID(t))
210   { case ST_PLACEOBJECT:
211     case ST_REMOVEOBJECT:
212       swf_GetU16(t); //id
213       depth = swf_GetU16(t);
214       break;
215     case ST_REMOVEOBJECT2:
216       depth = swf_GetU16(t);
217       break;
218     case ST_PLACEOBJECT2:
219     { U8 flags = swf_GetU8(t);
220       depth = swf_GetU16(t);
221     } break;
222   }
223   swf_SetTagPos(t,oldTagPos);
224   return depth;
225 }
226
227 char* swf_GetName(TAG * t)
228 {
229     char* name = 0;
230     U32 oldTagPos;
231     MATRIX m;
232     CXFORM c;
233     oldTagPos = swf_GetTagPos(t);
234     swf_SetTagPos(t,0);
235     switch(swf_GetTagID(t))
236     {
237         case ST_FRAMELABEL:
238             name = &t->data[swf_GetTagPos(t)];
239         break;
240         case ST_PLACEOBJECT2: {   
241             U8 flags = swf_GetU8(t);
242             swf_GetU16(t); //depth;
243             if(flags&PF_CHAR) 
244               swf_GetU16(t); //id
245             if(flags&PF_MATRIX)
246               swf_GetMatrix(t, &m);
247             if(flags&PF_CXFORM)
248               swf_GetCXForm(t, &c, 1);
249             if(flags&PF_RATIO)
250               swf_GetU16(t);
251             if(flags&PF_NAME) {
252               swf_ResetReadBits(t);
253               name = &t->data[swf_GetTagPos(t)];
254             }
255         }
256         break;
257     }
258     swf_SetTagPos(t,oldTagPos);
259     return name;
260 }
261