diff --git a/trunk/lib/FlashPlayer.exe b/trunk/lib/FlashPlayer.exe index a69b5af5b..544b31bee 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 be04df401..426ce1d08 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 5ccb69124..e73b4033a 100644 --- a/trunk/libsrc/FlashPlayer/uMain.dfm +++ b/trunk/libsrc/FlashPlayer/uMain.dfm @@ -1,6 +1,6 @@ object frmMain: TfrmMain - Left = 401 - Top = 190 + Left = 359 + Top = 168 Width = 1381 Height = 811 Caption = 'FFDec Flash Player' diff --git a/trunk/libsrc/FlashPlayer/uMain.pas b/trunk/libsrc/FlashPlayer/uMain.pas index 17a1a71d1..955fb9f6c 100644 --- a/trunk/libsrc/FlashPlayer/uMain.pas +++ b/trunk/libsrc/FlashPlayer/uMain.pas @@ -116,6 +116,7 @@ cmd:integer; written:cardinal; val:cardinal; vals:String; +vars:String; const CMD_PLAY = 1; @@ -129,6 +130,8 @@ const CMD_REWIND = 9; CMD_GOTO = 10; CMD_CALL = 11; + CMD_GETVARIABLE = 12; + CMD_SETVARIABLE = 13; begin pipename:=PAnsiChar('\\.\\pipe\ffdec_flashplayer_'+ParamStr(1)); @@ -234,7 +237,35 @@ begin Move(vals[1], buffer, val); WriteFile(pipe,buffer,val,written,nil); end; + CMD_GETVARIABLE: + begin + ReadFile(pipe,buffer,2,numBytesRead,nil); + val := (buffer[0] shl 8) + buffer[1]; + ReadFile(pipe,buffer,val,numBytesRead,nil); + SetString(vals, PChar(Addr(buffer)), val); + vals:=flaPreview.GetVariable(vals); + val:=length(vals); + buffer[0]:=(val shr 8) mod 256; + buffer[1]:=val mod 256; + WriteFile(pipe,buffer,2,written,nil); + Move(vals[1], buffer, val); + WriteFile(pipe,buffer,val,written,nil); + end; + CMD_SETVARIABLE: + begin + ReadFile(pipe,buffer,2,numBytesRead,nil); + val := (buffer[0] shl 8) + buffer[1]; + ReadFile(pipe,buffer,val,numBytesRead,nil); + SetString(vars, PChar(Addr(buffer)), val); + ReadFile(pipe,buffer,2,numBytesRead,nil); + val := (buffer[0] shl 8) + buffer[1]; + ReadFile(pipe,buffer,val,numBytesRead,nil); + SetString(vals, PChar(Addr(buffer)), val); + + flaPreview.SetVariable(vars,vals); + + end; end; end until numBytesRead<=0; diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java index 0b25c4671..98664303a 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java @@ -2956,6 +2956,9 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel return; } + if (flashPanel != null) { + flashPanel.specialPlayback = false; + } swfPreviewPanel.stop(); stopFlashPlayer(); oldValue = tagObj; @@ -3274,19 +3277,50 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel ea.tags.add(ds.soundId); 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" + List actions; + DoActionTag doa; + + + doa = new DoActionTag(null, new byte[]{}, SWF.DEFAULT_VERSION, 0); + actions = ASMParser.parse(0, 0, false, + "ConstantPool \"_root\" \"my_sound\" \"Sound\" \"my_define_sound\" \"attachSound\"\n" + + "Push \"_root\"\n" + + "GetVariable\n" + "Push \"my_sound\" 0.0 \"Sound\"\n" + "NewObject\n" - + "DefineLocal\n" - + "Push \"my_define_sound\" 1 \"my_sound\"\n" + + "SetMember\n" + + "Push \"my_define_sound\" 1 \"_root\"\n" + "GetVariable\n" + + "Push \"my_sound\"\n" + + "GetMember\n" + "Push \"attachSound\"\n" + "CallMethod\n" + "Pop\n" - + "Push 9999 0 2 \"my_sound\"\n" + + "Stop", SWF.DEFAULT_VERSION, false); + doa.setActions(actions, SWF.DEFAULT_VERSION); + sos2.writeTag(doa); + sos2.writeTag(new ShowFrameTag(null)); + + + actions = ASMParser.parse(0, 0, false, + "ConstantPool \"_root\" \"my_sound\" \"Sound\" \"my_define_sound\" \"attachSound\" \"start\"\n" + + "StopSounds\n" + + "Push \"_root\"\n" + "GetVariable\n" + + "Push \"my_sound\" 0.0 \"Sound\"\n" + + "NewObject\n" + + "SetMember\n" + + "Push \"my_define_sound\" 1 \"_root\"\n" + + "GetVariable\n" + + "Push \"my_sound\"\n" + + "GetMember\n" + + "Push \"attachSound\"\n" + + "CallMethod\n" + + "Pop\n" + + "Push 9999 0.0 2 \"_root\"\n" + + "GetVariable\n" + + "Push \"my_sound\"\n" + + "GetMember\n" + "Push \"start\"\n" + "CallMethod\n" + "Pop\n" @@ -3294,7 +3328,64 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel doa.setActions(actions, SWF.DEFAULT_VERSION); sos2.writeTag(doa); sos2.writeTag(new ShowFrameTag(null)); + + actions = ASMParser.parse(0, 0, false, + "ConstantPool \"_root\" \"my_sound\" \"Sound\" \"my_define_sound\" \"attachSound\" \"onSoundComplete\" \"start\" \"execParam\"\n" + + "StopSounds\n" + + "Push \"_root\"\n" + + "GetVariable\n" + + "Push \"my_sound\" 0.0 \"Sound\"\n" + + "NewObject\n" + + "SetMember\n" + + "Push \"my_define_sound\" 1 \"_root\"\n" + + "GetVariable\n" + + "Push \"my_sound\"\n" + + "GetMember\n" + + "Push \"attachSound\"\n" + + "CallMethod\n" + + "Pop\n" + + "Push \"_root\"\n" + + "GetVariable\n" + + "Push \"my_sound\"\n" + + "GetMember\n" + + "Push \"onSoundComplete\"\n" + + "DefineFunction2 \"\" 0 2 false true true false true false true false false {\n" + + "Push 0.0 register1 \"my_sound\"\n" + + "GetMember\n" + + "Push \"start\"\n" + + "CallMethod\n" + + "Pop\n" + + "}\n" + + "SetMember\n" + + "Push \"_root\"\n" + + "GetVariable\n" + + "Push \"execParam\"\n" + + "GetMember\n" + + "Push 1 \"_root\"\n" + + "GetVariable\n" + + "Push \"my_sound\"\n" + + "GetMember\n" + + "Push \"start\"\n" + + "CallMethod\n" + + "Pop\n" + + "Stop", SWF.DEFAULT_VERSION, false); + doa.setActions(actions, SWF.DEFAULT_VERSION); + sos2.writeTag(doa); sos2.writeTag(new ShowFrameTag(null)); + + + actions = ASMParser.parse(0, 0, false, + "StopSounds\n" + + "Stop", SWF.DEFAULT_VERSION, false); + doa.setActions(actions, SWF.DEFAULT_VERSION); + sos2.writeTag(doa); + sos2.writeTag(new ShowFrameTag(null)); + + + sos2.writeTag(new ShowFrameTag(null)); + if (flashPanel != null) { + flashPanel.specialPlayback = true; + } } 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)); 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 7d3673d58..a1aae678a 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java @@ -50,8 +50,49 @@ public class FlashPlayerPanel extends Panel implements FlashDisplay { private static final int CMD_REWIND = 9; private static final int CMD_GOTO = 10; private static final int CMD_CALL = 11; + private static final int CMD_GETVARIABLE = 12; + private static final int CMD_SETVARIABLE = 13; private int frameRate; - public boolean functionPlayback = false; + public boolean specialPlayback = false; + private boolean specialPlaying = false; + + public synchronized String getVariable(String name) { + if (pipe != null) { + IntByReference ibr = new IntByReference(); + Kernel32.INSTANCE.WriteFile(pipe, new byte[]{CMD_GETVARIABLE}, 1, ibr, null); + int nameLen = name.getBytes().length; + Kernel32.INSTANCE.WriteFile(pipe, new byte[]{(byte) ((nameLen >> 8) & 0xff), (byte) (nameLen & 0xff)}, 2, ibr, null); + Kernel32.INSTANCE.WriteFile(pipe, name.getBytes(), nameLen, ibr, null); + byte res[] = new byte[2]; + if (Kernel32.INSTANCE.ReadFile(pipe, res, 2, ibr, null)) { + int retLen = ((res[0] & 0xff) << 8) + (res[1] & 0xff); + res = new byte[retLen]; + if (Kernel32.INSTANCE.ReadFile(pipe, res, retLen, ibr, null)) { + String ret = new String(res, 0, retLen); + return ret; + } else { + return null; + } + } else { + return null; + } + } + return null; + } + + public synchronized void setVariable(String name, String value) { + if (pipe != null) { + IntByReference ibr = new IntByReference(); + Kernel32.INSTANCE.WriteFile(pipe, new byte[]{CMD_SETVARIABLE}, 1, ibr, null); + int nameLen = name.getBytes().length; + Kernel32.INSTANCE.WriteFile(pipe, new byte[]{(byte) ((nameLen >> 8) & 0xff), (byte) (nameLen & 0xff)}, 2, ibr, null); + Kernel32.INSTANCE.WriteFile(pipe, name.getBytes(), nameLen, ibr, null); + + int valLen = value.getBytes().length; + Kernel32.INSTANCE.WriteFile(pipe, new byte[]{(byte) ((valLen >> 8) & 0xff), (byte) (valLen & 0xff)}, 2, ibr, null); + Kernel32.INSTANCE.WriteFile(pipe, value.getBytes(), valLen, ibr, null); + } + } public synchronized String call(String callString) { if (pipe != null) { @@ -88,8 +129,7 @@ public class FlashPlayerPanel extends Panel implements FlashDisplay { } } - @Override - public synchronized int getCurrentFrame() { + private int __getCurrentFrame() { byte[] res = new byte[2]; IntByReference ibr = new IntByReference(); Kernel32.INSTANCE.WriteFile(pipe, new byte[]{CMD_CURRENT_FRAME}, 1, ibr, null); @@ -100,8 +140,28 @@ public class FlashPlayerPanel extends Panel implements FlashDisplay { } } + @Override + public synchronized int getCurrentFrame() { + if (specialPlayback) { + if (!specialPlaying) { + return specialPosition; + } + String posStr = getVariable("_root.my_sound.position"); + if (posStr != null) { + return Integer.parseInt(posStr); + } + } + return __getCurrentFrame(); + } + @Override public synchronized int getTotalFrames() { + if (specialPlayback) { + String durStr = getVariable("_root.my_sound.duration"); + if (durStr != null) { + return Integer.parseInt(durStr); + } + } byte[] res = new byte[2]; IntByReference ibr = new IntByReference(); Kernel32.INSTANCE.WriteFile(pipe, new byte[]{CMD_TOTAL_FRAMES}, 1, ibr, null); @@ -212,6 +272,11 @@ public class FlashPlayerPanel extends Panel implements FlashDisplay { } resize(); stopped = false; + specialPlaying = false; + specialPosition = 0; + if (specialPlayback) { + play(); + } } public static void unload() { @@ -230,27 +295,64 @@ public class FlashPlayerPanel extends Panel implements FlashDisplay { } super.paint(g); } + private int specialPosition = 0; - @Override - public void pause() { + private synchronized void __pause() { IntByReference ibr = new IntByReference(); Kernel32.INSTANCE.WriteFile(pipe, new byte[]{CMD_PAUSE}, 1, ibr, null); } + @Override + public void pause() { + if (specialPlayback) { + specialPosition = getCurrentFrame(); + __gotoFrame(3); + __play(); + specialPlaying = false; + return; + } + __pause(); + } + @Override public void rewind() { + if (specialPlayback) { + boolean plays = specialPlaying; + pause(); + specialPosition = 0; + if (plays) { + play(); + } + + return; + } IntByReference ibr = new IntByReference(); Kernel32.INSTANCE.WriteFile(pipe, new byte[]{CMD_REWIND}, 1, ibr, null); } - @Override - public void play() { + private synchronized void __play() { IntByReference ibr = new IntByReference(); Kernel32.INSTANCE.WriteFile(pipe, new byte[]{CMD_RESUME}, 1, ibr, null); } + @Override + public void play() { + if (specialPlayback) { + double p = (((double) specialPosition) / 1000.0); + setVariable("_root.execParam", "" + p); + __gotoFrame(1); + __play(); + specialPlaying = true; + return; + } + __play(); + } + @Override public boolean isPlaying() { + if (specialPlayback) { + return specialPlaying; + } IntByReference ibr = new IntByReference(); Kernel32.INSTANCE.WriteFile(pipe, new byte[]{CMD_PLAYING}, 1, ibr, null); byte[] res = new byte[1]; @@ -261,15 +363,32 @@ public class FlashPlayerPanel extends Panel implements FlashDisplay { } } - @Override - public void gotoFrame(int frame) { + private synchronized void __gotoFrame(int frame) { IntByReference ibr = new IntByReference(); Kernel32.INSTANCE.WriteFile(pipe, new byte[]{CMD_GOTO}, 1, ibr, null); Kernel32.INSTANCE.WriteFile(pipe, new byte[]{(byte) ((frame >> 8) & 0xff), (byte) (frame & 0xff)}, 2, ibr, null); } + @Override + public void gotoFrame(int frame) { + if (specialPlayback) { + if (specialPlaying) { + pause(); + specialPosition = frame; + play(); + } else { + specialPosition = frame; + } + return; + } + __gotoFrame(frame); + } + @Override public int getFrameRate() { + if (specialPlayback) { + return 1000; + } return frameRate; }