home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1996 December / PCWKCD1296.iso / sharewar / quake106 / utils / light / entities.c next >
C/C++ Source or Header  |  1996-09-12  |  6KB  |  279 lines

  1. // entities.c
  2.  
  3. #include "light.h"
  4.  
  5. entity_t    entities[MAX_MAP_ENTITIES];
  6. int            num_entities;
  7.  
  8. /*
  9. ==============================================================================
  10.  
  11. ENTITY FILE PARSING
  12.  
  13. If a light has a targetname, generate a unique style in the 32-63 range
  14. ==============================================================================
  15. */
  16.  
  17. int        numlighttargets;
  18. char    lighttargets[32][64];
  19.  
  20. int LightStyleForTargetname (char *targetname, qboolean alloc)
  21. {
  22.     int        i;
  23.     
  24.     for (i=0 ; i<numlighttargets ; i++)
  25.         if (!strcmp (lighttargets[i], targetname))
  26.             return 32 + i;
  27.     if (!alloc)
  28.         return -1;
  29.     strcpy (lighttargets[i], targetname);
  30.     numlighttargets++;
  31.     return numlighttargets-1 + 32;
  32. }
  33.  
  34.  
  35. /*
  36. ==================
  37. MatchTargets
  38. ==================
  39. */
  40. void MatchTargets (void)
  41. {
  42.     int        i,j;
  43.     
  44.     for (i=0 ; i<num_entities ; i++)
  45.     {
  46.         if (!entities[i].target[0])
  47.             continue;
  48.             
  49.         for (j=0 ; j<num_entities ; j++)
  50.             if (!strcmp(entities[j].targetname, entities[i].target))
  51.             {
  52.                 entities[i].targetent = &entities[j];
  53.                 break;
  54.             }
  55.         if (j==num_entities)
  56.         {
  57.             printf ("WARNING: entity at (%i,%i,%i) (%s) has unmatched target\n", (int)entities[i].origin[0], (int)entities[i].origin[1], (int)entities[i].origin[2], entities[i].classname);
  58.             continue;
  59.         }
  60.         
  61. // set the style on the source ent for switchable lights
  62.         if (entities[j].style)
  63.         {
  64.             char    s[16];
  65.             
  66.             entities[i].style = entities[j].style;
  67.             sprintf (s,"%i", entities[i].style);
  68.             SetKeyValue (&entities[i], "style", s);
  69.         }
  70.     }    
  71. }
  72.  
  73.  
  74. /*
  75. ==================
  76. LoadEntities
  77. ==================
  78. */
  79. void LoadEntities (void)
  80. {
  81.     char         *data;
  82.     entity_t    *entity;
  83.     char        key[64];    
  84.     epair_t        *epair;
  85.     double        vec[3];
  86.     int            i;
  87.  
  88.     data = dentdata;
  89. //
  90. // start parsing
  91. //
  92.     num_entities = 0;
  93.     
  94. // go through all the entities
  95.     while (1)
  96.     {
  97.     // parse the opening brace    
  98.         data = COM_Parse (data);
  99.         if (!data)
  100.             break;
  101.         if (com_token[0] != '{')
  102.             Error ("LoadEntities: found %s when expecting {",com_token);
  103.  
  104.         if (num_entities == MAX_MAP_ENTITIES)
  105.             Error ("LoadEntities: MAX_MAP_ENTITIES");
  106.         entity = &entities[num_entities];
  107.         num_entities++;
  108.         
  109.     // go through all the keys in this entity
  110.         while (1)
  111.         {
  112.             int        c;
  113.  
  114.         // parse key
  115.             data = COM_Parse (data);
  116.             if (!data)
  117.                 Error ("LoadEntities: EOF without closing brace");
  118.             if (!strcmp(com_token,"}"))
  119.                 break;
  120.             strcpy (key, com_token);
  121.  
  122.         // parse value
  123.             data = COM_Parse (data);
  124.             if (!data)
  125.                 Error ("LoadEntities: EOF without closing brace");
  126.             c = com_token[0];
  127.             if (c == '}')
  128.                 Error ("LoadEntities: closing brace without data");
  129.             
  130.             epair = malloc (sizeof(epair_t));
  131.             memset (epair, 0, sizeof(epair));
  132.             strcpy (epair->key, key);
  133.             strcpy (epair->value, com_token);
  134.             epair->next = entity->epairs;
  135.             entity->epairs = epair;
  136.             
  137.             if (!strcmp(key, "classname"))
  138.                 strcpy (entity->classname, com_token);
  139.             else if (!strcmp(key, "target"))
  140.                 strcpy (entity->target, com_token);            
  141.             else if (!strcmp(key, "targetname"))
  142.                 strcpy (entity->targetname, com_token);
  143.             else if (!strcmp(key, "origin"))
  144.             {
  145.                 // scan into doubles, then assign
  146.                 // which makes it vec_t size independent
  147.                 if (sscanf(com_token, "%lf %lf %lf",
  148.                         &vec[0], &vec[1], &vec[2]) != 3)
  149.                     Error ("LoadEntities: not 3 values for origin");
  150.                 for (i=0 ; i<3 ; i++)
  151.                     entity->origin[i] = vec[i];
  152.             }
  153.             else if (!strncmp(key, "light", 5) || !strcmp (key, "_light") )
  154.             {
  155.                 entity->light = atof(com_token);
  156.             }
  157.             else if (!strcmp(key, "style"))
  158.             {
  159.                 entity->style = atof(com_token);
  160.                 if ((unsigned)entity->style > 254)
  161.                     Error ("Bad light style %i (must be 0-254)", entity->style);
  162.             }
  163.             else if (!strcmp(key, "angle"))
  164.             {
  165.                 entity->angle = atof(com_token);
  166.             }
  167.         
  168.         }
  169.  
  170.     // all fields have been parsed
  171.         if (!strncmp (entity->classname, "light", 5) && !entity->light)
  172.             entity->light = DEFAULTLIGHTLEVEL;
  173.  
  174.         if (!strcmp (entity->classname, "light"))
  175.         {
  176.             if (entity->targetname[0] && !entity->style)
  177.             {
  178.                 char    s[16];
  179.                 
  180.                 entity->style = LightStyleForTargetname (entity->targetname, true);
  181.                 sprintf (s,"%i", entity->style);
  182.                 SetKeyValue (entity, "style", s);
  183.             }
  184.         }
  185.     }
  186.  
  187.     printf ("%d entities read\n", num_entities);
  188.  
  189.     MatchTargets ();
  190. }
  191.  
  192. char     *ValueForKey (entity_t *ent, char *key)
  193. {
  194.     epair_t    *ep;
  195.     
  196.     for (ep=ent->epairs ; ep ; ep=ep->next)
  197.         if (!strcmp (ep->key, key) )
  198.             return ep->value;
  199.     return "";
  200. }
  201.  
  202. void     SetKeyValue (entity_t *ent, char *key, char *value)
  203. {
  204.     epair_t    *ep;
  205.     
  206.     for (ep=ent->epairs ; ep ; ep=ep->next)
  207.         if (!strcmp (ep->key, key) )
  208.         {
  209.             strcpy (ep->value, value);
  210.             return;
  211.         }
  212.     ep = malloc (sizeof(*ep));
  213.     ep->next = ent->epairs;
  214.     ent->epairs = ep;
  215.     strcpy (ep->key, key);
  216.     strcpy (ep->value, value);
  217. }
  218.  
  219. float    FloatForKey (entity_t *ent, char *key)
  220. {
  221.     char    *k;
  222.     
  223.     k = ValueForKey (ent, key);
  224.     return atof(k);
  225. }
  226.  
  227. void     GetVectorForKey (entity_t *ent, char *key, vec3_t vec)
  228. {
  229.     char    *k;
  230.     
  231.     k = ValueForKey (ent, key);
  232.     sscanf (k, "%lf %lf %lf", &vec[0], &vec[1], &vec[2]);
  233. }
  234.  
  235.  
  236.  
  237. /*
  238. ================
  239. WriteEntitiesToString
  240. ================
  241. */
  242. void WriteEntitiesToString (void)
  243. {
  244.     char    *buf, *end;
  245.     epair_t    *ep;
  246.     char    line[128];
  247.     int        i;
  248.     
  249.     buf = dentdata;
  250.     end = buf;
  251.     *end = 0;
  252.     
  253.     printf ("%i switchable light styles\n", numlighttargets);
  254.     
  255.     for (i=0 ; i<num_entities ; i++)
  256.     {
  257.         ep = entities[i].epairs;
  258.         if (!ep)
  259.             continue;    // ent got removed
  260.         
  261.         strcat (end,"{\n");
  262.         end += 2;
  263.                 
  264.         for (ep = entities[i].epairs ; ep ; ep=ep->next)
  265.         {
  266.             sprintf (line, "\"%s\" \"%s\"\n", ep->key, ep->value);
  267.             strcat (end, line);
  268.             end += strlen(line);
  269.         }
  270.         strcat (end,"}\n");
  271.         end += 2;
  272.  
  273.         if (end > buf + MAX_MAP_ENTSTRING)
  274.             Error ("Entity text too long");
  275.     }
  276.     entdatasize = end - buf + 1;
  277. }
  278.  
  279.