Commit Graph

185 Commits

Author SHA1 Message Date
David Wendt ed4d51dfc1 avm1: Don't panic if we encounter an invalid display object hierarchy for AS2. Instead, yield a runtime error. 2020-12-09 14:00:06 -08:00
David Wendt afd033898c avm2: Implement `hitTestObject` 2020-12-09 14:00:06 -08:00
David Wendt 4b9deb7106 core: Don't crash on rootless display objects.
Instead, crash if AVM1 ever sees a rootless display object.
2020-12-09 14:00:06 -08:00
David Wendt a7b4f7fbd0 core: Add instantiated by timeline flag as AVM2 appears to track that 2020-12-09 14:00:06 -08:00
David Wendt 6080585d73 core: Assign `rootN` format names to top-level AVM2 movie clips. 2020-12-09 14:00:06 -08:00
David Wendt 3225cd40e2 core: Avoid panic when display objects are manipulated in clearly invalid ways. 2020-12-09 14:00:06 -08:00
David Wendt 01539baf5d core: Move `render_children` into `TDisplayObjectContainer`. 2020-11-27 13:23:34 -08:00
David Wendt ba311dd5b4 core: Remove previous changes to make certain `DisplayObject` methods take `&mut self`, which noises up the PR 2020-11-27 13:23:34 -08:00
David Wendt 8764831533 chore: cargo 1.47 changed the formatting algorithm 2020-11-27 13:23:34 -08:00
David Wendt 74b50f2586 core: AVM2-locked children should still be removable from the depth list. 2020-11-27 13:23:34 -08:00
David Wendt fec4e3c0a9 core: Replace direct container manipulation with `TDisplayObjectContainer` methods wherever possible.
The purpose of this refactor is twofold:

1. Ensure `TDisplayObjectContainer` holds all the container methods we need
2. Ensure that future adjustments to trait methods automatically apply to the display object's own use of the container, in case we want to do things in those methods that can't be done in a borrowed container

There are two places where we cannot use the new trait methods:

1. `Button.set_state` as it holds a borrow at the point we want to clear the container
2. `MovieClipData.goto_remove_object`, since it's a method on the data and thus cannot access trait methods

This particular commit generates a lot of noise as several `DisplayObject` methods were incorrectly marked as non-mutating.
2020-11-27 13:23:34 -08:00
David Wendt 80d7409fc5 core: Separate off container management into a separate `DisplayObjectContainer` trait 2020-11-27 13:23:34 -08:00
David Wendt a2d876bc8c core: Remove double-ended support for `ChildIter` as it's unnecessary and wastes time 2020-11-27 13:23:34 -08:00
David Wendt ab4dd984e8 core: Refactor display list management into a separate `ChildContainer` struct.
`ChildContainer` is responsible for maintaining child lists for all display objects that can hold children. Currently, this is just `Button` and `MovieClip` since those are the only objects in AVM1 that can have children, but this will be extended to other objects in future commits.

The number of lists managed has also increased from two to three. The execution list is unchanged save for it's migration into the `ChildContainer` struct. The render list has been split in two to support AS3. Specifically, the render list is now a `Vec`. Render children are still rendered in order but they are now referenced by AS3 `id`s rather than depths. The old `BTreeMap` that served as a render list is now the depth list and serves to maintain compatibility with SWF tags and AVM1 code that refers to things on the timeline by depth.
2020-11-27 13:23:34 -08:00
David Wendt 4817e92992 avm2: `getChildAt` works in reverse execution list order, not by depth 2020-11-27 13:23:34 -08:00
David Wendt f3ae65df93 core: Add flag for display objects which were placed by AS3.
In AS3. objects placed by scripts *cannot* be removed by `RemoveObject` tags. This enforces that in Ruffle.
2020-11-27 13:23:34 -08:00
David Wendt d04f131cfe avm2: Implement `DisplayObjectContainer.getChildAt`.
This test doesn't work yet because it needs `avm2-domainscope` to get merged in.
2020-11-27 13:23:34 -08:00
Mike Welsh 8d78ee5172 avm1: Use f64 when calculating scale/rotation (fix #1622) 2020-11-21 11:39:41 -08:00
Nathan Adams 1a230bda09 core: Remove focus when the focused object is removed 2020-11-02 11:43:10 -08:00
Nathan Adams a4a2cd00b2 avm1: Implement Selection index getters & setSelection - #271 2020-11-02 11:43:10 -08:00
Nathan Adams efbab816e7 avm1: Implement MovieClip.focusEnabled - #263 2020-11-02 11:43:10 -08:00
Nathan Adams 93acb07374 core: Introduce a focus tracker, to keep track of one (and only one) focused object 2020-11-02 11:43:10 -08:00
Nathan Adams f72310be43 core: Change the cursor to an IBeam on selectable text 2020-11-02 11:43:10 -08:00
Mike Welsh 0f4219610d core: Properly handle masker-inside-masker (fix #1347)
If a masker is placed inside a masker, the inner mask is inactive
and instead renders as normal art, masked by the outer mask. Properly
handle this case by only pushing new masks if we are not currently
drawing the mask stencil.

Maskee inside maskee still functions as expected. (i.e., a clip
using a mask is masked itself).
2020-10-25 20:41:31 -07:00
Mike Welsh 4558be948e render: Fix masking issues on wgpu/webgl backends
Change the usage of the stencil buffer to avoid running out of
stencil bits when too many nested masks are active.

This also cleans things up on wgpu which requires us to make
pipeline states in advice; now we only need a few stencil states
for masking as opposed to hundreds.
2020-10-17 02:42:56 -07:00
David Wendt 8152400a39 avm2: Implement `MovieClip.scenes`. 2020-10-06 06:03:22 -07:00
David Wendt f85319aa4c core: Allow `DisplayObject` to hold AVM2 objects.
This requires the use of an intermediary enum called `AvmObject` which can hold either object representation. Currently, it's mostly just being unwrapped as AVM1 objects, which we will need to fix.
2020-10-06 06:03:22 -07:00
David Wendt 6bb6bcab7a core: Store rotations in degrees to avoid floating-point conversion discrepancies. 2020-09-26 14:12:49 -07:00
David Wendt 28bf84bd8b core: Store object scale as percentages to avoid floating point precision problems.
Fixes a specific pattern of preloader design where animations were handled by just making the box bigger every frame until it's 100. Of course, direct equality of f64 is a terrible idea, but it works in Flash, which apparantly must store scale in percentages. So we must, too.
2020-09-26 14:12:49 -07:00
Luca Weiss d5cb396331 *: fix spelling mistakes 2020-09-19 16:17:58 -07:00
Mike Welsh e9a2ef5d82 core: DisplayObject::hit_test_shape now takes UpdateContext
Make default implementation the same as hit_test_bounds.
2020-09-15 02:34:32 -07:00
Mike Welsh 0d111ca92f avm1: _target of root should be /
Also, levels other than 0 should be appened in slash syntax, e.g
_level1/clip
2020-09-15 02:20:24 -07:00
Mike Welsh a18e80baf2 chore: Fix clippy lints 2020-09-07 12:18:41 -07:00
Mike Welsh 5ea06b0ce6 swf: Use Option for more PlaceObject parameters
There is a difference between empty/default (change value to default)
and none (don't modify), so make this explicit for some PlaceObject
parameters where it wasn't.

Fixes #1104.
2020-09-03 19:09:48 -07:00
Mike Welsh ce2b360ab7 core: Provide default impl for DisplayObject:hit_test_bounds 2020-09-02 17:51:55 -07:00
Mike Welsh d7a186b2cd avm1: Implement shape hit testing 2020-09-02 17:51:55 -07:00
Nathan Adams 2178beec87 core: When constructing objects for DisplayObjects, make sure frames are run at the right moment 2020-09-02 15:18:59 -07:00
Mike Welsh bc08971066 core: Return version from MovieClip::swf_version (fix #1086)
MovieClip was not returning the proper SWF version, causing it to
default to the newest SWF version in some cases when it shouldn't.
2020-09-02 13:25:53 -07:00
Mike Welsh 2a84d924bb chore: Don't mutably borrow self in TDisplayObject 2020-08-22 11:56:19 -07:00
Mike Welsh d2c49c0f33 core: Remove some mut from TDisplayObject methods 2020-08-18 01:18:15 -07:00
Mike Welsh 59ebd0167e core: Fix priority of conflicting instance names 2020-08-18 01:18:15 -07:00
David Wendt a19595c8b4 Embed `UpdateContext` in `Activation` directly.
The process of constructing an `Activation` now involves calling `UpdateContext.reborrow`, which "sheds" a lifetime by copying all of the borrows into a new "owned" context with that lifetime.

Likewise, to call out to functions that don't need an `Activation`, just borrow the context out of the current activation. You can also construct child-frame activations by reborrowing the parent activation's context.
2020-08-01 15:49:19 -04:00
David Wendt 7c7b019087 Move AVM1 inside UpdateContext. 2020-08-01 13:44:04 -04:00
David Wendt 14bfbc358f wip: Move UpdateContext into Activation 2020-08-01 13:33:04 -04:00
Nathan Adams 8bc3eedc43 avm1: Rename StackFrame to Activation now that they're merged 2020-07-02 00:09:43 +02:00
Nathan Adams da8ca1379f avm1: Change from 'avm, context' to 'activation, context' and restructured to support this 2020-06-29 10:09:38 +02:00
Mike Welsh 618fa11acb avm1: Implement text field variable binding 2020-06-28 18:36:10 -07:00
David Wendt bacbf06614 Setting the matrix of an `EditText` should scale it's bounds. 2020-06-20 19:48:12 -04:00
David Wendt 4eb2113a77 Setting positions and widths on the `EditText` should adjust intrinsic bounds rather than stretching or transforming the field. 2020-06-20 19:48:11 -04:00
David Wendt dc46885021 Implement `autoSize`.
This doesn't work right yet because the resulting width doesn't apply correctly to the field. This is because `EditText`'s `_width` and `_height` change it's intrinsic bounds rather than it's X and Y scale (like it would with a button or a movie clip).
2020-06-20 19:48:00 -04:00
Nathan Adams b2b57c1540 core: Make Value::as_object always return a (possibly boxed) object 2020-06-19 12:48:28 -07:00
Mike Welsh 62cfeb3754 core: Assign default name to unnamed clips (fix #66) 2020-06-18 16:26:36 -07:00
Mike Welsh 77cb186357 avm1: Constructors queue to run after a goto
If a class is registered to a clip that is placed on the timeline
during a goto, that constructor should run after the frame is
completely constructed. In order to tell whether to run the
constructor immediately, add a parameter to `post_instantiation`
to indicate if the clip is instantiated from the AVM or via a
standard timeline seek.
2020-06-16 14:53:44 -07:00
Mike Welsh ce73b4eaa7 core: Recursively unload child display objects
Child movie clips should run their unload actions when the parent
is removed.
2020-06-11 23:39:16 -07:00
Mike Welsh 932ad30570 core: Flatten ClipActions into a single event per action
Previously a MovieClip's clip action would have a set of events
that would trigger it. Now we flatten these out into a single
event per action, because this is by far the common case. If an
action does happen to have >1 event, it will be duplicated for each.
2020-05-24 08:57:30 -07:00
Mike Welsh c427d55dbb core: Clean up clip event handlers
Remove ButtonEvent and subsume it in ClipEvent. Player now tosses
ClipEvents down the display tree, cleaning up some of the event code.
2020-05-24 08:57:30 -07:00
Mike Welsh 6929cea996 core: Implement button event handlers for movie clips 2020-05-24 08:57:30 -07:00
Nathan Adams eda862c719 swf: Merged core::Matrix into swf::Matrix 2020-05-20 14:54:41 +02:00
Nathan Adams 84f6b4d06e core: Set init_object values after prototype but before constructor 2020-05-03 12:46:55 -07:00
Mike Welsh c1dc69c6b7 chore: rustfmt 2020-04-24 22:16:16 -07:00
Mike Welsh 2cdf780e6f avm1: Handle case sensitivity in DisplayObject children
Alter `get_child_by_name` and alter `get_level_by_path` to respect
case sensitivity.
2020-03-28 16:22:02 -07:00
Nathan Adams d850443c84 avm1: Refactor to expose `avm, context` in `post_instantiate` 2020-02-29 23:05:15 +01:00
Mike Welsh 223edb9bc1 core: Matrix translation is in twips 2020-02-26 12:47:47 -08:00
Mike Welsh a5c08f2e59 avm1: Implement MovieClip.getBounds and clean up bounding box methods
Implements MovieClip.getBounds, and also reorganized the
DisplayObject AABB methods:

 * `self_bounds` calculates the inherent untransfomed bounds of
 the object without children. All `DisplayObject`s must implement
 this method. For example, `Bitmap` returns the size of bitmap.
 Composite objects like `MovieClip` return a null AABB because they
 are made up of only children.
 * `bounds` calculates the untransformed bounds including children.
 * `local_bounds` calculates the bounds relative to the object's
 parent.
 * `world_bounds` calculates the bounds in global stage space.
 * `bounds_with_transform` calculates a tight AABB for the object
 with a given transform, and is used to implement the above.
2020-02-24 14:12:48 -08:00
Mike Welsh 1b08fb538d chore: Rename layer -> level
Unify mix of 'layer' and 'level' in the code, and it's probably
better to stick with Flash nomenclature.
2020-02-23 23:41:55 -08:00
David Wendt 766ded6dfd When replacing a movie clip with another movie, don't wipe out the entire display object base as that disassociates us from our parent, siblings, and most importantly, *layer depth*. 2020-02-22 00:02:51 -05:00
David Wendt e0b4a0f193 Top-level layers are referenced via their path (`_leveln`) rather than name - in fact, their name is always the empty string. 2020-02-22 00:02:51 -05:00
David Wendt 00f88f9e87 Use the depth to indicate which layer a particular root clip is, and then use that to calculate it's `_leveln` path. 2020-02-22 00:02:50 -05:00
David Wendt 9adf0f43d7 Allow levels to be read as scope variables, and add a test for this. 2020-02-22 00:02:50 -05:00
David Wendt aa6aba13dd Abolish `context.root` completely.
`_root` is calculated dynamically based on the clip the currently executing function was called in.

Other things that used `context.root` have been changed to either update all layers or just update layer 0, which is the former `context.root`.
2020-02-22 00:02:46 -05:00
David Wendt 5ce499d11e Add separate libraries for each loaded movie. 2020-02-21 23:57:56 -05:00
David Wendt 5ed5876e9a Merge SWF data and version into a single structure. Refactor everything that interacts with it to use `SwfSlice`s. 2020-02-21 23:57:53 -05:00
Mike Welsh 2ff76775e0 core: Empty movie clips can not be used as a mask
When a movie clip or button is used as a mask, the masking will be
disabled if that object has no children; the maskee will be
completely visible. An empty movie clip inside an empty movie clip
successfully masks.

An EditText can also not be used as a masker (although it can be
wrapped inside a movie clip, and then the text successfully masks).

Add a `TDisplayObject::allow_mask` trait method that will
return whether the object can be used as a mask.

This fixes characters not being visible in Dad 'n' Me.
2020-02-01 01:15:31 -08:00
Mike Welsh 2751b89d4e avm1: Root clip should not have a name
Previously we set the name of the root clip to `_level0`. Top-level
clips should actually have no name (`_root._name` returns `""`).

However, when constructing a dot path, `_level0` still gets inserted
by `DisplayObject::path` for the top-level, so that `trace(_root)`
still correctly prints `_level0`.

TODO: When `loadMovieNum` gets merged in, the proper level # needs
to be returned by `.DisplayObject::path`.
2020-01-27 23:35:41 -08:00
Mike Welsh 87158647d1 core: Implement keyPress button events 2019-12-24 03:06:03 -08:00
Mike Welsh 4bd54cc2ea core: Fix DisplayObject::global_to_local and local_to_global 2019-12-21 16:28:41 -08:00
Mike Welsh 540b03090a avm1: hitTest point is actually in root coordinates (fix #185) 2019-12-19 12:35:56 -08:00
Nathan Adams f6f358b4de avm1: Expose TextFields and allow setting their .text 2019-12-19 10:19:43 -08:00
Mike Welsh 2af76e10f8 core: Mark scale/rotation as dirty when matrix changes 2019-12-17 22:06:34 -08:00
Mike Welsh 1476930e0c avm1: Implement MovieClip.removeMovieClip 2019-12-17 03:20:01 -08:00
Mike Welsh d0504104b7 core: Use i32 for display object depth 2019-12-17 02:48:55 -08:00
Nathan Adams 84ff69854a avm1: Pass mouse events down to movie clips 2019-12-16 10:11:23 -08:00
Nathan Adams c8e42123cf avm1: Implemented `_xmouse` and `_ymouse` 2019-12-16 10:11:23 -08:00
Mike Welsh eb3aa1c878 core: Move `ClipAction` into crate::events 2019-12-15 19:22:23 -08:00
Mike Welsh 76e94dda1c core: Implement "unload" clip event
Fire unload clip event when a movie clip is removed. Added
`ActionType` enum used by `ActionQueue::queue_actions` that
determines the type of action that is running (replaces `is_init`
parameter).
2019-12-15 19:00:16 -08:00
Mike Welsh 38ebdd9d05 core: Fire "load" and "enterFrame" clip events
MovieClips will now fire their "load" and "enterFrame" clip events.
Added `MovieClipFlags` to store various flags for the movie clip.
2019-12-15 19:00:16 -08:00
Mike Welsh 3c83d9ac9d docs: Shuffle some docs in DisplayObject 2019-12-15 10:17:33 -08:00
Mike Welsh d7393dc81d core: Add DisplayObjectFlags::TransformedByScript
This is set when a DisplayObject is dynamically moved by AS code,
which causes further modification from PlaceObject tags to be
ignored.
2019-12-15 10:17:33 -08:00
Mike Welsh 8c27097240 core: Implement _target property
Add DisplayObject::slash_path to get the Flash 4-style slash path
to the clip. This fixes the tellTarget regression test and removes
the superfluous `target_path` from `UpdateContext`.
2019-12-15 10:17:33 -08:00
Mike Welsh c9864eb557 core: Add StageObject properties 2019-12-15 10:17:33 -08:00
Mike Welsh 783ede6f79 core: Add DisplayObject::path 2019-12-15 08:54:26 -08:00
Mike Welsh 73604a891e core: Move get_child_by_name to DisplayObject 2019-12-15 08:54:26 -08:00
Mike Welsh 71e4eb87d7 core: Remove as_*_mut methods on DisplayObject/Object 2019-12-10 01:36:02 -08:00
Mike Welsh 30ecbd0ecc core: Use enum_trait_object for DisplayObject 2019-12-10 01:36:01 -08:00
Mike Welsh 23ca66a7e3 avm1: Use enum_trait_object for avm1::Object 2019-12-10 01:36:01 -08:00
David Wendt d25bdbacf8 Separate `Object` into an interface trait and a standard implementation. Host object implementations may bypass `ScriptObject` and directly interface with the AVM using this trait.
Note that host objects that do so will *not* have access to their standard representation from within member functions - you will need to extend the interface to accomodate for them. This is due to long-standing limitations with type IDs and downcasting with types that bear lifetimes - it's entirely an unsafe operation and exposing such a facility to safe Rust is unsound. However, this will at least let us separate out several things from ScriptObject that don't need to be there for the time being.
2019-11-26 14:51:05 -05:00
David Wendt 2f965d1c64 First stab at moving system builtins to explicit prototypes 2019-11-26 14:51:03 -05:00
Nathan Adams ae064b62be chore: Change to no_drop from empty_drop for new gc-arena 2019-11-22 17:53:05 +00:00
Mike Welsh 01f47d675c core: Move UpdateContext into context submodule 2019-10-27 13:49:47 -07:00
Mike Welsh c4c895c6c9 core: Move display objects to display_object module 2019-10-26 15:04:52 -07:00