Skip to content

Commit e127506

Browse files
committed
pixelbender: Fix handling AVM2 parameters
1 parent 3a112e2 commit e127506

File tree

1 file changed

+114
-103
lines changed

1 file changed

+114
-103
lines changed

core/src/pixel_bender.rs

Lines changed: 114 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -34,116 +34,127 @@ impl PixelBenderTypeExt for PixelBenderType {
3434
where
3535
Self: Sized,
3636
{
37-
let is_float = matches!(
38-
kind,
39-
PixelBenderTypeOpcode::TFloat
40-
| PixelBenderTypeOpcode::TFloat2
41-
| PixelBenderTypeOpcode::TFloat3
42-
| PixelBenderTypeOpcode::TFloat4
43-
| PixelBenderTypeOpcode::TFloat2x2
44-
| PixelBenderTypeOpcode::TFloat3x3
45-
| PixelBenderTypeOpcode::TFloat4x4
46-
);
37+
fn next_val<'gc>(
38+
activation: &mut Activation<'_, 'gc>,
39+
vals: &mut impl Iterator<Item = Value<'gc>>,
40+
) -> Result<f64, Error<'gc>> {
41+
let Some(val) = vals.next() else {
42+
return Ok(0.0);
43+
};
4744

48-
match value {
49-
Value::String(s) => Ok(PixelBenderType::TString(s.to_string())),
50-
Value::Number(n) => Ok(PixelBenderType::TFloat(n as f32)),
51-
Value::Integer(i) => Ok(PixelBenderType::TInt(i as i16)),
52-
Value::Object(o) => {
53-
if let Some(array) = o.as_array_storage() {
54-
let mut vals = array.iter();
45+
val.try_as_f64()
46+
.ok_or_else(|| make_error_2004(activation, Error2004Type::ArgumentError))
47+
}
5548

56-
fn next_val<'gc>(
57-
activation: &mut Activation<'_, 'gc>,
58-
vals: &mut impl Iterator<Item = Option<Value<'gc>>>,
59-
) -> Result<f64, Error<'gc>> {
60-
let Some(Some(val)) = vals.next() else {
61-
return Ok(0.0);
62-
};
49+
let array_storage = match value {
50+
Value::Object(ref o) => o.as_array_storage(),
51+
Value::Null | Value::Undefined => None,
52+
_ => unreachable!("value should be an array"),
53+
};
6354

64-
val.try_as_f64().ok_or_else(|| {
65-
make_error_2004(activation, Error2004Type::ArgumentError)
66-
})
67-
}
55+
let mut vals: Box<dyn Iterator<Item = Value<'gc>>> = if let Some(ref array) = array_storage
56+
{
57+
Box::new(array.iter().map(|v| v.unwrap_or(Value::Integer(0))))
58+
} else {
59+
Box::new(std::iter::empty())
60+
};
6861

69-
if is_float {
70-
match kind {
71-
PixelBenderTypeOpcode::TFloat => Ok(PixelBenderType::TFloat(
72-
//
73-
next_val(activation, &mut vals)? as f32,
74-
)),
75-
PixelBenderTypeOpcode::TFloat2 => Ok(PixelBenderType::TFloat2(
76-
next_val(activation, &mut vals)? as f32,
77-
next_val(activation, &mut vals)? as f32,
78-
)),
79-
PixelBenderTypeOpcode::TFloat3 => Ok(PixelBenderType::TFloat3(
80-
next_val(activation, &mut vals)? as f32,
81-
next_val(activation, &mut vals)? as f32,
82-
next_val(activation, &mut vals)? as f32,
83-
)),
84-
PixelBenderTypeOpcode::TFloat4 => Ok(PixelBenderType::TFloat4(
85-
next_val(activation, &mut vals)? as f32,
86-
next_val(activation, &mut vals)? as f32,
87-
next_val(activation, &mut vals)? as f32,
88-
next_val(activation, &mut vals)? as f32,
89-
)),
90-
PixelBenderTypeOpcode::TFloat2x2 => Ok(PixelBenderType::TFloat2x2(
91-
// TODO use core::array::try_from_fn when it's stable
92-
(0..4)
93-
.map(|_| next_val(activation, &mut vals).map(|v| v as f32))
94-
.collect::<Result<Vec<f32>, Error<'gc>>>()?
95-
.try_into()
96-
.unwrap(),
97-
)),
98-
PixelBenderTypeOpcode::TFloat3x3 => Ok(PixelBenderType::TFloat3x3(
99-
// TODO use core::array::try_from_fn when it's stable
100-
(0..9)
101-
.map(|_| next_val(activation, &mut vals).map(|v| v as f32))
102-
.collect::<Result<Vec<f32>, Error<'gc>>>()?
103-
.try_into()
104-
.unwrap(),
105-
)),
106-
PixelBenderTypeOpcode::TFloat4x4 => Ok(PixelBenderType::TFloat4x4(
107-
// TODO use core::array::try_from_fn when it's stable
108-
(0..16)
109-
.map(|_| next_val(activation, &mut vals).map(|v| v as f32))
110-
.collect::<Result<Vec<f32>, Error<'gc>>>()?
111-
.try_into()
112-
.unwrap(),
113-
)),
114-
_ => unreachable!("Unexpected float kind {kind:?}"),
115-
}
116-
} else {
117-
match kind {
118-
PixelBenderTypeOpcode::TInt => Ok(PixelBenderType::TInt(
119-
//
120-
next_val(activation, &mut vals)? as i16,
121-
)),
122-
PixelBenderTypeOpcode::TInt2 => Ok(PixelBenderType::TInt2(
123-
next_val(activation, &mut vals)? as i16,
124-
next_val(activation, &mut vals)? as i16,
125-
)),
126-
PixelBenderTypeOpcode::TInt3 => Ok(PixelBenderType::TInt3(
127-
next_val(activation, &mut vals)? as i16,
128-
next_val(activation, &mut vals)? as i16,
129-
next_val(activation, &mut vals)? as i16,
130-
)),
131-
PixelBenderTypeOpcode::TInt4 => Ok(PixelBenderType::TInt4(
132-
next_val(activation, &mut vals)? as i16,
133-
next_val(activation, &mut vals)? as i16,
134-
next_val(activation, &mut vals)? as i16,
135-
next_val(activation, &mut vals)? as i16,
136-
)),
137-
_ => unreachable!("Unexpected int kind {kind:?}"),
138-
}
139-
}
140-
} else {
141-
panic!("Unexpected object {o:?}")
142-
}
62+
match kind {
63+
PixelBenderTypeOpcode::TFloat => Ok(PixelBenderType::TFloat(
64+
//
65+
next_val(activation, &mut vals)? as f32,
66+
)),
67+
PixelBenderTypeOpcode::TFloat2 => Ok(PixelBenderType::TFloat2(
68+
next_val(activation, &mut vals)? as f32,
69+
next_val(activation, &mut vals)? as f32,
70+
)),
71+
PixelBenderTypeOpcode::TFloat3 => Ok(PixelBenderType::TFloat3(
72+
next_val(activation, &mut vals)? as f32,
73+
next_val(activation, &mut vals)? as f32,
74+
next_val(activation, &mut vals)? as f32,
75+
)),
76+
PixelBenderTypeOpcode::TFloat4 => Ok(PixelBenderType::TFloat4(
77+
next_val(activation, &mut vals)? as f32,
78+
next_val(activation, &mut vals)? as f32,
79+
next_val(activation, &mut vals)? as f32,
80+
next_val(activation, &mut vals)? as f32,
81+
)),
82+
PixelBenderTypeOpcode::TFloat2x2 => Ok(PixelBenderType::TFloat2x2(
83+
// TODO use core::array::try_from_fn when it's stable
84+
(0..4)
85+
.map(|_| next_val(activation, &mut vals).map(|v| v as f32))
86+
.collect::<Result<Vec<f32>, Error<'gc>>>()?
87+
.try_into()
88+
.unwrap(),
89+
)),
90+
PixelBenderTypeOpcode::TFloat3x3 => Ok(PixelBenderType::TFloat3x3(
91+
// TODO use core::array::try_from_fn when it's stable
92+
(0..9)
93+
.map(|_| next_val(activation, &mut vals).map(|v| v as f32))
94+
.collect::<Result<Vec<f32>, Error<'gc>>>()?
95+
.try_into()
96+
.unwrap(),
97+
)),
98+
PixelBenderTypeOpcode::TFloat4x4 => Ok(PixelBenderType::TFloat4x4(
99+
// TODO use core::array::try_from_fn when it's stable
100+
(0..16)
101+
.map(|_| next_val(activation, &mut vals).map(|v| v as f32))
102+
.collect::<Result<Vec<f32>, Error<'gc>>>()?
103+
.try_into()
104+
.unwrap(),
105+
)),
106+
PixelBenderTypeOpcode::TInt => Ok(PixelBenderType::TInt(
107+
//
108+
next_val(activation, &mut vals)? as i16,
109+
)),
110+
PixelBenderTypeOpcode::TInt2 => Ok(PixelBenderType::TInt2(
111+
next_val(activation, &mut vals)? as i16,
112+
next_val(activation, &mut vals)? as i16,
113+
)),
114+
PixelBenderTypeOpcode::TInt3 => Ok(PixelBenderType::TInt3(
115+
next_val(activation, &mut vals)? as i16,
116+
next_val(activation, &mut vals)? as i16,
117+
next_val(activation, &mut vals)? as i16,
118+
)),
119+
PixelBenderTypeOpcode::TInt4 => Ok(PixelBenderType::TInt4(
120+
next_val(activation, &mut vals)? as i16,
121+
next_val(activation, &mut vals)? as i16,
122+
next_val(activation, &mut vals)? as i16,
123+
next_val(activation, &mut vals)? as i16,
124+
)),
125+
PixelBenderTypeOpcode::TString => Ok(PixelBenderType::TString(
126+
vals.next()
127+
.and_then(|v| v.coerce_to_string(activation).ok())
128+
.map(|s| s.to_string())
129+
.unwrap_or_default(),
130+
)),
131+
// TODO [KJ] I haven't been able to set a boolean parameter to true.
132+
// Investigate whether there's any way to do this.
133+
PixelBenderTypeOpcode::TBool => {
134+
next_val(activation, &mut vals)?;
135+
Ok(PixelBenderType::TBool(false))
136+
}
137+
PixelBenderTypeOpcode::TBool2 => {
138+
next_val(activation, &mut vals)?;
139+
next_val(activation, &mut vals)?;
140+
Ok(PixelBenderType::TBool2(false, false))
141+
}
142+
PixelBenderTypeOpcode::TBool3 => {
143+
next_val(activation, &mut vals)?;
144+
next_val(activation, &mut vals)?;
145+
next_val(activation, &mut vals)?;
146+
Ok(PixelBenderType::TBool3(false, false, false))
147+
}
148+
PixelBenderTypeOpcode::TBool4 => {
149+
next_val(activation, &mut vals)?;
150+
next_val(activation, &mut vals)?;
151+
next_val(activation, &mut vals)?;
152+
next_val(activation, &mut vals)?;
153+
Ok(PixelBenderType::TBool4(false, false, false, false))
143154
}
144-
_ => panic!("Unexpected value {value:?}"),
145155
}
146156
}
157+
147158
fn as_avm2_value<'gc>(
148159
&self,
149160
activation: &mut Activation<'_, 'gc>,

0 commit comments

Comments
 (0)