]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake2/qdata_heretic2/qdata.c
transfer from internal tree r5311 branches/1.4-gpl
[xonotic/netradiant.git] / tools / quake2 / qdata_heretic2 / qdata.c
1 /*\r
2 Copyright (C) 1999-2007 id Software, Inc. and contributors.\r
3 For a list of contributors, see the accompanying CONTRIBUTORS file.\r
4 \r
5 This file is part of GtkRadiant.\r
6 \r
7 GtkRadiant is free software; you can redistribute it and/or modify\r
8 it under the terms of the GNU General Public License as published by\r
9 the Free Software Foundation; either version 2 of the License, or\r
10 (at your option) any later version.\r
11 \r
12 GtkRadiant is distributed in the hope that it will be useful,\r
13 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
15 GNU General Public License for more details.\r
16 \r
17 You should have received a copy of the GNU General Public License\r
18 along with GtkRadiant; if not, write to the Free Software\r
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\r
20 */\r
21 \r
22 #include "qdata.h"\r
23 \r
24 void TK_Init();\r
25 \r
26 qboolean        g_compress_pak;\r
27 qboolean        g_release;                      // don't grab, copy output data to new tree\r
28 qboolean        g_pak;                          // if true, copy to pak instead of release\r
29 char            g_releasedir[1024];     // c:\quake2\baseq2, etc\r
30 qboolean        g_archive;                      // don't grab, copy source data to new tree\r
31 qboolean        do3ds;\r
32 char            g_only[256];            // if set, only grab this cd\r
33 qboolean        g_skipmodel;            // set true when a cd is not g_only\r
34 int                     g_forcemodel = MODEL_AUTO;\r
35 qboolean        g_verbose = false;\r
36 qboolean        g_allow_newskin = true;\r
37 qboolean        g_ignoreTriUV = false;\r
38 qboolean        g_publishOutput = false;\r
39 \r
40 char            *ext_3ds = "3ds";\r
41 char            *ext_tri= "tri";\r
42 char            *trifileext;\r
43 \r
44 char            g_materialFile[256] = "none";   // default for Heretic2\r
45 char            *g_outputDir;\r
46 extern char *g_publishDir;\r
47 \r
48 extern qboolean g_nomkdir;\r
49 \r
50 /*\r
51 =======================================================\r
52 \r
53   PAK FILES\r
54 \r
55 =======================================================\r
56 */\r
57 \r
58 typedef struct\r
59 {\r
60         char    name[56];\r
61         int             filepos, filelen;\r
62 } packfile_t;\r
63 \r
64 typedef struct\r
65 {\r
66         char    id[4];\r
67         int             dirofs;\r
68         int             dirlen;\r
69 } packheader_t;\r
70 \r
71 packfile_t              pfiles[16384];\r
72 FILE                    *pakfile;\r
73 packfile_t              *pf;\r
74 packheader_t    pakheader;\r
75 \r
76 \r
77 \r
78 /*\r
79 ==============\r
80 BeginPak\r
81 ==============\r
82 */\r
83 void BeginPak (char *outname)\r
84 {\r
85         if (!g_pak)\r
86                 return;\r
87 \r
88         pakfile = SafeOpenWrite (outname);\r
89 \r
90         // leave space for header\r
91         SafeWrite (pakfile, &pakheader, sizeof(pakheader));\r
92         \r
93         pf = pfiles;\r
94 }\r
95 \r
96 \r
97 /*\r
98 ==============\r
99 ReleaseFile\r
100 \r
101 Filename should be gamedir reletive.\r
102 Either copies the file to the release dir, or adds it to\r
103 the pak file.\r
104 ==============\r
105 */\r
106 void ReleaseFile (char *filename)\r
107 {\r
108         int             len;\r
109         byte    *buf;\r
110         char    source[1024];\r
111         char    dest[1024];\r
112 \r
113         if (!g_release)\r
114                 return;\r
115 \r
116         sprintf (source, "%s%s", gamedir, filename);\r
117 \r
118         if (!g_pak)\r
119         {       // copy it\r
120                 sprintf (dest, "%s/%s", g_releasedir, filename);\r
121                 printf ("copying to %s\n", dest);\r
122                 QCopyFile (source, dest);\r
123                 return;\r
124         }\r
125 \r
126         // pak it\r
127         printf ("paking %s\n", filename);\r
128         if (strlen(filename) >= sizeof(pf->name))\r
129                 Error ("Filename too long for pak: %s", filename);\r
130 \r
131         len = LoadFile (source, (void **)&buf);\r
132 \r
133         // segment moved to old.c\r
134 \r
135         strcpy (pf->name, filename);\r
136         pf->filepos = LittleLong(ftell(pakfile));\r
137         pf->filelen = LittleLong(len);\r
138         pf++;\r
139 \r
140         SafeWrite (pakfile, buf, len);\r
141 \r
142         free (buf);\r
143 }\r
144 \r
145 \r
146 /*\r
147 ==============\r
148 FinishPak\r
149 ==============\r
150 */\r
151 void FinishPak (void)\r
152 {\r
153         int             dirlen;\r
154         int             d;\r
155         int             i;\r
156 \r
157         if (!g_pak)\r
158                 return;\r
159 \r
160         pakheader.id[0] = 'P';\r
161         pakheader.id[1] = 'A';\r
162         pakheader.id[2] = 'C';\r
163         pakheader.id[3] = 'K';\r
164         dirlen = (byte *)pf - (byte *)pfiles;\r
165         pakheader.dirofs = LittleLong(ftell(pakfile));\r
166         pakheader.dirlen = LittleLong(dirlen);\r
167         \r
168         SafeWrite (pakfile, pfiles, dirlen);\r
169 \r
170         i = ftell (pakfile);\r
171          \r
172         fseek (pakfile, 0, SEEK_SET);\r
173         SafeWrite (pakfile, &pakheader, sizeof(pakheader));\r
174         fclose (pakfile);       \r
175         \r
176         d = pf - pfiles;\r
177         printf ("%i files packed in %i bytes\n",d, i);\r
178 }\r
179 \r
180 \r
181 /*\r
182 ===============\r
183 Cmd_File\r
184 \r
185 This is only used to cause a file to be copied during a release\r
186 build (default.cfg, maps, etc)\r
187 ===============\r
188 */\r
189 void Cmd_File (void)\r
190 {\r
191         GetScriptToken (false);\r
192         ReleaseFile (token);\r
193 }\r
194 \r
195 /*\r
196 ===============\r
197 PackDirectory_r\r
198 \r
199 ===============\r
200 */\r
201 #ifdef _WIN32\r
202 #include "io.h"\r
203 void PackDirectory_r (char *dir)\r
204 {\r
205         struct _finddata_t fileinfo;\r
206         int             handle;\r
207         char    dirstring[1024];\r
208         char    filename[1024];\r
209 \r
210         sprintf (dirstring, "%s%s/*.*", gamedir, dir);\r
211 \r
212         handle = _findfirst (dirstring, &fileinfo);\r
213         if (handle == -1)\r
214                 return;\r
215 \r
216         do\r
217         {\r
218                 sprintf (filename, "%s/%s", dir, fileinfo.name);\r
219                 if (fileinfo.attrib & _A_SUBDIR)\r
220                 {       // directory\r
221                         if (fileinfo.name[0] != '.')    // don't pak . and ..\r
222                                 PackDirectory_r (filename);\r
223                         continue;\r
224                 }\r
225                 // copy or pack the file\r
226                 ReleaseFile (filename);         \r
227         } while (_findnext( handle, &fileinfo ) != -1);\r
228 \r
229         _findclose (handle);\r
230 }\r
231 #else\r
232 \r
233 #include <sys/types.h>\r
234 #ifdef NeXT\r
235 #include <sys/dir.h>\r
236 #else\r
237 #include <dirent.h>\r
238 #endif\r
239 \r
240 void PackDirectory_r (char *dir)\r
241 {\r
242 #ifdef NeXT\r
243         struct direct **namelist, *ent;\r
244 #else\r
245         struct dirent **namelist, *ent;\r
246 #endif\r
247         int             count;\r
248         struct stat st;\r
249         int                     i;\r
250         int                     len;\r
251         char            fullname[1024];\r
252         char            dirstring[1024];\r
253         char            *name;\r
254         \r
255         sprintf (dirstring, "%s%s", gamedir, dir);\r
256         count = scandir(dirstring, &namelist, NULL, NULL);\r
257         \r
258         for (i=0 ; i<count ; i++)\r
259         {\r
260                 ent = namelist[i];      \r
261                 name = ent->d_name;\r
262 \r
263                 if (name[0] == '.')\r
264                         continue;\r
265         \r
266                 sprintf (fullname, "%s/%s", dir, name);\r
267                 sprintf (dirstring, "%s%s/%s", gamedir, dir, name);\r
268                 \r
269                 if (stat (dirstring, &st) == -1)\r
270                         Error ("fstating %s", pf->name);\r
271                 if (st.st_mode & S_IFDIR)\r
272                 {       // directory\r
273                         PackDirectory_r (fullname);\r
274                         continue;\r
275                 }\r
276 \r
277                 // copy or pack the file\r
278                 ReleaseFile (fullname);         \r
279         }\r
280 }\r
281 #endif\r
282 \r
283 \r
284 /*\r
285 ===============\r
286 Cmd_Dir\r
287 \r
288 This is only used to cause a directory to be copied during a\r
289 release build (sounds, etc)\r
290 ===============\r
291 */\r
292 void Cmd_Dir (void)\r
293 {\r
294         GetScriptToken (false);\r
295         PackDirectory_r (token);        \r
296 }\r
297 \r
298 //========================================================================\r
299 \r
300 #define MAX_RTEX        16384\r
301 int             numrtex;\r
302 char    rtex[MAX_RTEX][64];\r
303 \r
304 void ReleaseTexture (char *name)\r
305 {\r
306         int             i;\r
307         char    path[1024];\r
308 \r
309         for (i=0 ; i<numrtex ; i++)\r
310                 if (!Q_strcasecmp(name, rtex[i]))\r
311                         return;\r
312 \r
313         if (numrtex == MAX_RTEX)\r
314                 Error ("numrtex == MAX_RTEX");\r
315 \r
316         strcpy (rtex[i], name);\r
317         numrtex++;\r
318 \r
319         sprintf (path, "textures/%s.wal", name);\r
320         ReleaseFile (path);\r
321 }\r
322 \r
323 /*\r
324 ===============\r
325 Cmd_Maps\r
326 \r
327 Only relevent for release and pak files.\r
328 Releases the .bsp files for the maps, and scans all of the files to\r
329 build a list of all textures used, which are then released.\r
330 ===============\r
331 */\r
332 void Cmd_Maps (void)\r
333 {\r
334         char    map[1024];\r
335         int             i;\r
336 \r
337         while (ScriptTokenAvailable ())\r
338         {\r
339                 GetScriptToken (false);\r
340                 sprintf (map, "maps/%s.bsp", token);\r
341                 ReleaseFile (map);\r
342 \r
343                 if (!g_release)\r
344                         continue;\r
345 \r
346                 // get all the texture references\r
347                 sprintf (map, "%smaps/%s.bsp", gamedir, token);\r
348                 LoadBSPFileTexinfo (map);\r
349                 for (i=0 ; i<numtexinfo ; i++)\r
350                         ReleaseTexture (texinfo[i].texture);\r
351         }\r
352 }\r
353 \r
354 \r
355 //==============================================================\r
356 \r
357 /*\r
358 ===============\r
359 ParseScript\r
360 ===============\r
361 */\r
362 void ParseScript (void)\r
363 {\r
364         while (1)\r
365         {\r
366                 do\r
367                 {       // look for a line starting with a $ command\r
368                         GetScriptToken (true);\r
369                         if (endofscript)\r
370                                 return;\r
371                         if (token[0] == '$')\r
372                                 break;                          \r
373                         while (ScriptTokenAvailable())\r
374                                 GetScriptToken (false);\r
375                 } while (1);\r
376                 \r
377                 //\r
378                 // model commands\r
379                 //\r
380                 if (!strcmp (token, "$modelname"))\r
381                         MODELCMD_Modelname (MODEL_MD2);\r
382                 else if (!strcmp (token, "$cd"))\r
383                         MODELCMD_Cd (MODEL_MD2);\r
384                 else if (!strcmp (token, "$origin"))\r
385                         MODELCMD_Origin (MODEL_MD2);\r
386                 else if (!strcmp (token, "$cluster"))\r
387                         MODELCMD_Cluster (MODEL_MD2);\r
388                 else if (!strcmp (token, "$base"))\r
389                         MODELCMD_Base (MODEL_MD2);\r
390                 else if (!strcmp (token, "$scale"))\r
391                         MODELCMD_ScaleUp (MODEL_MD2);\r
392                 else if (!strcmp (token, "$frame"))\r
393                         MODELCMD_Frame (MODEL_MD2);\r
394                 else if (!strcmp (token, "$skin"))\r
395                         MODELCMD_Skin (MODEL_MD2);\r
396                 else if (!strcmp (token, "$skinsize"))\r
397                         MODELCMD_Skinsize (MODEL_MD2);\r
398                 //\r
399                 // flexible model commands\r
400                 //\r
401                 else if (!strcmp (token, "$fm_modelname"))\r
402                         MODELCMD_Modelname (MODEL_FM);\r
403                 else if (!strcmp (token, "$fm_base"))\r
404                         MODELCMD_Base (MODEL_FM);\r
405                 else if (!strcmp (token, "$fm_basest"))\r
406                         MODELCMD_BaseST (MODEL_FM);\r
407                 else if (!strcmp (token, "$fm_cd"))\r
408                         MODELCMD_Cd (MODEL_FM);\r
409                 else if (!strcmp (token, "$fm_origin"))\r
410                         MODELCMD_Origin (MODEL_FM);\r
411                 else if (!strcmp (token, "$fm_cluster"))\r
412                         MODELCMD_Cluster (MODEL_FM);\r
413                 else if (!strcmp (token, "$fm_skeleton"))\r
414                         MODELCMD_Skeleton (MODEL_FM);\r
415                 else if (!strcmp (token, "$fm_scale"))\r
416                         MODELCMD_ScaleUp (MODEL_FM);\r
417                 else if (!strcmp (token, "$fm_frame"))\r
418                         MODELCMD_Frame (MODEL_FM);\r
419                 else if (!strcmp (token, "$fm_skeletal_frame")) // left in for compadibility with qdt already using fm_skeletal_frame\r
420                         MODELCMD_Frame (MODEL_FM);\r
421                 else if (!strcmp (token, "$fm_skin"))\r
422                         MODELCMD_Skin (MODEL_FM);\r
423                 else if (!strcmp (token, "$fm_skinsize"))\r
424                         MODELCMD_Skinsize (MODEL_FM);\r
425                 else if (!strcmp (token, "$fm_begin_group"))\r
426                         MODELCMD_BeginGroup(MODEL_FM);\r
427                 else if (!strcmp (token, "$fm_end_group"))\r
428                         MODELCMD_EndGroup(MODEL_FM);\r
429                 else if (!strcmp (token, "$fm_referenced"))\r
430                         MODELCMD_Referenced(MODEL_FM);\r
431                 else if (!strcmp (token, "$fm_node_order"))\r
432                         MODELCMD_NodeOrder(MODEL_FM);\r
433                 \r
434                 //\r
435                 // sprite commands\r
436                 //\r
437                 else if (!strcmp (token, "$spritename"))\r
438                         Cmd_SpriteName ();\r
439                 else if (!strcmp (token, "$sprdir"))\r
440                         Cmd_Sprdir ();\r
441                 else if (!strcmp (token, "$load"))\r
442                         Cmd_Load ();\r
443                 else if (!strcmp (token, "$spriteframe"))\r
444                         Cmd_SpriteFrame ();\r
445                 //\r
446                 // image commands\r
447                 //\r
448                 else if (!strcmpi (token, "$grab"))\r
449                         Cmd_Grab ();\r
450                 else if (!strcmpi (token, "$raw"))\r
451                         Cmd_Raw ();\r
452                 else if (!strcmpi (token, "$colormap"))\r
453                         Cmd_Colormap ();\r
454                 else if (!strcmpi (token, "$mippal"))\r
455                         Cmd_Mippal ();\r
456                 else if (!strcmpi (token, "$mipdir"))\r
457                         Cmd_Mipdir ();\r
458                 else if (!strcmpi (token, "$mip"))\r
459                         Cmd_Mip ();\r
460                 else if (!strcmp (token, "$environment"))\r
461                         Cmd_Environment ();\r
462                 //\r
463                 // pics\r
464                 //\r
465                 else if (!strcmp (token, "$picdir"))\r
466                         Cmd_Picdir ();\r
467                 else if (!strcmp (token, "$pic"))\r
468                         Cmd_Pic ();\r
469                 //\r
470                 // book\r
471                 //\r
472                 else if (!strcmp (token, "$bookdir"))\r
473                         Cmd_Bookdir ();\r
474                 else if (!strcmp (token, "$book"))\r
475                         Cmd_Book ();\r
476                 //\r
477                 // tmix\r
478                 //\r
479                 else if (!strcmp (token, "$texturemix"))\r
480                         Cmd_TextureMix ();\r
481                 //\r
482                 // video\r
483                 //\r
484                 else if (!strcmp (token, "$video"))\r
485                         Cmd_Video ();\r
486                 //\r
487                 // misc\r
488                 //\r
489                 else if (!strcmp (token, "$file"))\r
490                         Cmd_File ();\r
491                 else if (!strcmp (token, "$dir"))\r
492                         Cmd_Dir ();\r
493                 else if (!strcmp (token, "$maps"))\r
494                         Cmd_Maps ();\r
495                 else if (!strcmp (token, "$alphalight"))\r
496                         Cmd_Alphalight ();\r
497                 else if (!strcmp (token, "$inverse16table" ))\r
498                         Cmd_Inverse16Table();\r
499                 else\r
500                         Error ("bad command %s\n", token);\r
501         }\r
502 }\r
503 \r
504 //=======================================================\r
505 \r
506 /*\r
507 ==============\r
508 main\r
509 ==============\r
510 */\r
511 int main (int argc, char **argv)\r
512 {\r
513         int                     i;\r
514         char            path[1024];\r
515         char            *basedir;\r
516         double          starttime, endtime;\r
517 \r
518         printf ("Qdata Plus : "__TIME__" "__DATE__"\n");\r
519 \r
520         starttime = I_FloatTime();\r
521         basedir = NULL;\r
522 \r
523         TK_Init();\r
524         ExpandWildcards (&argc, &argv);\r
525 \r
526         for (i=1 ; i<argc ; i++)\r
527         {\r
528                 if (!strcmp(argv[i], "-archive"))\r
529                 {\r
530                         // -archive f:/quake2/release/dump_11_30\r
531                         archive = true;\r
532                         strcpy (archivedir, argv[i+1]);\r
533                         printf ("Archiving source to: %s\n", archivedir);\r
534                         i++;\r
535                 }\r
536                 else if (!strcmp(argv[i], "-release"))\r
537                 {\r
538                         g_release = true;\r
539                         strcpy (g_releasedir, argv[i+1]);\r
540                         printf ("Copy output to: %s\n", g_releasedir);\r
541                         i++;\r
542                 }\r
543                 else if (!strcmp(argv[i], "-base"))\r
544                 {\r
545                         i++;\r
546                         basedir = argv[i];\r
547                 }\r
548                 else if (!strcmp(argv[i], "-compress"))\r
549                 {\r
550                         g_compress_pak = true;\r
551                         printf ("Compressing pakfile\n");\r
552                 }\r
553                 else if (!strcmp(argv[i], "-pak"))\r
554                 {\r
555                         g_release = true;\r
556                         g_pak = true;\r
557                         printf ("Building pakfile: %s\n", argv[i+1]);\r
558                         BeginPak (argv[i+1]);\r
559                         i++;\r
560                 }\r
561                 else if (!strcmp(argv[i], "-only"))\r
562                 {\r
563                         strcpy (g_only, argv[i+1]);\r
564                         printf ("Only grabbing %s\n", g_only);\r
565                         i++;\r
566                 }\r
567                 else if (!strcmpi(argv[i], "-keypress"))\r
568                 {\r
569                         g_dokeypress = true;\r
570                 }\r
571                 else if (!strcmp(argv[i], "-3ds"))\r
572                 {\r
573                         do3ds = true;\r
574                         printf ("loading .3ds files\n");\r
575                 }\r
576                 else if (!strcmp(argv[i], "-materialfile"))\r
577                 {\r
578                         strcpy(g_materialFile, argv[i+1]);\r
579                         printf("Setting material file to %s\n", g_materialFile);\r
580                         i++;\r
581                 }\r
582 /*              else if (!strcmpi(argv[i], "-newgen"))\r
583                 {\r
584                         if (i < argc-4)\r
585                         {\r
586                                 printf("run new triangle grouping routine here\n");\r
587                                 NewGen(argv[i+1],argv[i+2],atoi(argv[i+3]),atoi(argv[i+4]));\r
588                         }\r
589                         else\r
590                         {\r
591                                 printf("qdata -newskin <base.hrc> <skin.pcx> width height\n");\r
592                         }\r
593                         return 0;\r
594                 }\r
595 */              else if (!strcmpi(argv[i], "-genskin"))\r
596                 {\r
597                         i++;\r
598                         if (i < argc-3)\r
599                         {\r
600                                 GenSkin(argv[i],argv[i+1],atol(argv[i+2]),atol(argv[i+3]));\r
601                         }\r
602                         else\r
603                         {\r
604                                 printf("qdata -genskin <base.hrc> <skin.pcx> <desired width> <desired height>\n");\r
605                         }\r
606                         return 0;\r
607                         \r
608                 }\r
609                 else if (!strcmpi(argv[i], "-noopts"))\r
610                 {\r
611                         g_no_opimizations = true;\r
612                         printf("not performing optimizations\n");\r
613                 }\r
614                 else if (!strcmpi(argv[i], "-md2"))\r
615                 {\r
616                         g_forcemodel = MODEL_MD2;\r
617                 }\r
618                 else if (!strcmpi(argv[i], "-fm"))\r
619                 {\r
620                         g_forcemodel = MODEL_FM;\r
621                 }\r
622                 else if (!strcmpi(argv[i], "-verbose"))\r
623                 {\r
624                         g_verbose = true;\r
625                 }\r
626                 else if (!strcmpi(argv[i], "-oldskin"))\r
627                 {\r
628                         g_allow_newskin = false;\r
629                 }\r
630                 else if (!strcmpi(argv[i], "-ignoreUV"))\r
631                 {\r
632                         g_ignoreTriUV = true;\r
633                 }\r
634                 else if (!strcmpi(argv[i], "-publish"))\r
635                 {\r
636                         g_publishOutput = true;\r
637                 }\r
638                 else if (!strcmpi(argv[i], "-nomkdir"))\r
639                 {\r
640                         g_nomkdir = true;\r
641                 }\r
642                 else if (argv[i][0] == '-')\r
643                         Error ("Unknown option \"%s\"", argv[i]);\r
644                 else\r
645                         break;\r
646         }\r
647 \r
648         if (i >= argc)\r
649         {\r
650                 Error ("usage: qdata [-archive <directory>]\n"\r
651                         "             [-release <directory>]\n"\r
652                         "             [-base <directory>]\n"\r
653                         "             [-compress]\n"\r
654                         "             [-pak <file>]\n"\r
655                         "             [-only <model>]\n"\r
656                         "             [-keypress]\n"\r
657                         "             [-3ds]\n"\r
658                         "             [-materialfile <file>]\n"\r
659                         "             [-noopts]\n"\r
660                         "             [-md2]\n"\r
661                         "             [-fm]\n"\r
662                         "             [-verbose]\n"\r
663                         "             [-ignoreUV]\n"\r
664                         "             [-oldskin]\n"\r
665                         "             [-publish]\n"\r
666                         "             [-nomkdir]\n"\r
667                         "             file.qdt\n"\r
668                         "or\n"\r
669                         "       qdata -genskin <base.hrc> <skin.pcx> <desired width> <desired height>");\r
670         }\r
671 \r
672         if (do3ds)\r
673                 trifileext = ext_3ds;\r
674         else\r
675                 trifileext = ext_tri;\r
676 \r
677         for ( ; i<argc ; i++)\r
678         {\r
679                 printf ("--------------- %s ---------------\n", argv[i]);\r
680                 // load the script\r
681                 strcpy (path, argv[i]);\r
682                 DefaultExtension (path, ".qdt");\r
683                 DefaultExtension(g_materialFile, ".mat");\r
684                 SetQdirFromPath (path);\r
685 \r
686                 printf("workingdir='%s'\n", gamedir);\r
687                 if (basedir)\r
688                 {\r
689                         qdir[0] = 0;\r
690                         g_outputDir = basedir;\r
691                 }\r
692 \r
693                 printf("outputdir='%s'\n", g_outputDir);\r
694 \r
695                 QFile_ReadMaterialTypes(g_materialFile);\r
696                 LoadScriptFile (ExpandArg(path));\r
697                 \r
698                 //\r
699                 // parse it\r
700                 //\r
701                 ParseScript ();\r
702 \r
703                 // write out the last model\r
704                 FinishModel ();\r
705                 FMFinishModel ();\r
706                 FinishSprite ();\r
707         }\r
708 \r
709         if (total_textures)\r
710         {\r
711                 printf("\n");\r
712                 printf("Total textures processed: %d\n",total_textures);\r
713                 printf("Average size: %d x %d\n",total_x / total_textures, total_y / total_textures);\r
714         }\r
715 \r
716         if (g_pak)\r
717                 FinishPak ();\r
718 \r
719         endtime = I_FloatTime();\r
720         printf("Time elapsed:  %f\n", endtime-starttime);\r
721         \r
722         if (g_dokeypress)\r
723         {\r
724                 printf("Success! ... Hit a key: ");\r
725                 getchar();\r
726         }\r
727 \r
728         return 0;\r
729 }\r
730 \r