Commit Graph

3911 Commits

Author SHA1 Message Date
Aaron Hill 66df5ea3de avm2: Implement typed 'catch' blocks
Now that we have a custom `Error` enum, this is very straightforwawrd.
I've converted `getDefinitionByName` return an AVM error, since this
is commonly used by games to test for a class.
2022-09-24 13:03:29 -05:00
Aaron Hill b571b43375 avm2: Fix some `avm_debug!` calls.
These were debug-printing `Gc<Multiname>` instead of `Multiname`
2022-09-24 09:16:35 +03:00
Aaron Hill 7b0bc0fb74 avm2: Implement undocumented 'Function.length' property
This returns the function's parameter count, and is used by the Starling
framework to implement a custom event dispatcher.
2022-09-23 18:36:23 -05:00
Aaron Hill 25f176995a avm2: Stub flash.ui.Multitouch
This is needed by Starling
2022-09-23 16:04:30 -05:00
kmeisthax d09ea7514e chore: Oops, I meant to clamp to total frames.
Pointed out by @n0samu
2022-09-23 11:45:52 -06:00
David Wendt aca1c0fb50 avm1: Clamp `WaitForFrame` ops to the total frame count of the movie clip being tested. 2022-09-23 11:45:52 -06:00
relrelb 4828a9c5cf avm1: Remove `get_` prefix from `ColorTransformObject` getters
To match Rust naming conventions.
2022-09-23 11:10:12 +03:00
relrelb e7643c731b core: `ColorTransform` cleanup
Main changes:
* Merge `ColorTransformParams` into `ColorTransformObject`, as it's only relevant for AVM1.
* Make `BitmapData::color_transform` work with a generic `ColorTransform`, which uses fixed-point
arithmetic.

Note that Ruffle still calculates color transforms slightly different from Flash. This is probably
caused by inaccuracy of the current `ColorTransformObject` to `ColorTransform` conversion and/or the
`ColorTransform` application logic itself. Since this requires further research, it'll be fixed in a
future PR.
2022-09-23 11:10:12 +03:00
EmperorBale a17352a01a avm2: Switch XML & XMLList to actionscript 2022-09-22 15:18:23 -07:00
EmperorBale 1cc765d675 avm2: Implement checkfilter opcode 2022-09-22 15:18:23 -07:00
EmperorBale 6dea1fa264 avm2: Implement TypeError 2022-09-22 15:18:23 -07:00
relrelb 2c50a04e37 avm1: Remove `Value::to_primitive_num`
Use `Value::to_primitive` instead.
2022-09-22 22:40:07 +03:00
relrelb d5209c4c43 core: Refactor `Percent` type
Unconditionally represet percentages as `f64` between `0.0` and `100.0`.
2022-09-22 04:17:44 +03:00
relrelb 9d4ab37ef6 core: Replace consecutive `push`es with `extend`
This should be slightly more efficient.
2022-09-22 03:00:02 +03:00
EmperorBale fe951b4989 avm2: Implement ByteArray.writeObject
While doing this I also noticed that we were incorrectly producing AmfValue::Integer if our
target AMF version is AMF0. This is incorrect because AMF0 is based on AS2, which does not
recognise Integer as a valid type, and therefore must be represented with Number instead.
2022-09-21 13:39:58 -07:00
Daniel Jacobs eefaca1e05 avm2: Add a few missed ActionScript enums 2022-09-21 20:54:36 +02:00
Aaron Hill 6ad72d0ef9 avm2: Assign 'prototype.name' through class object
This makes the files compile under mxmlc
2022-09-21 12:37:37 -05:00
Aaron Hill e99c7fa4af Add size assertions for Result<Value, Error> and Value 2022-09-21 12:37:37 -05:00
Aaron Hill 93b7de2fe6 avm2: Use custom Error instead of std::error::Error 2022-09-21 12:37:37 -05:00
Adrian Wielgosik d1ffaad927 avm2: Support enumerating null/undefined 2022-09-21 00:03:44 +02:00
Aaron Hill 9b9c95bfe2 avm2: Add GameInput and GameInputEvent 2022-09-18 11:37:02 -05:00
EmperorBale bfca30fed7 avm2: Implement IDataOutput 2022-09-17 12:31:43 -07:00
EmperorBale b1aff49673 avm2: Implement IDataInput 2022-09-17 12:31:43 -07:00
EmperorBale e1eaa9770a avm2: Switch ByteArray to AS
avm2: Fix ByteArray

avm2: Implement ByteArray.defaultObjectEncoding

avm2: Rename ByteArray allocator
2022-09-17 12:31:43 -07:00
David Wendt 173b04cc5c avm2: Allow access to `Stage.loaderInfo.url` 2022-09-17 12:32:15 -06:00
David Wendt 0925412110 avm2: `LoaderInfo` needs to specifically know if it's the stage's loader or not. 2022-09-17 12:32:15 -06:00
David Wendt dbe6eb324c avm2: Explicitly delay all frame construction until the first frame is loaded.
This prevents the root from being constructed until we know its `SymbolClass`, and is roughly equivalent to delaying the work until `ShowFrame`. (We don't actually run any work on `ShowFrame` in our current movieclip impl.)
2022-09-16 21:44:11 -06:00
David Wendt 247a28d7e9 avm2: Impl `Sprite.useHandCursor` 2022-09-16 19:25:46 -06:00
David Wendt 6f1509d4cd avm2: Don't attempt to print registers that are out-of-bounds. 2022-09-16 15:46:36 -06:00
David Wendt 38c6369f6e avm2: Fix `avm_debug` not printing debugging information 2022-09-16 15:46:36 -06:00
David Wendt 187352b1db chore: Fix stubs to use the new `Error<'gc>` property 2022-09-15 20:25:21 -06:00
David Wendt e7379a26e9 docs: Mark `z` as needing a version-gate once we have that set up 2022-09-15 20:25:21 -06:00
David Wendt 2b2089e9cb docs: Bitmap subclasses tickle the "initialized by movie" code path because the DisplayObject code actually does its job here 2022-09-15 20:25:21 -06:00
David Wendt bd8ff4f024 avm2: Add support for Bitmaps being associated to subclasses of `flash.display.Bitmap` 2022-09-15 20:25:21 -06:00
David Wendt fc02715faa avm2: Stub `z`, `scaleZ`, and all 3D rotation properties 2022-09-15 20:25:21 -06:00
David Wendt 3c0b9b9f62 avm1: Implement `ActionWaitForFrame` and `ActionWaitForFrame2`. 2022-09-15 19:14:41 -06:00
David Wendt aa9e24fb9d core: Limit gotos to the currently loaded frame count 2022-09-15 19:14:41 -06:00
David Wendt c7e29e4173 chore: Various nitpicks and compilation fixes 2022-09-15 19:14:41 -06:00
David Wendt af9db3e9c7 docs: Drop "action" language for `ExecutionLimit` as that is confusable for AVM actions.
We now call them "operations" and clarify that they could be either AVM actions or SWF bytes.
2022-09-15 19:14:41 -06:00
David Wendt 44f1cdfdec avm2: `LoaderInfo` reports correct total size for SWFs loaded in-memory 2022-09-15 19:14:41 -06:00
David Wendt f3ca7f7673 avm2: Still-loading SWFs do not report a `url` 2022-09-15 19:14:41 -06:00
David Wendt 8f5afe09a1 core: Refactor `movie_loader` and its `loadBytes` variant to call into the same code. 2022-09-15 19:14:41 -06:00
David Wendt 86ecf6076e core: `loadBytes` does not emit `open` 2022-09-15 19:14:41 -06:00
TÖRÖK Attila d0277f7fe8 avm2: Add `Loader.loadBytes` 2022-09-15 19:14:41 -06:00
David Wendt 006269e1f8 core: Delay completion events until after the SWF is reported as fully loaded. 2022-09-15 19:14:41 -06:00
David Wendt 0a25f265d6 core: `LoaderInfo` now optionally contains a reference to the root clip in the not-loaded state so that things like `bytesLoaded` work 2022-09-15 19:14:41 -06:00
David Wendt 4976dc973d core: Emit a progress event after every preload tick.
This does not cover root movies, which already get progress events as part of a prior commit.
2022-09-15 19:14:41 -06:00
David Wendt e589df650f core: Centralize compressed length calculations into `movieclip.rs` 2022-09-15 19:14:41 -06:00
David Wendt 1323355a69 avm2: Fire progress events when the root movie is preloaded.
This is currently somewhat buggy, `homestuck_02791.swf` stops at 12% for some reason. I tried handing it both compressed and uncompressed lengths with no luck.
2022-09-15 19:14:41 -06:00
David Wendt 07bd7dda2e core: Do not overflow when querying loaded bytes on a fully-loaded movie. 2022-09-15 19:14:41 -06:00
David Wendt 029fecaa94 avm2: Implement `LoaderInfo.bytesLoaded`.
This requires estimating a count of bytes loaded of the original compressed stream, even though we only have uncompressed byte totals at this point. I instead rescale the uncompressed bytes by the compressed count to roughly estimate what would be the `bytesLoaded` had we been actually streaming bytes in and preloading them synchronously.
2022-09-15 19:14:41 -06:00
David Wendt bd08a6ebfe avm1: Expose preload progress to AVM1 via `getBytesLoaded` 2022-09-15 19:14:41 -06:00
David Wendt 0eff0bf91a core: Remove all synchronous preloading from core.
Backends that need synchronous preload behavior now explicitly ask for it as follows:

 * `tests` - repeatedly call `preload` in a loop with an exhausted execution limit to stress-test the chunked preload
 * `exporter`, `scanner` - synchronous/unlimited preload to match prior behavior

These may change in the future.
2022-09-15 19:14:41 -06:00
David Wendt 3d799acd96 core: Report to callers of preload if all preloading work was done or not. 2022-09-15 19:14:41 -06:00
David Wendt 10e944a911 core: Turns out this is NOT redundant, I just misread the loop points 2022-09-15 19:14:41 -06:00
David Wendt 15b781ff04 chore: Remove old version of code left behind during rebasing 2022-09-15 19:14:41 -06:00
David Wendt 89fcca4f0b core: Only mark the end of the frame if we hit the end of the tag stream. 2022-09-15 19:14:41 -06:00
David Wendt f272cba7e6 core: If we're marked as finished, set the preload position to `u64::MAX` so that the repeated call protection trips 2022-09-15 19:14:41 -06:00
David Wendt 31802ea96f chore: Reduce the number of necessary reads of the preload progress 2022-09-15 19:14:41 -06:00
David Wendt ea284ed6bf core: Preload should always start from the place we left off from. 2022-09-15 19:14:41 -06:00
David Wendt afd29d19a4 core: Don't do any work if a clip is preloaded after finishing preload. 2022-09-15 19:14:41 -06:00
David Wendt 86f9ee4821 core: Add a "preload everything we know about" method 2022-09-15 19:14:41 -06:00
David Wendt 940de4bb7e core: Add a special loader state for "downloaded but still parsing", and a function that ticks the preload.
Currently we do this automatically with no execution limit.
2022-09-15 19:14:41 -06:00
David Wendt 70e638b21f core: Actually decrease the current action limit correctly 2022-09-15 19:14:41 -06:00
David Wendt a05827eb90 core: Add a concept of an `ExecutionLimit` that checks both actions and runtime.
Actions are abstract; here we're using it to count bytes loaded (as a proxy for execution time). AVM code could potentially be adapted to count operations run instead.
2022-09-15 19:14:41 -06:00
David Wendt c80abff3a9 core: Allow chunked preloading within a `DefineSprite` tag 2022-09-15 19:14:41 -06:00
David Wendt 3a265adcc4 core: Ensure empty movie clips are born preloaded.
An "empty clip" is any clip created by the `new` or `new_with_avm2` function, intended for dynamically-created movie clips with no association to a movie symbol.
2022-09-15 19:14:41 -06:00
David Wendt f96017e6f3 avm2: Preload dynamically created movie clips
If we don't preload every movie clip we make, then they'll indicate themselves as not having been fully loaded yet, even though they are.
2022-09-15 19:14:41 -06:00
David Wendt 0f2237e171 core: Make frame loaded count no longer be off by one
The preload frame counting logic starts from one and continues to the end of the file, which results in a completely preloaded movie having one more frame "loaded" than there is in the file. This fixes that.
2022-09-15 19:14:41 -06:00
David Wendt 079b20a4f2 core: On unexpected EOF, mark the clip preload as completed 2022-09-15 19:14:41 -06:00
David Wendt 85cf383c84 core: Allow callers of `decode_tags` to flag when they would like decoding to stop 2022-09-15 19:14:41 -06:00
David Wendt f7f5316b71 core: Prohibit playing movie clip frames that haven't been preloaded yet. 2022-09-15 19:14:41 -06:00
David Wendt 0ab10d9ab0 core: Make the preload chunk size configurable per caller.
Right now, we do not actually set a chunk limit, as we still need infrastructure for backgrounding the preload calls.
2022-09-15 19:14:41 -06:00
David Wendt b5cbfaf093 core: When preloading other movie clips, forcibly preload them synchronously. 2022-09-15 19:14:41 -06:00
David Wendt 4e9bb3a173 core: Implement chunked decoding infrastructure.
We currently do not actually enforce a decoding limit; just add the functionality necessary to do so.
2022-09-15 19:14:41 -06:00
golfinq c63f915ae2 avm2: Implement missing enums 2022-09-15 15:42:29 -07:00
Aaron Hill e08f8d47ab Allow clippy::needless_lifetimes to keep explicit 'gc parameter
This makes it clear what the lifetime is used for.
2022-09-13 18:55:08 -05:00
Aaron Hill c4ce06a500 avm2: Use Box<dyn std::error::Error> for FromWStr impl
We don't currently have an `Activation` available in this
method, and we can't specify a 'gc lifetime without modifying
the trait itself.
2022-09-13 18:55:08 -05:00
Aaron Hill 3e65a554fa avm2: Add 'gc lifetime parameter to avm2::Error 2022-09-13 18:55:08 -05:00
relrelb b1760063ec avm2: Implement `flash.filters.DisplacementMapFilterMode` 2022-09-13 21:20:55 +03:00
relrelb 5d5093f0fd avm2: Implement `flash.filters.BitmapFilterType` 2022-09-13 21:20:55 +03:00
Adrian Wielgosik 1c940009a1 avm2: Convert Capabilities, System to AS 2022-09-12 02:03:34 +02:00
TÖRÖK Attila 866f5c83c5 avm2: Add `flash.filters.BitmapFilterQuality` 2022-09-11 22:05:15 +02:00
Aaron Hill fbcefc49dc avm2: Fix "Property does not exist" error message
The `multiname` is now a `Gc`, so we need to dereference it
to get a useful Debug impl.
2022-09-11 11:34:52 -05:00
Aaron Hill 81a5f3f10a core: Always check mergeAlpha in BitmapData.copyPixels
Previously, we would only use mergeAlpha if alphaBitmapData
and alphaPoint. However, mergeAlpha can be used even when
those parameters are null.

Some of the AVM1 argument handling was also incorrect - I've fixed
it, and extended the existing test with the output-based test
added for AVM2.
2022-09-11 11:12:09 -05:00
Aaron Hill 1d6b3b6f57 chore: Fix Clippy lints and allow `clippy::bool_to_int_with_if`
In several cases, the current code seems preferable to the
code required by `clippy::bool_to_int_with_if`. Let's suppress
this for now to get the build passing, and decide later if this
is something that we want to enable.
2022-09-11 13:31:46 +02:00
Nathan Adams 267ea0fd13 render: Introduced render commands, moved to a command list model instead of direct rendering 2022-09-11 09:07:53 +02:00
Aaron Hill a638b0498e core: Render Bitmap even if bitmap_data is None
We only need to access bitmap_data to check if we need to
update a dirty texture.
2022-09-11 07:06:11 +03:00
Aaron Hill 8370bc792d core: Use correct background alpha in BitmapData.draw
Previously, we would always use a transparent background,
even if the BitmapData is not transparent. This would normally
be corrected on the next frame when we copied the pixels to the
CPU. However, if an SWF ran `BitmapData.draw` on every frame,
this would never be corrected.
2022-09-09 19:24:21 -05:00
Aaron Hill 5de21428f5 core: Update dirty BitmapData before rendering
We now have a `MutationContext` available, so this doesn't need
to be done in `run_frame`
2022-09-09 16:36:40 -07:00
Adrian Wielgosik 4421fbff6a
avm2: Convert all Qname::new(...).into() to Multiname::new() (#7930) 2022-09-09 23:33:30 +02:00
Aaron Hill ca030169f7 avm2: Implement BitmapData.rect and stub BitmapData.applyFilter
These are the last BitmapData methods needed for Solarmax
(the victory screen after beating the last level now renders).
2022-09-09 13:05:13 -05:00
Aaron Hill bb138d9082 avm2: Implement some of SharedObject
Our AVM2 `SharedObject` support is now *almost* equivalent
to our avm1 `SharedObject` support. We implement serialization
and deserialization for primitives, arrays, and `Object` instances
with local properties. We also implement serialization for `Date`,
but not `Xml` (since our AVM2 `Xml` class is just a stub at the moment).

This is enough to make 'This is the only level too' save level
progress to disk.

Currently, we always serialize to AMF3. When we implement
the `defaultObjectEncoding` and `objectEncoding`, we'll need
to adjust this.
2022-09-08 21:22:05 -05:00
Aaron Hill c090fe30ad core: Mark DisplayObject as non-removed when added to display list
An AVM2 movie can repeatedly remove and add a DisplayObject from/to
a parent. This was causing SolarMax to stop working after advancing
to the next level.
2022-09-08 18:19:25 -05:00
relrelb 7ec587355b text: Store background and border colors as `swf::Color`
Instead of `u32`.
2022-09-08 08:44:50 +03:00
EmperorBale ece4b9a76d avm2: Small cleanup 2022-09-07 13:54:33 -07:00
EmperorBale 7da912bbb4 avm2: Only store stack traces if avm_debug is enabled 2022-09-07 13:54:33 -07:00
EmperorBale 53ae55ff6f avm2: Improve stack trace output 2022-09-07 13:54:33 -07:00
EmperorBale 7fa19c2ea3 avm2: Store stack trace in Error objects 2022-09-07 13:54:33 -07:00
Aaron Hill 7218146e04 avm2: Implement BitmapData.dispose
We now check if a BitmapData has been disposed by checking
for a zero width or height (which cannot happen otherwise).
As a result, we no longer need the 'disposed' field on the AVM1
BitmapData object.
2022-09-07 11:02:53 -07:00