1 /***********************************************************************
2  *
3  *   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010,
4  *   2011 Free Software Foundation, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program 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
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  *
21  ***********************************************************************
22  *
23  * The movie has 3 frames.
24  * Test1: mouse events.  Test2: hitTest.
25  *
26  *  - frame1: initialization
27  *  - frame2: place a red and a green square, red square is set to invisible.
28  *  - frame3: red square is set to visible, green square is set to invisible.
29  *  - frame4: remove the red and green squares, place 4 black squares.
30  *
31  * In frame2, rollOver event moves the playhead to frame3.
32  * In frame3, rollOut  event moves the playhead to frame2.
33  * In frame3, press    event moves the playhead to frame4.
34  *
35  ***********************************************************************/
36 
37 #include "ming_utils.h"
38 
39 #include <ming.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 
43 #define OUTPUT_VERSION 6
44 #define OUTPUT_FILENAME "RollOverOutTest.swf"
45 
46 SWFFont font;
47 
48 void add_event(SWFMovie mo, const char* name, const char* event, const char* action);
49 void add_text_field(SWFMovie mo, const char* name, int depth);
50 SWFDisplayItem add_square(SWFMovie mo, byte r, byte g, byte b, int depth);
51 
52 void
add_event(SWFMovie mo,const char * name,const char * event,const char * action)53 add_event(SWFMovie mo, const char* name, const char* event, const char* action)
54 {
55     SWFAction ac;
56     char buf[1024];
57 
58     sprintf(buf,
59     "event=undefined;"
60     "%s.on%s=function() { %s; };"
61     , name, event, action
62     );
63     ac = compileSWFActionCode(buf);
64 
65     SWFMovie_add(mo, (SWFBlock)ac);
66 }
67 
add_square(SWFMovie mo,byte r,byte g,byte b,int depth)68 SWFDisplayItem add_square(SWFMovie mo, byte r, byte g, byte b, int depth)
69 {
70     SWFDisplayItem it;
71     SWFMovieClip mc;
72     SWFShape sh;
73     mc = newSWFMovieClip();
74     sh = make_fill_square(0, 0, 40, 40, r, g, b, r, g, b);
75     SWFMovieClip_add(mc, (SWFBlock)sh);
76     SWFMovieClip_nextFrame(mc); /* showFrame */
77     it = SWFMovie_add(mo, (SWFBlock)mc);
78     SWFDisplayItem_setDepth(it, depth);
79     return it;
80 }
81 
82 void
add_text_field(SWFMovie mo,const char * name,int depth)83 add_text_field(SWFMovie mo, const char* name, int depth)
84 {
85     SWFDisplayItem it;
86     SWFTextField tf = newSWFTextField();
87     SWFTextField_setFlags(tf, SWFTEXTFIELD_DRAWBOX);
88 
89     SWFTextField_setFont(tf, (void*)font);
90     SWFTextField_addChars(tf, " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345689:.,/\\#@?!");
91     SWFTextField_addString(tf, " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345689:.,/\\#@?!");
92     SWFTextField_setVariableName(tf, name);
93 
94     it = SWFMovie_add(mo, (SWFBlock)tf);
95     SWFDisplayItem_moveTo(it, 0, 10);
96     SWFTextField_setBounds(tf, 600, 20);
97     SWFDisplayItem_setDepth(it, depth);
98 }
99 
100 int
main(int argc,char ** argv)101 main(int argc, char **argv)
102 {
103     SWFMovie mo;
104     SWFDisplayItem it1, it2, it3;
105     SWFMovieClip dejagnuclip;
106     char fdbfont[256];
107 
108     /*********************************************
109      *
110      * Initialization
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     puts("Setting things up");
123 
124     Ming_init();
125     Ming_useSWFVersion (OUTPUT_VERSION);
126     Ming_setScale(20.0);
127 
128     mo = newSWFMovie();
129     SWFMovie_setDimension(mo, 800, 600);
130 
131     dejagnuclip = get_dejagnu_clip((SWFBlock)get_default_font(srcdir), 10, 0, 0, 800, 600);
132     SWFMovie_add(mo, (SWFBlock)dejagnuclip);
133 
134     sprintf(fdbfont, "%s/Bitstream-Vera-Sans.fdb", srcdir);
135     FILE *font_file = fopen(fdbfont, "r");
136     if ( font_file == NULL )
137     {
138         perror(fdbfont);
139         exit(1);
140     }
141     font = loadSWFFontFromFile(font_file);
142     add_text_field(mo, "_root.msg", 100);
143 
144     SWFMovie_nextFrame(mo); // frame1
145 
146     /*****************************************************
147      *
148      * Add squares
149      *
150      *****************************************************/
151 
152     it1 = add_square(mo, 255, 0, 0, 3);
153     SWFDisplayItem_moveTo(it1, 40, 40);
154     SWFDisplayItem_setName(it1, "square1");
155 
156     it2 = add_square(mo, 0, 255, 0, 4);
157     SWFDisplayItem_moveTo(it2, 40, 40);
158     SWFDisplayItem_setName(it2, "square2");
159 
160     /*****************************************************
161      *
162      * Frame 2: display a red square.
163      *          onRollOver: goto frame3
164      *
165      *****************************************************/
166 
167     add_actions(mo, "_root.msg = 'Frame2: move the mouse on the square'; ");
168     add_actions(mo, "square1._visible = true; square2._visible=false;");
169 
170     add_event(mo, "square1", "RollOver", "gotoAndPlay(3)");
171 
172     add_actions(mo, "stop();");
173     SWFMovie_nextFrame(mo); // frame2
174 
175     /*****************************************************
176      *
177      * Frame 3: display a green square.
178      *          onRollOut: goto frame2
179      *
180      *****************************************************/
181 
182     add_actions(mo,
183         " _root.msg = 'Frame3: move the mouse off the square"
184         " or press the square with the left button'; ");
185     add_actions(mo, "square2._visible = true; square1._visible=false;");
186 
187     add_event(mo, "square2", "RollOut", "gotoAndPlay(2)");
188     add_event(mo, "square2", "Press", "gotoAndPlay(4)"  );
189 
190     add_actions(mo, "stop();");
191     SWFMovie_nextFrame(mo); // frame3
192 
193     //
194     //  Frame4:
195     //  (0) remove the squares placed at frame1.
196     //  (1) place a visible black square.
197     //  (2) place a invisible black square.
198     //  (3) place a static mask.
199     //  (4) place a dynamic mask.
200     //
201     // Expected behaviour:
202     //  (1)hitTest works for both visible and invisible sprites.
203     //  (2)hitTest works for both static mask and maskee sprites.
204     //  (3)hitTest does not work for dynamic masks created by drawing API.
205     //
206     SWFDisplayItem_remove(it1);
207     SWFDisplayItem_remove(it2);
208     add_actions(mo, "_root.msg = 'Frame4: move the mouse on the squares'; ");
209 
210     it3 = add_square(mo, 0, 0, 0, 10);
211     SWFDisplayItem_moveTo(it3, 60, 100);
212     SWFDisplayItem_setName(it3, "visible_mc");
213 
214     it3 = add_square(mo, 0, 0, 0, 11);
215     SWFDisplayItem_moveTo(it3, 60, 150);
216     SWFDisplayItem_setName(it3, "invisible_mc");
217     add_actions(mo, "invisible_mc._visible = false; ");
218 
219     it3 = add_square(mo, 0, 0, 0, 12);
220     SWFDisplayItem_moveTo(it3, 60, 200);
221     SWFDisplayItem_setName(it3, "static_mask");
222     SWFDisplayItem_setMaskLevel(it3, 13);
223 
224     add_actions(mo,
225         " _root.createEmptyMovieClip('dynamic_mask', 15); "
226         " _root.createEmptyMovieClip('maskee', 14); "
227         " with(maskee) {"
228         "   beginFill(0); "
229         "    moveTo( 60, 250); "
230         "    lineTo(100, 250); "
231         "    lineTo(100, 290); "
232         "    lineTo( 60, 290); "
233         "}"
234         " maskee.setMask(dynamic_mask); "
235         " with(dynamic_mask) { "
236         "    beginFill(0xff0000); "
237         "    moveTo( 60, 250); "
238         "    lineTo(100, 250); "
239         "    lineTo(100, 290); "
240         "    lineTo( 60, 290); "
241         "}"
242         "stop();");
243     // hitTest works for visible sprites.
244     check(mo, "visible_mc.hitTest(80, 120, true)");
245     // hitTest works for invisible sprites.
246     check(mo, "invisible_mc.hitTest(80, 180, true)");
247     // hitTest works for static placed maskes.
248     check(mo, "static_mask.hitTest(80, 240, true)");
249     // hitTest does not work for dynamic masks created by drawing API.
250     check(mo, "! dynamic_mask.hitTest(80, 280, true)");
251     // hitTest works for maskee sprites.
252     check(mo, "maskee.hitTest(80, 280, true)");
253     SWFMovie_nextFrame(mo); // frame4
254 
255     // save this file to a swf.
256     puts("Saving " OUTPUT_FILENAME );
257     SWFMovie_save(mo, OUTPUT_FILENAME);
258 
259     return 0;
260 }
261 
262