eclass.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1997-2006 Id Software, Inc.
  4. This file is part of Quake 2 Tools source code.
  5. Quake 2 Tools source code is free software; you can redistribute it
  6. and/or modify it under the terms of the GNU General Public License as
  7. published by the Free Software Foundation; either version 2 of the License,
  8. or (at your option) any later version.
  9. Quake 2 Tools source code is distributed in the hope that it will be
  10. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Quake 2 Tools source code; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. #include "qe3.h"
  19. #include "io.h"
  20. eclass_t *eclass;
  21. eclass_t *eclass_bad;
  22. char eclass_directory[1024];
  23. /*
  24. the classname, color triple, and bounding box are parsed out of comments
  25. A ? size means take the exact brush size.
  26. /*QUAKED <classname> (0 0 0) ?
  27. /*QUAKED <classname> (0 0 0) (-8 -8 -8) (8 8 8)
  28. Flag names can follow the size description:
  29. /*QUAKED func_door (0 .5 .8) ? START_OPEN STONE_SOUND DOOR_DONT_LINK GOLD_KEY SILVER_KEY
  30. */
  31. char *debugname;
  32. eclass_t *Eclass_InitFromText (char *text)
  33. {
  34. char *t;
  35. int len;
  36. int r, i;
  37. char parms[256], *p;
  38. eclass_t *e;
  39. char color[128];
  40. e = qmalloc(sizeof(*e));
  41. memset (e, 0, sizeof(*e));
  42. text += strlen("/*QUAKED ");
  43. // grab the name
  44. text = COM_Parse (text);
  45. e->name = qmalloc (strlen(com_token)+1);
  46. strcpy (e->name, com_token);
  47. debugname = e->name;
  48. // grab the color, reformat as texture name
  49. r = sscanf (text," (%f %f %f)", &e->color[0], &e->color[1], &e->color[2]);
  50. if (r != 3)
  51. return e;
  52. sprintf (color, "(%f %f %f)", e->color[0], e->color[1], e->color[2]);
  53. strcpy (e->texdef.name, color);
  54. while (*text != ')')
  55. {
  56. if (!*text)
  57. return e;
  58. text++;
  59. }
  60. text++;
  61. // get the size
  62. text = COM_Parse (text);
  63. if (com_token[0] == '(')
  64. { // parse the size as two vectors
  65. e->fixedsize = true;
  66. r = sscanf (text,"%f %f %f) (%f %f %f)", &e->mins[0], &e->mins[1], &e->mins[2],
  67. &e->maxs[0], &e->maxs[1], &e->maxs[2]);
  68. if (r != 6)
  69. return e;
  70. for (i=0 ; i<2 ; i++)
  71. {
  72. while (*text != ')')
  73. {
  74. if (!*text)
  75. return e;
  76. text++;
  77. }
  78. text++;
  79. }
  80. }
  81. else
  82. { // use the brushes
  83. }
  84. // get the flags
  85. // copy to the first /n
  86. p = parms;
  87. while (*text && *text != '\n')
  88. *p++ = *text++;
  89. *p = 0;
  90. text++;
  91. // any remaining words are parm flags
  92. p = parms;
  93. for (i=0 ; i<8 ; i++)
  94. {
  95. p = COM_Parse (p);
  96. if (!p)
  97. break;
  98. strcpy (e->flagnames[i], com_token);
  99. }
  100. // find the length until close comment
  101. for (t=text ; t[0] && !(t[0]=='*' && t[1]=='/') ; t++)
  102. ;
  103. // copy the comment block out
  104. len = t-text;
  105. e->comments = qmalloc (len+1);
  106. memcpy (e->comments, text, len);
  107. #if 0
  108. for (i=0 ; i<len ; i++)
  109. if (text[i] == '\n')
  110. e->comments[i] = '\r';
  111. else
  112. e->comments[i] = text[i];
  113. #endif
  114. e->comments[len] = 0;
  115. return e;
  116. }
  117. /*
  118. =================
  119. Eclass_InsertAlphabetized
  120. =================
  121. */
  122. void Eclass_InsertAlphabetized (eclass_t *e)
  123. {
  124. eclass_t *s;
  125. if (!eclass)
  126. {
  127. eclass = e;
  128. return;
  129. }
  130. s = eclass;
  131. if (stricmp (e->name, s->name) < 0)
  132. {
  133. e->next = s;
  134. eclass = e;
  135. return;
  136. }
  137. do
  138. {
  139. if (!s->next || stricmp (e->name, s->next->name) < 0)
  140. {
  141. e->next = s->next;
  142. s->next = e;
  143. return;
  144. }
  145. s=s->next;
  146. } while (1);
  147. }
  148. /*
  149. =================
  150. Eclass_ScanFile
  151. =================
  152. */
  153. void Eclass_ScanFile (char *filename)
  154. {
  155. int size;
  156. char *data;
  157. eclass_t *e;
  158. int i;
  159. char temp[1024];
  160. QE_ConvertDOSToUnixName( temp, filename );
  161. Sys_Printf ("ScanFile: %s\n", temp);
  162. size = LoadFile (filename, (void *)&data);
  163. for (i=0 ; i<size ; i++)
  164. if (!strncmp(data+i, "/*QUAKED",8))
  165. {
  166. e = Eclass_InitFromText (data+i);
  167. if (e)
  168. Eclass_InsertAlphabetized (e);
  169. else
  170. printf ("Error parsing: %s in %s\n",debugname, filename);
  171. }
  172. free (data);
  173. }
  174. void Eclass_InitForSourceDirectory (char *path)
  175. {
  176. struct _finddata_t fileinfo;
  177. int handle;
  178. char filename[1024];
  179. char filebase[1024];
  180. char temp[1024];
  181. char *s;
  182. QE_ConvertDOSToUnixName( temp, path );
  183. Sys_Printf ("Eclass_InitForSourceDirectory: %s\n", temp );
  184. strcpy (filebase, path);
  185. s = filebase + strlen(filebase)-1;
  186. while (*s != '\\' && *s != '/' && s!=filebase)
  187. s--;
  188. *s = 0;
  189. eclass = NULL;
  190. handle = _findfirst (path, &fileinfo);
  191. if (handle != -1)
  192. {
  193. do
  194. {
  195. sprintf (filename, "%s\\%s", filebase, fileinfo.name);
  196. Eclass_ScanFile (filename);
  197. } while (_findnext( handle, &fileinfo ) != -1);
  198. _findclose (handle);
  199. }
  200. eclass_bad = Eclass_InitFromText ("/*QUAKED UNKNOWN_CLASS (0 0.5 0) ?");
  201. }
  202. eclass_t *Eclass_ForName (char *name, qboolean has_brushes)
  203. {
  204. eclass_t *e;
  205. char init[1024];
  206. if (!name)
  207. return eclass_bad;
  208. for (e=eclass ; e ; e=e->next)
  209. if (!strcmp (name, e->name))
  210. return e;
  211. // create a new class for it
  212. if (has_brushes)
  213. {
  214. sprintf (init, "/*QUAKED %s (0 0.5 0) ?\nNot found in source.\n", name);
  215. e = Eclass_InitFromText (init);
  216. }
  217. else
  218. {
  219. sprintf (init, "/*QUAKED %s (0 0.5 0) (-8 -8 -8) (8 8 8)\nNot found in source.\n", name);
  220. e = Eclass_InitFromText (init);
  221. }
  222. Eclass_InsertAlphabetized (e);
  223. return e;
  224. }