added as3 compiler frontend
[swftools.git] / src / as3compile.c
1 /* as3compile.c
2    Compiles ActionScript 3.0 (.as) files into .swf files.
3
4    Part of the swftools package.
5
6    Copyright (c) 2008/2009 Matthias Kramm <kramm@quiss.org>
7
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.
12
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.
17
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 */
21
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <unistd.h>
27 #include "../lib/rfxswf.h"
28 #include "../lib/args.h"
29 #include "../lib/q.h"
30 #include "../lib/os.h"
31
32 static char * filename = 0;
33 static char * outputname = 0;
34 static int override_outputname = 0;
35 static int do_cgi = 0;
36 static double framerate = 25.0;
37 static double width = 400;
38 static double height = 300;
39 static int flashversion = 9;
40 static int verbose = 1;
41
42 static struct options_t options[] = {
43 {"h", "help"},
44 {"V", "version"},
45 {"C", "cgi"},
46 {"X", "width"},
47 {"Y", "height"},
48 {"r", "rate"},
49 {"T", "flashversion"},
50 {"o", "output"},
51 {0,0}
52 };
53
54 int args_callback_option(char*name,char*val)
55 {
56     if(!strcmp(name, "V")) {
57         printf("swfc - part of %s %s\n", PACKAGE, VERSION);
58         exit(0);
59     }
60     else if(!strcmp(name, "o")) {
61         outputname = val;
62         override_outputname = 1;
63         return 1;
64     }
65     else if(!strcmp(name, "r")) {
66         framerate = atof(val);
67         return 1;
68     }
69     else if(!strcmp(name, "v")) {
70         verbose++;
71         return 0;
72     }
73     else if(!strcmp(name, "q")) {
74         verbose--;
75         return 0;
76     }
77     else if(!strcmp(name, "X")) {
78         width = atof(val);
79         return 1;
80     }
81     else if(!strcmp(name, "Y")) {
82         height = atof(val);
83         return 1;
84     }
85     else if(!strcmp(name, "T")) {
86         flashversion = atoi(val);
87         return 1;
88     }
89     else if(!strcmp(name, "C")) {
90         do_cgi = 1;
91         return 0;
92     }
93     else {
94         printf("Unknown option: -%s\n", name);
95         exit(1);
96     }
97     return 0;
98 }
99 int args_callback_longoption(char*name,char*val)
100 {
101     return args_long2shortoption(options, name, val);
102 }
103 void args_callback_usage(char *name)
104 {
105     printf("\n");
106     printf("Usage: %s file.as [-o file.swf] \n", name);
107     printf("\n");
108     printf("-h , --help                    Print short help message and exit\n");
109     printf("-V , --version                 Print version info and exit\n");
110     printf("-C , --cgi                     Output to stdout (for use in CGI environments)\n");
111     printf("-X , --width                   Set target SWF width\n");
112     printf("-Y , --height                  Set target SWF width\n");
113     printf("-r , --rate                    Set target SWF framerate\n");
114     printf("-T , --flashversion <num>      Set target SWF flash version to <num>.\n");
115     printf("-o , --output <filename>       Set output file to <filename>.\n");
116     printf("\n");
117 }
118 int args_callback_command(char*name,char*val)
119 {
120     if(filename) {
121         fprintf(stderr, "Only one file allowed. You supplied at least two. (%s and %s)\n",
122                  filename, name);
123     }
124     filename = name;
125     return 0;
126 }
127
128 void writeSWF(SWF*swf)
129 {
130     int fi = -1;
131     if(do_cgi || !strcmp(filename, "-"))
132         fi = fileno(stdout);
133     else
134         fi = open(outputname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644);
135     if(fi<0) {
136         fprintf(stderr, "couldn't create output file %s\n", filename);
137         exit(1);
138     }
139     if(do_cgi) {
140         if(swf_WriteCGI(swf)<0) {
141             fprintf(stderr, "WriteCGI failed.\n");
142             exit(1);
143         }
144     } else {
145         if(swf_WriteSWF(fi, swf)<0) {
146             fprintf(stderr, "WriteSWF() failed.\n");
147             exit(1);
148         }
149     }
150 }
151
152 int main (int argc,char ** argv)
153 {
154     int t;
155     processargs(argc, argv);
156
157     if(!filename) {
158         args_callback_usage(argv[0]);
159         exit(1);
160     }
161     if(!outputname) {
162         outputname = stripFilename(filename, ".swf");
163         //as3_warning("output name not given, writing to %s", outputname);
164     }
165
166     as3_setverbosity(verbose);
167
168     char buf[512];
169     char*currentdir = getcwd(buf, 512);
170     if(!currentdir) {
171         as3_warning("Could not determine the current directory");
172     } else {
173         as3_add_include_dir(currentdir);
174     }
175
176     as3_parse_file(filename);
177     void*code = as3_getcode();
178
179     SWF swf;
180     memset(&swf, 0, sizeof(swf));
181     swf.fileVersion = flashversion;
182     swf.frameRate = framerate*0x100;
183     swf.movieSize.xmin = 0;
184     swf.movieSize.ymin = 0;
185     swf.movieSize.xmax = width*20;
186     swf.movieSize.ymax = height*20;
187     TAG*tag = swf.firstTag = swf_InsertTag(0, ST_DOABC);
188     swf_WriteABC(tag, code);
189
190     if(as3_getglobalclass()) {
191         tag = swf_InsertTag(tag, ST_SYMBOLCLASS);
192         swf_SetU16(tag, 1);
193         swf_SetU16(tag, 0);
194         swf_SetString(tag, as3_getglobalclass());
195     } else {
196         as3_warning("no global public MovieClip subclass");
197     }
198
199     
200     as3_destroy();
201
202     tag = swf_InsertTag(tag, ST_SHOWFRAME);
203     tag = swf_InsertTag(tag, ST_END);
204
205     swf_FreeABC(code);
206
207     writeSWF(&swf);
208     swf_FreeTags(&swf);
209
210     return 0;
211 }
212