1use crate::string::SwfStr;
2use bitflags::bitflags;
3use std::num::NonZeroU8;
4
5#[derive(Clone, Debug, PartialEq)]
6pub enum Action<'a> {
7 Add,
8 Add2,
9 And,
10 AsciiToChar,
11 BitAnd,
12 BitLShift,
13 BitOr,
14 BitRShift,
15 BitURShift,
16 BitXor,
17 Call,
18 CallFunction,
19 CallMethod,
20 CastOp,
21 CharToAscii,
22 CloneSprite,
23 ConstantPool(ConstantPool<'a>),
24 Decrement,
25 DefineFunction(DefineFunction<'a>),
26 DefineFunction2(DefineFunction2<'a>),
27 DefineLocal,
28 DefineLocal2,
29 Delete,
30 Delete2,
31 Divide,
32 End,
33 EndDrag,
34 Enumerate,
35 Enumerate2,
36 Equals,
37 Equals2,
38 Extends,
39 GetMember,
40 GetProperty,
41 GetTime,
42 GetUrl(GetUrl<'a>),
43 GetUrl2(GetUrl2),
44 GetVariable,
45 GotoFrame(GotoFrame),
46 GotoFrame2(GotoFrame2),
47 GotoLabel(GotoLabel<'a>),
48 Greater,
49 If(If),
50 ImplementsOp,
51 Increment,
52 InitArray,
53 InitObject,
54 InstanceOf,
55 Jump(Jump),
56 Less,
57 Less2,
58 MBAsciiToChar,
59 MBCharToAscii,
60 MBStringExtract,
61 MBStringLength,
62 Modulo,
63 Multiply,
64 NewMethod,
65 NewObject,
66 NextFrame,
67 Not,
68 Or,
69 Play,
70 Pop,
71 PreviousFrame,
72 Push(Push<'a>),
73 PushDuplicate,
74 RandomNumber,
75 RemoveSprite,
76 Return,
77 SetMember,
78 SetProperty,
79 SetTarget(SetTarget<'a>),
80 SetTarget2,
81 SetVariable,
82 StackSwap,
83 StartDrag,
84 Stop,
85 StopSounds,
86 StoreRegister(StoreRegister),
87 StrictEquals,
88 StringAdd,
89 StringEquals,
90 StringExtract,
91 StringGreater,
92 StringLength,
93 StringLess,
94 Subtract,
95 TargetPath,
96 Throw,
97 ToInteger,
98 ToNumber,
99 ToString,
100 ToggleQuality,
101 Trace,
102 Try(Try<'a>),
103 TypeOf,
104 WaitForFrame(WaitForFrame),
105 WaitForFrame2(WaitForFrame2),
106 With(With<'a>),
107 Unknown(Unknown<'a>),
108}
109
110#[derive(Clone, Debug, Eq, PartialEq)]
111pub struct ConstantPool<'a> {
112 pub strings: Vec<&'a SwfStr>,
113}
114
115#[derive(Clone, Debug, Eq, PartialEq)]
116pub struct DefineFunction<'a> {
117 pub name: &'a SwfStr,
118 pub params: Vec<&'a SwfStr>,
119 pub actions: &'a [u8],
120}
121
122#[derive(Clone, Debug, Eq, PartialEq)]
123pub struct DefineFunction2<'a> {
124 pub name: &'a SwfStr,
125 pub register_count: u8,
126 pub params: Vec<FunctionParam<'a>>,
127 pub flags: FunctionFlags,
128 pub actions: &'a [u8],
129}
130
131impl<'a> From<DefineFunction<'a>> for DefineFunction2<'a> {
132 #[inline]
133 fn from(function: DefineFunction<'a>) -> Self {
134 let params = function
135 .params
136 .into_iter()
137 .map(|param| FunctionParam {
138 name: param,
139 register_index: None,
140 })
141 .collect();
142 Self {
143 name: function.name,
144 register_count: 0,
145 params,
146 flags: FunctionFlags::empty(),
147 actions: function.actions,
148 }
149 }
150}
151
152#[derive(Clone, Debug, Eq, PartialEq)]
153pub struct FunctionParam<'a> {
154 pub name: &'a SwfStr,
155 pub register_index: Option<NonZeroU8>,
156}
157
158bitflags! {
159 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
160 pub struct FunctionFlags: u16 {
161 const PRELOAD_THIS = 1 << 0;
162 const SUPPRESS_THIS = 1 << 1;
163 const PRELOAD_ARGUMENTS = 1 << 2;
164 const SUPPRESS_ARGUMENTS = 1 << 3;
165 const PRELOAD_SUPER = 1 << 4;
166 const SUPPRESS_SUPER = 1 << 5;
167 const PRELOAD_ROOT = 1 << 6;
168 const PRELOAD_PARENT = 1 << 7;
169 const PRELOAD_GLOBAL = 1 << 8;
170 }
171}
172
173#[derive(Clone, Debug, Eq, PartialEq)]
174pub struct GetUrl<'a> {
175 pub url: &'a SwfStr,
176 pub target: &'a SwfStr,
177}
178
179#[derive(Clone, Debug, Eq, PartialEq)]
180pub struct GetUrl2(pub(crate) GetUrlFlags);
181
182impl GetUrl2 {
183 #[inline]
185 pub fn for_load_movie(method: SendVarsMethod) -> Self {
186 let mut flags = Self(GetUrlFlags::LOAD_TARGET);
187 flags.set_send_vars_method(method);
188 flags
189 }
190
191 #[inline]
193 pub fn for_get_url(method: SendVarsMethod) -> Self {
194 let mut flags = Self(GetUrlFlags::empty());
195 flags.set_send_vars_method(method);
196 flags
197 }
198
199 #[inline]
201 pub fn for_load_vars(method: SendVarsMethod) -> Self {
202 let mut flags = Self(GetUrlFlags::LOAD_VARIABLES);
203 flags.set_send_vars_method(method);
204 flags
205 }
206
207 #[inline]
209 pub fn send_vars_method(&self) -> SendVarsMethod {
210 match self.0 & GetUrlFlags::METHOD_MASK {
211 GetUrlFlags::METHOD_NONE => SendVarsMethod::None,
212 GetUrlFlags::METHOD_GET => SendVarsMethod::Get,
213 GetUrlFlags::METHOD_POST => SendVarsMethod::Post,
214 _ => unreachable!(),
215 }
216 }
217
218 #[inline]
220 pub fn set_send_vars_method(&mut self, method: SendVarsMethod) {
221 self.0 -= GetUrlFlags::METHOD_MASK;
222 self.0 |= GetUrlFlags::from_bits(method as u8).unwrap();
223 }
224
225 #[inline]
227 pub fn is_target_sprite(&self) -> bool {
228 self.0.contains(GetUrlFlags::LOAD_TARGET)
229 }
230
231 #[inline]
233 pub fn is_load_vars(&self) -> bool {
234 self.0.contains(GetUrlFlags::LOAD_VARIABLES)
235 }
236}
237
238bitflags! {
239 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
241 pub(crate) struct GetUrlFlags: u8 {
242 const METHOD_NONE = 0;
243 const METHOD_GET = 1;
244 const METHOD_POST = 2;
245 const METHOD_MASK = 3;
246
247 const LOAD_TARGET = 1 << 6;
248 const LOAD_VARIABLES = 1 << 7;
249 }
250}
251
252#[derive(Clone, Copy, Debug, Eq, PartialEq)]
253#[repr(u8)]
254pub enum SendVarsMethod {
255 None = 0,
256 Get = 1,
257 Post = 2,
258}
259
260#[derive(Clone, Debug, Eq, PartialEq)]
261pub struct GotoFrame {
262 pub frame: u16,
263}
264
265#[derive(Clone, Debug, Eq, PartialEq)]
266pub struct GotoFrame2 {
267 pub set_playing: bool,
268 pub scene_offset: u16,
269}
270
271#[derive(Clone, Debug, Eq, PartialEq)]
272pub struct GotoLabel<'a> {
273 pub label: &'a SwfStr,
274}
275
276#[derive(Clone, Debug, Eq, PartialEq)]
277pub struct If {
278 pub offset: i16,
279}
280
281#[derive(Clone, Debug, Eq, PartialEq)]
282pub struct Jump {
283 pub offset: i16,
284}
285
286#[derive(Clone, Debug, PartialEq)]
287pub struct Push<'a> {
288 pub values: Vec<Value<'a>>,
289}
290
291#[derive(Clone, Debug, PartialEq)]
292pub enum Value<'a> {
293 Undefined,
294 Null,
295 Bool(bool),
296 Int(i32),
297 Float(f32),
298 Double(f64),
299 Str(&'a SwfStr),
300 Register(u8),
301 ConstantPool(u16),
302}
303
304#[derive(Clone, Debug, Eq, PartialEq)]
305pub struct SetTarget<'a> {
306 pub target: &'a SwfStr,
307}
308
309#[derive(Clone, Copy, Debug, Eq, PartialEq)]
310pub struct StoreRegister {
311 pub register: u8,
312}
313
314#[derive(Clone, Debug, Eq, PartialEq)]
315pub struct Try<'a> {
316 pub try_body: &'a [u8],
317 pub catch_body: Option<(CatchVar<'a>, &'a [u8])>,
318 pub finally_body: Option<&'a [u8]>,
319}
320
321#[derive(Clone, Debug, Eq, PartialEq)]
322pub enum CatchVar<'a> {
323 Var(&'a SwfStr),
324 Register(u8),
325}
326
327bitflags! {
328 pub struct TryFlags: u8 {
329 const CATCH_BLOCK = 1 << 0;
330 const FINALLY_BLOCK = 1 << 1;
331 const CATCH_IN_REGISTER = 1 << 2;
332 }
333}
334
335#[derive(Clone, Debug, Eq, PartialEq)]
336pub struct WaitForFrame {
337 pub frame: u16,
338 pub num_actions_to_skip: u8,
339}
340
341#[derive(Clone, Debug, Eq, PartialEq)]
342pub struct WaitForFrame2 {
343 pub num_actions_to_skip: u8,
344}
345
346#[derive(Clone, Debug, Eq, PartialEq)]
347pub struct With<'a> {
348 pub actions: &'a [u8],
349}
350
351#[derive(Clone, Debug, Eq, PartialEq)]
352pub struct Unknown<'a> {
353 pub opcode: u8,
354 pub data: &'a [u8],
355}