X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=src%2Fswfc.c;h=131c794d6eccab29070eb4f46ed40400b18d5aee;hb=2c9f24cd50973dd2b69395fb284ca2e8981f93c2;hp=2463d94d862817091211dcd8e3abd9165c295e09;hpb=7d4238427eabb6e382e79031a5172d32b849908d;p=swftools.git diff --git a/src/swfc.c b/src/swfc.c index 2463d94..131c794 100644 --- a/src/swfc.c +++ b/src/swfc.c @@ -32,8 +32,10 @@ #include "../lib/log.h" #include "../lib/args.h" #include "../lib/q.h" +#include "../lib/mp3.h" +#include "../lib/wav.h" #include "parser.h" -#include "wav.h" +#include "../lib/png.h" //#define DEBUG @@ -48,7 +50,6 @@ static struct options_t options[] = { {"V", "version"}, {"v", "verbose"}, {"o", "output"}, -{"O", "optimize"}, {0,0} }; @@ -192,6 +193,7 @@ static int stackpos = 0; static dictionary_t characters; static dictionary_t images; +static dictionary_t textures; static dictionary_t outlines; static dictionary_t gradients; static char idmap[65536]; @@ -240,6 +242,10 @@ typedef struct _gradient { int rotate; } gradient_t; +typedef struct _texture { + FILLSTYLE fs; +} texture_t; + static void character_init(character_t*c) { memset(c, 0, sizeof(character_t)); @@ -395,6 +401,7 @@ void s_swf(char*name, SRECT r, int version, int fps, int compress, RGBA backgrou dictionary_init(&characters); dictionary_init(&images); + dictionary_init(&textures); dictionary_init(&outlines); dictionary_init(&gradients); dictionary_init(&instances); @@ -680,6 +687,7 @@ static void s_endSWF() dictionary_clear(&instances); dictionary_clear(&characters); dictionary_clear(&images); + dictionary_clear(&textures); dictionary_clear(&outlines); dictionary_clear(&gradients); dictionary_clear(&fonts); @@ -721,11 +729,13 @@ void s_frame(int nr, int cut, char*name) if(t==nr-1 && name && *name) { tag = swf_InsertTag(tag, ST_FRAMELABEL); swf_SetString(tag, name); + swf_SetU8(tag, 1); //make this an anchor } } if(nr == 0 && currentframe == 0 && name) { tag = swf_InsertTag(tag, ST_FRAMELABEL); swf_SetString(tag, name); + swf_SetU8(tag, 1); //make this an anchor } if(cut) { @@ -740,15 +750,18 @@ void s_frame(int nr, int cut, char*name) int parseColor2(char*str, RGBA*color); -int addFillStyle(SHAPE*s, SRECT*r, char*texture) +int addFillStyle(SHAPE*s, SRECT*r, char*name) { RGBA color; character_t*image; gradient_t*gradient; - if(texture[0] == '#') { - parseColor2(texture, &color); + texture_t*texture; + if(name[0] == '#') { + parseColor2(name, &color); return swf_ShapeAddSolidFillStyle(s, &color); - } else if((image = dictionary_lookup(&images, texture))) { + } else if ((texture = dictionary_lookup(&textures, name))) { + return swf_ShapeAddFillStyle2(s, &texture->fs); + } else if((image = dictionary_lookup(&images, name))) { MATRIX m; swf_GetMatrix(0, &m); m.sx = 65536.0*20.0*(r->xmax - r->xmin)/image->size.xmax; @@ -756,8 +769,7 @@ int addFillStyle(SHAPE*s, SRECT*r, char*texture) m.tx = r->xmin; m.ty = r->ymin; return swf_ShapeAddBitmapFillStyle(s, &m, image->id, 0); - } /*else if ((texture = dictionary_lookup(&textures, texture))) { - } */ else if ((gradient = dictionary_lookup(&gradients, texture))) { + } else if ((gradient = dictionary_lookup(&gradients, name))) { SRECT r2; MATRIX rot,m; double ccos,csin; @@ -777,10 +789,10 @@ int addFillStyle(SHAPE*s, SRECT*r, char*texture) m.tx = r->xmin + (r->xmax - r->xmin)/2; m.ty = r->ymin + (r->ymax - r->ymin)/2; return swf_ShapeAddGradientFillStyle(s, &m, &gradient->gradient, gradient->radial); - } else if (parseColor2(texture, &color)) { + } else if (parseColor2(name, &color)) { return swf_ShapeAddSolidFillStyle(s, &color); } else { - syntaxerror("not a color/fillstyle: %s", texture); + syntaxerror("not a color/fillstyle: %s", name); return 0; } } @@ -797,16 +809,18 @@ void s_box(char*name, int width, int height, RGBA color, int linewidth, char*tex r2.ymax = height; tag = swf_InsertTag(tag, ST_DEFINESHAPE3); swf_ShapeNew(&s); - if(linewidth) - ls1 = swf_ShapeAddLineStyle(s,linewidth>=20?linewidth-20:0,&color); + if(linewidth) { + linewidth = linewidth>=20?linewidth-20:0; + ls1 = swf_ShapeAddLineStyle(s,linewidth,&color); + } if(texture) fs1 = addFillStyle(s, &r2, texture); swf_SetU16(tag,id); - r.xmin = r2.xmin-linewidth-linewidth/2; - r.ymin = r2.ymin-linewidth-linewidth/2; - r.xmax = r2.xmax+linewidth+linewidth/2; - r.ymax = r2.ymax+linewidth+linewidth/2; + r.xmin = r2.xmin-linewidth/2; + r.ymin = r2.ymin-linewidth/2; + r.xmax = r2.xmax+linewidth/2; + r.ymax = r2.ymax+linewidth/2; swf_SetRect(tag,&r); swf_SetShapeHeader(tag,s); swf_ShapeSetAll(tag,s,0,0,ls1,fs1,0); @@ -835,22 +849,24 @@ void s_filled(char*name, char*outlinename, RGBA color, int linewidth, char*textu tag = swf_InsertTag(tag, ST_DEFINESHAPE3); swf_ShapeNew(&s); - if(linewidth) - ls1 = swf_ShapeAddLineStyle(s,linewidth>=20?linewidth-20:0,&color); + if(linewidth) { + linewidth = linewidth>=20?linewidth-20:0; + ls1 = swf_ShapeAddLineStyle(s,linewidth,&color); + } if(texture) fs1 = addFillStyle(s, &r2, texture); swf_SetU16(tag,id); - rect.xmin = r2.xmin-linewidth-linewidth/2; - rect.ymin = r2.ymin-linewidth-linewidth/2; - rect.xmax = r2.xmax+linewidth+linewidth/2; - rect.ymax = r2.ymax+linewidth+linewidth/2; + rect.xmin = r2.xmin-linewidth/2; + rect.ymin = r2.ymin-linewidth/2; + rect.xmax = r2.xmax+linewidth/2; + rect.ymax = r2.ymax+linewidth/2; swf_SetRect(tag,&rect); swf_SetShapeStyles(tag, s); swf_ShapeCountBits(s,0,0); - swf_RecodeShapeData(outline->shape->data, outline->shape->bitlen, 1, 1, - &s->data, &s->bitlen, s->bits.fill, s->bits.line); + swf_RecodeShapeData(outline->shape->data, outline->shape->bitlen, outline->shape->bits.fill, outline->shape->bits.line, + &s->data, &s->bitlen, s->bits.fill, s->bits.line); swf_SetShapeBits(tag, s); swf_SetBlock(tag, s->data, (s->bitlen+7)/8); swf_ShapeFree(s); @@ -870,15 +886,17 @@ void s_circle(char*name, int r, RGBA color, int linewidth, char*texture) tag = swf_InsertTag(tag, ST_DEFINESHAPE3); swf_ShapeNew(&s); - if(linewidth) - ls1 = swf_ShapeAddLineStyle(s,linewidth>=20?linewidth-20:0,&color); + if(linewidth) { + linewidth = linewidth>=20?linewidth-20:0; + ls1 = swf_ShapeAddLineStyle(s,linewidth,&color); + } if(texture) fs1 = addFillStyle(s, &r2, texture); swf_SetU16(tag,id); - rect.xmin = r2.xmin-linewidth-linewidth/2; - rect.ymin = r2.ymin-linewidth-linewidth/2; - rect.xmax = r2.xmax+linewidth+linewidth/2; - rect.ymax = r2.ymax+linewidth+linewidth/2; + rect.xmin = r2.xmin-linewidth/2; + rect.ymin = r2.ymin-linewidth/2; + rect.xmax = r2.xmax+linewidth/2; + rect.ymax = r2.ymax+linewidth/2; swf_SetRect(tag,&rect); swf_SetShapeHeader(tag,s); @@ -965,18 +983,21 @@ void s_quicktime(char*name, char*url) incrementid(); } -void s_edittext(char*name, char*fontname, int size, int width, int height, char*text, RGBA*color, int maxlength, char*variable, int flags) +void s_edittext(char*name, char*fontname, int size, int width, int height, char*text, RGBA*color, int maxlength, char*variable, int flags, int align) { - SWFFONT*font; + SWFFONT*font = 0; EditTextLayout layout; SRECT r; - font = dictionary_lookup(&fonts, fontname); - if(!font) - syntaxerror("font \"%s\" not known!", fontname); + if(fontname && *fontname) { + flags |= ET_USEOUTLINES; + font = dictionary_lookup(&fonts, fontname); + if(!font) + syntaxerror("font \"%s\" not known!", fontname); + } tag = swf_InsertTag(tag, ST_DEFINEEDITTEXT); swf_SetU16(tag, id); - layout.align = 0; + layout.align = align; layout.leftmargin = 0; layout.rightmargin = 0; layout.indent = 0; @@ -985,7 +1006,8 @@ void s_edittext(char*name, char*fontname, int size, int width, int height, char* r.ymin = 0; r.xmax = width; r.ymax = height; - swf_SetEditText(tag, flags|ET_USEOUTLINES, r, text, color, maxlength, font->id, size, &layout, variable); + + swf_SetEditText(tag, flags, r, text, color, maxlength, font?font->id:0, size, &layout, variable); s_addcharacter(name, id, tag, r); incrementid(); @@ -1002,12 +1024,7 @@ void s_image(char*name, char*type, char*filename, int quality) SRECT r; int imageID = id; int width, height; - if(type=="png") { - warning("image type \"png\" not supported yet!"); - s_box(name, 0, 0, black, 20, 0); - return; - } - if(type=="jpeg") { + if(!strcmp(type,"jpeg")) { #ifndef HAVE_LIBJPEG warning("no jpeg support compiled in"); s_box(name, 0, 0, black, 20, 0); @@ -1030,6 +1047,31 @@ void s_image(char*name, char*type, char*filename, int quality) s_addimage(name, id, tag, r); incrementid(); #endif + } else if(!strcmp(type,"png")) { + RGBA*data = 0; + swf_SetU16(tag, imageID); + + getPNG(filename, &width, &height, (unsigned char**)&data); + + if(!data) { + syntaxerror("Image \"%s\" not found, or contains errors", filename); + } + + /*tag = swf_AddImage(tag, imageID, data, width, height, quality)*/ + tag = swf_InsertTag(tag, ST_DEFINEBITSLOSSLESS); + swf_SetU16(tag, imageID); + swf_SetLosslessImage(tag, data, width, height); + + r.xmin = 0; + r.ymin = 0; + r.xmax = width*20; + r.ymax = height*20; + s_addimage(name, id, tag, r); + incrementid(); + } else { + warning("image type \"%s\" not supported yet!", type); + s_box(name, 0, 0, black, 20, 0); + return; } /* step 2: the character */ @@ -1041,6 +1083,63 @@ void s_image(char*name, char*type, char*filename, int quality) incrementid(); } +void s_getBitmapSize(char*name, int*width, int*height) +{ + character_t* image = dictionary_lookup(&images, name); + gradient_t* gradient = dictionary_lookup(&gradients,name); + if(image) { + *width = image->size.xmax; + *height = image->size.ymax; + return; + } + if(gradient) { + /* internal SWF gradient size */ + if(gradient->radial) { + *width = 16384; + *height = 16384; + } else { + *width = 32768; + *height = 32768; + } + return; + } + syntaxerror("No such bitmap/gradient: %s", name); +} + +void s_texture(char*name, char*object, int x, int y, float scalex, float scaley, float rotate, float shear) +{ + gradient_t* gradient = dictionary_lookup(&gradients, object); + character_t* bitmap = dictionary_lookup(&images, object); + texture_t* texture = (texture_t*)rfx_calloc(sizeof(texture_t)); + parameters_t p; + FILLSTYLE*fs = &texture->fs; + + if(bitmap) { + fs->type = FILL_TILED; + fs->id_bitmap = bitmap->id; + } else if(gradient) { + fs->type = gradient->radial?FILL_RADIAL:FILL_LINEAR; + fs->gradient = gradient->gradient; + } + p.x = x;p.y = y;p.scalex = scalex;p.scaley = scaley;p.rotate=rotate;p.shear=shear; + makeMatrix(&fs->m, &p); + if(gradient && !gradient->radial) { + MATRIX m = fs->m; + SPOINT p1,p2; + m.tx = 0; + m.ty = 0; + p1.x = 16384; + p1.y = 16384; + p2 = swf_TurnPoint(p1, &m); + fs->m.tx += p2.x; + fs->m.ty += p2.y; + } + + if(dictionary_lookup(&textures, name)) + syntaxerror("texture %s defined twice", name); + dictionary_put2(&textures, name, texture); +} + void dumpSWF(SWF*swf) { TAG* tag = swf->firstTag; @@ -1081,6 +1180,10 @@ void s_font(char*name, char*filename) font->id = id; tag = swf_InsertTag(tag, ST_DEFINEFONT2); swf_FontSetDefine2(tag, font); + tag = swf_InsertTag(tag, ST_EXPORTASSETS); + swf_SetU16(tag, 1); + swf_SetU16(tag, id); + swf_SetString(tag, name); incrementid(); if(dictionary_lookup(&fonts, name)) @@ -1099,17 +1202,16 @@ typedef struct _sound_t void s_sound(char*name, char*filename) { struct WAV wav, wav2; + struct MP3 mp3; sound_t* sound; - U16*samples; - int numsamples; - int t; - - if(!readWAV(filename, &wav)) { - warning("Couldn't read wav file \"%s\"", filename); - samples = 0; - numsamples = 0; - } else { - convertWAV2mono(&wav, &wav2, 44100); + U16*samples = NULL; + unsigned numsamples; + unsigned blocksize = 1152; + int is_mp3 = 0; + + if(wav_read(filename, &wav)) { + int t; + wav_convert2mono(&wav, &wav2, 44100); samples = (U16*)wav2.data; numsamples = wav2.size/2; free(wav.data); @@ -1119,11 +1221,47 @@ void s_sound(char*name, char*filename) samples[t] = (samples[t]>>8)&0xff | (samples[t]<<8)&0xff00; } #endif + } else if(mp3_read(&mp3, filename)) { + fprintf(stderr, "\"%s\" seems to work as a MP3 file...\n", filename); + blocksize = 1; + is_mp3 = 1; + } + else + { + warning("Couldn't read WAV/MP3 file \"%s\"", filename); + samples = 0; + numsamples = 0; + } + + if(numsamples%blocksize != 0) + { + // apply padding, so that block is a multiple of blocksize + int numblocks = (numsamples+blocksize-1)/blocksize; + int numsamples2; + U16* samples2; + numsamples2 = numblocks * blocksize; + samples2 = malloc(sizeof(U16)*numsamples2); + memcpy(samples2, samples, numsamples*sizeof(U16)); + memset(&samples2[numsamples], 0, sizeof(U16)*(numsamples2 - numsamples)); + numsamples = numsamples2; + samples = samples2; } tag = swf_InsertTag(tag, ST_DEFINESOUND); swf_SetU16(tag, id); //id - swf_SetSoundDefine(tag, samples, numsamples); + if(is_mp3) + { + swf_SetSoundDefineMP3( + tag, mp3.data, mp3.size, + mp3.SampRate, + mp3.Channels, + mp3.NumFrames); + mp3_clear(&mp3); + } + else + { + swf_SetSoundDefine(tag, samples, numsamples); + } sound = (sound_t*)malloc(sizeof(sound_t)); /* mem leak */ sound->tag = tag; @@ -1162,16 +1300,19 @@ RGBA parseColor(char*str); GRADIENT parseGradient(const char*str) { GRADIENT gradient; + int lastpos = -1; const char* p = str; memset(&gradient, 0, sizeof(GRADIENT)); while(*p) { char*posstr,*colorstr; - float pos; + int pos; RGBA color; posstr = gradient_getToken(&p); if(!*posstr) break; - pos = parsePercent(posstr); + pos = (int)(parsePercent(posstr)*255.0); + if(pos == lastpos) + pos++; if(!*p) syntaxerror("Error in shape data: Color expected after %s", posstr); colorstr = gradient_getToken(&p); color = parseColor(colorstr); @@ -1179,11 +1320,12 @@ GRADIENT parseGradient(const char*str) warning("gradient record too big- max size is 8, rest ignored"); break; } - gradient.ratios[gradient.num] = (int)(pos*255.0); + gradient.ratios[gradient.num] = pos; gradient.rgba[gradient.num] = color; gradient.num++; free(posstr); free(colorstr); + lastpos = pos; } return gradient; } @@ -1217,6 +1359,24 @@ void s_action(const char*text) swf_ActionFree(a); } +void s_initaction(const char*character, const char*text) +{ + ActionTAG* a = 0; + character_t*c = 0; + a = swf_ActionCompile(text, stack[0].swf->fileVersion); + if(!a) { + syntaxerror("Couldn't compile ActionScript"); + } + + c = (character_t*)dictionary_lookup(&characters, character); + + tag = swf_InsertTag(tag, ST_DOINITACTION); + swf_SetU16(tag, c->id); + swf_ActionSet(tag, a); + + swf_ActionFree(a); +} + int s_swf3action(char*name, char*action) { ActionTAG* a = 0; @@ -1250,7 +1410,9 @@ void s_outline(char*name, char*format, char*source) SHAPE2* shape2; SRECT bounds; + //swf_Shape10DrawerInit(&draw, 0); swf_Shape11DrawerInit(&draw, 0); + draw_string(&draw, source); draw.finish(&draw); shape = swf_ShapeDrawerToShape(&draw); @@ -1269,10 +1431,10 @@ void s_outline(char*name, char*format, char*source) int s_playsound(char*name, int loops, int nomultiple, int stop) { sound_t* sound; + SOUNDINFO info; if(!name) return 0; sound = dictionary_lookup(&sounds, name); - SOUNDINFO info; if(!sound) return 0; @@ -1782,6 +1944,19 @@ MULADD mergeMulAdd(MULADD m1, MULADD m2) return r; } +float parsePxOrPercent(char*fontname, char*str) +{ + int l = strlen(str); + if(strchr(str, '%')) + return parsePercent(str); + if(l>2 && str[l-2]=='p' && str[l-1]=='t') { + float p = atof(str); + return p/64.0; /*64 = FT_SUBPIXELS- see ../lib/modules/swffont.c */ + } + syntaxerror("Expression '%s' is neither a point size (?pt) nor a percentage (?%)", str); + return 0; +} + float parsePercent(char*str) { int l = strlen(str); @@ -1901,6 +2076,76 @@ SPOINT getPoint(SRECT r, char*name) l--; return *(SPOINT*)&mpoints.buffer[l]; } + +static int texture2(char*name, char*object, map_t*args, int errors) +{ + SPOINT pos,size; + char*xstr = map_lookup(args, "x"); + char*ystr = map_lookup(args, "y"); + char*widthstr = map_lookup(args, "width"); + char*heightstr = map_lookup(args, "height"); + char*scalestr = map_lookup(args, "scale"); + char*scalexstr = map_lookup(args, "scalex"); + char*scaleystr = map_lookup(args, "scaley"); + char*rotatestr = map_lookup(args, "rotate"); + char* shearstr = map_lookup(args, "shear"); + 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) +{ + char*name = lu(args, "instance"); + char*object = lu(args, "character"); + return texture2(name, object, args, 1); +} + static int c_gradient(map_t*args) { char*name = lu(args, "name"); @@ -1911,7 +2156,14 @@ static int c_gradient(map_t*args) if(type != RAWDATA) syntaxerror("colon (:) expected"); - s_gradient(name, text, radial,rotate); + 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 int c_point(map_t*args) @@ -2303,7 +2555,7 @@ static int c_textshape(map_t*args) char*name = lu(args, "name"); char*text = lu(args, "text"); char*font = lu(args, "font"); - float size = parsePercent(lu(args, "size")); + float size = parsePxOrPercent(font, lu(args, "size")); s_textshape(name, font, size, text); return 0; @@ -2341,7 +2593,7 @@ static int c_text(map_t*args) char*name = lu(args, "name"); char*text = lu(args, "text"); char*font = lu(args, "font"); - float size = parsePercent(lu(args, "size")); + float size = parsePxOrPercent(font, lu(args, "size")); RGBA color = parseColor(lu(args, "color")); s_text(name, font, text, (int)(size*100), color); return 0; @@ -2519,10 +2771,10 @@ static int c_on_key(map_t*args) static int c_edittext(map_t*args) { - //"name font size width height text="" color=black maxlength=0 variable="" @password=0 @wordwrap=0 @multiline=0 @html=0 @noselect=0 @readonly=0"}, + //"name font size width height text="" color=black maxlength=0 variable="" @password=0 @wordwrap=0 @multiline=0 @html=0 @noselect=0 @readonly=0 @autosize=0"}, char*name = lu(args, "name"); char*font = lu(args, "font"); - int size = (int)(1024*parsePercent(lu(args, "size"))); + int size = (int)(1024*parsePxOrPercent(font, lu(args, "size"))); int width = parseTwip(lu(args, "width")); int height = parseTwip(lu(args, "height")); char*text = lu(args, "text"); @@ -2536,6 +2788,9 @@ static int c_edittext(map_t*args) char*noselectstr = lu(args, "noselect"); char*readonlystr = lu(args, "readonly"); char*borderstr = lu(args, "border"); + char*autosizestr = lu(args, "autosize"); + char*alignstr = lu(args, "align"); + int align = -1; int flags = 0; if(!strcmp(passwordstr, "password")) flags |= ET_PASSWORD; @@ -2545,15 +2800,36 @@ static int c_edittext(map_t*args) if(!strcmp(htmlstr, "html")) flags |= ET_HTML; if(!strcmp(noselectstr, "noselect")) flags |= ET_NOSELECT; if(!strcmp(borderstr, "border")) flags |= ET_BORDER; - - s_edittext(name, font, size, width, height, text, &color, maxlength, variable, flags); + if(!strcmp(autosizestr, "autosize")) flags |= ET_AUTOSIZE; + if(!strcmp(alignstr, "left") || !*alignstr) align = ET_ALIGN_LEFT; + else if(!strcmp(alignstr, "right")) align = ET_ALIGN_RIGHT; + else if(!strcmp(alignstr, "center")) align = ET_ALIGN_CENTER; + else if(!strcmp(alignstr, "justify")) align = ET_ALIGN_JUSTIFY; + else syntaxerror("Unknown alignment: %s", alignstr); + + s_edittext(name, font, size, width, height, text, &color, maxlength, variable, flags, align); return 0; } static int c_morphshape(map_t*args) {return fakechar(args);} static int c_movie(map_t*args) {return fakechar(args);} -static int c_texture(map_t*args) {return 0;} +static char* readfile(const char*filename) +{ + FILE*fi = fopen(filename, "rb"); + int l; + char*text; + if(!fi) + syntaxerror("Couldn't find file %s: %s", filename, strerror(errno)); + fseek(fi, 0, SEEK_END); + l = ftell(fi); + fseek(fi, 0, SEEK_SET); + text = rfx_alloc(l+1); + fread(text, l, 1, fi); + text[l]=0; + fclose(fi); + return text; +} static int c_action(map_t*args) { @@ -2565,20 +2841,24 @@ static int c_action(map_t*args) } s_action(text); } else { - FILE*fi = fopen(filename, "rb"); - if(!fi) - syntaxerror("Couldn't find file %s: %s", filename, strerror(errno)); - int l; - char*text; - fseek(fi, 0, SEEK_END); - l = ftell(fi); - fseek(fi, 0, SEEK_SET); - text = rfx_alloc(l+1); - fread(text, l, 1, fi); - text[l]=0; - fclose(fi); + s_action(readfile(filename)); + } + + return 0; +} - s_action(text); +static int c_initaction(map_t*args) +{ + char* character = lu(args, "name"); + char* filename = map_lookup(args, "filename"); + if(!filename ||!*filename) { + readToken(); + if(type != RAWDATA) { + syntaxerror("colon (:) expected"); + } + s_initaction(character, text); + } else { + s_initaction(character, readfile(filename)); } return 0; @@ -2605,7 +2885,7 @@ static struct { // generators of primitives {"point", c_point, "name x=0 y=0"}, - {"gradient", c_gradient, "name @radial=0 rotate=0"}, + {"gradient", c_gradient, "name @radial=0 rotate=0 scale= scalex= scaley= x= y= width= height= r= shear="}, //extra parameters like .texture {"outline", c_outline, "name format=simple"}, {"textshape", c_textshape, "name font size=100% text"}, @@ -2616,7 +2896,7 @@ static struct { {"egon", c_egon, "name vertices color=white line=1 @fill=none"}, {"text", c_text, "name text font size=100% color=white"}, - {"edittext", c_edittext, "name font size=100% width height text="" color=white maxlength=0 variable="" @password=0 @wordwrap=0 @multiline=0 @html=0 @noselect=0 @readonly=0 @border=0"}, + {"edittext", c_edittext, "name font= size=100% width height text="" color=white maxlength=0 variable="" @password=0 @wordwrap=0 @multiline=0 @html=0 @noselect=0 @readonly=0 @border=0 @autosize=0 align="}, {"morphshape", c_morphshape, "name start end"}, {"button", c_button, "name"}, {"show", c_show, "name x=0 y=0 red=+0 green=+0 blue=+0 alpha=+0 luminance= scale= scalex= scaley= pivot= pin= shear= rotate= ratio= above= below= as="}, @@ -2641,12 +2921,13 @@ static struct { {"jump", c_jump, "name x= y= red= green= blue= alpha= luminance= scale= scalex= scaley= pivot= pin= shear= rotate= ratio= above= below="}, {"del", c_del, "name"}, // virtual object placement - {"texture", c_texture, " x=0 y=0 scale= scalex=100% scaley=100% shear=0 rotate=0"}, + {"texture", c_texture, " x=0 y=0 width= height= scale= scalex= scaley= r= shear= rotate="}, // commands which start a block //startclip (see above) {"sprite", c_sprite, "name"}, {"action", c_action, "filename="}, + {"initaction", c_initaction, "name filename="}, {"end", c_end, ""} };