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