Commit Graph

502 Commits

Author SHA1 Message Date
Aaron Hill 8c91c734c3 core: Only apply 'unload' and 'removed' logic to AVM1
I've also renamed these methods to 'avm1_unload' and
'avm1_removed', to make it clear that they don't
apply to AVM2.

This was causing us to incorrectly skip mouse picks,
and remove masks.
2023-03-09 12:34:16 -06:00
relrelb 83c15b8033 render: Replace `BoundingBox` with `swf::Rectangle` 2023-03-04 21:54:23 +02:00
Nathan Adams b10d4876d3 web: Add compatibilityRules config option to disable all compatibility rules 2023-03-01 21:25:19 +01:00
Nathan Adams ef42a391f5 core: Add default_compatibility_rules as a feature, and document when we add rules 2023-03-01 21:25:19 +01:00
Nathan Adams 1aedb7ff8d core: Add CompatibilityRules struct for on-the-fly replacements for compatibility. Initially konggames -> kongregate.com rules 2023-03-01 21:25:19 +01:00
relrelb b3fd1a47c6 core: Require `SwfMovie::url` 2023-02-28 19:05:20 +02:00
relrelb cf0c32bd70 core: Remove some unused `RenderContext` fields 2023-02-28 17:48:57 +02:00
feos 871a4d053d core: add framerate to SWF load log
fixes #8531
2023-02-24 12:13:00 +02:00
nosamu 70bf0a816a core: Add options to set and force stage scale mode 2023-02-22 12:13:20 +02:00
Aaron Hill 4149913967
core: Introduce dedicated avm2 mouse picking logic (#9565)
The mouse picking behavior in AVM2 interacts in complicated
ways with `mouseEnabled` and `mouseChildren.` It's sufficiently
different from AVM1 that I decided to split the logic into separate
`mouse_pick_avm1` and `mouse_pick_avm2` methods.

The `mouseChildren` property is now fully implemented.
Additionally, the `click_block` tests now work correctly
under Ruffle.

Combined with the orphan-movie PR, this is enough to make
SteamBirds fully playable (though performance greatly degrades
over a course of a level).
2023-02-17 19:04:52 +00:00
Aaron Hill 4e0dce2efa core: Make SandboxType configurable, and set to 'remote' on web
The Newgrounds API checks `Security.sandboxType` to see if it should
run in debug mode or not (which determines whether or not medals
can actually be unlocked).

For now, desktop continues to use `localTrusted` as the default,
while web now uses `remote`. We might want to make this configurable
at some point, but this should be good enough for now (and better
match Flash's behavior).
2023-02-11 14:44:11 -06:00
golfinq 37ec94f95b Avm2: Implement Stage.invalidate 2023-02-08 17:47:21 -07:00
CUB3D 755425ebfa avm1: Delay clip removals when a child has an unload listener
When removing a clip, first check if it has an unload event listener somewhere
it's hierarchy.
If it does, enqueue the removal to happen on the next frame, by moving it to a negative depth.
2023-02-06 10:53:45 -07:00
Nathan Adams 50fd7aeff5 core: Add quality options to the context menu 2023-02-06 16:08:04 +01:00
Nathan Adams a220703618 core: Made PlayerBuilder take quality instead of setting it after the Player was made 2023-02-06 16:08:04 +01:00
Nathan Adams d8e924affc render: Add RenderBackend::set_quality method, and call it from core 2023-02-06 16:08:04 +01:00
Nathan Adams 12bd38b338 core: Changed Player::set_quality to take in a StageQuality directly 2023-02-06 16:08:04 +01:00
Nathan Adams b270d1bbd7 render: Move StageQuality from core to render 2023-02-06 16:08:04 +01:00
Nathan Adams 4a0529dedc core: Add Stub and StubCollection for tracking stubs used during a movie 2023-02-01 21:45:12 +01:00
Nathan Adams 5f72ebaef9 core: Don't call avm2 callstack method if there's no callstack 2023-01-19 00:50:56 +01:00
Moulins 3b1c981d25 Clears the AVM1 stack after executing bytecode
AVM1 bytecode may leave the operand stack unbalanced, and this will
cause a slow memory leak if the stack is never cleared.
2023-01-10 14:14:17 +01:00
CUB3D 8db909a7d4 desktop: Allow specifying player version 2023-01-10 13:13:30 +01:00
Aaron Hill 1b71e288fd Remove 'gc_context lifetime
The latest `gc-arena` makes this unnecessary - we can just
use our `'a` lifetime for `MutationContext`
2023-01-06 19:20:39 -05:00
Moulins d332a174c3 Bump `gc-arena` to current master revision
This required small changes to some Debug impls that were missed in #8964
2023-01-06 18:22:43 -05:00
Nathan Adams a7738bec69 core: Added a few simple tracing::instruments 2023-01-06 04:25:22 +01:00
Nathan Adams 13fd830e7c core: Switch from log to tracing 2023-01-06 04:25:22 +01:00
MrCheeze 71fcd383a3 avm2: Add ctrlKey, altKey, shiftKey, controlKey properties to KeyboardEvent 2023-01-04 16:27:09 -05:00
Nathan Adams 40a7bb04d6 core: Removed default impl of TDisplayObject::movie(), implement it everywhere 2023-01-04 08:20:08 +01:00
Nathan Adams ded46e20e7 render: Replace PushBlendMode/PopBlendMode with Blend 2023-01-03 03:39:13 +01:00
Adrian Wielgosik e90d595cb3 avm2: Convert SharedObject to AS3 2022-12-21 22:21:23 +01:00
Adrian Wielgosik 2bb4e2e549 core: Fix failing builds without avm_debug feature 2022-12-07 00:34:01 +01:00
Adrian Wielgosik e351f9f19b core: use ctrl+alt+f to dump DO render tree 2022-12-05 19:49:41 -07:00
Moulins 05e3e6434b avm1: Remove all allocations in `Activation::from_nothing`
This is done by:
  - using the global constant pool instead of a fresh empty one:
    - OK, as no call-site is directly executing arbitrary bytecode that
      could care about the contents of the constant pool.
  - pre-allocating the global scope object in the `Avm1` context
  - using the global scope directly instead of allocating a local scope:
    - OK, because no call-site is directly defining locals on the
      returned Activation's scope.
2022-11-23 15:50:45 -07:00
Moulins 5faba34eb2 avm1: remove 'globals' parameter from Activation::from_nothing
Across all invocations, this is always set to the global object so it
can be hard-coded inside the call.
2022-11-23 15:50:45 -07:00
Moulins 2fa3d31732 Appease Clippy on nightly 2022-11-23 22:39:45 +01:00
Adrian Wielgosik e840d1f71c core: Support AVM2 context menu (sans callbacks) 2022-11-17 22:03:54 -05:00
moulins 8cbd527e4c
avm1: Small cleanups in ActionQueue (#8486)
- Use a fixed-size array instead of a Vec for the queues
- Remove unwanted plurals in methods and types names
2022-11-06 07:39:11 +02:00
Aaron Hill 68471723b3 core: Fix clippy format string lint 2022-10-27 08:49:39 +03:00
DragonGamesStudios 84f3739ece
core: Fixed a typo in messages on pressing Ctrl+Alt+D (#8360) 2022-10-23 16:44:33 +03:00
Aaron Hill 9dd0914bda core: Add root movie URL spoofing (desktop only).
The desktop player now takes a `--spoof-url` argument, which overrides
the movie URL provided to ActionScript. This does not affect non-root
movies loaded through `Loader`.
2022-10-22 15:24:14 -05:00
David Wendt 74d77a3df0 core: Add a player setting for if movies are allowed to execute before loading finishes 2022-10-18 16:47:49 -06:00
relrelb bf0ace0b88 chore: Appease clippy 2022-10-09 13:46:28 +05:45
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 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 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 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 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 86f9ee4821 core: Add a "preload everything we know about" method 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 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 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
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 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 93607aa86e
avm2: Implement `BitmapData.draw` for `wgpu` backend (#7254)
* avm2: Implement `BitmapData.draw` for `wgpu` backend

This method requires us to have the ability to render directly to a
texture. Fortunately, the `wgpu` backend already supports this in
the form of `TextureTarget`. However, the rendering code required
some refactoring in order to avoid creating duplicate `wgpu` resources.

The current implementation blocks on copying the pixels back
from the GPU to the CPU, so that we can immediately set them in
the Ruffle `BitmapData`. This is likely very inefficient, but will
work for a first implementation.

In the future, we could explore allowing the CPU image data and GPU
texture to be out of sync, and only synchronized when explicitly
necessary (e.g. on `getPixel` or `setPixel` calls).

* Rename `with_offscreen_backend` to `render_offscreen` and use Bitmap

* Don't panic when backend doesn't implement `render_offscreen`
2022-09-06 16:38:48 -05:00
= 2b3249c9a4 core: Made core no longer depend on software video decoders 2022-09-04 17:46:58 -07:00
= 8b12185d61 video: Moved NullVideoBackend from core to video 2022-09-04 17:46:58 -07:00
= aff49cd891 video: Moved VideoBackend from core to video 2022-09-04 17:46:58 -07:00
= ddaee950f8 avm1: Removed all public access into Avm1 modules, export only what's needed 2022-09-04 12:27:29 -07:00
= 2d24ed539e avm1: Moved Avm1 struct into its own file, fixing field access as needed 2022-09-04 12:27:29 -07: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 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
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 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
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
= 67eb34fbc5 core: Remove Error from player.rs, it wasn't needed 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
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
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
Adrian Wielgosik b18329c8fe web: Allow modifying player volume via JS 2022-08-20 11:53:42 -07:00
relrelb 04b4a6cabe avm1: Rename `ScriptObject::object` to `ScriptObject::new` 2022-08-19 12:22:48 -07:00
relrelb 4d8e4111e3 core: Remove `AvmType`
Simply use `is_action_script_3()` instead.
2022-08-16 13:04:02 +03:00
Nathan Adams 824b4aa8d1 render: Moved render backend from core to render 2022-08-14 18:38:14 -07:00
Nathan Adams 760da753fb render: Moved Transform from core to render 2022-08-14 18:38:14 -07:00
Nathan Adams 7dff19b559 core: Use a fixed seed when using deterministic feature 2022-08-12 13:11:46 +03:00
Adrian Wielgosik 54f9824ce0 avm1: Update drag in stopDrag() in case it wasn't called before 2022-08-10 00:20:09 +02:00
Nathan Adams 8efd69b525 core: Track 'actions since timeout check' globally instead of per Activation 2022-08-09 20:56:18 +03:00
Adrian Wielgosik 5be7f425f0 avm2: Migrate all Events to AS, remove EventData. 2022-07-30 12:34:12 -07:00
Aaron Hill 49d1a985ca avm2: Store `LoaderInfo` object on `MovieClip` and `Stage`
Previously, we would create a fresh `LoaderInfo` object each
time the `loaderInfo` property was accessed. However, users can
add event handlers to a `LoaderInfo`, so we need to create and
store exactly one `LoaderInfo` object per movie (and stage).

To verify that we're correctly handling the storage of `LoaderInfo`,
I've implemented firing the "init" event. This required a new
`on_frame_exit` hook, so that we can properly fire the "init"
event after the "exitFrame" for the initial frame but before
the "enterFrame" of the next frame.
2022-07-27 22:38:49 -07:00
Aaron Hill b4f98190e9 avm2: Implement flash.utils.Timer and associated events
The current 'setInterval/setTimeout' implementation is
moved to 'core/src/timers.rs', and now works with both
AVM1 and AVM2 objects. The `flash.utils.Timer` class is implemented
mostly in ActionScript, with minimal modifications to the actual
Ruffle timer code.
2022-07-24 20:43:00 -07:00
relrelb f643048c1c core: Introduce `Request`
Which holds both a URL and what was `RequestOptions` formerly.
2022-07-09 09:43:42 +03:00
Aaron Hill 6d9d155b15 avm2: Use render_list instead of depth_list in most cases
The `render_list` for a container always contains all of the children
under both AVM1 and AVM2 - howver, the depth_list may not contain
some children under AVM2.

When we're not performing some AVM1-specific operation
(e.g. `getInstanceAtDepth`, or dumping out AVM1 variables),
we should be using the render list.
2022-06-11 00:59:18 +03:00
Toad06 580a499e56 core: Run `update_drag` in `Player::handle_event` 2022-05-23 19:05:35 -07:00
bbb651 cf820b4f95 desktop: Add fullscreen command line option 2022-05-20 19:51:22 -07:00
Mike Welsh f20f53f555 avm1: Grab SWF version from executing clip
Remove the `swf_version` parameter from `Activation` constructors,
because this was incorrectly using the global or root SWF version
most times.

Instead, grab the SWF version for the activation directly from the
base clip.
2022-05-07 10:25:10 -07:00
Mike Welsh 1eb06908c8 core: Make PlayerBuilder::build infallible 2022-04-29 09:14:32 -07:00
Mike Welsh 3e15ca4cad core: Use `Arc::new_cyclic` in player initialization
Co-authored-by: relrelb <relrelbachar@gmail.com>

Change `UpdateContext::player` to not be an `Option`
2022-04-29 09:14:32 -07:00
Mike Welsh ddc28310f8 core: Clean up test_utils 2022-04-29 09:14:32 -07:00
Mike Welsh f48182ef3d core: Add various settings to PlayerBuilder 2022-04-29 09:14:32 -07:00
Mike Welsh 895508a0fb core: Remove Player::new
PlayerBuilder is effectively the Player constructor.
2022-04-29 09:14:32 -07:00
Mike Welsh e1e2b1008a core: Add PlayerBuilder 2022-04-29 09:14:32 -07:00
Daniel Jacobs aa92c3c1bc core: scale_mode -> window_mode for set_window_mode 2022-04-22 19:31:23 +03:00
Mike Welsh 3305ac69c4 web: Support wmode parameter 2022-04-17 08:33:51 -07:00
relrelb 7497fb7008 core: Change `Player::set_root_movie` to accept a `SwfMovie`
Move the `Arc::new` to within the function.
2022-04-08 15:16:25 -07:00