1 /* swfc- Compiles swf code (.sc) files into .swf files.
3 Part of the swftools package.
5 Copyright (c) 2007 Huub Schaeks <huub@h-schaeks.speedlinq.nl>
6 Copyright (c) 2007 Matthias Kramm <kramm@quiss.org>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
26 change_t* change_new(U16 frame, int function, float value, interpolation_t* inter)
28 change_t* newChange = (change_t*)malloc(sizeof(change_t));
29 change_init(newChange);
30 newChange->frame = frame;
31 newChange->function = function;
32 newChange->value = value;
33 newChange->interpolation = inter;
37 void change_free(change_t *change)
40 change_free(change->next);
44 void change_init(change_t* change)
46 memset(change, 0, sizeof(change_t));
49 void change_append(change_t* first, change_t* newChange)
53 first->next = newChange;
56 float interpolateParameter(float p1, float p2, float fraction, interpolation_t* inter)
59 return linear(fraction, p1, p2 - p1);
60 switch (inter->function)
62 case IF_LINEAR: return linear(fraction, p1, p2 - p1);
63 case IF_QUAD_IN: return quadIn(fraction, p1, p2 - p1);
64 case IF_QUAD_OUT: return quadOut(fraction, p1, p2 - p1);
65 case IF_QUAD_IN_OUT: return quadInOut(fraction, p1, p2 - p1);
66 case IF_CUBIC_IN: return cubicIn(fraction, p1, p2 - p1);
67 case IF_CUBIC_OUT: return cubicOut(fraction, p1, p2 - p1);
68 case IF_CUBIC_IN_OUT: return cubicInOut(fraction, p1, p2 - p1);
69 case IF_QUART_IN: return quartIn(fraction, p1, p2 - p1);
70 case IF_QUART_OUT: return quartOut(fraction, p1, p2 - p1);
71 case IF_QUART_IN_OUT: return quartInOut(fraction, p1, p2 - p1);
72 case IF_QUINT_IN: return quintIn(fraction, p1, p2 - p1);
73 case IF_QUINT_OUT: return quintOut(fraction, p1, p2 - p1);
74 case IF_QUINT_IN_OUT: return quintInOut(fraction, p1, p2 - p1);
75 case IF_CIRCLE_IN: return circleIn(fraction, p1, p2 - p1);
76 case IF_CIRCLE_OUT: return circleOut(fraction, p1, p2 - p1);
77 case IF_CIRCLE_IN_OUT: return circleInOut(fraction, p1, p2 - p1);
78 case IF_EXPONENTIAL_IN: return exponentialIn(fraction, p1, p2 - p1);
79 case IF_EXPONENTIAL_OUT: return exponentialOut(fraction, p1, p2 - p1);
80 case IF_EXPONENTIAL_IN_OUT: return exponentialInOut(fraction, p1, p2 - p1);
81 case IF_SINE_IN: return sineIn(fraction, p1, p2 - p1);
82 case IF_SINE_OUT: return sineOut(fraction, p1, p2 - p1);
83 case IF_SINE_IN_OUT: return sineInOut(fraction, p1, p2 - p1);
84 case IF_ELASTIC_IN: return elasticIn(fraction, p1, p2 - p1, inter->amplitude, inter->bounces, inter->damping);
85 case IF_ELASTIC_OUT: return elasticOut(fraction, p1, p2 - p1, inter->amplitude, inter->bounces, inter->damping);
86 case IF_ELASTIC_IN_OUT: return elasticInOut(fraction, p1, p2 - p1, inter->amplitude, inter->bounces, inter->damping);
87 case IF_BACK_IN: return backIn(fraction, p1, p2 - p1, inter->speed);
88 case IF_BACK_OUT: return backOut(fraction, p1, p2 - p1, inter->speed);
89 case IF_BACK_IN_OUT: return backInOut(fraction, p1, p2 - p1, inter->speed);
90 case IF_BOUNCE_IN: return bounceIn(fraction, p1, p2 - p1, inter->bounces, inter->growth, inter->damping);
91 case IF_BOUNCE_OUT: return bounceOut(fraction, p1, p2 - p1, inter->bounces, inter->growth, inter->damping);
92 case IF_BOUNCE_IN_OUT: return bounceInOut(fraction, p1, p2 - p1, inter->bounces, inter->growth, inter->damping);
93 case IF_FAST_BOUNCE_IN: return fastBounceIn(fraction, p1, p2 - p1, inter->bounces, inter->growth, inter->damping);
94 case IF_FAST_BOUNCE_OUT: return fastBounceOut(fraction, p1, p2 - p1, inter->bounces, inter->growth, inter->damping);
95 case IF_FAST_BOUNCE_IN_OUT: return fastBounceInOut(fraction, p1, p2 - p1, inter->bounces, inter->growth, inter->damping);
96 default: return linear(fraction, p1, p2 - p1);
100 float change_value(change_t* first, U16 frame)
102 change_t* previous = first;
103 while (first && first->frame < frame)
109 return previous->value;
110 if (first->frame == frame)
115 result = first->value;
118 while (first && first->frame == frame);
121 switch (first->function)
127 float fraction = (frame - previous->frame) / (float)(first->frame - previous->frame);
128 return interpolateParameter(previous->value, first->value, fraction, first->interpolation);
131 return previous->value;
137 changeFilter_t* changeFilter_new(U16 frame, int function, FILTER* value, interpolation_t* inter)
139 changeFilter_t* newChange = (changeFilter_t*)malloc(sizeof(changeFilter_t));
140 changeFilter_init(newChange);
141 newChange->frame = frame;
142 newChange->function = function;
143 newChange->value = value;
144 newChange->interpolation = inter;
148 void changeFilter_free(changeFilter_t *change)
151 changeFilter_free(change->next);
155 void changeFilter_init(changeFilter_t* change)
157 memset(change, 0, sizeof(changeFilter_t));
160 void changeFilter_append(changeFilter_t* first, changeFilter_t* newChange)
164 first->next = newChange;
167 RGBA interpolateColor(RGBA c1, RGBA c2, float ratio, interpolation_t* inter)
170 c.r = c1.r * (1-ratio) + c2.r * ratio;
171 c.g = c1.g * (1-ratio) + c2.g * ratio;
172 c.b = c1.b * (1-ratio) + c2.b * ratio;
173 c.a = c1.a * (1-ratio) + c2.a * ratio;
177 FILTER* interpolateFilter(FILTER* filter1,FILTER* filter2, float ratio, interpolation_t* inter)
179 if(!filter1 && !filter2)
182 return interpolateFilter(filter2,filter1,1-ratio, inter);
184 if(filter2 && filter2->type != filter1->type)
185 syntaxerror("can't interpolate between %s and %s filters yet", filtername[filter1->type], filtername[filter2->type]);
187 if(filter1->type == FILTERTYPE_BLUR)
189 FILTER_BLUR*f1 = (FILTER_BLUR*)filter1;
190 FILTER_BLUR*f2 = (FILTER_BLUR*)filter2;
191 if(f2 && f1->blurx == f2->blurx && f1->blury == f2->blury)
193 FILTER_BLUR*f = (FILTER_BLUR*)swf_NewFilter(FILTERTYPE_BLUR);
194 f->blurx= (f1->blurx)*(1-ratio) + (f2?f2->blurx:0)*ratio;
195 f->blury= (f1->blury)*(1-ratio) + (f2?f2->blury:0)*ratio;
196 f->passes= (f1->passes)*(1-ratio) + (f2?f2->passes:0)*ratio;
200 if (filter1->type == FILTERTYPE_DROPSHADOW)
202 FILTER_DROPSHADOW*f1 = (FILTER_DROPSHADOW*)filter1;
203 FILTER_DROPSHADOW*f2 = (FILTER_DROPSHADOW*)filter2;
204 if(f2 && !memcmp(&f1->color,&f2->color,sizeof(RGBA)) && f1->strength == f2->strength &&
205 f1->blurx == f2->blurx && f1->blury == f2->blury &&
206 f1->angle == f2->angle && f1->distance == f2->distance)
208 FILTER_DROPSHADOW*f = (FILTER_DROPSHADOW*)swf_NewFilter(FILTERTYPE_DROPSHADOW);
209 memcpy(f, f1, sizeof(FILTER_DROPSHADOW));
210 f->color = interpolateColor(f1->color, f2->color, ratio, inter);
211 f->blurx= (f1->blurx)*(1-ratio) + (f2?f2->blurx:0)*ratio;
212 f->blury= (f1->blury)*(1-ratio) + (f2?f2->blury:0)*ratio;
213 f->passes= (f1->passes)*(1-ratio) + (f2?f2->passes:0)*ratio;
214 f->angle= (f1->angle)*(1-ratio) + (f2?f2->angle:0)*ratio;
215 f->distance= (f1->distance)*(1-ratio) + (f2?f2->distance:0)*ratio;
216 f->strength= (f1->strength)*(1-ratio) + (f2?f2->strength:0)*ratio;
220 if (filter1->type == FILTERTYPE_BEVEL)
222 FILTER_BEVEL*f1 = (FILTER_BEVEL*)filter1;
223 FILTER_BEVEL*f2 = (FILTER_BEVEL*)filter2;
224 if(f2 && !memcmp(&f1->shadow,&f2->shadow,sizeof(RGBA)) &&
225 !memcmp(&f1->highlight,&f2->highlight,sizeof(RGBA)) &&
226 f1->blurx == f2->blurx && f1->blury == f2->blury && f1->angle == f2->angle && f1->strength == f2->strength && f1->distance == f2->distance)
228 FILTER_BEVEL*f = (FILTER_BEVEL*)swf_NewFilter(FILTERTYPE_BEVEL);
229 memcpy(f, f1, sizeof(FILTER_BEVEL));
230 f->shadow = interpolateColor(f1->shadow, f2->shadow, ratio, inter);
231 f->highlight = interpolateColor(f1->highlight, f2->highlight, ratio, inter);
232 f->blurx= (f1->blurx)*(1-ratio) + (f2?f2->blurx:0)*ratio;
233 f->blury= (f1->blury)*(1-ratio) + (f2?f2->blury:0)*ratio;
234 f->passes= (f1->passes)*(1-ratio) + (f2?f2->passes:0)*ratio;
235 f->angle= (f1->angle)*(1-ratio) + (f2?f2->angle:0)*ratio;
236 f->distance= (f1->distance)*(1-ratio) + (f2?f2->distance:0)*ratio;
237 f->strength= (f1->strength)*(1-ratio) + (f2?f2->strength:0)*ratio;
239 } /*else if (filter1->type == FILTERTYPE_GRADIENTGLOW) {
240 FILTER_GRADIENTGLOW*f = (FILTER_GRADIENTGLOW*)swf_NewFilter(FILTERTYPE_GRADIENTGLOW);
241 // can't interpolate gradients
242 memcpy(f, filter1, sizeof(FILTER_GRADIENTGLOW));
245 syntaxerror("can't interpolate %s filters yet", filtername[filter1->type]);
249 FILTER* copyFilter(FILTER* original)
253 FILTER* copy = swf_NewFilter(original->type);
254 switch (original->type)
256 case FILTERTYPE_BLUR:
257 memcpy(copy, original, sizeof(FILTER_BLUR));
259 case FILTERTYPE_GRADIENTGLOW:
260 memcpy(copy, original, sizeof(FILTER_GRADIENTGLOW));
262 case FILTERTYPE_DROPSHADOW:
263 memcpy(copy, original, sizeof(FILTER_DROPSHADOW));
265 case FILTERTYPE_BEVEL:
266 memcpy(copy, original, sizeof(FILTER_BEVEL));
268 default: printf("unsupported filterype");
273 FILTER* changeFilter_value(changeFilter_t* first, U16 frame)
275 changeFilter_t* previous = first;
276 while (first && first->frame < frame)
282 return copyFilter(previous->value);
283 if (first->frame == frame)
288 result = first->value;
291 while (first && first->frame == frame);
292 return copyFilter(result);
294 switch (first->function)
297 return copyFilter(first->value);
300 float fraction = (frame - previous->frame) / (float)(first->frame - previous->frame);
301 return interpolateFilter(previous->value, first->value, fraction, first->interpolation);
304 return copyFilter(previous->value);
310 history_t* history_new()
312 history_t* newHistory = (history_t*)malloc(sizeof(history_t));
313 history_init(newHistory);
317 void history_free(history_t* past)
319 change_free(dictionary_lookup(past->changes, "x"));
320 change_free(dictionary_lookup(past->changes, "y"));
321 change_free(dictionary_lookup(past->changes, "scalex"));
322 change_free(dictionary_lookup(past->changes, "scaley"));
323 change_free(dictionary_lookup(past->changes, "cxform.r0"));
324 change_free(dictionary_lookup(past->changes, "cxform.g0"));
325 change_free(dictionary_lookup(past->changes, "cxform.b0"));
326 change_free(dictionary_lookup(past->changes, "cxform.a0"));
327 change_free(dictionary_lookup(past->changes, "cxform.r1"));
328 change_free(dictionary_lookup(past->changes, "cxform.g1"));
329 change_free(dictionary_lookup(past->changes, "cxform.b1"));
330 change_free(dictionary_lookup(past->changes, "cxform.a1"));
331 change_free(dictionary_lookup(past->changes, "rotate"));
332 change_free(dictionary_lookup(past->changes, "shear"));
333 change_free(dictionary_lookup(past->changes, "pivot.x"));
334 change_free(dictionary_lookup(past->changes, "pivot.y"));
335 change_free(dictionary_lookup(past->changes, "pin.x"));
336 change_free(dictionary_lookup(past->changes, "pin.y"));
337 change_free(dictionary_lookup(past->changes, "blendmode"));
338 changeFilter_free(dictionary_lookup(past->changes, "filter"));
339 dictionary_destroy(past->changes);
343 void history_init(history_t* past)
345 past->changes = (dictionary_t*)malloc(sizeof(dictionary_t));
346 dictionary_init(past->changes);
349 void history_begin(history_t* past, char* parameter, U16 frame, TAG* tag, float value)
351 change_t* first = change_new(frame, CF_PUT, value, 0);
352 past->firstTag = tag;
353 past->firstFrame = frame;
354 dictionary_put2(past->changes, parameter, first);
357 void history_beginFilter(history_t* past, U16 frame, TAG* tag, FILTER* value)
359 changeFilter_t* first = changeFilter_new(frame, CF_PUT, value, 0);
360 past->firstTag = tag;
361 past->firstFrame = frame;
362 dictionary_put2(past->changes, "filter", first);
365 void history_remember(history_t* past, char* parameter, U16 frame, int function, float value, interpolation_t* inter)
367 change_t* first = dictionary_lookup(past->changes, parameter);
368 if (first) //should always be true
370 change_t* next = change_new(frame, function, value, inter);
371 change_append(first, next);
375 void history_rememberFilter(history_t* past, U16 frame, int function, FILTER* value, interpolation_t* inter)
377 changeFilter_t* first = dictionary_lookup(past->changes, "filter");
378 if (first) //should always be true
380 changeFilter_t* next = changeFilter_new(frame, function, value, inter);
381 changeFilter_append(first, next);
385 float history_value(history_t* past, U16 frame, char* parameter)
387 change_t* first = dictionary_lookup(past->changes, parameter);
388 if (first) //should always be true.
389 return change_value(first, frame);
390 printf("no history found for parameter %s\n", parameter);
394 FILTER* history_valueFilter(history_t* past, U16 frame)
396 changeFilter_t* first = dictionary_lookup(past->changes, "filter");
397 if (first) //should always be true.
398 return changeFilter_value(first, frame);
399 printf("no history found for parameter filter\n");