2 Copyright (C) 1999-2007 id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
5 This file is part of GtkRadiant.
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 qboolean g_compress_pak;
27 qboolean g_release; // don't grab, copy output data to new tree
28 qboolean g_pak; // if true, copy to pak instead of release
29 char g_releasedir[1024]; // c:\quake2\baseq2, etc
30 qboolean g_archive; // don't grab, copy source data to new tree
32 char g_only[256]; // if set, only grab this cd
33 qboolean g_skipmodel; // set true when a cd is not g_only
34 int g_forcemodel = MODEL_AUTO;
35 qboolean g_verbose = false;
36 qboolean g_allow_newskin = true;
37 qboolean g_ignoreTriUV = false;
38 qboolean g_publishOutput = false;
40 char *ext_3ds = "3ds";
44 char g_materialFile[256] = "none"; // default for Heretic2
46 extern char *g_publishDir;
48 extern qboolean g_nomkdir;
51 =======================================================
55 =======================================================
71 packfile_t pfiles[16384];
74 packheader_t pakheader;
83 void BeginPak (char *outname)
88 pakfile = SafeOpenWrite (outname);
90 // leave space for header
91 SafeWrite (pakfile, &pakheader, sizeof(pakheader));
101 Filename should be gamedir reletive.
102 Either copies the file to the release dir, or adds it to
106 void ReleaseFile (char *filename)
116 sprintf (source, "%s%s", gamedir, filename);
120 sprintf (dest, "%s/%s", g_releasedir, filename);
121 printf ("copying to %s\n", dest);
122 QCopyFile (source, dest);
127 printf ("paking %s\n", filename);
128 if (strlen(filename) >= sizeof(pf->name))
129 Error ("Filename too long for pak: %s", filename);
131 len = LoadFile (source, (void **)&buf);
133 // segment moved to old.c
135 strcpy (pf->name, filename);
136 pf->filepos = LittleLong(ftell(pakfile));
137 pf->filelen = LittleLong(len);
140 SafeWrite (pakfile, buf, len);
151 void FinishPak (void)
160 pakheader.id[0] = 'P';
161 pakheader.id[1] = 'A';
162 pakheader.id[2] = 'C';
163 pakheader.id[3] = 'K';
164 dirlen = (byte *)pf - (byte *)pfiles;
165 pakheader.dirofs = LittleLong(ftell(pakfile));
166 pakheader.dirlen = LittleLong(dirlen);
168 SafeWrite (pakfile, pfiles, dirlen);
172 fseek (pakfile, 0, SEEK_SET);
173 SafeWrite (pakfile, &pakheader, sizeof(pakheader));
177 printf ("%i files packed in %i bytes\n",d, i);
185 This is only used to cause a file to be copied during a release
186 build (default.cfg, maps, etc)
191 GetScriptToken (false);
203 void PackDirectory_r (char *dir)
205 struct _finddata_t fileinfo;
207 char dirstring[1024];
210 sprintf (dirstring, "%s%s/*.*", gamedir, dir);
212 handle = _findfirst (dirstring, &fileinfo);
218 sprintf (filename, "%s/%s", dir, fileinfo.name);
219 if (fileinfo.attrib & _A_SUBDIR)
221 if (fileinfo.name[0] != '.') // don't pak . and ..
222 PackDirectory_r (filename);
225 // copy or pack the file
226 ReleaseFile (filename);
227 } while (_findnext( handle, &fileinfo ) != -1);
233 #include <sys/types.h>
240 void PackDirectory_r (char *dir)
243 struct direct **namelist, *ent;
245 struct dirent **namelist, *ent;
252 char dirstring[1024];
255 sprintf (dirstring, "%s%s", gamedir, dir);
256 count = scandir(dirstring, &namelist, NULL, NULL);
258 for (i=0 ; i<count ; i++)
266 sprintf (fullname, "%s/%s", dir, name);
267 sprintf (dirstring, "%s%s/%s", gamedir, dir, name);
269 if (stat (dirstring, &st) == -1)
270 Error ("fstating %s", pf->name);
271 if (st.st_mode & S_IFDIR)
273 PackDirectory_r (fullname);
277 // copy or pack the file
278 ReleaseFile (fullname);
288 This is only used to cause a directory to be copied during a
289 release build (sounds, etc)
294 GetScriptToken (false);
295 PackDirectory_r (token);
298 //========================================================================
300 #define MAX_RTEX 16384
302 char rtex[MAX_RTEX][64];
304 void ReleaseTexture (char *name)
309 for (i=0 ; i<numrtex ; i++)
310 if (!Q_strcasecmp(name, rtex[i]))
313 if (numrtex == MAX_RTEX)
314 Error ("numrtex == MAX_RTEX");
316 strcpy (rtex[i], name);
319 sprintf (path, "textures/%s.wal", name);
327 Only relevent for release and pak files.
328 Releases the .bsp files for the maps, and scans all of the files to
329 build a list of all textures used, which are then released.
337 while (ScriptTokenAvailable ())
339 GetScriptToken (false);
340 sprintf (map, "maps/%s.bsp", token);
346 // get all the texture references
347 sprintf (map, "%smaps/%s.bsp", gamedir, token);
348 LoadBSPFileTexinfo (map);
349 for (i=0 ; i<numtexinfo ; i++)
350 ReleaseTexture (texinfo[i].texture);
355 //==============================================================
362 void ParseScript (void)
367 { // look for a line starting with a $ command
368 GetScriptToken (true);
373 while (ScriptTokenAvailable())
374 GetScriptToken (false);
380 if (!strcmp (token, "$modelname"))
381 MODELCMD_Modelname (MODEL_MD2);
382 else if (!strcmp (token, "$cd"))
383 MODELCMD_Cd (MODEL_MD2);
384 else if (!strcmp (token, "$origin"))
385 MODELCMD_Origin (MODEL_MD2);
386 else if (!strcmp (token, "$cluster"))
387 MODELCMD_Cluster (MODEL_MD2);
388 else if (!strcmp (token, "$base"))
389 MODELCMD_Base (MODEL_MD2);
390 else if (!strcmp (token, "$scale"))
391 MODELCMD_ScaleUp (MODEL_MD2);
392 else if (!strcmp (token, "$frame"))
393 MODELCMD_Frame (MODEL_MD2);
394 else if (!strcmp (token, "$skin"))
395 MODELCMD_Skin (MODEL_MD2);
396 else if (!strcmp (token, "$skinsize"))
397 MODELCMD_Skinsize (MODEL_MD2);
399 // flexible model commands
401 else if (!strcmp (token, "$fm_modelname"))
402 MODELCMD_Modelname (MODEL_FM);
403 else if (!strcmp (token, "$fm_base"))
404 MODELCMD_Base (MODEL_FM);
405 else if (!strcmp (token, "$fm_basest"))
406 MODELCMD_BaseST (MODEL_FM);
407 else if (!strcmp (token, "$fm_cd"))
408 MODELCMD_Cd (MODEL_FM);
409 else if (!strcmp (token, "$fm_origin"))
410 MODELCMD_Origin (MODEL_FM);
411 else if (!strcmp (token, "$fm_cluster"))
412 MODELCMD_Cluster (MODEL_FM);
413 else if (!strcmp (token, "$fm_skeleton"))
414 MODELCMD_Skeleton (MODEL_FM);
415 else if (!strcmp (token, "$fm_scale"))
416 MODELCMD_ScaleUp (MODEL_FM);
417 else if (!strcmp (token, "$fm_frame"))
418 MODELCMD_Frame (MODEL_FM);
419 else if (!strcmp (token, "$fm_skeletal_frame")) // left in for compadibility with qdt already using fm_skeletal_frame
420 MODELCMD_Frame (MODEL_FM);
421 else if (!strcmp (token, "$fm_skin"))
422 MODELCMD_Skin (MODEL_FM);
423 else if (!strcmp (token, "$fm_skinsize"))
424 MODELCMD_Skinsize (MODEL_FM);
425 else if (!strcmp (token, "$fm_begin_group"))
426 MODELCMD_BeginGroup(MODEL_FM);
427 else if (!strcmp (token, "$fm_end_group"))
428 MODELCMD_EndGroup(MODEL_FM);
429 else if (!strcmp (token, "$fm_referenced"))
430 MODELCMD_Referenced(MODEL_FM);
431 else if (!strcmp (token, "$fm_node_order"))
432 MODELCMD_NodeOrder(MODEL_FM);
437 else if (!strcmp (token, "$spritename"))
439 else if (!strcmp (token, "$sprdir"))
441 else if (!strcmp (token, "$load"))
443 else if (!strcmp (token, "$spriteframe"))
448 else if (!strcmpi (token, "$grab"))
450 else if (!strcmpi (token, "$raw"))
452 else if (!strcmpi (token, "$colormap"))
454 else if (!strcmpi (token, "$mippal"))
456 else if (!strcmpi (token, "$mipdir"))
458 else if (!strcmpi (token, "$mip"))
460 else if (!strcmp (token, "$environment"))
465 else if (!strcmp (token, "$picdir"))
467 else if (!strcmp (token, "$pic"))
472 else if (!strcmp (token, "$bookdir"))
474 else if (!strcmp (token, "$book"))
479 else if (!strcmp (token, "$texturemix"))
484 else if (!strcmp (token, "$video"))
489 else if (!strcmp (token, "$file"))
491 else if (!strcmp (token, "$dir"))
493 else if (!strcmp (token, "$maps"))
495 else if (!strcmp (token, "$alphalight"))
497 else if (!strcmp (token, "$inverse16table" ))
498 Cmd_Inverse16Table();
500 Error ("bad command %s\n", token);
504 //=======================================================
511 int main (int argc, char **argv)
516 double starttime, endtime;
518 printf ("Qdata Plus : "__TIME__" "__DATE__"\n");
520 starttime = I_FloatTime();
524 ExpandWildcards (&argc, &argv);
526 for (i=1 ; i<argc ; i++)
528 if (!strcmp(argv[i], "-archive"))
530 // -archive f:/quake2/release/dump_11_30
532 strcpy (archivedir, argv[i+1]);
533 printf ("Archiving source to: %s\n", archivedir);
536 else if (!strcmp(argv[i], "-release"))
539 strcpy (g_releasedir, argv[i+1]);
540 printf ("Copy output to: %s\n", g_releasedir);
543 else if (!strcmp(argv[i], "-base"))
548 else if (!strcmp(argv[i], "-compress"))
550 g_compress_pak = true;
551 printf ("Compressing pakfile\n");
553 else if (!strcmp(argv[i], "-pak"))
557 printf ("Building pakfile: %s\n", argv[i+1]);
558 BeginPak (argv[i+1]);
561 else if (!strcmp(argv[i], "-only"))
563 strcpy (g_only, argv[i+1]);
564 printf ("Only grabbing %s\n", g_only);
567 else if (!strcmpi(argv[i], "-keypress"))
571 else if (!strcmp(argv[i], "-3ds"))
574 printf ("loading .3ds files\n");
576 else if (!strcmp(argv[i], "-materialfile"))
578 strcpy(g_materialFile, argv[i+1]);
579 printf("Setting material file to %s\n", g_materialFile);
582 /* else if (!strcmpi(argv[i], "-newgen"))
586 printf("run new triangle grouping routine here\n");
587 NewGen(argv[i+1],argv[i+2],atoi(argv[i+3]),atoi(argv[i+4]));
591 printf("qdata -newskin <base.hrc> <skin.pcx> width height\n");
595 */ else if (!strcmpi(argv[i], "-genskin"))
600 GenSkin(argv[i],argv[i+1],atol(argv[i+2]),atol(argv[i+3]));
604 printf("qdata -genskin <base.hrc> <skin.pcx> <desired width> <desired height>\n");
609 else if (!strcmpi(argv[i], "-noopts"))
611 g_no_opimizations = true;
612 printf("not performing optimizations\n");
614 else if (!strcmpi(argv[i], "-md2"))
616 g_forcemodel = MODEL_MD2;
618 else if (!strcmpi(argv[i], "-fm"))
620 g_forcemodel = MODEL_FM;
622 else if (!strcmpi(argv[i], "-verbose"))
626 else if (!strcmpi(argv[i], "-oldskin"))
628 g_allow_newskin = false;
630 else if (!strcmpi(argv[i], "-ignoreUV"))
632 g_ignoreTriUV = true;
634 else if (!strcmpi(argv[i], "-publish"))
636 g_publishOutput = true;
638 else if (!strcmpi(argv[i], "-nomkdir"))
642 else if (argv[i][0] == '-')
643 Error ("Unknown option \"%s\"", argv[i]);
650 Error ("usage: qdata [-archive <directory>]\n"
651 " [-release <directory>]\n"
652 " [-base <directory>]\n"
658 " [-materialfile <file>]\n"
669 " qdata -genskin <base.hrc> <skin.pcx> <desired width> <desired height>");
673 trifileext = ext_3ds;
675 trifileext = ext_tri;
677 for ( ; i<argc ; i++)
679 printf ("--------------- %s ---------------\n", argv[i]);
681 strcpy (path, argv[i]);
682 DefaultExtension (path, ".qdt");
683 DefaultExtension(g_materialFile, ".mat");
684 SetQdirFromPath (path);
686 printf("workingdir='%s'\n", gamedir);
690 g_outputDir = basedir;
693 printf("outputdir='%s'\n", g_outputDir);
695 QFile_ReadMaterialTypes(g_materialFile);
696 LoadScriptFile (ExpandArg(path));
703 // write out the last model
712 printf("Total textures processed: %d\n",total_textures);
713 printf("Average size: %d x %d\n",total_x / total_textures, total_y / total_textures);
719 endtime = I_FloatTime();
720 printf("Time elapsed: %f\n", endtime-starttime);
724 printf("Success! ... Hit a key: ");