diff --git a/core/src/avm1/globals.rs b/core/src/avm1/globals.rs index d34bc0903..5e2f6c446 100644 --- a/core/src/avm1/globals.rs +++ b/core/src/avm1/globals.rs @@ -11,6 +11,7 @@ use std::f64; mod array; pub(crate) mod as_broadcaster; +mod bevel_filter; mod bitmap_filter; mod blur_filter; pub(crate) mod boolean; @@ -341,6 +342,8 @@ pub struct SystemPrototypes<'gc> { pub bitmap_filter_constructor: Object<'gc>, pub blur_filter: Object<'gc>, pub blur_filter_constructor: Object<'gc>, + pub bevel_filter: Object<'gc>, + pub bevel_filter_constructor: Object<'gc>, pub date: Object<'gc>, } @@ -550,6 +553,15 @@ pub fn create_globals<'gc>( blur_filter_proto, ); + let bevel_filter_proto = + bevel_filter::create_proto(gc_context, bitmap_filter_proto, function_proto); + let bevel_filter = FunctionObject::constructor( + gc_context, + Executable::Native(bevel_filter::constructor), + Some(function_proto), + bevel_filter_proto, + ); + filters.define_value( gc_context, "BitmapFilter", @@ -562,6 +574,12 @@ pub fn create_globals<'gc>( blur_filter.into(), EnumSet::empty(), ); + filters.define_value( + gc_context, + "BevelFilter", + bevel_filter.into(), + EnumSet::empty(), + ); let external = ScriptObject::object(gc_context, Some(object_proto)); let external_interface = external_interface::create_external_interface_object( @@ -835,6 +853,8 @@ pub fn create_globals<'gc>( bitmap_filter_constructor: bitmap_filter, blur_filter: blur_filter_proto, blur_filter_constructor: blur_filter, + bevel_filter: bevel_filter_proto, + bevel_filter_constructor: bevel_filter, date: date_proto, }, globals.into(), diff --git a/core/src/avm1/globals/bevel_filter.rs b/core/src/avm1/globals/bevel_filter.rs new file mode 100644 index 000000000..06e138009 --- /dev/null +++ b/core/src/avm1/globals/bevel_filter.rs @@ -0,0 +1,614 @@ +//! flash.filter.BevelFilter object + +use crate::avm1::activation::Activation; +use crate::avm1::error::Error; +use crate::avm1::function::{Executable, FunctionObject}; +use crate::avm1::object::bevel_filter::{BevelFilterType, BevelFilterObject}; +use crate::avm1::{AvmString, Object, TObject, Value}; +use enumset::EnumSet; +use gc_arena::MutationContext; + +pub fn constructor<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Object<'gc>, + args: &[Value<'gc>], +) -> Result, Error<'gc>> { + let distance = args + .get(0) + .unwrap_or(&4.into()) + .coerce_to_f64(activation) + .map(|x| x.max(0.0).min(255.0))?; + + let angle = args + .get(1) + .unwrap_or(&45.0.into()) + .coerce_to_f64(activation) + .map(|x| x.max(0.0).min(360.0))?; + + //TODO: range + let highlight_color = args + .get(2) + .unwrap_or(&0x000000.into()) + .coerce_to_i32(activation)?; + + let highlight_alpha = args + .get(3) + .unwrap_or(&1.into()) + .coerce_to_f64(activation) + .map(|x| x.max(0.0).min(1.0))?; + + //TODO: range + let shadow_color = args + .get(4) + .unwrap_or(&0x000000.into()) + .coerce_to_i32(activation)?; + + let shadow_alpha = args + .get(5) + .unwrap_or(&1.into()) + .coerce_to_f64(activation) + .map(|x| x.max(0.0).min(1.0))?; + + let blur_x = args + .get(6) + .unwrap_or(&4.into()) + .coerce_to_f64(activation) + .map(|x| x.max(0.0).min(255.0))?; + + let blur_y = args + .get(7) + .unwrap_or(&4.into()) + .coerce_to_f64(activation) + .map(|x| x.max(0.0).min(255.0))?; + + let strength = args + .get(8) + .unwrap_or(&1.into()) + .coerce_to_f64(activation) + .map(|x| x.max(0.0).min(255.0))?; + + let quality = args + .get(9) + .unwrap_or(&1.into()) + .coerce_to_i32(activation) + .map(|x| x.max(0).min(15))?; + + let type_: BevelFilterType = args + .get(10) + .unwrap_or(&"inner".into()) + .coerce_to_string(activation) + .map(|v| v.as_str().into())?; + + let knockout = args + .get(11) + .unwrap_or(&false.into()) + .as_bool(activation.current_swf_version()); + + let bevel_filter = this.as_bevel_filter_object().unwrap(); + + bevel_filter.set_distance(activation.context.gc_context, distance); + bevel_filter.set_angle(activation.context.gc_context, angle); + bevel_filter.set_highlight_color(activation.context.gc_context, highlight_color); + bevel_filter.set_highlight_alpha(activation.context.gc_context, highlight_alpha); + bevel_filter.set_shadow_color(activation.context.gc_context, shadow_color); + bevel_filter.set_shadow_alpha(activation.context.gc_context, shadow_alpha); + bevel_filter.set_blur_x(activation.context.gc_context, blur_x); + bevel_filter.set_blur_y(activation.context.gc_context, blur_y); + bevel_filter.set_strength(activation.context.gc_context, strength); + bevel_filter.set_quality(activation.context.gc_context, quality); + bevel_filter.set_type(activation.context.gc_context, type_); + bevel_filter.set_knockout(activation.context.gc_context, knockout); + + Ok(Value::Undefined) +} + +pub fn clone<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Object<'gc>, + args: &[Value<'gc>], +) -> Result, Error<'gc>> { + Ok(Value::Undefined) +} + +pub fn get_distance<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Object<'gc>, + args: &[Value<'gc>], +) -> Result, Error<'gc>> { + Ok(this.as_bevel_filter_object().unwrap().get_distance().into()) +} + +//TODO: check if int? +pub fn set_distance<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Object<'gc>, + args: &[Value<'gc>], +) -> Result, Error<'gc>> { + let distance = args + .get(0) + .unwrap_or(&4.0.into()) + .coerce_to_f64(activation)?; + + this.as_bevel_filter_object() + .unwrap() + .set_distance(activation.context.gc_context, distance); + + Ok(Value::Undefined) +} + +pub fn get_angle<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Object<'gc>, + args: &[Value<'gc>], +) -> Result, Error<'gc>> { + Ok(this.as_bevel_filter_object().unwrap().get_angle().into()) +} + +pub fn set_angle<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Object<'gc>, + args: &[Value<'gc>], +) -> Result, Error<'gc>> { + let angle = args + .get(0) + .unwrap_or(&45.0.into()) + .coerce_to_f64(activation) + .map(|x| x.max(0.0).min(360.0))?; + + this.as_bevel_filter_object() + .unwrap() + .set_angle(activation.context.gc_context, angle); + + Ok(Value::Undefined) +} + +pub fn get_highlight_color<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Object<'gc>, + args: &[Value<'gc>], +) -> Result, Error<'gc>> { + Ok(this + .as_bevel_filter_object() + .unwrap() + .get_highlight_color() + .into()) +} + +pub fn set_highlight_color<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Object<'gc>, + args: &[Value<'gc>], +) -> Result, Error<'gc>> { + let color = args + .get(0) + .unwrap_or(&0x000000.into()) + .coerce_to_i32(activation) + .map(|x| x.max(0x000000).min(0xFFFFFF))?; + + this.as_bevel_filter_object() + .unwrap() + .set_highlight_color(activation.context.gc_context, color); + + Ok(Value::Undefined)} + +pub fn get_highlight_alpha<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Object<'gc>, + args: &[Value<'gc>], +) -> Result, Error<'gc>> { + Ok(this + .as_bevel_filter_object() + .unwrap() + .get_highlight_alpha() + .into()) +} + +pub fn set_highlight_alpha<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Object<'gc>, + args: &[Value<'gc>], +) -> Result, Error<'gc>> { + let highlight_alpha = args + .get(0) + .unwrap_or(&1.into()) + .coerce_to_f64(activation) + .map(|x| x.max(0.0).min(1.0))?; + + this.as_bevel_filter_object() + .unwrap() + .set_highlight_alpha(activation.context.gc_context, highlight_alpha); + + Ok(Value::Undefined) +} + +pub fn get_shadow_color<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Object<'gc>, + args: &[Value<'gc>], +) -> Result, Error<'gc>> { + Ok(this + .as_bevel_filter_object() + .unwrap() + .get_shadow_color() + .into()) +} + +pub fn set_shadow_color<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Object<'gc>, + args: &[Value<'gc>], +) -> Result, Error<'gc>> { + Ok(Value::Undefined) +} + +pub fn get_shadow_alpha<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Object<'gc>, + args: &[Value<'gc>], +) -> Result, Error<'gc>> { + Ok(this + .as_bevel_filter_object() + .unwrap() + .get_shadow_alpha() + .into()) +} + +pub fn set_shadow_alpha<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Object<'gc>, + args: &[Value<'gc>], +) -> Result, Error<'gc>> { + Ok(Value::Undefined) +} + +pub fn get_quality<'gc>( + _activation: &mut Activation<'_, 'gc, '_>, + this: Object<'gc>, + args: &[Value<'gc>], +) -> Result, Error<'gc>> { + Ok(this.as_bevel_filter_object().unwrap().get_quality().into()) +} + +pub fn set_quality<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Object<'gc>, + args: &[Value<'gc>], +) -> Result, Error<'gc>> { + let blur_y = args + .get(0) + .unwrap_or(&Value::Undefined) + .coerce_to_i32(activation) + .map(|x| x.max(0).min(15))?; + + this.as_bevel_filter_object() + .unwrap() + .set_quality(activation.context.gc_context, blur_y); + + Ok(Value::Undefined) +} + +pub fn get_strength<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Object<'gc>, + args: &[Value<'gc>], +) -> Result, Error<'gc>> { + Ok(Value::Undefined) +} + +pub fn set_strength<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Object<'gc>, + args: &[Value<'gc>], +) -> Result, Error<'gc>> { + Ok(Value::Undefined) +} + +pub fn get_knockout<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Object<'gc>, + args: &[Value<'gc>], +) -> Result, Error<'gc>> { + Ok(Value::Undefined) +} + +pub fn set_knockout<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Object<'gc>, + args: &[Value<'gc>], +) -> Result, Error<'gc>> { + Ok(Value::Undefined) +} + +pub fn get_blur_x<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Object<'gc>, + args: &[Value<'gc>], +) -> Result, Error<'gc>> { + Ok(this.as_bevel_filter_object().unwrap().get_blur_x().into()) +} + +pub fn set_blur_x<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Object<'gc>, + args: &[Value<'gc>], +) -> Result, Error<'gc>> { + let blur_x = args + .get(0) + .unwrap_or(&Value::Undefined) + .coerce_to_f64(activation) + .map(|x| x.max(0.0).min(255.0))?; + + this.as_bevel_filter_object() + .unwrap() + .set_blur_x(activation.context.gc_context, blur_x); + + Ok(Value::Undefined) +} + +pub fn get_blur_y<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Object<'gc>, + args: &[Value<'gc>], +) -> Result, Error<'gc>> { + Ok(this.as_bevel_filter_object().unwrap().get_blur_y().into()) +} + +pub fn set_blur_y<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Object<'gc>, + args: &[Value<'gc>], +) -> Result, Error<'gc>> { + let blur_y = args + .get(0) + .unwrap_or(&Value::Undefined) + .coerce_to_f64(activation) + .map(|x| x.max(0.0).min(255.0))?; + + this.as_bevel_filter_object() + .unwrap() + .set_blur_y(activation.context.gc_context, blur_y); + + Ok(Value::Undefined) +} + +pub fn get_type<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Object<'gc>, + args: &[Value<'gc>], +) -> Result, Error<'gc>> { + let type_: &str = this.as_bevel_filter_object().unwrap().get_type().into(); + Ok(AvmString::new(activation.context.gc_context, type_.to_string()).into()) +} + +pub fn set_type<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Object<'gc>, + args: &[Value<'gc>], +) -> Result, Error<'gc>> { + let type_: BevelFilterType = args + .get(0) + .unwrap_or(&Value::String(AvmString::new(activation.context.gc_context, "full".to_string()))) + .coerce_to_string(activation) + .map(|s| s.as_str().into())?; + + this.as_bevel_filter_object() + .unwrap() + .set_type(activation.context.gc_context, type_); + Ok(Value::Undefined) +} + +pub fn create_proto<'gc>( + gc_context: MutationContext<'gc, '_>, + proto: Object<'gc>, + fn_proto: Object<'gc>, +) -> Object<'gc> { + let object = BevelFilterObject::empty_object(gc_context, Some(proto)); + let mut script_object = object.as_script_object().unwrap(); + + script_object.force_set_function("clone", clone, gc_context, EnumSet::empty(), Some(proto)); + script_object.add_property( + gc_context, + "distance", + FunctionObject::function( + gc_context, + Executable::Native(get_distance), + Some(fn_proto), + fn_proto, + ), + Some(FunctionObject::function( + gc_context, + Executable::Native(set_distance), + Some(fn_proto), + fn_proto, + )), + EnumSet::empty(), + ); + script_object.add_property( + gc_context, + "angle", + FunctionObject::function( + gc_context, + Executable::Native(get_angle), + Some(fn_proto), + fn_proto, + ), + Some(FunctionObject::function( + gc_context, + Executable::Native(set_angle), + Some(fn_proto), + fn_proto, + )), + EnumSet::empty(), + ); + script_object.add_property( + gc_context, + "highlightColor", + FunctionObject::function( + gc_context, + Executable::Native(get_highlight_color), + Some(fn_proto), + fn_proto, + ), + Some(FunctionObject::function( + gc_context, + Executable::Native(set_highlight_color), + Some(fn_proto), + fn_proto, + )), + EnumSet::empty(), + ); + script_object.add_property( + gc_context, + "highlightAlpha", + FunctionObject::function( + gc_context, + Executable::Native(get_highlight_alpha), + Some(fn_proto), + fn_proto, + ), + Some(FunctionObject::function( + gc_context, + Executable::Native(set_highlight_alpha), + Some(fn_proto), + fn_proto, + )), + EnumSet::empty(), + ); + script_object.add_property( + gc_context, + "shadowColor", + FunctionObject::function( + gc_context, + Executable::Native(get_shadow_color), + Some(fn_proto), + fn_proto, + ), + Some(FunctionObject::function( + gc_context, + Executable::Native(set_shadow_color), + Some(fn_proto), + fn_proto, + )), + EnumSet::empty(), + ); + script_object.add_property( + gc_context, + "shadowAlpha", + FunctionObject::function( + gc_context, + Executable::Native(get_shadow_alpha), + Some(fn_proto), + fn_proto, + ), + Some(FunctionObject::function( + gc_context, + Executable::Native(set_shadow_alpha), + Some(fn_proto), + fn_proto, + )), + EnumSet::empty(), + ); + script_object.add_property( + gc_context, + "quality", + FunctionObject::function( + gc_context, + Executable::Native(get_quality), + Some(fn_proto), + fn_proto, + ), + Some(FunctionObject::function( + gc_context, + Executable::Native(set_quality), + Some(fn_proto), + fn_proto, + )), + EnumSet::empty(), + ); + script_object.add_property( + gc_context, + "strength", + FunctionObject::function( + gc_context, + Executable::Native(get_strength), + Some(fn_proto), + fn_proto, + ), + Some(FunctionObject::function( + gc_context, + Executable::Native(set_strength), + Some(fn_proto), + fn_proto, + )), + EnumSet::empty(), + ); + script_object.add_property( + gc_context, + "knockout", + FunctionObject::function( + gc_context, + Executable::Native(get_knockout), + Some(fn_proto), + fn_proto, + ), + Some(FunctionObject::function( + gc_context, + Executable::Native(set_knockout), + Some(fn_proto), + fn_proto, + )), + EnumSet::empty(), + ); + script_object.add_property( + gc_context, + "blurX", + FunctionObject::function( + gc_context, + Executable::Native(get_blur_x), + Some(fn_proto), + fn_proto, + ), + Some(FunctionObject::function( + gc_context, + Executable::Native(set_blur_x), + Some(fn_proto), + fn_proto, + )), + EnumSet::empty(), + ); + script_object.add_property( + gc_context, + "blurY", + FunctionObject::function( + gc_context, + Executable::Native(get_blur_y), + Some(fn_proto), + fn_proto, + ), + Some(FunctionObject::function( + gc_context, + Executable::Native(set_blur_y), + Some(fn_proto), + fn_proto, + )), + EnumSet::empty(), + ); + script_object.add_property( + gc_context, + "type", + FunctionObject::function( + gc_context, + Executable::Native(get_type), + Some(fn_proto), + fn_proto, + ), + Some(FunctionObject::function( + gc_context, + Executable::Native(set_type), + Some(fn_proto), + fn_proto, + )), + EnumSet::empty(), + ); + script_object.into() +} diff --git a/core/src/avm1/object.rs b/core/src/avm1/object.rs index 094995663..571e19305 100644 --- a/core/src/avm1/object.rs +++ b/core/src/avm1/object.rs @@ -8,6 +8,7 @@ use crate::avm1::object::value_object::ValueObject; use crate::avm1::property::Attribute; use crate::avm1::activation::Activation; +use crate::avm1::object::bevel_filter::BevelFilterObject; use crate::avm1::object::blur_filter::BlurFilterObject; use crate::avm1::object::color_transform_object::ColorTransformObject; use crate::avm1::object::date_object::DateObject; @@ -25,6 +26,7 @@ use ruffle_macros::enum_trait_object; use std::borrow::Cow; use std::fmt::Debug; +pub mod bevel_filter; pub mod blur_filter; pub mod color_transform_object; mod custom_object; @@ -59,6 +61,7 @@ pub mod xml_object; ColorTransformObject(ColorTransformObject<'gc>), TransformObject(TransformObject<'gc>), BlurFilterObject(BlurFilterObject<'gc>), + BevelFilterObject(BevelFilterObject<'gc>), DateObject(DateObject<'gc>), } )] @@ -441,6 +444,11 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into> + Clone + Copy None } + /// Get the underlying `BevelFilterObject`, if it exists + fn as_bevel_filter_object(&self) -> Option> { + None + } + fn as_ptr(&self) -> *const ObjectPtr; /// Check if this object is in the prototype chain of the specified test object. diff --git a/core/src/avm1/object/bevel_filter.rs b/core/src/avm1/object/bevel_filter.rs new file mode 100644 index 000000000..4e221f2d4 --- /dev/null +++ b/core/src/avm1/object/bevel_filter.rs @@ -0,0 +1,166 @@ +use crate::add_field_accessors; +use crate::avm1::error::Error; +use crate::avm1::{Object, ScriptObject, TObject, Value}; +use crate::impl_custom_object_without_set; +use gc_arena::{Collect, GcCell, MutationContext}; + +use crate::avm1::activation::Activation; +use std::fmt; + +#[derive(Copy, Clone, Debug, Collect)] +#[collect(no_drop)] +pub enum BevelFilterType { + Inner, + Outer, + Full, +} + +impl From<&str> for BevelFilterType { + fn from(value: &str) -> Self { + match value { + "inner" => BevelFilterType::Inner, + "outer" => BevelFilterType::Outer, + "full" => BevelFilterType::Full, + _ => BevelFilterType::Full, + } + } +} + +impl From for &str { + fn from(v: BevelFilterType) -> Self { + match v { + BevelFilterType::Inner => "inner", + BevelFilterType::Outer => "outer", + BevelFilterType::Full => "full", + } + } +} + +/// A BevelFilter +#[derive(Clone, Copy, Collect)] +#[collect(no_drop)] +pub struct BevelFilterObject<'gc>(GcCell<'gc, BevelFilterData<'gc>>); + +#[derive(Clone, Collect)] +#[collect(no_drop)] +pub struct BevelFilterData<'gc> { + /// The underlying script object. + base: ScriptObject<'gc>, + + //TODO: is this an int + angle: f64, + blur_x: f64, + blur_y: f64, + distance: f64, + highlight_alpha: f64, + highlight_color: i32, + knockout: bool, + quality: i32, + shadow_alpha: f64, + shadow_color: i32, + strength: f64, + type_: BevelFilterType, +} + +impl fmt::Debug for BevelFilterObject<'_> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let this = self.0.read(); + f.debug_struct("BevelFilter") + .field("angle", &this.angle) + .field("blurX", &this.blur_x) + .field("blurY", &this.blur_y) + .field("distance", &this.distance) + .field("highlightAlpha", &this.highlight_alpha) + .field("highlightColor", &this.highlight_color) + .field("knockout", &this.knockout) + .field("quality", &this.quality) + .field("shadowAlpha", &this.shadow_alpha) + .field("strength", &this.strength) + .field("type", &this.type_) + .finish() + } +} + +impl<'gc> BevelFilterObject<'gc> { + add_field_accessors!( + [set_angle, get_angle, angle, f64], + [set_blur_x, get_blur_x, blur_x, f64], + [set_blur_y, get_blur_y, blur_y, f64], + [set_distance, get_distance, distance, f64], + [ + set_highlight_alpha, + get_highlight_alpha, + highlight_alpha, + f64 + ], + [ + set_highlight_color, + get_highlight_color, + highlight_color, + i32 + ], + [set_knockout, get_knockout, knockout, bool], + [set_quality, get_quality, quality, i32], + [set_shadow_alpha, get_shadow_alpha, shadow_alpha, f64], + [set_shadow_color, get_shadow_color, shadow_color, i32], + [set_strength, get_strength, strength, f64], + [set_type, get_type, type_, BevelFilterType], //TODO: type + ); + + pub fn empty_object(gc_context: MutationContext<'gc, '_>, proto: Option>) -> Self { + BevelFilterObject(GcCell::allocate( + gc_context, + BevelFilterData { + base: ScriptObject::object(gc_context, proto), + angle: 45.0, + blur_x: 4.0, + blur_y: 4.0, + distance: 4.0, // TODO: check if int + highlight_alpha: 1.0, + highlight_color: 0xFFFFFF.into(), //TODO: int? + knockout: false, + quality: 1, //TODO: must be int!! + shadow_alpha: 1.0, + shadow_color: 0x000000.into(), //TODO: is int? + strength: 1.0, // Int? + type_: BevelFilterType::Inner, + }, + )) + } +} + +impl<'gc> TObject<'gc> for BevelFilterObject<'gc> { + impl_custom_object_without_set!(base); + + fn set( + &self, + name: &str, + value: Value<'gc>, + activation: &mut Activation<'_, 'gc, '_>, + ) -> Result<(), Error<'gc>> { + let base = self.0.read().base; + base.internal_set( + name, + value, + activation, + (*self).into(), + Some(activation.context.avm1.prototypes.bevel_filter), + ) + } + + fn as_bevel_filter_object(&self) -> Option> { + Some(*self) + } + + fn create_bare_object( + &self, + activation: &mut Activation<'_, 'gc, '_>, + _this: Object<'gc>, + ) -> Result, Error<'gc>> { + Ok(BevelFilterObject::empty_object( + activation.context.gc_context, + Some(activation.context.avm1.prototypes.bevel_filter), + ) + .into()) + } +} diff --git a/core/src/avm1/object/custom_object.rs b/core/src/avm1/object/custom_object.rs index cfaff36ff..682a93819 100644 --- a/core/src/avm1/object/custom_object.rs +++ b/core/src/avm1/object/custom_object.rs @@ -262,7 +262,7 @@ macro_rules! impl_custom_object { #[macro_export] macro_rules! add_field_accessors { - ($([$set_ident: ident, $get_ident: ident, $var: ident, $type_: ident],)*) => { + ($([$set_ident: ident, $get_ident: ident, $var: ident, $type_: ty],)*) => { $( pub fn $set_ident(&self, gc_context: MutationContext<'gc, '_>, v: $type_) { self.0.write(gc_context).$var = v; diff --git a/core/tests/regression_tests.rs b/core/tests/regression_tests.rs index 72293d625..6921360c4 100644 --- a/core/tests/regression_tests.rs +++ b/core/tests/regression_tests.rs @@ -277,6 +277,7 @@ swf_tests! { (date_set_utc_seconds, "avm1/date/setUTCSeconds", 1), (date_set_year, "avm1/date/setYear", 1), (this_scoping, "avm1/this_scoping", 1), + (bevel_filter, "avm1/bevel_filter", 1), (as3_hello_world, "avm2/hello_world", 1), (as3_function_call, "avm2/function_call", 1), (as3_function_call_via_call, "avm2/function_call_via_call", 1), diff --git a/core/tests/swfs/avm1/bevel_filter/output.txt b/core/tests/swfs/avm1/bevel_filter/output.txt new file mode 100644 index 000000000..707921354 --- /dev/null +++ b/core/tests/swfs/avm1/bevel_filter/output.txt @@ -0,0 +1,94 @@ +// new BevelFilter +[object Object] +// x.clone() +[object Object] +// x.clone() == x +false +// x.angle +44.9999999772279 +// x.blurX +4 +// x.blurY +4 +// x.distance +4 +// x.highlightAlpha +1 +// x.highlightColor +16777215 +// x.knockout +false +// x.quality +1 +// x.shadowAlpha +1 +// x.shadowColor +0 +// x.strength +1 +// x.type +inner +// x.angle (after set to 361) +1 +// x.blurX(after set to 100) +100 +// x.blurY(after set to 100) +100 +// x.distance (after set to 1000) +1000 +// x.highlightAlpha (after set to 1.5) +1 +// x.highlightColor (after set to 0x1000000) +0 +// x.quality(after set to 100) +15 +// x.shadowAlpha (after set to 1.5) +1 +// x.shadowColor (after set to 1.5) +1 +// x.shadowColor (after set to 0x1000000) +0 +// x.strength (after set to 256) +255 +// x.angle (after set to -1) +-1 +// x.angle (after set to -366) +-6 +// x.blurX(after set to -1) +0 +// x.blurY(after set to -1) +0 +// x.distance (after set to -1) +-1 +// x.highlightAlpha (after set to -1) +0 +// x.highlightColor (after set to -1) +16777215 +// x.quality(after set to 2.5) +2 +// x.quality(after set to -1) +0 +// x.shadowAlpha (after set to -1) +0 +// x.shadowColor (after set to -1) +16777215 +// x.strength (after set to -1) +0 +// x.type (after set to "invalid") +full +// x.type (after set to "INNER") +full +// x.type (after set to 0) +full +// oob_under.blurX +4 +// oob_under.blurY +4 +// oob_under.quality +1 +// oob_over.blurX +4 +// oob_over.blurY +4 +// oob_over.quality +1 diff --git a/core/tests/swfs/avm1/bevel_filter/test.fla b/core/tests/swfs/avm1/bevel_filter/test.fla new file mode 100644 index 000000000..fe4958926 Binary files /dev/null and b/core/tests/swfs/avm1/bevel_filter/test.fla differ diff --git a/core/tests/swfs/avm1/bevel_filter/test.swf b/core/tests/swfs/avm1/bevel_filter/test.swf new file mode 100644 index 000000000..547e5a674 Binary files /dev/null and b/core/tests/swfs/avm1/bevel_filter/test.swf differ