1 /*
2     Ming, an SWF output library
3     Copyright (C) 2002  Opaque Industries - http://www.opaque.net/
4 
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Lesser General Public
7     License as published by the Free Software Foundation; either
8     version 2.1 of the License, or (at your option) any later version.
9 
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Lesser General Public License for more details.
14 
15     You should have received a copy of the GNU Lesser General Public
16     License along with this library; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19 
20 #include <stdlib.h>
21 
22 #include "movieclip.h"
23 #include "blocklist.h"
24 #include "displaylist.h"
25 #include "blocks/soundstream.h"
26 #include "blocks/soundinstance.h"
27 #include "blocks/outputblock.h"
28 #include "blocks/sprite.h"
29 #include "blocks/shape.h"
30 #include "blocks/morph.h"
31 #include "blocks/button.h"
32 #include "blocks/text.h"
33 #include "blocks/scalinggrid.h"
34 #include "libming.h"
35 
36 struct SWFMovieClip_s
37 {
38 	struct SWFSprite_s sprite;
39 
40 	SWFBlockList blockList;
41 	SWFDisplayList displayList;
42 	unsigned short nFrames;
43 
44 #if TRACK_ALLOCS
45 	/* memory node for garbage collection */
46 	mem_node *gcnode;
47 #endif
48 };
49 
50 /*
51  * destroy a SWFMovieClip instance
52  */
53 void
destroySWFMovieClip(SWFMovieClip movieClip)54 destroySWFMovieClip(SWFMovieClip movieClip)
55 {
56 #if TRACK_ALLOCS
57 	ming_gc_remove_node(movieClip->gcnode);
58 #endif
59 
60 	destroySWFBlockList(movieClip->blockList);
61 	destroySWFDisplayList(movieClip->displayList);
62 	destroySWFSprite((SWFSprite)movieClip);
63 
64 }
65 
66 /*
67  * create a new SWFMovieClip (Sprite) instance
68  * A SWFMovieClip is a movie inside a movie. It supports
69  * adding and removing displayable objects, actions and sound
70  *
71  * returns a SWFMovieClip instance.
72  */
73 SWFMovieClip
newSWFMovieClip()74 newSWFMovieClip()
75 {
76 	SWFMovieClip clip = (SWFMovieClip)newSWFSprite();
77 	clip = (SWFMovieClip)realloc(clip, sizeof(struct SWFMovieClip_s));
78 
79 	clip->blockList = newSWFBlockList();
80 	clip->displayList = newSWFSpriteDisplayList();
81 #if TRACK_ALLOCS
82 	clip->gcnode = ming_gc_add_node(clip, (dtorfunctype) destroySWFMovieClip);
83 #endif
84 
85 	return clip;
86 }
87 
88 
89 /*
90  * set the frame count of a movie
91  * This function sets the frame count for the movieclip. If the number of
92  * frames specified here exceeds the number of frame created when adding
93  * content to the movie, then blank frames will be added to the movieclip to
94  * pad it to the specified frame count.
95  */
96 void
SWFMovieClip_setNumberOfFrames(SWFMovieClip clip,int totalFrames)97 SWFMovieClip_setNumberOfFrames(SWFMovieClip clip, int totalFrames)
98 {
99 	SWFSprite_setNumberOfFrames((SWFSprite)clip, totalFrames);
100 }
101 
102 /*
103  * Includes streaming sound to a movie.
104  * Streaming (embedded) sound is played in sync with movie frames.
105  * The skip parameter describes the time in seconds (float) to be skiped.
106  * The rate parameter describes the parent movies framerate.
107  *
108  * See also SWFMovie_setSoundStream, SWFMovie_setSoundStreamAt, newSWFSoundStream,
109  * SWFMovieClip_setSoundStream
110  */
111 void
SWFMovieClip_setSoundStreamAt(SWFMovieClip clip,SWFSoundStream sound,float rate,float skip)112 SWFMovieClip_setSoundStreamAt(SWFMovieClip clip,
113                               SWFSoundStream sound /* soundstream object */,
114                               float rate /* framerate */,
115                               float skip /* skip in seconds */)
116 {
117 	SWFBlock block = SWFSoundStream_getStreamHead(sound, rate, skip);
118 
119 	if ( block != NULL )
120 	{
121 		SWFBlockList_addBlock(clip->blockList, block);
122 		SWFDisplayList_setSoundStream(clip->displayList, sound);
123 	}
124 }
125 
126 /*
127  * Includes streaming sound to a movie.
128  * Streaming (embedded) sound is played in sync with movie frames.
129  *
130  * See also SWFMovie_setSoundStream, SWFMovie_setSoundStreamAt, newSWFSoundStream,
131  * SWFMovieClip_setSoundStreamAt
132  */
133 void
SWFMovieClip_setSoundStream(SWFMovieClip clip,SWFSoundStream sound,float rate)134 SWFMovieClip_setSoundStream(SWFMovieClip clip, SWFSoundStream sound, float rate)
135 {
136 	SWFMovieClip_setSoundStreamAt(clip, sound, rate, 0);
137 }
138 
139 
140 /*
141  * Starts playing event-sound (SWFSound)
142  *
143  * returns a SWFSoundInstance object.
144  * see also SWFSoundInstance, SWFSound, SWFMovieClip_stopSound
145  */
146 SWFSoundInstance
SWFMovieClip_startSound(SWFMovieClip clip,SWFSound sound)147 SWFMovieClip_startSound(SWFMovieClip clip, SWFSound sound)
148 {
149 	SWFSoundInstance inst = newSWFSoundInstance(sound);
150 
151 	SWFCharacter_addDependency((SWFCharacter)clip, (SWFCharacter)sound);
152 	SWFBlockList_addBlock(clip->blockList, (SWFBlock)inst);
153 
154 	return inst;
155 }
156 
157 
158 /*
159  * Stops playing event sound (SWFSound)
160  *
161  * see also SWFSoundInstance, SWFSound, SWFMovieClip_startSound
162  */
163 void
SWFMovieClip_stopSound(SWFMovieClip clip,SWFSound sound)164 SWFMovieClip_stopSound(SWFMovieClip clip, SWFSound sound)
165 {
166 	SWFCharacter_addDependency((SWFCharacter)clip, (SWFCharacter)sound);
167 
168 	SWFBlockList_addBlock(clip->blockList,
169 												(SWFBlock)newSWFSoundInstance_stop(sound));
170 }
171 
172 /*
173  * Adds a block to a movie.
174  * This function adds a block or character to a movieclip.
175  * returns a SWFDisplayItem
176  */
177 SWFDisplayItem
SWFMovieClip_add(SWFMovieClip clip,SWFBlock block)178 SWFMovieClip_add(SWFMovieClip clip, SWFBlock block)
179 {
180 	if ( SWFBlock_getType(block) == SWF_DEFINEBITS ||
181 			 SWFBlock_getType(block) == SWF_DEFINEBITSJPEG2 ||
182 			 SWFBlock_getType(block) == SWF_DEFINEBITSJPEG3 ||
183 			 SWFBlock_getType(block) == SWF_DEFINELOSSLESS ||
184 			 SWFBlock_getType(block) == SWF_DEFINELOSSLESS2 )
185 	{
186 		block = (SWFBlock)newSWFShapeFromBitmap((SWFBitmap)block, SWFFILL_TILED_BITMAP);
187 	}
188 
189 	if ( SWFBlock_isCharacter(block) )
190 	{
191 		SWFCharacter_getDependencies((SWFCharacter)block,
192 																 &CHARACTER(clip)->dependencies,
193 																 &CHARACTER(clip)->nDependencies);
194 
195 		SWFCharacter_addDependency((SWFCharacter)clip, (SWFCharacter)block);
196 
197 		SWFCharacter_setFinished((SWFCharacter)block);
198 
199 		return SWFDisplayList_add(clip->displayList, clip->blockList, (SWFCharacter)block);
200 	}
201 	else
202 	{
203 		/* XXX - make sure it's a legit block for a sprite */
204 		SWFBlockList_addBlock(clip->blockList, block);
205 	}
206 
207 	return NULL;
208 }
209 
210 /*
211  * Removes a SWFDisplayItem from the movieclips stage.
212  * A SWFDisplayItem stays on stage until it gets removed. This function
213  * removes the item. The item is displayed until the current frame.
214  */
215 void
SWFMovieClip_remove(SWFMovieClip clip,SWFDisplayItem item)216 SWFMovieClip_remove(SWFMovieClip clip, SWFDisplayItem item)
217 {
218 	SWFDisplayItem_remove(item);
219 }
220 
221 /*
222  * Add a label Frame
223  * This function adds a labelFrame to current frame of the movieclip.
224  */
225 void
SWFMovieClip_labelFrame(SWFMovieClip clip,const char * label)226 SWFMovieClip_labelFrame(SWFMovieClip clip, const char *label)
227 {
228 	SWFSprite_addBlock((SWFSprite)clip, (SWFBlock)newSWFFrameLabelBlock(label));
229 }
230 
231 /*
232  * Add a new frame to the current movie.
233  * This function adds a new frame to the current movie. All items added, removed
234  * manipulated effect this frame and probably following frames.
235  */
236 void
SWFMovieClip_nextFrame(SWFMovieClip clip)237 SWFMovieClip_nextFrame(SWFMovieClip clip)
238 {
239 	SWFDisplayList_writeBlocks(clip->displayList, clip->blockList);
240 	SWFBlockList_addToSprite(clip->blockList, (SWFSprite)clip);
241 	SWFSprite_addBlock((SWFSprite)clip, newSWFShowFrameBlock());
242 }
243 
244 
245 /*
246  * set a 9 slice scaling grid to this sprite / movieclip / button
247  * This function sets a 9 slice scaling grid to buttons / sprites / movieclips
248  *
249  *      1 2 3
250  *      4 5 6
251  *      7 8 9
252  *
253  * x, y, w and h define a rectangle, which is the dimension of the center slice (5).
254  * All other slices are determined out of the characters bounds and the defined rect.
255  * While slice 5 is scaled vertical and horizontal, slice 2 and 8 are only scaled horizontal.
256  * slice 4 and 6 only vertical. the 4 corner slices are not scaled (1, 3, 7, 9).
257  */
258 void
SWFMovieClip_setScalingGrid(SWFMovieClip clip,int x,int y,int w,int h)259 SWFMovieClip_setScalingGrid(SWFMovieClip clip, int x, int y, int w, int h)
260 {
261 	if(clip->sprite.grid)
262 		destroySWFScalingGrid(clip->sprite.grid);
263 
264 	clip->sprite.grid = newSWFScalingGrid((SWFCharacter)clip, x, y, w, h);
265 }
266 
267 /*
268  * removes the scaling grid
269  */
270 void
SWFMovieClip_removeScalingGrid(SWFMovieClip clip)271 SWFMovieClip_removeScalingGrid(SWFMovieClip clip)
272 {
273 	if(clip->sprite.grid)
274 	{
275 		destroySWFScalingGrid(clip->sprite.grid);
276 		clip->sprite.grid = NULL;
277 	}
278 }
279 
280 /*
281  * add an initAction block to a MovieClip
282  *
283  * These actions are executed *before* the MovieClip is available as
284  * a script object.
285  */
286 void
SWFMovieClip_addInitAction(SWFMovieClip clip,SWFAction action)287 SWFMovieClip_addInitAction(SWFMovieClip clip, SWFAction action)
288 {
289 	if(clip->sprite.initAction)
290 		destroySWFInitAction(clip->sprite.initAction);
291 
292 	clip->sprite.initAction = newSWFInitAction_MovieClip(clip, action);
293 }
294 /*
295  * Local variables:
296  * tab-width: 2
297  * c-basic-offset: 2
298  * End:
299  */
300