/* Copyright (C) 1999-2006 Id Software, Inc. and contributors. For a list of contributors, see the accompanying CONTRIBUTORS file. This file is part of GtkRadiant. GtkRadiant is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. GtkRadiant is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GtkRadiant; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "qdata.h" #include "md4.h" void TK_Init(); qboolean g_compress_pak; qboolean g_release; // don't grab, copy output data to new tree qboolean g_pak; // if true, copy to pak instead of release char g_releasedir[1024]; // c:\quake2\baseq2, etc qboolean g_archive; // don't grab, copy source data to new tree qboolean do3ds; char g_only[256]; // if set, only grab this cd qboolean g_skipmodel; // set true when a cd is not g_only int g_forcemodel = MODEL_AUTO; qboolean g_verbose = false; qboolean g_allow_newskin = true; qboolean g_ignoreTriUV = false; qboolean g_publishOutput = false; char *ext_3ds = "3ds"; char *ext_tri= "tri"; char *trifileext; char g_materialFile[256] = "none"; // default for Heretic2 char *g_outputDir; extern char *g_publishDir; extern qboolean g_nomkdir; /* ======================================================= PAK FILES ======================================================= */ typedef struct { char name[56]; int filepos, filelen; } packfile_t; typedef struct { char id[4]; int dirofs; int dirlen; } packheader_t; packfile_t pfiles[16384]; FILE *pakfile; packfile_t *pf; packheader_t pakheader; /* ============== BeginPak ============== */ void BeginPak (char *outname) { if (!g_pak) return; pakfile = SafeOpenWrite (outname); // leave space for header SafeWrite (pakfile, &pakheader, sizeof(pakheader)); pf = pfiles; } /* ============== ReleaseFile Filename should be gamedir reletive. Either copies the file to the release dir, or adds it to the pak file. ============== */ void ReleaseFile (char *filename) { int len; byte *buf; char source[1024]; char dest[1024]; if (!g_release) return; sprintf (source, "%s%s", gamedir, filename); if (!g_pak) { // copy it sprintf (dest, "%s/%s", g_releasedir, filename); printf ("copying to %s\n", dest); QCopyFile (source, dest); return; } // pak it printf ("paking %s\n", filename); if (strlen(filename) >= sizeof(pf->name)) Error ("Filename too long for pak: %s", filename); len = LoadFile (source, (void **)&buf); // segment moved to old.c strcpy (pf->name, filename); pf->filepos = LittleLong(ftell(pakfile)); pf->filelen = LittleLong(len); pf++; SafeWrite (pakfile, buf, len); free (buf); } /* ============== FinishPak ============== */ void FinishPak (void) { int dirlen; int d; int i; unsigned checksum; if (!g_pak) return; pakheader.id[0] = 'P'; pakheader.id[1] = 'A'; pakheader.id[2] = 'C'; pakheader.id[3] = 'K'; dirlen = (byte *)pf - (byte *)pfiles; pakheader.dirofs = LittleLong(ftell(pakfile)); pakheader.dirlen = LittleLong(dirlen); checksum = Com_BlockChecksum ( (void *)pfiles, dirlen ); SafeWrite (pakfile, pfiles, dirlen); i = ftell (pakfile); fseek (pakfile, 0, SEEK_SET); SafeWrite (pakfile, &pakheader, sizeof(pakheader)); fclose (pakfile); d = pf - pfiles; printf ("%i files packed in %i bytes\n",d, i); printf ("checksum: 0x%x\n", checksum); } /* =============== Cmd_File This is only used to cause a file to be copied during a release build (default.cfg, maps, etc) =============== */ void Cmd_File (void) { GetScriptToken (false); ReleaseFile (token); } /* =============== PackDirectory_r =============== */ #ifdef _WIN32 #include "io.h" void PackDirectory_r (char *dir) { struct _finddata_t fileinfo; int handle; char dirstring[1024]; char filename[1024]; sprintf (dirstring, "%s%s/*.*", gamedir, dir); handle = _findfirst (dirstring, &fileinfo); if (handle == -1) return; do { sprintf (filename, "%s/%s", dir, fileinfo.name); if (fileinfo.attrib & _A_SUBDIR) { // directory if (fileinfo.name[0] != '.') // don't pak . and .. PackDirectory_r (filename); continue; } // copy or pack the file ReleaseFile (filename); } while (_findnext( handle, &fileinfo ) != -1); _findclose (handle); } #else #include #ifdef NeXT #include #else #include #endif void PackDirectory_r (char *dir) { #ifdef NeXT struct direct **namelist, *ent; #else struct dirent **namelist, *ent; #endif int count; struct stat st; int i; int len; char fullname[1024]; char dirstring[1024]; char *name; sprintf (dirstring, "%s%s", gamedir, dir); count = scandir(dirstring, &namelist, NULL, NULL); for (i=0 ; id_name; if (name[0] == '.') continue; sprintf (fullname, "%s/%s", dir, name); sprintf (dirstring, "%s%s/%s", gamedir, dir, name); if (stat (dirstring, &st) == -1) Error ("fstating %s", pf->name); if (st.st_mode & S_IFDIR) { // directory PackDirectory_r (fullname); continue; } // copy or pack the file ReleaseFile (fullname); } } #endif /* =============== Cmd_Dir This is only used to cause a directory to be copied during a release build (sounds, etc) =============== */ void Cmd_Dir (void) { GetScriptToken (false); PackDirectory_r (token); } //======================================================================== #define MAX_RTEX 16384 int numrtex; char rtex[MAX_RTEX][64]; void ReleaseTexture (char *name) { int i; char path[1024]; for (i=0 ; i width height\n"); } return 0; } */ else if (!strcmpi(argv[i], "-genskin")) { i++; if (i < argc-3) { GenSkin(argv[i],argv[i+1],atol(argv[i+2]),atol(argv[i+3])); } else { printf("qdata -genskin \n"); } return 0; } else if (!strcmpi(argv[i], "-noopts")) { g_no_opimizations = true; printf("not performing optimizations\n"); } else if (!strcmpi(argv[i], "-md2")) { g_forcemodel = MODEL_MD2; } else if (!strcmpi(argv[i], "-fm")) { g_forcemodel = MODEL_FM; } else if (!strcmpi(argv[i], "-verbose")) { g_verbose = true; } else if (!strcmpi(argv[i], "-oldskin")) { g_allow_newskin = false; } else if (!strcmpi(argv[i], "-ignoreUV")) { g_ignoreTriUV = true; } else if (!strcmpi(argv[i], "-publish")) { g_publishOutput = true; } else if (!strcmpi(argv[i], "-nomkdir")) { g_nomkdir = true; } else if (argv[i][0] == '-') Error ("Unknown option \"%s\"", argv[i]); else break; } if (i >= argc) { Error ("usage: qdata [-archive ]\n" " [-release ]\n" " [-base ]\n" " [-compress]\n" " [-pak ]\n" " [-only ]\n" " [-keypress]\n" " [-3ds]\n" " [-materialfile ]\n" " [-noopts]\n" " [-md2]\n" " [-fm]\n" " [-verbose]\n" " [-ignoreUV]\n" " [-oldskin]\n" " [-publish]\n" " [-nomkdir]\n" " file.qdt\n" "or\n" " qdata -genskin "); } if (do3ds) trifileext = ext_3ds; else trifileext = ext_tri; for ( ; i