home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Leser 19 / Amiga Plus Leser CD 19.iso / Tools / Freeware / Swf_Player / Lib / ScriptNew.cc < prev    next >
Encoding:
C/C++ Source or Header  |  2002-11-17  |  93.1 KB  |  3,676 lines

  1. // SWF file parser.
  2. //
  3. // I uploaded this file *as is* while I was in the middle
  4. // of debugging something (so its a bit of a mess) but still,
  5. // it fixes most (all?) of the bugs in the original parser
  6. // and includes quite a bit more functionality.
  7. //
  8. // It also uses the Zlib stuff in ParseDefineBitsLossless()
  9. // so you can either comment that out or grab the Zlib source
  10. // and link it in.
  11. //
  12. // Cheers, David.
  13. //
  14. // Change History:
  15. //
  16. // 99.07.12:    Uploaded first version (as is)
  17. // 99.07.22:    Added code to parse Flash 4 ActionScripts,
  18. //              and switches to dump image/sound/tag data
  19. //              Thanks to Jason Schuchert!
  20. // 99.07.28:    More flash 4 actionscript.
  21. //              Added GetUrl2 (thanks Olivier)
  22. //              Fixed callFrame (there's no arguments to print)
  23. //              Added WaitForFrameExpression
  24. //              - Jason Schuchert
  25. // 99.10.21:    Now parses streaming sound and MP3 headers
  26. //              - David Michie
  27. // 99.10.28:    Now parses DefineMorphShape and correctly
  28. //              interprets FLOAT values with ActionPush
  29. //              - David Michie
  30. // 99.11.02:    Now parses DefineFont2 and DefineEditText
  31. //              - David Michie
  32. //
  33. //////////////////////////////////////////////////////////////////////
  34.  
  35.  
  36. //!!@ dump sound data
  37.  
  38. #include <stdio.h>
  39. #include <string.h>
  40.  
  41.  
  42. void usage( void )
  43. {
  44.     fprintf(stderr, "usage: swfdump [options] inputFile\n");
  45.     fprintf(stderr, "       -a dumps all data (tag, image, sound)\n" );
  46.     fprintf(stderr, "       -i dumps image data\n" );
  47.     fprintf(stderr, "       -s dumps sound data\n" );
  48.     fprintf(stderr, "       -t dumps tag data\n" );
  49. }
  50.  
  51. extern "C"
  52. {
  53.     #include "zlib.h"
  54. }
  55.  
  56.  
  57. #if defined(_DEBUG) && defined(_WIN32)
  58.     #include <windows.h>
  59.     #define DEBUG_ASSERT    DebugBreak()
  60. #else
  61.     #define DEBUG_ASSERT
  62.     typedef unsigned long BOOL;
  63. #endif
  64.  
  65. // Global Types
  66. typedef unsigned long U32, *P_U32, **PP_U32;
  67. typedef signed long S32, *P_S32, **PP_S32;
  68. typedef unsigned short U16, *P_U16, **PP_U16;
  69. typedef signed short S16, *P_S16, **PP_S16;
  70. typedef unsigned char U8, *P_U8, **PP_U8;
  71. typedef signed char S8, *P_S8, **PP_S8;
  72. typedef signed long SFIXED, *P_SFIXED;
  73. typedef signed long SCOORD, *P_SCOORD;
  74.  
  75. typedef struct SPOINT
  76. {
  77.     SCOORD x;
  78.     SCOORD y;
  79. } SPOINT, *P_SPOINT;
  80.  
  81. typedef struct SRECT
  82. {
  83.     SCOORD xmin;
  84.     SCOORD xmax;
  85.     SCOORD ymin;
  86.     SCOORD ymax;
  87. } SRECT, *P_SRECT;
  88.  
  89. // Start Sound Flags
  90. enum {
  91.     soundHasInPoint     = 0x01,
  92.     soundHasOutPoint    = 0x02,
  93.     soundHasLoops       = 0x04,
  94.     soundHasEnvelope    = 0x08
  95.  
  96.     // the upper 4 bits are reserved for synchronization flags
  97. };
  98.  
  99. enum {
  100.     fillGradient        =   0x10,
  101.     fillLinearGradient  =   0x10,
  102.     fillRadialGradient  =   0x12,
  103.     fillMaxGradientColors   =   8,
  104.     // Texture/bitmap fills
  105.     fillBits            =   0x40    // if this bit is set, must be a bitmap pattern
  106. };
  107.  
  108. // Flags for defining a shape character
  109. enum {
  110.         // These flag codes are used for state changes - and as return values from ShapeParser::GetEdge()
  111.         eflagsMoveTo       = 0x01,
  112.         eflagsFill0        = 0x02,
  113.         eflagsFill1        = 0x04,
  114.         eflagsLine         = 0x08,
  115.         eflagsNewStyles    = 0x10,
  116.  
  117.         eflagsEnd          = 0x80  // a state change with no change marks the end
  118. };
  119.  
  120. enum FontFlags
  121. {
  122.     fontUnicode   = 0x20,
  123.     fontShiftJIS  = 0x10,
  124.     fontANSI      = 0x08,
  125.     fontItalic    = 0x04,
  126.     fontBold      = 0x02,
  127.     fontWideCodes = 0x01
  128. };
  129.  
  130. // Edit text field flags
  131. enum
  132. {
  133.     sfontFlagsBold          = 0x01,
  134.     sfontFlagsItalic        = 0x02,
  135.     sfontFlagsWideCodes     = 0x04,
  136.     sfontFlagsWideOffsets   = 0x08,
  137.     sfontFlagsANSI          = 0x10,
  138.     sfontFlagsUnicode       = 0x20,
  139.     sfontFlagsShiftJIS      = 0x40,
  140.     sfontFlagsHasLayout     = 0x80
  141. };
  142.  
  143. // Edit Text Flags
  144. enum {
  145.     seditTextFlagsHasFont       = 0x0001,
  146.     seditTextFlagsHasMaxLength  = 0x0002,
  147.     seditTextFlagsHasTextColor  = 0x0004,
  148.     seditTextFlagsReadOnly      = 0x0008,
  149.     seditTextFlagsPassword      = 0x0010,
  150.     seditTextFlagsMultiline     = 0x0020,
  151.     seditTextFlagsWordWrap      = 0x0040,
  152.     seditTextFlagsHasText       = 0x0080,
  153.     seditTextFlagsUseOutlines   = 0x0100,
  154.     seditTextFlagsBorder        = 0x0800,
  155.     seditTextFlagsNoSelect      = 0x1000,
  156.     seditTextFlagsHasLayout     = 0x2000
  157. };
  158.  
  159.  
  160. enum TextFlags
  161. {
  162.     isTextControl = 0x80,
  163.  
  164.     textHasFont   = 0x08,
  165.     textHasColor  = 0x04,
  166.     textHasYOffset= 0x02,
  167.     textHasXOffset= 0x01
  168. };
  169.  
  170.  
  171. typedef struct MATRIX
  172. {
  173.     SFIXED a;
  174.     SFIXED b;
  175.     SFIXED c;
  176.     SFIXED d;
  177.     SCOORD tx;
  178.     SCOORD ty;
  179. } MATRIX, *P_MATRIX;
  180.  
  181. typedef struct CXFORM
  182. {
  183.     /*
  184.     S32 flags;
  185.     enum
  186.     {
  187.         needA=0x1,  // Set if we need the multiply terms.
  188.         needB=0x2   // Set if we need the constant terms.
  189.     };
  190.     */
  191.  
  192.     S16 aa, ab;     // a is multiply factor, b is addition factor
  193.     S16 ra, rb;
  194.     S16 ga, gb;
  195.     S16 ba, bb;
  196. }
  197. CXFORM, *P_CXFORM;
  198.  
  199.  
  200. #ifndef NULL
  201. #define NULL 0
  202. #endif
  203.  
  204. // Tag values that represent actions or data in a Flash script.
  205. enum
  206. {
  207.     stagEnd                 = 0,
  208.     stagShowFrame           = 1,
  209.     stagDefineShape         = 2,
  210.     stagFreeCharacter       = 3,
  211.     stagPlaceObject         = 4,
  212.     stagRemoveObject        = 5,
  213.     stagDefineBits          = 6,
  214.     stagDefineButton        = 7,
  215.     stagJPEGTables          = 8,
  216.     stagSetBackgroundColor  = 9,
  217.     stagDefineFont          = 10,
  218.     stagDefineText          = 11,
  219.     stagDoAction            = 12,
  220.     stagDefineFontInfo      = 13,
  221.     stagDefineSound         = 14,   // Event sound tags.
  222.     stagStartSound          = 15,
  223.     stagDefineButtonSound   = 17,
  224.     stagSoundStreamHead     = 18,
  225.     stagSoundStreamBlock    = 19,
  226.     stagDefineBitsLossless  = 20,   // A bitmap using lossless zlib compression.
  227.     stagDefineBitsJPEG2     = 21,   // A bitmap using an internal JPEG compression table.
  228.     stagDefineShape2        = 22,
  229.     stagDefineButtonCxform  = 23,
  230.     stagProtect             = 24,   // This file should not be importable for editing.
  231.  
  232.     // These are the new tags for Flash 3.
  233.     stagPlaceObject2        = 26,   // The new style place w/ alpha color transform and name.
  234.     stagRemoveObject2       = 28,   // A more compact remove object that omits the character tag (just depth).
  235.     stagDefineShape3        = 32,   // A shape V3 includes alpha values.
  236.     stagDefineText2         = 33,   // A text V2 includes alpha values.
  237.     stagDefineButton2       = 34,   // A button V2 includes color transform, alpha and multiple actions
  238.     stagDefineBitsJPEG3     = 35,   // A JPEG bitmap with alpha info.
  239.     stagDefineBitsLossless2 = 36,   // A lossless bitmap with alpha info.
  240.     stagDefineEditText      = 37,   // An editable Text Field
  241.     stagDefineSprite        = 39,   // Define a sequence of tags that describe the behavior of a sprite.
  242.     stagNameCharacter       = 40,   // Name a character definition, character id and a string, (used for buttons, bitmaps, sprites and sounds).
  243.     stagFrameLabel          = 43,   // A string label for the current frame.
  244.     stagSoundStreamHead2    = 45,   // For lossless streaming sound, should not have needed this...
  245.     stagDefineMorphShape    = 46,   // A morph shape definition
  246.     stagDefineFont2         = 48,   //
  247. };
  248.  
  249. // PlaceObject2 Flags
  250. enum
  251. {
  252.     splaceMove          = 0x01, // this place moves an exisiting object
  253.     splaceCharacter     = 0x02, // there is a character tag (if no tag, must be a move)
  254.     splaceMatrix        = 0x04, // there is a matrix (matrix)
  255.     splaceColorTransform= 0x08, // there is a color transform (cxform with alpha)
  256.     splaceRatio         = 0x10, // there is a blend ratio (word)
  257.     splaceName          = 0x20, // there is an object name (string)
  258.     splaceDefineClip    = 0x40  // this shape should open or close a clipping bracket (character != 0 to open, character == 0 to close)
  259.     // one bit left for expansion
  260. };
  261.  
  262. // Action codes
  263. enum
  264. {
  265.     sactionNone                     = 0x00,
  266.     sactionNextFrame                = 0x04,
  267.     sactionPrevFrame                = 0x05,
  268.     sactionPlay                     = 0x06,
  269.     sactionStop                     = 0x07,
  270.     sactionToggleQuality            = 0x08,
  271.     sactionStopSounds               = 0x09,
  272.     sactionAdd                      = 0x0A,
  273.     sactionSubtract                 = 0x0B,
  274.     sactionMultiply                 = 0x0C,
  275.     sactionDivide                   = 0x0D,
  276.     sactionEqual                    = 0x0E,
  277.     sactionLessThan                 = 0x0F,
  278.     sactionLogicalAnd               = 0x10,
  279.     sactionLogicalOr                = 0x11,
  280.     sactionLogicalNot               = 0x12,
  281.     sactionStringEqual              = 0x13,
  282.     sactionStringLength             = 0x14,
  283.     sactionSubString                = 0x15,
  284.     sactionInt                      = 0x18,
  285.     sactionEval                     = 0x1C,
  286.     sactionSetVariable              = 0x1D,
  287.     sactionSetTargetExpression      = 0x20,
  288.     sactionStringConcat             = 0x21,
  289.     sactionGetProperty              = 0x22,
  290.     sactionSetProperty              = 0x23,
  291.     sactionDuplicateClip            = 0x24,
  292.     sactionRemoveClip               = 0x25,
  293.     sactionTrace                    = 0x26,
  294.     sactionStartDragMovie           = 0x27,
  295.     sactionStopDragMovie            = 0x28,
  296.     sactionStringLessThan           = 0x29,
  297.     sactionRandom                   = 0x30,
  298.     sactionMBLength                 = 0x31,
  299.     sactionOrd                      = 0x32,
  300.     sactionChr                      = 0x33,
  301.     sactionGetTimer                 = 0x34,
  302.     sactionMBSubString              = 0x35,
  303.     sactionMBOrd                    = 0x36,
  304.     sactionMBChr                    = 0x37,
  305.     sactionHasLength                = 0x80,
  306.     sactionGotoFrame                = 0x81, // frame num (WORD)
  307.     sactionGetURL                   = 0x83, // url (STR), window (STR)
  308.     sactionWaitForFrame             = 0x8A, // frame needed (WORD),
  309.                                             // actions to skip (BYTE)
  310.     sactionSetTarget                = 0x8B, // name (STR)
  311.     sactionGotoLabel                = 0x8C, // name (STR)
  312.     sactionWaitForFrameExpression   = 0x8D, // frame needed on stack,
  313.                                             // actions to skip (BYTE)
  314.     sactionPushData                 = 0x96,
  315.     sactionBranchAlways             = 0x99,
  316.     sactionGetURL2                  = 0x9A,
  317.     sactionBranchIfTrue             = 0x9D,
  318.     sactionCallFrame                = 0x9E,
  319.     sactionGotoExpression           = 0x9F
  320. };
  321.  
  322. //////////////////////////////////////////////////////////////////////
  323. // Input script object definition.
  324. //////////////////////////////////////////////////////////////////////
  325.  
  326. // An input script object.  This object represents a script created from
  327. // an external file that is meant to be inserted into an output script.
  328. struct CInputScript
  329. {
  330.     // Pointer to file contents buffer.
  331.     U8 *m_fileBuf;
  332.  
  333.     // File state information.
  334.     U32 m_filePos;
  335.     U32 m_fileSize;
  336.     U32 m_fileStart;
  337.     U16 m_fileVersion;
  338.  
  339.     // Bit Handling
  340.     S32 m_bitPos;
  341.     U32 m_bitBuf;
  342.  
  343.     // Tag parsing information.
  344.     U32 m_tagStart;
  345.     U32 m_tagZero;
  346.     U32 m_tagEnd;
  347.     U32 m_tagLen;
  348.  
  349.     // Parsing information.
  350.     S32 m_nFillBits;
  351.     S32 m_nLineBits;
  352.  
  353.    // Set to true if we wish to dump all contents long form
  354.     U32 m_dumpAll;
  355.  
  356.     // if set to true will dump image guts (i.e. jpeg, zlib, etc. data)
  357.     U32 m_dumpGuts;
  358.  
  359.     // if set to true will dump sound guts
  360.     U32 m_dumpSoundGuts;
  361.  
  362.  
  363.     // Handle to output file.
  364.     FILE *m_outputFile;
  365.  
  366.     // Font glyph counts (gotta save it somewhere!)
  367.     int m_iGlyphCounts[256];
  368.  
  369.     U8* m_srcAdpcm;
  370.     U32 m_bitBufAdpcm;      // this should always contain at least 24 bits of data
  371.     S32 m_bitPosAdpcm;
  372.     U32 m_nSamplesAdpcm;    // number of samples decompressed so far
  373.  
  374.     // Streaming sound info from SoundStreamHead tag
  375.     int m_iStreamCompression;
  376.     int m_iStreamSampleRate;
  377.     int m_iStreamSampleSize;
  378.     int m_iStreamStereoMono;
  379.     int m_nStreamSamples;
  380.  
  381.     // Constructor/destructor.
  382.     CInputScript();
  383.     ~CInputScript();
  384.  
  385.     // Tag scanning methods.
  386.     U16 GetTag(void);
  387.     void SkipBytes(int n);
  388.     U8 GetByte(void);
  389.     U16 GetWord(void);
  390.     U32 GetDWord(void);
  391.     void GetRect(SRECT *r);
  392.     void GetMatrix(MATRIX *matrix);
  393.     void GetCxform(CXFORM *cxform, BOOL hasAlpha);
  394.     void PrintCxform(char* str, CXFORM *cxform);
  395.     char *GetString(void);
  396.     U32 GetColor(BOOL fWithAlpha=false);
  397.  
  398.     void PrintMatrix(MATRIX matrix, char* str);
  399.     void PrintRect(SRECT rect, char* str);
  400.  
  401.     // Routines for reading arbitrary sized bit fields from the stream.
  402.     // Always call start bits before gettings bits and do not intermix
  403.     // these calls with GetByte, etc...
  404.     void InitBits();
  405.     S32 GetSBits(S32 n);
  406.     U32 GetBits(S32 n);
  407.     void where();
  408.  
  409.     // Tag subcomponent parsing methods
  410.     // For shapes
  411.     void ParseShapeStyle(char *str, BOOL fWithAlpha=false);
  412.     BOOL ParseShapeRecord(char *str, int& xLast, int& yLast, BOOL fWithAlpha=false);
  413.     void ParseButtonRecord(char *str, U32 byte, BOOL fGetColorMatrix=true);
  414.     BOOL ParseTextRecord(char* str, int nGlyphBits, int nAdvanceBits);
  415.  
  416.     // Parsing methods.
  417.     void ParseEnd(char *str);                               // 00: stagEnd
  418.     void ParseShowFrame(char *str, U32 frame, U32 offset);  // 01: stagShowFrame
  419.     void ParseDefineShape(char *str, BOOL fWithAlpha=false);// 02: stagDefineShape
  420.     void ParseFreeCharacter(char *str);                     // 03: stagFreeCharacter
  421.     void ParsePlaceObject(char *str);                       // 04: stagPlaceObject
  422.     void ParseRemoveObject(char *str);                      // 05: stagRemoveObject
  423.     void ParseDefineBits(char *str);                        // 06: stagDefineBits
  424.     void ParseDefineButton(char *str);       //x 07: stagDefineButton
  425.     void ParseJPEGTables(char *str);                        // 08: stagJPEGTables
  426.     void ParseSetBackgroundColor(char *str);                // 09: stagSetBackgroundColor
  427.     void ParseDefineFont(char *str);         //x 10: stagDefineFont
  428.     void ParseDefineText(char *str);         //x 11: stagDefineText
  429.     void ParseDoAction(char *str, BOOL fPrintTag=true);                          // 12: stagDoAction
  430.     void ParseDefineFontInfo(char *str);     //x 13: stagDefineFontInfo
  431.     void ParseDefineSound(char *str);                       // 14: stagDefineSound
  432.     void ParseStartSound(char *str);                        // 15: stagStartSound
  433.     void ParseStopSound(char *str);                         // 16: stagStopSound
  434.     void ParseDefineButtonSound(char *str);                 // 17: stagDefineButtonSound
  435.     void ParseSoundStreamHead(char *str);                   // 18: stagSoundStreamHead
  436.     void ParseSoundStreamBlock(char *str);                  // 19: stagSoundStreamBlock
  437.     void ParseDefineBitsLossless(char *str);                // 20: stagDefineBitsLossless
  438.     void ParseDefineBitsJPEG2(char *str);                   // 21: stagDefineBitsJPEG2
  439.     void ParseDefineShape2(char *str);       //x 22: stagDefineShape2
  440.     void ParseDefineButtonCxform(char *str);                // 23: stagDefineButtonCxform
  441.     void ParseProtect(char *str);                           // 24: stagProtect
  442.     void ParsePlaceObject2(char *str);                      // 26: stagPlaceObject2
  443.     void ParseRemoveObject2(char *str);                     // 28: stagRemoveObject2
  444.     void ParseDefineShape3(char *str);       //x 32: stagDefineShape3
  445.     void ParseDefineText2(char *str);        //x 33: stagDefineText2
  446.     void ParseDefineButton2(char *str);      //x 34: stagDefineButton2
  447.     void ParseDefineBitsJPEG3(char *str);                   // 35: stagDefineBitsJPEG3
  448.     void ParseDefineBitsLossless2(char *str);               // 36: stagDefineBitsLossless2
  449.     void ParseDefineEditText(char *str);                    // 37: stagDefineEditText
  450.     void ParseDefineMouseTarget(char *str);                 // 38: stagDefineMouseTarget
  451.     void ParseDefineSprite(char *str);       //x 39: stagDefineSprite
  452.     void ParseNameCharacter(char *str);                     // 40: stagNameCharacter
  453.     void ParseFrameLabel(char *str);                        // 43: stagFrameLabel
  454.     void ParseSoundStreamHead2(char *str, BOOL fIsHead2=true);                  // 45: stagSoundStreamHead2
  455.     void ParseDefineMorphShape(char *str);   //x 46: stagDefineMorphShape
  456.     void ParseDefineFont2(char *str);        //x 48: stagDefineFont2
  457.     void ParseUnknown(char *str, U16 code);
  458.     void ParseTags(BOOL sprite, U32 tabs);
  459.     BOOL ParseFile(char * pInput);
  460.     void S_DumpImageGuts(char *str);
  461.  
  462.     // ADPCM stuff
  463.     void AdpcmFillBuffer();
  464.     long AdpcmGetBits(int n);
  465.     long AdpcmGetSBits(int n);
  466.     void AdpcmDecompress(long n, long stereo, int if16bit, U8 *dst=NULL);
  467.  
  468.     // MP3 stuff
  469.     void DecodeMp3Headers(char* str, int iSamplesPerFrame);
  470.     void DecodeMp3Frame(U8* pbFrame, int iEncodedSize, int iDecodedSize);
  471. };
  472.  
  473. #define INDENT  printf("      ");
  474.  
  475. //////////////////////////////////////////////////////////////////////
  476. // Inline input script object methods.
  477. //////////////////////////////////////////////////////////////////////
  478.  
  479. //
  480. // Inlines to parse a Flash file.
  481. //
  482.  
  483. inline void CInputScript::SkipBytes(int n)
  484. {
  485.     m_filePos += n;
  486. }
  487.  
  488. inline U8 CInputScript::GetByte(void)
  489. {
  490.     //printf("GetByte: filePos: %02x [%02x]\n", m_filePos, m_fileBuf[m_filePos]);
  491.     InitBits();
  492.     return m_fileBuf[m_filePos++];
  493. }
  494.  
  495. inline U16 CInputScript::GetWord(void)
  496. {
  497.     //printf("GetWord: filePos: %02x\n", m_filePos);
  498.     U8* s = m_fileBuf + m_filePos;
  499.     m_filePos += 2;
  500.     InitBits();
  501.     return (U16) s[0] | ((U16) s[1] << 8);
  502. }
  503.  
  504. inline U32 CInputScript::GetDWord(void)
  505. {
  506.     //printf("GetDWord: filePos: %02x\n", m_filePos);
  507.     U8 * s = m_fileBuf + m_filePos;
  508.     m_filePos += 4;
  509.     InitBits();
  510.     return (U32) s[0] | ((U32) s[1] << 8) | ((U32) s[2] << 16) | ((U32) s [3] << 24);
  511. }
  512.  
  513. void CInputScript::PrintMatrix(MATRIX matrix, char* str)
  514. {
  515.     printf("%s\t[%5.3f   %5.3f]\n", str, (double)matrix.a/65536.0, (double)matrix.b/65536.0);
  516.     printf("%s\t[%5.3f   %5.3f]\n", str, (double)matrix.c/65536.0, (double)matrix.d/65536.0);
  517.     printf("%s\t[%5.3f   %5.3f]\n", str, (double)matrix.tx/20.0, (double)matrix.ty/20.0);
  518.     /*
  519.     printf("%s\t[%08x   %08x]\n", str, matrix.a, matrix.b);
  520.     printf("%s\t[%08x   %08x]\n", str, matrix.c, matrix.d);
  521.     printf("%s\t[%d   %d]\n", str, matrix.tx, matrix.ty);
  522.     */
  523. }
  524.  
  525. void CInputScript::PrintRect(SRECT rect, char* str)
  526. {
  527.     printf("\t%s(%g, %g)[%g x %g]\n", str,
  528.             (double)rect.xmin / 20.0, (double)rect.ymin / 20.0,
  529.             (double)(rect.xmax - rect.xmin) / 20.0,
  530.             (double)(rect.ymax - rect.ymin) / 20.0);
  531. }
  532.  
  533.  
  534. void CInputScript::where()
  535. {
  536.     printf("where: %04x [%02x]\n", m_filePos, m_fileBuf[m_filePos]);
  537. }
  538.  
  539.  
  540.  
  541.  
  542. //////////////////////////////////////////////////////////////////////
  543. // Input script object methods.
  544. //////////////////////////////////////////////////////////////////////
  545.  
  546. CInputScript::CInputScript(void)
  547. // Class constructor.
  548. {
  549.     // Initialize the input pointer.
  550.     m_fileBuf = NULL;
  551.  
  552.     // Initialize the file information.
  553.     m_filePos = 0;
  554.     m_fileSize = 0;
  555.     m_fileStart = 0;
  556.     m_fileVersion = 0;
  557.  
  558.     // Initialize the bit position and buffer.
  559.     m_bitPos = 0;
  560.     m_bitBuf = 0;
  561.  
  562.     // Initialize the output file.
  563.     m_outputFile = NULL;
  564.  
  565.     // Set to true if we wish to dump all contents long form
  566.     m_dumpAll = false;
  567.  
  568.     // if set to true will dump image guts (i.e. jpeg, zlib, etc. data)
  569.     m_dumpGuts = false;
  570.  
  571.     // if set to true will dump sound guts
  572.     m_dumpSoundGuts = false;
  573.  
  574.     return;
  575. }
  576.  
  577.  
  578. CInputScript::~CInputScript(void)
  579. // Class destructor.
  580. {
  581.     // Free the buffer if it is there.
  582.     if (m_fileBuf)
  583.     {
  584.         delete m_fileBuf;
  585.         m_fileBuf = NULL;
  586.         m_fileSize = 0;
  587.     }
  588. }
  589.  
  590.  
  591. U16 CInputScript::GetTag(void)
  592. {
  593.     // Save the start of the tag.
  594.     m_tagStart = m_filePos;
  595.     m_tagZero  = m_tagStart;
  596.  
  597.     // Get the combined code and length of the tag.
  598.     U16 wRawCode = GetWord();
  599.     U16 code = wRawCode;
  600.  
  601.     // The length is encoded in the tag.
  602.     U32 len = code & 0x3f;
  603.  
  604.     // Remove the length from the code.
  605.     code = code >> 6;
  606.  
  607.     // Determine if another long word must be read to get the length.
  608.     if (len == 0x3f)
  609.     {
  610.         len = (U32) GetDWord();
  611.         //printf("\nGetTag: long tag: raw-code: %04x len: 0x%08x\n", wRawCode, len);
  612.         m_tagZero += 4;
  613.     }
  614.  
  615.     //printf("->> GetTag: code:%04x len:%08x\n", code, len);
  616.  
  617.     // Determine the end position of the tag.
  618.     m_tagEnd = m_filePos + (U32) len;
  619.     m_tagLen = (U32) len;
  620.  
  621.     return code;
  622. }
  623.  
  624.  
  625. void CInputScript::GetRect (SRECT * r)
  626. {
  627.     InitBits();
  628.     int nBits = (int) GetBits(5);
  629.     r->xmin = GetSBits(nBits);
  630.     r->xmax = GetSBits(nBits);
  631.     r->ymin = GetSBits(nBits);
  632.     r->ymax = GetSBits(nBits);
  633. }
  634.  
  635.  
  636. void CInputScript::GetMatrix(MATRIX* mat)
  637. {
  638.     InitBits();
  639.  
  640.     // Scale terms
  641.     if (GetBits(1))
  642.     {
  643.         int nBits = (int) GetBits(5);
  644.         mat->a = GetSBits(nBits);
  645.         mat->d = GetSBits(nBits);
  646.     }
  647.     else
  648.     {
  649.         mat->a = mat->d = 0x00010000L;
  650.     }
  651.  
  652.     // Rotate/skew terms
  653.     if (GetBits(1))
  654.     {
  655.         int nBits = (int)GetBits(5);
  656.         mat->b = GetSBits(nBits);
  657.         mat->c = GetSBits(nBits);
  658.     }
  659.     else
  660.     {
  661.         mat->b = mat->c = 0;
  662.     }
  663.  
  664.     // Translate terms
  665.     int nBits = (int) GetBits(5);
  666.     mat->tx = GetSBits(nBits);
  667.     mat->ty = GetSBits(nBits);
  668. }
  669.  
  670.  
  671. void CInputScript::GetCxform(CXFORM* cx, BOOL hasAlpha)
  672. {
  673.     InitBits();
  674.  
  675.     // !!! The spec has these bits reversed !!!
  676.     BOOL fNeedAdd = (GetBits(1) != 0);
  677.     BOOL fNeedMul = (GetBits(1) != 0);
  678.     // !!! The spec has these bits reversed !!!
  679.  
  680.     //printf("fNeedMul:%d fNeedAdd:%d\n", fNeedMul, fNeedAdd);
  681.  
  682.     int nBits = (int) GetBits(4);
  683.  
  684.     cx->aa = 256; cx->ab = 0;
  685.     if (fNeedMul)
  686.     {
  687.         cx->ra = (S16) GetSBits(nBits);
  688.         cx->ga = (S16) GetSBits(nBits);
  689.         cx->ba = (S16) GetSBits(nBits);
  690.         if (hasAlpha) cx->aa = (S16) GetSBits(nBits);
  691.     }
  692.     else
  693.     {
  694.         cx->ra = cx->ga = cx->ba = 256;
  695.     }
  696.  
  697.     if (fNeedAdd)
  698.     {
  699.         cx->rb = (S16) GetSBits(nBits);
  700.         cx->gb = (S16) GetSBits(nBits);
  701.         cx->bb = (S16) GetSBits(nBits);
  702.         if (hasAlpha) cx->ab = (S16) GetSBits(nBits);
  703.     }
  704.     else
  705.     {
  706.         cx->rb = cx->gb = cx->bb = 0;
  707.     }
  708. }
  709.  
  710. void CInputScript::PrintCxform(char* str, CXFORM* pCxform)
  711. {
  712.     printf("%sCXFORM:\n", str);
  713.     printf("%sAlpha:  mul:%04u  add:%04u\n",str, pCxform->aa, pCxform->ab);
  714.     printf("%sRed:    mul:%04u  add:%04u\n",str, pCxform->ra, pCxform->rb);
  715.     printf("%sGreen:  mul:%04u  add:%04u\n",str, pCxform->ga, pCxform->gb);
  716.     printf("%sBlue:   mul:%04u  add:%04u\n",str, pCxform->ba, pCxform->bb);
  717. }
  718.  
  719. char *CInputScript::GetString(void)
  720. {
  721.     // Point to the string.
  722.     char *str = (char *) &m_fileBuf[m_filePos];
  723.  
  724.     // Skip over the string.
  725.     while (GetByte());
  726.  
  727.     return str;
  728. }
  729.  
  730. U32 CInputScript::GetColor(BOOL fWithAlpha)
  731. {
  732.     U32 r = GetByte();
  733.     U32 g = GetByte();
  734.     U32 b = GetByte();
  735.     U32 a = 0xff;
  736.  
  737.     if (fWithAlpha)
  738.         a = GetByte();
  739.  
  740.     return (a << 24) | (r << 16) | (g << 8) | b;
  741. }
  742.  
  743. void CInputScript::InitBits(void)
  744. {
  745.     // Reset the bit position and buffer.
  746.     m_bitPos = 0;
  747.     m_bitBuf = 0;
  748. }
  749.  
  750.  
  751. S32 CInputScript::GetSBits(S32 n)
  752. // Get n bits from the string with sign extension.
  753. {
  754.     // Get the number as an unsigned value.
  755.     S32 v = (S32) GetBits(n);
  756.  
  757.     // Is the number negative?
  758.     if (v & (1L << (n - 1)))
  759.     {
  760.         // Yes. Extend the sign.
  761.         v |= -1L << n;
  762.     }
  763.  
  764.     return v;
  765. }
  766.  
  767.  
  768. U32 CInputScript::GetBits (S32 n)
  769. // Get n bits from the stream.
  770. {
  771.     U32 v = 0;
  772.  
  773.     while (true)
  774.     {
  775.         //if (m_bitPos == 0)
  776.         //  printf("bitPos is ZERO: m_bitBuf: %02x\n", m_bitBuf);
  777.  
  778.         S32 s = n - m_bitPos;
  779.         if (s > 0)
  780.         {
  781.             // Consume the entire buffer
  782.             v |= m_bitBuf << s;
  783.             n -= m_bitPos;
  784.  
  785.             // Get the next buffer
  786.             m_bitBuf = GetByte();
  787.             m_bitPos = 8;
  788.         }
  789.         else
  790.         {
  791.             // Consume a portion of the buffer
  792.             v |= m_bitBuf >> -s;
  793.             m_bitPos -= n;
  794.             m_bitBuf &= 0xff >> (8 - m_bitPos); // mask off the consumed bits
  795.  
  796.             //printf("GetBits: nBitsToRead:%d m_bitPos:%d m_bitBuf:%02x v:%d\n", nBitsToRead, m_bitPos, m_bitBuf, v);
  797.             return v;
  798.         }
  799.     }
  800. }
  801.  
  802.  
  803. void CInputScript::ParseEnd(char *str)
  804. {
  805.     printf("%stagEnd\n", str);
  806. }
  807.  
  808.  
  809. void CInputScript::ParseShowFrame(char *str, U32 frame, U32 offset)
  810. {
  811.     printf("%stagShowFrame\n", str);
  812.     printf("\n%s<----- dumping frame %d file offset 0x%04x ----->\n", str, frame + 1, offset);
  813. }
  814.  
  815.  
  816. void CInputScript::ParseFreeCharacter(char *str)
  817. {
  818.     U32 tagid = (U32) GetWord();
  819.     printf("%stagFreeCharacter \ttagid %-5u\n", str, tagid);
  820. }
  821.  
  822.  
  823. void CInputScript::ParsePlaceObject(char *str)
  824. {
  825.     U32 tagid = (U32) GetWord();
  826.     U32 depth = (U32) GetWord();
  827.  
  828.     printf("%stagPlaceObject \ttagid %-5u depth %-5u\n", str, tagid, depth);
  829.  
  830.     if (!m_dumpAll)
  831.         return;
  832.  
  833.     MATRIX matrix;
  834.     GetMatrix(&matrix);
  835.     PrintMatrix(matrix, str);
  836.  
  837.     if (m_filePos < m_tagEnd)
  838.     {
  839.         CXFORM cxform;
  840.         GetCxform(&cxform, false);
  841.         PrintCxform(str, &cxform);
  842.     }
  843. }
  844.  
  845.  
  846. void CInputScript::ParsePlaceObject2(char *str)
  847. {
  848.     U8 flags = GetByte();
  849.     U32 depth = GetWord();
  850.  
  851.     printf("%stagPlaceObject2 \tflags %-5u depth %-5u ", str, (int) flags, (int) depth);
  852.  
  853.     if ( flags & splaceMove )
  854.         printf("move ");
  855.  
  856.     // Get the tag if specified.
  857.     if (flags & splaceCharacter)
  858.     {
  859.         U32 tag = GetWord();
  860.         printf("tag %-5u\n", tag);
  861.     }
  862.     else
  863.     {
  864.         printf("\n");
  865.     }
  866.  
  867.     // Get the matrix if specified.
  868.     if (flags & splaceMatrix)
  869.     {
  870.         // this one gets called
  871.  
  872.         MATRIX matrix;
  873.         GetMatrix(&matrix);
  874.         PrintMatrix(matrix, str);
  875.     }
  876.  
  877.     // Get the color transform if specified.
  878.     if (flags & splaceColorTransform)
  879.     {
  880.         CXFORM cxform;
  881.         GetCxform(&cxform, true);
  882.         PrintCxform(str, &cxform);
  883.     }
  884.  
  885.     // Get the ratio if specified.
  886.     if (flags & splaceRatio)
  887.     {
  888.         U32 ratio = GetWord();
  889.  
  890.         INDENT;
  891.         printf("%ratio %u\n", ratio);
  892.     }
  893.  
  894.     // Get the clipdepth if specified.
  895.     if (flags & splaceDefineClip)
  896.     {
  897.         U32 clipDepth = GetWord();
  898.         INDENT;
  899.         printf("clipDepth %i\n", clipDepth);
  900.     }
  901.  
  902.     // Get the instance name
  903.     if (flags & splaceName)
  904.     {
  905.         char* pszName = GetString();
  906.         INDENT;
  907.         printf("instance name %s\n", pszName);
  908.     }
  909.  
  910.     if (!m_dumpAll)
  911.         return;
  912. }
  913.  
  914.  
  915. void CInputScript::ParseRemoveObject(char *str)
  916. {
  917.     U32 tagid = (U32) GetWord();
  918.     U32 depth = (U32) GetWord();
  919.  
  920.     printf("%stagRemoveObject \ttagid %-5u depth %-5u\n", str, tagid, depth);
  921. }
  922.  
  923.  
  924. void CInputScript::ParseRemoveObject2(char *str)
  925. {
  926.     U32 depth = (U32) GetWord();
  927.  
  928.     printf("%stagRemoveObject2 depth %-5u\n", str, depth);
  929. }
  930.  
  931.  
  932. void CInputScript::ParseSetBackgroundColor(char *str)
  933. {
  934.     U32 r = GetByte();
  935.     U32 g = GetByte();
  936.     U32 b = GetByte();
  937.     U32 color = (r << 16) | (g << 8) | b;
  938.  
  939.     printf("%stagSetBackgroundColor \tRGB_HEX %06x\n", str, color);
  940. }
  941.  
  942.  
  943.  
  944.  
  945. void CInputScript::ParseStartSound(char *str)
  946. {
  947.     U32 tagid = (U32) GetWord();
  948.  
  949.     printf("%stagStartSound \ttagid %-5u\n", str, tagid);
  950.  
  951.     if (!m_dumpAll)
  952.         return;
  953.  
  954.     U32 code = GetByte();
  955.     INDENT;
  956.     printf("%scode %-3u", str, code);
  957.  
  958.     if ( code & soundHasInPoint )
  959.         printf(" inpoint %u ", GetDWord());
  960.     if ( code & soundHasOutPoint )
  961.         printf(" oupoint %u", GetDWord());
  962.     if ( code & soundHasLoops )
  963.         printf(" loops %u", GetDWord());
  964.  
  965.     printf("\n");
  966.     if ( code & soundHasEnvelope )
  967.     {
  968.         int points = GetByte();
  969.  
  970.         for ( int i = 0; i < points; i++ )
  971.         {
  972.             printf("\n");
  973.             INDENT;
  974.             printf("%smark44 %u", str, GetDWord());
  975.             printf(" left chanel %u", GetWord());
  976.             printf(" right chanel %u", GetWord());
  977.             printf("\n");
  978.         }
  979.     }
  980. }
  981.  
  982.  
  983. void CInputScript::ParseStopSound(char *str)
  984. {
  985.     printf("%stagStopSound\n", str);
  986. }
  987.  
  988.  
  989. void CInputScript::ParseProtect(char *str)
  990. {
  991.     printf("%stagProtect\n", str);
  992. }
  993.  
  994. BOOL CInputScript::ParseShapeRecord(char *str, int& xLast, int& yLast, BOOL fWithAlpha)
  995. {
  996.     // Determine if this is an edge.
  997.     BOOL isEdge = (BOOL) GetBits(1);
  998.  
  999.     if (!isEdge)
  1000.     {
  1001.         // Handle a state change
  1002.         U16 flags = (U16) GetBits(5);
  1003.  
  1004.         // Are we at the end?
  1005.         if (flags == 0)
  1006.         {
  1007.             printf("\tEnd of shape.\n\n");
  1008.             return true;
  1009.         }
  1010.  
  1011.         // Process a move to.
  1012.         if (flags & eflagsMoveTo)
  1013.         {
  1014.             U16 nBits = (U16) GetBits(5);
  1015.             S32 x = GetSBits(nBits);
  1016.             S32 y = GetSBits(nBits);
  1017.             //printf("\tmoveto: nBits:%d x:%d y:%d\n", nBits, x, y);
  1018.             xLast = x;
  1019.             yLast = y;
  1020.             printf("\n\tmoveto: (%g,%g)\n", double(xLast)/20.0, double(yLast)/20.0);
  1021.         }
  1022.         // Get new fill info.
  1023.         if (flags & eflagsFill0)
  1024.         {
  1025.             int i = GetBits(m_nFillBits);
  1026.             printf("\tFillStyle0: %d (%d bits)\n", i, m_nFillBits);
  1027.         }
  1028.         if (flags & eflagsFill1)
  1029.         {
  1030.             int i = GetBits(m_nFillBits);
  1031.             printf("\tFillStyle1: %d (%d bits)\n", i, m_nFillBits);
  1032.         }
  1033.         // Get new line info
  1034.         if (flags & eflagsLine)
  1035.         {
  1036.             int i = GetBits(m_nLineBits);
  1037.             printf("\tLineStyle: %d\n", i);
  1038.         }
  1039.         // Check to get a new set of styles for a new shape layer.
  1040.         if (flags & eflagsNewStyles)
  1041.         {
  1042.             printf("\tFound more Style info\n");
  1043.  
  1044.             // Parse the style.
  1045.             ParseShapeStyle(str, fWithAlpha);
  1046.  
  1047.             // Reset.
  1048.             m_nFillBits = (U16) GetBits(4);
  1049.             m_nLineBits = (U16) GetBits(4);
  1050.  
  1051.             //printf("\tm_nFillBits:%d  m_nLineBits:%d\n", m_nFillBits, m_nLineBits);
  1052.         }
  1053.         if (flags & eflagsEnd)
  1054.         {
  1055.             printf("\tEnd of shape.\n\n");
  1056.         }
  1057.  
  1058.         return flags & eflagsEnd ? true : false;
  1059.     }
  1060.     else
  1061.     {
  1062.         if (GetBits(1))
  1063.         {
  1064.             // Handle a line
  1065.             U16 nBits = (U16) GetBits(4) + 2;   // nBits is biased by 2
  1066.  
  1067.             // Save the deltas
  1068.             if (GetBits(1))
  1069.             {
  1070.                 // Handle a general line.
  1071.                 S32 x = GetSBits(nBits);
  1072.                 S32 y = GetSBits(nBits);
  1073.                 xLast += x;
  1074.                 yLast += y;
  1075.  
  1076.                 printf("\tlineto: (%g,%g).\n", double(xLast)/20.0, double(yLast)/20.0);
  1077.             }
  1078.             else
  1079.             {
  1080.                 // Handle a vert or horiz line.
  1081.                 if (GetBits(1))
  1082.                 {
  1083.                     // Vertical line
  1084.                     S32 y = GetSBits(nBits);
  1085.                     yLast += y;
  1086.  
  1087.                     printf("\tvlineto: (%g,%g).\n", double(xLast)/20.0, double(yLast)/20.0);
  1088.                 }
  1089.                 else
  1090.                 {
  1091.                     // Horizontal line
  1092.                     S32 x = GetSBits(nBits);
  1093.                     xLast += x;
  1094.  
  1095.                     printf("\thlineto: (%g,%g).\n", double(xLast)/20.0, double(yLast)/20.0);
  1096.                 }
  1097.             }
  1098.         }
  1099.         else
  1100.         {
  1101.             // Handle a curve
  1102.             U16 nBits = (U16) GetBits(4) + 2;   // nBits is biased by 2
  1103.  
  1104.             // Get the control
  1105.             S32 cx = GetSBits(nBits);
  1106.             S32 cy = GetSBits(nBits);
  1107.             xLast += cx;
  1108.             yLast += cy;
  1109.  
  1110.             printf("\tcurveto: (%g,%g)", double(xLast)/20.0, double(yLast)/20.0);
  1111.  
  1112.             // Get the anchor
  1113.             S32 ax = GetSBits(nBits);
  1114.             S32 ay = GetSBits(nBits);
  1115.             xLast += ax;
  1116.             yLast += ay;
  1117.  
  1118.             printf("(%g,%g)\n", double(xLast)/20.0, double(yLast)/20.0);
  1119.         }
  1120.  
  1121.         return false;
  1122.     }
  1123. }
  1124.  
  1125. void CInputScript::ParseShapeStyle(char *str, BOOL fWithAlpha)
  1126. {
  1127.     U16 i = 0;
  1128.  
  1129.     // Get the number of fills.
  1130.     U16 nFills = GetByte();
  1131.  
  1132.     // Do we have a larger number?
  1133.     if (nFills == 255)
  1134.     {
  1135.         // Get the larger number.
  1136.         nFills = GetWord();
  1137.     }
  1138.  
  1139.     printf("\tNumber of fill styles \t%u\n", nFills);
  1140.  
  1141.     // Get each of the fill style.
  1142.     for (i = 1; i <= nFills; i++)
  1143.     {
  1144.         U16 fillStyle = GetByte();
  1145.  
  1146.         if (fillStyle & fillGradient)
  1147.         {
  1148.             // Get the gradient matrix.
  1149.             MATRIX mat;
  1150.             GetMatrix(&mat);
  1151.  
  1152.             // Get the number of colors.
  1153.             U16 nColors = (U16) GetByte();
  1154.             printf("%s\tGradient Fill with %u colors\n", str, nColors);
  1155.  
  1156.             // Get each of the colors.
  1157.             for (U16 j = 0; j < nColors; j++)
  1158.             {
  1159.                 U8 pos = GetByte();
  1160.                 U32 rgba = GetColor(fWithAlpha);
  1161.                 printf("%s\tcolor:%d: at:%d  RGBA:%08x\n", str, j, pos, rgba);
  1162.             }
  1163.             printf("%s\tGradient Matrix:\n", str);
  1164.             PrintMatrix(mat, str);
  1165.         }
  1166.         else if (fillStyle & fillBits)
  1167.         {
  1168.             // Get the bitmap matrix.
  1169.             U16 uBitmapID = GetWord();
  1170.             printf("%s\tBitmap Fill: %04x\n", str, uBitmapID);
  1171.             MATRIX mat;
  1172.             GetMatrix(&mat);
  1173.             PrintMatrix(mat, str);
  1174.         }
  1175.         else
  1176.         {
  1177.             // A solid color
  1178.             U32 color = GetColor(fWithAlpha);
  1179.             printf("%s\tSolid Color Fill RGB_HEX %06x\n", str, color);
  1180.         }
  1181.     }
  1182.  
  1183.     // Get the number of lines.
  1184.     U16 nLines = GetByte();
  1185.  
  1186.     // Do we have a larger number?
  1187.     if (nLines == 255)
  1188.     {
  1189.         // Get the larger number.
  1190.         nLines = GetWord();
  1191.     }
  1192.  
  1193.     printf("\tNumber of line styles \t%u\n", nLines);
  1194.  
  1195.     // Get each of the line styles.
  1196.     for (i = 1; i <= nLines; i++)
  1197.     {
  1198.         U16 width = GetWord();
  1199.         U32 color = GetColor(fWithAlpha);
  1200.  
  1201.         printf("\tLine style %-5u width %g color RGB_HEX %06x\n", i, (double)width/20.0, color);
  1202.     }
  1203. }
  1204.  
  1205. void CInputScript::ParseDefineShape(char *str, BOOL fWithAlpha)
  1206. {
  1207.     U32 tagid = (U32) GetWord();
  1208.     printf("%stagDefineShape \ttagid %-5u\n", str, tagid);
  1209.  
  1210.     // Get the bounding rectangle
  1211.     SRECT rect;
  1212.     GetRect(&rect);
  1213.  
  1214.     ParseShapeStyle(str, fWithAlpha);
  1215.  
  1216.     InitBits();     // Bug!  this was not in the original swfparse.cpp
  1217.                     // Required to reset bit counters and read byte aligned.
  1218.  
  1219.     m_nFillBits = (U16) GetBits(4);
  1220.     m_nLineBits = (U16) GetBits(4);
  1221.  
  1222.     //printf("%sm_nFillBits:%d  m_nLineBits:%d\n", str, m_nFillBits, m_nLineBits);
  1223.  
  1224.     int xLast = 0;
  1225.     int yLast = 0;
  1226.  
  1227.     BOOL atEnd = false;
  1228.     while (!atEnd)
  1229.         atEnd = ParseShapeRecord(str, xLast, yLast, fWithAlpha);
  1230. }
  1231.  
  1232.  
  1233. void CInputScript::ParseDefineShape2(char *str)
  1234. {
  1235.     printf("%stagDefineShape2 -> ", str);
  1236.     ParseDefineShape(str);
  1237.     //U32 tagid = (U32) GetWord();
  1238.     //printf("%stagDefineShape2 \ttagid %-5u\n", str, tagid);
  1239. }
  1240.  
  1241.  
  1242. void CInputScript::ParseDefineShape3(char *str)
  1243. {
  1244.     printf("%stagDefineShape3: -> ", str);
  1245.     ParseDefineShape(str, true);
  1246.     //U32 tagid = (U32) GetWord();
  1247.     //printf("%stagDefineShape3 \ttagid %-5u\n", str, tagid);
  1248. }
  1249.  
  1250.  
  1251. void CInputScript::S_DumpImageGuts(char *str)
  1252. {
  1253.     U32 lfCount = 0;
  1254.     INDENT;
  1255.     printf("%s----- dumping image details -----", str);
  1256.     while (m_filePos < m_tagEnd)
  1257.     {
  1258.         if ((lfCount % 16) == 0)
  1259.         {
  1260.             printf("\n");
  1261.             INDENT;
  1262.             printf("%s", str);
  1263.         }
  1264.         lfCount += 1;
  1265.         printf("%02x ", GetByte());
  1266.     }
  1267.     printf("\n");
  1268. }
  1269.  
  1270. void CInputScript::ParseDefineBits(char *str)
  1271. {
  1272.     U32 tagid = (U32) GetWord();
  1273.  
  1274.     printf("%stagDefineBits \ttagid %-5u\n", str, tagid);
  1275.  
  1276.     if (!m_dumpGuts)
  1277.         return;
  1278.  
  1279.     S_DumpImageGuts(str);
  1280. }
  1281.  
  1282.  
  1283. void CInputScript::ParseDefineBitsJPEG2(char *str)
  1284. {
  1285.     U32 tagid = (U32) GetWord();
  1286.  
  1287.     printf("%stagDefineBitsJPEG2 \ttagid %-5u\n", str, tagid);
  1288.  
  1289.     if (!m_dumpGuts)
  1290.         return;
  1291.  
  1292.     //S_DumpImageGuts(str);
  1293. }
  1294.  
  1295.  
  1296. void CInputScript::ParseDefineBitsJPEG3(char *str)
  1297. {
  1298.     U32 tagid = (U32) GetWord();
  1299.  
  1300.     printf("%stagDefineBitsJPEG3 \ttagid %-5u\n", str, tagid);
  1301.  
  1302.     if (!m_dumpGuts)
  1303.         return;
  1304.  
  1305.     S_DumpImageGuts(str);
  1306. }
  1307.  
  1308. void CInputScript::ParseDefineBitsLossless(char *str)
  1309. {
  1310.     U32 tagid = (U32) GetWord();
  1311.  
  1312.     printf("%stagDefineBitsLossless tagid %-5u\n", str, tagid);
  1313.  
  1314.     if (!m_dumpAll)
  1315.         return;
  1316.  
  1317.     int format = GetByte();
  1318.     int width  =  GetWord();
  1319.     int height = GetWord();
  1320.     int tableSize = 0;
  1321.  
  1322.     if (format == 3)
  1323.         tableSize = GetByte();
  1324.  
  1325.     //INDENT;
  1326.     printf("%sformat %-3u width %-5u height %-5u tableSize %d\n", str, format, width, height, tableSize);
  1327.  
  1328.     tableSize += 1;
  1329.  
  1330.     z_stream    stream;
  1331.     unsigned char*  buffer = &m_fileBuf[m_filePos];
  1332.     unsigned char*  colorTable = new unsigned char[tableSize*3];
  1333.  
  1334.     stream.next_in = buffer;
  1335.     stream.avail_in = 1;
  1336.     stream.zalloc = Z_NULL;
  1337.     stream.zfree = Z_NULL;
  1338.  
  1339.  
  1340.     stream.next_out = colorTable;
  1341.     stream.avail_out = tableSize*3;
  1342.  
  1343.     inflateInit(&stream);
  1344.  
  1345.     int status;
  1346.     while (1)
  1347.     {
  1348.         status = inflate(&stream, Z_SYNC_FLUSH);
  1349.         if (status == Z_STREAM_END)
  1350.             break;
  1351.         if (status != Z_OK)
  1352.         {
  1353.             printf("Zlib cmap error : %s\n", stream.msg);
  1354.             return;
  1355.         }
  1356.         stream.avail_in = 1;
  1357.         // Colormap if full
  1358.         if (stream.avail_out == 0)
  1359.             break;
  1360.     }
  1361.  
  1362.     printf("\n");
  1363.     for (int i=0; i<tableSize*3; i+=3)
  1364.     {
  1365.         printf("%02x%02x%02x ", colorTable[i], colorTable[i+1], colorTable[i+2]);
  1366.         if ((i % 24) == 21)
  1367.             printf("\n");
  1368.     }
  1369.  
  1370.     unsigned char* data = new unsigned char[width*height];
  1371.  
  1372.     stream.next_out = data;
  1373.     stream.avail_out = width*height;
  1374.  
  1375.  
  1376.     while (1)
  1377.     {
  1378.         status = inflate(&stream, Z_SYNC_FLUSH) ;
  1379.         if (status == Z_STREAM_END)
  1380.             break;
  1381.  
  1382.         if (status != Z_OK)
  1383.         {
  1384.             printf("Zlib data error : %s\n", stream.msg);
  1385.             return;
  1386.         }
  1387.         stream.avail_in = 1;
  1388.     }
  1389.  
  1390.     inflateEnd(&stream);
  1391.  
  1392.     printf("\n");
  1393.     i = 0;
  1394.     for (int y=0; y<height; y++)
  1395.     {
  1396.         for (int x=0; x<width; x++, i++)
  1397.         {
  1398.             printf("%02x", data[i]);
  1399.         }
  1400.         printf("\n");
  1401.     }
  1402.     printf("\n");
  1403.  
  1404.  
  1405.  
  1406.     if (!m_dumpGuts)
  1407.         return;
  1408.  
  1409.     S_DumpImageGuts(str);
  1410. }
  1411.  
  1412. void CInputScript::ParseDefineBitsLossless2(char *str)
  1413. {
  1414.     ParseDefineBitsLossless(str);
  1415. }
  1416.  
  1417. void CInputScript::ParseJPEGTables(char *str)
  1418. {
  1419.     printf("%stagJPEGTables\n", str);
  1420.  
  1421.     if (!m_dumpGuts)
  1422.         return;
  1423.  
  1424.     S_DumpImageGuts(str);
  1425. }
  1426.  
  1427.  
  1428. void CInputScript::ParseButtonRecord(char *str, U32 iByte, BOOL fGetColorMatrix)
  1429. {
  1430.     U32 iPad = iByte >> 4;
  1431.     U32 iButtonStateHitTest = (iByte & 0x8);
  1432.     U32 iButtonStateDown = (iByte & 0x4);
  1433.     U32 iButtonStateOver = (iByte & 0x2);
  1434.     U32 iButtonStateUp = (iByte & 0x1);
  1435.  
  1436.     U32 iButtonCharacter = (U32)GetWord();
  1437.     U32 iButtonLayer = (U32)GetWord();
  1438.  
  1439.     printf("%s\tParseButtonRecord: char:%d layer:%d ", str, iButtonCharacter, iButtonLayer);
  1440.  
  1441.     if (iButtonStateHitTest != 0)   printf("HIT ");
  1442.     if (iButtonStateDown != 0)      printf("DOWN ");
  1443.     if (iButtonStateOver != 0)      printf("OVER ");
  1444.     if (iButtonStateUp != 0)        printf("UP ");
  1445.     printf("\n");
  1446.  
  1447.     MATRIX matrix;
  1448.     GetMatrix(&matrix);
  1449.     PrintMatrix(matrix, str);
  1450.  
  1451.     if (fGetColorMatrix)
  1452.     {
  1453.         // nCharactersInButton always seems to be one
  1454.         int nCharactersInButton = 1;
  1455.  
  1456.         for (int i=0; i<nCharactersInButton; i++)
  1457.         {
  1458.             CXFORM cxform;
  1459.             GetCxform(&cxform, true);   // ??could be false here??
  1460.         }
  1461.     }
  1462. }
  1463.  
  1464. void CInputScript::ParseDefineButton(char *str)
  1465. {
  1466.     U32 tagid = (U32) GetWord();
  1467.  
  1468.     U32 iButtonEnd = (U32)GetByte();
  1469.     do
  1470.         ParseButtonRecord(str, iButtonEnd, false);
  1471.     while ((iButtonEnd = (U32)GetByte()) != 0);
  1472.  
  1473.     // parse ACTIONRECORDs until ActionEndFlag
  1474.     ParseDoAction(str, false);
  1475. }
  1476.  
  1477. void CInputScript::ParseDefineButton2(char *str)
  1478. {
  1479.     U32 tagid = (U32) GetWord();
  1480.  
  1481.     printf("%stagDefineButton2 \ttagid %-5u\n", str, tagid);
  1482.  
  1483.     U32 iTrackAsMenu = (U32) GetByte();
  1484.  
  1485.     // Get offset to first "Button2ActionCondition"
  1486.     // This offset is not in the spec!
  1487.     U32 iOffset = (U32) GetWord();
  1488.     U32 iNextAction = m_filePos + iOffset - 2;
  1489.  
  1490.     //
  1491.     // Parse Button Records
  1492.     //
  1493.  
  1494.     U32 iButtonEnd = (U32)GetByte();
  1495.     do
  1496.         ParseButtonRecord(str, iButtonEnd, true);
  1497.     while ((iButtonEnd = (U32)GetByte()) != 0);
  1498.  
  1499.     //
  1500.     // Parse Button2ActionConditions
  1501.     //
  1502.  
  1503.     m_filePos = iNextAction;
  1504.  
  1505.     U32 iActionOffset = 0;
  1506.     while (true)
  1507.     {
  1508.         iActionOffset = (U32) GetWord();
  1509.         //printf("iActionOffset: %04x\n", iActionOffset);
  1510.         iNextAction  = m_filePos + iActionOffset - 2;
  1511.  
  1512.         U32 iCondition = (U32) GetWord();
  1513.  
  1514.         printf("%sCondition: %04x\n", str, iCondition);
  1515.  
  1516.         // parse ACTIONRECORDs until ActionEndFlag
  1517.         ParseDoAction(str, false);
  1518.  
  1519.         // Action Offset of zero means there's no more
  1520.         if (iActionOffset == 0)
  1521.             break;
  1522.  
  1523.         m_filePos = iNextAction;
  1524.     }
  1525.  
  1526.     printf("\n");
  1527. }
  1528.  
  1529. void CInputScript::ParseDoAction(char *str, BOOL fPrintTag)
  1530. {
  1531.     if (fPrintTag)
  1532.     {
  1533.         printf("%stagDoAction\n",  str);
  1534.     }
  1535.  
  1536.     for (;;)
  1537.     {
  1538.         // Handle the action
  1539.         int actionCode = GetByte();
  1540.         INDENT;
  1541.         printf("%saction code 0x%02x ", str, actionCode);
  1542.         if (actionCode == 0)
  1543.         {
  1544.             // Action code of zero indicates end of actions
  1545.             printf("\n");
  1546.             return;
  1547.         }
  1548.  
  1549.         int len = 0;
  1550.         if (actionCode & sactionHasLength)
  1551.         {
  1552.             len = GetWord();
  1553.             printf("has length %-5u ", len);
  1554.         }
  1555.  
  1556.         S32 pos = m_filePos + len;
  1557.  
  1558.         switch ( actionCode )
  1559.         {
  1560.             case sactionNextFrame:
  1561.             {
  1562.                 printf( "gotoNextFrame\n" );
  1563.                 break;
  1564.             }
  1565.  
  1566.             case sactionPrevFrame:
  1567.             {
  1568.                 printf( "gotoPrevFrame\n" );
  1569.                 break;
  1570.             }
  1571.  
  1572.             case sactionPlay:
  1573.             {
  1574.                 printf( "play\n" );
  1575.                 break;
  1576.             }
  1577.  
  1578.             case sactionStop:
  1579.             {
  1580.                 printf( "stop\n" );
  1581.                 break;
  1582.             }
  1583.  
  1584.             case sactionToggleQuality:
  1585.             {
  1586.                 printf( "toggleQuality\n" );
  1587.                 break;
  1588.             }
  1589.  
  1590.             case sactionStopSounds:
  1591.             {
  1592.                 printf( "stopSounds\n" );
  1593.                 break;
  1594.             }
  1595.  
  1596.             case sactionAdd:
  1597.             {
  1598.                 printf( "add\n" );
  1599.                 break;
  1600.             }
  1601.  
  1602.             case sactionSubtract:
  1603.             {
  1604.                 printf( "subtract\n" );
  1605.                 break;
  1606.             }
  1607.  
  1608.             case sactionMultiply:
  1609.             {
  1610.                 printf( "multiply\n" );
  1611.                 break;
  1612.             }
  1613.  
  1614.             case sactionDivide:
  1615.             {
  1616.                 printf( "divide\n" );
  1617.                 break;
  1618.             }
  1619.  
  1620.             case sactionEqual:
  1621.             {
  1622.                 printf( "equal\n" );
  1623.                 break;
  1624.             }
  1625.  
  1626.             case sactionLessThan:
  1627.             {
  1628.                 printf( "lessThan\n" );
  1629.                 break;
  1630.             }
  1631.  
  1632.             case sactionLogicalAnd:
  1633.             {
  1634.                 printf( "logicalAnd\n" );
  1635.                 break;
  1636.             }
  1637.  
  1638.             case sactionLogicalOr:
  1639.             {
  1640.                 printf( "logicalOr\n" );
  1641.                 break;
  1642.             }
  1643.  
  1644.             case sactionLogicalNot:
  1645.             {
  1646.                 printf( "logicalNot\n" );
  1647.                 break;
  1648.             }
  1649.  
  1650.             case sactionStringEqual:
  1651.             {
  1652.                 printf( "stringEqual\n" );
  1653.                 break;
  1654.             }
  1655.  
  1656.             case sactionStringLength:
  1657.             {
  1658.                 printf( "stringLength\n" );
  1659.                 break;
  1660.             }
  1661.  
  1662.             case sactionSubString:
  1663.             {
  1664.                 printf( "subString\n" );
  1665.                 break;
  1666.             }
  1667.  
  1668.             case sactionInt:
  1669.             {
  1670.                 printf( "int\n" );
  1671.                 break;
  1672.             }
  1673.  
  1674.             case sactionEval:
  1675.             {
  1676.                 printf( "eval\n" );
  1677.                 break;
  1678.             }
  1679.  
  1680.             case sactionSetVariable:
  1681.             {
  1682.                 printf( "setVariable\n" );
  1683.                 break;
  1684.             }
  1685.  
  1686.             case sactionSetTargetExpression:
  1687.             {
  1688.                 printf( "setTargetExpression\n" );
  1689.                 break;
  1690.             }
  1691.  
  1692.             case sactionStringConcat:
  1693.             {
  1694.                 printf( "stringConcat\n" );
  1695.                 break;
  1696.             }
  1697.  
  1698.             case sactionGetProperty:
  1699.             {
  1700.                 printf( "getProperty\n" );
  1701.                 break;
  1702.             }
  1703.  
  1704.             case sactionSetProperty:
  1705.             {
  1706.                 printf( "setProperty\n" );
  1707.                 break;
  1708.             }
  1709.  
  1710.             case sactionDuplicateClip:
  1711.             {
  1712.                 printf( "duplicateClip\n" );
  1713.                 break;
  1714.             }
  1715.  
  1716.             case sactionRemoveClip:
  1717.             {
  1718.                 printf( "removeClip\n" );
  1719.                 break;
  1720.             }
  1721.  
  1722.             case sactionTrace:
  1723.             {
  1724.                 printf( "trace\n" );
  1725.                 break;
  1726.             }
  1727.  
  1728.             case sactionStartDragMovie:
  1729.             {
  1730.                 printf( "startDragMovie\n" );
  1731.                 break;
  1732.             }
  1733.  
  1734.             case sactionStopDragMovie:
  1735.             {
  1736.                 printf( "stopDragMovie\n" );
  1737.                 break;
  1738.             }
  1739.  
  1740.             case sactionStringLessThan:
  1741.             {
  1742.                 printf( "stringLessThan\n" );
  1743.                 break;
  1744.             }
  1745.  
  1746.             case sactionRandom:
  1747.             {
  1748.                 printf( "random\n" );
  1749.                 break;
  1750.             }
  1751.  
  1752.             case sactionMBLength:
  1753.             {
  1754.                 printf( "mbLength\n" );
  1755.                 break;
  1756.             }
  1757.  
  1758.             case sactionOrd:
  1759.             {
  1760.                 printf( "ord\n" );
  1761.                 break;
  1762.             }
  1763.  
  1764.             case sactionChr:
  1765.             {
  1766.                 printf( "chr\n" );
  1767.                 break;
  1768.             }
  1769.  
  1770.             case sactionGetTimer:
  1771.             {
  1772.                 printf( "getTimer\n" );
  1773.                 break;
  1774.             }
  1775.  
  1776.             case sactionMBSubString:
  1777.             {
  1778.                 printf( "mbSubString\n" );
  1779.                 break;
  1780.             }
  1781.  
  1782.             case sactionMBOrd:
  1783.             {
  1784.                 printf( "mbOrd\n" );
  1785.                 break;
  1786.             }
  1787.  
  1788.             case sactionMBChr:
  1789.             {
  1790.                 printf( "mbChr\n" );
  1791.                 break;
  1792.             }
  1793.  
  1794.             case sactionGotoFrame:
  1795.             {
  1796.                 printf("gotoFrame %5u\n", GetWord());
  1797.                 break;
  1798.             }
  1799.  
  1800.             case sactionGetURL:
  1801.             {
  1802.                 char *url = GetString();
  1803.                 char *target = GetString();
  1804.                 printf("getUrl %s target %s\n", url, target);
  1805.                 break;
  1806.             }
  1807.  
  1808.             case sactionWaitForFrame:
  1809.             {
  1810.                 int frame = GetWord();
  1811.                 int skipCount = GetByte();
  1812.                 printf("waitForFrame %-5u skipCount %-5u\n", frame, skipCount);
  1813.                 break;
  1814.             }
  1815.  
  1816.             case sactionSetTarget:
  1817.             {
  1818.                 // swfparse used to crash here!
  1819.                 printf("setTarget %s\n", &m_fileBuf[m_filePos]);
  1820.                 break;
  1821.             }
  1822.  
  1823.             case sactionGotoLabel:
  1824.             {
  1825.                 // swfparse used to crash here!
  1826.                 printf("gotoLabel %s\n", &m_fileBuf[m_filePos]);
  1827.                 break;
  1828.             }
  1829.  
  1830.             case sactionWaitForFrameExpression:
  1831.             {
  1832.                 int skipCount = GetByte();
  1833.                 printf( "waitForFrameExpression skipCount %-5u\n", skipCount );
  1834.                 break;
  1835.             }
  1836.  
  1837.             case sactionPushData:
  1838.             {
  1839.                 U8 dataType = GetByte();
  1840.  
  1841.                 // property ids are pushed as floats for some reason
  1842.                 if ( dataType == 1 )
  1843.                 {
  1844.                     union
  1845.                     {
  1846.                         U32 dw;
  1847.                         float f;
  1848.                     } u;
  1849.  
  1850.                     u.dw = GetDWord();
  1851.                     printf("pushData (float): %08x %.1f\n", u.dw, u.f);
  1852.                 }
  1853.                 else
  1854.                 if ( dataType == 0 )
  1855.                 {
  1856.                     printf(
  1857.                         "pushData (string): %s\n",
  1858.                         &m_fileBuf[ m_filePos ]
  1859.                     );
  1860.                 }
  1861.                 else
  1862.                 {
  1863.                     printf(
  1864.                         "pushData invalid dataType: %02x\n",
  1865.                         dataType
  1866.                     );
  1867.                 }
  1868.  
  1869.  
  1870.                 break;
  1871.             }
  1872.  
  1873.             case sactionBranchAlways:
  1874.             {
  1875.                 U16 offset = GetWord();
  1876.                 printf(
  1877.                     "branchAlways offset: %-5u\n",
  1878.                     offset
  1879.                 );
  1880.                 break;
  1881.             }
  1882.  
  1883.             case sactionGetURL2:
  1884.             {
  1885.                 U8 flag = GetByte();
  1886.  
  1887.                 if ( flag == 1 )
  1888.                 {
  1889.                     printf( "getUrl2 sendvars=GET\n" );
  1890.                 }
  1891.                 else
  1892.                 if ( flag == 2 )
  1893.                 {
  1894.                     printf( "getUrl2 sendvars=POST\n" );
  1895.                 }
  1896.                 else
  1897.                 {
  1898.                     printf( "getUrl2 sendvars=Don't send\n" );
  1899.                 }
  1900.                 break;
  1901.             }
  1902.  
  1903.             case sactionBranchIfTrue:
  1904.             {
  1905.                 U16 offset = GetWord();
  1906.                 printf(
  1907.                     "branchIfTrue offset: %-5u\n",
  1908.                     offset
  1909.                 );
  1910.                 break;
  1911.             }
  1912.  
  1913.             case sactionCallFrame:
  1914.             {
  1915.                 printf( "callFrame\n" );
  1916.                 break;
  1917.             }
  1918.  
  1919.             case sactionGotoExpression:
  1920.             {
  1921.                 U8 stopFlag = GetByte();
  1922.                 if ( stopFlag == 0 )
  1923.                 {
  1924.                     printf("gotoExpression and Stop\n" );
  1925.                 }
  1926.                 else
  1927.                 if ( stopFlag == 1 )
  1928.                 {
  1929.                     printf("gotoExpression and Play\n" );
  1930.                 }
  1931.                 else
  1932.                 {
  1933.                     printf("gotoExpression invalid stopFlag: %d\n", stopFlag );
  1934.                 }
  1935.                 break;
  1936.             }
  1937.  
  1938.             default:
  1939.             {
  1940.                 printf("UNKNOWN?\n");
  1941.                 break;
  1942.             }
  1943.         }
  1944.  
  1945.         m_filePos = pos;
  1946.     }
  1947. }
  1948.  
  1949.  
  1950.  
  1951. void CInputScript::ParseDefineFont(char *str)
  1952. {
  1953.     U32 iFontID = (U32)GetWord();
  1954.     printf("%stagDefineFont \t\tFont ID %-5u\n", str, iFontID);
  1955.  
  1956.     int iStart = m_filePos;
  1957.  
  1958.     int iOffset = GetWord();
  1959.     //printf("%s\tiOffset: 0x%04x\n", str, iOffset);
  1960.  
  1961.     int iGlyphCount = iOffset/2;
  1962.     m_iGlyphCounts[iFontID] = iGlyphCount;
  1963.     printf("%s\tnumber of glyphs: %d\n", str, iGlyphCount);
  1964.  
  1965.     int* piOffsetTable = new int[iGlyphCount];
  1966.     piOffsetTable[0] = iOffset;
  1967.  
  1968.     for(int n=1; n<iGlyphCount; n++)
  1969.         piOffsetTable[n] = GetWord();
  1970.  
  1971.     for(n=0; n<iGlyphCount; n++)
  1972.     {
  1973.         m_filePos = piOffsetTable[n] + iStart;
  1974.  
  1975.         InitBits(); // reset bit counter
  1976.  
  1977.         m_nFillBits = (U16) GetBits(4);
  1978.         m_nLineBits = (U16) GetBits(4);
  1979.  
  1980.         //printf("%s\tm_nFillBits:%d m_nLineBits:%d\n", str, m_nFillBits, m_nLineBits);
  1981.  
  1982.         int xLast = 0;
  1983.         int yLast = 0;
  1984.  
  1985.         BOOL fAtEnd = false;
  1986.  
  1987.         while (!fAtEnd)
  1988.             fAtEnd = ParseShapeRecord(str, xLast, yLast);
  1989.     }
  1990.  
  1991.     delete piOffsetTable;
  1992. }
  1993.  
  1994.  
  1995. void CInputScript::ParseDefineFontInfo(char *str)
  1996. {
  1997.     U32 iFontID = (U32) GetWord();
  1998.     printf("%stagDefineFontInfo \tFont ID %-5u\n", str, iFontID);
  1999.  
  2000.     int iNameLen = GetByte();
  2001.     char* pszName = new char[iNameLen+1];
  2002.     for(int n=0; n < iNameLen; n++)
  2003.         pszName[n] = (char)GetByte();
  2004.     pszName[n] = '\0';
  2005.  
  2006.     printf("%s\tFontName: '%s'\n",str, pszName);
  2007.  
  2008.     delete pszName;
  2009.  
  2010.     U8 flags = (FontFlags)GetByte();
  2011.  
  2012.     int iGlyphCount = m_iGlyphCounts[iFontID];
  2013.  
  2014.     int *piCodeTable = new int[iGlyphCount];
  2015.  
  2016.     printf("%s\t", str);
  2017.     for(n=0; n < iGlyphCount; n++)
  2018.     {
  2019.         if (flags & fontWideCodes)
  2020.             piCodeTable[n] = (int)GetWord();
  2021.         else
  2022.             piCodeTable[n] = (int)GetByte();
  2023.         printf("[%d,'%c'] ", piCodeTable[n], (char)piCodeTable[n]);
  2024.     }
  2025.  
  2026.     printf("\n\n");
  2027.  
  2028.     delete piCodeTable;
  2029. }
  2030.  
  2031. BOOL CInputScript::ParseTextRecord(char* str, int nGlyphBits, int nAdvanceBits)
  2032. {
  2033.     U8 flags = (TextFlags)GetByte();
  2034.     if (flags == 0) return 0;
  2035.     printf("\n%s\tflags: 0x%02x\n", str, flags);
  2036.  
  2037.     if (flags & isTextControl)
  2038.     {
  2039.         if (flags & textHasFont)
  2040.         {
  2041.             long fontId = GetWord();
  2042.             printf("%s\tfontId: %d\n", str, fontId);
  2043.         }
  2044.         if (flags & textHasColor)
  2045.         {
  2046.             int r = GetByte();
  2047.             int g = GetByte();
  2048.             int b = GetByte();
  2049.             printf("%s\tfontColour: (%d,%d,%d)\n", str, r, g, b);
  2050.         }
  2051.         if (flags & textHasXOffset)
  2052.         {
  2053.             int iXOffset = GetWord();
  2054.             printf("%s\tX-offset: %d\n", str, iXOffset);
  2055.         }
  2056.         if (flags & textHasYOffset)
  2057.         {
  2058.             int iYOffset = GetWord();
  2059.             printf("%s\tY-offset: %d\n", str, iYOffset);
  2060.         }
  2061.         if (flags & textHasFont)
  2062.         {
  2063.             int iFontHeight = GetWord();
  2064.             printf("%s\tFont Height: %d\n", str, iFontHeight);
  2065.         }
  2066.     }
  2067.     else
  2068.     {
  2069.         int iGlyphCount = flags;
  2070.         printf("%s\tnumber of glyphs: %d\n", str, iGlyphCount);
  2071.  
  2072.         InitBits();     // reset bit counter
  2073.  
  2074.         printf("%s\t", str);
  2075.         for (int g = 0; g < iGlyphCount; g++)
  2076.         {
  2077.             int iIndex = GetBits(nGlyphBits);
  2078.             int iAdvance = GetBits(nAdvanceBits);
  2079.             printf("[%d,%d] ", iIndex, iAdvance);
  2080.         }
  2081.         printf("\n");
  2082.     }
  2083.  
  2084.     return true;
  2085. }
  2086.  
  2087.  
  2088. void CInputScript::ParseDefineText(char *str)
  2089. {
  2090.     U32 tagid = (U32) GetWord();
  2091.     printf("%stagDefineText \t\ttagid %-5u\n", str, tagid);
  2092.  
  2093.     SRECT   rect;
  2094.     GetRect(&rect);
  2095.     PrintRect(rect, str);
  2096.  
  2097.     MATRIX  m;
  2098.     GetMatrix(&m);
  2099.     PrintMatrix(m, str);
  2100.  
  2101.  
  2102.     int nGlyphBits = (int)GetByte();
  2103.     int nAdvanceBits = (int)GetByte();
  2104.  
  2105.     printf("%s\tnGlyphBits:%d nAdvanceBits:%d\n", str, nGlyphBits, nAdvanceBits);
  2106.  
  2107.     BOOL fContinue = true;
  2108.  
  2109.     do
  2110.         fContinue = ParseTextRecord(str, nGlyphBits, nAdvanceBits);
  2111.     while (fContinue);
  2112.  
  2113.     printf("\n");
  2114. }
  2115.  
  2116. void CInputScript::ParseDefineEditText(char* str)
  2117. {
  2118.     U32 tagid = (U32) GetWord();
  2119.  
  2120.     SRECT rBounds;
  2121.     GetRect(&rBounds);
  2122.  
  2123.     U16 flags = GetWord();
  2124.  
  2125.     printf("%stagDefineEditText: tagid %d flags:%04x ", str, tagid, flags);
  2126.  
  2127.     if (flags & seditTextFlagsHasFont)
  2128.     {
  2129.         U16 uFontId = GetWord();
  2130.         U16 uFontHeight = GetWord();
  2131.         printf("FontId:%d FontHeight:%d ", uFontId, uFontHeight);
  2132.     }
  2133.  
  2134.     if (flags & seditTextFlagsHasTextColor)
  2135.     {
  2136.         GetColor(true);
  2137.     }
  2138.  
  2139.     if (flags & seditTextFlagsHasMaxLength)
  2140.     {
  2141.         int iMaxLength = GetWord();
  2142.         printf("length:%d ", iMaxLength);
  2143.     }
  2144.  
  2145.     if (flags & seditTextFlagsHasLayout)
  2146.     {
  2147.         int iAlign = GetByte();
  2148.         U16 uLeftMargin = GetWord();
  2149.         U16 uRightMargin = GetWord();
  2150.         U16 uIndent = GetWord();
  2151.         U16 uLeading = GetWord();
  2152.     }
  2153.  
  2154.     char* pszVariable = GetString();
  2155.     printf("variable:%s ", pszVariable);
  2156.  
  2157.     if (flags & seditTextFlagsHasText )
  2158.     {
  2159.         char* pszInitialText = GetString();
  2160.         printf("text:%s ", pszInitialText);
  2161.     }
  2162.  
  2163.     printf("\n");
  2164. }
  2165.  
  2166. void CInputScript::ParseDefineFont2(char *str)
  2167. {
  2168.     U32 tagid = (U32) GetWord();
  2169.  
  2170.     U16 flags = GetWord();
  2171.  
  2172.     // Skip the font name
  2173.     int iNameLen = GetByte();
  2174.     char szFontName[256];
  2175.     for (int i=0; i<iNameLen; i++)
  2176.         szFontName[i] = GetByte();
  2177.     szFontName[i] = NULL;
  2178.  
  2179.     // Get the number of glyphs.
  2180.     U16 nGlyphs = GetWord();
  2181.  
  2182.     int iDataPos = m_filePos;
  2183.  
  2184.     printf("%stagDefineFont2 \ttagid %-5u flags:%04x nGlyphs:%d\n", str, tagid, flags, nGlyphs);
  2185.  
  2186.     if (nGlyphs > 0)
  2187.     {
  2188.         //
  2189.         // Get the FontOffsetTable
  2190.         //
  2191.  
  2192.         U32* puOffsetTable = new U32[nGlyphs];
  2193.         for (int n=0; n<nGlyphs; n++)
  2194.             if (flags & sfontFlagsWideOffsets)
  2195.                 puOffsetTable[n] = GetDWord();
  2196.             else
  2197.                 puOffsetTable[n] = GetWord();
  2198.  
  2199.         //
  2200.         // Get the CodeOffset
  2201.         //
  2202.  
  2203.         U32 iCodeOffset = 0;
  2204.         if (flags & sfontFlagsWideOffsets)
  2205.             iCodeOffset = GetDWord();
  2206.         else
  2207.             iCodeOffset = GetWord();
  2208.  
  2209.         //
  2210.         // Get the Glyphs
  2211.         //
  2212.  
  2213.         for(n=0; n<nGlyphs; n++)
  2214.         {
  2215.             printf("\n\t%s>>> Glyph:%d", str, n);
  2216.             m_filePos = iDataPos + puOffsetTable[n];
  2217.  
  2218.             InitBits(); // reset bit counter
  2219.  
  2220.             m_nFillBits = (U16) GetBits(4);
  2221.             m_nLineBits = (U16) GetBits(4);
  2222.  
  2223.             int xLast = 0;
  2224.             int yLast = 0;
  2225.  
  2226.             BOOL fAtEnd = false;
  2227.  
  2228.             while (!fAtEnd)
  2229.                 fAtEnd = ParseShapeRecord(str, xLast, yLast);
  2230.         }
  2231.  
  2232.         delete puOffsetTable;
  2233.  
  2234.  
  2235.         if (m_filePos != iDataPos + iCodeOffset)
  2236.         {
  2237.             printf("Bad CodeOffset\n");
  2238.             return;
  2239.         }
  2240.  
  2241.         //
  2242.         // Get the CodeTable
  2243.         //
  2244.  
  2245.         m_filePos = iDataPos + iCodeOffset;
  2246.         printf("\n%sCodeTable:\n%s", str, str);
  2247.  
  2248.         for (int i=0; i<nGlyphs; i++)
  2249.         {
  2250.             if (flags & sfontFlagsWideOffsets)
  2251.                 printf("%02x:[%04x] ", i, GetWord());
  2252.             else
  2253.                 printf("%02x:[%c] ", i, GetByte());
  2254.  
  2255.             if ((i & 7) == 7)
  2256.                 printf("\n%s", str);
  2257.         }
  2258.         printf("\n");
  2259.     }
  2260.  
  2261.     if (flags & sfontFlagsHasLayout)
  2262.     {
  2263.         //
  2264.         // Get "layout" fields
  2265.         //
  2266.  
  2267.         S16 iAscent = GetWord();
  2268.         S16 iDescent = GetWord();
  2269.         S16 iLeading = GetWord();
  2270.  
  2271.         printf("\n%sHasLayout: iAscent:%d iDescent:%d iLeading:%d\n", str, iAscent, iDescent, iLeading);
  2272.  
  2273.         // Skip Advance table
  2274.         SkipBytes(nGlyphs * 2);
  2275.  
  2276.  
  2277.         // Get BoundsTable
  2278.         int i;
  2279.         for (i=0; i<nGlyphs; i++)
  2280.         {
  2281.             SRECT rBounds;
  2282.             GetRect(&rBounds);
  2283.             //printf("rBounds: (%d,%d)(%d,%d)\n", rBounds.xmin, rBounds.ymin, rBounds.xmax, rBounds.ymax);
  2284.         }
  2285.  
  2286.         //
  2287.         // Get Kerning Pairs
  2288.         //
  2289.  
  2290.         S16 iKerningCount = GetWord();
  2291.         printf("\n%sKerning Pair Count:%d\n", str, iKerningCount);
  2292.         for (i=0; i<iKerningCount; i++)
  2293.         {
  2294.             U16 iCode1, iCode2;
  2295.             if (flags & sfontFlagsWideOffsets)
  2296.             {
  2297.                 iCode1 = GetWord();
  2298.                 iCode2 = GetWord();
  2299.             }
  2300.             else
  2301.             {
  2302.                 iCode1 = GetByte();
  2303.                 iCode2 = GetByte();
  2304.             }
  2305.             S16 iAdjust = GetWord();
  2306.  
  2307.             printf("%sKerningPair:%-4d %c <--> %c : %d\n", str, i, iCode1, iCode2, iAdjust);
  2308.         }
  2309.  
  2310.         printf("m_tagEnd:%08x m_filePos:%08x\n", m_tagEnd, m_filePos);
  2311.     }
  2312. }
  2313.  
  2314.  
  2315.  
  2316. void CInputScript::ParseDefineText2(char *str)
  2317. {
  2318.     U32 tagid = (U32) GetWord();
  2319.  
  2320.     printf("%stagDefineText2 \ttagid %-5u\n", str, tagid);
  2321. }
  2322.  
  2323. void CInputScript::ParseDefineMorphShape(char *str)
  2324. {
  2325.     U32 tagid = (U32) GetWord();
  2326.  
  2327.     printf("%stagDefineMorphShape: tagid:%d\n", str, tagid);
  2328.  
  2329.     SRECT r1, r2;
  2330.     GetRect(&r1);
  2331.     GetRect(&r2);
  2332.  
  2333.     // Calculate the position of the end shape edges
  2334.     U32 iOffset = GetDWord();
  2335.     U32 iEndShapePos = m_filePos + iOffset;
  2336.  
  2337.     // Always get RGBA not RGB for DefineMorphShape
  2338.     BOOL fGetAlpha = true;
  2339.  
  2340.     // Get the fills
  2341.     int nFills = GetByte();
  2342.     if ( nFills >= 255 )
  2343.         nFills = GetWord();
  2344.  
  2345.     for (int i = 1; i <= nFills; i++ )
  2346.     {
  2347.         int fillStyle = GetByte();
  2348.         if (fillStyle & fillGradient)
  2349.         {
  2350.             // Gradient fill
  2351.             MATRIX mat1, mat2;
  2352.             GetMatrix(&mat1);
  2353.             GetMatrix(&mat2);
  2354.  
  2355.             // Get the gradient color points
  2356.             int nColors = GetByte();
  2357.             for (int j = 0; j < nColors; j++)
  2358.             {
  2359.                 U8 r1, r2;
  2360.                 U32 c1, c2;
  2361.  
  2362.                 r1 = GetByte();
  2363.                 c1 = GetColor(fGetAlpha);
  2364.                 r2 = GetByte();
  2365.                 c2 = GetColor(fGetAlpha);
  2366.             }
  2367.         }
  2368.         else if (fillStyle & fillBits)
  2369.         {
  2370.             // A bitmap fill
  2371.             U16 tag = GetWord();        // the bitmap tag
  2372.  
  2373.             MATRIX mat1, mat2;
  2374.             GetMatrix(&mat1);
  2375.             GetMatrix(&mat2);
  2376.         }
  2377.         else
  2378.         {
  2379.             // A solid color
  2380.             U32 rgb1 = GetColor(fGetAlpha);
  2381.             U32 rgb2 = GetColor(fGetAlpha);
  2382.         }
  2383.     }
  2384.  
  2385.     // Get the lines
  2386.     int nLines = GetByte();
  2387.     if ( nLines >= 255 )
  2388.         nLines = GetWord();
  2389.  
  2390.     for (i = 1; i <= nLines; i++ )
  2391.     {
  2392.         U16 thick1, thick2;
  2393.         U32 rgb1, rgb2;
  2394.  
  2395.         // get the thickness
  2396.         thick1 = GetWord();
  2397.         thick2 = GetWord();
  2398.  
  2399.         // get the color
  2400.         rgb1 = GetColor(fGetAlpha);
  2401.         rgb2 = GetColor(fGetAlpha);
  2402.     }
  2403.  
  2404.     //
  2405.     // Get the bits per style index for the start shape
  2406.     //
  2407.  
  2408.     InitBits();
  2409.     m_nFillBits = (U16) GetBits(4);
  2410.     m_nLineBits = (U16) GetBits(4);
  2411.  
  2412.     //
  2413.     // Parse the start shape
  2414.     //
  2415.  
  2416.     printf("\n\t--- StartShape ---");
  2417.     BOOL atEnd = false;
  2418.     int  xLast = 0;
  2419.     int  yLast = 0;
  2420.     while (!atEnd)
  2421.         atEnd = ParseShapeRecord(str, xLast, yLast, true);
  2422.  
  2423.     if (m_filePos != iEndShapePos)
  2424.     {
  2425.         printf("Bad offset to end shape\n");
  2426.         return;
  2427.     }
  2428.  
  2429.     //
  2430.     // Get the bits per style index for the end shape
  2431.     // THIS IS POINTLESS -- THERE ARE NO STYLES ?!
  2432.     //
  2433.  
  2434.     InitBits();
  2435.     m_nFillBits = (U16) GetBits(4);     // not sure if we should save these to n_FillBits & nLineBits
  2436.     m_nLineBits = (U16) GetBits(4);     // there are no styles so none of this make sense.
  2437.  
  2438.     //
  2439.     // Parse the end shape
  2440.     //
  2441.  
  2442.     printf("\t--- EndShape ---");
  2443.     atEnd = false;
  2444.     xLast = 0;
  2445.     yLast = 0;
  2446.     while (!atEnd)
  2447.         atEnd = ParseShapeRecord(str, xLast, yLast, true);
  2448. }
  2449.  
  2450. //
  2451. // MP3 tables
  2452. //
  2453.  
  2454. int vertab[4]={2,3,1,0};
  2455. int freqtab[4]={44100,48000,32000};
  2456. int ratetab[2][3][16]=
  2457. {
  2458.   {
  2459.     {  0, 32, 64, 96,128,160,192,224,256,288,320,352,384,416,448,  0},
  2460.     {  0, 32, 48, 56, 64, 80, 96,112,128,160,192,224,256,320,384,  0},
  2461.     {  0, 32, 40, 48, 56, 64, 80, 96,112,128,160,192,224,256,320,  0},
  2462.   },
  2463.   {
  2464.     {  0, 32, 48, 56, 64, 80, 96,112,128,144,160,176,192,224,256,  0},
  2465.     {  0,  8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160,  0},
  2466.     {  0,  8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160,  0},
  2467.   },
  2468. };
  2469.  
  2470. void CInputScript::DecodeMp3Frame(U8* pbFrame, int iEncodedSize, int iDecodedSize)
  2471. {
  2472.     // This is left as an exercise for the reader (he he)
  2473. }
  2474.  
  2475. void CInputScript::DecodeMp3Headers(char* str, int iSamplesPerFrame)
  2476. {
  2477.     int iFrameCount = 0;
  2478.  
  2479.     if (iSamplesPerFrame > 0)
  2480.     {
  2481.         while (true)
  2482.         {
  2483.             // Get the MP3 frame header
  2484.             U8  hdr[4];
  2485.             for (int i=0; i<4; i++)
  2486.                 hdr[i] = GetByte();
  2487.  
  2488.             // Decode the MP3 frame header
  2489.             int ver     = vertab[((hdr[1] >> 3) & 3)];
  2490.             int layer   = 3 - ((hdr[1] >> 1) & 3);
  2491.             int pad     = (hdr[2] >>1 ) & 1;
  2492.             int stereo  = ((hdr[3] >> 6) & 3) != 3;
  2493.             int freq    = 0;
  2494.             int rate    = 0;
  2495.  
  2496.             if (hdr[0] != 0xFF || hdr[1] < 0xE0 || ver==3 || layer != 2)
  2497.             {
  2498.                 // bad MP3 header
  2499.                 printf("\t\tBAD MP3 FRAME HEADER\n");
  2500.                 break;
  2501.             }
  2502.             else
  2503.             {
  2504.                 freq = freqtab[(hdr[2] >>2 ) & 3] >> ver;
  2505.                 rate = ratetab[ver ? 1 : 0][layer][(hdr[2] >> 4) & 15] * 1000;
  2506.  
  2507.                 if (!freq || !rate)
  2508.                 {
  2509.                     // bad MP3 header
  2510.                     printf("\t\tBAD MP3 FRAME HEADER\n");
  2511.                     break;
  2512.                 }
  2513.             }
  2514.  
  2515.             // Get the size of a decoded MP3 frame
  2516.             int iDecodedFrameSize = (576 * (stereo + 1));
  2517.             if (!ver)
  2518.                 iDecodedFrameSize *= 2;
  2519.  
  2520.             // Get the size of this encoded MP3 frame
  2521.             int iEncodedFrameSize = ((ver ? 72 : 144) * rate) / freq + pad - 4;
  2522.  
  2523.             char* ppszMpegVer[4] = {"1","2","2.5","3?"};
  2524.  
  2525.             printf("%s  Frame%d: MPEG%s Layer%d %dHz %s %dbps size:Encoded:%d Decoded:%d\n",
  2526.                 str, iFrameCount, ppszMpegVer[ver], layer+1, freq, stereo ? "stereo" : "mono", rate, iEncodedFrameSize, iDecodedFrameSize);
  2527.  
  2528.             // Decode the MP3 frame
  2529.             DecodeMp3Frame(&m_fileBuf[m_filePos], iEncodedFrameSize, iDecodedFrameSize);
  2530.  
  2531.             // Move to the next frame
  2532.             iFrameCount++;
  2533.             if (m_filePos + iEncodedFrameSize >= m_tagEnd)
  2534.                 break;
  2535.             m_filePos += iEncodedFrameSize;
  2536.         }
  2537.     }
  2538.     printf("\n");
  2539. }
  2540.  
  2541. //
  2542. // ADPCM tables
  2543. //
  2544.  
  2545. static const int indexTable2[2] = {
  2546.     -1, 2,
  2547. };
  2548.  
  2549. // Is this ok?
  2550. static const int indexTable3[4] = {
  2551.     -1, -1, 2, 4,
  2552. };
  2553.  
  2554. static const int indexTable4[8] = {
  2555.     -1, -1, -1, -1, 2, 4, 6, 8,
  2556. };
  2557.  
  2558. static const int indexTable5[16] = {
  2559.  -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16,
  2560. };
  2561.  
  2562. static const int* indexTables[] = {
  2563.  indexTable2,
  2564.  indexTable3,
  2565.  indexTable4,
  2566.  indexTable5
  2567. };
  2568.  
  2569. static const int stepsizeTable[89] = {
  2570.     7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
  2571.     19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
  2572.     50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
  2573.     130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
  2574.     337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
  2575.     876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
  2576.     2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
  2577.     5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
  2578.     15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
  2579. };
  2580.  
  2581.  
  2582.  
  2583. void CInputScript::AdpcmFillBuffer()
  2584. {
  2585.     while (m_bitPosAdpcm <= 24)
  2586.     {
  2587.         m_bitBufAdpcm = (m_bitBufAdpcm<<8) | *m_srcAdpcm++;
  2588.         m_bitPosAdpcm += 8;
  2589.     }
  2590. }
  2591.  
  2592. long CInputScript::AdpcmGetBits(int n)
  2593. {
  2594.     if (m_bitPosAdpcm < n)
  2595.         AdpcmFillBuffer();
  2596.  
  2597.     //assert(bitPos >= n);
  2598.  
  2599.     long v = ((U32)m_bitBufAdpcm << (32-m_bitPosAdpcm)) >> (32-n);
  2600.     m_bitPosAdpcm -= n;
  2601.  
  2602.     return v;
  2603. }
  2604.  
  2605. long CInputScript::AdpcmGetSBits(int n)
  2606. {
  2607.     if (m_bitPosAdpcm < n)
  2608.         AdpcmFillBuffer();
  2609.  
  2610.     //assert(bitPos >= n);
  2611.  
  2612.     long v = ((S32)m_bitBufAdpcm << (32-m_bitPosAdpcm)) >> (32-n);
  2613.     m_bitPosAdpcm -= n;
  2614.  
  2615.     return v;
  2616. }
  2617.  
  2618.  
  2619. void CInputScript::AdpcmDecompress(long n, long stereo, int f16Bit, U8* data)
  2620. {
  2621.     long    valpred[2]; // Current state
  2622.     int     index[2];
  2623.  
  2624.     for (int i=0; i<2; i++)
  2625.     {
  2626.         valpred[i] = 0;
  2627.         index[i] = 0;
  2628.     }
  2629.  
  2630.     int iSampleCount = n;
  2631.  
  2632.     // Get the compression header
  2633.     int nBits = (int)GetBits(2)+2;
  2634.  
  2635.     printf("%d-bit ADPCM %d-bit %s ", nBits, f16Bit ? 16 : 8, stereo ? "stereo" : "mono");
  2636.     if (!m_dumpSoundGuts)
  2637.         printf("\n");
  2638.  
  2639.     const int* indexTable = indexTables[nBits-2];
  2640.     int k0 = 1 << (nBits-2);
  2641.     int signmask = 1 << (nBits-1);
  2642.  
  2643.  
  2644.     if (f16Bit)
  2645.     {
  2646.         short*  dst = (short*)data;
  2647.  
  2648.         if (!stereo)
  2649.         {
  2650.             // Optimize for mono
  2651.             long    vp = valpred[0]; // maybe these can get into registers...
  2652.             int     ind = index[0];
  2653.             long    ns = m_nSamplesAdpcm;
  2654.  
  2655.             while ( n-- > 0 )
  2656.             {
  2657.                 ns++;
  2658.  
  2659.                 if ((ns & 0xFFF) == 1)
  2660.                 {
  2661.                     // Get a new block header
  2662.                     vp = GetSBits(16);
  2663.                     if (dst != NULL)
  2664.                         *dst++ = (short)vp;
  2665.  
  2666.                     ind = (int)GetBits(6); // The first sample in a block does not have a delta
  2667.  
  2668.                     if (m_dumpSoundGuts)
  2669.                         printf("initial sample:%d index:%d\n", vp, ind);
  2670.                 }
  2671.                 else
  2672.                 {
  2673.                     // Process a delta value
  2674.                     int delta = (int)GetBits(nBits);
  2675.  
  2676.                     // Compute difference and new predicted value
  2677.                     // Computes 'vpdiff = (delta+0.5)*step/4'
  2678.                     int step = stepsizeTable[ind];
  2679.                     long vpdiff = 0;
  2680.                     int k = k0;
  2681.  
  2682.                     do
  2683.                     {
  2684.                         if (delta & k)
  2685.                             vpdiff += step;
  2686.                         step >>= 1;
  2687.                         k >>= 1;
  2688.                     }
  2689.                     while (k);
  2690.  
  2691.                     vpdiff += step; // add 0.5
  2692.  
  2693.                     if (delta & signmask) // the sign bit
  2694.                         vp -= vpdiff;
  2695.                     else
  2696.                         vp += vpdiff;
  2697.  
  2698.                     // Find new index value
  2699.                     ind += indexTable[delta & (~signmask)];
  2700.  
  2701.                     if (ind < 0)
  2702.                         ind = 0;
  2703.                     else if (ind > 88)
  2704.                         ind = 88;
  2705.  
  2706.                     // clamp output value
  2707.                     if (vp != (short)vp)
  2708.                         vp = vp < 0 ? -32768 : 32767;
  2709.  
  2710.                     if (m_dumpSoundGuts)
  2711.                     {
  2712.                         printf("%-2d=>%-6d ", delta, (short)vp);
  2713.                         if ((ns & 3) == 0)
  2714.                             printf("\n");
  2715.                     }
  2716.  
  2717.                     /* Step 7 - Output value */
  2718.                     if (dst != NULL)
  2719.                         *dst++ = (short)vp;
  2720.  
  2721.                     /*
  2722.                     if (m_dumpSoundGuts)
  2723.                     {
  2724.                         if ((ns & 0xFFF) == 0)
  2725.                         {
  2726.                             printf("\nind:%d vp:%d delta:%d\n", ind, vp, delta);
  2727.                         }
  2728.                     }
  2729.                     */
  2730.                 }
  2731.             }
  2732.  
  2733.             valpred[0] = vp;
  2734.             index[0] = ind;
  2735.             m_nSamplesAdpcm = ns;
  2736.         }
  2737.         else
  2738.         {
  2739.             int sn = stereo ? 2 : 1;
  2740.  
  2741.             // Stereo
  2742.             while ( n-- > 0 ) {
  2743.  
  2744.                 m_nSamplesAdpcm++;
  2745.  
  2746.                 if ((m_nSamplesAdpcm & 0xFFF) == 1 )
  2747.                 {
  2748.                     // Get a new block header
  2749.                     for ( int i = 0; i < sn; i++ )
  2750.                     {
  2751.                         valpred[i] = GetSBits(16);
  2752.                         if (dst != NULL)
  2753.                             *dst++ = (short)valpred[i];
  2754.  
  2755.                         // The first sample in a block does not have a delta
  2756.                         index[i] = (int)GetBits(6);
  2757.                     }
  2758.                 }
  2759.                 else
  2760.                 {
  2761.                     // Process a delta value
  2762.                     for ( int i = 0; i < sn; i++ ) {
  2763.                         int delta = (int)GetBits(nBits);
  2764.  
  2765.                         // Compute difference and new predicted value
  2766.                         // Computes 'vpdiff = (delta+0.5)*step/4'
  2767.  
  2768.                         int step = stepsizeTable[index[i]];
  2769.                         long vpdiff = 0;
  2770.                         int k = k0;
  2771.  
  2772.                         do {
  2773.                             if ( delta & k ) vpdiff += step;
  2774.                             step >>= 1;
  2775.                             k >>= 1;
  2776.                         } while ( k );
  2777.                         vpdiff += step; // add 0.5
  2778.  
  2779.  
  2780.                         if ( delta & signmask ) // the sign bit
  2781.                             valpred[i] -= vpdiff;
  2782.                         else
  2783.                             valpred[i] += vpdiff;
  2784.  
  2785.                         // Find new index value
  2786.                         index[i] += indexTable[delta&(~signmask)];
  2787.  
  2788.                         if ( index[i] < 0 )
  2789.                             index[i] = 0;
  2790.                         else if ( index[i] > 88 )
  2791.                             index[i] = 88;
  2792.  
  2793.                         // clamp output value
  2794.                         if ( valpred[i] != (short)valpred[i] )
  2795.                             valpred[i] = valpred[i] < 0 ? -32768 : 32767;
  2796.  
  2797.  
  2798.                         /* Step 7 - Output value */
  2799.                         if (dst != NULL)
  2800.                             *dst++ = (short)valpred[i];
  2801.                     }
  2802.                 }
  2803.             }
  2804.         }
  2805.     }
  2806.     else
  2807.     {
  2808.         U8* dst = data;
  2809.         U8* pbSamples = dst;
  2810.  
  2811.         if (!stereo)
  2812.         {
  2813.             // Optimize for mono
  2814.             long    vp = valpred[0]; // maybe these can get into registers...
  2815.             int     ind = index[0];
  2816.             long    ns = m_nSamplesAdpcm;
  2817.  
  2818.             while ( n-- > 0 )
  2819.             {
  2820.                 ns++;
  2821.  
  2822.                 if ((ns & 0xFFF) == 1)
  2823.                 {
  2824.                     // Get a new block header
  2825.                     vp = GetBits(8);
  2826.                     if (dst != NULL)
  2827.                         *dst++ = (U8)vp;
  2828.  
  2829.                     ind = (int)GetBits(6); // The first sample in a block does not have a delta
  2830.  
  2831.                     if (m_dumpSoundGuts)
  2832.                         printf("initial sample:%d index:%d\n", vp, ind);
  2833.                 }
  2834.                 else
  2835.                 {
  2836.                     // Process a delta value
  2837.                     int delta = (int)GetBits(nBits);
  2838.  
  2839.                     // Compute difference and new predicted value
  2840.                     // Computes 'vpdiff = (delta+0.5)*step/4'
  2841.                     int step = stepsizeTable[ind];
  2842.                     long vpdiff = 0;
  2843.                     int k = k0;
  2844.  
  2845.                     do
  2846.                     {
  2847.                         if (delta & k)
  2848.                             vpdiff += step;
  2849.                         step >>= 1;
  2850.                         k >>= 1;
  2851.                     }
  2852.                     while (k);
  2853.  
  2854.                     vpdiff += step; // add 0.5
  2855.  
  2856.                     if (delta & signmask) // the sign bit
  2857.                         vp -= vpdiff;
  2858.                     else
  2859.                         vp += vpdiff;
  2860.  
  2861.                     // Find new index value
  2862.                     ind += indexTable[delta & (~signmask)];
  2863.  
  2864.                     if (ind < 0)
  2865.                         ind = 0;
  2866.                     else if (ind > 88)
  2867.                         ind = 88;
  2868.  
  2869.                     // clamp output value
  2870.                     if (vp < 0)
  2871.                         vp = 0;
  2872.                     else if (vp > 255)
  2873.                         vp = 255;
  2874.  
  2875.                     if (m_dumpSoundGuts)
  2876.                     {
  2877.                         printf("%-2d=>%-6d ", delta, vp);
  2878.                         if ((ns & 3) == 0)
  2879.                             printf("\n");
  2880.                     }
  2881.  
  2882.                     /* Step 7 - Output value */
  2883.                     if (dst != NULL)
  2884.                         *dst++ = (U8)vp;
  2885.  
  2886.                     if ( m_dumpSoundGuts )
  2887.                     {
  2888.                         if ((ns & 0xFFF) == 0)
  2889.                         {
  2890.                             printf("\nind:%d vp:%d delta:%d\n", ind, vp, delta);
  2891.                         }
  2892.                     }
  2893.                 }
  2894.             }
  2895.  
  2896.             valpred[0] = vp;
  2897.             index[0] = ind;
  2898.             m_nSamplesAdpcm = ns;
  2899.  
  2900.         }
  2901.         else
  2902.         {
  2903.             int sn = stereo ? 2 : 1;
  2904.  
  2905.             // Stereo
  2906.             while ( n-- > 0 ) {
  2907.  
  2908.                 m_nSamplesAdpcm++;
  2909.  
  2910.                 if ((m_nSamplesAdpcm & 0xFFF) == 1 )
  2911.                 {
  2912.                     // Get a new block header
  2913.                     for ( int i = 0; i < sn; i++ )
  2914.                     {
  2915.                         valpred[i] = GetBits(8);
  2916.                         if (dst != NULL)
  2917.                             *dst++ = (U8)valpred[i];
  2918.  
  2919.                         // The first sample in a block does not have a delta
  2920.                         index[i] = (int)GetBits(6);
  2921.                     }
  2922.                 }
  2923.                 else
  2924.                 {
  2925.                     // Process a delta value
  2926.                     for ( int i = 0; i < sn; i++ )
  2927.                     {
  2928.                         int delta = (int)GetBits(nBits);
  2929.  
  2930.                         // Compute difference and new predicted value
  2931.                         // Computes 'vpdiff = (delta+0.5)*step/4'
  2932.  
  2933.                         int step = stepsizeTable[index[i]];
  2934.                         long vpdiff = 0;
  2935.                         int k = k0;
  2936.  
  2937.                         do {
  2938.                             if ( delta & k ) vpdiff += step;
  2939.                             step >>= 1;
  2940.                             k >>= 1;
  2941.                         } while ( k );
  2942.                         vpdiff += step; // add 0.5
  2943.  
  2944.  
  2945.                         if ( delta & signmask ) // the sign bit
  2946.                             valpred[i] -= vpdiff;
  2947.                         else
  2948.                             valpred[i] += vpdiff;
  2949.  
  2950.                         // Find new index value
  2951.                         index[i] += indexTable[delta&(~signmask)];
  2952.  
  2953.                         if ( index[i] < 0 )
  2954.                             index[i] = 0;
  2955.                         else if ( index[i] > 88 )
  2956.                             index[i] = 88;
  2957.  
  2958.                         // clamp output value
  2959.                         if ( valpred[i] != (short)valpred[i] )
  2960.                             valpred[i] = valpred[i] < 0 ? -32768 : 32767;
  2961.  
  2962.  
  2963.                         /* Step 7 - Output value */
  2964.                         if (dst != NULL)
  2965.                             *dst++ = (U8)valpred[i];
  2966.                     }
  2967.                 }
  2968.             }
  2969.         }
  2970.     }
  2971.  
  2972.     /*
  2973.     printf("\n");
  2974.     for (i=0; i<iSampleCount; i++)
  2975.     {
  2976.         printf("%-6d ", psSamples[i]);
  2977.         if ((i & 7) == 7)
  2978.             printf("\n");
  2979.     }
  2980.     printf("\n");
  2981.     */
  2982. }
  2983.  
  2984.  
  2985.  
  2986. void CInputScript::ParseDefineSound(char *str)
  2987. {
  2988.     U32 tagid = (U32) GetWord();
  2989.  
  2990.     printf("%stagDefineSound: ", str);
  2991.  
  2992.     int iCompression = GetBits(4);      // uncompressed, ADPCM or MP3
  2993.     int iSampleRate  = GetBits(2);
  2994.     int iSampleSize  = GetBits(1);
  2995.     int iStereoMono  = GetBits(1);
  2996.     int iSampleCount = GetDWord();
  2997.  
  2998.  
  2999.     char* ppszCompression[3] = {"uncompressed", "ADPCM", "MP3"};
  3000.     char* ppszSampleRate[4]  = {"5.5", "11", "22", "44"};
  3001.     char* pszSampleSize      = (iSampleSize == 0 ? "8" : "16");
  3002.     char* pszStereoMono      = (iStereoMono == 0 ? "mono" : "stereo");
  3003.  
  3004.     printf("%s %skHz %s-bit %s NumberOfSamples:%d (%08x)\n",
  3005.         ppszCompression[iCompression], ppszSampleRate[iSampleRate],
  3006.         pszSampleSize, pszStereoMono, iSampleCount, iSampleCount);
  3007.  
  3008.     if (!m_dumpSoundGuts)
  3009.         return;
  3010.  
  3011.     switch (iCompression)
  3012.     {
  3013.         case 0:
  3014.         {
  3015.             printf("%s  uncompressed samples\n", str);
  3016.             break;
  3017.         }
  3018.         case 1:
  3019.         {
  3020.             m_nSamplesAdpcm = 0;
  3021.             m_srcAdpcm = &m_fileBuf[m_filePos];
  3022.             AdpcmDecompress(iSampleCount, iStereoMono, iSampleSize);
  3023.             break;
  3024.         }
  3025.         case 2:
  3026.         {
  3027.             int iDelay = GetWord();
  3028.             printf("%s  MP3: delay:%d\n", str, iDelay);
  3029.             DecodeMp3Headers(str, iSampleCount);
  3030.             break;
  3031.         }
  3032.     }
  3033.  
  3034.     //U8* pbSamples = new U8[iSampleCount * (iSoundSize ? 2 : 1)];
  3035.     //delete pbSamples;
  3036. }
  3037.  
  3038.  
  3039. void CInputScript::ParseDefineButtonSound(char *str)
  3040. {
  3041.     U32 tagid = (U32) GetWord();
  3042.  
  3043.     printf("%stagDefineButtonSound \ttagid %-5u\n", str, tagid);
  3044.  
  3045.     if (!m_dumpAll)
  3046.         return;
  3047.  
  3048.     // step through for button states
  3049.     for (int i = 0; i < 3; i++)
  3050.     {
  3051.         U32 soundTag = GetWord();
  3052.         switch (i)
  3053.         {
  3054.             case 0:
  3055.                 INDENT;
  3056.                 printf("%supState \ttagid %-5u\n", str, soundTag);
  3057.                 break;
  3058.             case 1:
  3059.                 INDENT;
  3060.                 printf("%soverState \ttagid %-5u\n", str, soundTag);
  3061.                 break;
  3062.             case 2:
  3063.                 INDENT;
  3064.                 printf("%sdownState \ttagid %-5u\n", str, soundTag);
  3065.                 break;
  3066.         }
  3067.  
  3068.         if (soundTag)
  3069.         {
  3070.             U32 code = GetByte();
  3071.             INDENT;
  3072.             printf("%ssound code %u", str, code);
  3073.  
  3074.             if ( code & soundHasInPoint )
  3075.                 printf(" inpoint %u", GetDWord());
  3076.             if ( code & soundHasOutPoint )
  3077.                 printf(" outpoint %u", GetDWord());
  3078.             if ( code & soundHasLoops )
  3079.                 printf(" loops %u", GetDWord());
  3080.  
  3081.             printf("\n");
  3082.             if ( code & soundHasEnvelope )
  3083.             {
  3084.                 int points = GetByte();
  3085.  
  3086.                 for ( int i = 0; i < points; i++ )
  3087.                 {
  3088.                     printf("\n");
  3089.                     INDENT;
  3090.                     printf("%smark44 %u", str, GetDWord());
  3091.                     printf(" left chanel %u", GetWord());
  3092.                     printf(" right chanel %u", GetWord());
  3093.                     printf("\n");
  3094.                 }
  3095.             }
  3096.         }
  3097.     }
  3098.  
  3099. }
  3100.  
  3101.  
  3102. void CInputScript::ParseSoundStreamHead(char *str)
  3103. {
  3104.     ParseSoundStreamHead2(str, false);
  3105. }
  3106.  
  3107. void CInputScript::ParseSoundStreamHead2(char *str, BOOL fIsHead2)
  3108. {
  3109.     int iMixFormat = GetByte();
  3110.  
  3111.     // The stream settings
  3112.     m_iStreamCompression = GetBits(4);
  3113.     m_iStreamSampleRate  = GetBits(2);
  3114.     m_iStreamSampleSize  = GetBits(1);
  3115.     m_iStreamStereoMono  = GetBits(1);
  3116.     m_nStreamSamples     = GetWord();
  3117.  
  3118.     char* ppszCompression[3] = {"uncompressed", "ADPCM", "MP3"};
  3119.     char* ppszSampleRate[4]  = {"5.5", "11", "22", "44"};
  3120.     char* pszSampleSize      = (m_iStreamSampleSize == 0 ? "8" : "16");
  3121.     char* pszStereoMono      = (m_iStreamStereoMono == 0 ? "mono" : "stereo");
  3122.  
  3123.     printf("%stagSoundStreamHead%s: %s %skHz %s-bit %s AverageSamplesPerFrame:%d\n",
  3124.         str, fIsHead2 ? "2" : "", ppszCompression[m_iStreamCompression], ppszSampleRate[m_iStreamSampleRate],
  3125.         pszSampleSize, pszStereoMono, m_nStreamSamples);
  3126. }
  3127.  
  3128. void CInputScript::ParseSoundStreamBlock(char *str)
  3129. {
  3130.     printf("%stagSoundStreamBlock: ", str);
  3131.  
  3132.     switch (m_iStreamCompression)
  3133.     {
  3134.         case 0:
  3135.         {
  3136.             printf("%s  uncompressed samples\n", str);
  3137.             break;
  3138.         }
  3139.         case 1:
  3140.         {
  3141.             m_nSamplesAdpcm = 0;
  3142.             m_srcAdpcm = &m_fileBuf[m_filePos];
  3143.             AdpcmDecompress(m_nStreamSamples, m_iStreamStereoMono, m_iStreamSampleSize);
  3144.             break;
  3145.         }
  3146.         case 2:
  3147.         {
  3148.             U16 iSamplesPerFrame  = GetWord();
  3149.             U16 iDelay  = GetWord();
  3150.  
  3151.             printf("%s  MP3: SamplesPerFrame:%d Delay:%d\n", str, iSamplesPerFrame, iDelay);
  3152.             DecodeMp3Headers(str, iSamplesPerFrame);
  3153.         }
  3154.     }
  3155. }
  3156.  
  3157.  
  3158. void CInputScript::ParseDefineButtonCxform(char *str)
  3159. {
  3160.     U32 tagid = (U32) GetWord();
  3161.  
  3162.     printf("%stagDefineButtonCxform \ttagid %-5u\n", str, tagid);
  3163.  
  3164.     if (!m_dumpAll)
  3165.         return;
  3166.  
  3167.     while (m_filePos < m_tagEnd)
  3168.     {
  3169.         CXFORM cxform;
  3170.         GetCxform(&cxform, false);
  3171.         PrintCxform(str, &cxform);
  3172.     }
  3173. }
  3174.  
  3175. void CInputScript::ParseNameCharacter(char *str)
  3176. {
  3177.     U32 tagid = (U32) GetWord();
  3178.     char *label = GetString();
  3179.  
  3180.     printf("%stagNameCharacter \ttagid %-5u label '%s'\n", str, tagid, label);
  3181. }
  3182.  
  3183.  
  3184. void CInputScript::ParseFrameLabel(char *str)
  3185. {
  3186.     char *label = GetString();
  3187.  
  3188.     printf("%stagFrameLabel lable \"%s\"\n", str, label);
  3189. }
  3190.  
  3191.  
  3192. void CInputScript::ParseDefineMouseTarget(char *str)
  3193. {
  3194.     printf("%stagDefineMouseTarget\n", str);
  3195. }
  3196.  
  3197.  
  3198. void CInputScript::ParseUnknown(char *str, U16 code)
  3199. {
  3200.     printf("%sUnknown Tag:0x%02x len:0x%02x\n", str, code, m_tagLen);
  3201. }
  3202.  
  3203.  
  3204. void CInputScript::ParseTags(BOOL sprite, U32 tabs)
  3205. // Parses the tags within the file.
  3206. {
  3207.  
  3208.     char str[33];   // indent level
  3209.  
  3210.     {
  3211.         U32 i = 0;
  3212.  
  3213.         for (i = 0; i < tabs && i < 32; i++)
  3214.         {
  3215.             str[i] = '\t';
  3216.         }
  3217.         str[i] = 0;
  3218.     }
  3219.  
  3220.     if (sprite)
  3221.     {
  3222.         U32 tagid = (U32) GetWord();
  3223.         U32 frameCount = (U32) GetWord();
  3224.  
  3225.         printf("%stagDefineSprite \ttagid %-5u \tframe count %-5u\n", str, tagid, frameCount);
  3226.     }
  3227.     else
  3228.     {
  3229.         printf("\n%s<----- dumping frame %d file offset 0x%04x ----->\n", str, 0, m_filePos);
  3230.  
  3231.         // Set the position to the start position.
  3232.         m_filePos = m_fileStart;
  3233.     }
  3234.  
  3235.     // Initialize the end of frame flag.
  3236.     BOOL atEnd = false;
  3237.  
  3238.     // Reset the frame position.
  3239.     U32 frame = 0;
  3240.  
  3241.     // Loop through each tag.
  3242.     while (!atEnd)
  3243.     {
  3244.         // Get the current tag.
  3245.         U16 code = GetTag();
  3246.  
  3247.         if (false)
  3248.         {
  3249.             printf("Tag dump: %04x: ", m_tagStart);
  3250.             for (U32 i=m_tagStart; i<m_tagStart+8; i++)
  3251.                 printf("%02x ", m_fileBuf[i]);
  3252.         }
  3253.  
  3254.  
  3255.         // Get the tag ending position.
  3256.         U32 tagEnd = m_tagEnd;
  3257.  
  3258.         switch (code)
  3259.         {
  3260.             case stagEnd:
  3261.  
  3262.                 // Parse the end tag.
  3263.                 ParseEnd(str);
  3264.  
  3265.                 // We reached the end of the file.
  3266.                 atEnd = true;
  3267.  
  3268.                 break;
  3269.  
  3270.             case stagShowFrame:
  3271.                 ParseShowFrame(str, frame, tagEnd);
  3272.  
  3273.                 // Increment to the next frame.
  3274.                 ++frame;
  3275.                 break;
  3276.  
  3277.             case stagFreeCharacter:
  3278.                 ParseFreeCharacter(str);
  3279.                 break;
  3280.  
  3281.             case stagPlaceObject:
  3282.                 ParsePlaceObject(str);
  3283.                 break;
  3284.  
  3285.             case stagPlaceObject2:
  3286.                 ParsePlaceObject2(str);
  3287.                 break;
  3288.  
  3289.             case stagRemoveObject:
  3290.                 ParseRemoveObject(str);
  3291.                 break;
  3292.  
  3293.             case stagRemoveObject2:
  3294.                 ParseRemoveObject2(str);
  3295.                 break;
  3296.  
  3297.             case stagSetBackgroundColor:
  3298.                 ParseSetBackgroundColor(str);
  3299.                 break;
  3300.  
  3301.             case stagDoAction:
  3302.                 ParseDoAction(str);
  3303.                 break;
  3304.  
  3305.             case stagStartSound:
  3306.                 ParseStartSound(str);
  3307.                 break;
  3308.  
  3309.             case stagProtect:
  3310.                 ParseProtect(str);
  3311.                 break;
  3312.  
  3313.             case stagDefineShape:
  3314.                 ParseDefineShape(str);
  3315.                 break;
  3316.  
  3317.             case stagDefineShape2:
  3318.                 ParseDefineShape2(str);
  3319.                 break;
  3320.  
  3321.             case stagDefineShape3:
  3322.                 ParseDefineShape3(str);
  3323.                 break;
  3324.  
  3325.             case stagDefineBits:
  3326.                 ParseDefineBits(str);
  3327.                 break;
  3328.  
  3329.             case stagDefineBitsJPEG2:
  3330.                 ParseDefineBitsJPEG2(str);
  3331.                 break;
  3332.  
  3333.             case stagDefineBitsJPEG3:
  3334.                 ParseDefineBitsJPEG3(str);
  3335.                 break;
  3336.  
  3337.             case stagDefineBitsLossless:
  3338.                 ParseDefineBitsLossless(str);
  3339.                 break;
  3340.  
  3341.             case stagDefineBitsLossless2:
  3342.                 ParseDefineBitsLossless2(str);
  3343.                 break;
  3344.  
  3345.             case stagJPEGTables:
  3346.                 ParseJPEGTables(str);
  3347.                 break;
  3348.  
  3349.             case stagDefineButton:
  3350.                 ParseDefineButton(str);
  3351.                 break;
  3352.  
  3353.             case stagDefineButton2:
  3354.                 ParseDefineButton2(str);
  3355.                 break;
  3356.  
  3357.             case stagDefineFont:
  3358.                 ParseDefineFont(str);
  3359.                 break;
  3360.  
  3361.             case stagDefineMorphShape:
  3362.                 ParseDefineMorphShape(str);
  3363.                 break;
  3364.  
  3365.             case stagDefineFontInfo:
  3366.                 ParseDefineFontInfo(str);
  3367.                 break;
  3368.  
  3369.             case stagDefineText:
  3370.                 ParseDefineText(str);
  3371.                 break;
  3372.  
  3373.             case stagDefineText2:
  3374.                 ParseDefineText2(str);
  3375.                 break;
  3376.  
  3377.             case stagDefineSound:
  3378.                 ParseDefineSound(str);
  3379.                 break;
  3380.  
  3381.             case stagDefineEditText:
  3382.                 ParseDefineEditText(str);
  3383.                 break;
  3384.  
  3385.             case stagDefineButtonSound:
  3386.                 ParseDefineButtonSound(str);
  3387.                 break;
  3388.  
  3389.             case stagSoundStreamHead:
  3390.                 ParseSoundStreamHead(str);
  3391.                 break;
  3392.  
  3393.             case stagSoundStreamHead2:
  3394.                 ParseSoundStreamHead2(str);
  3395.                 break;
  3396.  
  3397.             case stagSoundStreamBlock:
  3398.                 ParseSoundStreamBlock(str);
  3399.                 break;
  3400.  
  3401.             case stagDefineButtonCxform:
  3402.                 ParseDefineButtonCxform(str);
  3403.                 break;
  3404.  
  3405.             case stagDefineSprite:
  3406.                 ParseTags(true, tabs + 1);
  3407.                 break;
  3408.  
  3409.             case stagNameCharacter:
  3410.                 ParseNameCharacter(str);
  3411.                 break;
  3412.  
  3413.             case stagFrameLabel:
  3414.                 ParseFrameLabel(str);
  3415.                 break;
  3416.  
  3417.             case stagDefineFont2:
  3418.                 ParseDefineFont2(str);
  3419.                 break;
  3420.  
  3421.             default:
  3422.                 ParseUnknown(str, code);
  3423.                 break;
  3424.         }
  3425.  
  3426.         // Increment the past the tag.
  3427.         m_filePos = tagEnd;
  3428.     }
  3429. }
  3430.  
  3431.  
  3432. BOOL CInputScript::ParseFile(char * pInput)
  3433. {
  3434.     U8 fileHdr[8];
  3435.     BOOL sts = true;
  3436.     FILE *inputFile = NULL;
  3437.  
  3438.     // Free the buffer if it is there.
  3439.     if (m_fileBuf != NULL)
  3440.     {
  3441.         delete m_fileBuf;
  3442.         m_fileBuf = NULL;
  3443.         m_fileSize = 0;
  3444.     }
  3445.  
  3446.     //printf("***** Dumping SWF File Information *****\n");
  3447.  
  3448.     // Open the file for reading.
  3449.     inputFile = fopen(pInput, "rb");
  3450.  
  3451.     // Did we open the file?
  3452.     if (inputFile == NULL)
  3453.     {
  3454.         sts = false;
  3455.         printf("ERROR: Can't open file %s\n", pInput);
  3456.     }
  3457.  
  3458.     // Are we OK?
  3459.     if (sts)
  3460.     {
  3461.         // Read the file header.
  3462.         if (fread(fileHdr, 1, 8, inputFile) != 8)
  3463.         {
  3464.             sts = false;
  3465.             printf("ERROR: Can't read the header of file %s\n", pInput);
  3466.         }
  3467.     }
  3468.  
  3469.     // Are we OK?
  3470.     if (sts)
  3471.     {
  3472.         printf("----- Reading the file header -----\n");
  3473.  
  3474.         // Verify the header and get the file size.
  3475.         if (fileHdr[0] != 'F' || fileHdr[1] != 'W' || fileHdr[2] != 'S' )
  3476.         {
  3477.             printf("ERROR: Illegal Header - not a Shockwave Flash File\n");
  3478.  
  3479.             // Bad header.
  3480.             sts = false;
  3481.         }
  3482.         else
  3483.         {
  3484.             // Get the file version.
  3485.             m_fileVersion = (U16) fileHdr[3];
  3486.  
  3487.             printf("FWS\n");
  3488.             printf("File version \t%u\n", m_fileVersion);
  3489.         }
  3490.     }
  3491.  
  3492.     // Are we OK?
  3493.     if (sts)
  3494.     {
  3495.         // Get the file size.
  3496.         m_fileSize = (U32) fileHdr[4] | ((U32) fileHdr[5] << 8) | ((U32) fileHdr[6] << 16) | ((U32) fileHdr[7] << 24);
  3497.  
  3498.         printf("File size \t%u\n", m_fileSize);
  3499.  
  3500.         // Verify the minimum length of a Flash file.
  3501.         if (m_fileSize < 21)
  3502.         {
  3503.             printf("ERROR: file size is too short\n");
  3504.             // The file is too short.
  3505.             sts = false;
  3506.         }
  3507.     }
  3508.  
  3509.     // Are we OK?
  3510.     if (sts)
  3511.     {
  3512.         // Allocate the buffer.
  3513.         m_fileBuf = new U8[m_fileSize];
  3514.  
  3515.         // Is there data in the file?
  3516.         if (m_fileBuf == NULL)
  3517.         {
  3518.             sts = false;
  3519.         }
  3520.     }
  3521.  
  3522.     // Are we OK?
  3523.     if (sts)
  3524.     {
  3525.         // Copy the data already read from the file.
  3526.         memcpy(m_fileBuf, fileHdr, 8);
  3527.  
  3528.         // Read the file into the buffer.
  3529.         if (fread(&m_fileBuf[8], 1, m_fileSize - 8, inputFile) != (m_fileSize - 8))
  3530.         {
  3531.             sts = false;
  3532.         }
  3533.     }
  3534.  
  3535.     // Do we have a file handle?
  3536.     if (inputFile != NULL)
  3537.     {
  3538.         // Close the file.
  3539.         fclose(inputFile);
  3540.         inputFile = NULL;
  3541.     }
  3542.  
  3543.     // Are we OK?
  3544.     if (sts)
  3545.     {
  3546.         SRECT rect;
  3547.  
  3548.         // Set the file position past the header and size information.
  3549.         m_filePos = 8;
  3550.  
  3551.         // Get the frame information.
  3552.         GetRect(&rect);
  3553.         printf("Movie width \t%u\n", (rect.xmax - rect.xmin) / 20);
  3554.         printf("Movie height \t%u\n", (rect.ymax - rect.ymin) / 20);
  3555.  
  3556.         U32 frameRate = GetWord() >> 8;
  3557.         printf("Frame rate \t%u\n", frameRate);
  3558.  
  3559.         U32 frameCount = GetWord();
  3560.         printf("Frame count \t%u\n", frameCount);
  3561.  
  3562.         // Set the start position.
  3563.         m_fileStart = m_filePos;
  3564.  
  3565.         printf("\n----- Reading movie details -----\n");
  3566.         fflush(stdout);
  3567.  
  3568.         // Parse the tags within the file.
  3569.         ParseTags(false, 0);
  3570.         printf("\n***** Finished Dumping SWF File Information *****\n");
  3571.     }
  3572.  
  3573.     // Free the buffer if it is there.
  3574.     if (m_fileBuf != NULL)
  3575.     {
  3576.         delete m_fileBuf;
  3577.         m_fileBuf = NULL;
  3578.     }
  3579.  
  3580.     // Reset the file information.
  3581.     m_filePos = 0;
  3582.     m_fileSize = 0;
  3583.     m_fileStart = 0;
  3584.     m_fileVersion = 0;
  3585.  
  3586.     // Reset the bit position and buffer.
  3587.     m_bitPos = 0;
  3588.     m_bitBuf = 0;
  3589.  
  3590.     return sts;
  3591. }
  3592.  
  3593.  
  3594. int main (int argc, char *argv[])
  3595. // Main program.
  3596. {
  3597.     CInputScript * pInputScript = NULL;
  3598.     char *fileName = 0;
  3599.     int i = 0;
  3600.  
  3601.     // Check the argument count.
  3602.     if (argc < 2)
  3603.     {
  3604.         // Bad arguments.
  3605.         usage();
  3606.         return -1;
  3607.     }
  3608.  
  3609.     // Create a flash script object.
  3610.     if ((pInputScript = new CInputScript()) == NULL)
  3611.     {
  3612.         fprintf( stderr, "Couldn't allocate CInputScript\n" );
  3613.         return -1;
  3614.     }
  3615.  
  3616.     for (i = 1; i < argc; i++)
  3617.     {
  3618.         char *str = argv[i];
  3619.  
  3620.         if (str[0] == '-')
  3621.         {
  3622.             switch (strlen(str))
  3623.             {
  3624.                 case 2:
  3625.                 {
  3626.                     switch( str[ 1 ] )
  3627.                     {
  3628.                         case 't':
  3629.                         {
  3630.                             pInputScript->m_dumpAll = true;
  3631.                             break;
  3632.                         }
  3633.                         case 'i':
  3634.                         {
  3635.                             pInputScript->m_dumpGuts = true;
  3636.                             break;
  3637.                         }
  3638.                         case 's':
  3639.                         {
  3640.                             pInputScript->m_dumpSoundGuts = true;
  3641.                             break;
  3642.                         }
  3643.                         case 'a':
  3644.                         {
  3645.                             pInputScript->m_dumpAll = true;
  3646.                             pInputScript->m_dumpGuts = true;
  3647.                             pInputScript->m_dumpSoundGuts = true;
  3648.                             break;
  3649.                         }
  3650.                         default:
  3651.                         {
  3652.                             fprintf( stderr,
  3653.                                         "Ignoring invalid option: %c\n",
  3654.                                         &str[ 1 ] );
  3655.                         }
  3656.                     }
  3657.                     break;
  3658.                 }
  3659.             }
  3660.         }
  3661.         else
  3662.         {
  3663.             fileName = argv[i];
  3664.         }
  3665.     }
  3666.  
  3667.  
  3668.     // Parse the file passed in.
  3669.     pInputScript->ParseFile(fileName);
  3670.  
  3671.     delete pInputScript;
  3672.     pInputScript = NULL;
  3673.  
  3674.     return 0;
  3675. }
  3676.