1 /*
2  *   Copyright (C) 2007, 2009, 2010, 2011 Free Software Foundation, Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
16  *
17  */
18 
19 /*
20  * Sandro Santilli, strk@keybit.net
21  *
22  * Test  "Jump backward to start of lifetime after replacement with different sprite"
23  *
24  * run as ./replace_sprites1test
25  *
26  * Timeline:
27  *
28  *   Frame  | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
29  *  --------+---+---+---+---+---+---+---+
30  *   Event  |   |P* | X | J |   |   |   |
31  *
32  *  P = place (by PlaceObject2)
33  *  X = replace (by PlaceObject2)
34  *  J = jump
35  *  * = jump target
36  *
37  * Description:
38  *
39  *  frame2: movieclip 1 placed at depth -16381 and position 100,300
40  *  frame3: instance at depth -16381 replaced by DisplayObject 2 at position 130,330
41  *  frame4: jump back to frame 2 and stop
42  *
43  * Expected behaviour:
44  *
45  *  In frame 2 we have a red square at (100,300), in frame 3 we have a red square at (130,330),
46  *  after the jump-back we have a red square at (100,300) again.
47  *  The name specified in the PlaceObject2 tag in frame 2 always point to the same instance
48  */
49 
50 #include "ming_utils.h"
51 
52 #include <stdlib.h>
53 #include <stdio.h>
54 #include <ming.h>
55 
56 #define OUTPUT_VERSION 6
57 #define OUTPUT_FILENAME "replace_sprites1test.swf"
58 
59 SWFDisplayItem add_static_mc(SWFMovie mo, const char* name, int depth, int x, int y, int width, int height);
60 SWFMovieClip get_static_mc(int width, int height, int r, int g, int b);
61 SWFShape get_shape(int width, int height, int r, int g, int b);
62 
63 SWFShape
get_shape(int width,int height,int r,int g,int b)64 get_shape(int width, int height, int r, int g, int b)
65 {
66   SWFShape sh;
67 
68   sh = make_fill_square (0, 0, width, height, r, g, b, r, g, b);
69 
70   return sh;
71 }
72 
73 SWFMovieClip
get_static_mc(int width,int height,int r,int g,int b)74 get_static_mc(int width, int height, int r, int g, int b)
75 {
76   SWFShape sh = get_shape(width, height, r, g, b);
77   SWFMovieClip mc = newSWFMovieClip();
78 
79   SWFMovieClip_add(mc, (SWFBlock)sh);
80 
81   SWFMovieClip_nextFrame(mc);
82 
83   return mc;
84 
85 }
86 
87 SWFDisplayItem
add_static_mc(SWFMovie mo,const char * name,int depth,int x,int y,int width,int height)88 add_static_mc(SWFMovie mo, const char* name, int depth, int x, int y, int width, int height)
89 {
90   SWFMovieClip mc;
91   SWFDisplayItem it;
92 
93   mc = get_static_mc(width, height, 255, 0, 0);
94 
95   it = SWFMovie_add(mo, (SWFBlock)mc);
96   SWFDisplayItem_setDepth(it, depth);
97   SWFDisplayItem_moveTo(it, x, y);
98   SWFDisplayItem_setName(it, name);
99 
100   return it;
101 }
102 
103 
104 int
main(int argc,char ** argv)105 main(int argc, char** argv)
106 {
107   SWFMovie mo;
108   SWFMovieClip dejagnuclip;
109   SWFMovieClip static1, static2;
110   SWFDisplayItem it1;
111 
112 
113   const char *srcdir=".";
114   if ( argc>1 )
115     srcdir=argv[1];
116   else
117   {
118       //fprintf(stderr, "Usage: %s <mediadir>\n", argv[0]);
119       //return 1;
120   }
121 
122   Ming_init();
123   mo = newSWFMovieWithVersion(OUTPUT_VERSION);
124   SWFMovie_setDimension(mo, 800, 600);
125   SWFMovie_setRate (mo, 2);
126 
127   static1 = get_static_mc(60, 60, 255, 0, 0);
128   static2 = get_static_mc(60, 60, 0, 255, 0);
129 
130   dejagnuclip = get_dejagnu_clip((SWFBlock)get_default_font(srcdir), 10, 0, 0, 800, 600);
131   SWFMovie_add(mo, (SWFBlock)dejagnuclip);
132   SWFMovie_nextFrame(mo);
133 
134   // Frame 2: place DisplayObject at depth 3 (-16381)
135   it1 = SWFMovie_add(mo, (SWFBlock)static1);
136   SWFDisplayItem_setDepth(it1, 3);
137   SWFDisplayItem_moveTo(it1, 100, 300);
138   SWFDisplayItem_setName(it1, "static1");
139   SWFDisplayItem_addAction(it1, newSWFAction(
140 			"_root.note(this+' onClipConstruct (place)');"
141 		        " if ( isNaN(_root.depth3Constructed) ) {"
142 			"	_root.depth3Constructed=1; "
143 			" } else {"
144 			"	_root.depth3Constructed++;"
145 			" }"
146 			" _root.note('_root.depth3Constructed set to '+_root.depth3Constructed);"
147 			), SWFACTION_CONSTRUCT);
148   SWFDisplayItem_addAction(it1, newSWFAction(
149 			"_root.note(this+' onClipUnload (place)');"
150 		        " if ( isNaN(_root.depth3Unloaded) ) {"
151 			"	_root.depth3Unloaded=1; "
152 			" } else {"
153 			"	_root.depth3Unloaded++;"
154 			" }"
155 			" _root.note('_root.depth3Unloaded set to '+_root.depth3Unloaded);"
156 			), SWFACTION_UNLOAD);
157   add_actions(mo, "static1.name='static1';");
158 
159   check_equals(mo, "typeof(static1)", "'movieclip'");
160 
161   // This is important to verify, see next check for it after REPLACE
162   check_equals(mo, "static1.name", "'static1'");
163 
164   check_equals(mo, "static1._target", "'/static1'");
165 
166   SWFMovie_nextFrame(mo);
167 
168   // Frame 3: replace instance at depth -16381 with DisplayObject 2
169   if ( SWFMovie_replace(mo, it1, (SWFBlock)static2) )
170   {
171 	  abort(); // grace and beauty...
172   }
173   SWFDisplayItem_moveTo(it1, 130, 330);
174   SWFDisplayItem_setName(it1, "static2");
175   SWFDisplayItem_addAction(it1, newSWFAction(
176 			"_root.note(this+' onClipConstruct (replace)');"
177 			" _root.check_equals(typeof(_root), 'movieclip');"
178 		        " if ( isNaN(_root.depth3Constructed) ) {"
179 			"	_root.depth3Constructed=1; "
180 			" } else {"
181 			"	_root.depth3Constructed++;"
182 			" }"
183 			" _root.note('_root.depth3Constructed set to '+_root.depth3Constructed);"
184 			), SWFACTION_CONSTRUCT);
185   SWFDisplayItem_addAction(it1, newSWFAction(
186 			"_root.note(this+' onClipUnload (replace)');"
187 		        " if ( isNaN(_root.depth3Unloaded) ) {"
188 			"	_root.depth3Unloaded=1; "
189 			" } else {"
190 			"	_root.depth3Unloaded++;"
191 			" }"
192 			" _root.note('_root.depth3Unloaded set to '+_root.depth3Unloaded);"
193 			), SWFACTION_UNLOAD);
194 
195 
196   // Can still reference the old DisplayObject and it's variables, after replace
197   check_equals(mo, "typeof(static1)", "'movieclip'");
198   check_equals(mo, "static1.name", "'static1'");
199   check_equals(mo, "static1._target", "'/static1'");
200   check_equals(mo, "static1._x", "130");
201 
202   // While the new name results undefined...
203   check_equals(mo, "typeof(static2)", "'undefined'");
204 
205   // Everything suggests that a new instance is NOT created on replace !!!
206   // Gnash here fails because it creates a NEW instance
207 
208   // Anyway, the old DisplayObject matrix changed to 130,330 !
209   check_equals(mo, "static1._x", "130");
210 
211   // We can't check the color in a self-contained testcase unfortunately,
212   // we'll need a MovieTester-based runner for this.
213   // It is expected the color of the current instance to be RED
214   // TODO: implement a MovieTester based runner !!
215 
216   SWFMovie_nextFrame(mo);
217 
218   // Frame 4: jump to frame 2, stop and check
219 
220   add_actions(mo,
221 
222     "gotoAndStop(2); "
223 
224     // A single instance has been constructed !!
225     "check_equals(_root.depth3Constructed, '1');"
226 
227     // Original DisplayObject name is still referenceable
228     "check_equals(typeof(static1), 'movieclip');"
229 
230     // And it still has it's user-provided property
231     "check_equals(static1.name, 'static1');"
232 
233     // The instance have been moved back to its original position (100,300)
234     "check_equals(static1._x, 100);"
235 
236     // We can't check the color in a self-contained testcase unfortunately,
237     // we'll need a MovieTester-based runner for this.
238     // It is expected the color of the current instance to be RED
239     // TODO: implement a MovieTester based runner !!
240 
241     "totals();"
242     );
243   SWFMovie_nextFrame(mo);
244 
245   //Output movie
246   puts("Saving " OUTPUT_FILENAME );
247   SWFMovie_save(mo, OUTPUT_FILENAME);
248 
249   return 0;
250 }
251