pixelplant - webdev meetup salzburg
DESCRIPTION
TRANSCRIPT
Upload to the Future
From Flash to HTML5
Wolfram Kriesing@wolframkriesingpixelplant / uxebu
Donnerstag, 21. November 13
Donnerstag, 21. November 13
uxebu / pixelplant
100%Technology
since 2008
Donnerstag, 21. November 13
Agenda
• Bonsai inside
• SWF (Flash) !le anatomy
• ActionScript2+3
• ByteCode - VM or ?
• ActionScript2 => JavaScript
• ActionScript API
• Editor with Live Preview
Donnerstag, 21. November 13
Bonsai - Inside
Donnerstag, 21. November 13
bonsaijs.orgDonnerstag, 21. November 13
... Bonsai Demos ...
Donnerstag, 21. November 13
Shapes
Timeline
Video
Matrix
Color
TextBitmap
Grouping
SpriteMovie
darker
darker
lighter
randomize rgba
hsla
hue
saturation
Filter blur
dropShadow sepia
greyscale
invert
saturate
Audio
Gradient
Eventsemit
on
keydown
keyupmousedown
touch
mouseup
drag Animationmatrix
rotation scaleclip
mask
xyopacitykeyframes
frames
units
play
stop length
radial
linear
Manipulation
Content creation
Organization
Donnerstag, 21. November 13
Single Threaded, almost
• Heavy Lifting• Decoupled from UI
Thread• WebWorker• Runs in nodejs
Bonsai ScriptRendererDonnerstag, 21. November 13
UI Thread
Client Setup
Bonsai ScriptIFrame
Renderer
Donnerstag, 21. November 13
Donnerstag, 21. November 13
UI Thread
Client Setup
Bonsai ScriptIFrame
Renderer
UI Thread
Bonsai ScriptWebWorker
Renderer
Donnerstag, 21. November 13
Client/Server Setup
iPhone
Bonsai Scriptnode.js
Renderer
DesktopRenderer
iPadRenderer
...
Donnerstag, 21. November 13
Renderers
• SVG• Canvas• HTML+CSS• WebGL• Mixed
Renderer RunnerDonnerstag, 21. November 13
SWF File Anatomy
Donnerstag, 21. November 13
Donnerstag, 21. November 13
Donnerstag, 21. November 13
Tools help!
Donnerstag, 21. November 13
Donnerstag, 21. November 13
> swfdump -D ikea-lady.swf [HEADER] File version: 6[HEADER] File size: 29640[HEADER] Frame rate: 30.000000[HEADER] Frame count: 1[HEADER] Movie width: 209.00[HEADER] Movie height: 242.00[009] 3 SETBACKGROUNDCOLOR (ff/ff/ff)
[00c] 2 DOACTION ( 0 bytes) action: Stop ( 0 bytes) action: End
[002] 30 DEFINESHAPE defines id 0001 | fillstyles(01) linestyles(00) | 1 ) SOLID ffffffff | | fill: 00/01 line:00 - moveTo -23.25 -23.25 | fill: 00/01 line:00 - lineTo 23.25 -23.25 | fill: 00/01 line:00 - lineTo 23.25 23.25 | fill: 00/01 line:00 - lineTo -23.25 23.25 | fill: 00/01 line:00 - lineTo -23.25 -23.25 |[027] 4 DEFINESPRITE defines id 0002[01a] 6 PLACEOBJECT2 places id 0001 at depth 0001 | Matrix | 1.000 0.000 0.00 | 0.000 1.000 0.00 [001] 0 SHOWFRAME 1 (00:00:00,000)[000] 0 END[01a] 26 PLACEOBJECT2 places id 0002 at depth 0001 | Matrix | CXForm r g b a | 4.495 0.000 104.50 | mul 0.0 0.0 0.0 1.0 | 0.000 5.204 121.00 | add 174 225 255 0 [023] 8043 DEFINEBITSJPEG3 defines id 0003[002] 54 DEFINESHAPE defines id 0004 | fillstyles(02) linestyles(00) | 1 ) BITMAPc 65535 | 2 ) BITMAPc 3 | | fill: 00/02 line:00 - moveTo 137.50 71.00 | fill: 00/02 line:00 - lineTo -137.50 71.00 | fill: 00/02 line:00 - lineTo -137.50 -65.00 | fill: 00/02 line:00 - lineTo 137.50 -65.00 | fill: 00/02 line:00 - lineTo 137.50 71.00 |[027] 4 DEFINESPRITE defines id 0005[01a] 6 PLACEOBJECT2 places id 0004 at depth 0001 | Matrix | 1.000 0.000 0.00 | 0.000 1.000 0.00 [001] 0 SHOWFRAME 1 (00:00:00,000)[000] 0 END
Metadata
Script
Shapes
Donnerstag, 21. November 13
ActionScript2+3
Donnerstag, 21. November 13
> swfdump -a demos/pong-simple.swf [HEADER] File version: 11[HEADER] File is zlib compressed. Ratio: 79%[HEADER] File size: 6967[HEADER] Frame rate: 24.000000[HEADER] Frame count: 1[HEADER] Movie width: 550.00[HEADER] Movie height: 400.00[045] 4 FILEATTRIBUTES symbolclass[04d] 1298 METADATA[009] 3 SETBACKGROUNDCOLOR (ff/ff/ff)[00c] 1284 DOACTION ( 229 bytes) action: Constantpool(28 entries) String:"handle" String:"_x" String:"_xmouse" String:"ball" String:"hitTest" String:"bounceBall" String:"numPoints" String:"ballSpeed" String:"gameTime" String:"Date" String:"startTime" String:"gameEnd" String:"_width" String:"direction" String:"y" String:"x" String:"_y" String:"Stage" String:"height" String:"width" String:"runInterval" String:"clearInterval" String:"moveBallInterval" String:"interval" String:"maxBallSpeed" String:"run" String:"setInterval" String:"moveBall" ( 11 bytes) action: unknown[8e] (remainder of 11 bytes:"run\0\0\0\3j\0?\0") ( 2 bytes) action: Push Lookup:0 ("handle") ( 0 bytes) action: GetVariable ( 6 bytes) action: Push Lookup:1 ("_x") register:1 Lookup:2 ("_xmouse") ( 0 bytes) action: GetMember ( 0 bytes) action: SetMember ( 2 bytes) action: Push Lookup:0 ("handle") ( 0 bytes) action: GetVariable ( 7 bytes) action: Push int:1 Lookup:3 ("ball") ( 0 bytes) action: GetVariable ( 2 bytes) action: Push Lookup:4 ("hitTest") ( 0 bytes) action: CallMethod ( 0 bytes) action: Not ( 2 bytes) action: If 78 ( 2 bytes) action: Push Lookup:0 ("handle") ( 0 bytes) action: GetVariable ( 2 bytes) action: Push Lookup:3 ("ball") ( 0 bytes) action: GetVariable ( 7 bytes) action: Push int:2 Lookup:5 ("bounceBall") ( 0 bytes) action: CallFunction ( 0 bytes) action: Pop ( 4 bytes) action: Push Lookup:6 ("numPoints") Lookup:6 ("numPoints") ( 0 bytes) action: GetVariable ( 0 bytes) action: Increment ( 0 bytes) action: SetVariable ( 2 bytes) action: Push Lookup:6 ("numPoints") ( 0 bytes) action: GetVariable ( 5 bytes) action: Push int:5 ( 0 bytes) action: Modulo ( 9 bytes) action: Push double:0.000000 ( 0 bytes) action: Equals2 ( 0 bytes) action: Not ( 2 bytes) action: If 10 ( 4 bytes) action: Push Lookup:7 ("ballSpeed") Lookup:7 ("ballSpeed") ( 0 bytes) action: GetVariable ( 0 bytes) action: Increment ( 0 bytes) action: SetVariable ( 2 bytes) action: Push Lookup:8 ("gameTime") ( 0 bytes) action: GetVariable ( 11 bytes) action: Push double:0.000000 Lookup:9 ("Date") ( 0 bytes) action: NewObject ( 2 bytes) action: Push Lookup:10 ("startTime") ( 0 bytes) action: GetVariable ( 0 bytes) action: Subtract ( 5 bytes) action: Push int:1000 ( 0 bytes) action: Divide ( 0 bytes) action: Subtract ( 1 bytes) action: StoreRegister 2 ( 0 bytes) action: Pop ( 11 bytes) action: Push register:2 double:0.000000 ( 0 bytes) action: Greater ( 0 bytes) action: Not
ActionScript2
Donnerstag, 21. November 13
//Frame 0// Action tag #0
function run(){ handle._x = _root._xmouse; if (ball.hitTest(handle)) { bounceBall(ball, handle); ++numPoints; if (numPoints % 5 == 0) { ++ballSpeed; } } var __reg2 = gameTime - (new Date() - startTime) / 1000; if (__reg2 <= 0) { gameEnd(); }}function bounceBall(ball, handle){ var __reg1 = handle._width / 2 + handle._x; var __reg2 = ball._x; direction.y = direction.y * -1; if (__reg2 == __reg1) { direction.x = 0; return; }
> swfdump -a demos/pong-simple.swf [HEADER] File version: 11[HEADER] File is zlib compressed. Ratio: 79%[HEADER] File size: 6967[HEADER] Frame rate: 24.000000[HEADER] Frame count: 1[HEADER] Movie width: 550.00[HEADER] Movie height: 400.00[045] 4 FILEATTRIBUTES symbolclass[04d] 1298 METADATA[009] 3 SETBACKGROUNDCOLOR (ff/ff/ff)[00c] 1284 DOACTION ( 229 bytes) action: Constantpool(28 entries) String:"handle" String:"_x" String:"_xmouse" String:"ball" String:"hitTest" String:"bounceBall" String:"numPoints" String:"ballSpeed" String:"gameTime" String:"Date" String:"startTime" String:"gameEnd" String:"_width" String:"direction" String:"y" String:"x" String:"_y" String:"Stage" String:"height" String:"width" String:"runInterval" String:"clearInterval" String:"moveBallInterval" String:"interval" String:"maxBallSpeed" String:"run" String:"setInterval" String:"moveBall" ( 11 bytes) action: unknown[8e] (remainder of 11 bytes:"run\0\0\0\3j\0?\0") ( 2 bytes) action: Push Lookup:0 ("handle") ( 0 bytes) action: GetVariable ( 6 bytes) action: Push Lookup:1 ("_x") register:1 Lookup:2 ("_xmouse") ( 0 bytes) action: GetMember ( 0 bytes) action: SetMember ( 2 bytes) action: Push Lookup:0 ("handle") ( 0 bytes) action: GetVariable ( 7 bytes) action: Push int:1 Lookup:3 ("ball") ( 0 bytes) action: GetVariable ( 2 bytes) action: Push Lookup:4 ("hitTest") ( 0 bytes) action: CallMethod ( 0 bytes) action: Not ( 2 bytes) action: If 78 ( 2 bytes) action: Push Lookup:0 ("handle") ( 0 bytes) action: GetVariable ( 2 bytes) action: Push Lookup:3 ("ball") ( 0 bytes) action: GetVariable ( 7 bytes) action: Push int:2 Lookup:5 ("bounceBall") ( 0 bytes) action: CallFunction ( 0 bytes) action: Pop ( 4 bytes) action: Push Lookup:6 ("numPoints") Lookup:6 ("numPoints") ( 0 bytes) action: GetVariable ( 0 bytes) action: Increment ( 0 bytes) action: SetVariable ( 2 bytes) action: Push Lookup:6 ("numPoints") ( 0 bytes) action: GetVariable ( 5 bytes) action: Push int:5 ( 0 bytes) action: Modulo ( 9 bytes) action: Push double:0.000000 ( 0 bytes) action: Equals2 ( 0 bytes) action: Not ( 2 bytes) action: If 10 ( 4 bytes) action: Push Lookup:7 ("ballSpeed") Lookup:7 ("ballSpeed") ( 0 bytes) action: GetVariable ( 0 bytes) action: Increment ( 0 bytes) action: SetVariable ( 2 bytes) action: Push Lookup:8 ("gameTime") ( 0 bytes) action: GetVariable ( 11 bytes) action: Push double:0.000000 Lookup:9 ("Date") ( 0 bytes) action: NewObject ( 2 bytes) action: Push Lookup:10 ("startTime") ( 0 bytes) action: GetVariable ( 0 bytes) action: Subtract ( 5 bytes) action: Push int:1000 ( 0 bytes) action: Divide ( 0 bytes) action: Subtract ( 1 bytes) action: StoreRegister 2 ( 0 bytes) action: Pop ( 11 bytes) action: Push register:2 double:0.000000 ( 0 bytes) action: Greater ( 0 bytes) action: Not
ActionScript2
Donnerstag, 21. November 13
//ActionScript 3.0// package filter_fla// class MainTimelinepackage filter_fla { import flash.display.*; import flash.filters.*; public dynamic class MainTimeline extends flash.display.MovieClip { public function MainTimeline() { super(); addFrameScript(0, this.frame1); return; }
function frame1():* { this.x1y1q5.filters = [new flash.filters.BlurFilter(1, 1, 5)]; this.x3y3q5.filters = [new flash.filters.BlurFilter(3, 3, 5)]; this.x6y6q5.filters = [new flash.filters.BlurFilter(6, 6, 5)]; this.x9y9q5.filters = [new flash.filters.BlurFilter(9, 9, 5)]; this.x12y12q5.filters = [new flash.filters.BlurFilter(12, 12, 5)]; this.x15y15q5.filters = [new flash.filters.BlurFilter(15, 15, 5)]; return; }
public var x9y9q5:flash.display.MovieClip;
public var x1y1q5:flash.display.MovieClip;
public var x6y6q5:flash.display.MovieClip;
public var x3y3q5:flash.display.MovieClip;
public var x15y15q5:flash.display.MovieClip;
public var x12y12q5:flash.display.MovieClip; }}
slot 0: var <q>[public]::x9y9q5:<q>[public]flash.display::MovieClip slot 0: var <q>[public]::x1y1q5:<q>[public]flash.display::MovieClip slot 0: var <q>[public]::x6y6q5:<q>[public]flash.display::MovieClip slot 0: var <q>[public]::x3y3q5:<q>[public]flash.display::MovieClip slot 0: var <q>[public]::x15y15q5:<q>[public]flash.display::MovieClip slot 0: var <q>[public]::x12y12q5:<q>[public]flash.display::MovieClip method * <q>[packageinternal]filter_fla::frame1=()(0 params, 0 optional) [stack:5 locals:1 scope:10-11 flags:] slot:0 { 00000) + 0:0 getlocal_0 00001) + 1:0 pushscope 00002) + 0:1 getlocal_0 00003) + 1:1 getproperty <q>[public]::x1y1q5 00004) + 1:1 findpropstrict <q>[public]flash.filters::BlurFilter 00005) + 2:1 pushbyte 1 00006) + 3:1 dup 00007) + 4:1 pushbyte 5 00008) + 5:1 constructprop <q>[public]flash.filters::BlurFilter, 3 params 00009) + 2:1 newarray 1 params 00010) + 2:1 setproperty <q>[public]::filters 00011) + 0:1 getlocal_0 00012) + 1:1 getproperty <q>[public]::x3y3q5 00013) + 1:1 findpropstrict <q>[public]flash.filters::BlurFilter 00014) + 2:1 pushbyte 3 00015) + 3:1 dup 00016) + 4:1 pushbyte 5 00017) + 5:1 constructprop <q>[public]flash.filters::BlurFilter, 3 params 00018) + 2:1 newarray 1 params 00019) + 2:1 setproperty <q>[public]::filters 00020) + 0:1 getlocal_0 00021) + 1:1 getproperty <q>[public]::x6y6q5 00022) + 1:1 findpropstrict <q>[public]flash.filters::BlurFilter 00023) + 2:1 pushbyte 6 00024) + 3:1 dup 00025) + 4:1 pushbyte 5 00026) + 5:1 constructprop <q>[public]flash.filters::BlurFilter, 3 params 00027) + 2:1 newarray 1 params 00028) + 2:1 setproperty <q>[public]::filters 00029) + 0:1 getlocal_0 00030) + 1:1 getproperty <q>[public]::x9y9q5 00031) + 1:1 findpropstrict <q>[public]flash.filters::BlurFilter 00032) + 2:1 pushbyte 9 00033) + 3:1 dup 00034) + 4:1 pushbyte 5 00035) + 5:1 constructprop <q>[public]flash.filters::BlurFilter, 3 params 00036) + 2:1 newarray 1 params 00037) + 2:1 setproperty <q>[public]::filters 00038) + 0:1 getlocal_0 00039) + 1:1 getproperty <q>[public]::x12y12q5 00040) + 1:1 findpropstrict <q>[public]flash.filters::BlurFilter 00041) + 2:1 pushbyte 12
ActionScript3
Donnerstag, 21. November 13
ActionScript2 ActionScript3
• ~60 classes
• simplest namespacing
• case-insensitive!!!
• script blocks attached to frames
• dynamic scope lookups
• lots of legacy
• small, AVM1, ...
• ~450 classes
• packages, classes, interfaces
• case-sensitive
• event-driven
• scope like JS
• very (over?) engineered
• huge, AVM2, ...
Donnerstag, 21. November 13
ByteCode - VM or JavaScript
Donnerstag, 21. November 13
Donnerstag, 21. November 13
Donnerstag, 21. November 13
ActionScript2 => JavaScript
Donnerstag, 21. November 13
... !rst a bit of architecture
Donnerstag, 21. November 13
Server
Architecture Overview
Images, Fonts, Audio, etc.JavaScript
assets,index.html,
movie-min.js
AS2/3 Shim
CDN
AS2/3 Shim
Runtime
LokalBrowser
Donnerstag, 21. November 13
Server side
SWF Parser{ header: { inflate: true, lzma: false, version: 11, len: 6967, rect: { name: 'Rect', x1: 0, y1: 0, x2: 550, y2: 400 }, frameRate: 24, frameCount: 1 }, tags: [ { name: 'FileAttributes', reserved: 0, useDirectBlit: 0, useGPU: 0, hasMetadata: 1, actionScript3: 0, reserved2: 0, useNetwork: 0, reserved3: 0 }, { name: 'MetaData', metaData: '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/"> <xmp:CreatorTool>Adobe Flash Professional CS5.5 - build 349</xmp:CreatorTool> <xmp:CreateDate>2013-11-05T14:00:16+01:00</xmp:CreateDate> <xmp:MetadataDate>2013-11-06T09:17:43+01:00</xmp:MetadataDate> <xmp:ModifyDate>2013-11-06T09:17:43+01:00</xmp:ModifyDate> </rdf:Description> <rdf:Description rdf:about="" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#"> <xmpMM:InstanceID>xmp.iid:43993C31FF2068118083F2A7E5573F79</xmpMM:InstanceID> <xmpMM:DocumentID>xmp.did:43993C31FF2068118083F2A7E5573F79</xmpMM:DocumentID> <xmpMM:OriginalDocumentID>xmp.did:B2319BF64B2068118083F2A7E5573F79</xmpMM:OriginalDocumentID> <xmpMM:DerivedFrom rdf:parseType="Resource"> <stRef:instanceID>xmp.iid:0F9F87A6F32068118083F2A7E5573F79</stRef:instanceID> <stRef:documentID>xmp.did:CA93569BEA2068118083F2A7E5573F79</stRef:documentID> <stRef:originalDocumentID>xmp.did:B2319BF64B2068118083F2A7E5573F79</stRef:originalDocumentID> </xmpMM:DerivedFrom> </rdf:Description> <rdf:Description rdf:about="" xmlns:dc="http://purl.org/dc/elements/1.1/"> <dc:format>application/x-shockwave-flash</dc:format> </rdf:Description> </rdf:RDF> ' }, { name: 'SetBackgroundColor', color: 'ffffff' }, { name: 'DoAction', actionRecords: [ { name: 'ActionRecord', len: 229, actionCode: 136, options: { count: 28, constantPool: [ 'handle', '_x', '_xmouse', 'ball', 'hitTest', 'bounceBall', 'numPoints', 'ballSpeed', 'gameTime', 'Date', 'startTime', 'gameEnd', '_width', 'direction', 'y', 'x', '_y', 'Stage', 'height', 'width', 'runInterval', 'clearInterval', 'moveBallInterval', 'interval', 'maxBallSpeed', 'run', 'setInterval', 'moveBall' ] }, actionName: 'ActionConstantPool' },
Donnerstag, 21. November 13
Server side
SWF Parser
{ header: { inflate: true, lzma: false, version: 11, len: 6967, rect: { name: 'Rect', x1: 0, y1: 0, x2: 550, y2: 400 }, frameRate: 24, frameCount: 1 }, tags: [ { name: 'FileAttributes', reserved: 0, useDirectBlit: 0, useGPU: 0, hasMetadata: 1, actionScript3: 0, reserved2: 0, useNetwork: 0, reserved3: 0 }, { name: 'MetaData', metaData: '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/"> <xmp:CreatorTool>Adobe Flash Professional CS5.5 - build 349</xmp:CreatorTool> <xmp:CreateDate>2013-11-05T14:00:16+01:00</xmp:CreateDate> <xmp:MetadataDate>2013-11-06T09:17:43+01:00</xmp:MetadataDate> <xmp:ModifyDate>2013-11-06T09:17:43+01:00</xmp:ModifyDate> </rdf:Description> <rdf:Description rdf:about="" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#"> <xmpMM:InstanceID>xmp.iid:43993C31FF2068118083F2A7E5573F79</xmpMM:InstanceID> <xmpMM:DocumentID>xmp.did:43993C31FF2068118083F2A7E5573F79</xmpMM:DocumentID> <xmpMM:OriginalDocumentID>xmp.did:B2319BF64B2068118083F2A7E5573F79</xmpMM:OriginalDocumentID> <xmpMM:DerivedFrom rdf:parseType="Resource"> <stRef:instanceID>xmp.iid:0F9F87A6F32068118083F2A7E5573F79</stRef:instanceID> <stRef:documentID>xmp.did:CA93569BEA2068118083F2A7E5573F79</stRef:documentID> <stRef:originalDocumentID>xmp.did:B2319BF64B2068118083F2A7E5573F79</stRef:originalDocumentID> </xmpMM:DerivedFrom> </rdf:Description> <rdf:Description rdf:about="" xmlns:dc="http://purl.org/dc/elements/1.1/"> <dc:format>application/x-shockwave-flash</dc:format> </rdf:Description> </rdf:RDF> ' }, { name: 'SetBackgroundColor', color: 'ffffff' }, { name: 'DoAction', actionRecords: [ { name: 'ActionRecord', len: 229, actionCode: 136, options: { count: 28, constantPool: [ 'handle', '_x', '_xmouse', 'ball', 'hitTest', 'bounceBall', 'numPoints', 'ballSpeed', 'gameTime', 'Date', 'startTime', 'gameEnd', '_width', 'direction', 'y', 'x', '_y', 'Stage', 'height', 'width', 'runInterval', 'clearInterval', 'moveBallInterval', 'interval', 'maxBallSpeed', 'run', 'setInterval', 'moveBall' ] }, actionName: 'ActionConstantPool' },
JSON
CodeGenerator
.!"" pong-simple #"" assets $ !"" img(2l-5)_1.png !"" src #"" as2js $ !"" rootMovie.js !"" js
!"" src #"" as2js $ !"" rootMovie.js !"" js #"" abc.js #"" dict $ #"" bitmap.js $ #"" button.js $ #"" font.js $ #"" html.js $ #"" morph.js $ #"" shape.js $ #"" sprite.js $ !"" text.js #"" movie-amd.js !"" resources.js
Donnerstag, 21. November 13
Code Generator
{ name: 'DefineShape', id: 2, bounds: { name: 'Rect', x1: 0, y1: 0, x2: 219, y2: 109 }, shape: { name: 'ShapeWithStyle', fillStyles: [ { name: 'FillStyle', type: 67, desc: 'non-smoothed clipped bitmap', color: 0, gradientMatrix: 0, gradient: 0, bitmapId: 1, bitmapMatrix: { name: 'Matrix', hasScale: true, hasRotate: false, hasTranslate: false, sx: 1, sy: 1 } } ], lineStyles: [], shapeRecords: [ { name: 'moveTo', move: true, mx: 219, my: 109, fillStyle1: { name: 'FillStyle', type: 67, desc: 'non-smoothed clipped bitmap', color: 0, gradientMatrix: 0, gradient: 0, bitmapId: 1, bitmapMatrix: { name: 'Matrix', hasScale: true, hasRotate: false, hasTranslate: false, sx: 1, sy: 1 } }, _lineStyle: null,
SWF Parser JSON Bonsai Code
Donnerstag, 21. November 13
ActionScript2 => JavaScript
.!"" pong-simple #"" assets $ !"" img(2l-5)_1.png !"" src #"" as2js $ !"" rootMovie.js
!"" src #"" as2js $ !"" rootMovie.js
#"" abc.js #"" dict $ #"" bitmap.js $ #"" button.js $ #"" font.js $ #"" html.js $ #"" morph.js $ #"" shape.js $ #"" sprite.js $ !"" text.js #"" movie-amd.js
Assets
SWF dataScripting
Donnerstag, 21. November 13
Source => ByteCode => Source
function run() { handle._x = _root._xmouse; if (ball.hitTest(handle)) { bounceBall(ball, handle); ++numPoints; if (numPoints % 5 == 0) { ++ballSpeed; } } var t = gameTime - (new Date() - startTime) / 1000; if (t <= 0) { gameEnd(); }}
AS2 (Flash IDE)
Donnerstag, 21. November 13
Source => ByteCode => Source
function run() { handle._x = _root._xmouse; if (ball.hitTest(handle)) { bounceBall(ball, handle); ++numPoints; if (numPoints % 5 == 0) { ++ballSpeed; } } var t = gameTime - (new Date() - startTime) / 1000; if (t <= 0) { gameEnd(); }}
( 11 bytes) action: unknown[8e] (remainder of 11 bytes:"run\0\0\0\3j\0?\0") ( 2 bytes) action: Push Lookup:0 ("handle") ( 0 bytes) action: GetVariable ( 6 bytes) action: Push Lookup:1 ("_x") register:1 Lookup:2 ("_xmouse") ( 0 bytes) action: GetMember ( 0 bytes) action: SetMember ( 2 bytes) action: Push Lookup:0 ("handle") ( 0 bytes) action: GetVariable ( 7 bytes) action: Push int:1 Lookup:3 ("ball") ( 0 bytes) action: GetVariable ( 2 bytes) action: Push Lookup:4 ("hitTest") ( 0 bytes) action: CallMethod ( 0 bytes) action: Not ( 2 bytes) action: If 78 ( 2 bytes) action: Push Lookup:0 ("handle") ( 0 bytes) action: GetVariable ( 2 bytes) action: Push Lookup:3 ("ball") ( 0 bytes) action: GetVariable ( 7 bytes) action: Push int:2 Lookup:5 ("bounceBall") ( 0 bytes) action: CallFunction ( 0 bytes) action: Pop ( 4 bytes) action: Push Lookup:6 ("numPoints") Lookup:6 ("numPoints") ( 0 bytes) action: GetVariable ( 0 bytes) action: Increment ( 0 bytes) action: SetVariable ( 2 bytes) action: Push Lookup:6 ("numPoints") ( 0 bytes) action: GetVariable ( 5 bytes) action: Push int:5 ( 0 bytes) action: Modulo ( 9 bytes) action: Push double:0.000000 ( 0 bytes) action: Equals2 ( 0 bytes) action: Not ( 2 bytes) action: If 10 ( 4 bytes) action: Push Lookup:7 ("ballSpeed") Lookup:7 ("ballSpeed") ( 0 bytes) action: GetVariable ( 0 bytes) action: Increment ( 0 bytes) action: SetVariable ( 2 bytes) action: Push Lookup:8 ("gameTime") ( 0 bytes) action: GetVariable ( 11 bytes) action: Push double:0.000000 Lookup:9 ("Date") ( 0 bytes) action: NewObject ( 2 bytes) action: Push Lookup:10 ("startTime") ( 0 bytes) action: GetVariable ( 0 bytes) action: Subtract ( 5 bytes) action: Push int:1000 ( 0 bytes) action: Divide ( 0 bytes) action: Subtract ( 1 bytes) action: StoreRegister 2 ( 0 bytes) action: Pop ( 11 bytes) action: Push register:2 double:0.000000 ( 0 bytes) action: Greater ( 0 bytes) action: Not
AS2 (Flash IDE) Compiled ByteCode
Donnerstag, 21. November 13
Source => ByteCode => Source
function run() { handle._x = _root._xmouse; if (ball.hitTest(handle)) { bounceBall(ball, handle); ++numPoints; if (numPoints % 5 == 0) { ++ballSpeed; } } var t = gameTime - (new Date() - startTime) / 1000; if (t <= 0) { gameEnd(); }}
( 11 bytes) action: unknown[8e] (remainder of 11 bytes:"run\0\0\0\3j\0?\0") ( 2 bytes) action: Push Lookup:0 ("handle") ( 0 bytes) action: GetVariable ( 6 bytes) action: Push Lookup:1 ("_x") register:1 Lookup:2 ("_xmouse") ( 0 bytes) action: GetMember ( 0 bytes) action: SetMember ( 2 bytes) action: Push Lookup:0 ("handle") ( 0 bytes) action: GetVariable ( 7 bytes) action: Push int:1 Lookup:3 ("ball") ( 0 bytes) action: GetVariable ( 2 bytes) action: Push Lookup:4 ("hitTest") ( 0 bytes) action: CallMethod ( 0 bytes) action: Not ( 2 bytes) action: If 78 ( 2 bytes) action: Push Lookup:0 ("handle") ( 0 bytes) action: GetVariable ( 2 bytes) action: Push Lookup:3 ("ball") ( 0 bytes) action: GetVariable ( 7 bytes) action: Push int:2 Lookup:5 ("bounceBall") ( 0 bytes) action: CallFunction ( 0 bytes) action: Pop ( 4 bytes) action: Push Lookup:6 ("numPoints") Lookup:6 ("numPoints") ( 0 bytes) action: GetVariable ( 0 bytes) action: Increment ( 0 bytes) action: SetVariable ( 2 bytes) action: Push Lookup:6 ("numPoints") ( 0 bytes) action: GetVariable ( 5 bytes) action: Push int:5 ( 0 bytes) action: Modulo ( 9 bytes) action: Push double:0.000000 ( 0 bytes) action: Equals2 ( 0 bytes) action: Not ( 2 bytes) action: If 10 ( 4 bytes) action: Push Lookup:7 ("ballSpeed") Lookup:7 ("ballSpeed") ( 0 bytes) action: GetVariable ( 0 bytes) action: Increment ( 0 bytes) action: SetVariable ( 2 bytes) action: Push Lookup:8 ("gameTime") ( 0 bytes) action: GetVariable ( 11 bytes) action: Push double:0.000000 Lookup:9 ("Date") ( 0 bytes) action: NewObject ( 2 bytes) action: Push Lookup:10 ("startTime") ( 0 bytes) action: GetVariable ( 0 bytes) action: Subtract ( 5 bytes) action: Push int:1000 ( 0 bytes) action: Divide ( 0 bytes) action: Subtract ( 1 bytes) action: StoreRegister 2 ( 0 bytes) action: Pop ( 11 bytes) action: Push register:2 double:0.000000 ( 0 bytes) action: Greater ( 0 bytes) action: Not
AS2 (Flash IDE) Compiled ByteCode JavaScript
Donnerstag, 21. November 13
• „!x“ scoping
• „!x“ case-insensitivity
• „!x“ class construction
• etc.
• from ByteCode 1) to ActionScript2 like JavaScript 2) to real JavaScript
Donnerstag, 21. November 13
Esprima
ActionScript2 ByteCode => JavaScript
Donnerstag, 21. November 13
Esprima
ActionScript2 ByteCode => JavaScript
Donnerstag, 21. November 13
AS2
What we translate
Converted to JavaScriptDonnerstag, 21. November 13
•estraverse => for traversing the tree
•escodegen => generating the code
Donnerstag, 21. November 13
ActionScript API
Donnerstag, 21. November 13
AccessibilityargumentsArrayAsBroadcasterBevelFilter ("ash.!lters.BevelFilter)BitmapData ("ash.display.BitmapData)BitmapFilter ("ash.!lters.BitmapFilter)BlurFilter ("ash.!lters.BlurFilter)BooleanButtonCameracapabilities (System.capabilities)ColorColorMatrixFilter ("ash.!lters.ColorMatrixFilter)ColorTransform ("ash.geom.ColorTransform)ContextMenuContextMenuItemConvolutionFilter ("ash.!lters.ConvolutionFilter)CustomActionsDateDisplacementMapFilter ("ash.!lters.DisplacementMapFilter)DropShadowFilter ("ash.!lters.DropShadowFilter)ErrorExternalInterface ("ash.external.ExternalInterface)FileReference ("ash.net.FileReference)FileReferenceList ("ash.net.FileReferenceList)FunctionGlowFilter ("ash.!lters.GlowFilter)GradientBevelFilter ("ash.!lters.GradientBevelFilter)GradientGlowFilter ("ash.!lters.GradientGlowFilter)IME (System.IME)
ActionScript2
KeyLoadVarsLocalConnectionLocale (mx.lang.Locale)MathMatrix ("ash.geom.Matrix)MicrophoneMouseMovieClipMovieClipLoaderNetConnectionNetStreamNumberObjectPoint ("ash.geom.Point)PrintJobRectangle ("ash.geom.Rectangle)security (System.security)SelectionSharedObjectSoundStageStringStyleSheet (TextField.StyleSheet)SystemTextFieldTextFormatTextRenderer ("ash.text.TextRenderer)TextSnapshotTransform ("ash.geom.Transform)VideoXMLXMLNodeXMLSocketXMLUI
Donnerstag, 21. November 13
"ash.accessibility"ash.concurrent"ash.crypto"ash.data"ash.desktop"ash.display"ash.display3D"ash.display3D.textures"ash.errors"ash.events"ash.external"ash.!lesystem"ash.!lters"ash.geom"ash.globalization"ash.html"ash.media"ash.net"ash.net.dns"ash.net.drm"ash.noti!cations"ash.printing"ash.pro!ler"ash.sampler"ash.security"ash.sensors"ash.system"ash.text"ash.text.engine"ash.text.ime"ash.ui"ash.utils"ash.xml
ActionScriptVersionAVM1MovieBitmapBitmapDataBitmapDataChannelBitmapEncodingColorSpaceBlendModeCapsStyleColorCorrectionColorCorrectionSupportDisplayObjectDisplayObjectContainerFocusDirection FrameLabelGradientTypeGraphicsGraphicsBitmapFillGraphicsEndFillGraphicsGradientFillGraphicsPathGraphicsPathCommandGraphicsPathWindingGraphicsShaderFillGraphicsSolidFillGraphicsStrokeGraphicsTrianglePathInteractiveObjectInterpolationMethodJointStyleJPEGEncoderOptionsJPEGXREncoderOptionsLineScaleModeLoaderLoaderInfoMorphShapeMovieClip
NativeMenu NativeMenuItem NativeWindow NativeWindowDisplayState NativeWindowInitOptions NativeWindowRenderMode NativeWindowResize NativeWindowSystemChrome NativeWindowType PixelSnappingPNGEncoderOptionsSceneScreen ShaderShaderDataShaderInputShaderJobShaderParameterShaderParameterTypeShaderPrecisionShapeSimpleButtonSpreadMethodSpriteStageStage3DStageAlignStageAspectRatio StageDisplayStateStageOrientation StageQualityStageScaleModeSWFVersionTriangleCulling
ActionScript3
"ash.display
Donnerstag, 21. November 13
Editor with Live Preview
Donnerstag, 21. November 13
Thank you
@wolframkriesing
Wolfram Kriesinguxebu / pixelplant
Donnerstag, 21. November 13