2 Copyright (C) 1999-2006 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
27 qboolean g_compress_pak;
28 qboolean g_release; // don't grab, copy output data to new tree
29 qboolean g_pak; // if true, copy to pak instead of release
30 char g_releasedir[1024]; // c:\quake2\baseq2, etc
31 qboolean g_archive; // don't grab, copy source data to new tree
33 char g_only[256]; // if set, only grab this cd
34 qboolean g_skipmodel; // set true when a cd is not g_only
35 int g_forcemodel = MODEL_AUTO;
36 qboolean g_verbose = false;
37 qboolean g_allow_newskin = true;
38 qboolean g_ignoreTriUV = false;
39 qboolean g_publishOutput = false;
41 char *ext_3ds = "3ds";
45 char g_materialFile[256] = "none"; // default for Heretic2
47 extern char *g_publishDir;
49 extern qboolean g_nomkdir;
52 =======================================================
56 =======================================================
72 packfile_t pfiles[16384];
75 packheader_t pakheader;
84 void BeginPak (char *outname)
89 pakfile = SafeOpenWrite (outname);
91 // leave space for header
92 SafeWrite (pakfile, &pakheader, sizeof(pakheader));
102 Filename should be gamedir reletive.
103 Either copies the file to the release dir, or adds it to
107 void ReleaseFile (char *filename)
117 sprintf (source, "%s%s", gamedir, filename);
121 sprintf (dest, "%s/%s", g_releasedir, filename);
122 printf ("copying to %s\n", dest);
123 QCopyFile (source, dest);
128 printf ("paking %s\n", filename);
129 if (strlen(filename) >= sizeof(pf->name))
130 Error ("Filename too long for pak: %s", filename);
132 len = LoadFile (source, (void **)&buf);
134 // segment moved to old.c
136 strcpy (pf->name, filename);
137 pf->filepos = LittleLong(ftell(pakfile));
138 pf->filelen = LittleLong(len);
141 SafeWrite (pakfile, buf, len);
152 void FinishPak (void)
162 pakheader.id[0] = 'P';
163 pakheader.id[1] = 'A';
164 pakheader.id[2] = 'C';
165 pakheader.id[3] = 'K';
166 dirlen = (byte *)pf - (byte *)pfiles;
167 pakheader.dirofs = LittleLong(ftell(pakfile));
168 pakheader.dirlen = LittleLong(dirlen);
170 checksum = Com_BlockChecksum ( (void *)pfiles, dirlen );
172 SafeWrite (pakfile, pfiles, dirlen);
176 fseek (pakfile, 0, SEEK_SET);
177 SafeWrite (pakfile, &pakheader, sizeof(pakheader));
181 printf ("%i files packed in %i bytes\n",d, i);
182 printf ("checksum: 0x%x\n", checksum);
190 This is only used to cause a file to be copied during a release
191 build (default.cfg, maps, etc)
196 GetScriptToken (false);
208 void PackDirectory_r (char *dir)
210 struct _finddata_t fileinfo;
212 char dirstring[1024];
215 sprintf (dirstring, "%s%s/*.*", gamedir, dir);
217 handle = _findfirst (dirstring, &fileinfo);
223 sprintf (filename, "%s/%s", dir, fileinfo.name);
224 if (fileinfo.attrib & _A_SUBDIR)
226 if (fileinfo.name[0] != '.') // don't pak . and ..
227 PackDirectory_r (filename);
230 // copy or pack the file
231 ReleaseFile (filename);
232 } while (_findnext( handle, &fileinfo ) != -1);
238 #include <sys/types.h>
245 void PackDirectory_r (char *dir)
248 struct direct **namelist, *ent;
250 struct dirent **namelist, *ent;
257 char dirstring[1024];
260 sprintf (dirstring, "%s%s", gamedir, dir);
261 count = scandir(dirstring, &namelist, NULL, NULL);
263 for (i=0 ; i<count ; i++)
271 sprintf (fullname, "%s/%s", dir, name);
272 sprintf (dirstring, "%s%s/%s", gamedir, dir, name);
274 if (stat (dirstring, &st) == -1)
275 Error ("fstating %s", pf->name);
276 if (st.st_mode & S_IFDIR)
278 PackDirectory_r (fullname);
282 // copy or pack the file
283 ReleaseFile (fullname);
293 This is only used to cause a directory to be copied during a
294 release build (sounds, etc)
299 GetScriptToken (false);
300 PackDirectory_r (token);
303 //========================================================================
305 #define MAX_RTEX 16384
307 char rtex[MAX_RTEX][64];
309 void ReleaseTexture (char *name)
314 for (i=0 ; i<numrtex ; i++)
315 if (!Q_strcasecmp(name, rtex[i]))
318 if (numrtex == MAX_RTEX)
319 Error ("numrtex == MAX_RTEX");
321 strcpy (rtex[i], name);
324 sprintf (path, "textures/%s.wal", name);
332 Only relevent for release and pak files.
333 Releases the .bsp files for the maps, and scans all of the files to
334 build a list of all textures used, which are then released.
342 while (ScriptTokenAvailable ())
344 GetScriptToken (false);
345 sprintf (map, "maps/%s.bsp", token);
351 // get all the texture references
352 sprintf (map, "%smaps/%s.bsp", gamedir, token);
353 LoadBSPFileTexinfo (map);
354 for (i=0 ; i<numtexinfo ; i++)
355 ReleaseTexture (texinfo[i].texture);
360 //==============================================================
367 void ParseScript (void)
372 { // look for a line starting with a $ command
373 GetScriptToken (true);
378 while (ScriptTokenAvailable())
379 GetScriptToken (false);
385 if (!strcmp (token, "$modelname"))
386 MODELCMD_Modelname (MODEL_MD2);
387 else if (!strcmp (token, "$cd"))
388 MODELCMD_Cd (MODEL_MD2);
389 else if (!strcmp (token, "$origin"))
390 MODELCMD_Origin (MODEL_MD2);
391 else if (!strcmp (token, "$cluster"))
392 MODELCMD_Cluster (MODEL_MD2);
393 else if (!strcmp (token, "$base"))
394 MODELCMD_Base (MODEL_MD2);
395 else if (!strcmp (token, "$scale"))
396 MODELCMD_ScaleUp (MODEL_MD2);
397 else if (!strcmp (token, "$frame"))
398 MODELCMD_Frame (MODEL_MD2);
399 else if (!strcmp (token, "$skin"))
400 MODELCMD_Skin (MODEL_MD2);
401 else if (!strcmp (token, "$skinsize"))
402 MODELCMD_Skinsize (MODEL_MD2);
404 // flexible model commands
406 else if (!strcmp (token, "$fm_modelname"))
407 MODELCMD_Modelname (MODEL_FM);
408 else if (!strcmp (token, "$fm_base"))
409 MODELCMD_Base (MODEL_FM);
410 else if (!strcmp (token, "$fm_basest"))
411 MODELCMD_BaseST (MODEL_FM);
412 else if (!strcmp (token, "$fm_cd"))
413 MODELCMD_Cd (MODEL_FM);
414 else if (!strcmp (token, "$fm_origin"))
415 MODELCMD_Origin (MODEL_FM);
416 else if (!strcmp (token, "$fm_cluster"))
417 MODELCMD_Cluster (MODEL_FM);
418 else if (!strcmp (token, "$fm_skeleton"))
419 MODELCMD_Skeleton (MODEL_FM);
420 else if (!strcmp (token, "$fm_scale"))
421 MODELCMD_ScaleUp (MODEL_FM);
422 else if (!strcmp (token, "$fm_frame"))
423 MODELCMD_Frame (MODEL_FM);
424 else if (!strcmp (token, "$fm_skeletal_frame")) // left in for compadibility with qdt already using fm_skeletal_frame
425 MODELCMD_Frame (MODEL_FM);
426 else if (!strcmp (token, "$fm_skin"))
427 MODELCMD_Skin (MODEL_FM);
428 else if (!strcmp (token, "$fm_skinsize"))
429 MODELCMD_Skinsize (MODEL_FM);
430 else if (!strcmp (token, "$fm_begin_group"))
431 MODELCMD_BeginGroup(MODEL_FM);
432 else if (!strcmp (token, "$fm_end_group"))
433 MODELCMD_EndGroup(MODEL_FM);
434 else if (!strcmp (token, "$fm_referenced"))
435 MODELCMD_Referenced(MODEL_FM);
436 else if (!strcmp (token, "$fm_node_order"))
437 MODELCMD_NodeOrder(MODEL_FM);
442 else if (!strcmp (token, "$spritename"))
444 else if (!strcmp (token, "$sprdir"))
446 else if (!strcmp (token, "$load"))
448 else if (!strcmp (token, "$spriteframe"))
453 else if (!strcmpi (token, "$grab"))
455 else if (!strcmpi (token, "$raw"))
457 else if (!strcmpi (token, "$colormap"))
459 else if (!strcmpi (token, "$mippal"))
461 else if (!strcmpi (token, "$mipdir"))
463 else if (!strcmpi (token, "$mip"))
465 else if (!strcmp (token, "$environment"))
470 else if (!strcmp (token, "$picdir"))
472 else if (!strcmp (token, "$pic"))
477 else if (!strcmp (token, "$bookdir"))
479 else if (!strcmp (token, "$book"))
484 else if (!strcmp (token, "$texturemix"))
489 else if (!strcmp (token, "$video"))
494 else if (!strcmp (token, "$file"))
496 else if (!strcmp (token, "$dir"))
498 else if (!strcmp (token, "$maps"))
500 else if (!strcmp (token, "$alphalight"))
502 else if (!strcmp (token, "$inverse16table" ))
503 Cmd_Inverse16Table();
505 Error ("bad command %s\n", token);
509 //=======================================================
516 int main (int argc, char **argv)
521 double starttime, endtime;
523 printf ("Qdata Plus : "__TIME__" "__DATE__"\n");
525 starttime = I_FloatTime();
529 ExpandWildcards (&argc, &argv);
531 for (i=1 ; i<argc ; i++)
533 if (!strcmp(argv[i], "-archive"))
535 // -archive f:/quake2/release/dump_11_30
537 strcpy (archivedir, argv[i+1]);
538 printf ("Archiving source to: %s\n", archivedir);
541 else if (!strcmp(argv[i], "-release"))
544 strcpy (g_releasedir, argv[i+1]);
545 printf ("Copy output to: %s\n", g_releasedir);
548 else if (!strcmp(argv[i], "-base"))
553 else if (!strcmp(argv[i], "-compress"))
555 g_compress_pak = true;
556 printf ("Compressing pakfile\n");
558 else if (!strcmp(argv[i], "-pak"))
562 printf ("Building pakfile: %s\n", argv[i+1]);
563 BeginPak (argv[i+1]);
566 else if (!strcmp(argv[i], "-only"))
568 strcpy (g_only, argv[i+1]);
569 printf ("Only grabbing %s\n", g_only);
572 else if (!strcmpi(argv[i], "-keypress"))
576 else if (!strcmp(argv[i], "-3ds"))
579 printf ("loading .3ds files\n");
581 else if (!strcmp(argv[i], "-materialfile"))
583 strcpy(g_materialFile, argv[i+1]);
584 printf("Setting material file to %s\n", g_materialFile);
587 /* else if (!strcmpi(argv[i], "-newgen"))
591 printf("run new triangle grouping routine here\n");
592 NewGen(argv[i+1],argv[i+2],atoi(argv[i+3]),atoi(argv[i+4]));
596 printf("qdata -newskin <base.hrc> <skin.pcx> width height\n");
600 */ else if (!strcmpi(argv[i], "-genskin"))
605 GenSkin(argv[i],argv[i+1],atol(argv[i+2]),atol(argv[i+3]));
609 printf("qdata -genskin <base.hrc> <skin.pcx> <desired width> <desired height>\n");
614 else if (!strcmpi(argv[i], "-noopts"))
616 g_no_opimizations = true;
617 printf("not performing optimizations\n");
619 else if (!strcmpi(argv[i], "-md2"))
621 g_forcemodel = MODEL_MD2;
623 else if (!strcmpi(argv[i], "-fm"))
625 g_forcemodel = MODEL_FM;
627 else if (!strcmpi(argv[i], "-verbose"))
631 else if (!strcmpi(argv[i], "-oldskin"))
633 g_allow_newskin = false;
635 else if (!strcmpi(argv[i], "-ignoreUV"))
637 g_ignoreTriUV = true;
639 else if (!strcmpi(argv[i], "-publish"))
641 g_publishOutput = true;
643 else if (!strcmpi(argv[i], "-nomkdir"))
647 else if (argv[i][0] == '-')
648 Error ("Unknown option \"%s\"", argv[i]);
655 Error ("usage: qdata [-archive <directory>]\n"
656 " [-release <directory>]\n"
657 " [-base <directory>]\n"
663 " [-materialfile <file>]\n"
674 " qdata -genskin <base.hrc> <skin.pcx> <desired width> <desired height>");
678 trifileext = ext_3ds;
680 trifileext = ext_tri;
682 for ( ; i<argc ; i++)
684 printf ("--------------- %s ---------------\n", argv[i]);
686 strcpy (path, argv[i]);
687 DefaultExtension (path, ".qdt");
688 DefaultExtension(g_materialFile, ".mat");
689 SetQdirFromPath (path);
691 printf("workingdir='%s'\n", gamedir);
695 g_outputDir = basedir;
698 printf("outputdir='%s'\n", g_outputDir);
700 QFile_ReadMaterialTypes(g_materialFile);
701 LoadScriptFile (ExpandArg(path));
708 // write out the last model
717 printf("Total textures processed: %d\n",total_textures);
718 printf("Average size: %d x %d\n",total_x / total_textures, total_y / total_textures);
724 endtime = I_FloatTime();
725 printf("Time elapsed: %f\n", endtime-starttime);
729 printf("Success! ... Hit a key: ");