2 * Copyright (C) 2003-2006 David Schleef <ds@schleef.org>
3 * 2005-2006 Eric Anholt <eric@anholt.net>
4 * 2006-2008 Benjamin Otte <otte@gnome.org>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301 USA
26 #include "swfdec_movie.h"
27 #include "swfdec_as_internal.h"
28 #include "swfdec_as_strings.h"
29 #include "swfdec_bitmap_data.h"
30 #include "swfdec_bitmap_movie.h"
31 #include "swfdec_bits.h"
32 #include "swfdec_debug.h"
33 #include "swfdec_decoder.h"
34 #include "swfdec_filter.h"
35 #include "swfdec_internal.h"
36 #include "swfdec_player_internal.h"
37 #include "swfdec_sandbox.h"
38 #include "swfdec_sprite.h"
39 #include "swfdec_sprite_movie.h"
40 #include "swfdec_swf_decoder.h"
41 #include "swfdec_transform_as.h"
42 #include "swfdec_resource.h"
43 #include "swfdec_utils.h"
44 #include "swfdec_as_internal.h"
46 SWFDEC_AS_NATIVE (900, 200, swfdec_sprite_movie_get_tabIndex
)
48 swfdec_sprite_movie_get_tabIndex (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
49 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
51 SWFDEC_STUB ("MovieClip.tabIndex (get)");
54 SWFDEC_AS_NATIVE (900, 201, swfdec_sprite_movie_set_tabIndex
)
56 swfdec_sprite_movie_set_tabIndex (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
57 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
59 SWFDEC_STUB ("MovieClip.tabIndex (set)");
62 SWFDEC_AS_NATIVE (900, 300, swfdec_sprite_movie_get__lockroot
)
64 swfdec_sprite_movie_get__lockroot (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
65 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
69 SWFDEC_AS_CHECK (SWFDEC_TYPE_MOVIE
, &movie
, "");
71 SWFDEC_AS_VALUE_SET_BOOLEAN (rval
, movie
->lockroot
);
74 SWFDEC_AS_NATIVE (900, 301, swfdec_sprite_movie_set__lockroot
)
76 swfdec_sprite_movie_set__lockroot (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
77 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
82 SWFDEC_AS_CHECK (SWFDEC_TYPE_MOVIE
, &movie
, "b", &lockroot
);
84 movie
->lockroot
= lockroot
;
87 SWFDEC_AS_NATIVE (900, 401, swfdec_sprite_movie_get_cacheAsBitmap
)
89 swfdec_sprite_movie_get_cacheAsBitmap (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
90 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
92 SWFDEC_STUB ("MovieClip.cacheAsBitmap (get)");
95 SWFDEC_AS_NATIVE (900, 402, swfdec_sprite_movie_set_cacheAsBitmap
)
97 swfdec_sprite_movie_set_cacheAsBitmap (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
98 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
100 SWFDEC_STUB ("MovieClip.cacheAsBitmap (set)");
103 SWFDEC_AS_NATIVE (900, 403, swfdec_sprite_movie_get_opaqueBackground
)
105 swfdec_sprite_movie_get_opaqueBackground (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
106 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
108 SWFDEC_STUB ("MovieClip.opaqueBackground (get)");
111 SWFDEC_AS_NATIVE (900, 404, swfdec_sprite_movie_set_opaqueBackground
)
113 swfdec_sprite_movie_set_opaqueBackground (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
114 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
116 SWFDEC_STUB ("MovieClip.opaqueBackground (set)");
119 SWFDEC_AS_NATIVE (900, 405, swfdec_sprite_movie_get_scrollRect
)
121 swfdec_sprite_movie_get_scrollRect (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
122 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
124 SWFDEC_STUB ("MovieClip.scrollRect (get)");
127 SWFDEC_AS_NATIVE (900, 406, swfdec_sprite_movie_set_scrollRect
)
129 swfdec_sprite_movie_set_scrollRect (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
130 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
132 SWFDEC_STUB ("MovieClip.scrollRect (set)");
135 SWFDEC_AS_NATIVE (900, 417, swfdec_sprite_movie_get_filters
)
137 swfdec_sprite_movie_get_filters (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
138 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
140 SWFDEC_STUB ("MovieClip.filters (get)");
143 SWFDEC_AS_NATIVE (900, 418, swfdec_sprite_movie_set_filters
)
145 swfdec_sprite_movie_set_filters (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
146 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
148 SwfdecAsObject
*array
;
150 SwfdecFilter
*filter
;
155 SWFDEC_AS_CHECK (SWFDEC_TYPE_MOVIE
, &movie
, "o", &array
);
157 swfdec_movie_invalidate_next (movie
);
159 swfdec_as_object_get_variable (array
, SWFDEC_AS_STR_length
, &val
);
160 length
= swfdec_as_value_to_integer (cx
, val
);
163 for (i
= 0; i
< length
; i
++) {
164 if (!swfdec_as_object_get_variable (array
,
165 swfdec_as_integer_to_string (cx
, i
), &val
) ||
166 !SWFDEC_AS_VALUE_IS_OBJECT (val
) ||
167 !SWFDEC_IS_FILTER (SWFDEC_AS_VALUE_GET_OBJECT (val
)->relay
))
169 filter
= SWFDEC_FILTER (SWFDEC_AS_VALUE_GET_OBJECT (val
)->relay
);
170 filter
= swfdec_filter_clone (filter
);
171 list
= g_slist_prepend (list
, filter
);
173 g_slist_free (movie
->filters
);
174 movie
->filters
= list
;
177 SWFDEC_AS_NATIVE (900, 419, swfdec_sprite_movie_get_transform
)
179 swfdec_sprite_movie_get_transform (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
180 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
182 SwfdecTransformAs
*trans
;
185 SWFDEC_AS_CHECK (SWFDEC_TYPE_MOVIE
, &movie
, "");
187 trans
= swfdec_transform_as_new (cx
, movie
);
188 SWFDEC_AS_VALUE_SET_OBJECT (rval
, swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (trans
)));
191 SWFDEC_AS_NATIVE (900, 420, swfdec_sprite_movie_set_transform
)
193 swfdec_sprite_movie_set_transform (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
194 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
196 SWFDEC_STUB ("MovieClip.transform (set)");
199 static const char *blend_mode_names
[] = {
200 SWFDEC_AS_STR_normal
,
202 SWFDEC_AS_STR_multiply
,
203 SWFDEC_AS_STR_screen
,
204 SWFDEC_AS_STR_lighten
,
205 SWFDEC_AS_STR_darken
,
206 SWFDEC_AS_STR_difference
,
208 SWFDEC_AS_STR_subtract
,
209 SWFDEC_AS_STR_invert
,
212 SWFDEC_AS_STR_overlay
,
213 SWFDEC_AS_STR_hardlight
215 static const gsize num_blend_mode_names
=
216 sizeof (blend_mode_names
) / sizeof (blend_mode_names
[0]);
218 SWFDEC_AS_NATIVE (900, 500, swfdec_sprite_movie_get_blendMode
)
220 swfdec_sprite_movie_get_blendMode (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
221 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
225 SWFDEC_AS_CHECK (SWFDEC_TYPE_MOVIE
, &movie
, "");
227 if (movie
->blend_mode
> 0 && movie
->blend_mode
<= num_blend_mode_names
)
228 SWFDEC_AS_VALUE_SET_STRING (rval
, blend_mode_names
[movie
->blend_mode
- 1]);
231 SWFDEC_AS_NATIVE (900, 501, swfdec_sprite_movie_set_blendMode
)
233 swfdec_sprite_movie_set_blendMode (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
234 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
242 SWFDEC_AS_CHECK (SWFDEC_TYPE_MOVIE
, &movie
, "v", &val
);
244 if (SWFDEC_AS_VALUE_IS_NUMBER (val
)) {
245 blend_mode
= SWFDEC_AS_VALUE_GET_NUMBER (val
);
246 } else if (SWFDEC_AS_VALUE_IS_STRING (val
)) {
248 str
= SWFDEC_AS_VALUE_GET_STRING (val
);
249 for (i
= 0; i
< num_blend_mode_names
; i
++) {
250 if (str
== blend_mode_names
[i
]) { // case-sensitive
255 } else if (SWFDEC_AS_VALUE_IS_OBJECT (val
)) {
261 if ((guint
)blend_mode
!= movie
->blend_mode
) {
262 movie
->blend_mode
= blend_mode
;
263 swfdec_movie_invalidate_last (movie
);
267 SWFDEC_AS_NATIVE (900, 2, swfdec_sprite_movie_localToGlobal
)
269 swfdec_sprite_movie_localToGlobal (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
270 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
274 SwfdecAsValue
*xv
, *yv
;
277 SWFDEC_AS_CHECK (SWFDEC_TYPE_MOVIE
, &movie
, "O", &o
);
279 xv
= swfdec_as_object_peek_variable (o
, SWFDEC_AS_STR_x
);
280 if (xv
== NULL
|| !SWFDEC_AS_VALUE_IS_NUMBER (*xv
))
282 yv
= swfdec_as_object_peek_variable (o
, SWFDEC_AS_STR_y
);
283 if (yv
== NULL
|| !SWFDEC_AS_VALUE_IS_NUMBER (*yv
))
286 x
= SWFDEC_AS_VALUE_GET_NUMBER (*xv
);
287 y
= SWFDEC_AS_VALUE_GET_NUMBER (*yv
);
288 x
= swfdec_as_double_to_integer (x
* SWFDEC_TWIPS_SCALE_FACTOR
);
289 y
= swfdec_as_double_to_integer (y
* SWFDEC_TWIPS_SCALE_FACTOR
);
290 swfdec_movie_local_to_global (movie
, &x
, &y
);
291 *xv
= swfdec_as_value_from_number (cx
, SWFDEC_TWIPS_TO_DOUBLE ((SwfdecTwips
) x
));
292 *yv
= swfdec_as_value_from_number (cx
, SWFDEC_TWIPS_TO_DOUBLE ((SwfdecTwips
) y
));
295 SWFDEC_AS_NATIVE (900, 3, swfdec_sprite_movie_globalToLocal
)
297 swfdec_sprite_movie_globalToLocal (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
298 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
302 SwfdecAsValue
*xv
, *yv
;
305 SWFDEC_AS_CHECK (SWFDEC_TYPE_MOVIE
, &movie
, "O", &o
);
307 xv
= swfdec_as_object_peek_variable (o
, SWFDEC_AS_STR_x
);
308 if (xv
== NULL
|| !SWFDEC_AS_VALUE_IS_NUMBER (*xv
))
310 yv
= swfdec_as_object_peek_variable (o
, SWFDEC_AS_STR_y
);
311 if (yv
== NULL
|| !SWFDEC_AS_VALUE_IS_NUMBER (*yv
))
314 x
= SWFDEC_AS_VALUE_GET_NUMBER (*xv
);
315 y
= SWFDEC_AS_VALUE_GET_NUMBER (*yv
);
316 x
= swfdec_as_double_to_integer (x
* SWFDEC_TWIPS_SCALE_FACTOR
);
317 y
= swfdec_as_double_to_integer (y
* SWFDEC_TWIPS_SCALE_FACTOR
);
318 swfdec_movie_global_to_local (movie
, &x
, &y
);
319 *xv
= swfdec_as_value_from_number (cx
, SWFDEC_TWIPS_TO_DOUBLE ((SwfdecTwips
) x
));
320 *yv
= swfdec_as_value_from_number (cx
, SWFDEC_TWIPS_TO_DOUBLE ((SwfdecTwips
) y
));
323 SWFDEC_AS_NATIVE (900, 8, swfdec_sprite_movie_attachAudio
)
325 swfdec_sprite_movie_attachAudio (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
326 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
328 SWFDEC_STUB ("MovieClip.attachAudio");
331 SWFDEC_AS_NATIVE (900, 9, swfdec_sprite_movie_attachVideo
)
333 swfdec_sprite_movie_attachVideo (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
334 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
336 SWFDEC_STUB ("MovieClip.attachVideo");
339 SWFDEC_AS_NATIVE (900, 23, swfdec_sprite_movie_getInstanceAtDepth
)
341 swfdec_sprite_movie_getInstanceAtDepth (SwfdecAsContext
*cx
,
342 SwfdecAsObject
*object
, guint argc
, SwfdecAsValue
*argv
,
348 SWFDEC_AS_CHECK (SWFDEC_TYPE_MOVIE
, &movie
, "i", &depth
);
351 if (SWFDEC_AS_VALUE_IS_UNDEFINED (argv
[0]))
354 movie
= swfdec_movie_find (movie
, depth
);
356 if (!swfdec_movie_is_scriptable (movie
))
357 movie
= movie
->parent
;
358 SWFDEC_AS_VALUE_SET_MOVIE (rval
, movie
);
362 SWFDEC_AS_NATIVE (900, 24, swfdec_sprite_movie_getSWFVersion
)
364 swfdec_sprite_movie_getSWFVersion (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
365 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
367 if (object
!= NULL
&& object
->movie
) {
368 *rval
= swfdec_as_value_from_integer (cx
,
369 swfdec_movie_get_version (SWFDEC_MOVIE (object
->relay
)));
371 *rval
= swfdec_as_value_from_integer (cx
, -1);
375 SWFDEC_AS_NATIVE (900, 25, swfdec_sprite_movie_attachBitmap
)
377 swfdec_sprite_movie_attachBitmap (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
378 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
381 SwfdecAsObject
*bitmap
;
382 const char *snapping
= SWFDEC_AS_STR_auto
;
383 gboolean smoothing
= FALSE
;
387 SWFDEC_AS_CHECK (SWFDEC_TYPE_SPRITE_MOVIE
, &parent
, "oi|sb",
388 &bitmap
, &depth
, &snapping
, &smoothing
);
390 if (!SWFDEC_IS_BITMAP_DATA (bitmap
->relay
))
392 if (swfdec_depth_classify (depth
) == SWFDEC_DEPTH_CLASS_EMPTY
)
395 movie
= swfdec_movie_find (parent
, depth
);
397 swfdec_movie_remove (movie
);
399 swfdec_bitmap_movie_new (parent
, SWFDEC_BITMAP_DATA (bitmap
->relay
), depth
);
400 SWFDEC_LOG ("created new BitmapMovie to parent %s at depth %d",
401 parent
->name
, depth
);
404 SWFDEC_AS_NATIVE (900, 26, swfdec_sprite_movie_getRect
)
406 swfdec_sprite_movie_getRect (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
407 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
409 SWFDEC_STUB ("MovieClip.getRect");
412 SWFDEC_AS_NATIVE (900, 12, swfdec_sprite_movie_play
)
414 swfdec_sprite_movie_play (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
415 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
417 SwfdecSpriteMovie
*movie
;
419 SWFDEC_AS_CHECK (SWFDEC_TYPE_SPRITE_MOVIE
, &movie
, "");
421 movie
->playing
= TRUE
;
424 SWFDEC_AS_NATIVE (900, 13, swfdec_sprite_movie_stop
)
426 swfdec_sprite_movie_stop (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
427 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
429 SwfdecSpriteMovie
*movie
;
431 SWFDEC_AS_CHECK (SWFDEC_TYPE_SPRITE_MOVIE
, &movie
, "");
433 movie
->playing
= FALSE
;
436 SWFDEC_AS_NATIVE (900, 7, swfdec_sprite_movie_getBytesLoaded
)
438 swfdec_sprite_movie_getBytesLoaded (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
439 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
442 SwfdecResource
*resource
;
444 SWFDEC_AS_CHECK (SWFDEC_TYPE_MOVIE
, &movie
, "");
446 resource
= swfdec_movie_get_own_resource (movie
);
447 if (resource
&& resource
->decoder
) {
448 *rval
= swfdec_as_value_from_integer (cx
, resource
->decoder
->bytes_loaded
);
450 *rval
= swfdec_as_value_from_integer (cx
, 0);
454 SWFDEC_AS_NATIVE (900, 6, swfdec_sprite_movie_getBytesTotal
)
456 swfdec_sprite_movie_getBytesTotal (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
457 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
460 SwfdecResource
*resource
;
462 SWFDEC_AS_CHECK (SWFDEC_TYPE_MOVIE
, &movie
, "");
464 resource
= swfdec_movie_get_own_resource (movie
);
466 if (resource
->decoder
) {
467 *rval
= swfdec_as_value_from_integer (cx
, resource
->decoder
->bytes_total
);
469 *rval
= swfdec_as_value_from_integer (cx
, -1);
472 *rval
= swfdec_as_value_from_integer (cx
, 0);
476 SWFDEC_AS_NATIVE (900, 22, swfdec_sprite_movie_getNextHighestDepth
)
478 swfdec_sprite_movie_getNextHighestDepth (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
479 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
484 SWFDEC_AS_CHECK (SWFDEC_TYPE_MOVIE
, &movie
, "");
487 depth
= SWFDEC_MOVIE (g_list_last (movie
->list
)->data
)->depth
+ 1;
493 *rval
= swfdec_as_value_from_integer (cx
, depth
);
497 swfdec_sprite_movie_do_goto (SwfdecSpriteMovie
*movie
, SwfdecAsValue
*target
)
501 g_return_if_fail (SWFDEC_IS_SPRITE_MOVIE (movie
));
502 g_return_if_fail (movie
->sprite
!= NULL
);
504 if (SWFDEC_AS_VALUE_IS_STRING (*target
)) {
505 const char *label
= SWFDEC_AS_VALUE_GET_STRING (*target
);
506 frame
= swfdec_sprite_get_frame (movie
->sprite
, label
);
507 /* FIXME: nonexisting frames? */
512 frame
= swfdec_as_value_to_integer (swfdec_gc_object_get_context (movie
), *target
);
514 /* FIXME: how to handle overflow? */
515 frame
= CLAMP (frame
, 1, (int) movie
->n_frames
);
517 swfdec_sprite_movie_goto (movie
, frame
);
520 SWFDEC_AS_NATIVE (900, 16, swfdec_sprite_movie_gotoAndPlay
)
522 swfdec_sprite_movie_gotoAndPlay (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
523 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
525 SwfdecSpriteMovie
*movie
;
528 SWFDEC_AS_CHECK (SWFDEC_TYPE_SPRITE_MOVIE
, &movie
, "v", &val
);
530 if (movie
->sprite
== NULL
)
533 swfdec_sprite_movie_do_goto (movie
, &val
);
534 movie
->playing
= TRUE
;
537 SWFDEC_AS_NATIVE (900, 17, swfdec_sprite_movie_gotoAndStop
)
539 swfdec_sprite_movie_gotoAndStop (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
540 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
542 SwfdecSpriteMovie
*movie
;
545 SWFDEC_AS_CHECK (SWFDEC_TYPE_SPRITE_MOVIE
, &movie
, "v", &val
);
547 if (movie
->sprite
== NULL
)
550 swfdec_sprite_movie_do_goto (movie
, &val
);
551 movie
->playing
= FALSE
;
554 SWFDEC_AS_NATIVE (900, 14, swfdec_sprite_movie_nextFrame
)
556 swfdec_sprite_movie_nextFrame (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
557 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
559 SwfdecSpriteMovie
*movie
;
561 SWFDEC_AS_CHECK (SWFDEC_TYPE_SPRITE_MOVIE
, &movie
, "");
563 swfdec_sprite_movie_goto (movie
, movie
->frame
+ 1);
564 movie
->playing
= FALSE
;
567 SWFDEC_AS_NATIVE (900, 15, swfdec_sprite_movie_prevFrame
)
569 swfdec_sprite_movie_prevFrame (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
570 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
572 SwfdecSpriteMovie
*movie
;
574 SWFDEC_AS_CHECK (SWFDEC_TYPE_SPRITE_MOVIE
, &movie
, "");
576 swfdec_sprite_movie_goto (movie
, movie
->frame
- 1);
577 movie
->playing
= FALSE
;
580 SWFDEC_AS_NATIVE (900, 4, swfdec_sprite_movie_hitTest
)
582 swfdec_sprite_movie_hitTest (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
583 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
587 SWFDEC_AS_CHECK (SWFDEC_TYPE_MOVIE
, &movie
, "");
591 SwfdecRect movie_rect
, other_rect
;
593 SWFDEC_AS_VALUE_SET_BOOLEAN (rval
, FALSE
);
594 SWFDEC_AS_CHECK (0, NULL
, "m", &other
);
596 swfdec_movie_update (movie
);
597 swfdec_movie_update (other
);
598 movie_rect
= movie
->extents
;
600 swfdec_movie_rect_local_to_global (movie
->parent
, &movie_rect
);
601 other_rect
= other
->extents
;
603 swfdec_movie_rect_local_to_global (other
->parent
, &other_rect
);
604 SWFDEC_AS_VALUE_SET_BOOLEAN (rval
, swfdec_rect_intersect (NULL
, &movie_rect
, &other_rect
));
605 } else if (argc
>= 2) {
607 gboolean shape
= FALSE
;
610 SWFDEC_AS_CHECK (0, NULL
, "nn|b", &x
, &y
, &shape
);
611 x
*= SWFDEC_TWIPS_SCALE_FACTOR
;
612 y
*= SWFDEC_TWIPS_SCALE_FACTOR
;
616 swfdec_movie_global_to_local (movie
->parent
, &x
, &y
);
617 ret
= swfdec_movie_contains (movie
, x
, y
);
619 if (movie
->cache_state
>= SWFDEC_MOVIE_INVALID_EXTENTS
)
620 swfdec_movie_update (movie
);
621 swfdec_movie_global_to_local (movie
, &x
, &y
);
622 ret
= swfdec_rect_contains (&movie
->original_extents
, x
, y
);
624 SWFDEC_AS_VALUE_SET_BOOLEAN (rval
, ret
);
628 SWFDEC_AS_NATIVE (900, 20, swfdec_sprite_movie_startDrag
)
630 swfdec_sprite_movie_startDrag (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
631 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
634 SwfdecPlayer
*player
= SWFDEC_PLAYER (cx
);
635 gboolean center
= FALSE
;
637 SWFDEC_AS_CHECK (SWFDEC_TYPE_ACTOR
, &actor
, "");
640 center
= swfdec_as_value_to_boolean (cx
, argv
[0]);
644 rect
.x0
= swfdec_as_value_to_number (cx
, argv
[1]);
645 rect
.y0
= swfdec_as_value_to_number (cx
, argv
[2]);
646 rect
.x1
= swfdec_as_value_to_number (cx
, argv
[3]);
647 rect
.y1
= swfdec_as_value_to_number (cx
, argv
[4]);
648 swfdec_rect_scale (&rect
, &rect
, SWFDEC_TWIPS_SCALE_FACTOR
);
649 swfdec_player_set_drag_movie (player
, actor
, center
, &rect
);
651 swfdec_player_set_drag_movie (player
, actor
, center
, NULL
);
655 SWFDEC_AS_NATIVE (900, 21, swfdec_sprite_movie_stopDrag
)
657 swfdec_sprite_movie_stopDrag (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
658 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
660 // FIXME: Should this work when called on non-movie objects or not?
662 swfdec_player_set_drag_movie (SWFDEC_PLAYER (cx
), NULL
, FALSE
, NULL
);
665 SWFDEC_AS_NATIVE (900, 1, swfdec_sprite_movie_swapDepths
)
667 swfdec_sprite_movie_swapDepths (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
668 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
670 SwfdecMovie
*movie
, *other
;
674 SWFDEC_AS_CHECK (SWFDEC_TYPE_MOVIE
, &movie
, "v", &value
);
676 if (movie
->parent
== NULL
)
677 SWFDEC_FIXME ("swapDepths on root movie, should do something weird");
679 if (SWFDEC_AS_VALUE_IS_MOVIE (value
)) {
680 other
= SWFDEC_AS_VALUE_GET_MOVIE (value
);
681 if (other
== NULL
|| other
->parent
!= movie
->parent
)
683 depth
= other
->depth
;
685 depth
= swfdec_as_value_to_integer (cx
, value
);
687 other
= swfdec_movie_find (movie
->parent
, depth
);
689 // special case: if root movie: we won't swap, but just set depth
694 // FIXME: one different than the reserved range, should the classify function
695 // be changed instead?
696 if (swfdec_depth_classify (depth
) == SWFDEC_DEPTH_CLASS_EMPTY
||
701 swfdec_movie_set_depth (other
, movie
->depth
);
702 swfdec_movie_set_depth (movie
, depth
);
705 SWFDEC_AS_NATIVE (901, 0, swfdec_sprite_movie_createEmptyMovieClip
)
707 swfdec_sprite_movie_createEmptyMovieClip (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
708 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
710 SwfdecMovie
*movie
, *parent
;
711 SwfdecSandbox
*sandbox
;
715 SWFDEC_AS_CHECK (SWFDEC_TYPE_MOVIE
, &parent
, "si", &name
, &depth
);
717 movie
= swfdec_movie_find (parent
, depth
);
719 swfdec_movie_remove (movie
);
720 movie
= swfdec_movie_new (SWFDEC_PLAYER (cx
), depth
, parent
, parent
->resource
, NULL
, name
);
722 sandbox
= swfdec_sandbox_get (SWFDEC_PLAYER (cx
));
723 swfdec_sandbox_unuse (sandbox
);
724 swfdec_movie_initialize (movie
);
725 swfdec_actor_execute (SWFDEC_ACTOR (movie
), SWFDEC_EVENT_CONSTRUCT
, 0);
726 swfdec_sandbox_use (sandbox
);
728 SWFDEC_AS_VALUE_SET_MOVIE (rval
, movie
);
732 swfdec_sprite_movie_copy_props (SwfdecMovie
*target
, SwfdecMovie
*src
)
734 swfdec_movie_begin_update_matrix (target
);
735 target
->matrix
= src
->matrix
;
736 target
->modified
= src
->modified
;
737 target
->xscale
= src
->xscale
;
738 target
->yscale
= src
->yscale
;
739 target
->rotation
= src
->rotation
;
740 target
->lockroot
= src
->lockroot
;
741 target
->color_transform
= src
->color_transform
;
742 swfdec_movie_end_update_matrix (target
);
746 swfdec_sprite_movie_foreach_copy_properties (SwfdecAsObject
*object
,
747 const char *variable
, SwfdecAsValue
*value
, guint flags
, gpointer data
)
749 SwfdecMovie
*target
= SWFDEC_MOVIE (data
);
751 /* FIXME: We likely need better flag handling here.
752 * We might even want to fix swfdec_as_object_foreach() */
753 if (flags
& SWFDEC_AS_VARIABLE_HIDDEN
)
756 swfdec_as_object_set_variable (swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (target
)),
763 swfdec_sprite_movie_init_from_object (SwfdecMovie
*movie
,
764 SwfdecAsObject
*initObject
)
766 g_return_if_fail (SWFDEC_IS_MOVIE (movie
));
768 if (initObject
!= NULL
) {
769 SwfdecAsContext
*cx
= swfdec_gc_object_get_context (movie
);
770 if (cx
->version
<= 6) {
771 swfdec_as_object_foreach (initObject
,
772 swfdec_sprite_movie_foreach_copy_properties
, movie
);
773 swfdec_movie_initialize (movie
);
775 swfdec_movie_initialize (movie
);
776 swfdec_as_object_foreach (initObject
,
777 swfdec_sprite_movie_foreach_copy_properties
, movie
);
780 swfdec_movie_initialize (movie
);
783 if (SWFDEC_IS_SPRITE_MOVIE (movie
)) {
784 SwfdecSandbox
*sandbox
= movie
->resource
->sandbox
;
785 SwfdecActor
*actor
= SWFDEC_ACTOR (movie
);
786 swfdec_actor_queue_script (actor
, SWFDEC_EVENT_INITIALIZE
);
787 swfdec_actor_queue_script (actor
, SWFDEC_EVENT_LOAD
);
788 swfdec_sandbox_unuse (sandbox
);
789 swfdec_actor_execute (actor
, SWFDEC_EVENT_CONSTRUCT
, 0);
790 swfdec_sandbox_use (sandbox
);
794 SWFDEC_AS_NATIVE (900, 0, swfdec_sprite_movie_attachMovie
)
796 swfdec_sprite_movie_attachMovie (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
797 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
801 SwfdecAsObject
*initObject
= NULL
, *constructor
, *o
;
802 const char *name
, *export
;
804 SwfdecGraphic
*sprite
;
806 SWFDEC_AS_CHECK (SWFDEC_TYPE_MOVIE
, &movie
, "ssi|O", &export
, &name
, &depth
, &initObject
);
808 sprite
= swfdec_resource_get_export (movie
->resource
, export
);
809 if (!SWFDEC_IS_SPRITE (sprite
)) {
810 if (sprite
== NULL
) {
811 SWFDEC_WARNING ("no symbol with name %s exported", export
);
813 SWFDEC_WARNING ("can only use attachMovie with sprites");
817 if (swfdec_depth_classify (depth
) == SWFDEC_DEPTH_CLASS_EMPTY
)
819 ret
= swfdec_movie_find (movie
, depth
);
821 swfdec_movie_remove (ret
);
822 ret
= swfdec_movie_new (SWFDEC_PLAYER (cx
),
823 depth
, movie
, movie
->resource
, sprite
, name
);
824 SWFDEC_LOG ("attached %s (%u) as %s to depth %u", export
, SWFDEC_CHARACTER (sprite
)->id
,
825 ret
->name
, ret
->depth
);
826 /* run init and construct */
827 constructor
= swfdec_player_get_export_class (SWFDEC_PLAYER (cx
), export
);
828 o
= swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (ret
));
829 if (constructor
== NULL
) {
830 swfdec_as_object_set_constructor_by_name (o
, SWFDEC_AS_STR_MovieClip
, NULL
);
832 swfdec_as_object_set_constructor (o
, constructor
);
835 swfdec_sprite_movie_init_from_object (ret
, initObject
);
836 SWFDEC_AS_VALUE_SET_MOVIE (rval
, ret
);
839 SWFDEC_AS_NATIVE (900, 18, swfdec_sprite_movie_duplicateMovieClip
)
841 swfdec_sprite_movie_duplicateMovieClip (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
842 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
849 SWFDEC_AS_CHECK (SWFDEC_TYPE_MOVIE
, &movie
, "si", &name
, &depth
);
851 if (swfdec_depth_classify (depth
) == SWFDEC_DEPTH_CLASS_EMPTY
)
853 new = swfdec_movie_duplicate (movie
, name
, depth
);
856 swfdec_sprite_movie_copy_props (new, movie
);
857 SWFDEC_LOG ("duplicated %s as %s to depth %u", movie
->name
, new->name
, new->depth
);
858 SWFDEC_AS_VALUE_SET_MOVIE (rval
, new);
861 SWFDEC_AS_NATIVE (900, 19, swfdec_sprite_movie_removeMovieClip
)
863 swfdec_sprite_movie_removeMovieClip (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
864 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
868 SWFDEC_AS_CHECK (SWFDEC_TYPE_MOVIE
, &movie
, "");
870 if (swfdec_depth_classify (movie
->depth
) == SWFDEC_DEPTH_CLASS_DYNAMIC
)
871 swfdec_movie_remove (movie
);
874 SWFDEC_AS_NATIVE (900, 10, swfdec_sprite_movie_getDepth
)
876 swfdec_sprite_movie_getDepth (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
877 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
881 SWFDEC_AS_CHECK (SWFDEC_TYPE_MOVIE
, &movie
, "");
883 *rval
= swfdec_as_value_from_integer (cx
, movie
->depth
);
886 SWFDEC_AS_NATIVE (900, 5, swfdec_sprite_movie_getBounds
)
888 swfdec_sprite_movie_getBounds (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
889 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
896 SWFDEC_AS_CHECK (SWFDEC_TYPE_MOVIE
, &movie
, "");
898 obj
= swfdec_as_object_new_empty (cx
);
900 swfdec_movie_update (movie
);
901 if (swfdec_rect_is_empty (&movie
->extents
)) {
902 x0
= x1
= y0
= y1
= 0x7FFFFFF;
904 SwfdecRect rect
= movie
->extents
;
909 swfdec_player_get_movie_from_value (SWFDEC_PLAYER (cx
), &argv
[0]);
917 swfdec_movie_rect_local_to_global (movie
->parent
, &rect
);
918 swfdec_movie_rect_global_to_local (other
, &rect
);
925 val
= swfdec_as_value_from_number (cx
, SWFDEC_TWIPS_TO_DOUBLE (x0
));
926 swfdec_as_object_set_variable (obj
, SWFDEC_AS_STR_xMin
, &val
);
927 val
= swfdec_as_value_from_number (cx
, SWFDEC_TWIPS_TO_DOUBLE (y0
));
928 swfdec_as_object_set_variable (obj
, SWFDEC_AS_STR_yMin
, &val
);
929 val
= swfdec_as_value_from_number (cx
, SWFDEC_TWIPS_TO_DOUBLE (x1
));
930 swfdec_as_object_set_variable (obj
, SWFDEC_AS_STR_xMax
, &val
);
931 val
= swfdec_as_value_from_number (cx
, SWFDEC_TWIPS_TO_DOUBLE (y1
));
932 swfdec_as_object_set_variable (obj
, SWFDEC_AS_STR_yMax
, &val
);
934 SWFDEC_AS_VALUE_SET_OBJECT (rval
, obj
);
937 SWFDEC_AS_NATIVE (900, 11, swfdec_sprite_movie_setMask
)
939 swfdec_sprite_movie_setMask (SwfdecAsContext
*cx
, SwfdecAsObject
*object
,
940 guint argc
, SwfdecAsValue
*argv
, SwfdecAsValue
*rval
)
942 SwfdecMovie
*movie
, *mask
;
944 /* yes, this works with regular movies */
945 SWFDEC_AS_CHECK (SWFDEC_TYPE_MOVIE
, &movie
, "M", &mask
);
947 if (argc
> 0 && mask
== NULL
&& !SWFDEC_AS_VALUE_IS_NULL (argv
[0])) {
948 SWFDEC_FIXME ("mask is not a movie and not null, what now?");
951 if (movie
->masked_by
)
952 movie
->masked_by
->mask_of
= NULL
;
954 movie
->mask_of
->masked_by
= NULL
;
955 movie
->masked_by
= mask
;
956 movie
->mask_of
= NULL
;
957 if (movie
->clip_depth
) {
958 g_assert (movie
->parent
);
959 swfdec_movie_invalidate_last (movie
->parent
);
960 movie
->clip_depth
= 0;
962 swfdec_movie_invalidate_last (movie
);
966 mask
->masked_by
->mask_of
= NULL
;
968 mask
->mask_of
->masked_by
= NULL
;
969 mask
->masked_by
= NULL
;
970 mask
->mask_of
= movie
;
971 swfdec_movie_invalidate_last (mask
);
972 if (mask
->clip_depth
) {
973 g_assert (mask
->parent
);
974 swfdec_movie_invalidate_last (mask
->parent
);
975 mask
->clip_depth
= 0;
977 swfdec_movie_invalidate_last (mask
);