EntityClass.m 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. #import "qedefs.h"
  2. @implementation EntityClass
  3. /*
  4. the classname, color triple, and bounding box are parsed out of comments
  5. A ? size means take the exact brush size.
  6. /*QUAKED <classname> (0 0 0) ?
  7. /*QUAKED <classname> (0 0 0) (-8 -8 -8) (8 8 8)
  8. Flag names can follow the size description:
  9. /*QUAKED func_door (0 .5 .8) ? START_OPEN STONE_SOUND DOOR_DONT_LINK GOLD_KEY SILVER_KEY
  10. */
  11. char *debugname;
  12. - initFromText: (char *)text
  13. {
  14. char *t;
  15. int len;
  16. int r, i;
  17. char parms[256], *p;
  18. [super init];
  19. text += strlen("/*QUAKED ");
  20. // grab the name
  21. text = COM_Parse (text);
  22. name = malloc (strlen(com_token)+1);
  23. strcpy (name, com_token);
  24. debugname = name;
  25. // grab the color
  26. r = sscanf (text," (%f %f %f)", &color[0], &color[1], &color[2]);
  27. if (r != 3)
  28. return NULL;
  29. while (*text != ')')
  30. {
  31. if (!*text)
  32. return NULL;
  33. text++;
  34. }
  35. text++;
  36. // get the size
  37. text = COM_Parse (text);
  38. if (com_token[0] == '(')
  39. { // parse the size as two vectors
  40. esize = esize_fixed;
  41. r = sscanf (text,"%f %f %f) (%f %f %f)", &mins[0], &mins[1], &mins[2], &maxs[0], &maxs[1], &maxs[2]);
  42. if (r != 6)
  43. return NULL;
  44. for (i=0 ; i<2 ; i++)
  45. {
  46. while (*text != ')')
  47. {
  48. if (!*text)
  49. return NULL;
  50. text++;
  51. }
  52. text++;
  53. }
  54. }
  55. else
  56. { // use the brushes
  57. esize = esize_model;
  58. }
  59. // get the flags
  60. // copy to the first /n
  61. p = parms;
  62. while (*text && *text != '\n')
  63. *p++ = *text++;
  64. *p = 0;
  65. text++;
  66. // any remaining words are parm flags
  67. p = parms;
  68. for (i=0 ; i<8 ; i++)
  69. {
  70. p = COM_Parse (p);
  71. if (!p)
  72. break;
  73. strcpy (flagnames[i], com_token);
  74. }
  75. // find the length until close comment
  76. for (t=text ; t[0] && !(t[0]=='*' && t[1]=='/') ; t++)
  77. ;
  78. // copy the comment block out
  79. len = t-text;
  80. comments = malloc (len+1);
  81. memcpy (comments, text, len);
  82. comments[len] = 0;
  83. return self;
  84. }
  85. - (esize_t)esize
  86. {
  87. return esize;
  88. }
  89. - (char *)classname
  90. {
  91. return name;
  92. }
  93. - (float *)mins
  94. {
  95. return mins;
  96. }
  97. - (float *)maxs
  98. {
  99. return maxs;
  100. }
  101. - (float *)drawColor
  102. {
  103. return color;
  104. }
  105. - (char *)comments
  106. {
  107. return comments;
  108. }
  109. - (char *)flagName: (unsigned)flagnum
  110. {
  111. if (flagnum >= MAX_FLAGS)
  112. Error ("EntityClass flagName: bad number");
  113. return flagnames[flagnum];
  114. }
  115. @end
  116. //===========================================================================
  117. @implementation EntityClassList
  118. /*
  119. =================
  120. insertEC:
  121. =================
  122. */
  123. - (void)insertEC: ec
  124. {
  125. char *name;
  126. int i;
  127. name = [ec classname];
  128. for (i=0 ; i<numElements ; i++)
  129. {
  130. if (strcasecmp (name, [[self objectAt: i] classname]) < 0)
  131. {
  132. [self insertObject: ec at:i];
  133. return;
  134. }
  135. }
  136. [self addObject: ec];
  137. }
  138. /*
  139. =================
  140. scanFile
  141. =================
  142. */
  143. - (void)scanFile: (char *)filename
  144. {
  145. int size;
  146. char *data;
  147. id cl;
  148. int i;
  149. char path[1024];
  150. sprintf (path,"%s/%s", source_path, filename);
  151. size = LoadFile (path, (void *)&data);
  152. for (i=0 ; i<size ; i++)
  153. if (!strncmp(data+i, "/*QUAKED",8))
  154. {
  155. cl = [[EntityClass alloc] initFromText: data+i];
  156. if (cl)
  157. [self insertEC: cl];
  158. else
  159. printf ("Error parsing: %s in %s\n",debugname, filename);
  160. }
  161. free (data);
  162. }
  163. /*
  164. =================
  165. scanDirectory
  166. =================
  167. */
  168. - (void)scanDirectory
  169. {
  170. int count, i;
  171. struct direct **namelist, *ent;
  172. [self empty];
  173. count = scandir(source_path, &namelist, NULL, NULL);
  174. for (i=0 ; i<count ; i++)
  175. {
  176. ent = namelist[i];
  177. if (ent->d_namlen <= 3)
  178. continue;
  179. if (!strcmp (ent->d_name+ent->d_namlen-3,".qc"))
  180. [self scanFile: ent->d_name];
  181. }
  182. }
  183. id entity_classes_i;
  184. - initForSourceDirectory: (char *)path
  185. {
  186. [super init];
  187. source_path = path;
  188. [self scanDirectory];
  189. entity_classes_i = self;
  190. nullclass = [[EntityClass alloc] initFromText:
  191. "/*QUAKED UNKNOWN_CLASS (0 0.5 0) ?"];
  192. return self;
  193. }
  194. - (id)classForName: (char *)name
  195. {
  196. int i;
  197. id o;
  198. for (i=0 ; i<numElements ; i++)
  199. {
  200. o = [self objectAt: i];
  201. if (!strcmp (name,[o classname]) )
  202. return o;
  203. }
  204. return nullclass;
  205. }
  206. @end