home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1996 December / PCWKCD1296.iso / sharewar / quake106 / utils / qcc / qcc.c < prev    next >
C/C++ Source or Header  |  1996-09-12  |  16KB  |  809 lines

  1.  
  2. #include "qcc.h"
  3.  
  4. char        sourcedir[1024];
  5. char        destfile[1024];
  6.  
  7. float        pr_globals[MAX_REGS];
  8. int            numpr_globals;
  9.  
  10. char        strings[MAX_STRINGS];
  11. int            strofs;
  12.  
  13. dstatement_t    statements[MAX_STATEMENTS];
  14. int            numstatements;
  15. int            statement_linenums[MAX_STATEMENTS];
  16.  
  17. dfunction_t    functions[MAX_FUNCTIONS];
  18. int            numfunctions;
  19.  
  20. ddef_t        globals[MAX_GLOBALS];
  21. int            numglobaldefs;
  22.  
  23. ddef_t        fields[MAX_FIELDS];
  24. int            numfielddefs;
  25.  
  26. char        precache_sounds[MAX_SOUNDS][MAX_DATA_PATH];
  27. int            precache_sounds_block[MAX_SOUNDS];
  28. int            numsounds;
  29.  
  30. char        precache_models[MAX_MODELS][MAX_DATA_PATH];
  31. int            precache_models_block[MAX_SOUNDS];
  32. int            nummodels;
  33.  
  34. char        precache_files[MAX_FILES][MAX_DATA_PATH];
  35. int            precache_files_block[MAX_SOUNDS];
  36. int            numfiles;
  37.  
  38. /*
  39. ============
  40. WriteFiles
  41.  
  42.   Generates files.dat, which contains all of the
  43.   data files actually used by the game, to be
  44.   processed by qfiles.exe
  45. ============
  46. */
  47. void WriteFiles (void)
  48. {
  49.     FILE    *f;
  50.     int        i;
  51.     char    filename[1024];
  52.  
  53.     sprintf (filename, "%sfiles.dat", sourcedir);
  54.     f = fopen (filename, "w");
  55.     if (!f)
  56.         Error ("Couldn't open %s", filename);
  57.  
  58.     fprintf (f, "%i\n", numsounds);
  59.     for (i=0 ; i<numsounds ; i++)
  60.         fprintf (f, "%i %s\n", precache_sounds_block[i],
  61.             precache_sounds[i]);
  62.  
  63.     fprintf (f, "%i\n", nummodels);
  64.     for (i=0 ; i<nummodels ; i++)
  65.         fprintf (f, "%i %s\n", precache_models_block[i],
  66.             precache_models[i]);
  67.  
  68.     fprintf (f, "%i\n", numfiles);
  69.     for (i=0 ; i<numfiles ; i++)
  70.         fprintf (f, "%i %s\n", precache_files_block[i],
  71.             precache_files[i]);
  72.  
  73.     fclose (f);
  74. }
  75.  
  76.  
  77. // CopyString returns an offset from the string heap
  78. int    CopyString (char *str)
  79. {
  80.     int        old;
  81.     
  82.     old = strofs;
  83.     strcpy (strings+strofs, str);
  84.     strofs += strlen(str)+1;
  85.     return old;
  86. }
  87.  
  88. void PrintStrings (void)
  89. {
  90.     int        i, l, j;
  91.     
  92.     for (i=0 ; i<strofs ; i += l)
  93.     {
  94.         l = strlen(strings+i) + 1;
  95.         printf ("%5i : ",i);
  96.         for (j=0 ; j<l ; j++)
  97.         {
  98.             if (strings[i+j] == '\n')
  99.             {
  100.                 putchar ('\\');
  101.                 putchar ('n');
  102.             }
  103.             else
  104.                 putchar (strings[i+j]);
  105.         }
  106.         printf ("\n");
  107.     }
  108. }
  109.  
  110.  
  111. void PrintFunctions (void)
  112. {
  113.     int        i,j;
  114.     dfunction_t    *d;
  115.     
  116.     for (i=0 ; i<numfunctions ; i++)
  117.     {
  118.         d = &functions[i];
  119.         printf ("%s : %s : %i %i (", strings + d->s_file, strings + d->s_name, d->first_statement, d->parm_start);
  120.         for (j=0 ; j<d->numparms ; j++)
  121.             printf ("%i ",d->parm_size[j]);
  122.         printf (")\n");
  123.     }
  124. }
  125.  
  126. void PrintFields (void)
  127. {
  128.     int        i;
  129.     ddef_t    *d;
  130.     
  131.     for (i=0 ; i<numfielddefs ; i++)
  132.     {
  133.         d = &fields[i];
  134.         printf ("%5i : (%i) %s\n", d->ofs, d->type, strings + d->s_name);
  135.     }
  136. }
  137.  
  138. void PrintGlobals (void)
  139. {
  140.     int        i;
  141.     ddef_t    *d;
  142.     
  143.     for (i=0 ; i<numglobaldefs ; i++)
  144.     {
  145.         d = &globals[i];
  146.         printf ("%5i : (%i) %s\n", d->ofs, d->type, strings + d->s_name);
  147.     }
  148. }
  149.  
  150.  
  151. void InitData (void)
  152. {
  153.     int        i;
  154.     
  155.     numstatements = 1;
  156.     strofs = 1;
  157.     numfunctions = 1;
  158.     numglobaldefs = 1;
  159.     numfielddefs = 1;
  160.     
  161.     def_ret.ofs = OFS_RETURN;
  162.     for (i=0 ; i<MAX_PARMS ; i++)
  163.         def_parms[i].ofs = OFS_PARM0 + 3*i;
  164. }
  165.  
  166.  
  167. void WriteData (int crc)
  168. {
  169.     def_t        *def;
  170.     ddef_t        *dd;
  171.     dprograms_t    progs;
  172.     FILE        *h;
  173.     int            i;
  174.  
  175.     for (def = pr.def_head.next ; def ; def = def->next)
  176.     {
  177.         if (def->type->type == ev_function)
  178.         {
  179. //            df = &functions[numfunctions];
  180. //            numfunctions++;
  181.  
  182.         }
  183.         else if (def->type->type == ev_field)
  184.         {
  185.             dd = &fields[numfielddefs];
  186.             numfielddefs++;
  187.             dd->type = def->type->aux_type->type;
  188.             dd->s_name = CopyString (def->name);
  189.             dd->ofs = G_INT(def->ofs);
  190.         }
  191.         dd = &globals[numglobaldefs];
  192.         numglobaldefs++;
  193.         dd->type = def->type->type;
  194.         if ( !def->initialized
  195.         && def->type->type != ev_function
  196.         && def->type->type != ev_field
  197.         && def->scope == NULL)
  198.             dd->type |= DEF_SAVEGLOBGAL;
  199.         dd->s_name = CopyString (def->name);
  200.         dd->ofs = def->ofs;
  201.     }
  202.  
  203. //PrintStrings ();
  204. //PrintFunctions ();
  205. //PrintFields ();
  206. //PrintGlobals ();
  207. strofs = (strofs+3)&~3;
  208.  
  209.     printf ("%6i strofs\n", strofs);
  210.     printf ("%6i numstatements\n", numstatements);
  211.     printf ("%6i numfunctions\n", numfunctions);
  212.     printf ("%6i numglobaldefs\n", numglobaldefs);
  213.     printf ("%6i numfielddefs\n", numfielddefs);
  214.     printf ("%6i numpr_globals\n", numpr_globals);
  215.     
  216.     h = SafeOpenWrite (destfile);
  217.     SafeWrite (h, &progs, sizeof(progs));
  218.  
  219.     progs.ofs_strings = ftell (h);
  220.     progs.numstrings = strofs;
  221.     SafeWrite (h, strings, strofs);
  222.  
  223.     progs.ofs_statements = ftell (h);
  224.     progs.numstatements = numstatements;
  225.     for (i=0 ; i<numstatements ; i++)
  226.     {
  227.         statements[i].op = LittleShort(statements[i].op);
  228.         statements[i].a = LittleShort(statements[i].a);
  229.         statements[i].b = LittleShort(statements[i].b);
  230.         statements[i].c = LittleShort(statements[i].c);
  231.     }
  232.     SafeWrite (h, statements, numstatements*sizeof(dstatement_t));
  233.  
  234.     progs.ofs_functions = ftell (h);
  235.     progs.numfunctions = numfunctions;
  236.     for (i=0 ; i<numfunctions ; i++)
  237.     {
  238.     functions[i].first_statement = LittleLong (functions[i].first_statement);
  239.     functions[i].parm_start = LittleLong (functions[i].parm_start);
  240.     functions[i].s_name = LittleLong (functions[i].s_name);
  241.     functions[i].s_file = LittleLong (functions[i].s_file);
  242.     functions[i].numparms = LittleLong (functions[i].numparms);
  243.     functions[i].locals = LittleLong (functions[i].locals);
  244.     }    
  245.     SafeWrite (h, functions, numfunctions*sizeof(dfunction_t));
  246.  
  247.     progs.ofs_globaldefs = ftell (h);
  248.     progs.numglobaldefs = numglobaldefs;
  249.     for (i=0 ; i<numglobaldefs ; i++)
  250.     {
  251.         globals[i].type = LittleShort (globals[i].type);
  252.         globals[i].ofs = LittleShort (globals[i].ofs);
  253.         globals[i].s_name = LittleLong (globals[i].s_name);
  254.     }
  255.     SafeWrite (h, globals, numglobaldefs*sizeof(ddef_t));
  256.  
  257.     progs.ofs_fielddefs = ftell (h);
  258.     progs.numfielddefs = numfielddefs;
  259.     for (i=0 ; i<numfielddefs ; i++)
  260.     {
  261.         fields[i].type = LittleShort (fields[i].type);
  262.         fields[i].ofs = LittleShort (fields[i].ofs);
  263.         fields[i].s_name = LittleLong (fields[i].s_name);
  264.     }
  265.     SafeWrite (h, fields, numfielddefs*sizeof(ddef_t));
  266.  
  267.     progs.ofs_globals = ftell (h);
  268.     progs.numglobals = numpr_globals;
  269.     for (i=0 ; i<numpr_globals ; i++)
  270.         ((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]);
  271.     SafeWrite (h, pr_globals, numpr_globals*4);
  272.  
  273.     printf ("%6i TOTAL SIZE\n", (int)ftell (h));    
  274.  
  275.     progs.entityfields = pr.size_fields;
  276.  
  277.     progs.version = PROG_VERSION;
  278.     progs.crc = crc;
  279.     
  280. // byte swap the header and write it out
  281.     for (i=0 ; i<sizeof(progs)/4 ; i++)
  282.         ((int *)&progs)[i] = LittleLong ( ((int *)&progs)[i] );        
  283.     fseek (h, 0, SEEK_SET);
  284.     SafeWrite (h, &progs, sizeof(progs));
  285.     fclose (h);
  286.     
  287. }
  288.  
  289.  
  290.  
  291. /*
  292. ===============
  293. PR_String
  294.  
  295. Returns a string suitable for printing (no newlines, max 60 chars length)
  296. ===============
  297. */
  298. char *PR_String (char *string)
  299. {
  300.     static char buf[80];
  301.     char    *s;
  302.     
  303.     s = buf;
  304.     *s++ = '"';
  305.     while (string && *string)
  306.     {
  307.         if (s == buf + sizeof(buf) - 2)
  308.             break;
  309.         if (*string == '\n')
  310.         {
  311.             *s++ = '\\';
  312.             *s++ = 'n';
  313.         }
  314.         else if (*string == '"')
  315.         {
  316.             *s++ = '\\';
  317.             *s++ = '"';
  318.         }
  319.         else
  320.             *s++ = *string;
  321.         string++;
  322.         if (s - buf > 60)
  323.         {
  324.             *s++ = '.';
  325.             *s++ = '.';
  326.             *s++ = '.';
  327.             break;
  328.         }
  329.     }
  330.     *s++ = '"';
  331.     *s++ = 0;
  332.     return buf;
  333. }
  334.  
  335.  
  336.  
  337. def_t    *PR_DefForFieldOfs (gofs_t ofs)
  338. {
  339.     def_t    *d;
  340.     
  341.     for (d=pr.def_head.next ; d ; d=d->next)
  342.     {
  343.         if (d->type->type != ev_field)
  344.             continue;
  345.         if (*((int *)&pr_globals[d->ofs]) == ofs)
  346.             return d;
  347.     }
  348.     Error ("PR_DefForFieldOfs: couldn't find %i",ofs);
  349.     return NULL;
  350. }
  351.  
  352. /*
  353. ============
  354. PR_ValueString
  355.  
  356. Returns a string describing *data in a type specific manner
  357. =============
  358. */
  359. char *PR_ValueString (etype_t type, void *val)
  360. {
  361.     static char    line[256];
  362.     def_t        *def;
  363.     dfunction_t    *f;
  364.     
  365.     switch (type)
  366.     {
  367.     case ev_string:
  368.         sprintf (line, "%s", PR_String(strings + *(int *)val));
  369.         break;
  370.     case ev_entity:    
  371.         sprintf (line, "entity %i", *(int *)val);
  372.         break;
  373.     case ev_function:
  374.         f = functions + *(int *)val;
  375.         if (!f)
  376.             sprintf (line, "undefined function");
  377.         else
  378.             sprintf (line, "%s()", strings + f->s_name);
  379.         break;
  380.     case ev_field:
  381.         def = PR_DefForFieldOfs ( *(int *)val );
  382.         sprintf (line, ".%s", def->name);
  383.         break;
  384.     case ev_void:
  385.         sprintf (line, "void");
  386.         break;
  387.     case ev_float:
  388.         sprintf (line, "%5.1f", *(float *)val);
  389.         break;
  390.     case ev_vector:
  391.         sprintf (line, "'%5.1f %5.1f %5.1f'", ((float *)val)[0], ((float *)val)[1], ((float *)val)[2]);
  392.         break;
  393.     case ev_pointer:
  394.         sprintf (line, "pointer");
  395.         break;
  396.     default:
  397.         sprintf (line, "bad type %i", type);
  398.         break;
  399.     }
  400.     
  401.     return line;
  402. }
  403.  
  404. /*
  405. ============
  406. PR_GlobalString
  407.  
  408. Returns a string with a description and the contents of a global,
  409. padded to 20 field width
  410. ============
  411. */
  412. char *PR_GlobalStringNoContents (gofs_t ofs)
  413. {
  414.     int        i;
  415.     def_t    *def;
  416.     void    *val;
  417.     static char    line[128];
  418.     
  419.     val = (void *)&pr_globals[ofs];
  420.     def = pr_global_defs[ofs];
  421.     if (!def)
  422. //        Error ("PR_GlobalString: no def for %i", ofs);
  423.         sprintf (line,"%i(???)", ofs);
  424.     else
  425.         sprintf (line,"%i(%s)", ofs, def->name);
  426.     
  427.     i = strlen(line);
  428.     for ( ; i<16 ; i++)
  429.         strcat (line," ");
  430.     strcat (line," ");
  431.         
  432.     return line;
  433. }
  434.  
  435. char *PR_GlobalString (gofs_t ofs)
  436. {
  437.     char    *s;
  438.     int        i;
  439.     def_t    *def;
  440.     void    *val;
  441.     static char    line[128];
  442.     
  443.     val = (void *)&pr_globals[ofs];
  444.     def = pr_global_defs[ofs];
  445.     if (!def)
  446.         return PR_GlobalStringNoContents(ofs);
  447.     if (def->initialized && def->type->type != ev_function)
  448.     {
  449.         s = PR_ValueString (def->type->type, &pr_globals[ofs]);
  450.         sprintf (line,"%i(%s)", ofs, s);
  451.     }
  452.     else
  453.         sprintf (line,"%i(%s)", ofs, def->name);
  454.     
  455.     i = strlen(line);
  456.     for ( ; i<16 ; i++)
  457.         strcat (line," ");
  458.     strcat (line," ");
  459.         
  460.     return line;
  461. }
  462.  
  463. /*
  464. ============
  465. PR_PrintOfs
  466. ============
  467. */
  468. void PR_PrintOfs (gofs_t ofs)
  469. {
  470.     printf ("%s\n",PR_GlobalString(ofs));
  471. }
  472.  
  473. /*
  474. =================
  475. PR_PrintStatement
  476. =================
  477. */
  478. void PR_PrintStatement (dstatement_t *s)
  479. {
  480.     int        i;
  481.     
  482.     printf ("%4i : %4i : %s ", (int)(s - statements), statement_linenums[s-statements], pr_opcodes[s->op].opname);
  483.     i = strlen(pr_opcodes[s->op].opname);
  484.     for ( ; i<10 ; i++)
  485.         printf (" ");
  486.         
  487.     if (s->op == OP_IF || s->op == OP_IFNOT)
  488.         printf ("%sbranch %i",PR_GlobalString(s->a),s->b);
  489.     else if (s->op == OP_GOTO)
  490.     {
  491.         printf ("branch %i",s->a);
  492.     }
  493.     else if ( (unsigned)(s->op - OP_STORE_F) < 6)
  494.     {
  495.         printf ("%s",PR_GlobalString(s->a));
  496.         printf ("%s", PR_GlobalStringNoContents(s->b));
  497.     }
  498.     else
  499.     {
  500.         if (s->a)
  501.             printf ("%s",PR_GlobalString(s->a));
  502.         if (s->b)
  503.             printf ("%s",PR_GlobalString(s->b));
  504.         if (s->c)
  505.             printf ("%s", PR_GlobalStringNoContents(s->c));
  506.     }
  507.     printf ("\n");
  508. }
  509.  
  510.  
  511. /*
  512. ============
  513. PR_PrintDefs
  514. ============
  515. */
  516. void PR_PrintDefs (void)
  517. {
  518.     def_t    *d;
  519.     
  520.     for (d=pr.def_head.next ; d ; d=d->next)
  521.         PR_PrintOfs (d->ofs);
  522. }
  523.  
  524.  
  525. /*
  526. ==============
  527. PR_BeginCompilation
  528.  
  529. called before compiling a batch of files, clears the pr struct
  530. ==============
  531. */
  532. void    PR_BeginCompilation (void *memory, int memsize)
  533. {
  534.     int        i;
  535.     
  536.     pr.memory = memory;
  537.     pr.max_memory = memsize;
  538.     
  539.     numpr_globals = RESERVED_OFS;
  540.     pr.def_tail = &pr.def_head;
  541.     
  542.     for (i=0 ; i<RESERVED_OFS ; i++)
  543.         pr_global_defs[i] = &def_void;
  544.         
  545. // link the function type in so state forward declarations match proper type
  546.     pr.types = &type_function;
  547.     type_function.next = NULL;
  548.     pr_error_count = 0;
  549. }
  550.  
  551. /*
  552. ==============
  553. PR_FinishCompilation
  554.  
  555. called after all files are compiled to check for errors
  556. Returns false if errors were detected.
  557. ==============
  558. */
  559. qboolean    PR_FinishCompilation (void)
  560. {
  561.     def_t        *d;
  562.     qboolean    errors;
  563.     
  564.     errors = false;
  565.     
  566. // check to make sure all functions prototyped have code
  567.     for (d=pr.def_head.next ; d ; d=d->next)
  568.     {
  569.         if (d->type->type == ev_function && !d->scope)// function parms are ok
  570.         {
  571. //            f = G_FUNCTION(d->ofs);
  572. //            if (!f || (!f->code && !f->builtin) )
  573.             if (!d->initialized)
  574.             {
  575.                 printf ("function %s was not defined\n",d->name);
  576.                 errors = true;
  577.             }
  578.         }
  579.     }
  580.  
  581.     return !errors;
  582. }
  583.  
  584. //=============================================================================
  585.  
  586. /*
  587. ============
  588. PR_WriteProgdefs
  589.  
  590. Writes the global and entity structures out
  591. Returns a crc of the header, to be stored in the progs file for comparison
  592. at load time.
  593. ============
  594. */
  595. int    PR_WriteProgdefs (char *filename)
  596. {
  597.     def_t    *d;
  598.     FILE    *f;
  599.     unsigned short        crc;
  600.     int        c;
  601.     
  602.     printf ("writing %s\n", filename);
  603.     f = fopen (filename, "w");
  604.     
  605. // print global vars until the first field is defined
  606.     fprintf (f,"\n/* file generated by qcc, do not modify */\n\ntypedef struct\n{\tint\tpad[%i];\n", RESERVED_OFS);
  607.     for (d=pr.def_head.next ; d ; d=d->next)
  608.     {
  609.         if (!strcmp (d->name, "end_sys_globals"))
  610.             break;
  611.             
  612.         switch (d->type->type)
  613.         {
  614.         case ev_float:
  615.             fprintf (f, "\tfloat\t%s;\n",d->name);
  616.             break;
  617.         case ev_vector:
  618.             fprintf (f, "\tvec3_t\t%s;\n",d->name);
  619.             d=d->next->next->next;    // skip the elements
  620.             break;
  621.         case ev_string:
  622.             fprintf (f,"\tstring_t\t%s;\n",d->name);
  623.             break;
  624.         case ev_function:
  625.             fprintf (f,"\tfunc_t\t%s;\n",d->name);
  626.             break;
  627.         case ev_entity:
  628.             fprintf (f,"\tint\t%s;\n",d->name);
  629.             break;
  630.         default:
  631.             fprintf (f,"\tint\t%s;\n",d->name);
  632.             break;
  633.         }
  634.     }
  635.     fprintf (f,"} globalvars_t;\n\n");
  636.  
  637. // print all fields
  638.     fprintf (f,"typedef struct\n{\n");
  639.     for (d=pr.def_head.next ; d ; d=d->next)
  640.     {
  641.         if (!strcmp (d->name, "end_sys_fields"))
  642.             break;
  643.             
  644.         if (d->type->type != ev_field)
  645.             continue;
  646.             
  647.         switch (d->type->aux_type->type)
  648.         {
  649.         case ev_float:
  650.             fprintf (f,"\tfloat\t%s;\n",d->name);
  651.             break;
  652.         case ev_vector:
  653.             fprintf (f,"\tvec3_t\t%s;\n",d->name);
  654.             d=d->next->next->next;    // skip the elements
  655.             break;
  656.         case ev_string:
  657.             fprintf (f,"\tstring_t\t%s;\n",d->name);
  658.             break;
  659.         case ev_function:
  660.             fprintf (f,"\tfunc_t\t%s;\n",d->name);
  661.             break;
  662.         case ev_entity:
  663.             fprintf (f,"\tint\t%s;\n",d->name);
  664.             break;
  665.         default:
  666.             fprintf (f,"\tint\t%s;\n",d->name);
  667.             break;
  668.         }
  669.     }
  670.     fprintf (f,"} entvars_t;\n\n");
  671.     
  672.     fclose (f);
  673.     
  674. // do a crc of the file
  675.     CRC_Init (&crc);
  676.     f = fopen (filename, "r+");
  677.     while ((c = fgetc(f)) != EOF)
  678.         CRC_ProcessByte (&crc, (byte)c);
  679.         
  680.     fprintf (f,"#define PROGHEADER_CRC %i\n", crc);
  681.     fclose (f);
  682.  
  683.     return crc;
  684. }
  685.  
  686.  
  687. void PrintFunction (char *name)
  688. {
  689.     int        i;
  690.     dstatement_t    *ds;
  691.     dfunction_t        *df;
  692.     
  693.     for (i=0 ; i<numfunctions ; i++)
  694.         if (!strcmp (name, strings + functions[i].s_name))
  695.             break;
  696.     if (i==numfunctions)
  697.         Error ("No function names \"%s\"", name);
  698.     df = functions + i;    
  699.     
  700.     printf ("Statements for %s:\n", name);
  701.     ds = statements + df->first_statement;
  702.     while (1)
  703.     {
  704.         PR_PrintStatement (ds);
  705.         if (!ds->op)
  706.             break;
  707.         ds++;
  708.     }
  709. }
  710.  
  711.  
  712. //============================================================================
  713.  
  714. /*
  715. ============
  716. main
  717. ============
  718. */
  719. void main (int argc, char **argv)
  720. {
  721.     char    *src;
  722.     char    *src2;
  723.     char    filename[1024];
  724.     int        p, crc;
  725.     double    start, stop;
  726.  
  727.     start = I_FloatTime ();
  728.  
  729.     myargc = argc;
  730.     myargv = argv;
  731.     
  732.     if ( CheckParm ("-?") || CheckParm ("-help"))
  733.     {
  734.         printf ("qcc looks for progs.src in the current directory.\n");
  735.         printf ("to look in a different directory: qcc -src <directory>\n");
  736.         printf ("to build a clean data tree: qcc -copy <srcdir> <destdir>\n");
  737.         printf ("to build a clean pak file: qcc -pak <srcdir> <packfile>\n");
  738.         printf ("to bsp all bmodels: qcc -bspmodels <gamedir>\n");
  739.         return;
  740.     }
  741.     
  742.     p = CheckParm ("-src");
  743.     if (p && p < argc-1 )
  744.     {
  745.         strcpy (sourcedir, argv[p+1]);
  746.         strcat (sourcedir, "/");
  747.         printf ("Source directory: %s\n", sourcedir);
  748.     }
  749.     else
  750.         strcpy (sourcedir, "");
  751.  
  752.     InitData ();
  753.     
  754.     sprintf (filename, "%sprogs.src", sourcedir);
  755.     LoadFile (filename, (void *)&src);
  756.     
  757.     src = COM_Parse (src);
  758.     if (!src)
  759.         Error ("No destination filename.  qcc -help for info.\n");
  760.     strcpy (destfile, com_token);
  761.     printf ("outputfile: %s\n", destfile);
  762.     
  763.     pr_dumpasm = false;
  764.  
  765.     PR_BeginCompilation (malloc (0x100000), 0x100000);
  766.  
  767. // compile all the files
  768.     do
  769.     {
  770.         src = COM_Parse(src);
  771.         if (!src)
  772.             break;
  773.         sprintf (filename, "%s%s", sourcedir, com_token);
  774.         printf ("compiling %s\n", filename);
  775.         LoadFile (filename, (void *)&src2);
  776.  
  777.         if (!PR_CompileFile (src2, filename) )
  778.             exit (1);
  779.             
  780.     } while (1);
  781.     
  782.     if (!PR_FinishCompilation ())
  783.         Error ("compilation errors");
  784.  
  785.     p = CheckParm ("-asm");
  786.     if (p)
  787.     {
  788.         for (p++ ; p<argc ; p++)
  789.         {
  790.             if (argv[p][0] == '-')
  791.                 break;
  792.             PrintFunction (argv[p]);
  793.         }
  794.     }
  795.     
  796.     
  797. // write progdefs.h
  798.     crc = PR_WriteProgdefs ("progdefs.h");
  799.     
  800. // write data file
  801.     WriteData (crc);
  802.     
  803. // write files.dat
  804.     WriteFiles ();
  805.  
  806.     stop = I_FloatTime ();
  807.     printf ("%i seconds elapsed.\n", (int)(stop-start));
  808. }
  809.