+ syntaxerror("Invalid point: \"%s\".", name);
+ }
+ return *(SPOINT*)&mpoints.buffer[l-1];
+}
+
+
+static int texture2(const char*name, const char*object, map_t*args, int errors)
+{
+ SPOINT pos,size;
+ const char*xstr = map_lookup(args, "x");
+ const char*ystr = map_lookup(args, "y");
+ const char*widthstr = map_lookup(args, "width");
+ const char*heightstr = map_lookup(args, "height");
+ const char*scalestr = map_lookup(args, "scale");
+ const char*scalexstr = map_lookup(args, "scalex");
+ const char*scaleystr = map_lookup(args, "scaley");
+ const char*rotatestr = map_lookup(args, "rotate");
+ const char* shearstr = map_lookup(args, "shear");
+ const char* radiusstr = map_lookup(args, "r");
+ float x=0,y=0;
+ float scalex = 1.0, scaley = 1.0;
+ float rotate=0, shear=0;
+ float r = 0;
+ if(!*xstr && !*ystr) {
+ if(errors)
+ syntaxerror("x and y must be set");
+ return 0;
+ }
+ if(*scalestr && (*scalexstr || *scaleystr)) {
+ syntaxerror("scale and scalex/scaley can't both be set");
+ return 0;
+ }
+ if((*widthstr || *heightstr) && *radiusstr) {
+ syntaxerror("width/height and radius can't both be set");
+ }
+ if(*radiusstr) {
+ widthstr = radiusstr;
+ heightstr = radiusstr;
+ }
+ if(!*xstr) xstr="0";
+ if(!*ystr) ystr="0";
+ if(!*rotatestr) rotatestr="0";
+ if(!*shearstr) shearstr="0";
+
+ if(*scalestr) {
+ scalex = scaley = parsePercent(scalestr);
+ } else if(*scalexstr || *scaleystr) {
+ if(scalexstr) scalex = parsePercent(scalexstr);
+ if(scaleystr) scaley = parsePercent(scaleystr);
+ } else if(*widthstr || *heightstr) {
+ int width=0;
+ int height=0;
+ s_getBitmapSize(object, &width, &height);
+ if(*widthstr)
+ scalex = (float)parseTwip(widthstr)/(float)width;
+ if(*heightstr)
+ scaley = (float)parseTwip(heightstr)/(float)height;
+ }
+ x = parseTwip(xstr);
+ y = parseTwip(ystr);
+ rotate = parseFloat(rotatestr);
+ shear = parseFloat(shearstr);
+
+ s_texture(name, object, x,y,scalex,scaley,rotate, shear);
+
+ return 0;
+}
+
+static int c_texture(map_t*args)
+{
+ const char*name = lu(args, "instance");
+ const char*object = lu(args, "character");
+ return texture2(name, object, args, 1);
+}
+
+static int c_gradient(map_t*args)
+{
+ const char*name = lu(args, "name");
+ int radial= strcmp(lu(args, "radial"), "radial")?0:1;
+ int rotate = parseInt(lu(args, "rotate"));
+
+ readToken();
+ if(type != RAWDATA)
+ syntaxerror("colon (:) expected");
+
+ if(dict_lookup(&gradients, name))
+ syntaxerror("gradient %s defined twice", name);
+
+ s_gradient(name, text, radial, rotate);
+
+ /* check whether we also have placement information,
+ which would make this a positioned gradient.
+ If there is placement information, texture2() will
+ add a texture, which has priority over the gradient.
+ */
+ texture2(name, name, args, 0);
+ return 0;
+}
+
+static const char* checkFiltername(map_t* args)
+{
+ const char* name = lu(args, "name");
+ if (strchr(name, ','))
+ syntaxerror("the comma (,) is used to separate filters in filterlists. Please do not use in filternames.");
+ return name;
+}
+
+static int c_blur(map_t*args)
+{
+ const char*name = checkFiltername(args);
+ const char*blurstr = lu(args, "blur");
+ const char*blurxstr = lu(args, "blurx");
+ const char*blurystr = lu(args, "blury");
+ float blurx=1.0, blury=1.0;
+ if(blurstr[0]) {
+ blurx = parseFloat(blurstr);
+ blury = parseFloat(blurstr);
+ }
+ if(blurxstr[0])
+ blurx = parseFloat(blurxstr);
+ if(blurystr[0])
+ blury = parseFloat(blurystr);
+ int passes = parseInt(lu(args, "passes"));
+ s_blur(name, blurx, blury, passes);
+ return 0;
+}
+
+static int c_gradientglow(map_t*args)
+{
+ const char*name = checkFiltername(args);
+ const char*gradient = lu(args, "gradient");
+ const char*blurstr = lu(args, "blur");
+ const char*blurxstr = lu(args, "blurx");
+ const char*blurystr = lu(args, "blury");
+ float blurx=1.0, blury=1.0;
+ if(blurstr[0]) {
+ blurx = parseFloat(blurstr);
+ blury = parseFloat(blurstr);
+ }
+ if(blurxstr[0])
+ blurx = parseFloat(blurxstr);
+ if(blurystr[0])
+ blury = parseFloat(blurystr);
+
+ float angle = parseFloat(lu(args, "angle")) / 180 * M_PI;
+ float distance = parseFloat(lu(args, "distance"));
+ float strength = parseFloat(lu(args, "strength"));
+ char innershadow = strcmp(lu(args, "innershadow"),"innershadow")?0:1;
+ char knockout = strcmp(lu(args, "knockout"),"knockout")?0:1;
+ char composite = strcmp(lu(args, "composite"),"composite")?0:1;
+ char ontop = strcmp(lu(args, "ontop"),"ontop")?0:1;
+ int passes = parseInt(lu(args, "passes"));
+
+ s_gradientglow(name, gradient, blurx, blury, angle, distance, strength, innershadow, knockout, composite, ontop, passes);
+ return 0;
+}
+
+static int c_dropshadow(map_t*args)
+{
+ const char*name = checkFiltername(args);
+ RGBA color = parseColor(lu(args, "color"));
+ const char*blurstr = lu(args, "blur");
+ const char*blurxstr = lu(args, "blurx");
+ const char*blurystr = lu(args, "blury");
+ float blurx=1.0, blury=1.0;
+ if(blurstr[0]) {
+ blurx = parseFloat(blurstr);
+ blury = parseFloat(blurstr);
+ }
+ if(blurxstr[0])
+ blurx = parseFloat(blurxstr);
+ if(blurystr[0])
+ blury = parseFloat(blurystr);
+
+ float angle = parseFloat(lu(args, "angle")) / 180 * M_PI;
+ float distance = parseFloat(lu(args, "distance"));
+ float strength = parseFloat(lu(args, "strength"));
+ char innershadow = strcmp(lu(args, "innershadow"),"innershadow")?0:1;
+ char knockout = strcmp(lu(args, "knockout"),"knockout")?0:1;
+ char composite = strcmp(lu(args, "composite"),"composite")?0:1;
+ int passes = parseInt(lu(args, "passes"));
+
+ s_dropshadow(name, color, blurx, blury, angle, distance, strength, innershadow, knockout, composite, passes);
+ return 0;
+}
+
+static int c_bevel(map_t*args)
+{
+ const char*name = checkFiltername(args);
+ RGBA shadow = parseColor(lu(args, "shadow"));
+ RGBA highlight = parseColor(lu(args, "highlight"));
+ const char*blurstr = lu(args, "blur");
+ const char*blurxstr = lu(args, "blurx");
+ const char*blurystr = lu(args, "blury");
+ float blurx=1.0, blury=1.0;
+ if(blurstr[0]) {
+ blurx = parseFloat(blurstr);
+ blury = parseFloat(blurstr);
+ }
+ if(blurxstr[0])
+ blurx = parseFloat(blurxstr);
+ if(blurystr[0])
+ blury = parseFloat(blurystr);
+
+ float angle = parseFloat(lu(args, "angle")) / 180 * M_PI;
+ float distance = parseFloat(lu(args, "distance"));
+ float strength = parseFloat(lu(args, "strength"));
+ char innershadow = strcmp(lu(args, "innershadow"),"innershadow")?0:1;
+ char knockout = strcmp(lu(args, "knockout"),"knockout")?0:1;
+ char composite = strcmp(lu(args, "composite"),"composite")?0:1;
+ char ontop = strcmp(lu(args, "ontop"),"ontop")?0:1;
+ int passes = parseInt(lu(args, "passes"));
+
+ s_bevel(name, shadow, highlight, blurx, blury, angle, distance, strength, innershadow, knockout, composite, ontop, passes);
+ return 0;
+}
+
+static int c_define(map_t*args)
+{
+ const char*name = lu(args, "name");
+ const char*value = lu(args, "value");
+
+ if(!defines_initialized) {
+ dict_init(&defines, 16);
+ mem_init(&define_values);
+ defines_initialized = 1;
+ }
+ int val = parseTwip(value);
+ int pos = mem_put(&define_values, &val, sizeof(val));
+ dict_put(&defines, name, (void*)(pos+1));
+ return 0;
+}
+static int c_point(map_t*args)
+{
+ const char*name = lu(args, "name");
+ int pos;
+ SPOINT p;
+ if(!points_initialized) {
+ dict_init(&points, 16);
+ mem_init(&mpoints);
+ points_initialized = 1;
+ }
+ p.x = parseTwip(lu(args, "x"));
+ p.y = parseTwip(lu(args, "y"));
+ pos = mem_put(&mpoints, &p, sizeof(p));
+ dict_put(&points, name, (void*)(pos+1));
+ return 0;
+}
+static int c_play(map_t*args)
+{
+ const char*name = lu(args, "name");
+ const char*loop = lu(args, "loop");
+ const char*nomultiple = lu(args, "nomultiple");
+ int nm = 0;
+ if(!strcmp(nomultiple, "nomultiple"))
+ nm = 1;
+ else
+ nm = parseInt(nomultiple);
+
+ if(s_playsound(name, parseInt(loop), nm, 0)) {
+ return 0;
+ } else if(s_swf3action(name, "play")) {
+ return 0;
+ }
+ return 0;
+}
+
+static int c_stop(map_t*args)
+{
+ const char*name = map_lookup(args, "name");
+
+ if(s_playsound(name, 0,0,1))
+ return 0;
+ else if(s_swf3action(name, "stop"))
+ return 0;
+ syntaxerror("I don't know anything about sound/movie \"%s\"", name);
+ return 0;
+}
+
+static int c_nextframe(map_t*args)
+{
+ const char*name = lu(args, "name");
+
+ if(s_swf3action(name, "nextframe")) {
+ return 0;
+ }
+ syntaxerror("I don't know anything about movie \"%s\"", name);
+ return 0;
+}
+
+static int c_previousframe(map_t*args)
+{
+ const char*name = lu(args, "name");
+
+ if(s_swf3action(name, "previousframe")) {
+ return 0;