Commit Graph

432 Commits

Author SHA1 Message Date
Mike Welsh aff34a4233 core: Seed RNG with timestamp 2020-11-26 00:07:59 -08:00
relrelb 2e0509694c docs: Miscellaneous spelling corrections 2020-11-12 13:34:05 -08:00
Mike Welsh 3905837679 avm1: Fire initialize clip event
This event fires for new clips before any construct clip events.

Split the action queue up into separate priorities, giving
initialize the highest priority.
2020-11-09 10:43:18 -08:00
Mike Welsh 316bc4e920 chore: Appease clippy 2020-11-09 01:52:57 -08:00
Nathan Adams 9893972710 core: Allow typing of text in edit boxes 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
Nathan Adams a2d53df49c render: Store immutable part of wgpu rendering as a reusable object, to speed up exporting 2020-10-17 04:16:24 -07:00
David Wendt 0d1676afda avm2: Create a separate domain for each loaded movie and pull symbols out of each. 2020-10-17 03:32:09 -07:00
Nathan Adams 6d9155477c core: Add flashvars support - #312 2020-10-12 15:28:16 -07:00
Nathan Adams fd6431f724 core: Don't use std Instant as it doesn't work for web, use a wrapper 2020-10-11 13:34:15 -07:00
Nathan Adams 4abd02e2f7 core: Implement a timeout for script execution, defaulting to 15 seconds. Fixes #554 2020-10-11 13:34:15 -07:00
David Wendt 693e56dc67 core: Always instantiate a new movie's library before creating it's root movieclip. 2020-10-06 06:03:22 -07:00
David Wendt 542147d657 avm2: Run all AVM2 frame scripts on the action queue.
This is the same way that AVM1 actions run and it appears that frame scripts work exactly the same way. It fixes all outstanding bugs with movie clip navigation in AVM2 and allows me to remove a lot of weird workarounds I was writing for the old, incorrect behavior.

I'm also removing the "last run script frame" rule as `run_frame_internal` already had rules to prevent stopped clips from rerunning actions.
2020-10-06 06:03:22 -07:00
David Wendt e915a07d4f core: ABC files should resolve at the time of discovery, not on the action queue. 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
Sean-Thomas a9538f81d0 web: Renamed "prime_audio" and "suspend_audio"
Renamed "prime_audio" and "suspend_audio" to "play" and "pause" respectfully.
2020-09-29 11:05:23 -07:00
Sean-Thomas 6b54cc4311 web: Add pause method for web player
Adds a suspend_audio method to compliment prime_audio on WebAudioBackend, as well as logic in player.rs on the set_is_playing method to suspend audio when is_playing is set to false. Exposes pause method for the ruffle player in JavaScript with logic to display the play button when paused.
2020-09-29 11:05:23 -07:00
Luca Weiss d5cb396331 *: fix spelling mistakes 2020-09-19 16:17:58 -07:00
Nathan Adams 319efabb47 tests: Make tests capture trace output through new backend 2020-09-13 13:51:39 -07:00
Nathan Adams e25e03a841 core: Log to new avm_trace method where we want things to show up 2020-09-13 13:51:39 -07:00
Nathan Adams de009c7673 core: Add Log backend, for capturing trace output specific to a movie 2020-09-13 13:51:39 -07:00
Mike Welsh 86ab300ee8 core: Call post_instantiate on initial empty root (fix #946)
The `fake_root` did not have an object, which could cause the
player to panic if the SWF was not completely loaded when playing.
Calling `post_instantiate` ensures that this dummy root has an
object.
2020-09-04 11:31:04 -07:00
Nathan Adams 32de953822 core: Allow passing arguments and returning values to/from ExternalInterface 2020-09-03 18:17:44 -07:00
Nathan Adams 502ea98ed4 core: Add ability to call in to ExternalInterface callbacks from outside of the player (+ test) 2020-09-03 18:17:44 -07:00
Nathan Adams 3784f411b4 core: Add ExternalInterface::addCallback 2020-09-03 18:17:44 -07:00
Nathan Adams b66e9f8d16 avm1: Add ExternalInterface with only 'available' property right now 2020-09-03 18:17:44 -07:00
Nathan Adams 8f11141426 core: Add initial ExternalInterface structs 2020-09-03 18:17:44 -07:00
Nathan Adams 86eb6f2e50 avm1: Implement Date - #249 2020-09-02 17:12:31 -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 e8178c35a3 core: Add MouseWheel player event 2020-08-23 13:38:59 -07:00
Mike Welsh 2a84d924bb chore: Don't mutably borrow self in TDisplayObject 2020-08-22 11:56:19 -07:00
David Wendt 16d8c85d20 Load player globals as soon as possible.
We're about to massively change the initialization process, and we really don't want to create another situation where the player can get caught with it's pants down.
2020-08-10 23:35:37 -04:00
David Wendt 3585cf983b Convert our stub implementations of all non-ECMA classes into `Class`es.
This was surprisingly tricky - due to the need to look up superclasses, class trait instantiation requires an active `Activation` and `UpdateContext`. We can't get those during VM instance creation, since the player needs the VM first before it can give it a context to work with. Ergo, we have to tear the global scope initialization in two. At the first possible moment, the player calls a new `load_player_globals` method that initializes all class traits in global scope.
2020-08-10 23:16:07 -04:00
David Wendt 8ebf5405e2 Move AVM2 into the UpdateContext. 2020-08-01 15:49:29 -04:00
David Wendt bfa5f8ae35 Further compilation fixes necessary to get the refactor to compile again.
Notably, all of the `Avm1` "run stack frame" functions can no longer take a self parameter as the update context they will be getting also has that same parameter. Ergo, they're associated functions that get the moral equivalent of self from the update context.

This also introduces a new `Activation::from_stub` which creates a stub frame that runs everything on the main movie in layer 0. This significantly reduces boilerplate code elsewhere in the project.
2020-08-01 15:49:28 -04: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
David Wendt 9f76a7b964 Ensure that `Player` always has a movie in level zero, even if no movie has been queued up yet.
There is a race condition inadvertently caused by allowing movies to be fetched in slot 0: it is possible for the player to be caught mid-load without a root movie. A lot of code assumes level 0 always exists (e.g. `levels.get(0).unwrap()`), while our initialization methods assumed no Player methods would be called until the root movie is installed. This is an unreasonable assumption, as among other things users can trigger the race condition by just playing the movie too quickly.
2020-08-01 02:35:00 -07:00
Nathan Adams 2131f7860b avm1: Change Object::construct to create and return a new object, instead of requiring the caller to do that first 2020-08-01 02:33:14 -07:00
Nathan Adams 88a31cc5a9 avm1: Ensure we call movie constructors through Function::construct, not manually, to set __constructor__ 2020-08-01 02:33:14 -07:00
unknown ef4240e95d chore: Satisfy rustfmt and clippy 2020-07-29 15:24:23 -07:00
unknown 795cd72dce avm1: Broadcasting functions are now copied from AsBroadcaster 2020-07-29 15:24:23 -07:00
Nathan Adams 17344613e3 core: Lock variable dumping behind avm_debug 2020-07-27 04:13:31 -07:00
Nathan Adams f1f04e0e7a avm1: Fixed a bunch of cases where we're using _level0 instead of current object (fixes #926) 2020-07-27 01:40:28 -07:00
Mike Welsh 8ac2ad9b40
avm1: Store movie URL on load and implement _url (merge #912) 2020-07-27 01:38:28 -07:00
Mike Welsh 07122dc931 avm1: Implement Key listeners 2020-07-24 14:32:41 -07:00
David Wendt 4813942fe7 The player should always change the audio backend's framerate itself. 2020-07-23 23:02:52 -04:00
David Wendt f56d16a68d Separate player creation from root movie setup, and allow users of Ruffle to load in movies synchronously or asynchronously.
During the small period of time when a player is created but has no root movie, a temporary empty movie is installed with an assumed stage size and framerate of 550x400@12fps. This is Flash default for new projects, so it seemed appropriate. User ActionScript cannot see these values, and I'm not even sure JavaScript can, either.
2020-07-23 23:02:51 -04:00
Nathan Adams 7f7281493f core: Allow toggling avm_debug output on and off with ctrl+alt+d, defaults to off 2020-07-23 19:14:32 -07:00
David Wendt 97e005622b Invert the role of `Avm2` and it's `Activation`, similar to what was done with `Avm1` and it's `Activation`.
This also results in a far reduced role for `ReturnValue`, since I also took the liberty of removing most of it's use. Furthermore, I also made it apply equally to native and AVM2 code, which ensures all native implementations of methods don't double-borrow.

In AVM1, `ReturnValue` was actually removed entirely, because it's not needed. I attempted to do the same, but the fact that we're currently embedding `ScriptObjectData` in native objects means that we need it for virtual properties. Otherwise, virtual property implementations will see locked objects, which is bad.
2020-07-13 17:45:06 -04:00
David Wendt 3362ec09e8 chore: Clippy conformance 2020-07-13 17:45:00 -04:00
David Wendt 67744650f1 Pass the ABC name and lazy init flag to the AVM2. 2020-07-13 17:44:25 -04:00
David Wendt 560900e708 ABC files are always pre-loaded.
Frame actions are handled as syntactic sugar on top of a `MovieClip` subclass and event handlers. ABC scripts do not live on the normal timeline.
2020-07-13 17:43:23 -04:00
David Wendt 7d75255a1a Add global scope which is automatically included on all new activations. 2020-07-13 17:43:20 -04:00
David Wendt 5600ac477c Always execute any AVM2 code that may have been queued as a result of loading ABC files. 2020-07-13 17:42:45 -04:00
David Wendt b7f257e7c8 Add a path to get from the movie clip to the Avm2. 2020-07-13 17:42:43 -04:00
David Wendt a852a6939a Add an extremely trivial implementation for the AVM2 interpreter state. 2020-07-13 17:42:31 -04:00
Nathan Adams fba8ccda81 avm1: Rename Avm1String to AvmString 2020-07-13 10:12:54 -07:00
Nathan Adams ad733f2f21 avm1: Add Avm1String which wraps Gc<String> 2020-07-13 10:12:54 -07:00
Nathan Adams 016b9db3c5 avm1: Change Value::String(String) to Value::String(Gc<String>) 2020-07-13 10:12:54 -07:00
Mike Welsh 3322c2d916 avm1: Implement updateAfterEvent 2020-07-10 14:38:48 -07:00
Mike Welsh 98e7da7d93 avm1: Implement setInterval 2020-07-10 14:38:48 -07:00
Nathan Adams 51321713b5 avm1: Show stack frame with the avm_debug feature 2020-07-03 17:24:20 -07:00
Nathan Adams c976cf8efb avm1: Replace action.avm() with activation.avm to help with borrow checker in next commit 2020-07-03 17:24:20 -07:00
Nathan Adams 8bc3eedc43 avm1: Rename StackFrame to Activation now that they're merged 2020-07-02 00:09:43 +02:00
Nathan Adams 987375299b avm1: Replace 'run_in_avm' with just building a StackFrame object, letting Rust borrowchecker do our stack management for us 2020-06-30 21:57:51 +02:00
Nathan Adams ec4affcf10 avm1: Use child activations when already running from another activation 2020-06-29 10:13:59 +02:00
Nathan Adams aaa082fb60 avm1: Replace run_with_stack_frame with run_in_avm 2020-06-29 10:13:57 +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
Nathan Adams 3a093dddbd avm1: Run activations immediate, not queued up for some-time-later 2020-06-29 10:07:12 +02:00
Mike Welsh 618fa11acb avm1: Implement text field variable binding 2020-06-28 18:36:10 -07:00
Mike Welsh 905f9d7ac6 core: Clear mouse down flag even if there is no hovered object 2020-06-27 23:34:19 -07:00
Mike Welsh a846d92d8c core: Don't fire rollOut events if clip is removed
Allows the inventory to work in The Room Tribute.
2020-06-27 21:24:49 -07:00
Mike Welsh 81d75c6256
text: Text formatting for EditText fields (merge #615)
First implementation of HTML parsing and formatting for text fields.
2020-06-24 23:06:11 -07:00
CUB3D f03093528c core: Add shared object cache and saving on exit
On the desktop player, shared objects will now be flushed on quit.
Attempting to retrieve an existing shared object will now return a
reference to the existing one.
2020-06-24 01:46:42 +01:00
CUB3D 0c6a7b3b4c core: Add SharedObject object type 2020-06-24 01:46:05 +01:00
CUB3D eff06d3d4d core: Add stub listener methods for SharedObject 2020-06-24 01:43:25 +01:00
CUB3D 48693e4a7a core: Add inital storage backend implementation
Currently SharedObjects are encoded and decoded from JSON via the
StorageBackend, also provided is a basic in-memory implementation
2020-06-24 01:43:23 +01:00
David Wendt 18e93b3d11 Implement tests for `wrap_line`.
These tests depend on the particulars of our default device font, Noto Sans. If this test proves to be fragile we may need to create a testing font with a locked width and kerning table...
2020-06-20 19:26:47 -04:00
Nathan Adams fc18c2fce5 core: Rename Value::as_object to Value::coerce_to_object 2020-06-19 12:48:28 -07: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 1d7e6b7e8a chore: Fix let-unit-value clippy lint 2020-06-17 11:25:06 -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 9b0881edb7 core: Set $version on root
_root has a $version property that should matches
`System.capabilites.version`. This allows Nanaca Crash to boot.
2020-06-11 10:03:29 -07:00
CUB3D 48bef91917 core: Remove clear_clipboard, format and fix tests 2020-06-09 22:41:11 +01:00
CUB3D 0f0f778830 core: Retain properties for System in the player 2020-06-09 22:41:11 +01:00
Nathan Adams da3e2bb0a0 core: `TObject::call` no longer requires you to resolve after calling it 2020-06-08 15:12:05 -07:00
Nathan Adams a121a3a4d0 core: `TObject::get` no longer requires you to resolve after retrieving it 2020-06-08 15:12:05 -07:00
Nathan Adams 4c1ce6d765 core: Print swf version on startup, and warn when we run into avm2 2020-05-30 02:48:54 -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 edcd1e6d65 core: Add keyboard shortcut to dump every variable (ctrl+alt+V, same as Flash Player) 2020-05-10 23:39:54 -07:00
Nathan Adams 601715aa19 render: Merge begin_frame and clear as they're always called together 2020-05-10 22:03:56 -07:00
Nathan Adams 47a44a5fe8 desktop: Prime window with known width/height of the movie 2020-05-04 16:07:38 -07:00
Nathan Adams 51d9f3ef36 core: Change Player::new to take in a SwfMovie, not &[u8] 2020-05-04 16:07:38 -07:00
Nathan Adams 84f6b4d06e core: Set init_object values after prototype but before constructor 2020-05-03 12:46:55 -07:00
Nathan Adams 0152f384ea core: Run any on(construct) events at the appropriate time 2020-05-03 12:46:55 -07:00
Mike Welsh f09bd8c079 core: Clean up tick/render loop
Don't call `render` from `Player::tick`; instead, require the
frontends to explicitly call `render` when they wish to redraw.
The frontend can query `Player::needs_render` to see if the stage
is dirty and needs a redraw. Update desktop and web to use this
new method.

This fits better with the newer winit event loop model, which
requires explicitly calling `request_redraw`, and should avoid
spurious renders.
2020-05-02 04:25:21 -07:00
Mike Welsh 8aa12d181f render: Remove RenderBackend::draw_pause_overlay 2020-04-27 04:45:53 -07:00
David Wendt f3b3db51cb Alter AVM1 to keep track of each function call's *base prototype*: the object from which a particular function was retrieved from.
A base prototype is only applicable in cases where a method is being called as a property on an object. Bare function calls, `apply`/`call` calls, and so on do not generate a base prototype.

We also add a convenience method, `call_method`, to all objects. This method automatically calculates the correct base prototype for a method call on an object, which is the only operation that should generate base prototypes.
2020-04-25 13:25:18 -04:00
Mike Welsh fd114959f9 core: Fix regressions from init order changes in #498
Revert to the old action queue method of popping off actions in a
loop, as new actions can be queued while iterating. Store proto
changes in a separate queue to maintain the high priority behavior.
2020-04-25 03:06:54 -07:00
Nathan Adams 330e6b40f0 core: post_instantiation should happen after properties are set, but before first frame or actions 2020-04-17 23:48:58 -07:00
Nathan Adams 9318290336 core: Execute init actions immediately, do not queue them up
Clip initializers can and will influence how the next clips are loaded, and must execute before that

This fixes #418
2020-04-17 23:48:58 -07:00
Nathan Adams fe6b79a9b7 chore: Make avm1 accessible to MovieClip::preload 2020-04-17 23:48:58 -07:00
Nathan Adams 601fcbfebd core: Queue up changes of movieclip prototypes, don't execute it immediately (but at a higher priority than normal actions) 2020-04-17 23:48:58 -07:00
Mike Welsh 4df1128c19
core: Implement Object.registerClass (merge #344)
Implement Object.registerClass
2020-03-25 18:55:49 -07:00
Nathan Adams d850443c84 avm1: Refactor to expose `avm, context` in `post_instantiate` 2020-02-29 23:05:15 +01:00
David Wendt ded7737ac0 `SwfMovie::from_data` is falliable and we should not hide those errors behind panics. 2020-02-26 18:15:01 -05:00
Mike Welsh 223edb9bc1 core: Matrix translation is in twips 2020-02-26 12:47:47 -08:00
Mike Welsh c4c02260fb core: Implement keyUp event 2020-02-26 03:48:07 -08:00
Mike Welsh 86ec2c6cb8 input: Add InputBackend::set_mouse_cursor. Change cursor on buttons
It doesn't feel like Flash without having the hand cursor display
when hovering over buttons. First pass at implementing this;
core communicates which mouse cursor to use via
`InputBackend::set_mouse_cursor`.

TODO: Hand cursor only displayed for Button display objects
currently. Movie clips should also display this when they are in
"button mode" (when a button mouse event is set on them in AVM1,
or `buttonMode` property in AVM2).
2020-02-25 02:50:26 -08:00
Mike Welsh f163afc5b4 core: Use collect to copy level pointers 2020-02-24 02:28:27 -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 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 8ef759d377 Top-level layers do not get an instance name of `_leveln`. 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 a8545ee277 Implement `onLoadInit` by pulling `LoadManager` into all clip load events. 2020-02-22 00:01:14 -05:00
David Wendt 7ff885a0de Implement `MovieClipLoader` event broadcasts for `onLoadStart`, `onLoadProgress`, `onLoadComplete`, and `onLoadError`.
Note that we do not implement `onLoadInit` yet - this requires some ability to trigger an event when another movie clip loads.
2020-02-22 00:01:14 -05:00
David Wendt d84e11ed40 Introduce a new top-level object, `LoadManager`, which is responsible for all asynchronous behavior in the program. Migrate the existing async impls to it. 2020-02-21 23:57:58 -05:00
David Wendt 2a82d21966 Change the layer list from a static array to a `BTreeMap`.
Flash allows creating layers at any 31-bit height without issue, so this should support similar limitations.
2020-02-21 23:57:57 -05:00
David Wendt 5ce499d11e Add separate libraries for each loaded movie. 2020-02-21 23:57:56 -05:00
David Wendt ed799fd2b9 Split the player up into nine layers, each of which is a separate root movie clip. 2020-02-21 23:57:55 -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
David Wendt 55149b7b7e Reference count the Player and provide a weak reference in UpdateContext.
This allows the formation of `'static` futures that can still interact with a player. Async code will need to upgrade the weak reference in order to be able to interact with the player.
2020-02-21 23:44:06 -05:00
David Wendt c1cf73ccb3 Add a public method to trigger a player update.
User-defined player updates are treated the same as if a stage frame had been run: queued actions are executed and garbage is collected.
2020-02-21 23:44:04 -05: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
Nathan Adams eedc4bbe24 core: Added Input backend, currently unimplemented, for polling user input 2019-12-21 19:08:06 -08:00
Mike Welsh d7df15989f core: Clear drag if object is removed while dragging 2019-12-21 16:28:41 -08:00
Mike Welsh 531e4d640d avm1: Implement StartDrag/EndDrag 2019-12-21 16:28:41 -08:00
Mike Welsh d459bbe010 avm1: Functions store their base clip
Functions now store their base clip (the code that contains the
executing bytecode). This is because `GotoFrame` and other actions
will execute on the clip the bytecode exists on, not on `this`.

(Note that `this.gotoAndStop` uses `GetMember` actions, which
worked correctly).

`Activation` now stores `target_clip`, and `Avm1::target_clip` and
`target_clip_or_root` grab this from the current stack frame.

Renamed `start_clip` to `base_clip` to match Flash conventions.
Removed `active_clip` as this was superfluous. Now you can use
`Avm1::target_clip_or_root`.

`UpdateContext` no longer contains `target_clip` etc.
2019-12-19 17:30:50 -08:00
Nathan Adams 5f6eea6f25 chore: Refactor system listeners into a reusable system 2019-12-18 15:15:56 -08:00
Mike Welsh 8b9aedc4c8 avm1: Fix extra stack frame in event handlers
When running an clip event handler (e.g. onEnterFrame), a stack
frame is pushed to get the property value. However, this frame
was causing an extra Undefined to be pushed on the operand stack in
`Avm1::retire_stack_frame`, which would blow out the stack.

Now this stack frame is popped after the property is resolved and
before the function is executed. The function will push its own
stack frame when it executes.
2019-12-18 13:47:01 -08:00
Mike Welsh 3ebc1ed928 avm1: Stub out Stage properties
This is a very rough stub out of Stage.width and height to get
basic V-cams to start functioning.

TODO: Implement the different stage scaling modes. We will probably
want to add a "Stage" display object to handle this.
2019-12-17 22:28:44 -08:00
Mike Welsh 0f3bad8f1b core: Wrap Font in a Gc 2019-12-17 02:48:55 -08:00
Mike Welsh b6df9fded0 core: Remove boxes from library items 2019-12-16 19:32:34 -08:00
Nathan Adams 45e497826b avm1: Implement `Mouse` listeners & events (excluding scroll) 2019-12-16 19:22:10 -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 e4af2502dc avm1: Fix mismatched action/init_action stack frames
DoAction was accidentally creating its stack frame using
Avm1::insert_stack_frame_for_init_action, causing a dummy
Undefined to be pushed and blowing out the stack.
2019-12-16 01:14:06 -08:00
Mike Welsh 46365c5702 avm1: Implement clip event method callbacks 2019-12-15 20:01:50 -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 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 783ede6f79 core: Add DisplayObject::path 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 d7740bc3ad core: Don't touch UpdateContext::active_clip in DisplayObjects
DisplayObject code no longer has to manage
UpdateContext::active_clip before calling out to children, because
each child still has access to its Gc pointer.
2019-12-10 01:36:02 -08:00
Mike Welsh 12c1bf7cf1 core: Clean up UpdateContext creation
Added Player::mutate_with_update_context, which takes a closure
and passes it an UpdateContext.
2019-12-10 01:36:01 -08:00
Mike Welsh 30ecbd0ecc core: Use enum_trait_object for DisplayObject 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 ab58c37feb core: Handle gaps between StreamSoundBlocks 2019-10-29 23:36:51 -07:00
David Wendt 6a81b5327d Implement `DoInitAction`.
This pushes an extra `undefined` onto the stack to fix underflow in AS2 interface declarations.

It is currently unknown if this is a miscompilation or if some other value is supposed to be there.

# Conflicts:
#	core/src/avm1.rs
#	core/src/avm1/object.rs
2019-10-29 11:11:25 -07:00
Mike Welsh 35be57553e desktop: Improve animation sync
The timing on desktop was causing the movie to run too slow,
causing it to get out of sync. Now it should run at the correct
speed.
2019-10-28 21:05:18 -07:00
Mike Welsh 01f47d675c core: Move UpdateContext into context submodule 2019-10-27 13:49:47 -07:00
Mike Welsh dddfb42e1e core: Merge ActionContext into UpdateContext 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
Mike Welsh 247fd3b9c6 core: Run gotos immediately
Gotos now goto the specified frames immediately as opposed to
queuing. Actions on the new frame will still be queued,
and are executed after any current actions are completed.
2019-10-26 03:35:58 -07:00
Mike Welsh e78be0f06f core: Remove avm from UpdateContext 2019-10-26 02:21:48 -07:00
Mike Welsh c718a6c8cb core: Add more properties to ActionContext
ActionContext needs to be able to call goto, so it needs access
to most of UpdateContext.

TODO: Remove ActionContext, and only have UpdateContext?
2019-10-26 02:21:46 -07:00
Mike Welsh 09fa755405 core: Make Library::device_font optional 2019-10-26 02:20:42 -07:00
Mike Welsh 57a737357b core: Remove RefMut/Ref from UpdateContext 2019-10-26 02:20:42 -07:00
Mike Welsh a4bed6c643 core: Improve execution order of AS 2019-10-26 01:52:42 -07:00
David Wendt ad17166c63 Store the player version in `Avm1` so that `current_swf_version` doesn't require the context. 2019-10-13 18:55:39 -04:00
David Wendt 911cf64cb0 Fix clippy lints 2019-10-13 17:58:21 -04:00
David Wendt 911de06584 Only version MovieClips. Unversioned display objects recursively read their parents' versions, or the default version otherwise. 2019-10-13 17:27:04 -04:00
David Wendt feaa3dd203 Add a version parameter to every DisplayObject impl 2019-10-12 10:39:52 -04:00
David Wendt 8668d47403 Add a player version parameter and expose it to AVM 2019-10-12 10:39:51 -04:00
Mike Welsh 1ab5211bfe swf: Fix compiling with lzma feature 2019-10-11 23:18:57 -07:00
Mike Welsh 800147043a swf: Try to recover from incorrect zlib streams
Some SWFs are compressed incorrectly, often with incorrect
compressed/uncompressed lengths, causing the zlib decoders
to vomit if you try to decompress them fully. However, often times
the data still decompresses all the way to the End tag, and we
still want to try to play it even if it's corrupt.
Now these errors only omit a warning, and we'll continue to run
the SWF.

Addresses #86.
2019-10-10 13:41:43 -07:00
Mike Welsh eded29ce6d text: Add dummy implementation of device text
Embed an SWF version of Noto Sans (core/assets/*) into the player.
The player will load this font and use it to render device text.

This is a quicky implementation to get dynamic device text
rendering.
2019-10-07 23:23:45 -07:00
Mike Welsh 574ede0541 avm1: Return proper root object for Avm1::root_object
Was returning start_clip instead. Also call
DisplayObject::post_instantiation for root after it's created in
Player::new.
2019-10-07 01:36:05 -07:00
Mike Welsh b6eba80ebd chore: cargo fmt 2019-10-06 14:57:43 -07:00
David Wendt ca1fb713a3 Execute actions in MovieClip scope 2019-10-06 13:02:31 -07:00
David Wendt 667b30f4b5 Add scope chains for local variable resolution. 2019-10-06 13:02:31 -07:00
David Wendt 728c3d18db Allow stack frames to hold SwfSlices, which are `Rc` already.
Functions that manipulate the stack now run inside of `with_current_reader_mut`, which calls a given function with a Reader for the current stack frame. If the stack frame still exists after that code runs, we update it's PC with the Reader's position.
2019-10-06 13:02:31 -07:00
David Wendt 617b493733 Give AVM1 the notion of a stack frame.
This necessitates the use of a copy of SWF data into the GC arena, along with unsafe (and possibly unsound) pointer manipulation to get the action reader to hold a GC pointer.
2019-10-06 13:02:30 -07:00
Mike Welsh 7b63dc05c4 core: Initial implementation of SetTarget2
Implement the SetTarget2 action, which pops the target off of the
stack, and GetProperty 11, which pushes _target.

However, our implementation of _target is not accurate yet,
because it requires dynamically building the target path. Currently
we fake it by caching the last path to tellTarget.
2019-09-17 12:51:44 -05:00
Mike Welsh 856a4c6130 core: Improve TellTarget support
The AVM1 contains an explicit "target clip" that is used for older
Flash 4-era actions. This target clip can be set to an invalid
value, at which point Play, Stop, etc. will fail silently.

For GetVariable and SetVariable, if the target is invalid,
the variables will be modified on root ("/").
2019-09-17 12:51:44 -05:00
Mike Welsh 82c1116c42 chore: cargo fmt 2019-09-16 20:37:11 -07:00
David Wendt 359d3e4780 Propagate the RNG to the action context. This lets random work. 2019-09-16 20:04:30 -07:00
David Wendt 0f9db1744b Add a backend for controlling the enclosing web browser. 2019-09-16 20:04:30 -07:00
Mike Welsh 28f0ce3c83 Mask work 2019-09-09 20:42:08 -05:00
Mike Welsh 545af9379a chore: cargo fmt pass 2019-09-06 15:19:59 -07:00
Mike Welsh 0849826c48 core: Add static data for morph shape and text 2019-09-06 15:15:34 -07:00
Nathan Adams a74d1734af Initial work on avm1 method calling, local and global variables.
This contains just enough AS1 support for early trivial loading screens to not crash (ie badgers badgers badgers)
2019-08-28 21:43:20 -05:00
Mike Welsh 6a5c5ab1df chore: Add rustfmt.toml and rustfmt pass 2019-08-26 16:38:48 -07:00
Mike Welsh c1b8978555 core: Add max frames-per-tick as sanity
Avoid running too many frames at once.
2019-08-22 13:31:24 -07:00
Mike Welsh b0eff353a9 tests: Add initial SWF tests 2019-08-22 09:54:40 -07:00
Mike Welsh dd3748a520 core: GC collect_debt each frame 2019-08-19 22:34:49 -07:00
Mike Welsh 9cbeacd7b2 core: Transform mouse coordinates from viewport to stage 2019-08-19 22:27:38 -07:00
Mike Welsh 637588fae5 core: Store view matrix in player
Player is now in charge of scaling/cropping/translating the content
to fit the viewport size supplied by the frontend.

Added backend::render::Letterbox, which stores the margin sizes
for letter/pillarboxing.
2019-08-19 22:27:38 -07:00
Mike Welsh 8be9b9089b avm1: Stub out StartDrag/EndDrag 2019-08-19 22:27:38 -07:00
Mike Welsh ff74409d20 core: Tick audio backend each frame 2019-08-19 22:27:38 -07:00
Mike Welsh 59c9385cb7 core: Collect GC debt at the end of each frame 2019-08-19 22:27:38 -07:00
Mike Welsh 0143d9716e core: Button work 2019-08-19 22:27:38 -07:00
Mike Welsh 9d962fd634 core: Improve button support 2019-08-19 22:27:38 -07:00
Mike Welsh fe086c11ff core: Store clip frame labels
Bump swf-rs revision to allow for read_frame_label calls.
Also fix read_place_object to take an explicit length.
2019-08-19 22:27:38 -07:00
Mike Welsh 49cc48d2d1 core: Run actions after a goto 2019-08-19 22:27:37 -07:00
Mike Welsh ce606cece8 core: Re-enable AVM1 2019-08-19 22:27:37 -07:00
Mike Welsh 5bba546a53 core: Add BoundingBox calculations
TODO: Add dirty flag and cache matrices.
2019-08-19 17:29:55 -07:00
Mike Welsh 2c7e3c835f core: Add parent to DisplayObjectBase 2019-08-19 17:29:55 -07:00
Mike Welsh 4666d211a7 core: Add dyn to fix Rust 1.37 warnings
Omitting dyn on trait objects now emits a warning, so add missing
dyn where necessary.
2019-08-15 13:54:20 -07:00
Mike Welsh af2287a658 desktop: Add letterbox to viewport
Add getters to Player to allow access to the type Renderer.
Letter/pillarboxes added as window resized.
2019-08-10 10:18:32 -07:00
Mike Welsh 24fc403e06 core: Make player generic over backend 2019-08-09 22:34:15 -07:00
Mike Welsh 2accd5bdd4 core: Remove audio struct 2019-08-09 16:03:13 -07:00
Mike Welsh 3edc3c3d3e web: Disable auto-play, add click-to-play 2019-08-09 14:50:20 -07:00
Mike Welsh e64e306137 Rework audio to allow for streaming decoding 2019-08-08 15:59:32 -07:00
Mike Welsh 725cdae6c5 Begin AVM1 cleanup 2019-08-08 15:58:45 -07:00
Mike Welsh ce5faefe1f Work 2019-08-08 15:57:10 -07:00
Mike Welsh 2a365288e8 Update to latest swf-rs 2019-06-17 02:59:32 -07:00
Mike Welsh 3cefeeba6a Use twips for internal calculations
Switch from pixels to twips for internal calculations. swf crate
was updated to add a Twips wrapper-type. Ruffle will use this type
internally for transforms and shapes. This fixes some precision
errors in rendering (see heroes_of_cybertron.swf) and will match
what the Flash Player does internally more closely. (e.g.
DisplayObject x and y will be quantized to 1/20 pixel units). It
is up to the renderer to convert units from twip space to pixels
when rendering.
2019-05-17 13:40:56 -07:00
Mike Welsh efe3270ce0 web: Decode streams completely on preload (for now) 2019-05-09 12:43:26 -07:00
Mike Welsh 12d6d3342b core: Switch to rust-gc 2019-05-08 18:10:43 -07:00
Mike Welsh 20844185d7 core: Set preload flag 2019-05-07 12:11:32 -07:00
Mike Welsh e6e8536672 Clean up DisplayObject traits 2019-05-07 03:34:17 -07:00
Mike Welsh 60b673986b Work 2019-05-06 23:31:34 -07:00
Mike Welsh a0c478379d Preload assets for web
Run through all definition tags to preload assets on web.
TODO: Keep track of which assets are done loading.
2019-05-05 17:35:00 -07:00
Mike Welsh 2480469c2c First pass of static text 2019-05-04 11:45:11 -07:00
Mike Welsh 1dfedae485 Add some button functionality 2019-05-03 11:44:12 -07:00
Mike Welsh 6e8082f01b Reorganized backend structure 2019-05-02 19:56:17 -07:00
Mike Welsh d6e68dd43e Add initial AVM1 implementation 2019-05-01 17:46:49 -07:00
Mike Welsh 5e88f43280 Color transforms 2019-05-01 09:55:54 -07:00
Mike Welsh ded41dffb0 work 2019-04-30 17:46:32 -07:00
Mike Welsh eb6c23d967 Work 2019-04-30 01:53:21 -07:00
Mike Welsh 663ad9f663 Work 2019-04-29 13:24:29 -07:00
Mike Welsh ed3797f28c work 2019-04-28 22:55:44 -07:00
Mike Welsh ee64cc77bc Reforactor 2019-04-27 23:08:59 -07:00