@swf2es/player-hosts 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/LICENSE.third-party +759 -0
- package/README.md +43 -2
- package/dist/indexeddb.d.ts +27 -0
- package/dist/indexeddb.d.ts.map +1 -0
- package/dist/indexeddb.js +170 -0
- package/dist/indexeddb.js.map +1 -0
- package/dist/node-worker.d.ts +2 -0
- package/dist/node-worker.d.ts.map +1 -0
- package/dist/node-worker.js +12 -0
- package/dist/node-worker.js.map +1 -0
- package/dist/node.d.ts +8 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +43 -0
- package/dist/node.js.map +1 -0
- package/dist/precompiled.d.ts +31 -0
- package/dist/precompiled.d.ts.map +1 -0
- package/dist/precompiled.js +125 -0
- package/dist/precompiled.js.map +1 -0
- package/dist/stage3d.d.ts +13 -0
- package/dist/stage3d.d.ts.map +1 -0
- package/dist/stage3d.js +61 -0
- package/dist/stage3d.js.map +1 -0
- package/dist/thread/codegen/codegen.js +308 -0
- package/dist/thread/codegen/index.js +405 -0
- package/dist/thread/format/abc-names.js +126 -0
- package/dist/thread/format/actions.js +222 -0
- package/dist/thread/format/air-descriptor.js +63 -0
- package/dist/thread/format/api-versions.js +22 -0
- package/dist/thread/format/bitmap.js +199 -0
- package/dist/thread/format/button.js +60 -0
- package/dist/thread/format/compression.js +200 -0
- package/dist/thread/format/display.js +305 -0
- package/dist/thread/format/filters.js +136 -0
- package/dist/thread/format/font.js +168 -0
- package/dist/thread/format/index.js +26 -0
- package/dist/thread/format/pbj.js +484 -0
- package/dist/thread/format/shape.js +411 -0
- package/dist/thread/format/sound.js +91 -0
- package/dist/thread/format/swf.js +163 -0
- package/dist/thread/format/tags.js +58 -0
- package/dist/thread/format/text.js +135 -0
- package/dist/thread/format/zip.js +91 -0
- package/dist/thread/native/audio/binary.js +3 -0
- package/dist/thread/native/audio/index.js +72 -0
- package/dist/thread/native/base64.js +9 -0
- package/dist/thread/native/compress/binary.js +3 -0
- package/dist/thread/native/compress/index.js +145 -0
- package/dist/thread/native/instance.js +49 -0
- package/dist/thread/native/mp3/binary.js +3 -0
- package/dist/thread/native/mp3/index.js +48 -0
- package/dist/thread/native/render/binary.js +3 -0
- package/dist/thread/native/render/bitmap-kernel.js +591 -0
- package/dist/thread/native/render/draw-kernel.js +204 -0
- package/dist/thread/native/render/dxt-encoder.js +94 -0
- package/dist/thread/native/render/index.js +10 -0
- package/dist/thread/native/render/lines.js +122 -0
- package/dist/thread/native/render/module.js +26 -0
- package/dist/thread/native/render/pixel-ops.js +235 -0
- package/dist/thread/native/render/tessellator.js +250 -0
- package/dist/thread/player/avm1/amf.js +507 -0
- package/dist/thread/player/avm1/avm1.js +1304 -0
- package/dist/thread/player/avm1/bindings.js +214 -0
- package/dist/thread/player/avm1/classes.js +75 -0
- package/dist/thread/player/avm1/clips.js +229 -0
- package/dist/thread/player/avm1/compile.js +140 -0
- package/dist/thread/player/avm1/external.js +79 -0
- package/dist/thread/player/avm1/focus.js +278 -0
- package/dist/thread/player/avm1/globals/BitmapData.js +542 -0
- package/dist/thread/player/avm1/globals/Button.js +31 -0
- package/dist/thread/player/avm1/globals/Color.js +115 -0
- package/dist/thread/player/avm1/globals/ExternalInterface.js +310 -0
- package/dist/thread/player/avm1/globals/FileReference.js +217 -0
- package/dist/thread/player/avm1/globals/Key.js +60 -0
- package/dist/thread/player/avm1/globals/LoadVars.js +208 -0
- package/dist/thread/player/avm1/globals/LocalConnection.js +92 -0
- package/dist/thread/player/avm1/globals/MovieClip.js +1070 -0
- package/dist/thread/player/avm1/globals/MovieClipLoader.js +90 -0
- package/dist/thread/player/avm1/globals/NetConnection.js +261 -0
- package/dist/thread/player/avm1/globals/PrintJob.js +37 -0
- package/dist/thread/player/avm1/globals/Selection.js +62 -0
- package/dist/thread/player/avm1/globals/SharedObject.js +245 -0
- package/dist/thread/player/avm1/globals/Sound.js +238 -0
- package/dist/thread/player/avm1/globals/Stage.js +12 -0
- package/dist/thread/player/avm1/globals/StyleSheet.js +205 -0
- package/dist/thread/player/avm1/globals/TextField.js +396 -0
- package/dist/thread/player/avm1/globals/TextFormat.js +194 -0
- package/dist/thread/player/avm1/globals/TextSnapshot.js +88 -0
- package/dist/thread/player/avm1/globals/XML.js +396 -0
- package/dist/thread/player/avm1/globals/XMLNode.js +413 -0
- package/dist/thread/player/avm1/globals/XMLSocket.js +205 -0
- package/dist/thread/player/avm1/globals/drawing.js +202 -0
- package/dist/thread/player/avm1/globals/filters.js +635 -0
- package/dist/thread/player/avm1/globals/geom.js +600 -0
- package/dist/thread/player/avm1/input.js +483 -0
- package/dist/thread/player/avm1/keyboard.js +113 -0
- package/dist/thread/player/avm1/loads.js +352 -0
- package/dist/thread/player/avm1/net.js +219 -0
- package/dist/thread/player/avm1/paths.js +104 -0
- package/dist/thread/player/avm1/pointer.js +512 -0
- package/dist/thread/player/avm1/queue.js +303 -0
- package/dist/thread/player/avm1/sound.js +106 -0
- package/dist/thread/player/avm1/swf.js +141 -0
- package/dist/thread/player/avm1/timers.js +113 -0
- package/dist/thread/player/bitmap/bitmap.js +627 -0
- package/dist/thread/player/bitmap/draw.js +68 -0
- package/dist/thread/player/bitmap/dxt.js +11 -0
- package/dist/thread/player/bitmap/filters.js +656 -0
- package/dist/thread/player/bitmap/images.js +240 -0
- package/dist/thread/player/bitmap/kernel.js +65 -0
- package/dist/thread/player/bitmap/ops.js +1239 -0
- package/dist/thread/player/bitmap/pixel-bender.js +911 -0
- package/dist/thread/player/bitmap/png.js +139 -0
- package/dist/thread/player/bitmap/turbulence.js +89 -0
- package/dist/thread/player/clock.js +182 -0
- package/dist/thread/player/display/bitmapobject.js +25 -0
- package/dist/thread/player/display/bounds.js +520 -0
- package/dist/thread/player/display/buttonobject.js +305 -0
- package/dist/thread/player/display/color.js +40 -0
- package/dist/thread/player/display/container.js +150 -0
- package/dist/thread/player/display/display.js +14 -0
- package/dist/thread/player/display/displayobject.js +664 -0
- package/dist/thread/player/display/drawing.js +613 -0
- package/dist/thread/player/display/filters.js +285 -0
- package/dist/thread/player/display/geometry.js +189 -0
- package/dist/thread/player/display/gradients.js +117 -0
- package/dist/thread/player/display/graphicsdata.js +592 -0
- package/dist/thread/player/display/instantiate.js +71 -0
- package/dist/thread/player/display/matrix3d.js +373 -0
- package/dist/thread/player/display/morph.js +226 -0
- package/dist/thread/player/display/movieclip.js +680 -0
- package/dist/thread/player/display/perspective.js +193 -0
- package/dist/thread/player/display/scale9.js +236 -0
- package/dist/thread/player/display/shapeobject.js +131 -0
- package/dist/thread/player/display/shapes.js +407 -0
- package/dist/thread/player/display/textobjects.js +222 -0
- package/dist/thread/player/display/timeline.js +471 -0
- package/dist/thread/player/display/value-lists.js +40 -0
- package/dist/thread/player/display/videoobject.js +6 -0
- package/dist/thread/player/display/walk.js +127 -0
- package/dist/thread/player/files.js +334 -0
- package/dist/thread/player/hosts.js +207 -0
- package/dist/thread/player/input/avm1.js +82 -0
- package/dist/thread/player/input/context-menu.js +63 -0
- package/dist/thread/player/input/keyboard.js +458 -0
- package/dist/thread/player/input/pointer.js +863 -0
- package/dist/thread/player/input/text-editor.js +319 -0
- package/dist/thread/player/input/touch.js +209 -0
- package/dist/thread/player/localconnection.js +90 -0
- package/dist/thread/player/media/audio.js +376 -0
- package/dist/thread/player/media/dynamic-sound.js +90 -0
- package/dist/thread/player/media/extract.js +135 -0
- package/dist/thread/player/media/mp3.js +152 -0
- package/dist/thread/player/media/sounds.js +507 -0
- package/dist/thread/player/media/streaming-audio.js +133 -0
- package/dist/thread/player/player.js +616 -0
- package/dist/thread/player/playerglobal/air/net/WebSocket.js +250 -0
- package/dist/thread/player/playerglobal/air-library.js +8 -0
- package/dist/thread/player/playerglobal/flash/accessibility/Accessibility.js +21 -0
- package/dist/thread/player/playerglobal/flash/crypto/generateRandomBytes.js +32 -0
- package/dist/thread/player/playerglobal/flash/data/EncryptedLocalStore.js +61 -0
- package/dist/thread/player/playerglobal/flash/desktop/Clipboard.js +173 -0
- package/dist/thread/player/playerglobal/flash/desktop/NativeApplication.js +179 -0
- package/dist/thread/player/playerglobal/flash/display/AVM1Movie.js +19 -0
- package/dist/thread/player/playerglobal/flash/display/Bitmap.js +58 -0
- package/dist/thread/player/playerglobal/flash/display/BitmapData.js +633 -0
- package/dist/thread/player/playerglobal/flash/display/DisplayObject.js +614 -0
- package/dist/thread/player/playerglobal/flash/display/DisplayObjectContainer.js +224 -0
- package/dist/thread/player/playerglobal/flash/display/Graphics.js +345 -0
- package/dist/thread/player/playerglobal/flash/display/InteractiveObject.js +87 -0
- package/dist/thread/player/playerglobal/flash/display/Loader.js +79 -0
- package/dist/thread/player/playerglobal/flash/display/LoaderInfo.js +128 -0
- package/dist/thread/player/playerglobal/flash/display/MovieClip.js +194 -0
- package/dist/thread/player/playerglobal/flash/display/NativeWindow.js +245 -0
- package/dist/thread/player/playerglobal/flash/display/Shader.js +26 -0
- package/dist/thread/player/playerglobal/flash/display/ShaderData.js +85 -0
- package/dist/thread/player/playerglobal/flash/display/ShaderInput.js +64 -0
- package/dist/thread/player/playerglobal/flash/display/ShaderJob.js +181 -0
- package/dist/thread/player/playerglobal/flash/display/ShaderParameter.js +23 -0
- package/dist/thread/player/playerglobal/flash/display/Shape.js +13 -0
- package/dist/thread/player/playerglobal/flash/display/SimpleButton.js +103 -0
- package/dist/thread/player/playerglobal/flash/display/Sprite.js +84 -0
- package/dist/thread/player/playerglobal/flash/display/Stage.js +231 -0
- package/dist/thread/player/playerglobal/flash/display/Stage3D.js +54 -0
- package/dist/thread/player/playerglobal/flash/display/shaders.js +228 -0
- package/dist/thread/player/playerglobal/flash/events/Event.js +58 -0
- package/dist/thread/player/playerglobal/flash/events/EventDispatcher.js +103 -0
- package/dist/thread/player/playerglobal/flash/events/GestureEvent.js +34 -0
- package/dist/thread/player/playerglobal/flash/events/HTTPStatusEvent.js +8 -0
- package/dist/thread/player/playerglobal/flash/events/KeyboardEvent.js +51 -0
- package/dist/thread/player/playerglobal/flash/events/MouseEvent.js +59 -0
- package/dist/thread/player/playerglobal/flash/events/PressAndTapGestureEvent.js +30 -0
- package/dist/thread/player/playerglobal/flash/events/TimerEvent.js +16 -0
- package/dist/thread/player/playerglobal/flash/events/TouchEvent.js +45 -0
- package/dist/thread/player/playerglobal/flash/external/ExternalInterface.js +73 -0
- package/dist/thread/player/playerglobal/flash/filesystem/File.js +340 -0
- package/dist/thread/player/playerglobal/flash/filesystem/FileStream.js +453 -0
- package/dist/thread/player/playerglobal/flash/filesystem/paths.js +156 -0
- package/dist/thread/player/playerglobal/flash/filesystem/writes.js +143 -0
- package/dist/thread/player/playerglobal/flash/filters/BevelFilter.js +4 -0
- package/dist/thread/player/playerglobal/flash/filters/BitmapFilter.js +205 -0
- package/dist/thread/player/playerglobal/flash/filters/BlurFilter.js +4 -0
- package/dist/thread/player/playerglobal/flash/filters/ColorMatrixFilter.js +11 -0
- package/dist/thread/player/playerglobal/flash/filters/ConvolutionFilter.js +26 -0
- package/dist/thread/player/playerglobal/flash/filters/DisplacementMapFilter.js +51 -0
- package/dist/thread/player/playerglobal/flash/filters/DropShadowFilter.js +4 -0
- package/dist/thread/player/playerglobal/flash/filters/GlowFilter.js +4 -0
- package/dist/thread/player/playerglobal/flash/filters/GradientBevelFilter.js +4 -0
- package/dist/thread/player/playerglobal/flash/filters/GradientGlowFilter.js +4 -0
- package/dist/thread/player/playerglobal/flash/filters/ShaderFilter.js +53 -0
- package/dist/thread/player/playerglobal/flash/geom/Matrix3D.js +361 -0
- package/dist/thread/player/playerglobal/flash/geom/PerspectiveProjection.js +122 -0
- package/dist/thread/player/playerglobal/flash/geom/Transform.js +245 -0
- package/dist/thread/player/playerglobal/flash/geom/Utils3D.js +85 -0
- package/dist/thread/player/playerglobal/flash/globalization/Collator.js +149 -0
- package/dist/thread/player/playerglobal/flash/globalization/CurrencyFormatter.js +272 -0
- package/dist/thread/player/playerglobal/flash/globalization/CurrencyParseResult.js +21 -0
- package/dist/thread/player/playerglobal/flash/globalization/DateTimeFormatter.js +463 -0
- package/dist/thread/player/playerglobal/flash/globalization/LocaleID.js +144 -0
- package/dist/thread/player/playerglobal/flash/globalization/NumberFormatter.js +444 -0
- package/dist/thread/player/playerglobal/flash/globalization/NumberParseResult.js +22 -0
- package/dist/thread/player/playerglobal/flash/globalization/StringTools.js +59 -0
- package/dist/thread/player/playerglobal/flash/globalization/locale.js +190 -0
- package/dist/thread/player/playerglobal/flash/media/Camera.js +89 -0
- package/dist/thread/player/playerglobal/flash/media/Microphone.js +126 -0
- package/dist/thread/player/playerglobal/flash/media/Sound.js +543 -0
- package/dist/thread/player/playerglobal/flash/media/SoundMixer.js +74 -0
- package/dist/thread/player/playerglobal/flash/media/SoundTransform.js +40 -0
- package/dist/thread/player/playerglobal/flash/media/Video.js +43 -0
- package/dist/thread/player/playerglobal/flash/net/FileFilter.js +27 -0
- package/dist/thread/player/playerglobal/flash/net/FileReference.js +197 -0
- package/dist/thread/player/playerglobal/flash/net/LocalConnection.js +167 -0
- package/dist/thread/player/playerglobal/flash/net/NetConnection.js +155 -0
- package/dist/thread/player/playerglobal/flash/net/SharedObject.js +299 -0
- package/dist/thread/player/playerglobal/flash/net/Socket.js +282 -0
- package/dist/thread/player/playerglobal/flash/net/URLRequest.js +93 -0
- package/dist/thread/player/playerglobal/flash/net/URLStream.js +146 -0
- package/dist/thread/player/playerglobal/flash/net/XMLSocket.js +14 -0
- package/dist/thread/player/playerglobal/flash/net/local-modern.js +142 -0
- package/dist/thread/player/playerglobal/flash/net/local-values.js +217 -0
- package/dist/thread/player/playerglobal/flash/net/navigateToURL.js +29 -0
- package/dist/thread/player/playerglobal/flash/profiler/Telemetry.js +25 -0
- package/dist/thread/player/playerglobal/flash/sensors/Accelerometer.js +12 -0
- package/dist/thread/player/playerglobal/flash/system/ApplicationDomain.js +69 -0
- package/dist/thread/player/playerglobal/flash/system/Capabilities.js +163 -0
- package/dist/thread/player/playerglobal/flash/system/FSCommandHost.js +17 -0
- package/dist/thread/player/playerglobal/flash/system/Security.js +46 -0
- package/dist/thread/player/playerglobal/flash/system/SecurityDomain.js +21 -0
- package/dist/thread/player/playerglobal/flash/system/System.js +73 -0
- package/dist/thread/player/playerglobal/flash/system/Worker.js +112 -0
- package/dist/thread/player/playerglobal/flash/text/Font.js +95 -0
- package/dist/thread/player/playerglobal/flash/text/StaticText.js +16 -0
- package/dist/thread/player/playerglobal/flash/text/StyleSheet.js +65 -0
- package/dist/thread/player/playerglobal/flash/text/TextField.js +707 -0
- package/dist/thread/player/playerglobal/flash/text/TextRenderer.js +77 -0
- package/dist/thread/player/playerglobal/flash/text/engine/FontDescription.js +141 -0
- package/dist/thread/player/playerglobal/flash/text/engine/TabStop.js +46 -0
- package/dist/thread/player/playerglobal/flash/trace/Trace.js +17 -0
- package/dist/thread/player/playerglobal/flash/ui/ContextMenu.js +17 -0
- package/dist/thread/player/playerglobal/flash/ui/GameInput.js +19 -0
- package/dist/thread/player/playerglobal/flash/ui/Keyboard.js +27 -0
- package/dist/thread/player/playerglobal/flash/ui/Mouse.js +127 -0
- package/dist/thread/player/playerglobal/flash/ui/Multitouch.js +46 -0
- package/dist/thread/player/playerglobal/flash/utils/ByteArray.js +155 -0
- package/dist/thread/player/playerglobal/flash/utils/Timer.js +25 -0
- package/dist/thread/player/playerglobal/flash/xml/XMLDocument.js +74 -0
- package/dist/thread/player/playerglobal/index.js +224 -0
- package/dist/thread/player/playerglobal/libraries.js +10 -0
- package/dist/thread/player/playerglobal/playerglobal-library.js +22 -0
- package/dist/thread/player/playerglobal/toplevel.js +122 -0
- package/dist/thread/player/scripting/clipboard.js +146 -0
- package/dist/thread/player/scripting/code.js +900 -0
- package/dist/thread/player/scripting/evaluate.js +144 -0
- package/dist/thread/player/scripting/events.js +172 -0
- package/dist/thread/player/scripting/handover.js +182 -0
- package/dist/thread/player/scripting/lazy.js +38 -0
- package/dist/thread/player/scripting/lifecycle.js +272 -0
- package/dist/thread/player/scripting/loads.js +860 -0
- package/dist/thread/player/scripting/sha256.js +95 -0
- package/dist/thread/player/scripting/symbols.js +348 -0
- package/dist/thread/player/scripting/timers.js +434 -0
- package/dist/thread/player/scripting/workers.js +923 -0
- package/dist/thread/player/scripting.js +1018 -0
- package/dist/thread/player/stage.js +4 -0
- package/dist/thread/player/text/csm.js +113 -0
- package/dist/thread/player/text/css.js +167 -0
- package/dist/thread/player/text/fonts.js +97 -0
- package/dist/thread/player/text/layout.js +393 -0
- package/dist/thread/player/text/static.js +109 -0
- package/dist/thread/player/text/text.js +431 -0
- package/dist/thread/player/workers/thread.js +159 -0
- package/dist/thread/player/workers/wire.js +198 -0
- package/dist/thread/player-hosts/web-worker.js +19 -0
- package/dist/thread/runtime/avm1/activation.js +89 -0
- package/dist/thread/runtime/avm1/case.js +249 -0
- package/dist/thread/runtime/avm1/clips.js +334 -0
- package/dist/thread/runtime/avm1/control.js +280 -0
- package/dist/thread/runtime/avm1/errors.js +50 -0
- package/dist/thread/runtime/avm1/functions.js +249 -0
- package/dist/thread/runtime/avm1/globals/array.js +549 -0
- package/dist/thread/runtime/avm1/globals/broadcaster.js +131 -0
- package/dist/thread/runtime/avm1/globals/date.js +436 -0
- package/dist/thread/runtime/avm1/globals/global.js +344 -0
- package/dist/thread/runtime/avm1/globals/math.js +139 -0
- package/dist/thread/runtime/avm1/globals/number.js +93 -0
- package/dist/thread/runtime/avm1/globals/string.js +201 -0
- package/dist/thread/runtime/avm1/globals/timers.js +129 -0
- package/dist/thread/runtime/avm1/host.js +5 -0
- package/dist/thread/runtime/avm1/index.js +14 -0
- package/dist/thread/runtime/avm1/inheritance.js +132 -0
- package/dist/thread/runtime/avm1/numbers.js +298 -0
- package/dist/thread/runtime/avm1/objects.js +896 -0
- package/dist/thread/runtime/avm1/operators.js +170 -0
- package/dist/thread/runtime/avm1/realm.js +529 -0
- package/dist/thread/runtime/avm1/runtime.js +882 -0
- package/dist/thread/runtime/avm1/scope.js +385 -0
- package/dist/thread/runtime/avm1/urls.js +180 -0
- package/dist/thread/runtime/avm1/values.js +97 -0
- package/dist/thread/runtime/avm2/amf-classes.js +66 -0
- package/dist/thread/runtime/avm2/amf.js +801 -0
- package/dist/thread/runtime/avm2/array-conversion.js +100 -0
- package/dist/thread/runtime/avm2/builtin-library.js +21 -0
- package/dist/thread/runtime/avm2/cache-fill.js +86 -0
- package/dist/thread/runtime/avm2/classes.js +211 -0
- package/dist/thread/runtime/avm2/definitions.js +69 -0
- package/dist/thread/runtime/avm2/descriptors.js +5 -0
- package/dist/thread/runtime/avm2/dictionary-keys.js +295 -0
- package/dist/thread/runtime/avm2/domain-memory.js +75 -0
- package/dist/thread/runtime/avm2/domain.js +280 -0
- package/dist/thread/runtime/avm2/dynamic-properties.js +182 -0
- package/dist/thread/runtime/avm2/enumeration.js +393 -0
- package/dist/thread/runtime/avm2/errors.js +45 -0
- package/dist/thread/runtime/avm2/float-library.js +66 -0
- package/dist/thread/runtime/avm2/float.js +26 -0
- package/dist/thread/runtime/avm2/hooks.js +19 -0
- package/dist/thread/runtime/avm2/index.js +38 -0
- package/dist/thread/runtime/avm2/messages.js +177 -0
- package/dist/thread/runtime/avm2/method-factories.js +95 -0
- package/dist/thread/runtime/avm2/modules.js +105 -0
- package/dist/thread/runtime/avm2/names.js +248 -0
- package/dist/thread/runtime/avm2/natives/aliases.js +47 -0
- package/dist/thread/runtime/avm2/natives/array.js +390 -0
- package/dist/thread/runtime/avm2/natives/bytearray.js +1227 -0
- package/dist/thread/runtime/avm2/natives/case.js +88 -0
- package/dist/thread/runtime/avm2/natives/concurrent.js +199 -0
- package/dist/thread/runtime/avm2/natives/date.js +581 -0
- package/dist/thread/runtime/avm2/natives/define.js +130 -0
- package/dist/thread/runtime/avm2/natives/describe.js +351 -0
- package/dist/thread/runtime/avm2/natives/dictionary.js +12 -0
- package/dist/thread/runtime/avm2/natives/float-vector.js +81 -0
- package/dist/thread/runtime/avm2/natives/float.js +96 -0
- package/dist/thread/runtime/avm2/natives/index.js +64 -0
- package/dist/thread/runtime/avm2/natives/json.js +514 -0
- package/dist/thread/runtime/avm2/natives/number.js +162 -0
- package/dist/thread/runtime/avm2/natives/object.js +237 -0
- package/dist/thread/runtime/avm2/natives/proxy.js +75 -0
- package/dist/thread/runtime/avm2/natives/regexp.js +485 -0
- package/dist/thread/runtime/avm2/natives/shell-workers.js +404 -0
- package/dist/thread/runtime/avm2/natives/shell.js +557 -0
- package/dist/thread/runtime/avm2/natives/sort.js +377 -0
- package/dist/thread/runtime/avm2/natives/string.js +132 -0
- package/dist/thread/runtime/avm2/natives/sync.js +821 -0
- package/dist/thread/runtime/avm2/natives/toplevel.js +139 -0
- package/dist/thread/runtime/avm2/natives/vector-elements.js +46 -0
- package/dist/thread/runtime/avm2/natives/vector.js +406 -0
- package/dist/thread/runtime/avm2/natives/xml/access.js +633 -0
- package/dist/thread/runtime/avm2/natives/xml/build.js +291 -0
- package/dist/thread/runtime/avm2/natives/xml/chars.js +112 -0
- package/dist/thread/runtime/avm2/natives/xml/escape.js +38 -0
- package/dist/thread/runtime/avm2/natives/xml/names.js +204 -0
- package/dist/thread/runtime/avm2/natives/xml/node.js +272 -0
- package/dist/thread/runtime/avm2/natives/xml/operators.js +69 -0
- package/dist/thread/runtime/avm2/natives/xml/parser.js +356 -0
- package/dist/thread/runtime/avm2/natives/xml/strings.js +191 -0
- package/dist/thread/runtime/avm2/natives/xml/values.js +122 -0
- package/dist/thread/runtime/avm2/natives/xml/xml.js +645 -0
- package/dist/thread/runtime/avm2/number-strings.js +110 -0
- package/dist/thread/runtime/avm2/numbers.js +558 -0
- package/dist/thread/runtime/avm2/options.js +16 -0
- package/dist/thread/runtime/avm2/player-messages.js +550 -0
- package/dist/thread/runtime/avm2/property-cache.js +135 -0
- package/dist/thread/runtime/avm2/runtime.js +2644 -0
- package/dist/thread/runtime/avm2/traits.js +509 -0
- package/dist/thread/runtime/index.js +7 -0
- package/dist/web-worker.d.ts +2 -0
- package/dist/web-worker.d.ts.map +1 -0
- package/dist/web-worker.js +20 -0
- package/dist/web-worker.js.map +1 -0
- package/dist/websocket.d.ts +4 -0
- package/dist/websocket.d.ts.map +1 -0
- package/dist/websocket.js +27 -0
- package/dist/websocket.js.map +1 -0
- package/dist/workers.d.ts +35 -0
- package/dist/workers.d.ts.map +1 -0
- package/dist/workers.js +171 -0
- package/dist/workers.js.map +1 -0
- package/package.json +62 -3
- package/src/indexeddb.ts +227 -0
- package/src/node-worker.ts +13 -0
- package/src/node.ts +49 -0
- package/src/precompiled.ts +166 -0
- package/src/stage3d.ts +76 -0
- package/src/web-worker.ts +24 -0
- package/src/websocket.ts +32 -0
- package/src/workers.ts +255 -0
|
@@ -0,0 +1,1070 @@
|
|
|
1
|
+
// MovieClip's AS2 face over the player's display objects (docs/avm1.md,
|
|
2
|
+
// "Hosting AVM1 objects"): a clip's, a button's or a text field's AVM1
|
|
3
|
+
// object finds its children by name, `_root`, `_parent` and `_levelN`, and
|
|
4
|
+
// the display properties `_x` to `_ymouse`, after its own properties; and
|
|
5
|
+
// MovieClip's methods, as Ruffle's (https://github.com/ruffle-rs/ruffle)
|
|
6
|
+
// core/src/avm1/object/stage_object.rs and globals/movie_clip.rs have them:
|
|
7
|
+
// MIT OR Apache-2.0, Copyright (c) 2018-2022 Ruffle LLC and Ruffle
|
|
8
|
+
// contributors. Where adl parts from Ruffle, adl decides (docs/avm1.md,
|
|
9
|
+
// "Clips and paths").
|
|
10
|
+
import { avm1 } from "../../../runtime/index.js";
|
|
11
|
+
import { bounds, hitsObject, hitsPoint, toStage } from "../../display/bounds.js";
|
|
12
|
+
import { ButtonObject, MovieClip, TextObject, TRANSFORM, } from "../../display/display.js";
|
|
13
|
+
import { apply, contains, invert, transformRect } from "../../display/geometry.js";
|
|
14
|
+
import { cached } from "../../display/shapeobject.js";
|
|
15
|
+
import { asciiLower, childByName, pathOf, slashPathOf } from "../paths.js";
|
|
16
|
+
import { blendModeOf, storeOf } from "./BitmapData.js";
|
|
17
|
+
import { drawingMethods } from "./drawing.js";
|
|
18
|
+
import { filtersProperty } from "./filters.js";
|
|
19
|
+
import { assignTransform, transformOf } from "./geom.js";
|
|
20
|
+
import { formVars } from "./LoadVars.js";
|
|
21
|
+
/** AVM1's depths are the timeline's less this, as Flash gives them to scripts. */
|
|
22
|
+
export const DEPTH_BIAS = 16384;
|
|
23
|
+
/** A number cast to an int as x86 casts one: cut toward zero, NaN and what does not fit -2^31. */
|
|
24
|
+
const castInt = (n) => n > -2147483649 && n < 2147483648 ? Math.trunc(n) : -2147483648;
|
|
25
|
+
/** A pixel value in whole twips, as Flash keeps positions. */
|
|
26
|
+
const twips = (px) => castInt(px * 20);
|
|
27
|
+
/** A value as a property set takes it: a number, or none for undefined, null or NaN, which leave the property be. */
|
|
28
|
+
function numberOf(value, version) {
|
|
29
|
+
if (value === undefined || value === null) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
const n = avm1.toNumber(value, version);
|
|
33
|
+
return Number.isNaN(n) ? null : n;
|
|
34
|
+
}
|
|
35
|
+
/** An object's width and height in its parent's space, in twips as Flash reports them. */
|
|
36
|
+
function size(d) {
|
|
37
|
+
const r = twipsBounds(d, twipsMatrix(d.placed));
|
|
38
|
+
return r === null ? [0, 0] : [(r.xMax - r.xMin) / 20, (r.yMax - r.yMin) / 20];
|
|
39
|
+
}
|
|
40
|
+
/** Move a display object, by a copy of its matrix, and have it drawn again. */
|
|
41
|
+
function moveTo(d, x, y) {
|
|
42
|
+
d.touch();
|
|
43
|
+
d.matrix = { ...d.matrix, tx: x ?? d.matrix.tx, ty: y ?? d.matrix.ty };
|
|
44
|
+
d.invalidate(TRANSFORM);
|
|
45
|
+
}
|
|
46
|
+
/** An alpha as Flash keeps it, an 8.8 multiplier: the percentage's 256ths cut toward zero, in 16 bits. */
|
|
47
|
+
function alphaOf(percent) {
|
|
48
|
+
const n = castInt(percent * 2.56);
|
|
49
|
+
return (n << 16) >> 16;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The display properties, in GetProperty's and SetProperty's order: `_x`
|
|
53
|
+
* is 0, `_ymouse` 21.
|
|
54
|
+
*/
|
|
55
|
+
const PROPERTIES = [
|
|
56
|
+
[
|
|
57
|
+
"_x",
|
|
58
|
+
{
|
|
59
|
+
get: (f) => f.target.matrix.tx,
|
|
60
|
+
set(f, value, version) {
|
|
61
|
+
const n = numberOf(value, version);
|
|
62
|
+
if (n !== null) {
|
|
63
|
+
moveTo(f.target, twips(n) / 20, null);
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
[
|
|
69
|
+
"_y",
|
|
70
|
+
{
|
|
71
|
+
get: (f) => f.target.matrix.ty,
|
|
72
|
+
set(f, value, version) {
|
|
73
|
+
const n = numberOf(value, version);
|
|
74
|
+
if (n !== null) {
|
|
75
|
+
moveTo(f.target, null, twips(n) / 20);
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
[
|
|
81
|
+
"_xscale",
|
|
82
|
+
{
|
|
83
|
+
get: (f) => f.xscale !== null && f.target.scaleX === clampScale(f.xscale / 100)
|
|
84
|
+
? f.xscale
|
|
85
|
+
: f.target.scaleX * 100,
|
|
86
|
+
set(f, value, version) {
|
|
87
|
+
const n = numberOf(value, version);
|
|
88
|
+
if (n !== null) {
|
|
89
|
+
f.target.touch();
|
|
90
|
+
setScaleX(f, n / 100, n);
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
[
|
|
96
|
+
"_yscale",
|
|
97
|
+
{
|
|
98
|
+
get: (f) => f.yscale !== null && f.target.scaleY === clampScale(f.yscale / 100)
|
|
99
|
+
? f.yscale
|
|
100
|
+
: f.target.scaleY * 100,
|
|
101
|
+
set(f, value, version) {
|
|
102
|
+
const n = numberOf(value, version);
|
|
103
|
+
if (n !== null) {
|
|
104
|
+
f.target.touch();
|
|
105
|
+
setScaleY(f, n / 100, n);
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
[
|
|
111
|
+
"_currentframe",
|
|
112
|
+
{ get: (f) => (f.target instanceof MovieClip ? f.target.currentFrame : undefined), set: null },
|
|
113
|
+
],
|
|
114
|
+
[
|
|
115
|
+
"_totalframes",
|
|
116
|
+
{ get: (f) => (f.target instanceof MovieClip ? f.target.totalFrames : undefined), set: null },
|
|
117
|
+
],
|
|
118
|
+
[
|
|
119
|
+
"_alpha",
|
|
120
|
+
{
|
|
121
|
+
get: (f) => (f.target.colorTransform?.aMul ?? 1) * 100,
|
|
122
|
+
set(f, value, version) {
|
|
123
|
+
const n = numberOf(value, version);
|
|
124
|
+
if (n !== null) {
|
|
125
|
+
const d = f.target;
|
|
126
|
+
d.touch();
|
|
127
|
+
const aMul = Number.isFinite(n) ? alphaOf(n) / 256 : 0;
|
|
128
|
+
d.colorTransform = { ...(d.colorTransform ?? IDENTITY_COLOR), aMul };
|
|
129
|
+
d.invalidate(TRANSFORM);
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
],
|
|
134
|
+
[
|
|
135
|
+
"_visible",
|
|
136
|
+
{
|
|
137
|
+
get: (f) => f.target.visible,
|
|
138
|
+
set(f, value, version) {
|
|
139
|
+
// A number, as in Flash 4: "false" is NaN, which leaves it be.
|
|
140
|
+
const n = numberOf(value, version);
|
|
141
|
+
if (n !== null) {
|
|
142
|
+
f.target.visible = n !== 0;
|
|
143
|
+
f.target.invalidate(TRANSFORM);
|
|
144
|
+
if (n === 0) {
|
|
145
|
+
f.movie.hidden(f.target);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
],
|
|
151
|
+
[
|
|
152
|
+
"_width",
|
|
153
|
+
{
|
|
154
|
+
get: (f) => size(f.target)[0],
|
|
155
|
+
set(f, value, version) {
|
|
156
|
+
const n = numberOf(value, version);
|
|
157
|
+
if (n !== null) {
|
|
158
|
+
setSize(f, n, true);
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
],
|
|
163
|
+
[
|
|
164
|
+
"_height",
|
|
165
|
+
{
|
|
166
|
+
get: (f) => size(f.target)[1],
|
|
167
|
+
set(f, value, version) {
|
|
168
|
+
const n = numberOf(value, version);
|
|
169
|
+
if (n !== null) {
|
|
170
|
+
setSize(f, n, false);
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
],
|
|
175
|
+
[
|
|
176
|
+
"_rotation",
|
|
177
|
+
{
|
|
178
|
+
get: (f) => f.target.rotation,
|
|
179
|
+
set(f, value, version) {
|
|
180
|
+
const n = numberOf(value, version);
|
|
181
|
+
if (n !== null) {
|
|
182
|
+
f.target.touch();
|
|
183
|
+
f.target.setRotation(n);
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
],
|
|
188
|
+
["_target", { get: (f) => slashPathOf(f.target, (d) => f.movie.levelOf(d)), set: null }],
|
|
189
|
+
[
|
|
190
|
+
"_framesloaded",
|
|
191
|
+
{
|
|
192
|
+
// -1 for a load's root in error, which has -1 bytes.
|
|
193
|
+
get: (f) => {
|
|
194
|
+
if (!(f.target instanceof MovieClip)) {
|
|
195
|
+
return undefined;
|
|
196
|
+
}
|
|
197
|
+
const swf = f.movie.swfOf(f.target);
|
|
198
|
+
return swf.root === f.target && swf.length < 0 ? -1 : f.target.totalFrames;
|
|
199
|
+
},
|
|
200
|
+
set: null,
|
|
201
|
+
},
|
|
202
|
+
],
|
|
203
|
+
[
|
|
204
|
+
"_name",
|
|
205
|
+
{
|
|
206
|
+
get: (f) => f.target.name,
|
|
207
|
+
set(f, value, version) {
|
|
208
|
+
f.target.name = avm1.stringOf(version >= 7 && typeof value === "number" && Number.isNaN(value) ? 0 : value, version);
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
],
|
|
212
|
+
[
|
|
213
|
+
"_droptarget",
|
|
214
|
+
{
|
|
215
|
+
// The slash path of what it was last dragged over; "" for nothing, in every version (adl;
|
|
216
|
+
// Ruffle: undefined up to SWF 5).
|
|
217
|
+
get: (f) => {
|
|
218
|
+
const over = f.movie.dropTargetOf(f.target);
|
|
219
|
+
return over === null ? "" : slashPathOf(over, (d) => f.movie.levelOf(d));
|
|
220
|
+
},
|
|
221
|
+
set: null,
|
|
222
|
+
},
|
|
223
|
+
],
|
|
224
|
+
["_url", { get: (f) => f.movie.swfOf(f.target).url, set: null }],
|
|
225
|
+
[
|
|
226
|
+
"_highquality",
|
|
227
|
+
{
|
|
228
|
+
get: (f) => (f.movie.quality === "BEST" ? 2 : f.movie.quality === "LOW" ? 0 : 1),
|
|
229
|
+
set(f, value, version) {
|
|
230
|
+
if (value === undefined || value === null) {
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
const n = avm1.toNumber(value, version);
|
|
234
|
+
if (!Number.isNaN(n)) {
|
|
235
|
+
f.movie.quality = n > 1.5 ? "BEST" : n === 0 ? "LOW" : "HIGH";
|
|
236
|
+
}
|
|
237
|
+
},
|
|
238
|
+
},
|
|
239
|
+
],
|
|
240
|
+
[
|
|
241
|
+
"_focusrect",
|
|
242
|
+
{
|
|
243
|
+
get(f, version) {
|
|
244
|
+
if (version <= 5) {
|
|
245
|
+
return f.movie.focusRect ? 1 : 0;
|
|
246
|
+
}
|
|
247
|
+
return f.target === f.movie.root ? f.movie.focusRect : (f.focusRect ?? null);
|
|
248
|
+
},
|
|
249
|
+
set(f, value, version) {
|
|
250
|
+
if (version <= 5 || f.target === f.movie.root) {
|
|
251
|
+
if (value === undefined || value === null) {
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
const n = value instanceof avm1.Avm1Object ? 0 : avm1.toNumber(value, version);
|
|
255
|
+
if (!Number.isNaN(n)) {
|
|
256
|
+
f.movie.focusRect = n !== 0;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
f.focusRect =
|
|
261
|
+
value === undefined || value === null ? null : avm1.toBoolean(value, version);
|
|
262
|
+
}
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
],
|
|
266
|
+
[
|
|
267
|
+
"_soundbuftime",
|
|
268
|
+
{
|
|
269
|
+
get: (f) => f.movie.soundBufferTime,
|
|
270
|
+
set(f, value, version) {
|
|
271
|
+
if (value === undefined || value === null) {
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
const n = avm1.toNumber(value, version);
|
|
275
|
+
if (!Number.isNaN(n)) {
|
|
276
|
+
f.movie.soundBufferTime = castInt(n);
|
|
277
|
+
}
|
|
278
|
+
},
|
|
279
|
+
},
|
|
280
|
+
],
|
|
281
|
+
[
|
|
282
|
+
"_quality",
|
|
283
|
+
{
|
|
284
|
+
get: (f) => f.movie.quality,
|
|
285
|
+
set(f, value, version) {
|
|
286
|
+
const quality = avm1.stringOf(value, version).toUpperCase();
|
|
287
|
+
if (QUALITIES.includes(quality)) {
|
|
288
|
+
f.movie.quality = quality;
|
|
289
|
+
}
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
],
|
|
293
|
+
["_xmouse", { get: (f) => mouse(f.target, f.movie)[0], set: null }],
|
|
294
|
+
["_ymouse", { get: (f) => mouse(f.target, f.movie)[1], set: null }],
|
|
295
|
+
];
|
|
296
|
+
const QUALITIES = ["LOW", "MEDIUM", "HIGH", "BEST"];
|
|
297
|
+
/** A clip's colour transform where it has none. */
|
|
298
|
+
export const IDENTITY_COLOR = {
|
|
299
|
+
rMul: 1,
|
|
300
|
+
gMul: 1,
|
|
301
|
+
bMul: 1,
|
|
302
|
+
aMul: 1,
|
|
303
|
+
rAdd: 0,
|
|
304
|
+
gAdd: 0,
|
|
305
|
+
bAdd: 0,
|
|
306
|
+
aAdd: 0,
|
|
307
|
+
};
|
|
308
|
+
/** The display properties by name in lower case, which they are found by in any case. */
|
|
309
|
+
const BY_NAME = new Map(PROPERTIES.map(([name, p]) => [name, p]));
|
|
310
|
+
/**
|
|
311
|
+
* The pointer in `d`'s space, as Flash gives it (Ruffle's
|
|
312
|
+
* local_mouse_position): through the matrix from `d`'s twips to the
|
|
313
|
+
* screen's pixels (`pixelRatio` of them a stage pixel), whose translation
|
|
314
|
+
* a matrix keeps whole, so a whole pixel, and back to whole twips, each
|
|
315
|
+
* rounded half to even; where that matrix cannot be inverted, as for a
|
|
316
|
+
* clip scaled to nothing, the pointer's pixels are taken as twips (the
|
|
317
|
+
* corpus's `mouse_pos`).
|
|
318
|
+
*/
|
|
319
|
+
function mouse(d, movie) {
|
|
320
|
+
const m = toStage(d, movie.root.parent);
|
|
321
|
+
const ratio = movie.pixelRatio;
|
|
322
|
+
const px = movie.mouseX * ratio;
|
|
323
|
+
const py = movie.mouseY * ratio;
|
|
324
|
+
const device = {
|
|
325
|
+
a: (m.a * ratio) / 20,
|
|
326
|
+
b: (m.b * ratio) / 20,
|
|
327
|
+
c: (m.c * ratio) / 20,
|
|
328
|
+
d: (m.d * ratio) / 20,
|
|
329
|
+
tx: roundEven(m.tx * ratio),
|
|
330
|
+
ty: roundEven(m.ty * ratio),
|
|
331
|
+
};
|
|
332
|
+
const back = invert(device);
|
|
333
|
+
if (back === null) {
|
|
334
|
+
return [roundEven(px) / 20, roundEven(py) / 20];
|
|
335
|
+
}
|
|
336
|
+
const x = back.a * px + back.c * py + roundEven(back.tx);
|
|
337
|
+
const y = back.b * px + back.d * py + roundEven(back.ty);
|
|
338
|
+
return [roundEven(x) / 20, roundEven(y) / 20];
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* The largest scale Flash's matrix holds, either way: a larger `_xscale`
|
|
342
|
+
* or `_yscale` is given back as set but draws at this (adl).
|
|
343
|
+
*/
|
|
344
|
+
const MAX_SCALE = 32768;
|
|
345
|
+
const clampScale = (s) => Math.max(-MAX_SCALE, Math.min(MAX_SCALE, s));
|
|
346
|
+
/** Preserve explicit percentages without a divide/multiply round trip; size setters supply factors. */
|
|
347
|
+
function setScaleX(f, s, percent = s * 100) {
|
|
348
|
+
f.target.setScaleX(clampScale(s));
|
|
349
|
+
f.xscale = percent;
|
|
350
|
+
}
|
|
351
|
+
function setScaleY(f, s, percent = s * 100) {
|
|
352
|
+
f.target.setScaleY(clampScale(s));
|
|
353
|
+
f.yscale = percent;
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* `_width` or `_height` set, as adl sets them: the bounds of the object's
|
|
357
|
+
* own content turned by its rotation, unscaled, in whole twips, are the
|
|
358
|
+
* base; the side set scales to the value over its base, the other to its
|
|
359
|
+
* size now over its base, both positive. A negative value changes nothing.
|
|
360
|
+
*/
|
|
361
|
+
function setSize(f, value, horizontal) {
|
|
362
|
+
if (value < 0) {
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
const d = f.target;
|
|
366
|
+
d.touch();
|
|
367
|
+
// A field's own size is the value, in whole twips, whatever its scale (the corpus's
|
|
368
|
+
// `movieclip_create_text_field` and `edittext_width_height`).
|
|
369
|
+
if (d instanceof TextObject) {
|
|
370
|
+
if (horizontal) {
|
|
371
|
+
d.width = twips(value) / 20;
|
|
372
|
+
}
|
|
373
|
+
else {
|
|
374
|
+
d.height = twips(value) / 20;
|
|
375
|
+
}
|
|
376
|
+
d.fit();
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
const r = twipsBounds(d, null);
|
|
380
|
+
const width = r === null ? 0 : r.xMax - r.xMin;
|
|
381
|
+
const height = r === null ? 0 : r.yMax - r.yMin;
|
|
382
|
+
const radians = ((d.rotation || 0) * Math.PI) / 180;
|
|
383
|
+
const cos = Math.abs(Math.cos(radians));
|
|
384
|
+
const sin = Math.abs(Math.sin(radians));
|
|
385
|
+
const baseWidth = Math.round(cos * width + sin * height) / 20;
|
|
386
|
+
const baseHeight = Math.round(sin * width + cos * height) / 20;
|
|
387
|
+
const [w, h] = size(d);
|
|
388
|
+
const sx = baseWidth !== 0 ? (horizontal ? value : w) / baseWidth : 0;
|
|
389
|
+
const sy = baseHeight !== 0 ? (horizontal ? h : value) / baseHeight : 0;
|
|
390
|
+
setScaleX(f, sx);
|
|
391
|
+
setScaleY(f, sy);
|
|
392
|
+
}
|
|
393
|
+
/** A number rounded to the nearest whole one, a half to the even one, as Rust's round_ties_even. */
|
|
394
|
+
function roundEven(n) {
|
|
395
|
+
const r = Math.round(n);
|
|
396
|
+
return Math.abs(n % 1) === 0.5 && r % 2 !== 0 ? r - 1 : r;
|
|
397
|
+
}
|
|
398
|
+
const f32 = Math.fround;
|
|
399
|
+
/** `m`, in pixels, as Flash keeps it. */
|
|
400
|
+
const twipsMatrix = (m) => ({
|
|
401
|
+
a: f32(m.a),
|
|
402
|
+
b: f32(m.b),
|
|
403
|
+
c: f32(m.c),
|
|
404
|
+
d: f32(m.d),
|
|
405
|
+
tx: Math.round(m.tx * 20),
|
|
406
|
+
ty: Math.round(m.ty * 20),
|
|
407
|
+
});
|
|
408
|
+
/** A single float rounded to an int, a half to the even one, out of range -2^31, NaN 0 (Ruffle's round_to_i32). */
|
|
409
|
+
function roundInt(n) {
|
|
410
|
+
if (!Number.isFinite(n)) {
|
|
411
|
+
return 0;
|
|
412
|
+
}
|
|
413
|
+
return n < 2147483648 ? roundEven(n) | 0 : -2147483648;
|
|
414
|
+
}
|
|
415
|
+
/** `m` then `n`, a child's matrix then its parent's, as Flash concatenates them. */
|
|
416
|
+
function concatTwips(n, m) {
|
|
417
|
+
return {
|
|
418
|
+
a: f32(f32(n.a * m.a) + f32(n.c * m.b)),
|
|
419
|
+
b: f32(f32(n.b * m.a) + f32(n.d * m.b)),
|
|
420
|
+
c: f32(f32(n.a * m.c) + f32(n.c * m.d)),
|
|
421
|
+
d: f32(f32(n.b * m.c) + f32(n.d * m.d)),
|
|
422
|
+
tx: roundInt(f32(f32(n.a * m.tx) + f32(n.c * m.ty))) + n.tx,
|
|
423
|
+
ty: roundInt(f32(f32(n.b * m.tx) + f32(n.d * m.ty))) + n.ty,
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
/** `d`'s matrix to the stage's space, as Flash's local_to_global_matrix. */
|
|
427
|
+
function toStageTwips(d, stage) {
|
|
428
|
+
let m = twipsMatrix(d.placed);
|
|
429
|
+
for (let p = d.parent; p !== null && p !== stage; p = p.parent) {
|
|
430
|
+
m = concatTwips(twipsMatrix(p.placed), m);
|
|
431
|
+
}
|
|
432
|
+
return m;
|
|
433
|
+
}
|
|
434
|
+
/** The inverse of `m`, null for a singular one (Ruffle's Matrix::inverse). */
|
|
435
|
+
function invertTwips(m) {
|
|
436
|
+
const det = f32(f32(m.a * m.d) - f32(m.b * m.c));
|
|
437
|
+
if (!(Math.abs(det) > 1.1920929e-7)) {
|
|
438
|
+
return null;
|
|
439
|
+
}
|
|
440
|
+
return {
|
|
441
|
+
a: f32(m.d / det),
|
|
442
|
+
b: f32(m.b / -det),
|
|
443
|
+
c: f32(m.c / -det),
|
|
444
|
+
d: f32(m.a / det),
|
|
445
|
+
tx: roundInt(f32(f32(f32(m.d * m.tx) - f32(m.c * m.ty)) / -det)),
|
|
446
|
+
ty: roundInt(f32(f32(f32(m.b * m.tx) - f32(m.a * m.ty)) / det)),
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
/** A point in twips through `m`, rounded to twips as Flash's matrices do. */
|
|
450
|
+
function transformTwips(m, x, y) {
|
|
451
|
+
return [
|
|
452
|
+
roundInt(f32(f32(m.a * x) + f32(m.c * y))) + m.tx,
|
|
453
|
+
roundInt(f32(f32(m.b * x) + f32(m.d * y))) + m.ty,
|
|
454
|
+
];
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* `d`'s bounds in twips, its own (`m` null) or through matrix `m`, each
|
|
458
|
+
* corner rounded to twips; null for an object with nothing in it.
|
|
459
|
+
*/
|
|
460
|
+
function twipsBounds(d, m, lines = true) {
|
|
461
|
+
const r = bounds(d, lines);
|
|
462
|
+
if (r === null) {
|
|
463
|
+
return null;
|
|
464
|
+
}
|
|
465
|
+
const xMin = Math.round(r.xMin * 20);
|
|
466
|
+
const yMin = Math.round(r.yMin * 20);
|
|
467
|
+
const xMax = Math.round(r.xMax * 20);
|
|
468
|
+
const yMax = Math.round(r.yMax * 20);
|
|
469
|
+
if (m === null) {
|
|
470
|
+
return { xMin, yMin, xMax, yMax };
|
|
471
|
+
}
|
|
472
|
+
const corners = [
|
|
473
|
+
transformTwips(m, xMin, yMin),
|
|
474
|
+
transformTwips(m, xMin, yMax),
|
|
475
|
+
transformTwips(m, xMax, yMin),
|
|
476
|
+
transformTwips(m, xMax, yMax),
|
|
477
|
+
];
|
|
478
|
+
const xs = corners.map((c) => c[0]);
|
|
479
|
+
const ys = corners.map((c) => c[1]);
|
|
480
|
+
return {
|
|
481
|
+
xMin: Math.min(...xs),
|
|
482
|
+
yMin: Math.min(...ys),
|
|
483
|
+
xMax: Math.max(...xs),
|
|
484
|
+
yMax: Math.max(...ys),
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
/** `name` among the path properties: `_root`, `_parent`, `_global` from SWF 6, `_levelN` and `_flashN`. */
|
|
488
|
+
function pathProperty(face, name, version) {
|
|
489
|
+
if (version < 5) {
|
|
490
|
+
return avm1.ABSENT;
|
|
491
|
+
}
|
|
492
|
+
const key = version > 6 ? name : asciiLower(name);
|
|
493
|
+
const movie = face.movie;
|
|
494
|
+
switch (key) {
|
|
495
|
+
case "_root":
|
|
496
|
+
return movie.faceOf(movie.rootOf(face.target)) ?? undefined;
|
|
497
|
+
case "_parent": {
|
|
498
|
+
const parent = movie.levelOf(face.target) !== null ? null : face.target.parent;
|
|
499
|
+
return parent === null ? undefined : (movie.faceOf(parent) ?? undefined);
|
|
500
|
+
}
|
|
501
|
+
case "_global":
|
|
502
|
+
return version >= 6 ? movie.realm.global : avm1.ABSENT;
|
|
503
|
+
}
|
|
504
|
+
if (!key.startsWith("_level") && !key.startsWith("_flash")) {
|
|
505
|
+
return avm1.ABSENT;
|
|
506
|
+
}
|
|
507
|
+
const level = movie.level(levelOf(key.slice(6)));
|
|
508
|
+
return level === null ? undefined : (movie.faceOf(level) ?? undefined);
|
|
509
|
+
}
|
|
510
|
+
/** `_levelN`'s N as Flash reads it: a sign and the digits up to anything else, wrapping. */
|
|
511
|
+
function levelOf(digits) {
|
|
512
|
+
const negative = digits.charCodeAt(0) === 0x2d;
|
|
513
|
+
let n = 0;
|
|
514
|
+
for (let i = negative ? 1 : 0; i < digits.length; i++) {
|
|
515
|
+
const d = digits.charCodeAt(i) - 0x30;
|
|
516
|
+
if (d < 0 || d > 9) {
|
|
517
|
+
break;
|
|
518
|
+
}
|
|
519
|
+
n = (Math.imul(n, 10) + d) | 0;
|
|
520
|
+
}
|
|
521
|
+
return negative ? -n | 0 : n;
|
|
522
|
+
}
|
|
523
|
+
/** `d`'s AVM1 side, null for one without. */
|
|
524
|
+
export function nativeOf(d) {
|
|
525
|
+
const native = d.avm1?.display;
|
|
526
|
+
return native instanceof ClipNative ? native : null;
|
|
527
|
+
}
|
|
528
|
+
/** A display object's side of its AVM1 object (runtime's DisplayNative). */
|
|
529
|
+
export class ClipNative {
|
|
530
|
+
movie;
|
|
531
|
+
target;
|
|
532
|
+
[Symbol.for("nodejs.util.inspect.custom")]() {
|
|
533
|
+
return `ClipNative(${this.target.name})`;
|
|
534
|
+
}
|
|
535
|
+
type;
|
|
536
|
+
/** `_xscale` and `_yscale` as last set, given back as set while the scale is still theirs. */
|
|
537
|
+
xscale = null;
|
|
538
|
+
yscale = null;
|
|
539
|
+
/** A clip's own `_focusrect` from SWF 6, null for the stage's. */
|
|
540
|
+
focusRect = null;
|
|
541
|
+
/** Where it was as it was removed, the path its references find a clip at from then on. */
|
|
542
|
+
removedAt = null;
|
|
543
|
+
/** A clip's clip actions, from its place or the clip it duplicates; null for none. */
|
|
544
|
+
handlers = null;
|
|
545
|
+
/** The events of clip actions Flash could not read, which stop the SWF as one comes. */
|
|
546
|
+
corrupt = 0;
|
|
547
|
+
/** Whether a clip's load came, on its first frame. */
|
|
548
|
+
loaded = false;
|
|
549
|
+
/** Whether its unload came. */
|
|
550
|
+
unloaded = false;
|
|
551
|
+
/** Whether it was removed with an unload handler, and stays until the next frame. */
|
|
552
|
+
pending = false;
|
|
553
|
+
/** The SWF whose blocks its clip actions are, its place's. */
|
|
554
|
+
swf = null;
|
|
555
|
+
/** `_lockroot`: whether it is `_root` for the code in it, as a SWF loaded into it has it. */
|
|
556
|
+
lockroot = false;
|
|
557
|
+
constructor(movie, target) {
|
|
558
|
+
this.movie = movie;
|
|
559
|
+
this.target = target;
|
|
560
|
+
this.type = target instanceof MovieClip ? "movieclip" : "object";
|
|
561
|
+
}
|
|
562
|
+
get(name, version) {
|
|
563
|
+
// Ruffle's stage_object.rs: the path properties, then children, then the display properties.
|
|
564
|
+
const magic = name.charCodeAt(0) === 0x5f;
|
|
565
|
+
if (magic) {
|
|
566
|
+
const p = pathProperty(this, name, version);
|
|
567
|
+
if (p !== avm1.ABSENT) {
|
|
568
|
+
return p;
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
const child = childByName(this.target, name, version > 6);
|
|
572
|
+
if (child !== null) {
|
|
573
|
+
// An object without an AVM1 object of its own, a shape's, is its parent's.
|
|
574
|
+
return this.movie.faceOf(child) ?? this.movie.faceOf(this.target) ?? undefined;
|
|
575
|
+
}
|
|
576
|
+
if (magic) {
|
|
577
|
+
const property = BY_NAME.get(asciiLower(name));
|
|
578
|
+
if (property !== undefined) {
|
|
579
|
+
return property.get(this, version);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
return avm1.ABSENT;
|
|
583
|
+
}
|
|
584
|
+
set(name, value, version) {
|
|
585
|
+
if (name.charCodeAt(0) !== 0x5f) {
|
|
586
|
+
return false;
|
|
587
|
+
}
|
|
588
|
+
const property = BY_NAME.get(asciiLower(name));
|
|
589
|
+
if (property === undefined) {
|
|
590
|
+
return false;
|
|
591
|
+
}
|
|
592
|
+
property.set?.(this, value, version);
|
|
593
|
+
return true;
|
|
594
|
+
}
|
|
595
|
+
changed(name, value, version) {
|
|
596
|
+
this.movie.propertyChanged(this.target, name, value, version);
|
|
597
|
+
}
|
|
598
|
+
keys(out) {
|
|
599
|
+
const d = this.target;
|
|
600
|
+
if (d instanceof MovieClip || d instanceof ButtonObject) {
|
|
601
|
+
const children = d.children;
|
|
602
|
+
for (let i = children.length - 1; i >= 0; i--) {
|
|
603
|
+
if (children[i].name !== "") {
|
|
604
|
+
out.push(children[i].name);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
path() {
|
|
610
|
+
return pathOf(this.target, (d) => this.movie.levelOf(d));
|
|
611
|
+
}
|
|
612
|
+
live() {
|
|
613
|
+
if (!this.movie.removed(this.target)) {
|
|
614
|
+
return this.movie.faceOf(this.target);
|
|
615
|
+
}
|
|
616
|
+
const path = this.removedAt;
|
|
617
|
+
const d = path === null ? null : this.movie.atPath(path);
|
|
618
|
+
return d === null || d === this.target ? null : this.movie.faceOf(d);
|
|
619
|
+
}
|
|
620
|
+
property(index, version) {
|
|
621
|
+
const p = PROPERTIES[index];
|
|
622
|
+
return p === undefined ? undefined : p[1].get(this, version);
|
|
623
|
+
}
|
|
624
|
+
setProperty(index, value, version) {
|
|
625
|
+
const p = PROPERTIES[index];
|
|
626
|
+
if (p === undefined) {
|
|
627
|
+
return false;
|
|
628
|
+
}
|
|
629
|
+
if (p[1].set === null) {
|
|
630
|
+
avm1Coerce(index, value, version);
|
|
631
|
+
}
|
|
632
|
+
else {
|
|
633
|
+
p[1].set(this, value, version);
|
|
634
|
+
}
|
|
635
|
+
return true;
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
/** A read-only property's value converted all the same, as SetProperty converts it. */
|
|
639
|
+
function avm1Coerce(index, value, version) {
|
|
640
|
+
if (index <= 12 && value !== undefined && value !== null) {
|
|
641
|
+
avm1.toNumber(value, version);
|
|
642
|
+
}
|
|
643
|
+
else if (index === 20 || index === 21) {
|
|
644
|
+
avm1.toNumber(value, version);
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
/** The display object of `self`, a clip's AVM1 object, where it is one's. */
|
|
648
|
+
function clipOf(self) {
|
|
649
|
+
if (!(self instanceof avm1.Avm1Object) || self.display === null) {
|
|
650
|
+
return null;
|
|
651
|
+
}
|
|
652
|
+
const live = self.display.live();
|
|
653
|
+
const d = live?.display?.target;
|
|
654
|
+
return d instanceof MovieClip ? d : null;
|
|
655
|
+
}
|
|
656
|
+
/** The bounds of `d` in `target`'s space, or the invalid ones of nothing, as an Object of xMin, xMax, yMin, yMax. */
|
|
657
|
+
function boundsObject(movie, d, target, lines, version) {
|
|
658
|
+
let r;
|
|
659
|
+
if (target === d) {
|
|
660
|
+
r = twipsBounds(d, null, lines);
|
|
661
|
+
}
|
|
662
|
+
else {
|
|
663
|
+
const stage = movie.root.parent;
|
|
664
|
+
const up = toStageTwips(d, stage);
|
|
665
|
+
const down = invertTwips(toStageTwips(target, stage));
|
|
666
|
+
r = twipsBounds(d, down ? concatTwips(down, up) : up, lines);
|
|
667
|
+
}
|
|
668
|
+
if (!movie.newInvalidBounds && (version >= 8 || movie.version >= 8)) {
|
|
669
|
+
movie.newInvalidBounds = true;
|
|
670
|
+
}
|
|
671
|
+
// Twips of nothing: one more in another clip's space once switched, as Flash.
|
|
672
|
+
const none = target !== d && movie.newInvalidBounds ? 0x8000000 : 0x7ffffff;
|
|
673
|
+
const o = movie.realm.newObject(version);
|
|
674
|
+
avm1.set(o, "xMin", (r?.xMin ?? none) / 20, version);
|
|
675
|
+
avm1.set(o, "xMax", (r?.xMax ?? none) / 20, version);
|
|
676
|
+
avm1.set(o, "yMin", (r?.yMin ?? none) / 20, version);
|
|
677
|
+
avm1.set(o, "yMax", (r?.yMax ?? none) / 20, version);
|
|
678
|
+
return o;
|
|
679
|
+
}
|
|
680
|
+
/**
|
|
681
|
+
* A display object's `blendMode` on its class's prototype, of `flags`: its
|
|
682
|
+
* mode's name; one set that is none leaves it as it was (the corpus's
|
|
683
|
+
* movieclip_blend_mode_property, adl for a button's).
|
|
684
|
+
*/
|
|
685
|
+
export function blendModeProperty(realm, proto, flags, targetOf) {
|
|
686
|
+
const p = proto.add("blendMode", undefined, flags);
|
|
687
|
+
p.get = realm.method((self) => targetOf(self)?.blendMode);
|
|
688
|
+
p.set = realm.method((self, args) => {
|
|
689
|
+
const d = targetOf(self);
|
|
690
|
+
const mode = blendModeOf(args[0]);
|
|
691
|
+
if (d !== null && mode !== null) {
|
|
692
|
+
d.touch();
|
|
693
|
+
d.setBlendMode(mode);
|
|
694
|
+
}
|
|
695
|
+
return undefined;
|
|
696
|
+
});
|
|
697
|
+
}
|
|
698
|
+
/**
|
|
699
|
+
* A display object's `cacheAsBitmap` on its class's prototype, of `flags`:
|
|
700
|
+
* whether Flash draws it from a bitmap it keeps, as it does any filtered
|
|
701
|
+
* one whatever was set (as AS3's reads it); one set is what the script asks
|
|
702
|
+
* for, as Ruffle has it.
|
|
703
|
+
*/
|
|
704
|
+
export function cacheAsBitmapProperty(realm, proto, flags, targetOf) {
|
|
705
|
+
const p = proto.add("cacheAsBitmap", undefined, flags);
|
|
706
|
+
p.get = realm.method((self) => {
|
|
707
|
+
const d = targetOf(self);
|
|
708
|
+
return d === null ? undefined : cached(d);
|
|
709
|
+
});
|
|
710
|
+
p.set = realm.method((self, args, version) => {
|
|
711
|
+
targetOf(self)?.setCachedAsBitmap(avm1.toBoolean(args[0], version));
|
|
712
|
+
return undefined;
|
|
713
|
+
});
|
|
714
|
+
}
|
|
715
|
+
/** The display object a method's argument names from `start`: a clip's AVM1 object, or a path. */
|
|
716
|
+
export function targetOf(movie, start, value, version) {
|
|
717
|
+
if (value instanceof avm1.Avm1Object && value.display !== null) {
|
|
718
|
+
return value.display.target;
|
|
719
|
+
}
|
|
720
|
+
const path = avm1.stringOf(value, version);
|
|
721
|
+
const from = movie.faceOf(start);
|
|
722
|
+
const cx = movie.realm.current;
|
|
723
|
+
if (path === "" || from === null || cx === null) {
|
|
724
|
+
return null;
|
|
725
|
+
}
|
|
726
|
+
const object = avm1.targetPath(cx, from, path, true, false, version);
|
|
727
|
+
const d = object?.display?.target;
|
|
728
|
+
return d === undefined ? null : d;
|
|
729
|
+
}
|
|
730
|
+
/** A point's own stored x and y, numbers both, as localToGlobal reads them, null for anything else. */
|
|
731
|
+
function pointOf(value) {
|
|
732
|
+
if (!(value instanceof avm1.Avm1Object)) {
|
|
733
|
+
return null;
|
|
734
|
+
}
|
|
735
|
+
const x = value.exact("x");
|
|
736
|
+
const y = value.exact("y");
|
|
737
|
+
if (x === undefined ||
|
|
738
|
+
y === undefined ||
|
|
739
|
+
typeof x.value !== "number" ||
|
|
740
|
+
typeof y.value !== "number") {
|
|
741
|
+
return null;
|
|
742
|
+
}
|
|
743
|
+
return [value, x.value, y.value];
|
|
744
|
+
}
|
|
745
|
+
/** MovieClip: its constructor and its prototype's methods, as `_global.MovieClip`. */
|
|
746
|
+
export function movieClipClass(movie) {
|
|
747
|
+
const realm = movie.realm;
|
|
748
|
+
const proto = new avm1.Avm1Object(realm.objectProto);
|
|
749
|
+
const constr = realm.classOf(proto, (self) => self, () => undefined);
|
|
750
|
+
const method = (name, flags, fn) => {
|
|
751
|
+
proto.define(name, realm.method((self, args, version) => {
|
|
752
|
+
const clip = clipOf(self);
|
|
753
|
+
return clip === null ? undefined : fn(clip, args, version);
|
|
754
|
+
}), avm1.DONT_ENUM | avm1.DONT_DELETE | flags);
|
|
755
|
+
};
|
|
756
|
+
proto.define("useHandCursor", true, avm1.DONT_ENUM);
|
|
757
|
+
proto.define("enabled", true, avm1.DONT_ENUM);
|
|
758
|
+
drawingMethods(method, (clip) => movie.swfOf(clip).version);
|
|
759
|
+
method("attachMovie", 0, (clip, args, version) => {
|
|
760
|
+
if (args.length < 3) {
|
|
761
|
+
return undefined;
|
|
762
|
+
}
|
|
763
|
+
const name = avm1.stringOf(args[0], version);
|
|
764
|
+
const instance = avm1.stringOf(args[1], version);
|
|
765
|
+
const depth = avm1.toNumber(args[2], version) | 0;
|
|
766
|
+
const init = args.length > 3 && args[3] instanceof avm1.Avm1Object ? args[3] : null;
|
|
767
|
+
const child = movie.attachMovie(clip, name, instance, depth, init);
|
|
768
|
+
// A SWF 5 gets nothing back, as from duplicateMovieClip (adl).
|
|
769
|
+
return version < 6 || child === null ? undefined : (movie.faceOf(child) ?? undefined);
|
|
770
|
+
});
|
|
771
|
+
method("swapDepths", 0, (clip, args, version) => {
|
|
772
|
+
swapDepths(movie, clip, args[0], version);
|
|
773
|
+
return undefined;
|
|
774
|
+
});
|
|
775
|
+
method("localToGlobal", 0, (clip, args, version) => {
|
|
776
|
+
const p = pointOf(args[0]);
|
|
777
|
+
if (p !== null) {
|
|
778
|
+
const m = toStageTwips(clip, movie.root.parent);
|
|
779
|
+
const [x, y] = transformTwips(m, twips(p[1]), twips(p[2]));
|
|
780
|
+
avm1.set(p[0], "x", x / 20, version);
|
|
781
|
+
avm1.set(p[0], "y", y / 20, version);
|
|
782
|
+
}
|
|
783
|
+
return undefined;
|
|
784
|
+
});
|
|
785
|
+
method("globalToLocal", 0, (clip, args, version) => {
|
|
786
|
+
const p = pointOf(args[0]);
|
|
787
|
+
if (p !== null) {
|
|
788
|
+
const m = invertTwips(toStageTwips(clip, movie.root.parent));
|
|
789
|
+
const [x, y] = m ? transformTwips(m, twips(p[1]), twips(p[2])) : [twips(p[1]), twips(p[2])];
|
|
790
|
+
avm1.set(p[0], "x", x / 20, version);
|
|
791
|
+
avm1.set(p[0], "y", y / 20, version);
|
|
792
|
+
}
|
|
793
|
+
return undefined;
|
|
794
|
+
});
|
|
795
|
+
method("hitTest", 0, (clip, args, version) => {
|
|
796
|
+
if (args.length > 1) {
|
|
797
|
+
const x = avm1.toNumber(args[0], version);
|
|
798
|
+
const y = avm1.toNumber(args[1], version);
|
|
799
|
+
const shape = args.length > 2 && avm1.toBoolean(args[2], version);
|
|
800
|
+
if (Number.isFinite(x) && Number.isFinite(y)) {
|
|
801
|
+
// In the root's space, which may have moved; without the shape, in the
|
|
802
|
+
// box around the clip on the stage (Ruffle's hit_test_bounds).
|
|
803
|
+
const stage = movie.root.parent;
|
|
804
|
+
const [sx, sy] = apply(toStage(movie.root, stage), x, y);
|
|
805
|
+
if (shape) {
|
|
806
|
+
return hitsPoint(clip, sx, sy, true, stage);
|
|
807
|
+
}
|
|
808
|
+
const r = bounds(clip, true);
|
|
809
|
+
return r !== null && contains(transformRect(r, toStage(clip, stage)), sx, sy);
|
|
810
|
+
}
|
|
811
|
+
return false;
|
|
812
|
+
}
|
|
813
|
+
if (args.length === 1) {
|
|
814
|
+
const other = targetOf(movie, clip, args[0], version);
|
|
815
|
+
return other !== null && hitsObject(clip, other, movie.root.parent);
|
|
816
|
+
}
|
|
817
|
+
return false;
|
|
818
|
+
});
|
|
819
|
+
// A snapshot of this clip by whatever TextSnapshot is on _global now.
|
|
820
|
+
method("getTextSnapshot", 0, (clip, _, version) => realm.construct(avm1.get(realm.global, "TextSnapshot", version), [movie.faceOf(clip) ?? undefined], version));
|
|
821
|
+
method("getBounds", 0, (clip, args, version) => {
|
|
822
|
+
const target = args.length > 0 ? targetOf(movie, clip, args[0], version) : clip;
|
|
823
|
+
return target === null ? undefined : boundsObject(movie, clip, target, true, version);
|
|
824
|
+
});
|
|
825
|
+
// A sprite's are its tags', a SWF's root's the SWF's.
|
|
826
|
+
const bytes = (clip) => {
|
|
827
|
+
const swf = movie.swfOf(clip);
|
|
828
|
+
return clip === swf.root ? swf.length : (clip.timeline.length ?? 0);
|
|
829
|
+
};
|
|
830
|
+
method("getBytesTotal", 0, bytes);
|
|
831
|
+
// A load in error has -1 bytes in all, none loaded (the corpus's movieclip_state_values).
|
|
832
|
+
method("getBytesLoaded", 0, (clip) => Math.max(0, bytes(clip)));
|
|
833
|
+
// The root is level 0's, at depth 0 (the corpus's movieclip_get_instance_at_depth).
|
|
834
|
+
method("getDepth", avm1.READ_ONLY | avm1.VERSION_6, (clip) => clip.depth !== null ? clip.depth - DEPTH_BIAS : clip === movie.root ? -DEPTH_BIAS : undefined);
|
|
835
|
+
// The SWF at the URL in place of what the clip shows, the clip's own variables sent where
|
|
836
|
+
// a method is "GET" or "POST", in any case (Ruffle's load_movie).
|
|
837
|
+
method("loadMovie", 0, (clip, args, version) => {
|
|
838
|
+
const face = clip.avm1;
|
|
839
|
+
if (face === null) {
|
|
840
|
+
return undefined;
|
|
841
|
+
}
|
|
842
|
+
const url = avm1.stringOf(args[0], version);
|
|
843
|
+
const method = args.length > 1 ? avm1.stringOf(args[1], version).toUpperCase() : "";
|
|
844
|
+
const form = method === "GET" || method === "POST" ? { method, vars: formVars(face, version) } : null;
|
|
845
|
+
movie.loadMovie(clip, url, form);
|
|
846
|
+
return undefined;
|
|
847
|
+
});
|
|
848
|
+
method("unloadMovie", 0, (clip) => {
|
|
849
|
+
movie.unloadMovie(clip);
|
|
850
|
+
return undefined;
|
|
851
|
+
});
|
|
852
|
+
method("play", 0, (clip) => {
|
|
853
|
+
clip.playing = true;
|
|
854
|
+
return undefined;
|
|
855
|
+
});
|
|
856
|
+
// As GetURL, from the code that called it, whose variables a method sends.
|
|
857
|
+
method("getURL", 0, (_, args, version) => {
|
|
858
|
+
const cx = movie.realm.current;
|
|
859
|
+
if (cx !== null) {
|
|
860
|
+
avm1.getUrlMethod(cx, args, version);
|
|
861
|
+
}
|
|
862
|
+
return undefined;
|
|
863
|
+
});
|
|
864
|
+
// The clip's own variables sent where a method is "GET" or "POST", in any case.
|
|
865
|
+
method("loadVariables", 0, (clip, args, version) => {
|
|
866
|
+
const face = clip.avm1;
|
|
867
|
+
if (args.length === 0 || face === null) {
|
|
868
|
+
return undefined;
|
|
869
|
+
}
|
|
870
|
+
const method = args.length > 1 ? avm1.stringOf(args[1], version).toUpperCase() : "";
|
|
871
|
+
const form = method === "GET" || method === "POST" ? { method, vars: formVars(face, version) } : null;
|
|
872
|
+
movie.loadVariables(clip, avm1.stringOf(args[0], version), form);
|
|
873
|
+
return undefined;
|
|
874
|
+
});
|
|
875
|
+
method("stop", 0, (clip) => {
|
|
876
|
+
clip.playing = false;
|
|
877
|
+
return undefined;
|
|
878
|
+
});
|
|
879
|
+
method("nextFrame", 0, (clip) => {
|
|
880
|
+
if (clip.currentFrame < clip.totalFrames) {
|
|
881
|
+
movie.timeline(clip).goto(clip.currentFrame + 1, false);
|
|
882
|
+
}
|
|
883
|
+
return undefined;
|
|
884
|
+
});
|
|
885
|
+
method("prevFrame", 0, (clip) => {
|
|
886
|
+
if (clip.currentFrame > 1) {
|
|
887
|
+
movie.timeline(clip).goto(clip.currentFrame - 1, false);
|
|
888
|
+
}
|
|
889
|
+
return undefined;
|
|
890
|
+
});
|
|
891
|
+
// Whether the clip is `_root` for the code in it; any value set as a boolean (the corpus's
|
|
892
|
+
// movieclip_lockroot).
|
|
893
|
+
const lockroot = proto.add("_lockroot", undefined, avm1.DONT_ENUM | avm1.DONT_DELETE);
|
|
894
|
+
lockroot.get = realm.method((self) => {
|
|
895
|
+
const clip = clipOf(self);
|
|
896
|
+
const native = clip?.avm1?.display;
|
|
897
|
+
return native instanceof ClipNative ? native.lockroot : undefined;
|
|
898
|
+
});
|
|
899
|
+
lockroot.set = realm.method((self, args, version) => {
|
|
900
|
+
const clip = clipOf(self);
|
|
901
|
+
const native = clip?.avm1?.display;
|
|
902
|
+
if (native instanceof ClipNative) {
|
|
903
|
+
native.lockroot = avm1.toBoolean(args[0], version);
|
|
904
|
+
}
|
|
905
|
+
return undefined;
|
|
906
|
+
});
|
|
907
|
+
// A new Transform of it each read; one given takes the matrix and colour transform of its clip.
|
|
908
|
+
const transform = proto.add("transform", undefined, avm1.DONT_ENUM | avm1.VERSION_8);
|
|
909
|
+
transform.get = realm.method((self, _, version) => {
|
|
910
|
+
const clip = clipOf(self);
|
|
911
|
+
const face = clip === null ? null : movie.faceOf(clip);
|
|
912
|
+
return face === null ? undefined : transformOf(movie, face, version);
|
|
913
|
+
});
|
|
914
|
+
transform.set = realm.method((self, args) => {
|
|
915
|
+
const clip = clipOf(self);
|
|
916
|
+
if (clip !== null) {
|
|
917
|
+
assignTransform(clip, args[0]);
|
|
918
|
+
}
|
|
919
|
+
return undefined;
|
|
920
|
+
});
|
|
921
|
+
filtersProperty(realm, proto, avm1.DONT_DELETE | avm1.DONT_ENUM | avm1.VERSION_8, clipOf, () => movie.filterFaces);
|
|
922
|
+
blendModeProperty(realm, proto, avm1.DONT_DELETE | avm1.DONT_ENUM | avm1.VERSION_8, clipOf);
|
|
923
|
+
cacheAsBitmapProperty(realm, proto, avm1.DONT_DELETE | avm1.DONT_ENUM | avm1.VERSION_8, clipOf);
|
|
924
|
+
// A BitmapData, disposed or not, at a depth; anything else does nothing. pixelSnapping is
|
|
925
|
+
// not read (Ruffle).
|
|
926
|
+
method("attachBitmap", avm1.VERSION_8, (clip, args, version) => {
|
|
927
|
+
const store = storeOf(args[0]);
|
|
928
|
+
if (store !== null && args.length > 1) {
|
|
929
|
+
const depth = avm1.toNumber(args[1], version) | 0;
|
|
930
|
+
movie.attachBitmap(clip, store, depth, args.length > 3 && avm1.toBoolean(args[3], version));
|
|
931
|
+
}
|
|
932
|
+
return undefined;
|
|
933
|
+
});
|
|
934
|
+
method("startDrag", 0, (clip, args, version) => {
|
|
935
|
+
const lockCenter = args.length > 0 && avm1.toBoolean(args[0], version);
|
|
936
|
+
const bounds = args.length > 4 ? args.slice(1, 5).map((a) => avm1.toNumber(a, version)) : null;
|
|
937
|
+
movie.startDrag(clip, lockCenter, bounds);
|
|
938
|
+
return undefined;
|
|
939
|
+
});
|
|
940
|
+
method("stopDrag", 0, () => {
|
|
941
|
+
movie.stopDrag();
|
|
942
|
+
return undefined;
|
|
943
|
+
});
|
|
944
|
+
method("setMask", avm1.VERSION_6, (clip, args, version) => {
|
|
945
|
+
if (args.length === 0) {
|
|
946
|
+
return undefined;
|
|
947
|
+
}
|
|
948
|
+
const value = args[0];
|
|
949
|
+
const mask = value == null ? null : movie.resolve(value, version);
|
|
950
|
+
if (value != null && mask === null) {
|
|
951
|
+
return false;
|
|
952
|
+
}
|
|
953
|
+
clip.setMask(mask);
|
|
954
|
+
return true;
|
|
955
|
+
});
|
|
956
|
+
method("gotoAndPlay", 0, (clip, args, version) => {
|
|
957
|
+
const cx = realm.current;
|
|
958
|
+
if (cx !== null) {
|
|
959
|
+
avm1.goto(cx, clip, args[0], true, 0, version);
|
|
960
|
+
}
|
|
961
|
+
return undefined;
|
|
962
|
+
});
|
|
963
|
+
method("gotoAndStop", 0, (clip, args, version) => {
|
|
964
|
+
const cx = realm.current;
|
|
965
|
+
if (cx !== null) {
|
|
966
|
+
avm1.goto(cx, clip, args[0], false, 0, version);
|
|
967
|
+
}
|
|
968
|
+
return undefined;
|
|
969
|
+
});
|
|
970
|
+
method("duplicateMovieClip", 0, (clip, args, version) => {
|
|
971
|
+
if (args.length === 0) {
|
|
972
|
+
return undefined;
|
|
973
|
+
}
|
|
974
|
+
// Any init object, as Flash takes it, an object made of a primitive (Ruffle: not version-gated).
|
|
975
|
+
const name = avm1.stringOf(args[0], version);
|
|
976
|
+
const depth = args.length > 1 ? avm1.toNumber(args[1], version) | 0 : 0;
|
|
977
|
+
const init = args.length > 2 ? realm.box(args[2], version) : null;
|
|
978
|
+
const child = movie.duplicate(clip, name, (depth + DEPTH_BIAS) | 0, init);
|
|
979
|
+
// A SWF 5 gets nothing back.
|
|
980
|
+
return version < 6 || child === null ? undefined : (movie.faceOf(child) ?? undefined);
|
|
981
|
+
});
|
|
982
|
+
proto.define("removeMovieClip", realm.method((self) => {
|
|
983
|
+
// Any display object's, as removeMovieClip.call(field) takes a text field.
|
|
984
|
+
const d = self instanceof avm1.Avm1Object ? self.display?.live()?.display?.target : undefined;
|
|
985
|
+
if (d !== undefined) {
|
|
986
|
+
movie.remove(d);
|
|
987
|
+
}
|
|
988
|
+
return undefined;
|
|
989
|
+
}), avm1.DONT_ENUM | avm1.DONT_DELETE);
|
|
990
|
+
method("getNextHighestDepth", avm1.VERSION_7, (clip) => {
|
|
991
|
+
let highest = -1;
|
|
992
|
+
for (const depth of clip.depths.keys()) {
|
|
993
|
+
highest = Math.max(highest, depth);
|
|
994
|
+
}
|
|
995
|
+
return Math.max(0, highest - (DEPTH_BIAS - 1));
|
|
996
|
+
});
|
|
997
|
+
method("getInstanceAtDepth", avm1.VERSION_7, (clip, args, version) => {
|
|
998
|
+
if (args.length === 0) {
|
|
999
|
+
return undefined;
|
|
1000
|
+
}
|
|
1001
|
+
const child = clip.depths.get((avm1.toNumber(args[0], version) | 0) + DEPTH_BIAS);
|
|
1002
|
+
return child === undefined
|
|
1003
|
+
? undefined
|
|
1004
|
+
: (movie.faceOf(child) ?? movie.faceOf(clip) ?? undefined);
|
|
1005
|
+
});
|
|
1006
|
+
method("getSWFVersion", 0, (clip) => {
|
|
1007
|
+
const version = movie.swfOf(clip).version;
|
|
1008
|
+
return version > 0 ? version : -1;
|
|
1009
|
+
});
|
|
1010
|
+
method("getRect", avm1.VERSION_8, (clip, args, version) => {
|
|
1011
|
+
const target = args.length > 0 ? targetOf(movie, clip, args[0], version) : clip;
|
|
1012
|
+
return target === null ? undefined : boundsObject(movie, clip, target, false, version);
|
|
1013
|
+
});
|
|
1014
|
+
method("createEmptyMovieClip", avm1.VERSION_6, (clip, args, version) => {
|
|
1015
|
+
if (args.length < 2) {
|
|
1016
|
+
return undefined;
|
|
1017
|
+
}
|
|
1018
|
+
const instance = avm1.stringOf(args[0], version);
|
|
1019
|
+
const depth = avm1.toNumber(args[1], version) | 0;
|
|
1020
|
+
return movie.faceOf(movie.createEmptyMovieClip(clip, instance, depth)) ?? undefined;
|
|
1021
|
+
});
|
|
1022
|
+
// Its place in whole pixels; a SWF 8 gets the field back, an earlier one nothing. The
|
|
1023
|
+
// depth is cast as Rust casts it, saturating (Ruffle).
|
|
1024
|
+
method("createTextField", avm1.VERSION_6, (clip, args, version) => {
|
|
1025
|
+
const instance = avm1.stringOf(args[0], version);
|
|
1026
|
+
const d = avm1.toNumber(args[1], version);
|
|
1027
|
+
const depth = Number.isNaN(d) ? 0 : Math.trunc(Math.max(-0x80000000, Math.min(0x7fffffff, d)));
|
|
1028
|
+
const [x, y, width, height] = args.slice(2, 6).map((a) => avm1.toNumber(a, version) | 0);
|
|
1029
|
+
const field = movie.createTextField(clip, instance, depth, [x, y, width, height]);
|
|
1030
|
+
return version < 8 ? undefined : (movie.faceOf(field) ?? undefined);
|
|
1031
|
+
});
|
|
1032
|
+
return { constr, proto };
|
|
1033
|
+
}
|
|
1034
|
+
/** swapDepths: to a depth, or to where a sibling is, swapping with what is there. */
|
|
1035
|
+
function swapDepths(movie, clip, arg, version) {
|
|
1036
|
+
const parent = clip === movie.root ? null : clip.parent;
|
|
1037
|
+
if (movie.removed(clip) || !(parent instanceof MovieClip)) {
|
|
1038
|
+
return;
|
|
1039
|
+
}
|
|
1040
|
+
let depth = null;
|
|
1041
|
+
if (typeof arg === "number") {
|
|
1042
|
+
depth = ((avm1.toNumber(arg, version) | 0) + DEPTH_BIAS) | 0;
|
|
1043
|
+
}
|
|
1044
|
+
else {
|
|
1045
|
+
const target = targetOf(movie, clip, arg, version);
|
|
1046
|
+
if (target !== null && target.parent === parent && !movie.removed(target)) {
|
|
1047
|
+
depth = target.depth;
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
if (depth === null || depth < 0 || depth > 2130706428 || depth === clip.depth) {
|
|
1051
|
+
return;
|
|
1052
|
+
}
|
|
1053
|
+
const other = parent.depths.get(depth);
|
|
1054
|
+
const from = clip.depth;
|
|
1055
|
+
if (other !== undefined) {
|
|
1056
|
+
parent.swapChildren(clip, other);
|
|
1057
|
+
parent.depths.set(from, other);
|
|
1058
|
+
other.depth = from;
|
|
1059
|
+
// The clip swapped away is the script's too: the timeline no longer
|
|
1060
|
+
// moves it, nor makes it anew on a rewind (`avm1-rewind-swapped-other`).
|
|
1061
|
+
other.touch();
|
|
1062
|
+
}
|
|
1063
|
+
else {
|
|
1064
|
+
parent.removeChild(clip);
|
|
1065
|
+
parent.placeAtDepth(clip, depth);
|
|
1066
|
+
}
|
|
1067
|
+
parent.depths.set(depth, clip);
|
|
1068
|
+
clip.depth = depth;
|
|
1069
|
+
clip.touch();
|
|
1070
|
+
}
|