qcc.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134
  1. /* Copyright (C) 1996-1997 Id Software, Inc.
  2. This program is free software; you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation; either version 2 of the License, or
  5. (at your option) any later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program; if not, write to the Free Software
  12. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  13. See file, 'COPYING', for details.
  14. */
  15. #include "qcc.h"
  16. char destfile[1024];
  17. float pr_globals[MAX_REGS];
  18. int numpr_globals;
  19. char strings[MAX_STRINGS];
  20. int strofs;
  21. dstatement_t statements[MAX_STATEMENTS];
  22. int numstatements;
  23. int statement_linenums[MAX_STATEMENTS];
  24. dfunction_t functions[MAX_FUNCTIONS];
  25. int numfunctions;
  26. ddef_t globals[MAX_GLOBALS];
  27. int numglobaldefs;
  28. ddef_t fields[MAX_FIELDS];
  29. int numfielddefs;
  30. char precache_sounds[MAX_SOUNDS][MAX_DATA_PATH];
  31. int precache_sounds_block[MAX_SOUNDS];
  32. int numsounds;
  33. char precache_models[MAX_MODELS][MAX_DATA_PATH];
  34. int precache_models_block[MAX_SOUNDS];
  35. int nummodels;
  36. char precache_files[MAX_FILES][MAX_DATA_PATH];
  37. int precache_files_block[MAX_SOUNDS];
  38. int numfiles;
  39. /*
  40. =================
  41. BspModels
  42. Runs qbsp and light on all of the models with a .bsp extension
  43. =================
  44. */
  45. void BspModels (void)
  46. {
  47. int p;
  48. char *gamedir;
  49. int i;
  50. char *m;
  51. char cmd[1024];
  52. char name[256];
  53. p = CheckParm ("-bspmodels");
  54. if (!p)
  55. return;
  56. if (p == myargc-1)
  57. Error ("-bspmodels must preceed a game directory");
  58. gamedir = myargv[p+1];
  59. for (i=0 ; i<nummodels ; i++)
  60. {
  61. m = precache_models[i];
  62. if (strcmp(m+strlen(m)-4, ".bsp"))
  63. continue;
  64. strcpy (name, m);
  65. name[strlen(m)-4] = 0;
  66. sprintf (cmd, "qbsp %s/%s ; light -extra %s/%s", gamedir, name, gamedir, name);
  67. system (cmd);
  68. }
  69. }
  70. // CopyString returns an offset from the string heap
  71. int CopyString (char *str)
  72. {
  73. int old;
  74. old = strofs;
  75. strcpy (strings+strofs, str);
  76. strofs += strlen(str)+1;
  77. return old;
  78. }
  79. void PrintStrings (void)
  80. {
  81. int i, l, j;
  82. for (i=0 ; i<strofs ; i += l)
  83. {
  84. l = strlen(strings+i) + 1;
  85. printf ("%5i : ",i);
  86. for (j=0 ; j<l ; j++)
  87. {
  88. if (strings[i+j] == '\n')
  89. {
  90. putchar ('\\');
  91. putchar ('n');
  92. }
  93. else
  94. putchar (strings[i+j]);
  95. }
  96. printf ("\n");
  97. }
  98. }
  99. void PrintFunctions (void)
  100. {
  101. int i,j;
  102. dfunction_t *d;
  103. for (i=0 ; i<numfunctions ; i++)
  104. {
  105. d = &functions[i];
  106. printf ("%s : %s : %i %i (", strings + d->s_file, strings + d->s_name, d->first_statement, d->parm_start);
  107. for (j=0 ; j<d->numparms ; j++)
  108. printf ("%i ",d->parm_size[j]);
  109. printf (")\n");
  110. }
  111. }
  112. void PrintFields (void)
  113. {
  114. int i;
  115. ddef_t *d;
  116. for (i=0 ; i<numfielddefs ; i++)
  117. {
  118. d = &fields[i];
  119. printf ("%5i : (%i) %s\n", d->ofs, d->type, strings + d->s_name);
  120. }
  121. }
  122. void PrintGlobals (void)
  123. {
  124. int i;
  125. ddef_t *d;
  126. for (i=0 ; i<numglobaldefs ; i++)
  127. {
  128. d = &globals[i];
  129. printf ("%5i : (%i) %s\n", d->ofs, d->type, strings + d->s_name);
  130. }
  131. }
  132. void InitData (void)
  133. {
  134. int i;
  135. numstatements = 1;
  136. strofs = 1;
  137. numfunctions = 1;
  138. numglobaldefs = 1;
  139. numfielddefs = 1;
  140. def_ret.ofs = OFS_RETURN;
  141. for (i=0 ; i<MAX_PARMS ; i++)
  142. def_parms[i].ofs = OFS_PARM0 + 3*i;
  143. }
  144. void WriteData (int crc)
  145. {
  146. def_t *def;
  147. ddef_t *dd;
  148. dprograms_t progs;
  149. int h;
  150. int i;
  151. for (def = pr.def_head.next ; def ; def = def->next)
  152. {
  153. if (def->type->type == ev_function)
  154. {
  155. // df = &functions[numfunctions];
  156. // numfunctions++;
  157. }
  158. else if (def->type->type == ev_field)
  159. {
  160. dd = &fields[numfielddefs];
  161. numfielddefs++;
  162. dd->type = def->type->aux_type->type;
  163. dd->s_name = CopyString (def->name);
  164. dd->ofs = G_INT(def->ofs);
  165. }
  166. dd = &globals[numglobaldefs];
  167. numglobaldefs++;
  168. dd->type = def->type->type;
  169. if ( !def->initialized
  170. && def->type->type != ev_function
  171. && def->type->type != ev_field
  172. && def->scope == NULL)
  173. dd->type |= DEF_SAVEGLOBGAL;
  174. dd->s_name = CopyString (def->name);
  175. dd->ofs = def->ofs;
  176. }
  177. //PrintStrings ();
  178. //PrintFunctions ();
  179. //PrintFields ();
  180. //PrintGlobals ();
  181. strofs = (strofs+3)&~3;
  182. printf ("%6i strofs\n", strofs);
  183. printf ("%6i numstatements\n", numstatements);
  184. printf ("%6i numfunctions\n", numfunctions);
  185. printf ("%6i numglobaldefs\n", numglobaldefs);
  186. printf ("%6i numfielddefs\n", numfielddefs);
  187. printf ("%6i numpr_globals\n", numpr_globals);
  188. h = SafeOpenWrite (destfile);
  189. SafeWrite (h, &progs, sizeof(progs));
  190. progs.ofs_strings = lseek (h, 0, SEEK_CUR);
  191. progs.numstrings = strofs;
  192. SafeWrite (h, strings, strofs);
  193. progs.ofs_statements = lseek (h, 0, SEEK_CUR);
  194. progs.numstatements = numstatements;
  195. for (i=0 ; i<numstatements ; i++)
  196. {
  197. statements[i].op = LittleShort(statements[i].op);
  198. statements[i].a = LittleShort(statements[i].a);
  199. statements[i].b = LittleShort(statements[i].b);
  200. statements[i].c = LittleShort(statements[i].c);
  201. }
  202. SafeWrite (h, statements, numstatements*sizeof(dstatement_t));
  203. progs.ofs_functions = lseek (h, 0, SEEK_CUR);
  204. progs.numfunctions = numfunctions;
  205. for (i=0 ; i<numfunctions ; i++)
  206. {
  207. functions[i].first_statement = LittleLong (functions[i].first_statement);
  208. functions[i].parm_start = LittleLong (functions[i].parm_start);
  209. functions[i].s_name = LittleLong (functions[i].s_name);
  210. functions[i].s_file = LittleLong (functions[i].s_file);
  211. functions[i].numparms = LittleLong (functions[i].numparms);
  212. functions[i].locals = LittleLong (functions[i].locals);
  213. }
  214. SafeWrite (h, functions, numfunctions*sizeof(dfunction_t));
  215. progs.ofs_globaldefs = lseek (h, 0, SEEK_CUR);
  216. progs.numglobaldefs = numglobaldefs;
  217. for (i=0 ; i<numglobaldefs ; i++)
  218. {
  219. globals[i].type = LittleShort (globals[i].type);
  220. globals[i].ofs = LittleShort (globals[i].ofs);
  221. globals[i].s_name = LittleLong (globals[i].s_name);
  222. }
  223. SafeWrite (h, globals, numglobaldefs*sizeof(ddef_t));
  224. progs.ofs_fielddefs = lseek (h, 0, SEEK_CUR);
  225. progs.numfielddefs = numfielddefs;
  226. for (i=0 ; i<numfielddefs ; i++)
  227. {
  228. fields[i].type = LittleShort (fields[i].type);
  229. fields[i].ofs = LittleShort (fields[i].ofs);
  230. fields[i].s_name = LittleLong (fields[i].s_name);
  231. }
  232. SafeWrite (h, fields, numfielddefs*sizeof(ddef_t));
  233. progs.ofs_globals = lseek (h, 0, SEEK_CUR);
  234. progs.numglobals = numpr_globals;
  235. for (i=0 ; i<numpr_globals ; i++)
  236. ((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]);
  237. SafeWrite (h, pr_globals, numpr_globals*4);
  238. printf ("%6i TOTAL SIZE\n", (int)lseek (h, 0, SEEK_CUR));
  239. progs.entityfields = pr.size_fields;
  240. progs.version = PROG_VERSION;
  241. progs.crc = crc;
  242. // byte swap the header and write it out
  243. for (i=0 ; i<sizeof(progs)/4 ; i++)
  244. ((int *)&progs)[i] = LittleLong ( ((int *)&progs)[i] );
  245. lseek (h, 0, SEEK_SET);
  246. SafeWrite (h, &progs, sizeof(progs));
  247. close (h);
  248. }
  249. /*
  250. ===============
  251. PR_String
  252. Returns a string suitable for printing (no newlines, max 60 chars length)
  253. ===============
  254. */
  255. char *PR_String (char *string)
  256. {
  257. static char buf[80];
  258. char *s;
  259. s = buf;
  260. *s++ = '"';
  261. while (string && *string)
  262. {
  263. if (s == buf + sizeof(buf) - 2)
  264. break;
  265. if (*string == '\n')
  266. {
  267. *s++ = '\\';
  268. *s++ = 'n';
  269. }
  270. else if (*string == '"')
  271. {
  272. *s++ = '\\';
  273. *s++ = '"';
  274. }
  275. else
  276. *s++ = *string;
  277. string++;
  278. if (s - buf > 60)
  279. {
  280. *s++ = '.';
  281. *s++ = '.';
  282. *s++ = '.';
  283. break;
  284. }
  285. }
  286. *s++ = '"';
  287. *s++ = 0;
  288. return buf;
  289. }
  290. def_t *PR_DefForFieldOfs (gofs_t ofs)
  291. {
  292. def_t *d;
  293. for (d=pr.def_head.next ; d ; d=d->next)
  294. {
  295. if (d->type->type != ev_field)
  296. continue;
  297. if (*((int *)&pr_globals[d->ofs]) == ofs)
  298. return d;
  299. }
  300. Error ("PR_DefForFieldOfs: couldn't find %i",ofs);
  301. return NULL;
  302. }
  303. /*
  304. ============
  305. PR_ValueString
  306. Returns a string describing *data in a type specific manner
  307. =============
  308. */
  309. char *PR_ValueString (etype_t type, void *val)
  310. {
  311. static char line[256];
  312. def_t *def;
  313. dfunction_t *f;
  314. switch (type)
  315. {
  316. case ev_string:
  317. sprintf (line, "%s", PR_String(strings + *(int *)val));
  318. break;
  319. case ev_entity:
  320. sprintf (line, "entity %i", *(int *)val);
  321. break;
  322. case ev_function:
  323. f = functions + *(int *)val;
  324. if (!f)
  325. sprintf (line, "undefined function");
  326. else
  327. sprintf (line, "%s()", strings + f->s_name);
  328. break;
  329. case ev_field:
  330. def = PR_DefForFieldOfs ( *(int *)val );
  331. sprintf (line, ".%s", def->name);
  332. break;
  333. case ev_void:
  334. sprintf (line, "void");
  335. break;
  336. case ev_float:
  337. sprintf (line, "%5.1f", *(float *)val);
  338. break;
  339. case ev_vector:
  340. sprintf (line, "'%5.1f %5.1f %5.1f'", ((float *)val)[0], ((float *)val)[1], ((float *)val)[2]);
  341. break;
  342. case ev_pointer:
  343. sprintf (line, "pointer");
  344. break;
  345. default:
  346. sprintf (line, "bad type %i", type);
  347. break;
  348. }
  349. return line;
  350. }
  351. /*
  352. ============
  353. PR_GlobalString
  354. Returns a string with a description and the contents of a global,
  355. padded to 20 field width
  356. ============
  357. */
  358. char *PR_GlobalStringNoContents (gofs_t ofs)
  359. {
  360. int i;
  361. def_t *def;
  362. void *val;
  363. static char line[128];
  364. val = (void *)&pr_globals[ofs];
  365. def = pr_global_defs[ofs];
  366. if (!def)
  367. // Error ("PR_GlobalString: no def for %i", ofs);
  368. sprintf (line,"%i(???)", ofs);
  369. else
  370. sprintf (line,"%i(%s)", ofs, def->name);
  371. i = strlen(line);
  372. for ( ; i<16 ; i++)
  373. strcat (line," ");
  374. strcat (line," ");
  375. return line;
  376. }
  377. char *PR_GlobalString (gofs_t ofs)
  378. {
  379. char *s;
  380. int i;
  381. def_t *def;
  382. void *val;
  383. static char line[128];
  384. val = (void *)&pr_globals[ofs];
  385. def = pr_global_defs[ofs];
  386. if (!def)
  387. return PR_GlobalStringNoContents(ofs);
  388. if (def->initialized && def->type->type != ev_function)
  389. {
  390. s = PR_ValueString (def->type->type, &pr_globals[ofs]);
  391. sprintf (line,"%i(%s)", ofs, s);
  392. }
  393. else
  394. sprintf (line,"%i(%s)", ofs, def->name);
  395. i = strlen(line);
  396. for ( ; i<16 ; i++)
  397. strcat (line," ");
  398. strcat (line," ");
  399. return line;
  400. }
  401. /*
  402. ============
  403. PR_PrintOfs
  404. ============
  405. */
  406. void PR_PrintOfs (gofs_t ofs)
  407. {
  408. printf ("%s\n",PR_GlobalString(ofs));
  409. }
  410. /*
  411. =================
  412. PR_PrintStatement
  413. =================
  414. */
  415. void PR_PrintStatement (dstatement_t *s)
  416. {
  417. int i;
  418. printf ("%4i : %4i : %s ", (int)(s - statements), statement_linenums[s-statements], pr_opcodes[s->op].opname);
  419. i = strlen(pr_opcodes[s->op].opname);
  420. for ( ; i<10 ; i++)
  421. printf (" ");
  422. if (s->op == OP_IF || s->op == OP_IFNOT)
  423. printf ("%sbranch %i",PR_GlobalString(s->a),s->b);
  424. else if (s->op == OP_GOTO)
  425. {
  426. printf ("branch %i",s->a);
  427. }
  428. else if ( (unsigned)(s->op - OP_STORE_F) < 6)
  429. {
  430. printf ("%s",PR_GlobalString(s->a));
  431. printf ("%s", PR_GlobalStringNoContents(s->b));
  432. }
  433. else
  434. {
  435. if (s->a)
  436. printf ("%s",PR_GlobalString(s->a));
  437. if (s->b)
  438. printf ("%s",PR_GlobalString(s->b));
  439. if (s->c)
  440. printf ("%s", PR_GlobalStringNoContents(s->c));
  441. }
  442. printf ("\n");
  443. }
  444. /*
  445. ============
  446. PR_PrintDefs
  447. ============
  448. */
  449. void PR_PrintDefs (void)
  450. {
  451. def_t *d;
  452. for (d=pr.def_head.next ; d ; d=d->next)
  453. PR_PrintOfs (d->ofs);
  454. }
  455. /*
  456. ==============
  457. PR_BeginCompilation
  458. called before compiling a batch of files, clears the pr struct
  459. ==============
  460. */
  461. void PR_BeginCompilation (void *memory, int memsize)
  462. {
  463. int i;
  464. pr.memory = memory;
  465. pr.max_memory = memsize;
  466. numpr_globals = RESERVED_OFS;
  467. pr.def_tail = &pr.def_head;
  468. for (i=0 ; i<RESERVED_OFS ; i++)
  469. pr_global_defs[i] = &def_void;
  470. // link the function type in so state forward declarations match proper type
  471. pr.types = &type_function;
  472. type_function.next = NULL;
  473. pr_error_count = 0;
  474. }
  475. /*
  476. ==============
  477. PR_FinishCompilation
  478. called after all files are compiled to check for errors
  479. Returns false if errors were detected.
  480. ==============
  481. */
  482. boolean PR_FinishCompilation (void)
  483. {
  484. def_t *d;
  485. boolean errors;
  486. errors = false;
  487. // check to make sure all functions prototyped have code
  488. for (d=pr.def_head.next ; d ; d=d->next)
  489. {
  490. if (d->type->type == ev_function && !d->scope)// function parms are ok
  491. {
  492. // f = G_FUNCTION(d->ofs);
  493. // if (!f || (!f->code && !f->builtin) )
  494. if (!d->initialized)
  495. {
  496. printf ("function %s was not defined\n",d->name);
  497. errors = true;
  498. }
  499. }
  500. }
  501. return !errors;
  502. }
  503. //=============================================================================
  504. // FIXME: byte swap?
  505. // this is a 16 bit, non-reflected CRC using the polynomial 0x1021
  506. // and the initial and final xor values shown below... in other words, the
  507. // CCITT standard CRC used by XMODEM
  508. #define CRC_INIT_VALUE 0xffff
  509. #define CRC_XOR_VALUE 0x0000
  510. static unsigned short crctable[256] =
  511. {
  512. 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
  513. 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
  514. 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
  515. 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
  516. 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
  517. 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
  518. 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
  519. 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
  520. 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
  521. 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
  522. 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
  523. 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
  524. 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
  525. 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
  526. 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
  527. 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
  528. 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
  529. 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
  530. 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
  531. 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
  532. 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
  533. 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
  534. 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
  535. 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
  536. 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
  537. 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
  538. 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
  539. 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
  540. 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
  541. 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
  542. 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
  543. 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
  544. };
  545. void CRC_Init(unsigned short *crcvalue)
  546. {
  547. *crcvalue = CRC_INIT_VALUE;
  548. }
  549. void CRC_ProcessByte(unsigned short *crcvalue, byte data)
  550. {
  551. *crcvalue = (*crcvalue << 8) ^ crctable[(*crcvalue >> 8) ^ data];
  552. }
  553. unsigned short CRC_Value(unsigned short crcvalue)
  554. {
  555. return crcvalue ^ CRC_XOR_VALUE;
  556. }
  557. //=============================================================================
  558. /*
  559. ============
  560. PR_WriteProgdefs
  561. Writes the global and entity structures out
  562. Returns a crc of the header, to be stored in the progs file for comparison
  563. at load time.
  564. ============
  565. */
  566. int PR_WriteProgdefs (char *filename)
  567. {
  568. def_t *d;
  569. FILE *f;
  570. unsigned short crc;
  571. int c;
  572. printf ("writing %s\n", filename);
  573. f = fopen (filename, "w");
  574. // print global vars until the first field is defined
  575. fprintf (f,"\n/* file generated by qcc, do not modify */\n\ntypedef struct\n{\tint\tpad[%i];\n", RESERVED_OFS);
  576. for (d=pr.def_head.next ; d ; d=d->next)
  577. {
  578. if (!strcmp (d->name, "end_sys_globals"))
  579. break;
  580. switch (d->type->type)
  581. {
  582. case ev_float:
  583. fprintf (f, "\tfloat\t%s;\n",d->name);
  584. break;
  585. case ev_vector:
  586. fprintf (f, "\tvec3_t\t%s;\n",d->name);
  587. d=d->next->next->next; // skip the elements
  588. break;
  589. case ev_string:
  590. fprintf (f,"\tstring_t\t%s;\n",d->name);
  591. break;
  592. case ev_function:
  593. fprintf (f,"\tfunc_t\t%s;\n",d->name);
  594. break;
  595. case ev_entity:
  596. fprintf (f,"\tint\t%s;\n",d->name);
  597. break;
  598. default:
  599. fprintf (f,"\tint\t%s;\n",d->name);
  600. break;
  601. }
  602. }
  603. fprintf (f,"} globalvars_t;\n\n");
  604. // print all fields
  605. fprintf (f,"typedef struct\n{\n");
  606. for (d=pr.def_head.next ; d ; d=d->next)
  607. {
  608. if (!strcmp (d->name, "end_sys_fields"))
  609. break;
  610. if (d->type->type != ev_field)
  611. continue;
  612. switch (d->type->aux_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,"} entvars_t;\n\n");
  636. fclose (f);
  637. // do a crc of the file
  638. CRC_Init (&crc);
  639. f = fopen (filename, "r+");
  640. while ((c = fgetc(f)) != EOF)
  641. CRC_ProcessByte (&crc, c);
  642. fprintf (f,"#define PROGHEADER_CRC %i\n", crc);
  643. fclose (f);
  644. return crc;
  645. }
  646. void PrintFunction (char *name)
  647. {
  648. int i;
  649. dstatement_t *ds;
  650. dfunction_t *df;
  651. for (i=0 ; i<numfunctions ; i++)
  652. if (!strcmp (name, strings + functions[i].s_name))
  653. break;
  654. if (i==numfunctions)
  655. Error ("No function names \"%s\"", name);
  656. df = functions + i;
  657. printf ("Statements for %s:\n", name);
  658. ds = statements + df->first_statement;
  659. while (1)
  660. {
  661. PR_PrintStatement (ds);
  662. if (!ds->op)
  663. break;
  664. ds++;
  665. }
  666. }
  667. /*
  668. ==============================================================================
  669. DIRECTORY COPYING / PACKFILE CREATION
  670. ==============================================================================
  671. */
  672. typedef struct
  673. {
  674. char name[56];
  675. int filepos, filelen;
  676. } packfile_t;
  677. typedef struct
  678. {
  679. char id[4];
  680. int dirofs;
  681. int dirlen;
  682. } packheader_t;
  683. packfile_t pfiles[4096], *pf;
  684. int packhandle;
  685. int packbytes;
  686. void Sys_mkdir (char *path)
  687. {
  688. if (mkdir (path, 0777) != -1)
  689. return;
  690. if (errno != EEXIST)
  691. Error ("mkdir %s: %s",path, strerror(errno));
  692. }
  693. /*
  694. ============
  695. CreatePath
  696. ============
  697. */
  698. void CreatePath (char *path)
  699. {
  700. char *ofs;
  701. for (ofs = path+1 ; *ofs ; ofs++)
  702. {
  703. if (*ofs == '/')
  704. { // create the directory
  705. *ofs = 0;
  706. Sys_mkdir (path);
  707. *ofs = '/';
  708. }
  709. }
  710. }
  711. /*
  712. ===========
  713. PackFile
  714. Copy a file into the pak file
  715. ===========
  716. */
  717. void PackFile (char *src, char *name)
  718. {
  719. int in;
  720. int remaining, count;
  721. char buf[4096];
  722. if ( (byte *)pf - (byte *)pfiles > sizeof(pfiles) )
  723. Error ("Too many files in pak file");
  724. in = SafeOpenRead (src);
  725. remaining = filelength (in);
  726. pf->filepos = LittleLong (lseek (packhandle, 0, SEEK_CUR));
  727. pf->filelen = LittleLong (remaining);
  728. strcpy (pf->name, name);
  729. printf ("%64s : %7i\n", pf->name, remaining);
  730. packbytes += remaining;
  731. while (remaining)
  732. {
  733. if (remaining < sizeof(buf))
  734. count = remaining;
  735. else
  736. count = sizeof(buf);
  737. SafeRead (in, buf, count);
  738. SafeWrite (packhandle, buf, count);
  739. remaining -= count;
  740. }
  741. close (in);
  742. pf++;
  743. }
  744. /*
  745. ===========
  746. CopyFile
  747. Copies a file, creating any directories needed
  748. ===========
  749. */
  750. void CopyFile (char *src, char *dest)
  751. {
  752. int in, out;
  753. int remaining, count;
  754. char buf[4096];
  755. printf ("%s to %s\n", src, dest);
  756. in = SafeOpenRead (src);
  757. remaining = filelength (in);
  758. CreatePath (dest);
  759. out = SafeOpenWrite (dest);
  760. while (remaining)
  761. {
  762. if (remaining < sizeof(buf))
  763. count = remaining;
  764. else
  765. count = sizeof(buf);
  766. SafeRead (in, buf, count);
  767. SafeWrite (out, buf, count);
  768. remaining -= count;
  769. }
  770. close (in);
  771. close (out);
  772. }
  773. /*
  774. ===========
  775. CopyFiles
  776. ===========
  777. */
  778. void CopyFiles (void)
  779. {
  780. int i, p;
  781. char srcdir[1024], destdir[1024];
  782. char srcfile[1024], destfile[1024];
  783. int copytype;
  784. char name[1024];
  785. packheader_t header;
  786. int dirlen;
  787. int blocknum;
  788. unsigned short crc;
  789. printf ("%3i unique precache_sounds\n", numsounds);
  790. printf ("%3i unique precache_models\n", nummodels);
  791. copytype = 0;
  792. p = CheckParm ("-copy");
  793. if (p && p < myargc-2)
  794. { // create a new directory tree
  795. copytype = 1;
  796. strcpy (srcdir, myargv[p+1]);
  797. strcpy (destdir, myargv[p+2]);
  798. if (srcdir[strlen(srcdir)-1] != '/')
  799. strcat (srcdir, "/");
  800. if (destdir[strlen(destdir)-1] != '/')
  801. strcat (destdir, "/");
  802. }
  803. blocknum = 1;
  804. p = CheckParm ("-pak2");
  805. if (p && p <myargc-2)
  806. blocknum = 2;
  807. else
  808. p = CheckParm ("-pak");
  809. if (p && p < myargc-2)
  810. { // create a pak file
  811. strcpy (srcdir, myargv[p+1]);
  812. strcpy (destdir, myargv[p+2]);
  813. if (srcdir[strlen(srcdir)-1] != '/')
  814. strcat (srcdir, "/");
  815. DefaultExtension (destdir, ".pak");
  816. pf = pfiles;
  817. packhandle = SafeOpenWrite (destdir);
  818. SafeWrite (packhandle, &header, sizeof(header));
  819. copytype = 2;
  820. }
  821. if (!copytype)
  822. return;
  823. for (i=0 ; i<numsounds ; i++)
  824. {
  825. if (precache_sounds_block[i] != blocknum)
  826. continue;
  827. sprintf (name, "sound/%s", precache_sounds[i]);
  828. sprintf (srcfile,"%s%s",srcdir, name);
  829. sprintf (destfile,"%s%s",destdir, name);
  830. if (copytype == 1)
  831. CopyFile (srcfile, destfile);
  832. else
  833. PackFile (srcfile, name);
  834. }
  835. for (i=0 ; i<nummodels ; i++)
  836. {
  837. if (precache_models_block[i] != blocknum)
  838. continue;
  839. sprintf (srcfile,"%s%s",srcdir, precache_models[i]);
  840. sprintf (destfile,"%s%s",destdir, precache_models[i]);
  841. if (copytype == 1)
  842. CopyFile (srcfile, destfile);
  843. else
  844. PackFile (srcfile, precache_models[i]);
  845. }
  846. for (i=0 ; i<numfiles ; i++)
  847. {
  848. if (precache_files_block[i] != blocknum)
  849. continue;
  850. sprintf (srcfile,"%s%s",srcdir, precache_files[i]);
  851. sprintf (destfile,"%s%s",destdir, precache_files[i]);
  852. if (copytype == 1)
  853. CopyFile (srcfile, destfile);
  854. else
  855. PackFile (srcfile, precache_files[i]);
  856. }
  857. if (copytype == 2)
  858. {
  859. header.id[0] = 'P';
  860. header.id[1] = 'A';
  861. header.id[2] = 'C';
  862. header.id[3] = 'K';
  863. dirlen = (byte *)pf - (byte *)pfiles;
  864. header.dirofs = LittleLong(lseek (packhandle, 0, SEEK_CUR));
  865. header.dirlen = LittleLong(dirlen);
  866. SafeWrite (packhandle, pfiles, dirlen);
  867. lseek (packhandle, 0, SEEK_SET);
  868. SafeWrite (packhandle, &header, sizeof(header));
  869. close (packhandle);
  870. // do a crc of the file
  871. CRC_Init (&crc);
  872. for (i=0 ; i<dirlen ; i++)
  873. CRC_ProcessByte (&crc, ((byte *)pfiles)[i]);
  874. i = pf - pfiles;
  875. printf ("%i files packed in %i bytes (%i crc)\n",i, packbytes, crc);
  876. }
  877. }
  878. //============================================================================
  879. /*
  880. ============
  881. main
  882. ============
  883. */
  884. void main (int argc, char **argv)
  885. {
  886. char *src;
  887. char *src2;
  888. char filename[1024];
  889. int p, crc;
  890. char sourcedir[1024];
  891. myargc = argc;
  892. myargv = argv;
  893. if ( CheckParm ("-?") || CheckParm ("-help"))
  894. {
  895. printf ("qcc looks for progs.src in the current directory.\n");
  896. printf ("to look in a different directory: qcc -src <directory>\n");
  897. printf ("to build a clean data tree: qcc -copy <srcdir> <destdir>\n");
  898. printf ("to build a clean pak file: qcc -pak <srcdir> <packfile>\n");
  899. printf ("to bsp all bmodels: qcc -bspmodels <gamedir>\n");
  900. return;
  901. }
  902. p = CheckParm ("-src");
  903. if (p && p < argc-1 )
  904. {
  905. strcpy (sourcedir, argv[p+1]);
  906. strcat (sourcedir, "/");
  907. printf ("Source directory: %s\n", sourcedir);
  908. }
  909. else
  910. strcpy (sourcedir, "");
  911. InitData ();
  912. sprintf (filename, "%sprogs.src", sourcedir);
  913. LoadFile (filename, (void *)&src);
  914. src = COM_Parse (src);
  915. if (!src)
  916. Error ("No destination filename. qcc -help for info.\n");
  917. strcpy (destfile, com_token);
  918. printf ("outputfile: %s\n", destfile);
  919. pr_dumpasm = false;
  920. PR_BeginCompilation (malloc (0x100000), 0x100000);
  921. // compile all the files
  922. do
  923. {
  924. src = COM_Parse(src);
  925. if (!src)
  926. break;
  927. sprintf (filename, "%s%s", sourcedir, com_token);
  928. printf ("compiling %s\n", filename);
  929. LoadFile (filename, (void *)&src2);
  930. if (!PR_CompileFile (src2, filename) )
  931. exit (1);
  932. } while (1);
  933. if (!PR_FinishCompilation ())
  934. Error ("compilation errors");
  935. p = CheckParm ("-asm");
  936. if (p)
  937. {
  938. for (p++ ; p<argc ; p++)
  939. {
  940. if (argv[p][0] == '-')
  941. break;
  942. PrintFunction (argv[p]);
  943. }
  944. }
  945. // write progdefs.h
  946. crc = PR_WriteProgdefs ("progdefs.h");
  947. // write data file
  948. WriteData (crc);
  949. // regenerate bmodels if -bspmodels
  950. BspModels ();
  951. // report / copy the data files
  952. CopyFiles ();
  953. }