# Flash::Writer::SwpParse; package Flash::Writer::Swfparse; use Exporter; use Data::Dumper; use Flash::Constants; use vars qw ($VERSION); @ISA = qw(Exporter); @EXPORT = qw(write); @EXPORT_OK = qw(); $VERSION = "0.01"; # we load the routines array with references to the various # parsing routines this means that all we need to do to parse # a tag with code x is call the routine referenced at # $routines[x] which should mean that it is very fast $routines[0] = \&end; $routines[1] = \&show_frame; $routines[2] = \&define_shape; $routines[3] = \&free_character; $routines[4] = \&place_object; $routines[5] = \&remove_object; $routines[6] = \&define_bits; $routines[7] = \&define_button; $routines[8] = \&JPEG_tables; $routines[9] = \&set_background_colour; $routines[10] = \&define_font; $routines[11] = \&define_text; $routines[12] = \&do_action; $routines[13] = \&define_fontinfo; $routines[14] = \&define_sound; # Event sound tags. $routines[15] = \&start_sound; $routines[17] = \&define_buttonsound; $routines[18] = \&sound_streamhead; $routines[19] = \&sound_streamblock; $routines[20] = \&define_bitslossless; # A bitmap using lossless zlib compression. $routines[21] = \&define_bitsJPEG2; # A bitmap using an internal JPEG compression table. $routines[22] = \&define_shape2; $routines[23] = \&define_buttoncxform; $routines[24] = \&protect; # This file should not be importable for editing. # These are the new tags for Flash 3, $routines[26] = \&place_object2; # The new style place w/ alpha color transform and name. $routines[28] = \&remove_object2; # A more compact remove object that omits the character tag (just depth). $routines[32] = \&define_shape3; # A shape V3 includes alpha values. $routines[33] = \&define_text2; # A text V2 includes alpha values. $routines[34] = \&define_button2; # A button V2 includes color transform, alpha and multiple actions $routines[35] = \&define_bitsJPEG3; # A JPEG bitmap with alpha info. $routines[36] = \&define_bitslossless2; # A lossless bitmap with alpha info. $routines[37] = \&define_edittext; # An editable Text Field $routines[38] = \&define_mousetarget; $routines[39] = \&define_sprite; # Define a sequence of tags that describe the behavior of a sprite. $routines[40] = \&name_character; # Name a character definition, character id and a string, # (used for buttons, bitmaps, sprites and sounds). $routines[43] = \&frame_label; # A string label for the current frame. $routines[45] = \&sound_streamhead2; # For lossless streaming sound, should not have needed this... $routines[46] = \&define_morphshape; # A morph shape definition $routines[48] = \&define_font2; my $framecount; sub new{ my ($self,$flash) = @_; my $tab = "\t"; my ($ver,$len,$xmin,$xmax,$ymin,$ymax,$framec,$framer, $offset) = $flash->get_headers(); print STDERR "dumping file\n"; print "----- Reading the file header -----\n"; print "FWS\n"; print "File version $ver\n"; print "File size $len\n"; print "Movie width ".(($xmax-$xmin)/20)."\n"; print "Movie height ".(($ymax-$ymin)/20)."\n"; print "Frame rate $framer\n"; print "Frame count $framec\n"; print "\n----- Reading movie details -----\n"; print_tags($flash,$tab); return 1; } sub print_tags { my ($flash, $tab) = @_; my @frames = @{$flash->{frames}}; for ($framecount=0; $framecount < scalar(@frames); $framecount++) { foreach my $tag (@{$frames[$framecount]}) { (ref $tag) =~ /Flash::Tags::(.+)$/; my $code = $tagdef->{$1}; if (defined $routines[$code]) { ($routines[$code])->($tag,$tab) } else { default_tag-> ($tag,$tab) } #printf("%stag%s\n", $tab, $1); #printf("\n%s<----- dumping frame %d file offset 0x%04x ----->\n", $tab, $framecount + 1, $tag->offset) if($1 eq 'ShowFrame'); } } } sub INDENT { printf(" "); } sub end { my ($tag, $tab) = @_; printf("%stagEnd\n", $tab); } sub show_frame { my ($tag, $tab) = @_; printf("%stagShowFrame\n", $tab); printf("\n%s<----- dumping frame %d file offset 0x%04x ----->\n", $tab, $framecount + 1, $tag->offset); } sub free_character { my ($tag, $tab) = @_; printf("%stagFreeCharacter \ttagid %-5u\n", $tab, $tag->tagid); } sub place_object { my ($tag, $tab) = @_; printf("%stagPlaceObject \ttagid %-5u depth %-5u\n", $tab, $tag->tagid, $tag->depth); print_matrix($tag->matrix, $tab); print_cxform($tag->cxform, $tab) if (defined $tag->cxform->aa); } sub place_object2 { my ($tag, $tab) = @_; printf("%stagPlaceObject2 \tflags %-5u depth %-5u ", $tab, $tag->flags, $tag->depth); printf("move ") if ( $tag->flags & place_move ); # Get the tag if specified. printf("tag %-5u", $tag->tag) if ($tag->flags & place_character); print "\n"; # Get the matrix if specified. print_matrix($tag->matrix, $tab) if ($tag->flags & place_matrix); # Get the color transform if specified. print_cxform($tag->cxform, $tab) if ($tag->flags & place_colour_transform); # Get the ratio if specified. if ($tag->flags & place_ratio) { &INDENT; printf("ratio %u\n", $tag->ratio); } # Get the clipdepth if specified. if ($tag->flags & place_define_clip) { &INDENT; printf("clipDepth %i\n", $tag->clip_depth); } # Get the instance name if ($tag->flags & place_name) { &INDENT; printf("instance name %s\n", $tag->name); } } sub remove_object { my ($tag, $tab) = @_; printf("%stagRemoveObject \ttagid %-5u depth %-5u\n", $tab, $tag->tagid, $tag->depth); } sub remove_object2 { my ($tag, $tab) = @_; printf("%stagRemoveObject2 depth %-5u\n", $tab, $tag->depth); } sub set_background_colour { my ($tag, $tab) = @_; my $colour = ($tag->colour->r << 16) | ($tag->colour->g << 8) | $tag->colour->b; printf("%stagSetBackgroundColor \tRGB_HEX %06x\n", $tab, $colour); } sub start_sound { my ($tag, $tab) = @_; printf("%stagStartSound \ttagid %-5u\n", $tab, $tag->tagid); &INDENT; print_sound_state($tag->soundstate, $tab); } sub stop_sound { my ($tag, $tab) = @_; printf("%stagStopSound\n", $tab); } sub protect { my ($tag, $tab) = @_; printf("%stagProtect\n", $tab); } sub print_shape_records { my ($records, $tab) = @_; foreach my $record (@{$records}){ print_shape_record($record, $tab) } } sub print_shape_record { my ($record, $tab) = @_; unless ($record->isedge()) { if ($record->flags == 0) { printf("\tEnd of shape.\n\n"); return 1; } if ($record->flags & flags_moveto) { $$x_last = $record->x; $$y_last = $record->y; printf("\n\tmoveto: (%g,%g)\n", $$x_last/20.0, $$y_last/20.0); } printf("\tFillStyle0: %d (%d bits)\n", $record->fillstyle0, $record->fillbits) if ($record->flags & flags_fill0); printf("\tFillStyle1: %d (%d bits)\n", $record->fillstyle1, $record->fillbits) if ($record->flags & flags_fill1); printf("\tLineStyle: %d\n", $record->linestyle ) if ($record->flags & flags_line); if ($record->flags & flags_newstyles) { printf("\tFound more Style info\n"); print_shape_style($record->style,$tab); } printf("\tEnd of shape.\n\n") if ($record->flags & flags_end); return ($record->flags & flags_end) ? 1 : 0; } else { if (substr($record->type,-4) eq "line") { if ($record->type eq "line") { $$x_last += $record->x; $$y_last += $record->y; printf("\tlineto: (%g,%g).\n", $$x_last/20.0, $$y_last/20.0); } else { if (substr($record->type,0,1) eq 'v') { # Vertical line $$y_last += $record->y; printf("\tvlineto: (%g,%g).\n", $$x_last/20.0, $$y_last/20.0); } else { # Horizontal line $$x_last += $record->x; printf("\thlineto: (%g,%g).\n", $$x_last/20.0, $$y_last/20.0); } } } else { # Handle a curve # Get the control $$x_last += $record->cx; $$y_last += $record->cy; printf("\tcurveto: (%g,%g)", $$x_last/20.0, $$y_last/20.0); #Get the anchor $$x_last += $record->ax; $$y_last += $record->ay; printf("(%g,%g)\n", $$x_last/20.0, $$y_last/20.0); } return 0; } } sub print_matrix { my ($matrix, $tab) = @_; printf("%s\t[%5.3f %5.3f]\n", $tab, $matrix->a/65536.0, $matrix->b/65536.0); printf("%s\t[%5.3f %5.3f]\n", $tab, $matrix->c/65536.0, $matrix->d/65536.0); printf("%s\t[%5.3f %5.3f]\n", $tab, $matrix->tx/20.0, $matrix->ty/20.0); #printf("%s\t[%08x %08x]\n", $tab, $matrix->a, $matrix->b); #printf("%s\t[%08x %08x]\n", $tab, $matrix->c, $matrix->d); #printf("%s\t[%d %d]\n", $tab, $matrix->tx, $matrix->ty); } sub print_rect { my ($rect, $tab) = @_; printf("\t%s(%g, %g)[%g x %g]\n", $tab, $rect->xmin / 20.0, $rect->ymin / 20.0, $rect->xmax - $rect->xmin / 20.0, $rect->ymax - $rect->ymin / 20.0); } sub print_cxform { my ($cx, $tab) = @_; printf("%sCXFORM:\n", $tab); printf("%sAlpha: mul:%04u add:%04u\n",$tab, $cx->aa, $cx->ab); printf("%sRed: mul:%04u add:%04u\n",$tab, $cx->ra, $cx->rb); printf("%sGreen: mul:%04u add:%04u\n",$tab, $cx->ga, $cx->gb); printf("%sBlue: mul:%04u add:%04u\n",$tab, $cx->ba, $cx->bb); } sub print_shape_style #!!!!!!! pos { my ($style, $tab) = @_; printf("\tNumber of fill styles \t%u\n", scalar(@{$style->fills})); for (my $a=0; $a<=scalar(@{$style->fills}); $a++) { my $fill = $style->fills->[$a]; last unless (defined $fill); if ($fill->style & fill_gradient) { my $ncolours = scalar(@{$fill->colours}); printf("%s\tGradient Fill with %u colors\n", $tab, $ncolours-1 ); for (my $j=0; $j<$ncolours; $j++) { my $pos = 0;#GetByte(); printf("%s\tcolor:%d: at:%d RGBA:%08x\n", $tab, $j, $pos, $fill->colours->[$j]->rgba()); } printf("%s\tGradient Matrix:\n", $tab); print_matrix($fill->matrix, $tab); } elsif ($fill->style & fill_bits) { printf("%s\tBitmap Fill: %04x\n", $tab, $fill->bitmapid); print_matrix($fill->matrix, $tab); } else { # A solid color printf("%s\tSolid Color Fill RGB_HEX %06x\n", $tab, $fill->colours->[0]->rgba()); } } my $nlines = scalar(@{$style->lines}); printf("\tNumber of line styles \t%u\n", $nlines); for (my $i = 1; $i <$nlines; $i++) { printf("\tLine style %-5u width %g color RGB_HEX %06x\n", $i, $style->lines->[$i]->width/20.0, $style->lines->[$i]->colour->rgba()); } } sub define_shape { my ($tag, $tab) = @_; printf("%stagDefineShape \ttagid %-5u\n", $tab, $tag->shapeid); print_shape_style($tag->style,$tab); print_shape_records($tag->records,$tab); } sub define_shape2 { my ($tag, $tab) = @_; printf("%stagDefineShape2 -> ", $tab); define_shape($tag, $tab); } sub define_shape3 { my ($tag, $tab) = @_; printf("%stagDefineShape3: -> ", $tab); define_shape($tag, $tab, 1); } sub dump_image_guts { my ($guts, $tab) = @_; my $lfcount = 0; &INDENT; printf("%s----- dumping image details -----", $tab); foreach my $val (@{$guts}) { if (($lfcount % 16) == 0) { printf("\n"); &INDENT; printf("%s", $tab); } $lfcount ++; printf("%02x ", $val); } printf("\n"); } sub define_bits { my ($tag, $tab) = @_; printf("%stagDefineBits \ttagid %-5u\n", $tab, $tag->tagid); dump_image_guts($tag->guts, $tab); } sub define_bitsJPEG2 { my ($tag, $tab) = @_; printf("%stagDefineBitsJPEG2 \ttagid %-5u\n", $tab, $tag->tagid); dump_image_guts($tag->encoding, $tab); dump_image_guts($tag->image, $tab); } sub define_bitsJPEG3 { my ($tag, $tab) = @_; printf("%stagDefineBitsJPEG3 \ttagid %-5u\n", $tab, $tag->tagid); dump_image_guts($tag->guts, $tab); } sub define_bitslossless # split into two arrays (plus guts { my ($tag, $tab) = @_; printf("%stagDefineBitsLossless tagid %-5u\n", $tab, $tag->tagid); printf("%sformat %-3u width %-5u height %-5u tableSize %d\n", $tab, $tag->format, $tag->width, $tag->height, $tag->table_size); printf("\n"); my $i; for ($i=0; $i<$tag->table_size*3; $i+=3) { printf("%02x%02x%02x ", $tag->decompressed->[$i],$tag->decompressed->[$i+1], $tag->decompressed->[$i+2]); printf("\n") if (($i % 24) == 21); } printf("\n"); $i++; for (my $y=0; $y<$tag->height; $y++) { for (my $x=0; $x<$tag->width; $x++, $i++) { printf("%02x", $tag->[$i]); } printf("\n"); } printf("\n"); # hmmm !!! #dump_image_guts($guts,$tab); } sub define_bitsLossless2 { my ($tag, $tab) = @_; ParseDefineBitsLossless($tag, $tab); } sub JPEG_tables { my ($tag, $tab) = @_; printf("%stagJPEGTables\n", $tab); dump_image_guts($tag->guts, $tab); } sub print_buttonrecord { my ($record, $tab) = @_; printf("%s\tParseButtonRecord: char:%d layer:%d ", $tab, $record->character,$record->layer); printf("HIT ") if ($recordg->state_hittest); printf("DOWN ") if ($record->state_down); printf("OVER ") if ($recordg->state_over); printf("UP ") if ($record->state_up); printf("\n"); print_matrix($record->matrix, $tab); } sub define_button { my ($tag, $tab) = @_; printf("%stagDefineButton \ttagid %-5u\n", $tab, $tag->tagid); foreach my $record (@{$tag->buttonrecords}) { print_buttonrecord($record, $tab); } foreach my $action (@{$tag->actions}) { print_action($action, $tab); } } sub define_button2(char *str) # ????? { my ($tag, $tab) = @_; printf("%stagDefineButton2 \ttagid %-5u\n", $tab, $tag->tagid); foreach my $record (@{$tag->buttonrecords}) { print_buttonrecord($record, $tab); } foreach my $condition (@{$tag->actionconditions}) { print_actioncondition($condition, $tab); } printf("\n"); } sub print_actioncondition { my ($condition, $tab) = @_; printf("%sCondition: %04x\n", $tab, $condition->condition); foreach my $action (@{$condition->actions}) { print_action($action, $tab); } } sub do_action { my ($tag, $tab) = @_; printf("%stagDoAction\n", $tab); foreach my $action (@{$tag->actions}) { print_action($action, $tab); } } sub print_action { my ($action, $tab) = @_; &INDENT; printf("%saction code 0x%02x ", $tab, $action->code); if ($action->code == 0) { # Action code of zero indicates end of actions printf("\n"); return; } printf("has length %-5u ", $action->length) if ($action->length>0); SWITCH: for ($_ = $actiondict->{$action->code}) { /NextFrame/ && do { printf( "gotoNextFrame\n" ); last SWITCH; }; /PrevFrame/ && do { printf( "gotoPrevFrame\n" ); last SWITCH; }; /Play/ && do { printf( "play\n" ); last SWITCH; }; /Stop/ && do { printf( "stop\n" ); last SWITCH; }; /ToggleQuality/ && do { printf( "toggleQuality\n" ); last SWITCH; }; /StopSounds/ && do { printf( "stopSounds\n" ); last SWITCH; }; /Add/ && do { printf( "add\n" ); last SWITCH; }; /Subtract/ && do { printf( "subtract\n" ); last SWITCH; }; /Multiply/ && do { printf( "multiply\n" ); last SWITCH; }; /Divide/ && do { printf( "divide\n" ); last SWITCH; }; /Equal/ && do { printf( "equal\n" ); last SWITCH; }; /LessThan/ && do { printf( "lessThan\n" ); last SWITCH; }; /LogicalAnd/ && do { printf( "logicalAnd\n" ); last SWITCH; }; /LogicalOr/ && do { printf( "logicalOr\n" ); last SWITCH; }; /LogicalNot/ && do { printf( "logicalNot\n" ); last SWITCH; }; /StringEqual/ && do { printf( "stringEqual\n" ); last SWITCH; }; /StringLength/ && do { printf( "stringLength\n" ); last SWITCH; }; /SubString/ && do { printf( "subString\n" ); last SWITCH; }; /Int/ && do { printf( "int\n" ); last SWITCH; }; /Eval/ && do { printf( "eval\n" ); last SWITCH; }; /SetVariable/ && do { printf( "setVariable\n" ); last SWITCH; }; /SetTargetExpression/ && do { printf( "setTargetExpression\n" ); last SWITCH; }; /StringConcat/ && do { printf( "stringConcat\n" ); last SWITCH; }; /GetProperty/ && do { printf( "getProperty\n" ); last SWITCH; }; /SetProperty/ && do { printf( "setProperty\n" ); last SWITCH; }; /DuplicateClip/ && do { printf( "duplicateClip\n" ); last SWITCH; }; /RemoveClip/ && do { printf( "removeClip\n" ); last SWITCH; }; /Trace/ && do { printf( "trace\n" ); last SWITCH; }; /StartDragMovie/ && do { printf( "startDragMovie\n" ); last SWITCH; }; /StopDragMovie/ && do { printf( "stopDragMovie\n" ); last SWITCH; }; /StringLessThan/ && do { printf( "stringLessThan\n" ); last SWITCH; }; /Random/ && do { printf( "random\n" ); last SWITCH; }; /MBLength/ && do { printf( "mbLength\n" ); last SWITCH; }; /Ord/ && do { printf( "ord\n" ); last SWITCH; }; /Chr/ && do { printf( "chr\n" ); last SWITCH; }; /GetTimer/ && do { printf( "getTimer\n" ); last SWITCH; }; /MBSubString/ && do { printf( "mbSubString\n" ); last SWITCH; }; /MBOrd/ && do { printf( "mbOrd\n" ); last SWITCH; }; /MBChr/ && do { printf( "mbChr\n" ); last SWITCH; }; /GotoFrame/ && do { printf("gotoFrame %5u\n", $action->frame); last SWITCH; }; /GetURL/ && do { printf("getUrl %s target %s\n", $action->url, $action->target); last SWITCH; }; /WaitForFrame/ && do { printf("waitForFrame %-5u skipCount %-5u\n", $action->frame, $action->skip_count); last SWITCH; }; /SetTarget/ && do { printf("setTarget %s\n", $action->target); last SWITCH; }; /GotoLabel/ && do { printf("gotoLabel %s\n", $action->label); last SWITCH; }; /WaitForFrameExpression/ && do { printf( "waitForFrameExpression skipCount %-5u\n", $action->skip_count); last SWITCH; }; /PushData/ && do { if ( $action->datatype == 1 ) { printf("pushData (float): %08x %.1f\n", $action->propertyid, $action->propertyid) }elsif ( $action->datatype == 0 ){ printf("pushData (string): %s\n", $action->label) }else{ printf("pushData invalid dataType: %02x\n",$action->datatype); } last SWITCH; }; /BranchAlways/ && do { printf("branchAlways offset: %-5u\n",$action->offset); last SWITCH; }; /GetURL2/ && do { if ( $action->flag == 1 ) { printf( "getUrl2 sendvars=GET\n" ); } elsif ( $action->flag == 2 ) { printf( "getUrl2 sendvars=POST\n" ); } else { printf( "getUrl2 sendvars=Don't send\n" ); } last SWITCH; }; /BranchIfTrue/ && do { printf("branchIfTrue offset: %-5u\n",$action->offset); last SWITCH; }; /CallFrame/ && do { printf( "callFrame\n" ); last SWITCH; }; /GotoExpression/ && do { if ( $action->stopflag == 0 ) { printf("gotoExpression and Stop\n" ); } elsif ( $action->stopflag == 1 ) { printf("gotoExpression and Play\n" ); } else { printf("gotoExpression invalid stopFlag: %d\n", $action->stopflag ); } last SWITCH; }; # default printf("UNKNOWN?\n"); } } # ignore the fillbits etc because we just dont' need em sub define_font #!!!!!!!!!!!! { my ($tag, $tab) = @_; printf("%stagDefineFont \t\tFont ID %-5u\n", $tab, $tag->fontid); printf("%s\tiOffset: 0x%04x\n", $tab, $tag->offset); printf("%s\tnumber of glyphs: %d\n", $tab, scalar(@{$tag->glyphs})-1); foreach my $record (@{$tag->glyphs}) { last unless (defined $record); #print_text_record($record, $tab); } } sub define_fontinfo { my ($tag, $tab) = @_; printf("%stagDefineFontInfo \tFont ID %-5u\n", $tab, $tag->fontid); printf("%s\tNameLen: '%i'\n", $tab, length($tag->name)); printf("%s\tFontName: '%s'\n", $tab, $tag->name); printf("%s\t", $tab); foreach my $code (@{$tag->code_table}) { printf("[%d,'%c'] ", $code, $code); } printf("\n\n"); } sub print_text_record { my ($record, $tab) = @_; return unless (defined $record); printf("\n%s\tflags: 0x%02x\n", $tab, $record->flags); if ($record->flags & is_text_control) { printf("%s\tfontId: %d\n", $tab, $record->fontid) if ($record->flags & text_hasfont); if ($record->flags & text_hascolour) { printf("%s\tfontColour: (%d,%d,%d)\n", $tab, $record->colour->r, $record->colour->g, $record->colour->b) } printf("%s\tX-offset: %d\n", $tab, $record->x_offset) if ($record->flags & text_hasxoffset); printf("%s\tY-offset: %d\n", $tab, $record->y_offset) if ($record->flags & text_hasyoffset); printf("%s\tFont Height: %d\n", $tab, $record->height) if ($record->flags & text_hasfont); }else{ printf("%s\tnumber of glyphs: %d\n", $tab, scalar(@{$record->glyphs})-1); printf("%s\t", $tab); foreach my $gr (@{$record->glyphs}) { printf("[%d,%d] ", $gr->{index}, $gr->{advance}); } printf("\n"); } return 1; } sub define_text { my ($tag, $tab) = @_; printf("%stagDefineText \t\ttagid %-5u\n", $tab, $tag->tagid); print_rect($tag->rect, $tab); #print_matrix(m, $tab); printf("%s\tnGlyphBits:%d nAdvanceBits:%d\n", $tab, $tag->glyph_bits, $tag->advance_bits); foreach my $record (@{$tag->text_records}) { #print_text_record($record, $tab); } printf("\n"); } sub define_edittext { my ($tag, $tab) = @_; printf("%stagDefineEditText: tagid %d flags:%04x ", $tab, $tag->tagid, $tag->flags); printf("FontId:%d FontHeight:%d ", $tag->fontid, $tag->height) if ($tag->flags & edittext_hashont); printf("length:%d ", $tag->maxlength) if ($tag->flags & edittext_hasmaxlength); printf("variable:%s ", $tag->variable); printf("text:%s ", $tag->initialtext) if ($tag->flags & edittext_hastext ); printf("\n"); } # ignore the tag end and file pos at the end of this. Just not worth it. sub define_font2 { my ($tag, $tab) = @_; print STDERR "DefienFont2 : "; printf("%stagDefineFont2 \ttagid %-5u flags:%04x nGlyphs:%d\n", $tab, $tag->tagid, $tag->flags, scalar(@{$tag->glyphs})-1); if (scalar(@{$tag->glyphs}) > 1) { for(my $n=0; $nglyphs}); $n++) { printf("\n\t%s>>> Glyph:%d", $tab, $n); print_shape_records($tag->glyphs,$tab); } printf("\n%sCodeTable:\n%s", $tab, $tab); for(my $n=0; $nglyphs}); $n++) { printf("%02x:[%c] ", $tag->code_table->[$n], GetByte()); printf("\n%s", $tab) if (($tag->code_table->[$n] & 7) == 7); } printf("\n"); } if ($tag->flags & font_haslayout) { printf("\n%sHasLayout: iAscent:%d iDescent:%d iLeading:%d\n", $tab, $tag->ascent, $tag->descent, $tag->leading); printf("\n%sKerning Pair Count:%d\n", $tab, scalar(@{$tag->kerning_pairs})-1); for (my $i=0; $ikerning_pairs}); $i++) { printf("%sKerningPair:%-4d %c <--> %c : %d\n", $tab, $i, $tag->kerning_pairs->[$i]->code1, $tag->kerning_pairs->[$i]->code2, $tag->kerning_pairs->[$i]->adjust); } #printf("m_tagEnd:%08x m_filePos:%08x\n", m_tagEnd, m_filePos); } } sub define_text2 { my ($tag, $tab) = @_; printf("%stagDefineText2 \ttagid %-5u\n", $tab, $tag->tagid); } sub define_morphshape { my ($tag, $tab) = @_; printf("%stagDefineMorphShape: tagid:%d\n", $tab, $tag->tagid); # swfparse doesn't print any info about the shapestyles :( # Print the start shape printf("\n\t--- StartShape ---"); foreach my $record (@{$tag->startrecords}) { print_shape_record($record,$tab) } # Parse the end shape printf("\t--- EndShape ---"); foreach my $record (@{$tag->endrecords}) { print_shape_record($record,$tab) } } sub print_adpcm #!!!!!!!!! { } sub print_mp3_headers { } sub print_sound_state #!!!!!!!!!!! { my ($state,$tab) = @_; &INDENT; printf("%ssound code %u", $tab, $state->soundcode); printf(" inpoint %u", $state->inpoint) if ($state->soundcode & sound_hasinpoint ); printf(" outpoint %u", $state->outpoint) if ($state->soundcode & sound_hasoutpoint ); printf(" loops %u", $state->loops) if ($state->soundcode & sound_hasloops ); printf("\n"); if ($state->soundcode & sound_hasenvelope ) { foreach my $envelope (@{$state->envelopes}) { printf("\n"); &INDENT; printf("%smark44 %u", $tab, $envelope->mark44); printf(" left chanel %u", $envelope->left); printf(" right chanel %u", $envelope->right); printf("\n"); } } } sub define_sound { my ($tag, $tab) = @_; printf("%stagDefineSound: ", $tab); # The stream settings my @compression = qw(uncompressed ADPCM MP3); my @samplerate = qw(5.5 11 22 44); my $samplesize = ($tag->samplesize == 0) ? "8" : "16"; my $stereomono = ($tag->stereomono == 0) ? "mono" : "stereo"; printf("%s %skHz %s-bit %s NumberOfSamples:%d (%08x)\n", $compression[$tag->compression], $samplerate[$tag->samplerate], $samplesize, $stereomono, $tag->samplecount, $tag->samplecount); printf("%s uncompressed samples\n", $tab) if ($tag->compression == 0); print_adpcm($tag->adpcm) if ($tag->compression == 1); if ($tag->compression == 2) { printf("%s MP3: %d Delay:%d\n", $tab, $tag->mp3delay); print_mp3_headers ($tag->mp3headers); } # U8* pbSamples = new U8[iSampleCount * (iSoundSize ? 2 : 1)]; # delete pbSamples; } sub define_buttonsound { my ($tag, $tab) = @_; printf("%stagDefineButtonSound \ttagid %-5u\n", $tab, $tag->tagid); # step through for button states for (my $i = 0; $i < 3; $i++) { my $state = $tag->states->[$i]; &INDENT; printf("%supState \ttagid %-5u\n", $tab, $state->soundtag) if ($i == 0); printf("%soverState \ttagid %-5u\n", $tab, $state->soundtag) if ($i == 1); printf("%sdownState \ttagid %-5u\n", $tab, $state->soundtag) if ($i == 2); print_sound_state($state->soundstate,$tab) if ($state->soundtag); } } sub sound_streamhead { my ($tag, $tab) = @_; print_stream_head($tag, $tab, 0); } sub sound_streamhead2 { my ($tag, $tab) = @_; print_stream_head($tag, $tab, 1); } sub print_stream_head { my ($tag, $tab, $ishead2) = @_; # The stream settings my @compression = qw(uncompressed ADPCM MP3); my @samplerate = qw(5.5 11 22 44); my $samplesize = ($tag->sample_size == 0) ? "8" : "16"; my $stereomono = ($tag->stereomono == 0) ? "mono" : "stereo"; printf("%stagSoundStreamHead%s: %s %skHz %s-bit %s AverageSamplesPerFrame:%d\n", $tab, $ishead2 ? "2" : "", $compression[$tag->compression], $samplerate[$tag->sample_rate], $samplesize, $stereomono, $tag->samples); } sub sound_streamblock { my ($tag, $tab) = @_; printf("%stagSoundStreamBlock: ", $tab); printf("%s uncompressed samples\n", $tab) if ($tag->compression == 0); print_adpcm($tag->adpcm) if ($tag->compression == 1); if ($tag->compression == 2) { printf("%s MP3: SamplesPerFrame:%d Delay:%d\n", $tab, $tag->samplesperframe, $tag->delay); print_mp3_headers ($tag->mp3headers, $tag->samplesperframe); } } sub define_buttoncxform { my ($tag, $tab) = @_; printf("%stagDefineButtonCxform \ttagid %-5u\n", $tab, $tag->tagid); foreach my $cxform (@{$tag->cxform}) { print_cxform($cxform, $tab); } } sub name_character { my ($tag, $tab) = @_; printf("%stagNameCharacter \ttagid %-5u label '%s'\n", $tab, $tag->tagid, $tag->label); } sub frame_label { my ($tag, $tab) = @_; printf("%stagFrameLabel label \"%s\"\n", $tab, $tag->label); } sub define_mousetarget { my ($tag, $tab) = @_; printf("%stagDefineMouseTarget\n",$tab); } sub default { my ($tag, $tab) = @_; printf("%sUnknown Tag:0x%02x len:0x%02x\n", $tab, $tag->type, $tag->length); } sub define_sprite { my ($tag, $tab) = @_; printf("%stagDefineSprite \ttagid %-5u \tframe count %-5u\n", $tab, $tag->tagid, $tag->framecount); print_tags($tag->movie, $tab."\t"); } 1;