home *** CD-ROM | disk | FTP | other *** search
/ Superpower (Alt) / SUPERPOWER.iso / q / source / entitycl.m < prev    next >
Encoding:
Text File  |  1996-08-08  |  3.9 KB  |  267 lines

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