]> git.xonotic.org Git - xonotic/netradiant.git/blobdiff - tools/quake2/qdata/qdata.c
transfer from internal tree r5311 branches/1.4-gpl
[xonotic/netradiant.git] / tools / quake2 / qdata / qdata.c
diff --git a/tools/quake2/qdata/qdata.c b/tools/quake2/qdata/qdata.c
new file mode 100644 (file)
index 0000000..1ba332b
--- /dev/null
@@ -0,0 +1,526 @@
+#include "qdata.h"\r
+#include "inout.h"\r
+\r
+qboolean       g_compress_pak;\r
+qboolean       g_release;                      // don't grab, copy output data to new tree\r
+qboolean       g_pak;                          // if true, copy to pak instead of release\r
+char           g_releasedir[1024];     // c:\quake2\baseq2, etc\r
+qboolean       g_archive;                      // don't grab, copy source data to new tree\r
+qboolean       do3ds;\r
+char           g_only[256];            // if set, only grab this cd\r
+qboolean       g_skipmodel;            // set true when a cd is not g_only\r
+\r
+char           *ext_3ds = "3ds";\r
+char           *ext_tri= "tri";\r
+char           *trifileext;\r
+\r
+char           game[64] = "quake2";\r
+\r
+void InitPaths( int *argc, char **argv );\r
+\r
+/*\r
+=======================================================\r
+\r
+  PAK FILES\r
+\r
+=======================================================\r
+*/\r
+\r
+typedef struct\r
+{\r
+       char    name[56];\r
+       int             filepos, filelen;\r
+} packfile_t;\r
+\r
+typedef struct\r
+{\r
+       char    id[4];\r
+       int             dirofs;\r
+       int             dirlen;\r
+} packheader_t;\r
+\r
+packfile_t             pfiles[16384];\r
+FILE                   *pakfile;\r
+packfile_t             *pf;\r
+packheader_t   pakheader;\r
+\r
+\r
+\r
+/*\r
+==============\r
+BeginPak\r
+==============\r
+*/\r
+void BeginPak (char *outname)\r
+{\r
+       if (!g_pak)\r
+               return;\r
+\r
+       pakfile = SafeOpenWrite (outname);\r
+\r
+       // leave space for header\r
+       SafeWrite (pakfile, &pakheader, sizeof(pakheader));\r
+       \r
+       pf = pfiles;\r
+}\r
+\r
+\r
+/*\r
+==============\r
+ReleaseFile\r
+\r
+Filename should be gamedir reletive.\r
+Either copies the file to the release dir, or adds it to\r
+the pak file.\r
+==============\r
+*/\r
+void ReleaseFile (char *filename)\r
+{\r
+       int             len;\r
+       byte    *buf;\r
+       char    source[1024];\r
+       char    dest[1024];\r
+\r
+       if (!g_release)\r
+               return;\r
+\r
+       sprintf (source, "%s%s", gamedir, filename);\r
+\r
+       if (!g_pak)\r
+       {       // copy it\r
+               sprintf (dest, "%s/%s", g_releasedir, filename);\r
+               printf ("copying to %s\n", dest);\r
+               QCopyFile (source, dest);\r
+               return;\r
+       }\r
+\r
+       // pak it\r
+       printf ("paking %s\n", filename);\r
+       if (strlen(filename) >= sizeof(pf->name))\r
+               Error ("Filename too long for pak: %s", filename);\r
+\r
+       len = LoadFile (source, (void **)&buf);\r
+\r
+       if (g_compress_pak && len < 4096*1024 )\r
+       {\r
+               cblock_t        in, out;\r
+               cblock_t Huffman (cblock_t in);\r
+\r
+               in.count = len;\r
+               in.data = buf;\r
+\r
+               out = Huffman (in);\r
+\r
+               if (out.count < in.count)\r
+               {\r
+                       printf ("   compressed from %i to %i\n", in.count, out.count);\r
+                       free (in.data);\r
+                       buf = out.data;\r
+                       len = out.count;\r
+               }\r
+               else\r
+                       free (out.data);\r
+       }\r
+\r
+       strcpy (pf->name, filename);\r
+       pf->filepos = LittleLong(ftell(pakfile));\r
+       pf->filelen = LittleLong(len);\r
+       pf++;\r
+\r
+       SafeWrite (pakfile, buf, len);\r
+\r
+       free (buf);\r
+}\r
+\r
+\r
+/*\r
+==============\r
+FinishPak\r
+==============\r
+*/\r
+void FinishPak (void)\r
+{\r
+       int             dirlen;\r
+       int             d;\r
+       int             i;\r
+\r
+       if (!g_pak)\r
+               return;\r
+\r
+       pakheader.id[0] = 'P';\r
+       pakheader.id[1] = 'A';\r
+       pakheader.id[2] = 'C';\r
+       pakheader.id[3] = 'K';\r
+       dirlen = (byte *)pf - (byte *)pfiles;\r
+       pakheader.dirofs = LittleLong(ftell(pakfile));\r
+       pakheader.dirlen = LittleLong(dirlen);\r
+       \r
+       SafeWrite (pakfile, pfiles, dirlen);\r
+\r
+       i = ftell (pakfile);\r
+        \r
+       fseek (pakfile, 0, SEEK_SET);\r
+       SafeWrite (pakfile, &pakheader, sizeof(pakheader));\r
+       fclose (pakfile);       \r
+       \r
+       d = pf - pfiles;\r
+       printf ("%i files packed in %i bytes\n",d, i);\r
+}\r
+\r
+\r
+/*\r
+===============\r
+Cmd_File\r
+\r
+This is only used to cause a file to be copied during a release\r
+build (default.cfg, maps, etc)\r
+===============\r
+*/\r
+void Cmd_File (void)\r
+{\r
+       GetToken (false);\r
+       ReleaseFile (token);\r
+}\r
+\r
+/*\r
+===============\r
+PackDirectory_r\r
+\r
+===============\r
+*/\r
+#ifdef _WIN32\r
+#include "io.h"\r
+void PackDirectory_r (char *dir)\r
+{\r
+       struct _finddata_t fileinfo;\r
+       int             handle;\r
+       char    dirstring[1024];\r
+       char    filename[1024];\r
+\r
+       sprintf (dirstring, "%s%s/*.*", gamedir, dir);\r
+\r
+       handle = _findfirst (dirstring, &fileinfo);\r
+       if (handle == -1)\r
+               return;\r
+\r
+       do\r
+       {\r
+               sprintf (filename, "%s/%s", dir, fileinfo.name);\r
+               if (fileinfo.attrib & _A_SUBDIR)\r
+               {       // directory\r
+                       if (fileinfo.name[0] != '.')    // don't pak . and ..\r
+                               PackDirectory_r (filename);\r
+                       continue;\r
+               }\r
+               // copy or pack the file\r
+               ReleaseFile (filename);         \r
+       } while (_findnext( handle, &fileinfo ) != -1);\r
+\r
+       _findclose (handle);\r
+}\r
+#else\r
+\r
+#include <sys/types.h>\r
+#include <sys/dir.h>\r
+\r
+void PackDirectory_r (char *dir)\r
+{\r
+#ifdef NeXT\r
+       struct direct **namelist, *ent;\r
+#else\r
+       struct dirent **namelist, *ent;\r
+#endif\r
+       int             count;\r
+       struct stat st;\r
+       int                     i;\r
+       int                     len;\r
+       char            fullname[1024];\r
+       char            dirstring[1024];\r
+       char            *name;\r
+       \r
+       sprintf (dirstring, "%s%s", gamedir, dir);\r
+       count = scandir(dirstring, &namelist, NULL, NULL);\r
+       \r
+       for (i=0 ; i<count ; i++)\r
+       {\r
+               ent = namelist[i];      \r
+               name = ent->d_name;\r
+\r
+               if (name[0] == '.')\r
+                       continue;\r
+       \r
+               sprintf (fullname, "%s/%s", dir, name);\r
+               sprintf (dirstring, "%s%s/%s", gamedir, dir, name);\r
+               \r
+               if (stat (dirstring, &st) == -1)\r
+                       Error ("fstating %s", pf->name);\r
+               if (st.st_mode & S_IFDIR)\r
+               {       // directory\r
+                       PackDirectory_r (fullname);\r
+                       continue;\r
+               }\r
+\r
+               // copy or pack the file\r
+               ReleaseFile (fullname);         \r
+       }\r
+}\r
+#endif\r
+\r
+\r
+/*\r
+===============\r
+Cmd_Dir\r
+\r
+This is only used to cause a directory to be copied during a\r
+release build (sounds, etc)\r
+===============\r
+*/\r
+void Cmd_Dir (void)\r
+{\r
+       GetToken (false);\r
+       PackDirectory_r (token);        \r
+}\r
+\r
+//========================================================================\r
+\r
+#define        MAX_RTEX        16384\r
+int            numrtex;\r
+char   rtex[MAX_RTEX][64];\r
+\r
+void ReleaseTexture (char *name)\r
+{\r
+       int             i;\r
+       char    path[1024];\r
+\r
+       for (i=0 ; i<numrtex ; i++)\r
+               if (!Q_strncasecmp(name, rtex[i], strlen(name)))\r
+                       return;\r
+\r
+       if (numrtex == MAX_RTEX)\r
+               Error ("numrtex == MAX_RTEX");\r
+\r
+       strcpy (rtex[i], name);\r
+       numrtex++;\r
+\r
+       sprintf (path, "textures/%s.wal", name);\r
+       ReleaseFile (path);\r
+}\r
+\r
+/*\r
+===============\r
+Cmd_Maps\r
+\r
+Only relevent for release and pak files.\r
+Releases the .bsp files for the maps, and scans all of the files to\r
+build a list of all textures used, which are then released.\r
+===============\r
+*/\r
+void Cmd_Maps (void)\r
+{\r
+       char    map[1024];\r
+       int             i;\r
+\r
+       while (TokenAvailable ())\r
+       {\r
+               GetToken (false);\r
+               sprintf (map, "maps/%s.bsp", token);\r
+               ReleaseFile (map);\r
+\r
+               if (!g_release)\r
+                       continue;\r
+\r
+               // get all the texture references\r
+               sprintf (map, "%smaps/%s.bsp", gamedir, token);\r
+               LoadBSPFileTexinfo (map);\r
+               for (i=0 ; i<numtexinfo ; i++)\r
+                       ReleaseTexture (texinfo[i].texture);\r
+       }\r
+}\r
+\r
+\r
+//==============================================================\r
+\r
+/*\r
+===============\r
+ParseScript\r
+===============\r
+*/\r
+void ParseScript (void)\r
+{\r
+       while (1)\r
+       {\r
+               do\r
+               {       // look for a line starting with a $ command\r
+                       GetToken (true);\r
+                       if (endofscript)\r
+                               return;\r
+                       if (token[0] == '$')\r
+                               break;                          \r
+                       while (TokenAvailable())\r
+                               GetToken (false);\r
+               } while (1);\r
+       \r
+               //\r
+               // model commands\r
+               //\r
+               if (!strcmp (token, "$modelname"))\r
+                       Cmd_Modelname ();\r
+               else if (!strcmp (token, "$base"))\r
+                       Cmd_Base ();\r
+               else if (!strcmp (token, "$cd"))\r
+                       Cmd_Cd ();\r
+               else if (!strcmp (token, "$origin"))\r
+                       Cmd_Origin ();\r
+               else if (!strcmp (token, "$scale"))\r
+                       Cmd_ScaleUp ();\r
+               else if (!strcmp (token, "$frame"))\r
+                       Cmd_Frame ();\r
+               else if (!strcmp (token, "$skin"))\r
+                       Cmd_Skin ();\r
+               else if (!strcmp (token, "$skinsize"))\r
+                       Cmd_Skinsize ();\r
+               //\r
+               // sprite commands\r
+               //\r
+               else if (!strcmp (token, "$spritename"))\r
+                       Cmd_SpriteName ();\r
+               else if (!strcmp (token, "$load"))\r
+                       Cmd_Load ();\r
+               else if (!strcmp (token, "$spriteframe"))\r
+                       Cmd_SpriteFrame ();\r
+               //\r
+               // image commands\r
+               //\r
+               else if (!strcmp (token, "$grab"))\r
+                       Cmd_Grab ();\r
+               else if (!strcmp (token, "$raw"))\r
+                       Cmd_Raw ();\r
+               else if (!strcmp (token, "$colormap"))\r
+                       Cmd_Colormap ();\r
+               else if (!strcmp (token, "$mippal"))\r
+                       Cmd_Mippal ();\r
+               else if (!strcmp (token, "$mipdir"))\r
+                       Cmd_Mipdir ();\r
+               else if (!strcmp (token, "$mip"))\r
+                       Cmd_Mip ();\r
+               else if (!strcmp (token, "$environment"))\r
+                       Cmd_Environment ();\r
+               //\r
+               // video\r
+               //\r
+               else if (!strcmp (token, "$video"))\r
+                       Cmd_Video ();\r
+               //\r
+               // misc\r
+               //\r
+               else if (!strcmp (token, "$file"))\r
+                       Cmd_File ();\r
+               else if (!strcmp (token, "$dir"))\r
+                       Cmd_Dir ();\r
+               else if (!strcmp (token, "$maps"))\r
+                       Cmd_Maps ();\r
+               else if (!strcmp (token, "$alphalight"))\r
+                       Cmd_Alphalight ();\r
+               else if (!strcmp (token, "$inverse16table" ))\r
+                       Cmd_Inverse16Table();\r
+               else\r
+                       Error ("bad command %s\n", token);\r
+       }\r
+}\r
+\r
+//=======================================================\r
+\r
+/*\r
+==============\r
+main\r
+==============\r
+*/\r
+int main (int argc, char **argv)\r
+{\r
+       static  int             i;              // VC4.2 compiler bug if auto...\r
+       char    path[1024];\r
+\r
+       ExpandWildcards (&argc, &argv);\r
+\r
+  InitPaths( &argc, argv );\r
+\r
+       for (i=1 ; i<argc ; i++)\r
+       {\r
+               if (!strcmp(argv[i], "-archive"))\r
+               {\r
+                       // -archive f:/quake2/release/dump_11_30\r
+                       archive = true;\r
+                       strcpy (archivedir, argv[i+1]);\r
+                       printf ("Archiving source to: %s\n", archivedir);\r
+                       i++;\r
+               }\r
+               else if (!strcmp(argv[i], "-release"))\r
+               {\r
+                       g_release = true;\r
+                       strcpy (g_releasedir, argv[i+1]);\r
+                       printf ("Copy output to: %s\n", g_releasedir);\r
+                       i++;\r
+               }\r
+               else if (!strcmp(argv[i], "-compress"))\r
+               {\r
+                       g_compress_pak = true;\r
+                       printf ("Compressing pakfile\n");\r
+               }\r
+               else if (!strcmp(argv[i], "-pak"))\r
+               {\r
+                       g_release = true;\r
+                       g_pak = true;\r
+                       printf ("Building pakfile: %s\n", argv[i+1]);\r
+                       BeginPak (argv[i+1]);\r
+                       i++;\r
+               }\r
+               else if (!strcmp(argv[i], "-only"))\r
+               {\r
+                       strcpy (g_only, argv[i+1]);\r
+                       printf ("Only grabbing %s\n", g_only);\r
+                       i++;\r
+               }\r
+               else if (!strcmp(argv[i], "-3ds"))\r
+               {\r
+                       do3ds = true;\r
+                       printf ("loading .3ds files\n");\r
+               }\r
+               else if (argv[i][0] == '-')\r
+                       Error ("Unknown option \"%s\"", argv[i]);\r
+               else\r
+                       break;\r
+       }\r
+\r
+       if (i >= argc)\r
+               Error ("usage: %s [-archive <directory>] [-release <directory>] [-only <model>] [-3ds] file.qgr", argv[ 0 ] );\r
+\r
+       if (do3ds)\r
+               trifileext = ext_3ds;\r
+       else\r
+               trifileext = ext_tri;\r
+\r
+       for ( ; i<argc ; i++)\r
+       {\r
+               printf ("--------------- %s ---------------\n", argv[i]);\r
+               // load the script\r
+               strcpy (path, argv[i]);\r
+               DefaultExtension (path, ".qdt");\r
+               SetQdirFromPath (path);\r
+               LoadScriptFile (ExpandArg(path));\r
+               \r
+               //\r
+               // parse it\r
+               //\r
+               ParseScript ();\r
+\r
+               // write out the last model\r
+               FinishModel ();\r
+               FinishSprite ();\r
+       }\r
+\r
+       if (g_pak)\r
+               FinishPak ();\r
+\r
+       return 0;\r
+}\r
+\r