1 /****************************************************************************
2  *
3  *  Copyright (C) 2005-2006 "Stuart R. Anderson" <anderson@netsweng.com>
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  ****************************************************************************/
20 
21 #include <math.h>
22 #include <stdarg.h>
23 #include <string.h>
24 
25 #include "blocks/blocktypes.h"
26 #include "decompile.h"
27 #include "parser.h"
28 #include "swfoutput.h"
29 
30 extern char *swftargetfile;
31 
32 /*
33  * This file contains output functions that can convert the different SWF block
34  * types into libming API calls that can recreate the block. Because the Ming
35  * API usage is the same independent of the language being used, this file
36  * can be used for multiple language bindings (OK, maybe not LISP). The
37  * difference in syntax can be paramterized so the code in #ifdefs is not
38  * a lot of duplicated code.
39  */
40 #if !defined(SWFPHP) && !defined(SWFPERL) && !defined(SWFPYTHON) && !defined(SWFPLUSPLUS) && !defined(SWFTCL)
41 #error "You must define SWFPHP or SWFPERL or SWFPYTHON or SWFPLUSPLUS or SWFTCL when building this file"
42 #endif
43 
44 #ifdef SWFPERL
45 #define COMMSTART "#"
46 #define COMMEND   ""
47 #define VAR       "$"
48 #define DECLOBJ(x) "$"
49 #define MEMBER    "->"
50 #define OBJPREF   "SWF::"
51 #define NEWOP     "new"
52 #define SQ	"'"
53 #define ARGSEP	","
54 #define ARGSTART "("
55 #define ARGEND	")"
56 #define STMNTEND ";"
57 #endif
58 #ifdef SWFPHP
59 #define COMMSTART "/*"
60 #define COMMEND   "*/"
61 #define VAR       "$"
62 #define DECLOBJ(x) "$"
63 #define MEMBER    "->"
64 #define OBJPREF   "SWF"
65 #define NEWOP     "new"
66 #define SQ	"'"
67 #define ARGSEP	","
68 #define ARGSTART "("
69 #define ARGEND	")"
70 #define STMNTEND ";"
71 #endif
72 #ifdef SWFPYTHON
73 #define COMMSTART "#"
74 #define COMMEND   ""
75 #define VAR       ""
76 #define DECLOBJ(x) ""
77 #define MEMBER    "."
78 #define OBJPREF   "SWF"
79 #define NEWOP     ""
80 #define SQ	"'"
81 #define ARGSEP	","
82 #define ARGSTART "("
83 #define ARGEND	")"
84 #define STMNTEND ";"
85 #endif
86 #ifdef SWFPLUSPLUS
87 #define COMMSTART "//"
88 #define COMMEND   ""
89 #define VAR       ""
90 #define DECLOBJ(x) "SWF" #x "* "
91 #define MEMBER    "->"
92 #define OBJPREF   "SWF"
93 #define NEWOP     "new"
94 #define SQ	"\""
95 #define ARGSEP	","
96 #define ARGSTART "("
97 #define ARGEND	")"
98 #define STMNTEND ";"
99 #endif
100 #ifdef SWFTCL
101 #define COMMSTART "#"
102 #define COMMEND   ""
103 #define VAR       "$"
104 #define DECLOBJ(x) "SWF" #x "* "
105 #define MEMBER    " "
106 #define OBJPREF   "SWF"
107 #define NEWOP     "new"
108 #define SQ	""
109 #define ARGSEP	" "
110 #define ARGSTART ""
111 #define ARGEND	""
112 #define STMNTEND ""
113 #endif
114 
115 static int framenum = 1;
116 static int spframenum = 1;
117 static int spritenum = 0;
118 static char spritename[64];
119 static int offsetX=0;
120 static int offsetY=0;
121 
122 struct FONTINFO {		/* a linked list for all our font code info: */
123  int *fontcodeptr;		/* built in several outputSWF_DEFINEFONTxxxx(), used in outputSWF_TEXT_RECORD() */
124  int fontcodearrsize;
125  int fontcodeID;
126  struct FONTINFO *next;
127 };
128 static struct FONTINFO *fip; 	/* start point of list */
129 static struct FONTINFO *fip_current;
130 #define OUT_BEGIN(block) \
131 	struct block *sblock = (struct block *)pblock; \
132 	printf( "\n" COMMSTART " " #block " " COMMEND "\n");
133 
134 #define OUT_BEGIN_EMPTY(block) \
135 	printf( "\n" COMMSTART " " #block " " COMMEND "\n");
136 
137 static struct SWFBlockOutput outputs[] = {
138   {SWF_CHARACTERSET, outputSWF_CHARACTERSET},
139   {SWF_DEFINEBITS, outputSWF_DEFINEBITS},
140   {SWF_DEFINEBITSJPEG2, outputSWF_DEFINEBITSJPEG2},
141   {SWF_DEFINEBITSJPEG3, outputSWF_DEFINEBITSJPEG3},
142   {SWF_DEFINEBITSPTR, outputSWF_DEFINEBITSPTR},
143   {SWF_DEFINEBUTTON, outputSWF_DEFINEBUTTON},
144   {SWF_DEFINEBUTTON2, outputSWF_DEFINEBUTTON2},
145   {SWF_DEFINEBUTTONCXFORM, outputSWF_DEFINEBUTTONCXFORM},
146   {SWF_DEFINEBUTTONSOUND, outputSWF_DEFINEBUTTONSOUND},
147   {SWF_DEFINECOMMANDOBJ, outputSWF_DEFINECOMMANDOBJ},
148   {SWF_DEFINEEDITTEXT, outputSWF_DEFINEEDITTEXT},
149   {SWF_DEFINEFONT, outputSWF_DEFINEFONT},
150   {SWF_DEFINEFONT2, outputSWF_DEFINEFONT2},
151   {SWF_DEFINEFONT3, outputSWF_DEFINEFONT3},
152   {SWF_DEFINEFONTINFO, outputSWF_DEFINEFONTINFO},
153   {SWF_DEFINEFONTINFO2, outputSWF_DEFINEFONTINFO2},
154   {SWF_DEFINELOSSLESS, outputSWF_DEFINELOSSLESS},
155   {SWF_DEFINELOSSLESS2, outputSWF_DEFINELOSSLESS2},
156   {SWF_DEFINEMORPHSHAPE, outputSWF_DEFINEMORPHSHAPE},
157   {SWF_DEFINESHAPE, outputSWF_DEFINESHAPE},
158   {SWF_DEFINESHAPE2, outputSWF_DEFINESHAPE2},
159   {SWF_DEFINESHAPE3, outputSWF_DEFINESHAPE3},
160   {SWF_DEFINESHAPE4, outputSWF_DEFINESHAPE4},
161   {SWF_DEFINESOUND, outputSWF_DEFINESOUND},
162   {SWF_DEFINESPRITE, outputSWF_DEFINESPRITE},
163   {SWF_DEFINETEXT, outputSWF_DEFINETEXT},
164   {SWF_DEFINETEXT2, outputSWF_DEFINETEXT2},
165   {SWF_DEFINETEXTFORMAT, outputSWF_DEFINETEXTFORMAT},
166   {SWF_DEFINEVIDEO, outputSWF_DEFINEVIDEO},
167   {SWF_DEFINEVIDEOSTREAM, outputSWF_DEFINEVIDEOSTREAM},
168   {SWF_DOACTION, outputSWF_DOACTION},
169   {SWF_ENABLEDEBUGGER, outputSWF_ENABLEDEBUGGER},
170   {SWF_END, outputSWF_END},
171   {SWF_EXPORTASSETS, outputSWF_EXPORTASSETS},
172   {SWF_FONTREF, outputSWF_FONTREF},
173   {SWF_FRAMELABEL, outputSWF_FRAMELABEL},
174   {SWF_FRAMETAG, outputSWF_FRAMETAG},
175   {SWF_FREEALL, outputSWF_FREEALL},
176   {SWF_FREECHARACTER, outputSWF_FREECHARACTER},
177   {SWF_GENCOMMAND, outputSWF_GENCOMMAND},
178   {SWF_IMPORTASSETS, outputSWF_IMPORTASSETS},
179   {SWF_JPEGTABLES, outputSWF_JPEGTABLES},
180   {SWF_NAMECHARACTER, outputSWF_NAMECHARACTER},
181   {SWF_PATHSAREPOSTSCRIPT, outputSWF_PATHSAREPOSTSCRIPT},
182   {SWF_PLACEOBJECT, outputSWF_PLACEOBJECT},
183   {SWF_PLACEOBJECT2, outputSWF_PLACEOBJECT2},
184   {SWF_PLACEOBJECT3, outputSWF_PLACEOBJECT3},
185   {SWF_PREBUILT, outputSWF_PREBUILT},
186   {SWF_PREBUILTCLIP, outputSWF_PREBUILTCLIP},
187   {SWF_PROTECT, outputSWF_PROTECT},
188   {SWF_REMOVEOBJECT, outputSWF_REMOVEOBJECT},
189   {SWF_REMOVEOBJECT2, outputSWF_REMOVEOBJECT2},
190   {SWF_SERIALNUMBER, outputSWF_SERIALNUMBER},
191   {SWF_SETBACKGROUNDCOLOR, outputSWF_SETBACKGROUNDCOLOR},
192   {SWF_SHOWFRAME, outputSWF_SHOWFRAME},
193   {SWF_SOUNDSTREAMBLOCK, outputSWF_SOUNDSTREAMBLOCK},
194   {SWF_SOUNDSTREAMHEAD, outputSWF_SOUNDSTREAMHEAD},
195   {SWF_SOUNDSTREAMHEAD2, outputSWF_SOUNDSTREAMHEAD2},
196   {SWF_STARTSOUND, outputSWF_STARTSOUND},
197   {SWF_SYNCFRAME, outputSWF_SYNCFRAME},
198   {SWF_INITACTION, outputSWF_INITACTION},
199   {SWF_VIDEOFRAME, outputSWF_VIDEOFRAME},
200   {SWF_METADATA, outputSWF_METADATA},
201   {SWF_SETTABINDEX, outputSWF_SETTABINDEX},
202   {SWF_SCRIPTLIMITS, outputSWF_SCRIPTLIMITS},
203   {SWF_SYMBOLCLASS, outputSWF_SYMBOLCLASS},
204   {SWF_DEFINESCENEANDFRAMEDATA, outputSWF_DEFINESCENEANDFRAMEDATA},
205 };
206 
207 static int numOutputs = sizeof (outputs) / sizeof (struct SWFBlockOutput);
208 
209 #if defined(SWFPLUSPLUS)
210 static char **g_varlist;
211 static int g_nvars;
212 
add_var(const char * var)213 static void add_var(const char *var)
214 {
215     g_nvars++;
216     g_varlist = (char **)realloc(g_varlist, g_nvars*sizeof(void*));
217     g_varlist[g_nvars - 1] = strdup(var);
218 }
219 
search_var(const char * var)220 static int search_var(const char *var)
221 {
222     int i;
223     for (i = 0; i < g_nvars; i++)
224         if (0 == strcmp(g_varlist[i], var))
225             return 1;
226     add_var(var);
227     return 0;
228 }
229 #else
230 #define search_var(n) 0
231 #endif
232 
233 /* Handle language syntax differnces with these function */
234 
235 static void
init_script()236 init_script()
237 {
238 	static int initialized = 0;
239 	if ( initialized ) return;
240 #ifdef SWFPHP
241 	setNewLineString("\n");
242 #endif
243 #ifdef SWFPERL
244 	setNewLineString("\n");
245 #endif
246 	initialized = 1;
247 
248 }
249 
250 
251 char *
methodcall(char * varname,char * method)252 methodcall (char *varname, char *method)
253 {
254   static char buf[256];
255 
256 #if defined(SWFTCL)
257   sprintf (buf, "%s " VAR "%s ", method, varname);
258 #else
259   sprintf (buf, VAR "%s" MEMBER "%s", varname, method);
260 #endif
261 
262   return buf;
263 }
264 
265 void
params(int nparam,...)266 params(int nparam, ...)
267 {
268 va_list ap;
269 char *fmt;
270 unsigned long p;
271 int i;
272 
273 va_start(ap,nparam);
274 printf("%s", ARGSTART);
275 for(i=0;i<nparam;i++) {
276 	fmt = va_arg(ap,char *);
277 	p = va_arg(ap,unsigned long);
278 	printf(fmt,p);
279 	if( i<nparam-1 )
280 		printf(ARGSEP " ");
281 }
282 printf("%s", ARGEND);
283 va_end(ap);
284 }
285 
286 char *
newobj(char * varname,char * obj)287 newobj (char *varname, char *obj)
288 {
289   static char buf[256];
290 
291   if (varname)
292   {
293 #if defined(SWFPLUSPLUS)
294     // might be worth storing the newly created object in a std::auto_ptr here
295     // as I dubt we're outputting nested scopes anyway..
296     if (!search_var(varname))
297         sprintf (buf, OBJPREF "%s* %s = " NEWOP " " OBJPREF "%s", obj, varname, obj);
298     else
299         sprintf (buf, "%s = " NEWOP " " OBJPREF "%s", varname, obj);
300 #elif defined(SWFTCL)
301     sprintf (buf, "set %s [" NEWOP OBJPREF "%s]", varname, obj);
302 #else
303     sprintf (buf, VAR "%s = " NEWOP " " OBJPREF "%s", varname, obj);
304 #endif
305   }
306   else
307     sprintf (buf, NEWOP " " OBJPREF "%s", obj);
308 
309   return buf;
310 }
311 
312 /* Output basic Flash Types */
313 
314 void
outputSWF_RGBA(SWF_RGBA * color,char * pname)315 outputSWF_RGBA (SWF_RGBA * color, char *pname)
316 {
317 #ifdef SWFPLUSPLUS
318   char varname[256];
319   sprintf(varname, "%s_red", pname);
320   if (!search_var(varname))
321   {
322     printf ("int %s_red   = 0x%2.2x;\n", pname, color->red);
323     printf ("int %s_green = 0x%2.2x;\n", pname, color->green);
324     printf ("int %s_blue  = 0x%2.2x;\n", pname, color->blue);
325     printf ("int %s_alpha = 0x%2.2x;\n", pname, color->alpha);
326   } else
327   {
328     printf ("%s_red   = 0x%2.2x;\n", pname, color->red);
329     printf ("%s_green = 0x%2.2x;\n", pname, color->green);
330     printf ("%s_blue  = 0x%2.2x;\n", pname, color->blue);
331     printf ("%s_alpha = 0x%2.2x;\n", pname, color->alpha);
332   }
333 #else
334   printf ("" VAR "%s_red   = 0x%2.2x;\n", pname, color->red);
335   printf ("" VAR "%s_green = 0x%2.2x;\n", pname, color->green);
336   printf ("" VAR "%s_blue  = 0x%2.2x;\n", pname, color->blue);
337   printf ("" VAR "%s_alpha = 0x%2.2x;\n", pname, color->alpha);
338 #endif
339 }
340 
341 void
outputSWF_MATRIX(SWF_MATRIX * matrix,char * fname)342 outputSWF_MATRIX (SWF_MATRIX * matrix, char *fname)
343 {
344   float a, b, c, d;
345   float angle, xScale, yScale, skew;
346 
347   a = matrix->ScaleX;
348   b = matrix->RotateSkew0;
349   c = matrix->RotateSkew1;
350   d = matrix->ScaleY;
351 
352   xScale = sqrt (a * a + c * c);	/* always >= 0 */
353   if (a<0)
354    xScale *= -1;			/* preserve sign if needed */
355   yScale = (a * d - b * c) / xScale;
356   skew = (a * b + c * d) / (a * a + c * c);
357 
358   if (a == 0)
359     {
360       if (c < 0)
361 	angle = -90;
362       else
363 	angle = 90;
364     }
365   else
366     {
367       angle = atan (c / a) * 180 / M_PI;
368 
369       if (a < 0)
370 	{
371 	  if (angle < 0)
372 	    angle += 180;
373 	  else
374 	    angle -= 180;
375 	}
376     }
377 
378 #define TOLERANCE 0.02
379 
380   if (skew < -TOLERANCE || skew > TOLERANCE)
381     printf ("%s(%f);\n", methodcall (fname, "skewXTo"), skew);
382 
383   if (matrix->HasScale)
384   {
385   if (xScale > 1.0 - TOLERANCE && xScale < 1.0 + TOLERANCE)
386     xScale = 1.0;
387 
388   if (yScale > 1.0 - TOLERANCE && yScale < 1.0 + TOLERANCE)
389     yScale = 1.0;
390 
391   if (xScale != 1.0 || yScale != 1.0)
392     {
393       if (xScale == yScale)
394 	printf ("%s(%f);\n", methodcall (fname, "scaleTo"), xScale);
395       else
396 	printf ("%s(%f, %f);\n", methodcall (fname, "scaleTo"), xScale,
397 		yScale);
398     }
399   }
400 
401   if (matrix->HasRotate)
402    if (angle < -TOLERANCE || angle > TOLERANCE)
403     printf ("%s(%f);\n", methodcall (fname, "rotateTo"), angle);
404 
405   if (matrix->TranslateX != 0 || matrix->TranslateY != 0)
406     printf ("%s(%ld, %ld);\n", methodcall (fname, "moveTo"),
407 	    matrix->TranslateX, matrix->TranslateY);
408 }
409 
410 static void
prepareSWF_MATRIX(SWF_MATRIX * matrix,SWF_RECT * shapeBounds)411 prepareSWF_MATRIX (SWF_MATRIX * matrix, SWF_RECT *shapeBounds)
412 {
413  if (shapeBounds)
414   if (shapeBounds->Xmax-shapeBounds->Xmin && shapeBounds->Ymax-shapeBounds->Ymin)
415   {
416    matrix->ScaleX*=(32768.0/(shapeBounds->Xmax-shapeBounds->Xmin));
417    matrix->ScaleY*=(32768.0/(shapeBounds->Ymax-shapeBounds->Ymin));
418    matrix->RotateSkew1*=(32768.0/(shapeBounds->Xmax-shapeBounds->Xmin));
419    matrix->RotateSkew0*=(32768.0/(shapeBounds->Ymax-shapeBounds->Ymin));
420    matrix->TranslateX = (long)(matrix->TranslateX*32768) / (long)(shapeBounds->Xmax-shapeBounds->Xmin) - 16384;
421    matrix->TranslateY = (long)(matrix->TranslateY*32768) / (long)(shapeBounds->Ymax-shapeBounds->Ymin) - 16384;
422   }
423 }
424 
425 static void
outputSWF_CXFORMWITHALPHA(SWF_CXFORMWITHALPHA * cxform,char * name)426 outputSWF_CXFORMWITHALPHA(SWF_CXFORMWITHALPHA * cxform, char *name)
427 {
428  if (cxform->HasMultTerms)
429  {
430   printf("%s" ARGSTART "%0.2f" ARGSEP "%0.2f" ARGSEP "%0.2f" ARGSEP "%0.2f" ARGEND STMNTEND "\n",
431     methodcall (name, "multColor"), cxform->RedMultTerm/256.0,
432     cxform->GreenMultTerm/256.0, cxform->BlueMultTerm/256.0, cxform->AlphaMultTerm/256.0);
433  }
434  if (cxform->HasAddTerms)
435  {
436   printf("%s" ARGSTART "%ld" ARGSEP "%ld" ARGSEP "%ld" ARGSEP "%ld" ARGEND STMNTEND "\n",
437     methodcall (name, "addColor"),  cxform->RedAddTerm,
438     cxform->GreenAddTerm, cxform->BlueAddTerm, cxform->AlphaAddTerm);
439  }
440 }
441 
442 static char*
getButtonCondString(SWF_BUTTONCONDACTION * flags)443 getButtonCondString(SWF_BUTTONCONDACTION *flags)
444 {
445   if ( flags->CondOverUpToOverDown ) return ("SWFBUTTON_MOUSEDOWN");
446   if ( flags->CondOverDownToOverUp ) return ("SWFBUTTON_MOUSEUP");
447   if ( flags->CondIdleToOverUp )     return ("SWFBUTTON_MOUSEOVER");
448   if ( flags->CondOverUpToIdle )     return ("SWFBUTTON_MOUSEOUT");
449   if ( flags->CondIdleToOverDown )   return ("SWFBUTTON_DRAGOVER");
450   if ( flags->CondOutDownToOverDown) return ("SWFBUTTON_DRAGOVER");
451   if ( flags->CondOutDownToIdle )    return ("SWFBUTTON_MOUSEUPOUTSIDE");
452   if ( flags->CondOverDownToIdle )   return ("SWFBUTTON_DRAGOUT");
453   return "unknown_flag";
454 }
455 
456 static char*
getEventString(SWF_CLIPEVENTFLAGS * clipevflags)457 getEventString(SWF_CLIPEVENTFLAGS *clipevflags)
458 {
459   if ( clipevflags->ClipEventKeyUp ) return ("SWFACTION_KEYUP");
460   if ( clipevflags->ClipEventKeyDown ) return ("SWFACTION_KEYDOWN");
461   if ( clipevflags->ClipEventMouseUp ) return ("SWFACTION_MOUSEUP");
462   if ( clipevflags->ClipEventMouseDown ) return ("SWFACTION_MOUSEDOWN");
463   if ( clipevflags->ClipEventMouseMove ) return ("SWFACTION_MOUSEMOVE");
464   if ( clipevflags->ClipEventUnload ) return ("SWFACTION_UNLOAD");
465   if ( clipevflags->ClipEventEnterFrame ) return ("SWFACTION_ENTERFRAME");
466   if ( clipevflags->ClipEventLoad ) return ("SWFACTION_ONLOAD");
467   if ( clipevflags->ClipEventDragOver ) return ("SWFACTION_DRAGOVER");
468   if ( clipevflags->ClipEventRollOut ) return ("SWFACTION_ROLLOUT");
469   if ( clipevflags->ClipEventRollOver ) return ("SWFACTION_ROLLOVER");
470   if ( clipevflags->ClipEventReleaseOutside ) return ("SWFACTION_RELEASEOUTSIDE");
471   if ( clipevflags->ClipEventRelease ) return ("SWFACTION_RELEASE");
472   if ( clipevflags->ClipEventPress ) return ("SWFACTION_PRESS");
473   if ( clipevflags->ClipEventInitialize ) return ("SWFACTION_INIT");
474   if ( clipevflags->ClipEventData ) return ("SWFACTION_DATA");
475   if ( clipevflags->ClipEventConstruct ) return ("SWFACTION_CONSTRUCT");
476   if ( clipevflags->ClipEventKeyPress ) return ("SWFACTION_KEYPRESS");
477   if ( clipevflags->ClipEventDragOut ) return ("SWFACTION_DRAGOUT");
478   return "unknown_flag";
479 }
480 
481 void
outputSWF_CLIPACTIONS(SWF_CLIPACTIONS * clipactions,char * sname)482 outputSWF_CLIPACTIONS (SWF_CLIPACTIONS * clipactions, char *sname)
483 {
484   int i;
485 /*  printf( COMMSTART " %d clip actions " COMMEND "\n", clipactions->NumClipRecords );*/
486   for (i = 0; i < clipactions->NumClipRecords-1 ; i++)
487   {
488     printf ("%s(%s(\"%s\"),%s);\n\n", methodcall (sname, "addAction"), newobj (NULL, "Action"),
489 	decompile5Action(clipactions->ClipActionRecords[i].numActions,
490 	clipactions->ClipActionRecords[i].Actions, 0),
491 	getEventString( &clipactions->ClipActionRecords[i].EventFlag)
492   );
493  }
494 }
495 
496 void
outputSWF_GRADIENT(SWF_GRADIENT * gradient,char * gname)497 outputSWF_GRADIENT (SWF_GRADIENT * gradient, char *gname)
498 {
499   int i;
500   printf ("%s();\n", newobj (gname, "Gradient"));
501   for (i = 0; i < gradient->NumGradients; i++)
502     printf ("%s(%f,0x%2.2x,0x%2.2x,0x%2.2x,0x%2.2x);\n",
503 	    methodcall (gname, "addEntry"),
504 	    (gradient->GradientRecords[i].Ratio / 255.0),
505 	    gradient->GradientRecords[i].Color.red,
506 	    gradient->GradientRecords[i].Color.green,
507 	    gradient->GradientRecords[i].Color.blue,
508 	    gradient->GradientRecords[i].Color.alpha);
509 }
510 
511 void
outputSWF_FILLSTYLE_new(SWF_FILLSTYLE * fillstyle,char * parentname,int i,SWF_RECT * shapeBounds)512 outputSWF_FILLSTYLE_new (SWF_FILLSTYLE * fillstyle, char *parentname, int i, SWF_RECT *shapeBounds)
513 {
514   char fname[64];
515   char gname[64];
516   const char* fillTypeName = NULL;
517   int do_declare;
518 
519   sprintf (fname, "%s_f%d", parentname, i);
520   do_declare = !search_var(fname);
521 
522   switch (fillstyle->FillStyleType)
523     {
524     case 0x00:			/* Solid Fill */
525       outputSWF_RGBA (&fillstyle->Color, fname);
526       if (do_declare)
527         printf ("" DECLOBJ(Fill) " ");
528       printf ("%s = %s(" VAR "%s_red, "
529 	      VAR "%s_green, "
530 	      VAR "%s_blue, "
531 	      VAR "%s_alpha "
532 	      "); " COMMSTART "SWFFILL_SOLID" COMMEND "\n",
533 	      fname,
534 	      methodcall (parentname, "addSolidFill"), fname, fname, fname, fname);
535       break;
536     case 0x10:			/* Linear Gradient Fill */
537       sprintf (gname, "%s_g%d", parentname, i);
538       outputSWF_GRADIENT (&fillstyle->Gradient, gname);
539       if (do_declare)
540         printf ("" DECLOBJ(Fill) " ");
541       printf ("%s = %s(" VAR "%s,SWFFILL_LINEAR_GRADIENT);\n",
542 	      fname, methodcall (parentname, "addGradientFill"), gname);
543       if (shapeBounds)
544         prepareSWF_MATRIX(&fillstyle->GradientMatrix, shapeBounds);
545       outputSWF_MATRIX (&fillstyle->GradientMatrix, fname);
546       break;
547     case 0x12:			/* Radial Gradient Fill */
548       sprintf (gname, "%s_g%d", parentname, i);
549       outputSWF_GRADIENT (&fillstyle->Gradient, gname);
550       if (do_declare)
551         printf ("" DECLOBJ(Fill) " ");
552       printf ("%s = %s(" VAR "%s,SWFFILL_RADIAL_GRADIENT);\n",
553 	      fname, methodcall (parentname, "addGradientFill"), gname);
554       if (shapeBounds)
555         prepareSWF_MATRIX(&fillstyle->GradientMatrix, shapeBounds);
556       outputSWF_MATRIX (&fillstyle->GradientMatrix, fname);
557       break;
558 
559     case 0x40:			/* Repeating Bitmap Fill */
560              fillTypeName = "SWFFILL_TILED_BITMAP";
561     case 0x41:			/* Clipped Bitmap Fill */
562       if ( ! fillTypeName )
563              fillTypeName = "SWFFILL_CLIPPED_BITMAP";
564     case 0x42:			/* Non-smoothed Repeating Bitmap Fill */
565       if ( ! fillTypeName )
566              fillTypeName = "SWFFILL_NONSMOOTHED_TILED_BITMAP";
567     case 0x43:			/* Non-smoothed Clipped Bitmap Fill */
568       if ( ! fillTypeName )
569              fillTypeName = "SWFFILL_NONSMOOTHED_CLIPPED_BITMAP";
570       /*
571        * TODO:
572        *  - specially handle a CharacterID of 65535 (it occurs!)
573        */
574       printf (COMMSTART " BitmapID: %d " COMMEND "\n", fillstyle->BitmapId);
575       sprintf (gname, "character%d", fillstyle->BitmapId);
576       if (do_declare)
577         printf ("" DECLOBJ(Fill) " ");
578       printf ("%s = %s(" VAR "%s,%s);\n",
579 	      fname, methodcall (parentname, "addBitmapFill"),
580               gname, fillTypeName);
581       outputSWF_MATRIX (&fillstyle->BitmapMatrix, fname);
582       break;
583   }
584 }
585 
586 void
outputSWF_FILLSTYLEARRAY_new(SWF_FILLSTYLEARRAY * fillstylearray,char * parentname,SWF_RECT * shapeBounds)587 outputSWF_FILLSTYLEARRAY_new (SWF_FILLSTYLEARRAY * fillstylearray,
588 			  char *parentname,SWF_RECT *shapeBounds)
589 {
590   int i, count;
591 
592   count = (fillstylearray->FillStyleCount != 0xff) ?
593     fillstylearray->FillStyleCount : fillstylearray->FillStyleCountExtended;
594 
595   printf ("" COMMSTART "%d fillstyle(s)" COMMEND "\n", count);
596 
597   for (i = 0; i < count; i++)
598     {
599       outputSWF_FILLSTYLE_new (&(fillstylearray->FillStyles[i]), parentname, i,shapeBounds);
600     }
601 }
602 
603 void
outputSWF_LINESTYLE(SWF_LINESTYLE * linestyle,char * parentname,int i)604 outputSWF_LINESTYLE (SWF_LINESTYLE * linestyle, char *parentname, int i)
605 {
606   char lname[64], varname[256];
607   sprintf (lname, "%s_l%d", parentname, i);
608   sprintf (varname, "%s_l%d_width", parentname, i);
609 #ifdef SWFPLUSPLUS
610   if (!search_var(varname))
611     printf ("int %s = %d;\n", varname, linestyle->Width);
612   else
613     printf ("%s = %d;\n", varname, linestyle->Width);
614 #else
615   printf ("" VAR "%s = %d;\n", varname, linestyle->Width);
616 #endif
617 
618   outputSWF_RGBA (&linestyle->Color, lname);
619 
620 }
621 
622 void
outputSWF_LINESTYLE2(SWF_LINESTYLE2 * linestyle,char * parentname,int i)623 outputSWF_LINESTYLE2 (SWF_LINESTYLE2 * linestyle, char *parentname, int i)
624 {
625   char lname[64], varname[256];
626   sprintf (lname, "%s_l%d", parentname, i);
627   sprintf (varname, "%s_l%d_width", parentname, i);
628 #ifdef SWFPLUSPLUS
629   if (!search_var(varname))
630     printf ("int %s = %d;\n", varname, linestyle->Width);
631   else
632     printf ("%s = %d;\n", varname, linestyle->Width);
633 #else
634   printf ("" VAR "%s = %d;\n", varname, linestyle->Width);
635 #endif
636 
637   /* TODO: use also all the other fields (styles) */
638   printf (COMMSTART "Style information not output" COMMEND "\n");
639 
640   outputSWF_RGBA (&linestyle->Color, lname);
641 
642 }
643 
644 void
outputSWF_LINESTYLEARRAY(SWF_LINESTYLEARRAY * linestylearray,char * parentname)645 outputSWF_LINESTYLEARRAY (SWF_LINESTYLEARRAY * linestylearray,
646 			  char *parentname)
647 {
648   int i, count;
649 
650   count = linestylearray->LineStyleCount;
651 
652   printf ("" COMMSTART "%d linestyles(s)" COMMEND "\n", count);
653   for (i = 0; i < count; i++)
654   {
655     if(linestylearray->LineStyles != NULL)
656       outputSWF_LINESTYLE (&(linestylearray->LineStyles[i]), parentname, i);
657     else if(linestylearray->LineStyles2 != NULL)
658       outputSWF_LINESTYLE2 (&(linestylearray->LineStyles2[i]), parentname, i);
659     else
660       printf ("" COMMSTART "Unknown linestyle %d (parser error?)" COMMEND "\n", i);
661   }
662 }
663 
664 void
outputSWF_SHAPERECORD(SWF_SHAPERECORD * shaperec,char * parentname)665 outputSWF_SHAPERECORD (SWF_SHAPERECORD * shaperec, char *parentname)
666 {
667   if (shaperec->EndShape.TypeFlag)
668     {
669       /* An Edge Record */
670       if (shaperec->StraightEdge.StraightEdge == 1)
671 	{
672 	  /* A Straight Edge Record */
673 	  if (shaperec->StraightEdge.GeneralLineFlag)
674 	    {
675 	      /* The general case */
676 	      printf ("%s(%ld, %ld);\n", methodcall (parentname, "drawLine"),
677 		      shaperec->StraightEdge.DeltaX,
678 		      shaperec->StraightEdge.DeltaY);
679 	    }
680 	  else
681 	    {
682 	      /* The Horizontal or Verticle case */
683 	      printf ("%s(%ld, %ld);\n", methodcall (parentname, "drawLine"),
684 		      shaperec->StraightEdge.VLDeltaX,
685 		      shaperec->StraightEdge.VLDeltaY);
686 	    }
687 	}
688       else
689 	{
690 	  /* A Curved Edge Record */
691 	  printf ("%s(%ld, %ld, %ld, %ld);\n",
692 		  methodcall (parentname, "drawCurve"),
693 		  shaperec->CurvedEdge.ControlDeltaX,
694 		  shaperec->CurvedEdge.ControlDeltaY,
695 		  shaperec->CurvedEdge.AnchorDeltaX,
696 		  shaperec->CurvedEdge.AnchorDeltaY);
697 	}
698     }
699   else
700     {
701       /* A Non-Edge Record */
702       if (shaperec->EndShape.EndOfShape == 0)
703 	{
704 	  return;
705 	}
706       if (shaperec->StyleChange.StateNewStyles)
707       {
708 	 /* output new style changes before using */
709 	 printf (COMMSTART "Some styles are CHANGED now:" COMMEND "\n");
710 	 outputSWF_LINESTYLEARRAY (&(shaperec->StyleChange.LineStyles), parentname);
711 	 outputSWF_FILLSTYLEARRAY_new (&(shaperec->StyleChange.FillStyles), parentname,NULL);
712       }
713       if (shaperec->StyleChange.StateLineStyle)
714 	{
715 	  printf (COMMSTART " StateLineStyle: %ld " COMMEND "\n", shaperec->StyleChange.LineStyle);
716 	  if (shaperec->StyleChange.LineStyle == 0)
717 	    {
718 	      printf ("%s(0,0,0,0,0);\n", methodcall (parentname, "setLine"));
719 	    }
720 	  else
721 	    {
722 	      /*
723 	       * We use the variable names that were output by
724 	       * outputSWF_LINESTYLE()
725 	       */
726 	      printf ("%s(" VAR "%s_l%ld_width, " VAR "%s_l%ld_red, "
727 		      VAR "%s_l%ld_green, " VAR "%s_l%ld_blue, "
728 		      VAR "%s_l%ld_alpha);\n",
729 		      methodcall (parentname, "setLine"),
730 		      parentname, shaperec->StyleChange.LineStyle - 1,
731 		      parentname, shaperec->StyleChange.LineStyle - 1,
732 		      parentname, shaperec->StyleChange.LineStyle - 1,
733 		      parentname, shaperec->StyleChange.LineStyle - 1,
734 		      parentname, shaperec->StyleChange.LineStyle - 1);
735 	    }
736 	}
737       if (shaperec->StyleChange.StateFillStyle1 && shaperec->StyleChange.FillStyle1)
738 	{
739 	  printf ("%s(", methodcall (parentname, "setRightFill"));
740 	  if (shaperec->StyleChange.FillStyle1)
741 	    {
742 	      printf (VAR "%s_f%ld", parentname,shaperec->StyleChange.FillStyle1 - 1);
743 	    }
744 	  printf (");\n");
745 	}
746       if (shaperec->StyleChange.StateFillStyle0 && shaperec->StyleChange.FillStyle0)
747 	{
748 	  printf ("%s(", methodcall (parentname, "setLeftFill"));
749 	  if (shaperec->StyleChange.FillStyle0)
750 	    {
751 	      printf (VAR "%s_f%ld", parentname,shaperec->StyleChange.FillStyle0 - 1);
752 	    }
753 	  printf (");\n");
754 	}
755       if (shaperec->StyleChange.StateMoveTo)
756 	{
757 	  printf ("%s(%ld, %ld);\n", methodcall (parentname, "movePenTo"),
758 		  shaperec->StyleChange.MoveDeltaX,
759 		  shaperec->StyleChange.MoveDeltaY);
760 	}
761     }
762 
763 }
764 
765 void
outputSWF_SHAPE(SWF_SHAPE * shape,char * name)766 outputSWF_SHAPE (SWF_SHAPE * shape, char *name)
767 {
768   int i;
769   for (i = 0; i < shape->NumShapeRecords; i++)
770     {
771       outputSWF_SHAPERECORD (&(shape->ShapeRecords[i]), name);
772     }
773 }
774 
775 void
outputSWF_SHAPEWITHSTYLE_new(SWF_SHAPEWITHSTYLE * shape,int level,char * name,SWF_RECT * shapeBounds)776 outputSWF_SHAPEWITHSTYLE_new (SWF_SHAPEWITHSTYLE * shape, int level, char *name, SWF_RECT *shapeBounds )
777 {
778   int i;
779   outputSWF_FILLSTYLEARRAY_new (&(shape->FillStyles), name, shapeBounds);
780   outputSWF_LINESTYLEARRAY (&(shape->LineStyles), name);
781   for (i = 0; i < shape->NumShapeRecords; i++)
782     {
783       outputSWF_SHAPERECORD (&(shape->ShapeRecords[i]), name);
784     }
785 }
786 
787 /* Output Flash Blocks */
788 void
outputSWF_CHARACTERSET(SWF_Parserstruct * pblock)789 outputSWF_CHARACTERSET (SWF_Parserstruct * pblock)
790 {
791   OUT_BEGIN_EMPTY (SWF_CHARACTERSET);
792 
793 }
794 
795 void
outputSWF_DEFINEBITS(SWF_Parserstruct * pblock)796 outputSWF_DEFINEBITS (SWF_Parserstruct * pblock)
797 {
798   char name[32];
799 
800   /* TODO: use JPEGData and JPEGDataSize to actually include content. dump to a file maybe */
801 
802   OUT_BEGIN (SWF_DEFINEBITS);
803 
804   sprintf (name, "character%d", sblock->CharacterID);
805   printf ("\n" COMMSTART " Bitmap %d (bits). To extract: " COMMEND "\n",
806     sblock->CharacterID);
807   printf (COMMSTART " swfextract -j %d -o %s.jpg $swf " COMMEND "\n",
808     sblock->CharacterID, name);
809   printf ("%s('%s.jpg');\n", newobj (name, "Bitmap"), name);
810 
811 }
812 
813 void
outputSWF_DEFINEBITSJPEG2(SWF_Parserstruct * pblock)814 outputSWF_DEFINEBITSJPEG2 (SWF_Parserstruct * pblock)
815 {
816   char name[32];
817 
818   /* TODO: use JPEGData and JPEGDataSize to actually include content. dump to a file maybe */
819 
820   OUT_BEGIN (SWF_DEFINEBITSJPEG2);
821 
822   sprintf (name, "character%d", sblock->CharacterID);
823   printf ("\n" COMMSTART " Bitmap %d (jpeg2). To extract: " COMMEND "\n",
824     sblock->CharacterID);
825   printf (COMMSTART " swfextract -j %d -o %s.jpg $swf " COMMEND "\n",
826     sblock->CharacterID, name);
827   printf ("%s('%s.jpg');\n", newobj (name, "Bitmap"), name);
828 
829 }
830 
831 void
outputSWF_DEFINEBITSJPEG3(SWF_Parserstruct * pblock)832 outputSWF_DEFINEBITSJPEG3 (SWF_Parserstruct * pblock)
833 {
834   char name[32];
835 
836   /* TODO: use JPEGData and JPEGDataSize to actually include content. dump to a file maybe */
837 
838   OUT_BEGIN (SWF_DEFINEBITSJPEG3);
839 
840   sprintf (name, "character%d", sblock->CharacterID);
841   printf ("\n" COMMSTART " Bitmap %d (jpeg3). To extract: " COMMEND "\n",
842     sblock->CharacterID);
843   printf (COMMSTART " swfextract -j %d -o %s.jpg $swf " COMMEND "\n",
844     sblock->CharacterID, name);
845   printf ("%s('%s.jpg');\n", newobj (name, "Bitmap"), name);
846 }
847 
848 void
outputSWF_DEFINEBITSPTR(SWF_Parserstruct * pblock)849 outputSWF_DEFINEBITSPTR (SWF_Parserstruct * pblock)
850 {
851   OUT_BEGIN_EMPTY (SWF_DEFINEBITSPTR);
852 
853 }
854 
855 
856 void
outputSWF_BUTTONRECORD(SWF_BUTTONRECORD * brec,char * bname)857 outputSWF_BUTTONRECORD( SWF_BUTTONRECORD *brec, char *bname)
858 {
859   int notFirst = 0;
860   char cname[64];
861   char brname[64];
862   //char buttonstates[64];
863 
864   OUT_BEGIN_EMPTY (SWF_BUTTONRECORD);
865 
866   sprintf(cname, "character%d", brec->CharacterId);
867   sprintf(brname, "%sbr%d", bname, brec->PlaceDepth);
868 
869   //printf ("%s(" VAR "%s,", methodcall(bname, "addCharacter"), cname);
870   if (!search_var(brname))
871     printf (DECLOBJ(ButtonRecord) " ");
872   printf ("%s = %s(" VAR "%s,",
873         brname, methodcall(bname, "addCharacter"), cname);
874 
875   if (brec->ButtonStateHitTest)
876   {
877     if (notFirst)
878       printf(" | ");
879     printf("SWFBUTTON_HIT");
880     notFirst = 1;
881   }
882   if (brec->ButtonStateDown)
883   {
884     if (notFirst)
885       printf(" | ");
886     printf("SWFBUTTON_DOWN");
887     notFirst = 1;
888   }
889   if (brec->ButtonStateOver)
890   {
891     if (notFirst)
892       printf(" | ");
893     printf("SWFBUTTON_OVER");
894     notFirst = 1;
895   }
896   if (brec->ButtonStateUp)
897   {
898     if (notFirst)
899       printf(" | ");
900     printf("SWFBUTTON_UP");
901     notFirst = 1;
902   }
903   printf (")"STMNTEND"\n");
904 
905   // ButtonRecord uses same transformation function names as DisplayItem, so this should work.
906   outputSWF_MATRIX(&brec->PlaceMatrix, brname);
907 }
908 
909 void
outputSWF_DEFINEBUTTON(SWF_Parserstruct * pblock)910 outputSWF_DEFINEBUTTON (SWF_Parserstruct * pblock)
911 {
912   OUT_BEGIN_EMPTY (SWF_DEFINEBUTTON);
913 
914 }
915 
916 void
outputSWF_DEFINEBUTTON2(SWF_Parserstruct * pblock)917 outputSWF_DEFINEBUTTON2 (SWF_Parserstruct * pblock)
918 {
919   int i;
920   char bname[64];
921   OUT_BEGIN (SWF_DEFINEBUTTON2);
922 
923   sprintf (bname, "character%d", sblock->Buttonid);
924   printf ("%s()"STMNTEND"\n", newobj (bname, "Button"));
925   for(i=0;i < sblock->numCharacters;i++)
926   {
927     outputSWF_BUTTONRECORD( &(sblock->Characters[i]), bname );
928   }
929   for(i=0;i < sblock->numActions;i++)
930   {
931     printf ("%s(%s(\"%s\"),%s);\n\n", methodcall (bname, "addAction"), newobj (NULL, "Action"),
932 	decompile5Action(sblock->Actions[i].numActions, sblock->Actions[i].Actions,0),
933 	getButtonCondString(&sblock->Actions[i]) );
934   }
935 }
936 
937 
938 void
outputSWF_DEFINEBUTTONCXFORM(SWF_Parserstruct * pblock)939 outputSWF_DEFINEBUTTONCXFORM (SWF_Parserstruct * pblock)
940 {
941   OUT_BEGIN_EMPTY (SWF_DEFINEBUTTONCXFORM);
942 
943 }
944 
945 void
outputSWF_DEFINEBUTTONSOUND(SWF_Parserstruct * pblock)946 outputSWF_DEFINEBUTTONSOUND (SWF_Parserstruct * pblock)
947 {
948   char bname[64];
949   char sname[64];
950   OUT_BEGIN (SWF_DEFINEBUTTONSOUND);
951   sprintf (bname, "character%d", sblock->CharacterID);
952 
953   if (sblock->ButtonSoundChar0)
954   {
955    sprintf (sname, VAR "character%d", sblock->ButtonSoundChar0);
956    printf ("%s(%s,%s);\n\n", methodcall (bname, "addSound"), sname, "SWFBUTTON_MOUSEOUT");
957   }
958   if (sblock->ButtonSoundChar1)
959   {
960    sprintf (sname, VAR "character%d", sblock->ButtonSoundChar1);
961    printf ("%s(%s,%s);\n\n", methodcall (bname, "addSound"), sname, "SWFBUTTON_MOUSEOVER");
962   }
963   if (sblock->ButtonSoundChar2)
964   {
965    sprintf (sname, VAR "character%d", sblock->ButtonSoundChar2);
966    printf ("%s(%s,%s);\n\n", methodcall (bname, "addSound"), sname, "SWFBUTTON_MOUSEDOWN");
967   }
968   if (sblock->ButtonSoundChar3)
969   {
970    sprintf (sname, VAR "character%d", sblock->ButtonSoundChar3);
971    printf ("%s(%s,%s);\n\n", methodcall (bname, "addSound"), sname, "SWFBUTTON_MOUSEUP");
972   }
973   /* todo proc soundinstance */
974 }
975 
976 void
outputSWF_DEFINECOMMANDOBJ(SWF_Parserstruct * pblock)977 outputSWF_DEFINECOMMANDOBJ (SWF_Parserstruct * pblock)
978 {
979   OUT_BEGIN_EMPTY (SWF_DEFINECOMMANDOBJ);
980 
981 }
982 
983 void
outputSWF_DEFINEEDITTEXT(SWF_Parserstruct * pblock)984 outputSWF_DEFINEEDITTEXT (SWF_Parserstruct * pblock)
985 {
986   struct FONTINFO *fi=fip;
987   int notFirst = 0;
988   char tname[64];
989   OUT_BEGIN (SWF_DEFINEEDITTEXT);
990 
991   sprintf (tname, "character%d", sblock->CharacterID);
992   printf ("%s();\n", newobj (tname, "TextField"));
993 
994   printf ("%s(", methodcall (tname, "setFlags"));
995   if (sblock->WordWrap)
996     {
997       printf ("SWFTEXTFIELD_WORDWRAP");
998       notFirst = 1;
999     }
1000   if (sblock->Multiline)
1001     {
1002       if (notFirst)
1003 	printf (" | ");
1004       printf ("SWFTEXTFIELD_MULTILINE");
1005       notFirst = 1;
1006     }
1007   if (sblock->Password)
1008     {
1009       if (notFirst)
1010 	printf (" | ");
1011       printf ("SWFTEXTFIELD_PASSWORD");
1012       notFirst = 1;
1013     }
1014   if (sblock->ReadOnly)
1015     {
1016       if (notFirst)
1017 	printf (" | ");
1018       printf ("SWFTEXTFIELD_NOEDIT");
1019       notFirst = 1;
1020     }
1021 /* handled by setLength later on
1022   if (sblock->HasMaxLength)
1023     {
1024       if (notFirst)
1025 	printf (" | ");
1026       printf ("SWFTEXTFIELD_HASLENGTH");
1027       notFirst = 1;
1028     }
1029 */
1030   if (sblock->AutoSize)
1031     {
1032       if (notFirst)
1033 	printf (" | ");
1034       printf ("SWFTEXTFIELD_AUTOSIZE");
1035       notFirst = 1;
1036     }
1037 /*
1038 if( sblock->HasLayout ) {
1039 	if( notFirst ) printf("|");
1040 	printf("SWFTEXTFIELD_HASLAYOUT");
1041 	notFirst=1;
1042 }
1043 */
1044   if (sblock->NoSelect)
1045     {
1046       if (notFirst)
1047 	printf (" | ");
1048       printf ("SWFTEXTFIELD_NOSELECT");
1049       notFirst = 1;
1050     }
1051   if (sblock->Border)
1052     {
1053       if (notFirst)
1054 	printf (" | ");
1055       printf ("SWFTEXTFIELD_DRAWBOX");
1056       notFirst = 1;
1057     }
1058   if (sblock->HTML)
1059     {
1060       if (notFirst)
1061 	printf (" | ");
1062       printf ("SWFTEXTFIELD_HTML");
1063       notFirst = 1;
1064     }
1065   printf (");\n");
1066 
1067   printf ("%s(%ld, %ld);\n", methodcall (tname, "setBounds"),
1068 	  sblock->Bounds.Xmax, sblock->Bounds.Ymax);
1069   if (sblock->HasFont)
1070     {
1071       printf ("%s(" VAR "f%d);\n", methodcall (tname, "setFont"),
1072 	      sblock->FontID);
1073       printf ("%s(%d);\n", methodcall (tname, "setHeight"),
1074 	      sblock->FontHeight);
1075       while (fi)
1076       {
1077        int i;
1078        if (fi->fontcodeID==sblock->FontID)
1079        {
1080         printf ("%s(" SQ , methodcall (tname, "addChars"));
1081         for(i=0;i<fi->fontcodearrsize;i++)
1082         {
1083 #ifdef SWFPERL
1084          if (fi->fontcodeptr[i]=='\'' || fi->fontcodeptr[i]=='\\' || fi->fontcodeptr[i]=='@' || fi->fontcodeptr[i]=='%' )
1085           printf ("\\");
1086 #endif
1087 #if defined(SWFPHP) || defined(SWFPYTHON)
1088          if (fi->fontcodeptr[i]=='\'' || fi->fontcodeptr[i]=='\\')
1089           printf ("\\");
1090 #endif
1091          if (fi->fontcodeptr[i]<256)
1092           printf ("%c",fi->fontcodeptr[i]);
1093         }
1094         printf (SQ ");\n" );
1095         break;
1096        }
1097        else
1098         fi=fi->next;
1099       }
1100     }
1101   if (sblock->HasTextColor)
1102     {
1103       printf ("%s(0x%02x, 0x%02x, 0x%02x, 0x%02x);\n",
1104 	      methodcall (tname, "setColor"),
1105 	      sblock->TextColor.red,
1106 	      sblock->TextColor.green,
1107 	      sblock->TextColor.blue, sblock->TextColor.alpha);
1108     }
1109   if (sblock->HasMaxLength)
1110     {
1111       printf ("%s(%d);\n", methodcall (tname, "setLength"),
1112 	      sblock->MaxLength);
1113     }
1114   if (sblock->HasLayout)
1115     {
1116       printf ("%s(", methodcall (tname, "align"));
1117       switch (sblock->Align)
1118 	{
1119 	case 0:
1120 	  printf ("SWFTEXTFIELD_ALIGN_LEFT");
1121 	  break;
1122 	case 1:
1123 	  printf ("SWFTEXTFIELD_ALIGN_RIGHT");
1124 	  break;
1125 	case 2:
1126 	  printf ("SWFTEXTFIELD_ALIGN_CENTER");
1127 	  break;
1128 	case 3:
1129 	  printf ("SWFTEXTFIELD_ALIGN_JUSTIFY");
1130 	  break;
1131 	}
1132       printf (");\n");
1133       printf ("%s(%d);\n", methodcall (tname, "setLeftMargin"),
1134 	      sblock->LeftMargin);
1135       printf ("%s(%d);\n", methodcall (tname, "setRightMargin"),
1136 	      sblock->RightMargin);
1137       printf ("%s(%d);\n", methodcall (tname, "setIndentation"),
1138 	      sblock->Indent);
1139       printf ("%s(%d);\n", methodcall (tname, "setLineSpacing"),
1140 	      sblock->Leading);
1141     }
1142   printf ("%s('%s');\n", methodcall (tname, "setName"),
1143 	  sblock->VariableName);
1144   if (sblock->HasText)
1145     {
1146       printf ("%s('%s');\n", methodcall (tname, "addString"),
1147 	      sblock->InitialText);
1148     }
1149 
1150 }
1151 
1152 void
outputSWF_DEFINEFONT(SWF_Parserstruct * pblock)1153 outputSWF_DEFINEFONT (SWF_Parserstruct * pblock)
1154 {
1155   char fname[64];
1156   OUT_BEGIN (SWF_DEFINEFONT);
1157 
1158   sprintf (fname, "f%d", sblock->FontID);
1159 
1160   printf ("\n" COMMSTART " Font %d (%d glyps)." COMMEND "\n",
1161     sblock->FontID, sblock->NumGlyphs);
1162   printf ("%s(\"font%d.fdb\" );\n", newobj (fname, "Font"), sblock->FontID);
1163 }
1164 
1165 /* save important part for later usage in outputSWF_DEFINETEXT(), outputSWF_DEFINETEXT2() */
saveFontInfo(int id,int numglyph,int * codetable,UI16 * ct16)1166 static void saveFontInfo(int id,int numglyph,int *codetable,UI16 *ct16)
1167 {
1168   struct FONTINFO *fi=fip;
1169 
1170   if (!fi)
1171     fi=fip=fip_current=calloc(1,sizeof(struct FONTINFO));
1172   else
1173   {
1174    while (fi->next)
1175      fi=fi->next;
1176    fi->next=calloc(1,sizeof(struct FONTINFO));
1177    fi=fi->next;
1178   }
1179   if (fi)
1180   {
1181    if (NULL != (fi->fontcodeptr=malloc(numglyph * sizeof(int))))
1182    {
1183     int i;
1184     for (i=0;i<numglyph;i++)
1185     {
1186      fi->fontcodeptr[i]=codetable ? codetable[i] : ct16[i];
1187     }
1188     fi->fontcodearrsize=numglyph;
1189     fi->fontcodeID=id;
1190     printf (COMMSTART " init font %d code table" COMMEND "\n",id);
1191    }
1192   }
1193 }
1194 
1195 
1196 void
outputSWF_DEFINEFONT2(SWF_Parserstruct * pblock)1197 outputSWF_DEFINEFONT2 (SWF_Parserstruct * pblock)
1198 {
1199   char fname[64];
1200   OUT_BEGIN (SWF_DEFINEFONT2);
1201 
1202   sprintf (fname, "f%d", sblock->FontID);
1203   if (sblock->FontFlagsHasLayout || sblock->NumGlyphs)
1204   {
1205    printf (COMMSTART " font name: %s" COMMEND "\n", sblock->FontName);
1206    printf ("%s(\"font%d.fdb\" );\n", newobj (fname, "Font"), sblock->FontID);
1207    saveFontInfo(sblock->FontID,sblock->NumGlyphs,sblock->CodeTable,NULL);
1208   }
1209   else
1210   {
1211    printf ("%s(\"%s\" );\n", newobj (fname, "BrowserFont"), sblock->FontName);
1212   }
1213 }
1214 
1215 void
outputSWF_DEFINEFONT3(SWF_Parserstruct * pblock)1216 outputSWF_DEFINEFONT3 (SWF_Parserstruct * pblock)
1217 {
1218   char fname[64];
1219   OUT_BEGIN (SWF_DEFINEFONT3);
1220 
1221   sprintf (fname, "f%d", sblock->FontID);
1222 
1223   if (sblock->FontFlagsHasLayout || sblock->NumGlyphs)
1224   {
1225    printf (COMMSTART " font name: %s" COMMEND "\n", sblock->FontName);
1226    printf ("%s(\"font%d.fdb\" );\n", newobj (fname, "Font"), sblock->FontID);
1227    saveFontInfo(sblock->FontID,sblock->NumGlyphs,NULL,sblock->CodeTable);
1228   }
1229   else
1230   {
1231    printf ("%s(\"%s\" );\n", newobj (fname, "BrowserFont"), sblock->FontName);
1232   }
1233 }
1234 
1235 void
outputSWF_DEFINEFONTINFO(SWF_Parserstruct * pblock)1236 outputSWF_DEFINEFONTINFO (SWF_Parserstruct * pblock)
1237 {
1238   char fname[64];
1239   OUT_BEGIN (SWF_DEFINEFONTINFO);
1240 
1241   sprintf (fname, "f%d", sblock->FontID);
1242   printf ("%s(\"%s.fdb\" );\n", newobj (fname, "Font"), sblock->FontName);
1243   saveFontInfo(sblock->FontID,sblock->nGlyph,NULL,sblock->CodeTable);
1244 }
1245 
1246 void
outputSWF_DEFINEFONTINFO2(SWF_Parserstruct * pblock)1247 outputSWF_DEFINEFONTINFO2(SWF_Parserstruct * pblock)
1248 {
1249   char fname[64];
1250   OUT_BEGIN (SWF_DEFINEFONTINFO2);
1251 
1252   sprintf (fname, "f%d", sblock->FontID);
1253   printf ("%s(\"%s.fdb\" );\n", newobj (fname, "Font"), sblock->FontName);
1254   saveFontInfo(sblock->FontID,sblock->nGlyph,NULL,sblock->CodeTable);
1255 }
1256 
1257 void
outputSWF_DEFINELOSSLESS(SWF_Parserstruct * pblock)1258 outputSWF_DEFINELOSSLESS (SWF_Parserstruct * pblock)
1259 {
1260   char name[32];
1261 
1262   OUT_BEGIN (SWF_DEFINELOSSLESS);
1263 
1264   sprintf (name, "character%d", sblock->CharacterID);
1265   printf ("\n" COMMSTART " Bitmap %d (lossless). To extract: " COMMEND "\n",
1266     sblock->CharacterID);
1267   printf (COMMSTART " swfextract -p %d -o %s.png $swf " COMMEND "\n",
1268     sblock->CharacterID, name);
1269   printf ("%s('%s.png');\n", newobj (name, "Bitmap"), name);
1270 
1271 }
1272 
1273 void
outputSWF_DEFINELOSSLESS2(SWF_Parserstruct * pblock)1274 outputSWF_DEFINELOSSLESS2 (SWF_Parserstruct * pblock)
1275 {
1276   char name[32];
1277 
1278   OUT_BEGIN (SWF_DEFINELOSSLESS2);
1279 
1280   sprintf (name, "character%d", sblock->CharacterID);
1281   printf ("\n" COMMSTART " Bitmap %d (lossless2). To extract:" COMMEND "\n",
1282     sblock->CharacterID);
1283   printf (COMMSTART " swfextract -p %d -o %s.png $swf " COMMEND "\n",
1284     sblock->CharacterID, name);
1285   printf ("%s('%s.png');\n", newobj (name, "Bitmap"), name);
1286 }
1287 
1288 void
outputSWF_DEFINEMORPHSHAPE(SWF_Parserstruct * pblock)1289 outputSWF_DEFINEMORPHSHAPE (SWF_Parserstruct * pblock)
1290 {
1291   OUT_BEGIN_EMPTY (SWF_DEFINEMORPHSHAPE);
1292 
1293 }
1294 
1295 void
outputSWF_DEFINESHAPE(SWF_Parserstruct * pblock)1296 outputSWF_DEFINESHAPE (SWF_Parserstruct * pblock)
1297 {
1298   char name[32];
1299   OUT_BEGIN (SWF_DEFINESHAPE);
1300   sprintf (name, "character%d", sblock->ShapeID);
1301 
1302   printf ("\n" COMMSTART " Shape %d (TYPE=1, RECT=%d,%d %d,%d)" COMMEND "\n", sblock->ShapeID,
1303    (int)sblock->ShapeBounds.Xmin,(int)sblock->ShapeBounds.Xmax,(int)sblock->ShapeBounds.Ymin,(int)sblock->ShapeBounds.Ymax);
1304   printf ("%s();\n", newobj (name, "Shape"));
1305   /* There doesn't seem to be a way to use this in the API
1306    * it is calculated internal to teh shape object, but I'm not
1307    * sure it will come up with the same answer.
1308    outputSWF_RECT(&sblock->ShapeBounds);
1309    */
1310   outputSWF_SHAPEWITHSTYLE_new (&sblock->Shapes, 1, name, &sblock->ShapeBounds);
1311 }
1312 
1313 void
outputSWF_DEFINESHAPE2(SWF_Parserstruct * pblock)1314 outputSWF_DEFINESHAPE2 (SWF_Parserstruct * pblock)
1315 {
1316   char name[32];
1317   OUT_BEGIN (SWF_DEFINESHAPE2);
1318   sprintf (name, "character%d", sblock->ShapeID);
1319 
1320   printf ("\n" COMMSTART " Shape %d (TYPE=2, RECT=%d,%d %d,%d)" COMMEND "\n", sblock->ShapeID,
1321    (int)sblock->ShapeBounds.Xmin,(int)sblock->ShapeBounds.Xmax,(int)sblock->ShapeBounds.Ymin,(int)sblock->ShapeBounds.Ymax);
1322   printf ("%s();\n", newobj (name, "Shape"));
1323   /* There doesn't seem to be a way to use this in the API
1324    * it is calculated internal to teh shape object, but I'm not
1325    * sure it will come up with the same answer.
1326    outputSWF_RECT(&sblock->ShapeBounds);
1327    */
1328   outputSWF_SHAPEWITHSTYLE_new (&sblock->Shapes, 2, name, &sblock->ShapeBounds);
1329 }
1330 
1331 void
outputSWF_DEFINESHAPE3(SWF_Parserstruct * pblock)1332 outputSWF_DEFINESHAPE3 (SWF_Parserstruct * pblock)
1333 {
1334   char name[32];
1335   OUT_BEGIN (SWF_DEFINESHAPE3);
1336   sprintf (name, "character%d", sblock->ShapeID);
1337 
1338   printf ("\n" COMMSTART " Shape %d (TYPE=3, RECT=%d,%d %d,%d)" COMMEND "\n", sblock->ShapeID,
1339    (int)sblock->ShapeBounds.Xmin,(int)sblock->ShapeBounds.Xmax,(int)sblock->ShapeBounds.Ymin,(int)sblock->ShapeBounds.Ymax);
1340   printf ("%s();\n", newobj (name, "Shape"));
1341   /* There doesn't seem to be a way to use this in the API
1342    * it is calculated internal to teh shape object, but I'm not
1343    * sure it will come up with the same answer.
1344    outputSWF_RECT(&sblock->ShapeBounds);
1345    */
1346   outputSWF_SHAPEWITHSTYLE_new (&sblock->Shapes, 3, name, &sblock->ShapeBounds);
1347 
1348 }
1349 
1350 void
outputSWF_DEFINESHAPE4(SWF_Parserstruct * pblock)1351 outputSWF_DEFINESHAPE4 (SWF_Parserstruct * pblock)
1352 {
1353   char name[32];
1354   OUT_BEGIN (SWF_DEFINESHAPE4);
1355   sprintf (name, "character%d", sblock->ShapeID);
1356 
1357   printf ("\n" COMMSTART " Shape %d (TYPE=4, RECT=%d,%d %d,%d)" COMMEND "\n", sblock->ShapeID,
1358    (int)sblock->ShapeBounds.Xmin,(int)sblock->ShapeBounds.Xmax,(int)sblock->ShapeBounds.Ymin,(int)sblock->ShapeBounds.Ymax);
1359   printf ("%s();\n", newobj (name, "Shape"));
1360   /* There doesn't seem to be a way to use this in the API
1361    * it is calculated internal to teh shape object, but I'm not
1362    * sure it will come up with the same answer.
1363    outputSWF_RECT(&sblock->ShapeBounds);
1364    */
1365   outputSWF_SHAPEWITHSTYLE_new (&sblock->Shapes, 4, name, &sblock->ShapeBounds);
1366 
1367 }
1368 
1369 void
outputSWF_DEFINESOUND(SWF_Parserstruct * pblock)1370 outputSWF_DEFINESOUND (SWF_Parserstruct * pblock)
1371 {
1372   char sname[64];
1373   OUT_BEGIN (SWF_DEFINESOUND);
1374   sprintf (sname, "character%d", sblock->SoundId);
1375   printf ("%s(\"FIX_MY_PARAMS\")"STMNTEND"\n", newobj (sname, "Sound"));
1376 }
1377 
1378 void
outputSWF_DEFINESPRITE(SWF_Parserstruct * pblock)1379 outputSWF_DEFINESPRITE (SWF_Parserstruct * pblock)
1380 {
1381   int i;
1382   OUT_BEGIN (SWF_DEFINESPRITE);
1383 
1384   spritenum = sblock->SpriteId;
1385   spframenum = 1;
1386   sprintf(spritename,"character%d",sblock->SpriteId);
1387   printf ("\n\t" COMMSTART "  MovieClip %d " COMMEND "\n", sblock->SpriteId);
1388   printf ("%s(); " COMMSTART " %d frames " COMMEND "\n",
1389 		  newobj (spritename, "MovieClip"), sblock->FrameCount);
1390   for(i=0;i<sblock->BlockCount;i++) {
1391 	  outputBlock( sblock->tagTypes[i], sblock->Tags[i], NULL);
1392   }
1393   spritenum = 0;
1394 
1395 }
1396 
1397 static void
outputSWF_TEXT_RECORD(SWF_TEXTRECORD * trec,int level,char * tname,char * buffer,int bsize,int id)1398 outputSWF_TEXT_RECORD (SWF_TEXTRECORD *trec, int level,char *tname,char *buffer,int bsize,int id)
1399 {
1400   int i=0;
1401   struct FONTINFO *fi=fip;
1402   if ( trec->TextRecordType == 0 )
1403     return;
1404   if (trec->StyleFlagHasFont)
1405   {
1406    printf("%s(" VAR "f%d);\n", methodcall (tname, "setFont"), trec->FontID);
1407    printf("%s(%d);\n",methodcall(tname,"setHeight"),trec->TextHeight);
1408   }
1409   if( trec->StyleFlagHasColor )
1410   {
1411    if (level==2)
1412     printf ("%s(0x%02x, 0x%02x, 0x%02x, 0x%02x);\n",methodcall (tname, "setColor"),
1413       trec->TextColor.red,trec->TextColor.green,trec->TextColor.blue, trec->TextColor.alpha);
1414    else
1415     printf ("%s(0x%02x, 0x%02x, 0x%02x);\n",methodcall (tname, "setColor"),
1416       trec->TextColor.red,trec->TextColor.green,trec->TextColor.blue);
1417   }
1418   if( trec->StyleFlagHasYOffset || trec->StyleFlagHasXOffset )
1419   {
1420     printf ("%s(%d, %d);\n", methodcall (tname, "moveTo"),trec->XOffset,trec->YOffset);
1421   }
1422   if (trec->FontID)
1423   {
1424     id=trec->FontID;
1425   }
1426   if (!trec->StyleFlagHasFont)				/* always check flag before use data */
1427   {
1428    fi = fip_current;					/* so cont w current font */
1429    id = fi->fontcodeID;					/* trigger next if */
1430   }
1431   while (fi)
1432   {
1433    if (fi->fontcodeID==id)
1434    {
1435     fip_current=fi;					/* set current font */
1436     for(i=0;i<trec->GlyphCount && i<bsize-1 ;i++)	/* byte n-1 will be terminator '\0' */
1437     {
1438      int off=(&(trec->GlyphEntries[i]))->GlyphIndex[0];
1439      if (off<fi->fontcodearrsize)
1440       buffer[i]=fi->fontcodeptr[off];
1441      else
1442       buffer[i]='?';		/* fallback to dummy A */
1443      /* printf ( COMMSTART "GlyphIndex[0] = %d  char = %d " COMMEND"\n",off,fi->fontcodeptr[off] ); */
1444     }
1445     buffer[i]='\0';
1446     return;
1447    }
1448    else
1449     fi=fi->next;
1450   }
1451   buffer[0]='X';		/* fallback to dummy B */
1452   buffer[1]='\0';
1453 }
1454 
1455 void
outputSWF_DEFINETEXT(SWF_Parserstruct * pblock)1456 outputSWF_DEFINETEXT (SWF_Parserstruct * pblock)
1457 {
1458   int i,id=0;
1459   char name[32];
1460   char buffer[64];
1461   OUT_BEGIN (SWF_DEFINETEXT);
1462   sprintf (name, "character%d", sblock->CharacterID);
1463   printf ("%s(1);\n", newobj (name, "Text"));
1464   for(i=0;i<sblock->numTextRecords;i++)
1465   {
1466    if (!id && sblock->TextRecords[i].FontID)
1467      id=sblock->TextRecords[i].FontID;
1468    if ( sblock->TextRecords[i].TextRecordType  )
1469    {
1470      memset(buffer,0,64);
1471      outputSWF_TEXT_RECORD(&(sblock->TextRecords[i]), 1,name,buffer,64,id );
1472      printf ("%s(\"%s\");\n", methodcall (name, "addString"),buffer);
1473    }
1474   }
1475 }
1476 
1477 void
outputSWF_DEFINETEXT2(SWF_Parserstruct * pblock)1478 outputSWF_DEFINETEXT2 (SWF_Parserstruct * pblock)
1479 {
1480   int i,id=0;
1481   char name[32];
1482   char buffer[64];
1483   OUT_BEGIN (SWF_DEFINETEXT2);
1484   sprintf (name, "character%d", sblock->CharacterID);
1485   printf ("%s(2);\n", newobj (name, "Text"));
1486   for(i=0;i<sblock->numTextRecords;i++)
1487   {
1488    if (!id && sblock->TextRecords[i].FontID)
1489      id=sblock->TextRecords[i].FontID;
1490    if ( sblock->TextRecords[i].TextRecordType  )
1491    {
1492      memset(buffer,0,64);
1493      outputSWF_TEXT_RECORD(&(sblock->TextRecords[i]), 2,name,buffer,64,id );
1494      printf ("%s(\"%s\");\n", methodcall (name, "addString"),buffer);
1495    }
1496   }
1497 }
1498 
1499 void
outputSWF_DEFINETEXTFORMAT(SWF_Parserstruct * pblock)1500 outputSWF_DEFINETEXTFORMAT (SWF_Parserstruct * pblock)
1501 {
1502   OUT_BEGIN_EMPTY (SWF_DEFINETEXTFORMAT);
1503 
1504 }
1505 
1506 void
outputSWF_DEFINEVIDEO(SWF_Parserstruct * pblock)1507 outputSWF_DEFINEVIDEO (SWF_Parserstruct * pblock)
1508 {
1509   OUT_BEGIN_EMPTY (SWF_DEFINEVIDEO);
1510 
1511 }
1512 
1513 void
outputSWF_DEFINEVIDEOSTREAM(SWF_Parserstruct * pblock)1514 outputSWF_DEFINEVIDEOSTREAM (SWF_Parserstruct * pblock)
1515 {
1516   char name[32];
1517 
1518   OUT_BEGIN (SWF_DEFINEVIDEOSTREAM);
1519 
1520   sprintf (name, "character%d", sblock->CharacterID);
1521 
1522   /* NOTE: Ming sets NumFrames = 65535 for empty movies.. */
1523   if ( sblock->NumFrames && sblock->NumFrames != 65535 ) {
1524     printf (COMMSTART " You'll need to extract video%d.flv " COMMEND "\n",
1525             sblock->CharacterID);
1526     printf ("%s('video%d.flv');", newobj (name, "VideoStream"),
1527             sblock->CharacterID);
1528   } else {
1529     printf ("%s(); ", newobj (name, "VideoStream"));
1530   }
1531   printf (COMMSTART " %d frames advertised " COMMEND "\n", sblock->NumFrames);
1532 
1533   printf ("%s(%d, %d);\n", methodcall (name, "setDimension"),
1534     sblock->Width, sblock->Height);
1535 
1536   /* We go manual and have SWF_VIDEOFRAME trigger a nextFrame */
1537   printf ("%s(SWF_VIDEOSTREAM_MODE_MANUAL);\n",
1538     methodcall (name, "setFrameMode"));
1539 
1540 }
1541 
1542 void
outputSWF_DOACTION(SWF_Parserstruct * pblock)1543 outputSWF_DOACTION (SWF_Parserstruct * pblock)
1544 {
1545   OUT_BEGIN (SWF_DOACTION);
1546 
1547   printf ("%s(%s(\"%s\") );\n", methodcall (spritenum?spritename:"m", "add"),
1548 	  newobj (NULL, "Action"), decompile5Action(sblock->numActions,sblock->Actions,0));
1549 }
1550 
1551 void
outputSWF_ENABLEDEBUGGER(SWF_Parserstruct * pblock)1552 outputSWF_ENABLEDEBUGGER (SWF_Parserstruct * pblock)
1553 {
1554   OUT_BEGIN_EMPTY (SWF_ENABLEDEBUGGER);
1555 
1556 }
1557 
1558 void
outputSWF_END(SWF_Parserstruct * pblock)1559 outputSWF_END (SWF_Parserstruct * pblock)
1560 {
1561   OUT_BEGIN_EMPTY (SWF_END);
1562 
1563 }
1564 
1565 void
outputSWF_EXPORTASSETS(SWF_Parserstruct * pblock)1566 outputSWF_EXPORTASSETS (SWF_Parserstruct * pblock)
1567 {
1568   int i;
1569   char name[32];
1570   OUT_BEGIN (SWF_EXPORTASSETS);
1571 
1572   for (i = 0; i < sblock->Count; i++)
1573   {
1574    sprintf (name, VAR "character%d", sblock->Tags[i]);
1575    printf ("%s" ARGSTART "%s" ARGSEP SQ "%s" SQ ARGEND STMNTEND "\n",
1576      methodcall ("m", "addExport"),name,sblock->Names[i]);
1577   }
1578   printf ("%s" ARGSTART ARGEND STMNTEND "\n",methodcall ("m", "writeExports"));
1579 }
1580 
1581 void
outputSWF_FONTREF(SWF_Parserstruct * pblock)1582 outputSWF_FONTREF (SWF_Parserstruct * pblock)
1583 {
1584   OUT_BEGIN_EMPTY (SWF_FONTREF);
1585 
1586 }
1587 
1588 void
outputSWF_FRAMELABEL(SWF_Parserstruct * pblock)1589 outputSWF_FRAMELABEL (SWF_Parserstruct * pblock)
1590 {
1591   OUT_BEGIN (SWF_FRAMELABEL);
1592 
1593   printf ("%s("SQ"%s"SQ");\n",
1594 	  methodcall (spritenum?spritename:"m", sblock->IsAnchor?"namedAnchor":"labelFrame"), sblock->Name );
1595 
1596 }
1597 
1598 void
outputSWF_FRAMETAG(SWF_Parserstruct * pblock)1599 outputSWF_FRAMETAG (SWF_Parserstruct * pblock)
1600 {
1601   OUT_BEGIN_EMPTY (SWF_FRAMETAG);
1602 
1603 }
1604 
1605 void
outputSWF_FREEALL(SWF_Parserstruct * pblock)1606 outputSWF_FREEALL (SWF_Parserstruct * pblock)
1607 {
1608   OUT_BEGIN_EMPTY (SWF_FREEALL);
1609 
1610 }
1611 
1612 void
outputSWF_FREECHARACTER(SWF_Parserstruct * pblock)1613 outputSWF_FREECHARACTER (SWF_Parserstruct * pblock)
1614 {
1615   OUT_BEGIN_EMPTY (SWF_FREECHARACTER);
1616 
1617 }
1618 
1619 void
outputSWF_GENCOMMAND(SWF_Parserstruct * pblock)1620 outputSWF_GENCOMMAND (SWF_Parserstruct * pblock)
1621 {
1622   OUT_BEGIN_EMPTY (SWF_GENCOMMAND);
1623 
1624 }
1625 
1626 void
outputSWF_IMPORTASSETS(SWF_Parserstruct * pblock)1627 outputSWF_IMPORTASSETS (SWF_Parserstruct * pblock)
1628 {
1629   OUT_BEGIN_EMPTY (SWF_IMPORTASSETS);
1630 
1631 }
1632 
1633 void
outputSWF_JPEGTABLES(SWF_Parserstruct * pblock)1634 outputSWF_JPEGTABLES (SWF_Parserstruct * pblock)
1635 {
1636   OUT_BEGIN_EMPTY (SWF_JPEGTABLES);
1637 
1638 }
1639 
1640 void
outputSWF_NAMECHARACTER(SWF_Parserstruct * pblock)1641 outputSWF_NAMECHARACTER (SWF_Parserstruct * pblock)
1642 {
1643   OUT_BEGIN_EMPTY (SWF_NAMECHARACTER);
1644 
1645 }
1646 
1647 void
outputSWF_PATHSAREPOSTSCRIPT(SWF_Parserstruct * pblock)1648 outputSWF_PATHSAREPOSTSCRIPT (SWF_Parserstruct * pblock)
1649 {
1650   OUT_BEGIN_EMPTY (SWF_PATHSAREPOSTSCRIPT);
1651 
1652 }
1653 
1654 void
outputSWF_PLACEOBJECT(SWF_Parserstruct * pblock)1655 outputSWF_PLACEOBJECT (SWF_Parserstruct * pblock)
1656 {
1657   OUT_BEGIN_EMPTY (SWF_PLACEOBJECT);
1658 
1659 }
1660 
1661 void
outputSWF_PLACEOBJECT2(SWF_Parserstruct * pblock)1662 outputSWF_PLACEOBJECT2 (SWF_Parserstruct * pblock)
1663 {
1664   char cname[64];
1665   OUT_BEGIN (SWF_PLACEOBJECT2);
1666 
1667   if( sblock->PlaceFlagHasCharacter ) {
1668     sprintf(cname, "character%d", sblock->CharacterId );
1669     if(sblock->Depth)
1670     {
1671       char varname[64];
1672       sprintf(varname, "%s%d", "i" , sblock->Depth);
1673       if (!search_var(varname))
1674         printf ("" DECLOBJ(DisplayItem) " ");
1675       printf ("%s = %s(" VAR "%s)"STMNTEND"\n", varname,
1676         methodcall (spritenum?spritename:"m", "add"),     cname);
1677 
1678       sprintf(cname, "i%d", sblock->Depth );
1679       printf("%s(%d)"STMNTEND"\n", methodcall(cname, "setDepth"), sblock->Depth);
1680     }
1681     else
1682       printf(COMMSTART " PlaceFlagHasCharacter and Depth == 0! " COMMEND "\n");
1683   }
1684   if( sblock->PlaceFlagHasMatrix ) {
1685     printf(COMMSTART " PlaceFlagHasMatrix " COMMEND "\n");
1686     sprintf(cname, "i%d", sblock->Depth );
1687     if (!spritenum)				/* coordinate translation on main movie */
1688     {
1689       sblock->Matrix.TranslateX-=offsetX;
1690       sblock->Matrix.TranslateY-=offsetY;
1691     }
1692     outputSWF_MATRIX (&sblock->Matrix, cname);
1693   }
1694   if( sblock->PlaceFlagHasColorTransform ) {
1695     sprintf(cname, "i%d", sblock->Depth);
1696     outputSWF_CXFORMWITHALPHA(&sblock->ColorTransform, cname);
1697   }
1698   if( sblock->PlaceFlagHasRatio ) {
1699     printf(COMMSTART " PlaceFlagHasRatio " COMMEND "\n");
1700   }
1701   if( sblock->PlaceFlagHasName ) {
1702     sprintf(cname, "i%d", sblock->Depth );
1703     printf("%s("SQ"%s"SQ")"STMNTEND"\n", methodcall(cname, "setName"), sblock->Name);
1704   }
1705   if( sblock->PlaceFlagHasClipDepth ) {
1706     sprintf(cname, "i%d", sblock->Depth );
1707     printf("%s(%d)"STMNTEND"\n", methodcall(cname, "setMaskLevel"), sblock->ClipDepth);
1708   }
1709   if( sblock->PlaceFlagHasClipActions ) {
1710     sprintf(cname, "i%d", sblock->Depth );
1711     outputSWF_CLIPACTIONS (&sblock->ClipActions, cname);
1712   }
1713 
1714 }
1715 
1716 void
outputSWF_PLACEOBJECT3(SWF_Parserstruct * pblock)1717 outputSWF_PLACEOBJECT3 (SWF_Parserstruct * pblock)
1718 {
1719   OUT_BEGIN_EMPTY (SWF_PLACEOBJECT3);
1720 
1721 }
1722 
1723 void
outputSWF_PREBUILT(SWF_Parserstruct * pblock)1724 outputSWF_PREBUILT (SWF_Parserstruct * pblock)
1725 {
1726   OUT_BEGIN_EMPTY (SWF_PREBUILT);
1727 
1728 }
1729 
1730 void
outputSWF_PREBUILTCLIP(SWF_Parserstruct * pblock)1731 outputSWF_PREBUILTCLIP (SWF_Parserstruct * pblock)
1732 {
1733   OUT_BEGIN_EMPTY (SWF_PREBUILTCLIP);
1734 
1735 }
1736 
1737 void
outputSWF_PROTECT(SWF_Parserstruct * pblock)1738 outputSWF_PROTECT (SWF_Parserstruct * pblock)
1739 {
1740   OUT_BEGIN (SWF_PROTECT);
1741 
1742   if( sblock->Password == NULL ) {
1743   	printf ("%s();\n",
1744 	  methodcall ("m", "protect"));
1745   } else{
1746   	printf ("%s(\"%s\");\n",
1747 	  methodcall ("m", "protect"),sblock->Password);
1748   }
1749 
1750 }
1751 
1752 void
outputSWF_REMOVEOBJECT(SWF_Parserstruct * pblock)1753 outputSWF_REMOVEOBJECT (SWF_Parserstruct * pblock)
1754 {
1755   OUT_BEGIN (SWF_REMOVEOBJECT);
1756   printf ("%s(" VAR "c%d);\n",
1757 	  methodcall (spritenum?spritename:"m", "remove"), sblock->CharacterId);
1758 
1759 }
1760 
1761 void
outputSWF_REMOVEOBJECT2(SWF_Parserstruct * pblock)1762 outputSWF_REMOVEOBJECT2 (SWF_Parserstruct * pblock)
1763 {
1764   OUT_BEGIN (SWF_REMOVEOBJECT2);
1765   printf ("%s(" VAR "i%d);\n",
1766 	  methodcall (spritenum?spritename:"m", "remove"), sblock->Depth);
1767 
1768 }
1769 
1770 void
outputSWF_SERIALNUMBER(SWF_Parserstruct * pblock)1771 outputSWF_SERIALNUMBER (SWF_Parserstruct * pblock)
1772 {
1773   OUT_BEGIN_EMPTY (SWF_SERIALNUMBER);
1774 
1775 }
1776 
1777 void
outputSWF_SETBACKGROUNDCOLOR(SWF_Parserstruct * pblock)1778 outputSWF_SETBACKGROUNDCOLOR (SWF_Parserstruct * pblock)
1779 {
1780   OUT_BEGIN (SWF_SETBACKGROUNDCOLOR);
1781 
1782   printf ("%s", methodcall ("m", "setBackground"));
1783   params (3,"0x%02x", sblock->rgb.red,
1784 	    "0x%02x", sblock->rgb.green,
1785 	    "0x%02x", sblock->rgb.blue);
1786   printf (STMNTEND "\n");
1787 
1788 }
1789 
1790 void
outputSWF_SHOWFRAME(SWF_Parserstruct * pblock)1791 outputSWF_SHOWFRAME (SWF_Parserstruct * pblock)
1792 {
1793   OUT_BEGIN_EMPTY (SWF_SHOWFRAME);
1794 
1795   printf ("%s", methodcall (spritenum?spritename:"m", "nextFrame"));
1796   params(0);
1797   printf (STMNTEND " " COMMSTART " end of %sframe %d " COMMEND "\n",
1798 	  spritenum?"clip ":"",
1799 	  spritenum?spframenum++:framenum++);
1800 }
1801 
1802 void
outputSWF_SOUNDSTREAMBLOCK(SWF_Parserstruct * pblock)1803 outputSWF_SOUNDSTREAMBLOCK (SWF_Parserstruct * pblock)
1804 {
1805   OUT_BEGIN_EMPTY (SWF_SOUNDSTREAMBLOCK);
1806 
1807 }
1808 
1809 void
outputSWF_SOUNDSTREAMHEAD(SWF_Parserstruct * pblock)1810 outputSWF_SOUNDSTREAMHEAD (SWF_Parserstruct * pblock)
1811 {
1812   OUT_BEGIN_EMPTY (SWF_SOUNDSTREAMHEAD);
1813 
1814 }
1815 
1816 void
outputSWF_SOUNDSTREAMHEAD2(SWF_Parserstruct * pblock)1817 outputSWF_SOUNDSTREAMHEAD2 (SWF_Parserstruct * pblock)
1818 {
1819   OUT_BEGIN_EMPTY (SWF_SOUNDSTREAMHEAD2);
1820 
1821 }
1822 
1823 void
outputSWF_STARTSOUND(SWF_Parserstruct * pblock)1824 outputSWF_STARTSOUND (SWF_Parserstruct * pblock)
1825 {
1826   OUT_BEGIN_EMPTY (SWF_STARTSOUND);
1827 
1828 }
1829 
1830 void
outputSWF_SYNCFRAME(SWF_Parserstruct * pblock)1831 outputSWF_SYNCFRAME (SWF_Parserstruct * pblock)
1832 {
1833   OUT_BEGIN_EMPTY (SWF_SYNCFRAME);
1834 
1835 }
1836 
1837 void
outputSWF_INITACTION(SWF_Parserstruct * pblock)1838 outputSWF_INITACTION (SWF_Parserstruct * pblock)
1839 {
1840   OUT_BEGIN (SWF_INITACTION);
1841 
1842   printf (COMMSTART
1843     " Might be more appropriate to use addInitAction here" COMMEND "\n");
1844 
1845   /* NOTE: the printf must be split in two cause newobj uses
1846    *       a static buffer so can't be used twice to return
1847    *       different strings
1848    */
1849 
1850   printf ("%s(%s(",
1851           methodcall (spritenum?spritename:"m", "add"),
1852           newobj (NULL, "InitAction"));
1853 
1854   /* TODO: add SpriteID ? */
1855 
1856   printf ("%s(\"%s\")));\n",
1857           newobj (NULL, "Action"),
1858           decompile5Action(sblock->numActions,sblock->Actions,0));
1859 }
1860 
1861 void
outputSWF_VIDEOFRAME(SWF_Parserstruct * pblock)1862 outputSWF_VIDEOFRAME (SWF_Parserstruct * pblock)
1863 {
1864   char name[32];
1865 
1866   OUT_BEGIN (SWF_VIDEOFRAME);
1867 
1868   sprintf (name, "character%d", sblock->StreamID);
1869 
1870   printf (COMMSTART " Frame %d of stream %d " COMMEND "\n",
1871     sblock->FrameNum, sblock->StreamID);
1872   printf ("%s();\n", methodcall (name, "nextFrame"));
1873 }
1874 
1875 void
outputSWF_METADATA(SWF_Parserstruct * pblock)1876 outputSWF_METADATA (SWF_Parserstruct * pblock)
1877 {
1878   OUT_BEGIN (SWF_METADATA);
1879 
1880   /* TODO: escape Metadata string (might contain quotes!) */
1881   printf ("%s(\"%s\");\n",
1882           methodcall (spritenum?spritename:"m", "addMetadata"),
1883           sblock->Metadata);
1884 }
1885 
1886 void
outputSWF_SETTABINDEX(SWF_Parserstruct * pblock)1887 outputSWF_SETTABINDEX (SWF_Parserstruct * pblock)
1888 {
1889   OUT_BEGIN (SWF_SETTABINDEX);
1890 
1891   printf("%s(%d, %d)"STMNTEND"\n", methodcall("m", "setTabIndex"),
1892     sblock->Depth, sblock->TabIndex);
1893 
1894 }
1895 
1896 void
outputSWF_SCRIPTLIMITS(SWF_Parserstruct * pblock)1897 outputSWF_SCRIPTLIMITS (SWF_Parserstruct * pblock)
1898 {
1899   OUT_BEGIN (SWF_SCRIPTLIMITS);
1900 
1901   printf("%s(%d, %d)"STMNTEND"\n", methodcall("m", "setScriptLimits"),
1902     sblock->MaxRecursionDepth, sblock->ScriptTimeoutSeconds);
1903 
1904 }
1905 
1906 void
outputSWF_SYMBOLCLASS(SWF_Parserstruct * pblock)1907 outputSWF_SYMBOLCLASS (SWF_Parserstruct * pblock)
1908 {
1909   char cname[64];
1910   int i;
1911 
1912   OUT_BEGIN (SWF_SYMBOLCLASS);
1913 
1914   for(i = 0; i < sblock->SymbolCount; ++i)
1915   {
1916     struct AS_SYMBOL* sym = &(sblock->SymbolList[i]);
1917     sprintf(cname, "character%d", sym->SymbolId );
1918 
1919     printf("%s(" VAR "%s, \"%s\")"STMNTEND"\n", methodcall("m", "assignSymbol"),
1920       cname, sym->SymbolName);
1921   }
1922 
1923 }
1924 
1925 
1926 void
outputSWF_DEFINESCENEANDFRAMEDATA(SWF_Parserstruct * pblock)1927 outputSWF_DEFINESCENEANDFRAMEDATA (SWF_Parserstruct * pblock)
1928 {
1929   int i;
1930 
1931   OUT_BEGIN (SWF_DEFINESCENEANDFRAMEDATA);
1932 
1933   for(i = 0; i < sblock->SceneCount; ++i)
1934   {
1935     struct SCENE_DATA* sc = &(sblock->Scenes[i]);
1936 	// SWFMovie_defineScene(m, 0, "test0");
1937 
1938     printf("%s(%lu, \"%s\")"STMNTEND"\n", methodcall("m", "defineScene"),
1939       sc->Offset, sc->Name);
1940   }
1941 
1942   for(i = 0; i < sblock->FrameLabelCount; ++i)
1943   {
1944     /* TODO: output a method for this! */
1945     struct FRAME_DATA* fd = &(sblock->Frames[i]);
1946     printf (COMMSTART " Label for frame %lu : %s " COMMEND "\n",
1947 	  fd->FrameNum, fd->FrameLabel);
1948   }
1949 
1950 }
1951 
1952 void
outputHeader(struct Movie * m)1953 outputHeader (struct Movie *m)
1954 {
1955   int npending=0;
1956   if( m->version == 4 )
1957   {
1958     m->version=5;		/* a note for user follows after language dependent part */
1959     npending=1;
1960   }
1961 #ifdef SWFPHP
1962   if( swftargetfile != NULL ) {
1963 	printf ("#!/usr/bin/php\n");
1964   }
1965   printf ("<?php\n");
1966   if( m->version == 5 )
1967   	printf ("%s();\n\n", newobj ("m", "Movie"));
1968   else
1969   	printf ("%s(%d);\n\n", newobj ("m", "Movie"), m->version);
1970   printf ("ming_setscale(1.0);\n");
1971 #endif
1972 #ifdef SWFPERL
1973   printf ("#!/usr/bin/perl -w\n");
1974   printf
1975     ("# Generated by swftoperl converter included with ming. Have fun. \n\n");
1976   printf
1977     ("# Change this to your needs. If you installed perl-ming global you don't need this.\n");
1978   printf ("#use lib(\"/home/peter/mystuff/lib/site_perl\");\n\n");
1979 
1980   printf
1981     ("# We import all because our converter is not so clever to select only needed. ;-)\n");
1982   printf ("use SWF qw(:ALL);\n");
1983   printf
1984     ("# Just copy from a sample, needed to use Constants like SWFFILL_RADIAL_GRADIENT\n");
1985   printf ("use SWF::Constants qw(:Text :Button :DisplayItem :Fill);\n\n");
1986   if( m->version == 5 )
1987   	printf ("%s();\n\n", newobj ("m", "Movie"));
1988   else
1989   	printf ("$m = %s(%d);\n\n", "SWF::Movie::newSWFMovieWithVersion", m->version);
1990   printf ("SWF::setScale(1.0);\n");
1991 #endif
1992 #ifdef SWFPYTHON
1993   printf ("#!/usr/bin/python\n");
1994   printf ("from ming import *\n\n");
1995   if( m->version != 5 )
1996 	printf ("Ming_useSWFVersion(%d);\n\n", m->version);
1997   printf ("%s();\n\n", newobj ("m", "Movie"));
1998   printf ("Ming_setScale(1.0);\n");
1999 #endif
2000 #ifdef SWFPLUSPLUS
2001   printf ("#include <mingpp.h>\n");
2002   printf ("\n\nmain(){\n");
2003   if( m->version == 5 )
2004   	printf ("%s();\n\n", newobj ("m", "Movie"));
2005   else
2006   	printf ("%s(%d);\n\n", newobj ("m", "Movie"), m->version);
2007   printf ("Ming_setScale(1.0);\n");
2008 #endif
2009 #ifdef SWFTCL
2010   printf ("load mingc.so mingc\n");
2011   printf ("%s\n", newobj ("m", "Movie"));
2012   if( m->version != 5 ) {
2013   	printf ("#%s(%d);\n\n", newobj ("m", "Movie"), m->version);
2014 	// XXX:
2015   	// printf ("#add setversion here\n\n", "m", m->version);
2016 	}
2017   printf (COMMSTART "add setscale here" COMMEND "\n");
2018 #endif
2019   if( npending )
2020     printf( "\n" COMMSTART " Note: using v5+ syntax for script blocks (original SWF file version was 4)! " COMMEND "\n\n");
2021   if( m->rate != 12.0 )
2022   	printf ("%s(%f);\n", methodcall ("m", "setRate"), m->rate);
2023   if( m->frame.xMax != 6400 || m->frame.yMax != 4800 )
2024   	printf ("%s(%d, %d);\n", methodcall ("m", "setDimension"),
2025  			m->frame.xMax - m->frame.xMin, m->frame.yMax - m->frame.yMin);
2026   if (m->frame.xMin || m->frame.yMin)
2027   {
2028     offsetX= m->frame.xMin;
2029     offsetY= m->frame.yMin;
2030     printf( "\n" COMMSTART " Note: xMin and/or yMin are not 0! " COMMEND "\n\n");
2031   }
2032   if( m->nFrames != 1 )
2033   	printf ("%s(%i);\n", methodcall ("m", "setFrames"), m->nFrames);
2034 }
2035 
2036 void
outputTrailer(struct Movie * m)2037 outputTrailer (struct Movie *m)
2038 {
2039 	if( swftargetfile == NULL ) {
2040 #ifdef SWFPHP
2041 	printf ("\n\theader('Content-type: application/x-shockwave-flash');\n");
2042 #endif
2043 #ifdef SWFPERL
2044 	printf ("#print('Content-type: application/x-shockwave-flash\\n\\n');\n");
2045 #endif
2046 #ifdef SWFPYTHON
2047 	printf ("#print('Content-type: application/x-shockwave-flash\\n\\n');\n");
2048 #endif
2049 	if( m->version > 5 ) {
2050 		printf ("%s(%i);\n", methodcall ("m", "output"), 9);
2051 	} else {
2052 		printf ("%s();\n", methodcall ("m", "output"));
2053 	}
2054 	} else {
2055 	printf ("%s", methodcall ("m", "save"));
2056 	params (1, "\"%s\"", swftargetfile);
2057 	printf ( STMNTEND "\n");
2058 	}
2059 #ifdef SWFPHP
2060 	printf ("?>\n");
2061 #endif
2062 #ifdef SWFPLUSPLUS
2063 	printf ("}\n");
2064 #endif
2065 }
2066 
2067 void
outputBlock(int type,SWF_Parserstruct * blockp,FILE * stream)2068 outputBlock (int type, SWF_Parserstruct * blockp, FILE* stream)
2069 {
2070 	int i;
2071 
2072 	if (type < 0)
2073 		return;
2074 
2075 	init_script();
2076 
2077 	for (i = 0; i < numOutputs; i++){
2078 		if (outputs[i].type == type){
2079 			outputs[i].output (blockp);
2080 			return;
2081 		}
2082 	}
2083 	printf( COMMSTART "Unknown block type %d" COMMEND "\n", type );
2084 	return;
2085 }
2086