diff --git a/trunk/lib/FlashPlayer.exe b/trunk/lib/FlashPlayer.exe index 4e0288eda..0f5dc1e0a 100644 Binary files a/trunk/lib/FlashPlayer.exe and b/trunk/lib/FlashPlayer.exe differ diff --git a/trunk/libsrc/FlashPlayer/uMain.dcu b/trunk/libsrc/FlashPlayer/uMain.dcu index 0fb017b3c..e74554a12 100644 Binary files a/trunk/libsrc/FlashPlayer/uMain.dcu and b/trunk/libsrc/FlashPlayer/uMain.dcu differ diff --git a/trunk/libsrc/FlashPlayer/uMain.dfm b/trunk/libsrc/FlashPlayer/uMain.dfm index 850b957df..7a4b131e6 100644 --- a/trunk/libsrc/FlashPlayer/uMain.dfm +++ b/trunk/libsrc/FlashPlayer/uMain.dfm @@ -1,11 +1,10 @@ object frmMain: TfrmMain - Left = 567 - Top = 217 - Width = 604 - Height = 537 - HorzScrollBar.Position = 8 + Left = 506 + Top = 161 + Width = 1381 + Height = 811 Caption = 'FFDec Flash Player' - Color = clBtnFace + Color = clWhite Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -14 @@ -650,22 +649,24 @@ object frmMain: TfrmMain PixelsPerInch = 120 TextHeight = 16 object flaPreview: TShockwaveFlash - Left = 2 - Top = 10 - Width = 752 - Height = 432 + Left = 98 + Top = 34 + Width = 151 + Height = 135 TabOrder = 0 + OnReadyStateChange = flaPreviewReadyStateChange ControlData = { - 67556655000B00002D3E0000B823000008000200000000000800000000000800 - 0000000008000E000000570069006E0064006F00770000000800060000002D00 - 310000000800060000002D003100000008000A00000048006900670068000000 - 08000200000000000800060000002D0031000000080000000000080002000000 - 0000080010000000530068006F00770041006C006C0000000800040000003000 - 0000080004000000300000000800020000000000080000000000080002000000 - 00000D0000000000000000000000000000000000080004000000310000000800 - 0400000030000000080000000000080004000000300000000800080000006100 - 6C006C00000008000C000000660061006C0073006500000008000C0000006600 - 61006C007300650000000800060000002D0031000000} + 67556655000B00007C0C00002A0B000008000200000000000800040000002D00 + 00000800040000002D00000008000E000000570069006E0064006F0077000000 + 0800060000002D00310000000800060000002D003100000008000A0000004800 + 690067006800000008000200000000000800060000002D003100000008000000 + 000008000E00000061006C007700610079007300000008001000000053006800 + 6F00770041006C006C0000000800040000003000000008000400000030000000 + 080002000000000008000000000008000200000000000D000000000000000000 + 0000000000000000080004000000310000000800040000003000000008000000 + 00000800040000003000000008000800000061006C006C00000008000C000000 + 660061006C0073006500000008000C000000660061006C007300650000000800 + 060000002D0031000000} end object tmrWatchDog: TTimer OnTimer = tmrWatchDogTimer diff --git a/trunk/libsrc/FlashPlayer/uMain.pas b/trunk/libsrc/FlashPlayer/uMain.pas index e3c0a7014..78be0bec2 100644 --- a/trunk/libsrc/FlashPlayer/uMain.pas +++ b/trunk/libsrc/FlashPlayer/uMain.pas @@ -15,6 +15,8 @@ type procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure tmrWatchDogTimer(Sender: TObject); + procedure flaPreviewReadyStateChange(ASender: TObject; + newState: Integer); private { Private declarations } public @@ -63,19 +65,20 @@ end; procedure TPipeThread.displaySWF(); begin windows.SetParent(frmMain.Handle,target); - frmMain.flaPreview.Free; - frmMain.flaPreview:=nil; - frmMain.flaPreview:=TShockwaveFlash.Create(frmMain); + frmMain.flaPreview.Stop; + frmMain.flaPreview.Movie := ''; frmMain.flaPreview.Left:=0; frmMain.flaPreview.Top:=0; frmMain.flaPreview.Width:=self.w; frmMain.flaPreview.Height:=self.h; - frmMain.flaPreview.Parent:=frmMain; - frmMain.flaPreview.Movie:=flashFile; - - frmMain.flaPreview.Play; + frmMain.flaPreview.AllowScriptAccess:='always'; frmMain.Caption:='set movie:'+flashFile; - //showmessage('flashmovie:'+flashFile); + frmMain.Repaint(); + + frmMain.flaPreview.Playing := true; + frmMain.flaPreview.Movie:=flashFile; + frmMain.flaPreview.Play; + end; @@ -83,18 +86,22 @@ end; procedure TPipeThread.setPos(); var movie:WideString; begin + movie:=frmMain.flaPreview.Movie; SetWindowPos(frmMain.Handle,0,0,0,self.w,self.h,SWP_SHOWWINDOW); + frmMain.flaPreview.Movie:=''; + frmMain.flaPreview.Playing := false; frmMain.flaPreview.Parent:=nil; frmMain.flaPreview.Left:=0; frmMain.flaPreview.Top:=0; frmMain.flaPreview.Width:=self.w; frmMain.flaPreview.Height:=self.h; frmMain.flaPreview.Parent:=frmMain; + frmMain.flaPreview.AllowScriptAccess:='always'; frmMain.flaPreview.Movie:=movie; - + frmMain.flaPreview.Play; frmMain.Caption:=''+inttostr(self.w)+'x'+inttostr(self.h); - frmMain.Repaint; + end; procedure TPipeThread.Execute(); @@ -105,6 +112,7 @@ pipename:PAnsiChar; len:integer; cmd:integer; begin + pipename:=PAnsiChar('\\.\\pipe\ffdec_flashplayer_'+ParamStr(1)); while (not self.Terminated) do begin @@ -152,6 +160,12 @@ procedure TfrmMain.FormActivate(Sender: TObject); begin if(ParamCount>=2) then begin + + ShowWindow(Application.Handle, SW_HIDE) ; + SetWindowLong(Application.Handle, GWL_EXSTYLE, getWindowLong(Application.Handle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW) ; + ShowWindow(Application.Handle, SW_SHOW); + + SetForegroundWindow(HWND(strtoint(ParamStr(2)))); frmMain.Caption:='FlashPlayerWindow_'+ParamStr(2); Application.Title:='FlashPlayerWindow_'+ParamStr(2); @@ -161,18 +175,17 @@ begin frmMain.Left:=0; frmMain.Top:=0; windows.SetParent(frmMain.Handle,target); - end; + + t:=TPipeThread.Create(true); + t.Resume; + end; end; procedure TfrmMain.FormCreate(Sender: TObject); begin if(ParamCount>=2) then begin - ShowWindow(Application.Handle, SW_HIDE) ; - SetWindowLong(Application.Handle, GWL_EXSTYLE, getWindowLong(Application.Handle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW) ; - ShowWindow(Application.Handle, SW_SHOW); - t:=TPipeThread.Create(true); - t.Resume; + end; end; @@ -192,4 +205,14 @@ begin end; end; +procedure TfrmMain.flaPreviewReadyStateChange(ASender: TObject; + newState: Integer); +begin +if newState = 4 then + begin + frmMain.flaPreview.Playing := True; + frmMain.flaPreview.Play; + end; +end; + end. diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java index c38dd286b..f2ec35a90 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java @@ -28,6 +28,8 @@ import com.jpexs.decompiler.flash.abc.RenameType; import com.jpexs.decompiler.flash.abc.ScriptPack; import com.jpexs.decompiler.flash.abc.types.traits.Trait; import com.jpexs.decompiler.flash.abc.types.traits.TraitClass; +import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.parser.pcode.ASMParser; import com.jpexs.decompiler.flash.gui.abc.ABCPanel; import com.jpexs.decompiler.flash.gui.abc.ClassesListTreeModel; import com.jpexs.decompiler.flash.gui.abc.DeobfuscationDialog; @@ -61,8 +63,10 @@ import com.jpexs.decompiler.flash.tags.DefineSpriteTag; import com.jpexs.decompiler.flash.tags.DefineText2Tag; import com.jpexs.decompiler.flash.tags.DefineTextTag; import com.jpexs.decompiler.flash.tags.DefineVideoStreamTag; +import com.jpexs.decompiler.flash.tags.DoActionTag; import com.jpexs.decompiler.flash.tags.EndTag; import com.jpexs.decompiler.flash.tags.ExportAssetsTag; +import com.jpexs.decompiler.flash.tags.FileAttributesTag; import com.jpexs.decompiler.flash.tags.JPEGTablesTag; import com.jpexs.decompiler.flash.tags.PlaceObject2Tag; import com.jpexs.decompiler.flash.tags.SetBackgroundColorTag; @@ -72,6 +76,7 @@ import com.jpexs.decompiler.flash.tags.SoundStreamHead2Tag; import com.jpexs.decompiler.flash.tags.SoundStreamHeadTag; import com.jpexs.decompiler.flash.tags.SymbolClassTag; import com.jpexs.decompiler.flash.tags.Tag; +import com.jpexs.decompiler.flash.tags.VideoFrameTag; import com.jpexs.decompiler.flash.tags.base.ASMSource; import com.jpexs.decompiler.flash.tags.base.AloneTag; import com.jpexs.decompiler.flash.tags.base.BoundedTag; @@ -140,6 +145,9 @@ import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -2868,6 +2876,14 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel setEditText(false); reload(false); } + + private void stopFlashPlayer(){ + if (flashPanel != null) { + if(!flashPanel.isStopped()){ + flashPanel.stopSWF(); + } + } + } public void reload(boolean forceReload) { Object tagObj = tagTree.getLastSelectedPathComponent(); @@ -2924,26 +2940,32 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel } swfPreviewPanel.stop(); if ((tagObj instanceof SWFRoot) && miInternalViewer.isSelected()) { + stopFlashPlayer(); showCard(CARDSWFPREVIEWPANEL); swfPreviewPanel.load(swf); swfPreviewPanel.play(); - } else if (tagObj instanceof DefineVideoStreamTag) { + } /*else if (tagObj instanceof DefineVideoStreamTag) { showCard(CARDEMPTYPANEL); } else if ((tagObj instanceof DefineSoundTag) || (tagObj instanceof SoundStreamHeadTag) || (tagObj instanceof SoundStreamHead2Tag)) { showCard(CARDEMPTYPANEL); - } else if (tagObj instanceof DefineBinaryDataTag) { - showCard(CARDEMPTYPANEL); + } */else if (tagObj instanceof DefineBinaryDataTag) { + stopFlashPlayer(); + showCard(CARDEMPTYPANEL); } else if (tagObj instanceof ASMSource) { + stopFlashPlayer(); showCard(CARDACTIONSCRIPTPANEL); actionPanel.setSource((ASMSource) tagObj, !forceReload); } else if (tagObj instanceof ImageTag) { + stopFlashPlayer(); imageButtonsPanel.setVisible(((ImageTag) tagObj).importSupported()); showCard(CARDIMAGEPANEL); imagePanel.setImage(((ImageTag) tagObj).getImage(swf.tags)); } else if ((tagObj instanceof DrawableTag) && (!(tagObj instanceof TextTag)) && (miInternalViewer.isSelected())) { + stopFlashPlayer(); showCard(CARDDRAWPREVIEWPANEL); previewImagePanel.setDrawable((DrawableTag) tagObj, swf, characters); } else if (tagObj instanceof FrameNode && ((FrameNode) tagObj).isDisplayed() && (miInternalViewer.isSelected())) { + stopFlashPlayer(); showCard(CARDDRAWPREVIEWPANEL); FrameNode fn = (FrameNode) tagObj; List controlTags = swf.tags; @@ -2968,8 +2990,18 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel try (FileOutputStream fos = new FileOutputStream(tempFile)) { SWFOutputStream sos = new SWFOutputStream(fos, 10); sos.write("FWS".getBytes()); - sos.write(13); + sos.write(swf.version); + int frameCount = 100; + HashMap videoFrames=new HashMap<>(); + DefineVideoStreamTag vs=null; + if (tagObj instanceof DefineVideoStreamTag){ + vs = (DefineVideoStreamTag)tagObj; + swf.populateVideoFrames(vs.getCharacterId(), new ArrayList(swf.tags), videoFrames); + frameCount = videoFrames.size(); + } + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); SWFOutputStream sos2 = new SWFOutputStream(baos, 10); int width = swf.displayRect.Xmax - swf.displayRect.Xmin; @@ -2977,7 +3009,10 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel sos2.writeRECT(swf.displayRect); sos2.writeUI8(0); sos2.writeUI8(swf.frameRate); - sos2.writeUI16(100); //framecnt + sos2.writeUI16(frameCount); //framecnt + + FileAttributesTag fa = new FileAttributesTag(); + sos2.writeTag(fa); Color backgroundColor = View.swfBackgroundColor; if (tagObj instanceof FontTag) { //Fonts are always black on white @@ -2985,7 +3020,7 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel } sos2.writeTag(new SetBackgroundColorTag(null, new RGB(backgroundColor))); - + if (tagObj instanceof FrameNode) { FrameNode fn = (FrameNode) tagObj; Object parent = fn.getParent(); @@ -3121,10 +3156,67 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel sos2.writeTag(new PlaceObject2Tag(null, false, false, false, true, false, true, false, true, 1, chtId, mat, null, ratio, null, 0, null)); sos2.writeTag(new ShowFrameTag(null)); } + } else if (tagObj instanceof SoundStreamHeadTypeTag){ + List sbs=new ArrayList<>(); + SWF.populateSoundStreamBlocks(new ArrayList(swf.tags), (Tag)tagObj,sbs); + for(SoundStreamBlockTag blk:sbs){ + sos2.writeTag(blk); + sos2.writeTag(new ShowFrameTag(null)); + } + } else if (tagObj instanceof DefineSoundTag){ + ExportAssetsTag ea=new ExportAssetsTag(); + ea.tags.add(1); + ea.names.add("my_define_sound"); + sos2.writeTag(ea); + DoActionTag doa=new DoActionTag(null, new byte[]{}, SWF.DEFAULT_VERSION, 0); + List actions=ASMParser.parse(0, 0, false, + "ConstantPool \"my_sound\" \"Sound\" \"my_define_sound\" \"attachSound\" \"start\"\n" + + "Push \"my_sound\" 0.0 \"Sound\"\n"+ + "NewObject\n"+ + "DefineLocal\n"+ + "Push \"my_define_sound\" 1 \"my_sound\"\n"+ + "GetVariable\n"+ + "Push \"attachSound\"\n"+ + "CallMethod\n"+ + "Pop\n"+ + "Push 9999 0.0 2 \"my_sound\"\n"+ + "GetVariable\n"+ + "Push \"start\"\n"+ + "CallMethod\n"+ + "Pop\n"+ + "Stop", SWF.DEFAULT_VERSION); + doa.setActions(actions, SWF.DEFAULT_VERSION); + sos2.writeTag(doa); + sos2.writeTag(new ShowFrameTag(null)); + sos2.writeTag(new ShowFrameTag(null)); + } else if (tagObj instanceof DefineVideoStreamTag){ + + sos2.writeTag(new PlaceObject2Tag(null, false, false, false, false, false, true, true, false, 1, chtId, mat, null, 0, null, 0, null)); + List frs=new ArrayList<>(videoFrames.values()); + Collections.sort(frs,new Comparator() { + + @Override + public int compare(VideoFrameTag o1, VideoFrameTag o2) { + return o1.frameNum-o2.frameNum; + } + }); + boolean first=true; + int ratio=0; + for(VideoFrameTag f:frs){ + if(!first){ + ratio++; + sos2.writeTag(new PlaceObject2Tag(null, false, false, false, true, false, false, false, true, 1, 0 , null, null, ratio, null, 0, null)); + } + sos2.writeTag(f); + sos2.writeTag(new ShowFrameTag(null)); + first = false; + } } else { sos2.writeTag(new PlaceObject2Tag(null, false, false, false, true, false, true, true, false, 1, chtId, mat, null, 0, null, 0, null)); sos2.writeTag(new ShowFrameTag(null)); } + + }//not showframe sos2.writeTag(new EndTag(null)); @@ -3132,7 +3224,8 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel sos.writeUI32(sos.getPos() + data.length + 4); sos.write(data); - } + fos.flush(); + } showCard(CARDFLASHPANEL); if (flashPanel != null) { if (flashPanel instanceof FlashPlayerPanel) { diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java index c8f07b9b9..f6f6ef791 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java @@ -37,6 +37,7 @@ public class FlashPlayerPanel extends Panel { private static List processes = new ArrayList<>(); private static List pipes = new ArrayList<>(); private JFrame frame; + private boolean stopped=false; private synchronized void resize() { if (pipe != null) { @@ -109,11 +110,26 @@ public class FlashPlayerPanel extends Panel { executed = true; } + public synchronized void stopSWF(){ + displaySWF("-"); + stopped = true; + } + + public synchronized boolean isStopped() { + return stopped; + } + + public synchronized void displaySWF(String flash) { this.flash = flash; repaint(); if (!executed) { execute(); + try { + Thread.sleep(1000); + } catch (InterruptedException ex) { + Logger.getLogger(FlashPlayerPanel.class.getName()).log(Level.SEVERE, null, ex); + } } if (pipe != null) { IntByReference ibr = new IntByReference(); @@ -122,6 +138,7 @@ public class FlashPlayerPanel extends Panel { Kernel32.INSTANCE.WriteFile(pipe, flash.getBytes(), flash.getBytes().length, ibr, null); } resize(); + stopped = false; } public static void unload() { diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/DefineVideoStreamTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/DefineVideoStreamTag.java index 33015de07..1af4ba70d 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/DefineVideoStreamTag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/DefineVideoStreamTag.java @@ -19,18 +19,22 @@ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; +import com.jpexs.decompiler.flash.tags.base.BoundedTag; import com.jpexs.decompiler.flash.tags.base.CharacterTag; +import com.jpexs.decompiler.flash.types.RECT; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.util.HashMap; +import java.util.Stack; /** * * * @author JPEXS */ -public class DefineVideoStreamTag extends CharacterTag { +public class DefineVideoStreamTag extends CharacterTag implements BoundedTag { public int characterID; public int numFrames; @@ -94,4 +98,9 @@ public class DefineVideoStreamTag extends CharacterTag { videoFlagsSmoothing = sis.readUB(1) == 1; codecID = sis.readUI8(); } + + @Override + public RECT getRect(HashMap characters, Stack visited) { + return new RECT(0, 20*width, 0, 20*height); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/ExportAssetsTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/ExportAssetsTag.java index 81e6edc43..e356bb55f 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/ExportAssetsTag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/ExportAssetsTag.java @@ -40,6 +40,13 @@ public class ExportAssetsTag extends Tag { public List names; public static final int ID = 56; + + public ExportAssetsTag(){ + super(null, ID, "ExportAssets", new byte[]{}, 0); + tags = new ArrayList<>(); + names = new ArrayList<>(); + } + /** * Constructor * diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/FileAttributesTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/FileAttributesTag.java index b6f752ae0..a07945b90 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/FileAttributesTag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/FileAttributesTag.java @@ -37,6 +37,10 @@ public class FileAttributesTag extends Tag { private int reserved3; public static final int ID = 69; + public FileAttributesTag(){ + super(null, ID, "FileAttributes", new byte[]{}, 0); + } + public FileAttributesTag(SWF swf, byte data[], int version, long pos) throws IOException { super(swf, ID, "FileAttributes", data, pos); SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);