Skip to content

Latest commit

 

History

History
102 lines (73 loc) · 7.61 KB

translator.md

File metadata and controls

102 lines (73 loc) · 7.61 KB

SWF translator

This document describes the SWF translator component.

Architecture Overview

Architecture Overview

Input

A SWF file has two main components, the movie timeline and ActionScript code. To translate a SWF file, we handle the two components individually for simplicity.

For the movie timeline, the SWF file should be feed directly to the translator. The translator would decode the SWF file into tags, and translate them into asset files and character data JSON files.

For the ActionScript code, the SWF file should be decompiled to ActionScript 3 code first (e.g. using FFDec), then feed the decompiled source code into the translator. The translator would then translate the AS3 code into TypeScript source files.

Note: only AS3 is supported.

SWF character handling

SWF file consists of properties and tags. For SWF properties (e.g. stage size, frame rate, background color), they are collected and emitted as a JSON directly. This process is trivial so details are omitted here.

The most significant tags are character tags. The character tags can be divided roughly into 4 categories:

  • Assets: images, sounds, etc.
  • Shapes: fonts, shapes/morph shapes, etc.
  • Sprites: buttons, Sprites, etc.
  • Timeline: place/remove objects, frame & scene labels, etc.

Translation of other tags (e.g. class linkage, property tags) are trivial so details are omitted here.

Assets decoding

Assets like images & sounds are decoded into common formats, such as PNG, MP3, etc. The decoded assets are emitted as individual files directly. A JS index file is also emitted for easy consumption by JS bundler (e.g. webpack).

Shape tessellation

Shapes and font glyphs are tessellated into triangles (using libtess) ahead-of-time for simplicity of runtime. Texture description (e.g. fill color, gradient) are associated with the triangles. The result triangle definitions are emitted as a character definition JSON file.

Sprite translation

Sprites, buttons and text fields are mainly consist of attribute values and timeline actions. They are translated from SWF format into a custom JSON format for easy consumption by runtime.

AS3 code handling

For simplicity of translation (avoid need to handling ABC bytecode directly), AS3 source code is accepted instead. Since AS3 has semantics rather similar to JS, AS3 is translated into TypeScript (preserving type information from AS3), and ran directly by JS VM.

AST construction

A33 source code is parsed into AST using lezer (with a AS3 grammer based on official JS/TS grammar). Since lezer AST is optimized for performance, and is rather hard to consume directly, the entire AST is converted to our defined AST nodes before continuing on translation.

TypeScript translation

The translation from AS3 to TypeScript is rather simple, and mostly one-to-one mapped. A runtime is needed to emulate some AS3 features though, and some fixup is needed:

  • AS3 class variable can be accessed without this qualification, so a scope chain need to be constructed.
  • AS3 supports interfaces. A simple Symbol-based interface mechanism is devised (although not verified to work) to emulate it.
  • AS3 can have code like str instanceof String. These are translated to typeof checks instead.
  • AS3 allows running code in constructor before calling super(). To avoid dropping down to use ES5-style classes, the code before super() is just moved after it. Some manual fixup may be needed.
  • AS3 class method are bound to instances automatically, the runtime should perform this binding instead.

The translated source files are emitted, and can be used (or bundled) directly.

Output

After the processes, the SWF file should be translated into character definition JSON files, asset files, and TS source code. The character definition JSON files and asset files should be bundled into a data-pack JSON, and loaded into runtime along with transpiled TS code to run the SWF.