added -l, -I options
[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 {"v", "verbose"},
46 {"q", "quiet"},
47 {"C", "cgi"},
48 {"X", "width"},
49 {"Y", "height"},
50 {"r", "rate"},
51 {"l", "library"},
52 {"I", "include"},
53 {"T", "flashversion"},
54 {"o", "output"},
55 {0,0}
56 };
57
58 int args_callback_option(char*name,char*val)
59 {
60     if(!strcmp(name, "V")) {
61         printf("swfc - part of %s %s\n", PACKAGE, VERSION);
62         exit(0);
63     }
64     else if(!strcmp(name, "o")) {
65         outputname = val;
66         override_outputname = 1;
67         return 1;
68     }
69     else if(!strcmp(name, "r")) {
70         framerate = atof(val);
71         return 1;
72     }
73     else if(!strcmp(name, "v")) {
74         verbose++;
75         return 0;
76     }
77     else if(!strcmp(name, "q")) {
78         verbose--;
79         return 0;
80     }
81     else if(!strcmp(name, "X")) {
82         width = atof(val);
83         return 1;
84     }
85     else if(!strcmp(name, "Y")) {
86         height = atof(val);
87         return 1;
88     }
89     else if(!strcmp(name, "T")) {
90         flashversion = atoi(val);
91         return 1;
92     }
93     else if(!strcmp(name, "C")) {
94         do_cgi = 1;
95         return 0;
96     }
97     else if(!strcmp(name, "-l")) {
98         as3_import_file(val);
99         return 1;
100     }
101     else if(!strcmp(name, "-I")) {
102         as3_add_include_dir(val);
103         return 1;
104     }
105     else {
106         printf("Unknown option: -%s\n", name);
107         exit(1);
108     }
109     return 0;
110 }
111 int args_callback_longoption(char*name,char*val)
112 {
113     return args_long2shortoption(options, name, val);
114 }
115 void args_callback_usage(char *name)
116 {
117     printf("\n");
118     printf("Usage: %s file.as [-o file.swf] \n", name);
119     printf("\n");
120     printf("-h , --help                    Print short help message and exit\n");
121     printf("-V , --version                 Print version info and exit\n");
122     printf("-v , --verbose                 Increase verbosity\n");
123     printf("-q , --quiet                   Decrease verbosity\n");
124     printf("-C , --cgi                     Output to stdout (for use in CGI environments)\n");
125     printf("-X , --width                   Set target SWF width\n");
126     printf("-Y , --height                  Set target SWF width\n");
127     printf("-r , --rate                    Set target SWF framerate\n");
128     printf("-l , --library <file>          Include library file <file>\n");
129     printf("-I , --include <dir>           Add include dir <dir>\n");
130     printf("-T , --flashversion <num>      Set target SWF flash version to <num>.\n");
131     printf("-o , --output <filename>       Set output file to <filename>.\n");
132     printf("\n");
133 }
134 int args_callback_command(char*name,char*val)
135 {
136     if(filename) {
137         fprintf(stderr, "Only one file allowed. You supplied at least two. (%s and %s)\n",
138                  filename, name);
139     }
140     filename = name;
141     return 0;
142 }
143
144 void writeSWF(SWF*swf)
145 {
146     int fi = -1;
147     if(do_cgi || !strcmp(filename, "-"))
148         fi = fileno(stdout);
149     else
150         fi = open(outputname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644);
151     if(fi<0) {
152         fprintf(stderr, "couldn't create output file %s\n", filename);
153         exit(1);
154     }
155     if(do_cgi) {
156         if(swf_WriteCGI(swf)<0) {
157             fprintf(stderr, "WriteCGI failed.\n");
158             exit(1);
159         }
160     } else {
161         if(swf_WriteSWF(fi, swf)<0) {
162             fprintf(stderr, "WriteSWF() failed.\n");
163             exit(1);
164         }
165     }
166 }
167
168 int main (int argc,char ** argv)
169 {
170     char buf[512];
171     char*currentdir = getcwd(buf, 512);
172     if(!currentdir) {
173         as3_warning("Could not determine the current directory");
174     } else {
175         as3_add_include_dir(currentdir);
176     }
177     registry_init();
178
179     int t;
180     processargs(argc, argv);
181     as3_setverbosity(verbose);
182
183     if(!filename) {
184         args_callback_usage(argv[0]);
185         exit(1);
186     }
187     if(!outputname) {
188         outputname = stripFilename(filename, ".swf");
189         //as3_warning("output name not given, writing to %s", outputname);
190     }
191
192     as3_parse_file(filename);
193     void*code = as3_getcode();
194
195     SWF swf;
196     memset(&swf, 0, sizeof(swf));
197     swf.fileVersion = flashversion;
198     swf.frameRate = framerate*0x100;
199     swf.movieSize.xmin = 0;
200     swf.movieSize.ymin = 0;
201     swf.movieSize.xmax = width*20;
202     swf.movieSize.ymax = height*20;
203     TAG*tag = swf.firstTag = swf_InsertTag(0, ST_DOABC);
204     swf_WriteABC(tag, code);
205
206     if(as3_getglobalclass()) {
207         tag = swf_InsertTag(tag, ST_SYMBOLCLASS);
208         swf_SetU16(tag, 1);
209         swf_SetU16(tag, 0);
210         swf_SetString(tag, as3_getglobalclass());
211     } else {
212         as3_warning("no global public MovieClip subclass");
213     }
214     
215     as3_destroy();
216
217     tag = swf_InsertTag(tag, ST_SHOWFRAME);
218     tag = swf_InsertTag(tag, ST_END);
219
220     swf_FreeABC(code);
221
222     writeSWF(&swf);
223     swf_FreeTags(&swf);
224
225     return 0;
226 }
227