This matches the Context3D docs. Calling 'present' swaps
the buffers.
I wasn't certain if we actually need a double-buffered depth
texture, but I included one just to be safe.
Now that most of the complicated Context3D methods have been
implemented, we can simplify the overall design. Instead of queueing
up commands and having `present` execute them in a loop, we
can execute each command immediately. The key insight is that
a `RenderPass` is only needed for `DrawTriangles`, so we don't
have to store it in `Context3D` and deal with complicated lifetime
issues.
The old behavior gave us implicit double-buffering behavior,
since nothing would get rendered until a 'present' call.
Now that a 'drawTriangles' call will immediately submit
a draw command, we need to implement actual double buffering.
This is done in the next commit.
The `Avm2::{dispatch, broadcast}_event` methods now log and swallow any
AVM2 error occuring during the dispatch, instead of repeating the
handling code for each caller.
This also introduces some behavioral changes:
- Errors messages are more consistent;
- For consistency with `broadcast_event`, `dispatch_event` panics if
given a non-event object to dispatch.
When we were using a fork of quick-xml, we modified the actual
unescape method. Now that we're using the crates.io release again,
we need to go through our `custom_unescape` function.
If a SWF contains multiple DefineFont tags with the same
font name (but different font IDs), the first tag will win
when a font is looked up by *name*. This affects the behavior
of EditText objects, which can have embedded HTML like
`<font face="MyFontName">` which performs a font lookup by name.
This fixes Fancy Pants World 4 Part 3, which contains two
DefineFont3 tags with the name FancyFont. The second font is
missing many glyphs, so using it causes us to be unable to
render the squiggle and life count text.
These functions are intentionally no-ops in Ruffle because it has
no concept of a player dirty region, so unmark them as stubs.
The only observable difference is that Flash Player will sometimes
not re-render a `Bitmap` instance on the stage immediately if it's
`BitmapData` is locked and changed, but this is only temporary and
depends on the redraw behavior of the Flash Player.
* `global_to_local` returns `None` if the object has zero scale.
* Adjust AVM `globalToLocal` methods to return the untransformed
point on failure.
* Add `DisplayObject::mouse_to_local` to handle AVM `mouseX`
and `mouseY` coordinates. For zero scale objects, these end up
returning values based on the twips-to-pixels scale,
divided by 20.
* Add `Matrix::determinant`.
* Rename `Matrix::invert` to `inverse`.
* `Matrix::inverse` return an `Option`, with `None` returned
for non-invertible matrices.
* AMV `Matrix::invert` duplicates the code as the behavior is
different (works in f64 and not twips, etc.)
I've moved our special entity handling logic into
a `custom_unescape` function. This lets us move off
of our fork of `quick-xml` back onto the crates.io release
When we receieve a nonzero 'antiAlias' parameter, we create
create a non-multisampled resolve buffer to use with WGPU.
Several tests were already requesting antialiasing, so their
output images are now anti-aliased without any changes to
the tests themselves.
Previously, the `ApplicationDomain` constructor ignored its argument,
instead of constructing a new domain with the specified domain as
the parent.
Additionally, we were incorrectly executing code with
`Activation::from_nothing` in several places, causing
`ApplicationDomain.currentDomain` to return the system domain
instead of the correct parent domain. I've introduced a new method
`Activation::from_domain`, which allows explicitly passing in the
domain. Internally, we now store an `Option<Domain>`, and panic
when calling `caller_domain` with a `None` domain. Several places
in the codebase have been adjusted to pass in the correct domain.
If you use a `Loader` to load an SWF containing a class that shadows
an already-defined class, the class definition from the Loader SWF
will be ignoredin favor of the already-defined class. This commit
applies this log to symbol classes as well - the symbol registry for the class
should continue to point to the existing MovieClip in the parent.
This results in the child SWF instantiating the class from the parent
SWF when the child places the affected movie clip on the timeline.
This fixes a bug in Fancy Pants World 4 Part 3, where the sub-level
SWF was replacing the symbol class entry for the parent 'shipInteract'
class with the dummy clip provided in the sub-level SWF (instead
of continuing to use the correct clip from the parent SWF).
Instead of queueing up these events in the `Activation`,
we can fire them immediately by making `AudioManager::update_sounds`
a freestanding method that takes in an `UpdateContext`
Avoid panic in ChildContainer.replace_at_depth() panic when previous child is not in render list.
---------
Co-authored-by: Gleb Piskunov <emgfc@ya.ru>
Previously, we were scaling down the source image to fit into
the smaller sourceRect, instead of cropping at the original scale.
This broke the background textures in Fancy Pants World 4 Part 2,
as the scaled-down output image resulted in a smaller rectangle
being returned from 'getColorBoundsRect'
We now crop the image by properly constructing the UV-coordinate
transformation matrix. We were also using the wrong value for the
'destPoint' y coordinate, which I fixed.
This slightly changes the image output of two tests - the new images
now more closely match the Flash output.
So far this just sticks the stream into the playback list and kicks off a download; we do not actually support decoding, seeking, or any of the other things that we expect `play` to do.
Calling `StreamManager::tick` advances all streams to the appropriate time. This is an unlocked timestep to support things like non-stage-FPS video and the like.