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 how swapDepth affects DisplayList refresh on gotoAndPlay(current-X).
23  *
24  * run as ./displaylist_depths_test2
25  *
26  * Timeline:
27  *
28  *   Frame  | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
29  *  --------+---+---+---+---+---+---+---+
30  *   Event  |   | P |   | T*| T | M | J |
31  *
32  *  P = place (by PlaceObject2)
33  *  T = transform matrix (by PlaceObject2)
34  *  M = move to another depth (by swapDepth)
35  *  J = jump
36  *  * = jump target
37  *
38  * Description:
39  *
40  *  frame2: DisplayObject placed at depth -16381 at position (10,200)
41  *  frame4: position of instance at depth -16381 shifted to the right (50,200)
42  *  frame5: position of instance at depth -16381 shifted to the right (200,200)
43  *  frame6: depth of instance changed to 10 (dynamic zone) and stop.
44  *  frame7: jump back to frame 4
45  *
46  * Expected behaviour on jump back:
47  *
48  *  Before the jump we have a single instance at depth 10 and position 100,200.
49  *  After the jump we have two instances:
50  *         - one at depth 10 and position 100,200
51  *           (the same we had before, with its state intact)
52  *         - another at depth -16381 and position 50,200
53  *           (newly created and placed accordingly to the PlaceObject2 tag on frame4)
54  *  Two distinct instances have been constructed in total.
55  *
56  */
57 
58 #include "ming_utils.h"
59 
60 #include <stdlib.h>
61 #include <stdio.h>
62 #include <ming.h>
63 
64 // We need version 7 to use getInstanceAtDepth()
65 #define OUTPUT_VERSION 7
66 #define OUTPUT_FILENAME "displaylist_depths_test2.swf"
67 
68 SWFDisplayItem add_static_mc(SWFMovie mo, const char* name, int depth, int x, int y, int width, int height);
69 
70 SWFDisplayItem
add_static_mc(SWFMovie mo,const char * name,int depth,int x,int y,int width,int height)71 add_static_mc(SWFMovie mo, const char* name, int depth, int x, int y, int width, int height)
72 {
73 	SWFShape sh;
74 	SWFMovieClip mc;
75 	SWFDisplayItem it;
76 
77 	sh = make_fill_square (-(width/2), -(height/2), width, height, 255, 0, 0, 255, 0, 0);
78 	mc = newSWFMovieClip();
79 	SWFMovieClip_add(mc, (SWFBlock)sh);
80 
81 	SWFMovieClip_nextFrame(mc);
82 
83 	it = SWFMovie_add(mo, (SWFBlock)mc);
84 	SWFDisplayItem_setDepth(it, depth);
85 	SWFDisplayItem_moveTo(it, x, y);
86 	SWFDisplayItem_setName(it, name);
87 	SWFDisplayItem_addAction(it, newSWFAction(
88 			"_root.note(this+' onClipConstruct');"
89 			" _root.check_equals(typeof(_root), 'movieclip');"
90 		        " if ( isNaN(_root.depth3Constructed) ) {"
91 			"	_root.depth3Constructed=1; "
92 			" 	_root.note('_root.depth3Constructed set to '+_root.depth3Constructed);"
93 			" } else {"
94 			"	_root.depth3Constructed++;"
95 			" 	_root.note('_root.depth3Constructed set to '+_root.depth3Constructed);"
96 			" }"
97 			), SWFACTION_CONSTRUCT);
98 
99 	return it;
100 }
101 
102 
103 int
main(int argc,char ** argv)104 main(int argc, char** argv)
105 {
106 	SWFMovie mo;
107 	SWFMovieClip dejagnuclip;
108 	SWFDisplayItem it1;
109 
110 
111 	const char *srcdir=".";
112 	if ( argc>1 )
113 		srcdir=argv[1];
114 	else
115 	{
116    		//fprintf(stderr, "Usage: %s <mediadir>\n", argv[0]);
117    		//return 1;
118 	}
119 
120 	Ming_init();
121 	mo = newSWFMovieWithVersion(OUTPUT_VERSION);
122 	SWFMovie_setDimension(mo, 800, 600);
123 	SWFMovie_setRate (mo, 2);
124 
125 	dejagnuclip = get_dejagnu_clip((SWFBlock)get_default_font(srcdir), 10, 0, 0, 800, 600);
126 	SWFMovie_add(mo, (SWFBlock)dejagnuclip);
127 	SWFMovie_nextFrame(mo);
128 
129 	// Frame 2: Add a static movieclip at depth 3 with origin at 10,200
130 	it1 = add_static_mc(mo, "static3", 3, 10, 200, 20, 20);
131 	add_actions(mo,
132 		"static3.myThing = 'guess';"
133 		"check_equals(static3._x, 10);"
134 		"check_equals(static3.myThing, 'guess');"
135 		"check_equals(static3.getDepth(), -16381);"
136 		);
137 	SWFMovie_nextFrame(mo);
138 
139 	// Frame 3: nothing new
140 	SWFMovie_nextFrame(mo);
141 
142 	// Frame 4: move DisplayObject at depth 3 to position 50,200
143 	SWFDisplayItem_moveTo(it1, 50, 200);
144 	add_actions(mo,
145 		"check_equals(static3._x, 50);"
146 		"check_equals(static3.getDepth(), -16381);"
147 		);
148 	SWFMovie_nextFrame(mo);
149 
150 	// Frame 5: move DisplayObject at depth 3 to position 200,200
151 	SWFDisplayItem_moveTo(it1, 200, 200);
152 	add_actions(mo,
153 		"check_equals(static3.myThing, 'guess');"
154 		"check_equals(static3._x, 200);"
155 		"check_equals(static3.getDepth(), -16381);"
156 		);
157 	SWFMovie_nextFrame(mo);
158 
159 	// Frame 6: change depth DisplayObject at depth 3 to depth 10 (dynamic zone)
160 	add_actions(mo,
161 		"static3.swapDepths(10);"
162 		"check_equals(static3.getDepth(), 10);"
163 		"static3._rotation = 45;"
164 		"check_equals(static3.myThing, 'guess');"
165 		);
166 	SWFMovie_nextFrame(mo);
167 
168 	// Frame 7: go to frame 4
169 	add_actions(mo,
170 
171 		"check_equals(static3.myThing, 'guess');"
172 
173 		// Store a reference to the static3 instance
174 		// before overriding its name
175 		"dynRef = static3;"
176 
177 		// this repopulates depth -16381 with a *new* instance
178 		"gotoAndStop(4);"
179 
180 		"note('right after gotoAndStop()');"
181 
182 		// static3 doesn't refer to the dynamic object anymore !
183 		"check_equals(typeof(static3.myThing), 'undefined');"
184 
185 		// but the reference still does !!
186 		// Gnash fails here due to it's implementation of "soft references"
187 		// ... argh ...
188 		// TODO: use a MovieTester based test runner to check for actual
189 		//       existance of the old (dynamicized) instance by looking
190 		//       at the real DisplayList and at the rendered buffer
191 		//
192 		"check_equals(dynRef.myThing, 'guess');"
193 		"check_equals(dynRef.getDepth(), 10);"
194 
195 		// Luckly we can query for depth chars with getInstanceAtDepth
196 		"check_equals(typeof(getInstanceAtDepth(-16381)), 'movieclip');"
197 		"check_equals(typeof(getInstanceAtDepth(10)), 'movieclip');"
198 
199 		"check_equals(static3.getDepth(), -16381);"
200 		"check_equals(static3._x, 50);"
201 		"check_equals(depth3Constructed, 2);"
202 		"totals();"
203 		);
204 	SWFMovie_nextFrame(mo);
205 
206 	//Output movie
207 	puts("Saving " OUTPUT_FILENAME );
208 	SWFMovie_save(mo, OUTPUT_FILENAME);
209 
210 	return 0;
211 }
212