Commit Graph

4325 Commits

Author SHA1 Message Date
relrelb 3645061910 core: Simplify `DisplayObjectContainer::highest_depth`
The `less_than` parameter remained just `Depth::MAX` since #7199,
which makes it useless. As such it can be removed.
2022-08-29 17:26:15 -06:00
Aaron Hill e9697439de avm2: Skip over holes during array enumeration
This brings us closer to matching the Flash Player
enumeration behavior. Unfortunately, the precise enumeration
order for ScriptObject properties depends on the precise
order in the internal avmplus hashmap. This order is deterministic,
but adding/removing a property effectively randomizes it. Hopefully
there aren't any SWFS that depend on the *exact* order.
2022-08-29 15:53:44 -07:00
dependabot[bot] 802de0e7d1 build(deps): bump futures from 0.3.23 to 0.3.24
Bumps [futures](https://github.com/rust-lang/futures-rs) from 0.3.23 to 0.3.24.
- [Release notes](https://github.com/rust-lang/futures-rs/releases)
- [Changelog](https://github.com/rust-lang/futures-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/futures-rs/compare/0.3.23...0.3.24)

---
updated-dependencies:
- dependency-name: futures
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-29 23:38:43 +03:00
Toad06 c4e64c5e26 avm1: Function calls in SWF4 bump the version to 5 2022-08-29 02:17:09 -07:00
TÖRÖK Attila e86efd5c63 avm2: Add flash.utils.[set|clear][Timeout|Interval](...) 2022-08-29 01:44:57 -07:00
relrelb 5c29da6707 avm1: Implement `MovieClip.scrollRect`
The core functionality and AVM2 bindings were implemented in #7739.
2022-08-28 22:18:33 -07:00
= f180183ec5 core: Add audio feature, made dasp optional 2022-08-28 21:10:05 -07:00
= c6c22cebc9 core: Make nellymoser optional, enable on desktop and web 2022-08-28 21:10:05 -07:00
= f5245d72da core: Make core not use minimp3 by default - only desktop uses it 2022-08-28 21:10:05 -07:00
relrelb 81f803d77e avm1: Remove `DisplayObject::prev_avm1_clip`
It is no longer needed.
2022-08-28 19:21:03 -06:00
relrelb de6163569e avm1: Simplify frame execution logic
Handle removed clips inline in `Avm1::run_frame`, such that
`DisplayObject::prev_avm1_clip` is no longer used. Thus it can be
removed in a follow-up commit.
2022-08-28 19:21:03 -06:00
relrelb 0b7d8ea007 avm1: Move frame lifecycle logic to `Avm1::run_frame`
This allows better encapsulation of AVM1.
2022-08-28 19:21:03 -06:00
Aaron Hill 397de91a2a core: Do not run sounds on no-op goto.
When we run a 'goto' where the initial and target frame are the same,
we need to skip triggering any sounds in the target frame.
Some games like 'This is the only level too' rely on this behavior:
they repeatedly run 'movieClip.gotoAndStop(current_frame_id)',
where 'current_frame_id' is the id of a frame that starts playing
a sound. Without this change, the sound will restart every frame
intead of playing exactly once.
2022-08-28 18:55:29 -06:00
David Wendt e353553835 core: When reporting errors in the AVM2 constructor from MovieClip, also report the name of the class being constructed. 2022-08-28 18:17:57 -06:00
David Wendt 4b9ee55b56 avm2: The failsafe for self-referencing class properties should allow the use of `null` and `undefined`. 2022-08-28 17:54:22 -06:00
Aaron Hill ae8e5b2f33 avm2: Don't error when executing 'null as SomeType'
We previously used 'coerce_to_object', which produced
an error with `Value::Null`. Instead, we can just ues
`value.as_type_of`, which will correctly handle `null`
2022-08-28 16:33:15 -05:00
Aaron Hill c531994b1c avm2: Fire KeyboardEvent.KEY_UP and KeyboardEvent.KEY_DOWN
The 'charCode' and 'keyCode' properties are now implemented
on `KeyboardEvent`

The input injection code we use does not support keyboard events,
so we can't yet write a regression test for this. However,
both 'You need to burn the rope' and 'This is the Only Level TOO'
now properly handle keyboard events with this PR.
2022-08-28 14:15:57 -05:00
Aaron Hill e3e0488ed4 avm2: Delete enumerant when property is deleted 2022-08-28 12:03:19 -05:00
Aaron Hill 1296121dc5 avm2: Make 'set_local_property_is_enumerable` infallible
We always returned `Ok(())`
2022-08-28 12:03:19 -05:00
EmperorBale f8289b47d8
avm2: Implement call stack & stack traces (#7564)
* avm2: Implement call stack

* avm2: Class traits should have a special prefix

* avm2: Stack tracebacks should also contain error message

* avm2: Move method naming to Executable

* avm2: Handle getter and setter methods in tracebacks

* chore: Formatting

* chore: Add comments

* avm2: Make full_name write to a string, instead of creating a new one

* core: Make GcArena publicly accessible

* core: Add Deref impl for Either type

* desktop: Add AVM2 call stack to panic message

* avm2: Prefix native methods with a `/`

* chore: Appease clippy

* avm2: Check if method actually contains bytecode instead of unwrapping

* web: Add AVM2 stack trace to panic message

* chore: Formatting

* chore: Clippy

* avm2: Fix stack traces for free standing functions

* core: Remove global data from context

* core: Rename GcGlobalData to GcCallstack

* core: Introduce StaticCallstack, make GcArena private again

Co-authored-by: Adrian Wielgosik <4729533+adrian17@users.noreply.github.com>
2022-08-28 18:30:20 +02:00
Aaron Hill 6a01fa93c5 avm2: Implement `String.toLowerCase` and `String.toUpperCase`
These are implemented in the same way as in AVM1. Testing
in Flash Player shows that the behavior is the same.
2022-08-28 01:32:53 -05:00
Aaron Hill 576c35a768 avm2: Declare 'Array.concat' as a public method
Previously, it was only declared in the AS3 namespace. However,
some SWFs look it up as a public method.
2022-08-27 20:20:19 -05:00
relrelb 2f106da04c avm2: Port toplevel constants to ActionScript
Declare `NaN`, `Infinity` and `undefined` in ActionScript, similarly
to how `avmplus` does in its `actionscript.lang.as`.

Note that `null` is only removed, without an ActionScript declaration,
as it seems like `avmplus` neither declares it. Probably `null` is
only usable as a compile-time constant.
2022-08-26 15:45:36 -07:00
Callum Thomson 046514eeb9
avm1: Enumerate should push Undefined if the target isn't an object 2022-08-26 14:01:42 -07:00
Aaron Hill 249648674c Fix bounds computation 2022-08-26 13:04:01 -07:00
Aaron Hill 5fb95e6961 Use round-to-even for scrollRect 2022-08-26 13:04:01 -07:00
Aaron Hill fa0c843a4d avm2: Implement DisplayObject.scrollRect
This property causes a DisplayObject to be both translated
and cropped.
2022-08-26 13:04:01 -07:00
relrelb 72d8c152b9 core: Make `Player::load_device_font` infallible
It is always called with the same known data, which should parse
successfully.
2022-08-26 12:24:15 -07:00
relrelb ad84c2bbcb avm2: Rename `Avm2::load_abc` to `Avm2::do_abc`
This aligns with the name of `DoAbc` tags.
2022-08-26 11:37:04 -07:00
relrelb ad91992cb5 swf: Simplify `DoAbc` tag handling
Extract `swf::Reader::read_do_abc()` which, as the name suggests,
reads a `DoAbc` tag, and use it before calling to `Avm2::load_abc`.
Finally, introduce `DoAbcFlag` using `bitflags`.
This greatly simplifies the ABC loading code.
2022-08-26 11:37:04 -07:00
EmperorBale 18bd7879e5 core: Add better error message when java could not be found 2022-08-26 10:11:35 +02:00
Aaron Hill c4157fd0ce Miscellaneous stubs
This gets Solarmax to the main level select screen
(once BitmapData.draw support is added)
2022-08-25 19:57:03 -07:00
Aaron Hill 61d0f73fdb core: Use catchup_display_object_to_frame in Loader 2022-08-25 19:24:56 -06:00
David Wendt 2c93da9a70 docs: Add comments documenting subtle points of AS3 loop & tag queueing behavior 2022-08-25 19:24:56 -06:00
David Wendt 074f2ff76f core: Replace `Vec` of queued tags with a more restrictive enum that enforces our queueing invariants 2022-08-25 19:24:56 -06:00
David Wendt 59623a8452 core: Fix a potential stack overflow caused by gotos triggering frame scripts on one another. 2022-08-25 19:24:56 -06:00
David Wendt 05caa0fceb core: Explicit gotos drain the tag queue of any prior operations.
This is in keeping with the whole idea of a "recursive frame": gotos run the entire frame lifecycle on the target clip, including broadcasts for `frameConstructed` and `exitFrame`.
2022-08-25 19:24:56 -06:00
David Wendt 6f0de246ed core: Clear queued tags if AS3 attempts a goto in the middle of a loop. 2022-08-25 19:24:56 -06:00
David Wendt ed28578c12 core: Fast-forwarding gotos should run frame scripts on all removed children 2022-08-25 19:24:56 -06:00
David Wendt bcb1030883 core: Only `Construct` and `Enter` phases want forced script frames on gotos 2022-08-25 19:24:56 -06:00
David Wendt 3677a0107b core: Only force-queue frame scripts if the goto is not a no-op. 2022-08-25 19:24:56 -06:00
David Wendt ac2b82f26e core: Gotos *always* queue the target frame's scripts on the target clip, even if we already executed that script beforehand. 2022-08-25 19:24:56 -06:00
David Wendt 9bff6406d1 core: Allow queueing both a remove and a place tag at the same depth, in that order only. 2022-08-25 19:24:56 -06:00
David Wendt 2929681a93 core: No-op gotos should be treated as rewinding. 2022-08-25 19:24:56 -06:00
David Wendt 7a09bbfaab core: In AVM2, run removals before frame advance.
We still retain the queue system as events are fired at removal time, and those events can trigger more gotos. If such a goto happens, AS3 code will hit a clip still in the old state rather than an inconsistent one. I don't have test coverage for this exact scenario just yet.
2022-08-25 19:24:56 -06:00
David Wendt d691543c4c core: Child removals appear to resolve in reverse render order. 2022-08-25 19:24:56 -06:00
David Wendt 8feb3fc7b0 core: Fast-forward removals as the result of a goto happen before the frame number advances. 2022-08-25 19:24:56 -06:00
David Wendt 66c24ff188 core: Queue new object placement at loop time on the tag queue. 2022-08-25 19:24:56 -06:00
David Wendt 0353d176e4 core: Movie clip rewinds should not remove any children until after the new timeline position has been set. 2022-08-25 19:24:56 -06:00
David Wendt 99003643ac core: Same-frame gotos should only proceed on AVM2. 2022-08-25 19:24:56 -06:00
David Wendt cdfc6f5eae core: Explicit gotos must run even if they are no-ops. 2022-08-25 19:24:56 -06:00
David Wendt cb86340fb1 core: `frameConstructed` during a goto fires after the goto commands have fully completed. 2022-08-25 19:24:56 -06:00
David Wendt 51401ae660 core: Remove AVM2 compatibility hacks surrounding place frame.
They are no longer needed, frame advance happens at enterframe time.
2022-08-25 19:24:56 -06:00
David Wendt 1eef8a47c9 core: Movie clips run all their tags at `enter_frame`, and place/remove actions are queued until later.
This prevents repeated place/remove actions at the same depth from resulting in repeated event dispatches.
2022-08-25 19:24:56 -06:00
David Wendt 963144e59c core: Centralize all the various calls to `enter_frame`/`construct_frame` into a single method, `catchup_display_object_to_frame`.
The rationale for the catch-up logic is as follows:

 * We must always enter-frame and construct objects, even if those respective display events haven't happened yet.
 * Display objects created in event handlers still need to run catchup phases, otherwise they will tag-stream desync
 * Frame scripts are never triggered by catchup phases
 * `exit_frame` is not a catchup phase as it is *only* an event broadcast currently
2022-08-25 19:24:56 -06:00
David Wendt 0400d4dee4 core: `Player` should start in the `Idle` phase 2022-08-25 19:24:56 -06:00
David Wendt f0ef8adb42 core: Add a new frame phase to represent non-frame work such as input event handlers. 2022-08-25 19:24:56 -06:00
David Wendt ae530b5d6b core: Track what part of the frame processing loop we're in 2022-08-25 19:24:56 -06:00
David Wendt ee2454e09f core: Frame actions should start with `enterFrame`; not `exitFrame`. 2022-08-25 19:24:56 -06:00
David Wendt 1f0b8bdda4 core: In AVM2, movie clips process `RemoveObject` before any other frame actions are done. 2022-08-25 19:24:56 -06:00
David Wendt 318b018da8 core: `enter_frame` should be an event that all display objects get and can respond to 2022-08-25 19:24:56 -06:00
relrelb d152cc3e64 avm2: Port `Math` to ActionScript 2022-08-25 16:03:08 -07:00
relrelb 4e9cc919a1 avm2: Fix bindings of empty namespace
Previously native functions defined inside a `package {}` block
(without a package name) would cause a syntax error by two consecutive
`::`.
2022-08-25 16:03:08 -07:00
= 620820be9e core: Replaced tag_utils Error with an actual Error enum 2022-08-25 23:43:21 +02:00
= 67eb34fbc5 core: Remove Error from player.rs, it wasn't needed 2022-08-25 23:43:21 +02:00
= b7dcd26c38 core: Use Cow<str> for FullscreenError in UI backend, as it can't ever be anything else 2022-08-25 23:43:21 +02:00
= 1c7bfd8c5f core: Use real Error enums for video backend 2022-08-25 23:43:21 +02:00
= 461c977be0 render: unregister_bitmap is infallible, removed error path 2022-08-25 23:43:21 +02:00
= 03eb769a33 render: Made render use a real Error enum and not generic box<error> 2022-08-25 23:43:21 +02:00
= 5b5ee7d448 core: Made audio backend use actual real error enums, and not box<error> 2022-08-25 23:43:21 +02:00
= 2d2869f44f core: Font::from_swf_tag is currently infallible, remove error path 2022-08-25 23:43:21 +02:00
= 1df8de5bac core: set_text and set_html_text are currently infallible, remove error path 2022-08-25 23:43:21 +02:00
Mike Welsh 78247a37ab avm1: Load correct _root and _parent registers if base clip is removed
Normally a function closures also closes around its base clip.
If the base clip is removed, and then the function is executed, the
base clip then defaults to `this`.

However, Ruffle was incorrectly using the wrong base clip when
loading the `_root` and `_parent` registers in this case.

Fixes #5645.
2022-08-25 00:01:02 -07:00
Roman Rogowski 66d144bbdd core: Fix incorrect rendering of word-wrap text boxes (close #1095) 2022-08-24 22:51:51 -07:00
relrelb a8edce8294 core: Remove unneeded `Box` 2022-08-24 22:36:20 +03:00
Aaron Hill c7216bf842 avm2: Set URLRequest.method default to GET
This was missed when I added 'method'
2022-08-23 17:54:10 -05:00
onkrot 14abd01e91 avm2: Pull flash.crypto package method from globals to crypto.as 2022-08-23 09:58:19 -05:00
onkrot db22992b86 avm2: Pull flash.utils package methods from globals to utils.as 2022-08-23 09:58:19 -05:00
onkrot 1a243bdd86 avm2: Implement all remaining matrix methods 2022-08-23 10:44:12 +02:00
Aaron Hill 86e6983943 avm2: Partially implement Loader.load
This PR implements the `Loader.load` method, as well as
the associated `LoaderInfo` properties and events.

We can now load in an external AVM2 SWf: it will be added
as a child of `Loader` object, and will render properly
to the screen.

Limitations:
* The only supported `URLRequest` property is `url`
* `LoaderContext` is not supported at all - we always use the default
  behavior
* Only `Loader.load` is implemented - we do not yet support unloading.
* We fire a plain 'Event' for the 'progress' event, instead of using
  the (not yet implemented) 'ProgressEvent' class

The main changes in this PR are:
* The AVM2 `Loader` class now has an associated display object,
  `LoaderDisplay`. This is basically a stub, and just renders
  its single child (if it exists).
* `LoaderStream::Stage` is renamed to `LoaderStream::NotYetLoaded`.
  This is used for both the `Stage` and an 'uninitialized'
  `Loader.contentLoaderInfo`. In both cases, certain properties throw
  errors, while others return actual values.
* The rust `Loader` manager now handles both AVM1 and AVM2 movie loads.
2022-08-22 19:36:29 -07:00
dependabot[bot] 25a77869ab build(deps): bump serde from 1.0.143 to 1.0.144
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.143 to 1.0.144.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.143...v1.0.144)

---
updated-dependencies:
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-22 16:51:56 -07:00
Aaron Hill 98c7f443ce core: Only store viewport dimensions in `RenderBackend`
Previously, the viewport height and width were stored in
both `Stage` and the `RenderBackend`. Any changes to the viewport
dimensions (e.g. due to window resizing) needed to be updated in both
places to keep our handling of the viewport consistent.

This PR adds a new `ViewportDimensions` type, which holds the
width, height, and scale factor. It is stored inside the
`RenderBackend` impl, and is retrieved using the newly added
method `RenderBackend.get_viewport_dimensions`. After a `Player`
has been constructed, any code that needes access to the viewport
dimensions will ultimate go through this method.

Unfortunately, `Stage` needs to use the viewport dimensions
in `build_matrices`. Therefore, any code modifying the viewport
dimensions should go through `player.set_viewport_dimensions`,
which ensures that the stage matrices are rebuilt after the render
backend is updated.
2022-08-22 13:44:30 -07:00
Mike Welsh 3629a55c00 core: Mouse picking respects order of children (fix #7393)
When doing mouse picking, interactive children were considered
before all non-interactives, which could cause an `_droptarget` to
be set to an underlying movieclip even if a shape occluded it.

Now consider all children in render order so that the top-most
shape will capture the mouse input.
2022-08-21 21:16:02 -07:00
= 3a1947445e core: Made SwfSlice::to_subslice return an empty slice in case of errors 2022-08-21 20:12:10 -07:00
= 44cfaa9200 core: Made SwfSlice::to_unbounded_subslice return an empty slice in case of errors 2022-08-21 20:12:10 -07:00
= 55566037f7 core: Made SwfSlice::resize_to_reader return an empty slice in case of errors 2022-08-21 20:12:10 -07:00
= 0cfbdc0385 core: Made SwfSlice::to_start_and_end return an empty slice in case of errors 2022-08-21 20:12:10 -07:00
Adrian Wielgosik b18329c8fe web: Allow modifying player volume via JS 2022-08-20 11:53:42 -07:00
Mike Welsh b38fce230d audio: Add AudioBackend::volume/set_volume 2022-08-20 11:53:42 -07:00
David Wendt f66e54bd03 core: Log a `debug` message every time we run a goto. 2022-08-19 18:52:21 -07:00
David Wendt fe828d7c24 core: At the end of a goto, fix tag stream desyncs caused by not hitting the target frame.
If we try to go to a frame that doesn't exist, or hasn't been loaded yet, we will stop on the last available frame, but skip any tags that would have run there. This is technically a desync, but it hasn't caused any problems so far as any further timeline interaction would trigger a rewind (which isn't affected by desyncs).

Of course, now that we're actually testing the tag stream position it *does* cause problems. We actually have to fix up the position to be correct even though it will never be used (hopefully). It may be prudent to do this outside of the `timeline_debug` feature as well in the future.
2022-08-19 18:52:21 -07:00
David Wendt 32542fdbc8 core: When `timeline_debug` is enabled, assert every goto's tag stream positions against the list of stream boundaries. 2022-08-19 18:52:21 -07:00
David Wendt 72e40423fa core: Calculate the start and end position of every frame when the `timeline_debug` feature is enabled. 2022-08-19 18:52:21 -07:00
Mike Welsh 89cb1212ad render: Disable most blend modes
Avoid blend modes except ADD and SUBTRACT until they can be
implemented properly.
2022-08-19 14:59:08 -07:00
relrelb c7941e7248 avm1: Remove `ScriptObject::bare_object`
Use `ScriptObject::new` instead.
2022-08-19 12:22:48 -07:00
relrelb 5cbfcde784 avm1: Remove `ScriptObject::object_cell`
Use `ScriptObject::new` instead.
2022-08-19 12:22:48 -07:00
relrelb 04b4a6cabe avm1: Rename `ScriptObject::object` to `ScriptObject::new` 2022-08-19 12:22:48 -07:00
Aaron Hill f3feaaf2be avm1: Set init object properties in reverse order
Fixes #7667

This behavior is by setter functions, and some SWFS
depend on it.
2022-08-19 11:49:40 -07:00
Aaron Hill 0cd6d13783
avm2: Stub ContextMenu.builtInItems (#7652) 2022-08-18 20:50:42 -04:00
Mike Welsh 7a53322cbb avm1: Wire up Button.blendMode 2022-08-18 16:38:17 -07:00