void change_append(change_t* first, change_t* newChange)
{
+ change_t* previous = 0;
+ change_t* start = first;
+ float p0, p1, m0, m1;
+
while (first->next)
+ {
+ previous = first;
first = first->next;
+ }
first->next = newChange;
+ if (first->function == CF_QCHANGE)
+ {
+ p0 = previous->value;
+ p1 = first->value;
+ if (previous->function == CF_QCHANGE)
+ m0 = (3 * previous->spline.a + 2 * previous->spline.b + previous->spline.c);
+ else
+ if (previous->function == CF_CHANGE)
+ m0 = (change_value(start, previous->frame) - change_value(start, previous->frame - 1)) * (first->frame - previous->frame);
+ else
+ m0 = (first->value - previous->value);
+ if (newChange->function == CF_QCHANGE)
+ m1 = 0.5 * (newChange->value - previous->value);
+ else
+ if (newChange->function == CF_CHANGE)
+ m1 = (change_value(previous, first->frame + 1) - change_value(previous, first->frame)) * (first->frame - previous->frame);
+ else
+ m1 = (first->value - previous->value);
+ first->spline.a = 2 * p0 + m0 - 2 * p1 + m1;
+ first->spline.b = -3 * p0 - 2 * m0 + 3 * p1 - m1;
+ first->spline.c = m0;
+ first->spline.d = p0;
+ }
+ if (newChange->function == CF_QCHANGE)
+ {
+ p0 = first->value;
+ p1 = newChange->value;
+ if (first->function == CF_QCHANGE)
+ m0 = m1;
+ else
+ if (first->function == CF_CHANGE)
+ m0 = (change_value(start, first->frame) - change_value(start, first->frame - 1)) * (first->frame - previous->frame);
+ else
+ m0 = (newChange->value - first->value);
+ m1 = (newChange->value - first->value);
+ newChange->spline.a = 2 * p0 + m0 - 2 * p1 + m1;
+ newChange->spline.b = -3 * p0 - 2 * m0 + 3 * p1 - m1;
+ newChange->spline.c = m0;
+ newChange->spline.d = p0;
+ }
}
-float interpolateParameter(float p1, float p2, float fraction, interpolation_t* inter)
+float calculateSpline(change_t* modification, float fraction)
+{
+ spline_t s = modification->spline;
+ return (((s.a * fraction) + s.b) * fraction + s.c) * fraction + s.d;
+}
+
+float interpolateScalar(float p1, float p2, float fraction, interpolation_t* inter)
{
if (!inter)
return linear(fraction, p1, p2 - p1);
}
}
-float change_value(change_t* first, U16 frame)
+int change_differs(change_t* modification, U16 frame)
{
- change_t* previous = first;
- while (first && first->frame < frame)
+ change_t* previous = modification;
+ while (modification && modification->frame < frame)
{
- previous = first;
- first = first->next;
+ previous = modification;
+ modification = modification->next;
+ }
+ if (!modification)
+ return 0;
+ if (modification->frame == frame)
+ return 1;
+ return (modification->function != CF_JUMP);
}
- if (!first)
+
+float change_value(change_t* modification, U16 frame)
+{
+ change_t* previous = modification;
+ while (modification && modification->frame < frame)
+ {
+ previous = modification;
+ modification = modification->next;
+ }
+ if (!modification)
return previous->value;
- if (first->frame == frame)
+ if (modification->frame == frame)
{
- float result;
do
{
- result = first->value;
- first = first->next;
+ previous = modification;
+ modification = modification->next;
}
- while (first && first->frame == frame);
- return result;
+ while (modification && modification->frame == frame);
+ return previous->value;
}
- switch (first->function)
+ switch (modification->function)
{
case CF_PUT:
- return first->value;
+ return modification->value;
case CF_CHANGE:
{
- float fraction = (frame - previous->frame) / (float)(first->frame - previous->frame);
- return interpolateParameter(previous->value, first->value, fraction, first->interpolation);
+ float fraction = (frame - previous->frame) / (float)(modification->frame - previous->frame);
+ return interpolateScalar(previous->value, modification->value, fraction, modification->interpolation);
+ }
+ case CF_QCHANGE:
+ {
+ float fraction = (frame - previous->frame) / (float)(modification->frame - previous->frame);
+ return calculateSpline(modification, fraction);
}
case CF_JUMP:
return previous->value;
RGBA interpolateColor(RGBA c1, RGBA c2, float ratio, interpolation_t* inter)
{
RGBA c;
- c.r = c1.r * (1-ratio) + c2.r * ratio;
- c.g = c1.g * (1-ratio) + c2.g * ratio;
- c.b = c1.b * (1-ratio) + c2.b * ratio;
- c.a = c1.a * (1-ratio) + c2.a * ratio;
+ c.r = interpolateScalar(c1.r, c2.r, ratio, inter);
+ c.g = interpolateScalar(c1.g, c2.g, ratio, inter);
+ c.b = interpolateScalar(c1.b, c2.b, ratio, inter);
+ c.a = interpolateScalar(c1.a, c2.a, ratio, inter);
return c;
}
-FILTER* interpolateFilter(FILTER* filter1,FILTER* filter2, float ratio, interpolation_t* inter)
+GRADIENT* interpolateNodes(GRADIENT* g1, GRADIENT* g2, float fraction, interpolation_t* inter)
{
- if(!filter1 && !filter2)
- return 0;
- if(!filter1)
- return interpolateFilter(filter2,filter1,1-ratio, inter);
+ if (g1->num != g2->num)
+ syntaxerror("Internal error: gradients are not equal in size");
- if(filter2 && filter2->type != filter1->type)
- syntaxerror("can't interpolate between %s and %s filters yet", filtername[filter1->type], filtername[filter2->type]);
+ int i;
+ GRADIENT* g = (GRADIENT*) malloc(sizeof(GRADIENT));
+ g->ratios = rfx_calloc(16*sizeof(U8));
+ g->rgba = rfx_calloc(16*sizeof(RGBA));
+ g->num = g1->num;
+ for (i = 0; i < g->num; i++)
+ {
+ g->ratios[i] = interpolateScalar(g1->ratios[i], g2->ratios[i], fraction, inter);
+ g->rgba[i] = interpolateColor(g1->rgba[i], g2->rgba[i], fraction, inter);
+ }
+ return g;
+}
+
+void copyGradient(GRADIENT* dest, GRADIENT* source)
+{
+ dest->num = source->num;
+ memcpy(dest->ratios, source->ratios, source->num * sizeof(U8));
+ memcpy(dest->rgba, source->rgba, source->num * sizeof(RGBA));
+}
+
+void insertNode(GRADIENT* g, int pos)
+{
+ memmove(&g->ratios[pos + 1], &g->ratios[pos], (g->num - pos) * sizeof(U8));
+ memmove(&g->rgba[pos + 1], &g->rgba[pos], (g->num - pos) * sizeof(RGBA));
+ if (pos == 0)
+ {
+ g->ratios[0] = g->ratios[1] / 2;
+ g->rgba[0] = g->rgba[1];
+ }
+ else
+ if (pos == g->num)
+ {
+ g->ratios[pos] = (255 + g->ratios[g->num - 1]) / 2;
+ g->rgba[pos] = g->rgba[pos - 1];
+ }
+ else
+ {
+ g->ratios[pos] = (g->ratios[pos - 1] + g->ratios[pos + 1]) / 2;
+ g->rgba[pos] = interpolateColor(g->rgba[pos - 1], g->rgba[pos + 1], 0.5, 0);
+ }
+ g->num++;
+}
+
+void insertOptimalNode(GRADIENT* g)
+{
+ int i, next_gap;
+ int pos = 0;
+ int gap = g->ratios[0];
+ for (i = 0; i < g->num - 1; i++)
+ {
+ next_gap = g->ratios[i + 1] - g->ratios[i];
+ if (next_gap > gap)
+ {
+ gap = next_gap;
+ pos = i + 1;
+ }
+ }
+ next_gap = 255 - g->ratios[g->num -1];
+ if (next_gap > gap)
+ pos = g->num;
+ insertNode(g, pos);
+}
- if(filter1->type == FILTERTYPE_BLUR)
+void growGradient(GRADIENT* start, int size)
+{
+ while (start->num < size)
+ insertOptimalNode(start);
+}
+
+GRADIENT* interpolateGradient(GRADIENT* g1, GRADIENT* g2, float fraction, interpolation_t* inter)
+{
+ int i;
+ GRADIENT g;
+ g.ratios = rfx_calloc(16*sizeof(U8));
+ g.rgba = rfx_calloc(16*sizeof(RGBA));
+
+ if (g1->num > g2->num)
+ {
+ copyGradient(&g, g2);
+ growGradient(&g, g1->num);
+ GRADIENT* result = interpolateNodes(g1, &g, fraction, inter);
+ rfx_free(g.rgba);
+ rfx_free(g.ratios);
+ return result;
+ }
+ else
+ if (g1->num < g2->num)
+ {
+ copyGradient(&g, g1);
+ growGradient(&g, g2->num);
+ GRADIENT* result = interpolateNodes(&g, g2, fraction, inter);
+ rfx_free(g.rgba);
+ rfx_free(g.ratios);
+ return result;
+ }
+ else
+ return interpolateNodes(g1, g2, fraction, inter);
+}
+
+FILTER* interpolateBlur(FILTER* filter1, FILTER* filter2, float ratio, interpolation_t* inter)
{
FILTER_BLUR*f1 = (FILTER_BLUR*)filter1;
FILTER_BLUR*f2 = (FILTER_BLUR*)filter2;
- if(f2 && f1->blurx == f2->blurx && f1->blury == f2->blury)
+ if (!f1)
+ f1 = noBlur;
+ if (!f2)
+ f2 = noBlur;
+ if(f1->blurx == f2->blurx && f1->blury == f2->blury)
return 0;
FILTER_BLUR*f = (FILTER_BLUR*)swf_NewFilter(FILTERTYPE_BLUR);
- f->blurx= (f1->blurx)*(1-ratio) + (f2?f2->blurx:0)*ratio;
- f->blury= (f1->blury)*(1-ratio) + (f2?f2->blury:0)*ratio;
- f->passes= (f1->passes)*(1-ratio) + (f2?f2->passes:0)*ratio;
+ f->blurx= interpolateScalar(f1->blurx, (f2->blurx), ratio, inter);
+ f->blury= interpolateScalar(f1->blury, (f2->blury), ratio, inter);
+ f->passes= interpolateScalar(f1->passes, (f2->passes), ratio, inter);
return (FILTER*)f;
}
- else
- if (filter1->type == FILTERTYPE_DROPSHADOW)
+
+void matchDropshadowFlags(FILTER_DROPSHADOW* unset, FILTER_DROPSHADOW* target)
+{
+ unset->innershadow = target->innershadow;
+ unset->knockout = target->knockout;
+ unset->composite = target->composite;
+}
+
+FILTER* interpolateDropshadow(FILTER* filter1,FILTER* filter2, float ratio, interpolation_t* inter)
{
FILTER_DROPSHADOW*f1 = (FILTER_DROPSHADOW*)filter1;
FILTER_DROPSHADOW*f2 = (FILTER_DROPSHADOW*)filter2;
- if(f2 && !memcmp(&f1->color,&f2->color,sizeof(RGBA)) && f1->strength == f2->strength &&
+ if (!f1)
+ f1 = noDropshadow;
+ if (!f2)
+ f2 = noDropshadow;
+ if(!memcmp(&f1->color,&f2->color,sizeof(RGBA)) && f1->strength == f2->strength &&
f1->blurx == f2->blurx && f1->blury == f2->blury &&
f1->angle == f2->angle && f1->distance == f2->distance)
return 0;
FILTER_DROPSHADOW*f = (FILTER_DROPSHADOW*)swf_NewFilter(FILTERTYPE_DROPSHADOW);
memcpy(f, f1, sizeof(FILTER_DROPSHADOW));
f->color = interpolateColor(f1->color, f2->color, ratio, inter);
- f->blurx= (f1->blurx)*(1-ratio) + (f2?f2->blurx:0)*ratio;
- f->blury= (f1->blury)*(1-ratio) + (f2?f2->blury:0)*ratio;
- f->passes= (f1->passes)*(1-ratio) + (f2?f2->passes:0)*ratio;
- f->angle= (f1->angle)*(1-ratio) + (f2?f2->angle:0)*ratio;
- f->distance= (f1->distance)*(1-ratio) + (f2?f2->distance:0)*ratio;
- f->strength= (f1->strength)*(1-ratio) + (f2?f2->strength:0)*ratio;
- return (FILTER*)f;
+ f->blurx= interpolateScalar(f1->blurx, (f2->blurx), ratio, inter);
+ f->blury= interpolateScalar(f1->blury, (f2->blury), ratio, inter);
+ f->passes= interpolateScalar(f1->passes, (f2->passes), ratio, inter);
+ f->angle= interpolateScalar(f1->angle, (f2->angle), ratio, inter);
+ f->distance= interpolateScalar(f1->distance, (f2->distance), ratio, inter);
+ f->strength= interpolateScalar(f1->strength, (f2->strength), ratio, inter);
+ if (f1 == noDropshadow)
+ {
+ if (f2 != noDropshadow)
+ matchDropshadowFlags(f, f2);
}
else
- if (filter1->type == FILTERTYPE_BEVEL)
+ if (f2 == noDropshadow)
+ matchDropshadowFlags(f, f1);
+ else
+ if (ratio > 0.5)
+ matchDropshadowFlags(f, f2);
+ else
+ matchDropshadowFlags(f, f1);
+ return (FILTER*)f;
+}
+
+void matchBevelFlags(FILTER_BEVEL* unset, FILTER_BEVEL* target)
+{
+ unset->innershadow = target->innershadow;
+ unset->knockout = target->knockout;
+ unset->composite = target->composite;
+ unset->ontop = target->ontop;
+}
+
+FILTER* interpolateBevel(FILTER* filter1,FILTER* filter2, float ratio, interpolation_t* inter)
{
FILTER_BEVEL*f1 = (FILTER_BEVEL*)filter1;
FILTER_BEVEL*f2 = (FILTER_BEVEL*)filter2;
- if(f2 && !memcmp(&f1->shadow,&f2->shadow,sizeof(RGBA)) &&
+ if (!f1)
+ f1 = noBevel;
+ if (!f2)
+ f2 = noBevel;
+ if(!memcmp(&f1->shadow,&f2->shadow,sizeof(RGBA)) &&
!memcmp(&f1->highlight,&f2->highlight,sizeof(RGBA)) &&
f1->blurx == f2->blurx && f1->blury == f2->blury && f1->angle == f2->angle && f1->strength == f2->strength && f1->distance == f2->distance)
return 0;
memcpy(f, f1, sizeof(FILTER_BEVEL));
f->shadow = interpolateColor(f1->shadow, f2->shadow, ratio, inter);
f->highlight = interpolateColor(f1->highlight, f2->highlight, ratio, inter);
- f->blurx= (f1->blurx)*(1-ratio) + (f2?f2->blurx:0)*ratio;
- f->blury= (f1->blury)*(1-ratio) + (f2?f2->blury:0)*ratio;
- f->passes= (f1->passes)*(1-ratio) + (f2?f2->passes:0)*ratio;
- f->angle= (f1->angle)*(1-ratio) + (f2?f2->angle:0)*ratio;
- f->distance= (f1->distance)*(1-ratio) + (f2?f2->distance:0)*ratio;
- f->strength= (f1->strength)*(1-ratio) + (f2?f2->strength:0)*ratio;
+ f->blurx= interpolateScalar(f1->blurx, (f2->blurx), ratio, inter);
+ f->blury= interpolateScalar(f1->blury, (f2->blury), ratio, inter);
+ f->passes= interpolateScalar(f1->passes, (f2->passes), ratio, inter);
+ f->angle= interpolateScalar(f1->angle, (f2->angle), ratio, inter);
+ f->distance= interpolateScalar(f1->distance, (f2->distance), ratio, inter);
+ f->strength= interpolateScalar(f1->strength, (f2->strength), ratio, inter);
+ if (f1 == noBevel)
+ {
+ if (f2 != noBevel)
+ matchBevelFlags(f, f2);
+ }
+ else
+ if (f2 == noBevel)
+ matchBevelFlags(f, f1);
+ else
+ if (ratio > 0.5)
+ matchBevelFlags(f, f2);
+ else
+ matchBevelFlags(f, f1);
return (FILTER*)f;
- } /*else if (filter1->type == FILTERTYPE_GRADIENTGLOW) {
+}
+
+void matchGradientGlowFlags(FILTER_GRADIENTGLOW* unset, FILTER_GRADIENTGLOW* target)
+{
+ unset->innershadow = target->innershadow;
+ unset->knockout = target->knockout;
+ unset->composite = target->composite;
+ unset->ontop = target->ontop;
+}
+
+FILTER* interpolateGradientGlow(FILTER* filter1,FILTER* filter2, float ratio, interpolation_t* inter)
+{
+ FILTER_GRADIENTGLOW*f1 = (FILTER_GRADIENTGLOW*)filter1;
+ FILTER_GRADIENTGLOW*f2 = (FILTER_GRADIENTGLOW*)filter2;
+ if (!f1)
+ f1 = noGradientGlow;
+ if (!f2)
+ f2 = noGradientGlow;
+ if(f1->gradient->num == f2->gradient->num &&
+ !memcmp(&f1->gradient->ratios,&f2->gradient->ratios,f1->gradient->num * sizeof(U8)) &&
+ !memcmp(&f1->gradient->rgba,&f2->gradient->rgba,f1->gradient->num * sizeof(RGBA)) &&
+ f1->blurx == f2->blurx && f1->blury == f2->blury && f1->angle == f2->angle && f1->strength == f2->strength && f1->distance == f2->distance)
+ return 0;
FILTER_GRADIENTGLOW*f = (FILTER_GRADIENTGLOW*)swf_NewFilter(FILTERTYPE_GRADIENTGLOW);
- // can't interpolate gradients
- memcpy(f, filter1, sizeof(FILTER_GRADIENTGLOW));
+ memcpy(f, f1, sizeof(FILTER_GRADIENTGLOW));
+ f->blurx= interpolateScalar(f1->blurx, (f2->blurx), ratio, inter);
+ f->blury= interpolateScalar(f1->blury, (f2->blury), ratio, inter);
+ f->passes= interpolateScalar(f1->passes, (f2->passes), ratio, inter);
+ f->angle= interpolateScalar(f1->angle, (f2->angle), ratio, inter);
+ f->distance= interpolateScalar(f1->distance, (f2->distance), ratio, inter);
+ double d = f->distance;
+ double fr;
+ if (d < 0)
+ fr = ((int)d - d)*65536;
+ else
+ fr = (d - (int)d)*65536;
+ printf("%.3f <> %.3f : %.3f = %.3f [%.3f . %.3f] - %.5u.%.5u\n", f1->distance, f2->distance, ratio, f->distance, d, fr/65536, (U16)d, (U16)fr);
+ f->strength= interpolateScalar(f1->strength, (f2->strength), ratio, inter);
+ f->gradient= interpolateGradient(f1->gradient, f2->gradient, ratio, inter);
+ if (f1 == noGradientGlow)
+ {
+ if (f2 != noGradientGlow)
+ matchGradientGlowFlags(f, f2);
+ }
+ else
+ if (f2 == noGradientGlow)
+ matchGradientGlowFlags(f, f1);
+ else
+ if (ratio > 0.5)
+ matchGradientGlowFlags(f, f2);
+ else
+ matchGradientGlowFlags(f, f1);
return (FILTER*)f;
- }*/ else
- syntaxerror("can't interpolate %s filters yet", filtername[filter1->type]);
+}
+
+FILTER* interpolateFilter(FILTER* filter1,FILTER* filter2, float ratio, interpolation_t* inter)
+{
+ if(!filter1 && !filter2)
+ return 0;
+
+
+ int filter_type;
+ if (!filter1)
+ filter_type = filter2->type;
+ else
+ if (!filter2)
+ filter_type = filter1->type;
+ else
+ if(filter2->type != filter1->type)
+ syntaxerror("can't interpolate between %s and %s filters yet", filtername[filter1->type], filtername[filter2->type]);
+ else
+ filter_type = filter1->type;
+
+
+ switch (filter_type)
+ {
+ case FILTERTYPE_BLUR:
+ return interpolateBlur(filter1, filter2, ratio, inter);
+ case FILTERTYPE_BEVEL:
+ return interpolateBevel(filter1, filter2, ratio, inter);
+ case FILTERTYPE_DROPSHADOW:
+ return interpolateDropshadow(filter1, filter2, ratio, inter);
+ case FILTERTYPE_GRADIENTGLOW:
+ return interpolateGradientGlow(filter1, filter2, ratio, inter);
+ default:
+ syntaxerror("Filtertype %s not supported yet.\n", filtername[filter1->type]);
+ }
return 0;
}
memcpy(copy, original, sizeof(FILTER_BLUR));
break;
case FILTERTYPE_GRADIENTGLOW:
+ {
memcpy(copy, original, sizeof(FILTER_GRADIENTGLOW));
+ FILTER_GRADIENTGLOW* ggcopy = (FILTER_GRADIENTGLOW*)copy;
+ ggcopy->gradient = (GRADIENT*)malloc(sizeof(GRADIENT));
+ ggcopy->gradient->ratios = (U8*)malloc(16 * sizeof(U8));
+ ggcopy->gradient->rgba = (RGBA*)malloc(16 * sizeof(RGBA));
+ copyGradient(ggcopy->gradient, ((FILTER_GRADIENTGLOW*)original)->gradient);
+ }
break;
case FILTERTYPE_DROPSHADOW:
memcpy(copy, original, sizeof(FILTER_DROPSHADOW));
case FILTERTYPE_BEVEL:
memcpy(copy, original, sizeof(FILTER_BEVEL));
break;
- default: printf("unsupported filterype");
+ default: syntaxerror("Internal error: unsupported filterype");
}
return copy;
}
-FILTER* changeFilter_value(changeFilter_t* first, U16 frame)
+int changeFilter_differs(changeFilter_t* modification, U16 frame)
{
- changeFilter_t* previous = first;
- while (first && first->frame < frame)
+ changeFilter_t* previous = modification;
+ while (modification && modification->frame < frame)
{
- previous = first;
- first = first->next;
+ previous = modification;
+ modification = modification->next;
}
- if (!first)
+ if (!modification)
+ return 0;
+ if (modification->frame == frame)
+ return 1;
+ return (modification->function != CF_JUMP);
+}
+
+FILTER* changeFilter_value(changeFilter_t* modification, U16 frame)
+{
+ changeFilter_t* previous = modification;
+ while (modification && modification->frame < frame)
+ {
+ previous = modification;
+ modification = modification->next;
+ }
+ if (!modification)
return copyFilter(previous->value);
- if (first->frame == frame)
+ if (modification->frame == frame)
{
- FILTER* result;
do
{
- result = first->value;
- first = first->next;
+ previous = modification;
+ modification = modification->next;
}
- while (first && first->frame == frame);
- return copyFilter(result);
+ while (modification && modification->frame == frame);
+ return copyFilter(previous->value);
}
- switch (first->function)
+ switch (modification->function)
{
case CF_PUT:
- return copyFilter(first->value);
+ return copyFilter(modification->value);
case CF_CHANGE:
{
- float fraction = (frame - previous->frame) / (float)(first->frame - previous->frame);
- return interpolateFilter(previous->value, first->value, fraction, first->interpolation);
+ float fraction = (frame - previous->frame) / (float)(modification->frame - previous->frame);
+ return interpolateFilter(previous->value, modification->value, fraction, modification->interpolation);
}
case CF_JUMP:
return copyFilter(previous->value);
}
}
+int history_change(history_t* past, U16 frame, char* parameter)
+{
+ change_t* first = dictionary_lookup(past->changes, parameter);
+ if (first) //should always be true.
+ return change_differs(first, frame);
+ printf("no history found for parameter %s\n", parameter);
+ return 0;
+}
+
float history_value(history_t* past, U16 frame, char* parameter)
{
change_t* first = dictionary_lookup(past->changes, parameter);
return 0;
}
+int history_changeFilter(history_t* past, U16 frame)
+{
+ changeFilter_t* first = dictionary_lookup(past->changes, "filter");
+ if (first) //should always be true.
+ return changeFilter_differs(first, frame);
+ printf("no history found for parameter filter\n");
+ return 0;
+}
+
FILTER* history_valueFilter(history_t* past, U16 frame)
{
changeFilter_t* first = dictionary_lookup(past->changes, "filter");
static int optimize = 0;
static int override_outputname = 0;
static int do_cgi = 0;
+static int change_sets_all = 0;
static struct options_t options[] = {
{"h", "help"},
return m;
}
-void builtInInterpolations()
+void initBuiltIns()
{
interpolation_t* new;
new = (interpolation_t*)malloc(sizeof(interpolation_t));
new = (interpolation_t*)malloc(sizeof(interpolation_t));
new->function = IF_SINE_IN_OUT;
dictionary_put2(&interpolations, "sineInOut", new);
+
+ RGBA c;
+ memset(&c, 0, sizeof(RGBA));
+ gradient_t* noGradient = (gradient_t*)malloc(sizeof(gradient_t));
+ noGradient->gradient.ratios = (U8*)malloc(16 * sizeof(U8));
+ noGradient->gradient.rgba = (RGBA*)malloc(16 * sizeof(RGBA));
+ noGradient->gradient.num = 2;
+ noGradient->gradient.rgba[0] = c;
+ noGradient->gradient.ratios[0] = 0;
+ noGradient->gradient.rgba[1] = c;
+ noGradient->gradient.ratios[1] = 255;
+ noGradient->radial = 0;
+ noGradient->rotate = 0;
+ dictionary_put2(&gradients, "no_gradient", noGradient);
+
+ noBlur = (FILTER_BLUR*) swf_NewFilter(FILTERTYPE_BLUR);
+ noBlur->passes = 1;
+ dictionary_put2(&filters, "no_blur", noBlur);
+ noBevel = (FILTER_BEVEL*) swf_NewFilter(FILTERTYPE_BEVEL);
+ noBevel->passes = 1;
+ dictionary_put2(&filters, "no_bevel", noBevel);
+ noDropshadow = (FILTER_DROPSHADOW*) swf_NewFilter(FILTERTYPE_DROPSHADOW);
+ noDropshadow->passes = 1;
+ dictionary_put2(&filters, "no_dropshadow", noDropshadow);
+ noGradientGlow = (FILTER_GRADIENTGLOW*) swf_NewFilter(FILTERTYPE_GRADIENTGLOW);
+ noGradientGlow->passes = 1;
+ noGradientGlow->gradient = &noGradient->gradient;
+ dictionary_put2(&filters, "no_gradientglow", noGradientGlow);
}
void s_swf(char*name, SRECT r, int version, int fps, int compress, RGBA background)
dictionary_init(&instances);
dictionary_init(&sounds);
dictionary_init(&interpolations);
- builtInInterpolations();
+ initBuiltIns();
cleanUp = &freeDictionaries;
memset(&stack[stackpos], 0, sizeof(stack[0]));
return save;
}
+static int parametersChange(history_t* history, int frame)
+{
+ int willChange = 0;
+
+ willChange = willChange || history_change(history, frame, "x");
+ willChange = willChange || history_change(history, frame, "y");
+ willChange = willChange || history_change(history, frame, "scalex");
+ willChange = willChange || history_change(history, frame, "scaley");
+ willChange = willChange || history_change(history, frame, "cxform.r0");
+ willChange = willChange || history_change(history, frame, "cxform.g0");
+ willChange = willChange || history_change(history, frame, "cxform.b0");
+ willChange = willChange || history_change(history, frame, "cxform.a0");
+ willChange = willChange || history_change(history, frame, "cxform.r1");
+ willChange = willChange || history_change(history, frame, "cxform.g1");
+ willChange = willChange || history_change(history, frame, "cxform.b1");
+ willChange = willChange || history_change(history, frame, "cxform.a1");
+ willChange = willChange || history_change(history, frame, "rotate");
+ willChange = willChange || history_change(history, frame, "shear");
+ willChange = willChange || history_change(history, frame, "pivot.x");
+ willChange = willChange || history_change(history, frame, "pivot.y");
+ willChange = willChange || history_change(history, frame, "pin.x");
+ willChange = willChange || history_change(history, frame, "pin.y");
+ willChange = willChange || history_change(history, frame, "blendmode");
+ willChange = willChange || history_changeFilter(history, frame);
+
+ return willChange;
+}
+
static void readParameters(history_t* history, parameters_t* p, int frame)
{
p->x = history_value(history, frame, "x");
while (frame < currentframe)
{
frame++;
- readParameters(i->history, &p, frame);
while (tag->id != ST_SHOWFRAME)
tag = tag->next;
+ if (parametersChange(i->history, frame))
+ {
+ readParameters(i->history, &p, frame);
m = s_instancepos(i->character->size, &p);
if(p.blendmode || p.filter)
tag = swf_InsertTag(tag, ST_PLACEOBJECT2);
setPlacement(tag, 0, i->depth, m, 0, &p, 1);
if (p.filter)
+ {
+ if (p.filter->type == FILTERTYPE_GRADIENTGLOW)
+ gradient_free(((FILTER_GRADIENTGLOW*)p.filter)->gradient);
free(p.filter);
}
}
+ else
+ tag = tag->next;
+ }
+}
void dumpSWF(SWF*swf)
{
num++;
name = stringarray_at(index, num);
}
+ while (tag->next)
+ tag = tag->next;
tag = swf_InsertTag(tag, ST_SHOWFRAME);
tag = swf_InsertTag(tag, ST_END);
syntaxerror("filter %s defined twice", name);
gradient_t* g = dictionary_lookup(&gradients, gradient);
+ if(!g)
+ syntaxerror("unknown gradient %s", gradient);
composite = 1;
- if(!g)
- syntaxerror("unknown gradient %s", gradient);
FILTER_GRADIENTGLOW* filter = rfx_calloc(sizeof(FILTER_GRADIENTGLOW));
filter->type = FILTERTYPE_GRADIENTGLOW;
filter->gradient = &g->gradient;
if(!c) syntaxerror("internal error(5)");
return c->size;
}
-parameters_t s_getParameters(char*name)
+void s_getParameters(char*name, parameters_t* p)
{
instance_t * i = dictionary_lookup(&instances, name);
- if(!i) syntaxerror("instance '%s' unknown(10)", name);
- return i->parameters;
+ if(!i)
+ syntaxerror("instance '%s' unknown(10)", name);
+ if (change_sets_all)
+ readParameters(i->history, p, currentframe);
+ else
+ *p = i->parameters;
}
void s_startclip(char*instance, char*character, parameters_t p)
{
instance_t* i = dictionary_lookup(&instances, instance);
if(!i)
syntaxerror("instance %s not known", instance);
+
recordChanges(i->history, p2, CF_CHANGE, inter);
}
{
char* filename = map_lookup(args, "filename");
char* compressstr = lu(args, "compress");
+ char* change_modestr = lu(args, "change-sets-all");
SRECT bbox = parseBox(lu(args, "bbox"));
int version = parseInt(lu(args, "version"));
int fps = (int)(parseFloat(lu(args, "fps"))*256);
- int compress = 0;
RGBA color = parseColor(lu(args, "background"));
+ int compress = 0;
if(!filename || !*filename) {
/* for compatibility */
compress = 0;
else syntaxerror("value \"%s\" not supported for the compress argument", compressstr);
+ if(!strcmp(change_modestr, "yes"))
+ change_sets_all = 1;
+ else
+ if(strcmp(change_modestr, "no"))
+ syntaxerror("value \"%s\" not supported for the change-sets-all argument", change_modestr);
+
s_swf(filename, bbox, version, fps, compress, color);
return 0;
}
SRECT oldbbox;
MULADD luminance;
parameters_t p;
- U32 set = 0x00000000;
+ U16 set = 0x0000;
if(type==9)
{ // (?) .rotate or .arcchange
parameters_clear(&p);
// button's show
} else {
- p = s_getParameters(instance);
+ s_getParameters(instance, &p);
}
/* x,y position */
set = set | SF_FILTER;
}
+ if (change_sets_all)
+ set = SF_ALL;
p.set = set;
switch (type)
command_func_t* func;
char*arguments;
} arguments[] =
-{{"flash", c_flash, "bbox=autocrop background=black version=6 fps=50 name= filename= @compress=default"},
+{{"flash", c_flash, "bbox=autocrop background=black version=6 fps=50 name= filename= @compress=default @change-sets-all=no"},
{"frame", c_frame, "n=<plus>1 name= @cut=no @anchor=no"},
// "import" type stuff
{"swf", c_swf, "name filename"},