home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the DOOM Programming Gurus / Tricks_of_the_Doom_Programming_Gurus.iso / bonus / editors / deth / source / readcfg.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-01  |  10.1 KB  |  518 lines

  1. #include "deu.h"
  2.  
  3. #include <assert.h>
  4. #include <stdio.h>
  5.  
  6. #ifdef NULL
  7. #undef NULL
  8. #define NULL ((char *)0x0L)
  9. #endif
  10.  
  11.  
  12. BCINT getcol(char *str);
  13. void readcfg(char *file);
  14. void add_thing(char *line);
  15. void add_thing_class(char *line);
  16. void add_linedef(char *line);
  17. void add_linedef_class(char *line);
  18. void add_sector_type(char *line);
  19. void add_sector_class(char *line);
  20. void add_levels(char *line);
  21. void add_texture_sections(char *line);
  22. void add_ftexture_sections(char *line);
  23. void get_palette_colour(char *line);
  24. int read_line(FILE *f, char *buf, int buflen);
  25.  
  26. /* stuff for manipulating SList s */
  27. SList SList_append(SList l, char *str);
  28. SList SList_find(SList l, char *str);
  29.  
  30. extern BCINT Palette[];
  31.  
  32. /* what all the various sections in the cfg file are */
  33. typedef enum {
  34.     NONE = 0,    /* haven't got a section header yet */
  35.     WAD,
  36.     THINGS,
  37.     LINEDEFS,
  38.     LEVELS,
  39.     TEXTURES,
  40.     FTEXTURES,
  41.     REGTEST,
  42.     SECTORS,
  43.     COLORS,
  44.     NUM_SECTIONS
  45. } cfg_section;
  46.  
  47. char *header[NUM_SECTIONS] = {
  48.     /* these go hand in hand with the numbers above */
  49.     "",
  50.     "[wad]",
  51.     "[things]",
  52.     "[linedefs]",
  53.     "[levels]",
  54.     "[textures]",
  55.     "[ftextures]",
  56.     "[regtest]",
  57.     "[sectors]",
  58.     "[colors]"
  59. };
  60.  
  61. char *colours[23] = {
  62.     "BLACK", "BLUE", "GREEN", "CYAN", "RED", "MAGENTA", "BROWN", "LIGHTGRAY",
  63.     "DARKGRAY", "LIGHTBLUE", "LIGHTGREEN", "LIGHTCYAN", "LIGHTRED",
  64.     "LIGHTMAGENTA", "YELLOW", "WHITE", "DARKBLUE", "DARKGREEN", "DARKRED",
  65.     "DARKMAGENTA", "GRAY", "DARKERGRAY", "ORANGE"
  66. };
  67.  
  68. ld_class *linedef_class = (ld_class *)NULL;
  69. /* what was the last linedef class we had? */
  70.  
  71. thing_class *current_thing_class = (thing_class *)NULL;
  72. /* ditto for thing class */
  73.  
  74. sector_class *current_sector_class = (sector_class *)NULL;
  75. /* ditto for sectors */
  76.  
  77. BCINT getcol(char *str)
  78. {
  79.     BCINT i = -1;
  80.  
  81.     /* first, do the easy bit -- is the colour specified as a number? */
  82.     if(sscanf(str, "%d", &i))
  83.         return i;
  84.  
  85.     /* check it against the colour names */
  86.     for(i = 0; i < 23; i++)
  87.         if(!stricmp(str, colours[i]))
  88.             return i;
  89.  
  90.     return -1;
  91. }
  92.     
  93.  
  94. void readcfg(char *file)
  95. {
  96.     static cfg_section what = NONE;
  97.     /* what section are we currently reading? */
  98.  
  99.     FILE *thefile;
  100.     char buf[256], *tok;
  101.  
  102.     int i;
  103.  
  104.     if(!(thefile = fopen(file, "rb")))
  105.         return;
  106.  
  107.     /* OK, we opened the file */
  108.     while(read_line(thefile, buf, 255)) {
  109.         /* first, see whether it's just a comment */
  110.         if(*buf == '#')
  111.             goto nextline;
  112.  
  113.         if(!strnicmp("include", buf, 7)) {
  114.             tok = strtok(buf + 7, "\t ");
  115.             readcfg(tok);
  116.             goto nextline;
  117.         }
  118.  
  119.         for(i = 0; i < NUM_SECTIONS; i++) {
  120.             if(!stricmp(buf, header[i])) {
  121.                 what = i;
  122.                 goto nextline;
  123.             }
  124.         }
  125.  
  126.         switch(what) {
  127.         case NONE:
  128.         case NUM_SECTIONS:
  129.             break;
  130.  
  131.         case WAD:
  132.             MainWad = strdup(buf);
  133.             break;
  134.  
  135.         case THINGS:
  136.             if(buf[0] == '"' && buf[strlen(buf) - 1] ==  '"')
  137.                 add_thing_class(buf);
  138.             else
  139.                 add_thing(buf);
  140.             break;
  141.  
  142.         case LINEDEFS:
  143.             if(buf[0] == '"' && buf[strlen(buf) - 1] == '"')
  144.                 add_linedef_class(buf);
  145.             else    
  146.                 add_linedef(buf);
  147.             break;
  148.  
  149.         case SECTORS:
  150.             if(buf[0] == '"' && buf[strlen(buf) - 1] == '"')
  151.                 add_sector_class(buf);
  152.             else
  153.                 add_sector_type(buf);
  154.             break;
  155.  
  156.         case REGTEST:
  157.             RegTest = strdup(buf);
  158.             break;
  159.  
  160.         case LEVELS:
  161.             add_levels(buf);
  162.             break;
  163.  
  164.         case TEXTURES:
  165.             add_texture_sections(buf);
  166.             break;
  167.  
  168.         case FTEXTURES:
  169.             add_ftexture_sections(buf);
  170.             break;
  171.  
  172.         case COLORS:
  173.             get_palette_colour(buf);
  174.             break;
  175.         }
  176.  
  177.     nextline:
  178.     }
  179.  
  180.     fclose(thefile);
  181. }
  182.  
  183.  
  184. void add_thing(char *line)
  185. {
  186.     BCINT c1, c2, radius, type;
  187.     char *tok;
  188.     thing_type *p, *new = (thing_type *)NULL;
  189.  
  190.     if(!current_thing_class)
  191.         return;
  192.  
  193.     tok = strtok(line, "\t ,");
  194.     if(tok && (type = atoi(tok))) {
  195.         tok = strtok(NULL, "\t ,");
  196.         if(tok && (c1 = getcol(tok)) != -1) {
  197.             tok = strtok(NULL, "\t ,");
  198.             if(tok && (c2 = getcol(tok)) != -1) {
  199.                 tok = strtok(NULL, "\t ,");
  200.                 if(tok && (radius = atoi(tok))) {
  201.                     tok = strtok(NULL, "\t\",");
  202.                     /* bodging so that we can get a string delimited
  203.                        by quotes which may contain spaces */
  204.                     while(tok && (tok[0] == ' '))
  205.                         tok = strtok(NULL, "\t\",");
  206.                     /* do the add here */
  207.                     for(p = current_thing_class->types;
  208.                         (p && p->next); p = p->next);
  209.  
  210.                     new = (thing_type *)malloc(sizeof(thing_type));
  211.                     assert(new);
  212.  
  213.                     new->type = type;
  214.                     new->col1 = c1;
  215.                     new->col2 = c2;
  216.                     new->radius = radius;
  217.                     new->name = strdup(tok);
  218.                     new->next = (thing_type *)NULL;
  219.  
  220.                     if(p)
  221.                         p->next = new;
  222.                     else
  223.                         current_thing_class->types = new;
  224.                 }
  225.             }
  226.         }
  227.     }
  228. }
  229.                            
  230. void add_thing_class(char *line)
  231. {
  232.     thing_class *p, *new = (thing_class *)NULL;
  233.  
  234.     line[strlen(line) - 1] = '\0';
  235.     line++;
  236.     /* add it here */
  237.  
  238.     for(p = Thing_classes; (p && p->next); p = p->next)
  239.         if(!strcmp(line, p->name)) {
  240.             current_thing_class = p;
  241.             return;
  242.         }
  243.  
  244.     new = (thing_class *)malloc(sizeof(thing_class));
  245.     assert(new);
  246.  
  247.     new->name = strdup(line);
  248.     new->next = (thing_class *)NULL;
  249.  
  250.     if(p)
  251.         p->next = new;
  252.     else
  253.         Thing_classes = new;
  254.  
  255.     current_thing_class = new; 
  256. }
  257.  
  258. void add_linedef(char *line)
  259. {
  260.     char *short_desc, *long_desc, *tok;
  261.     BCINT type = -1;
  262.     ld_type *p, *new = (ld_type *)NULL;
  263.  
  264.     if(!linedef_class)
  265.         return;
  266.     /* can't add a linedef if we don't know what class
  267.        to put it in */
  268.  
  269.     tok = strtok(line, "\t ,");
  270.     if(tok && (type = atoi(tok)) != -1) {
  271.         tok = strtok(NULL, "\t,\"");
  272.         while(tok && ((tok[0] == ' ') || (tok[0] == ',')))
  273.             tok = strtok(NULL, "\t\"");
  274.         /* should by now have the short description */
  275.         short_desc = strdup(tok);
  276.  
  277.         tok = strtok(NULL, "\t,\"");
  278.         while(tok && ((tok[0] == ' ') || (tok[0] == ',')))
  279.             tok = strtok(NULL, "\t\"");
  280.         /* should by now have the long description */
  281.         long_desc = strdup(tok);
  282.  
  283.         /* now add it */
  284.         for(p = linedef_class->types; (p && p->next); p = p->next);
  285.         /* make p point to the last item in the list, or be NULL */
  286.  
  287.         new = (ld_type *)malloc(sizeof(ld_type));
  288.         assert(new);
  289.  
  290.         new->longname = long_desc;
  291.         new->shortname = short_desc;
  292.         new->type = type;
  293.         new->next = (ld_type *)NULL;
  294.  
  295.         if(p)
  296.             p->next = new;
  297.         else
  298.             linedef_class->types = new;
  299.     }
  300. }
  301.  
  302. void add_linedef_class(char *line)
  303. {
  304.     ld_class *p, *new = (ld_class *)NULL;
  305.  
  306.     line++;
  307.     line[strlen(line) - 1] = '\0';
  308.     /* lose the quotes */
  309.  
  310.     for(p = Linedef_classes; (p && p->next); p = p->next)
  311.         if(!strcmp(p->name, line)) {
  312.             linedef_class = p;
  313.             return;
  314.             /* we already had it */
  315.         }
  316.  
  317.     /* p now points to the last item in the list, or is NULL
  318.        if there is no list. */
  319.  
  320.     new = (ld_class *)malloc(sizeof(ld_class));
  321.     assert(new);
  322.     /* get memory */
  323.  
  324.     new->name = strdup(line);
  325.     new->types = (ld_type *)NULL;
  326.     new->next = (ld_class *)NULL;
  327.     /* fill in the fields */
  328.  
  329.     if(p)
  330.         p->next = new;
  331.     else
  332.         Linedef_classes = new;
  333.  
  334.     linedef_class = new;
  335. }
  336.  
  337. void add_sector_class(char *line)
  338. {
  339.     sector_class *p, *new = (sector_class *)NULL;
  340.  
  341.     line[strlen(line) - 1] = '\0';
  342.     line++;
  343.  
  344.     for(p = Sector_classes; (p && p->next); p = p->next)
  345.         if(!strcmp(line, p->name)) {
  346.             current_sector_class = p;
  347.             return;
  348.         }
  349.  
  350.     new = (sector_class *)malloc(sizeof(sector_class));
  351.     assert(new);
  352.  
  353.     new->name = strdup(line);
  354.     new->next = (sector_class *)NULL;
  355.  
  356.     if(p)
  357.         p->next = new;
  358.     else
  359.         Sector_classes = new;
  360.  
  361.     current_sector_class = new; 
  362. }
  363.  
  364. void add_sector_type(char *line)
  365. {
  366.     char *short_desc;
  367.     char *long_desc;
  368.     BCINT type = -1;
  369.     char *tok;
  370.     sector_type *p, *new = (sector_type *)NULL;
  371.  
  372.     tok = strtok(line, "\t ,");
  373.     if(tok && (type = atoi(tok)) != -1) {
  374.         tok = strtok(NULL, "\t\"");
  375.         while(tok && ((tok[0] == ' ') || (tok[0] == ',')))
  376.             tok = strtok(NULL, "\t\"");
  377.         /* should by now have the short description */
  378.         short_desc = strdup(tok);
  379.  
  380.         tok = strtok(NULL, "\t\"");
  381.         while(tok && ((tok[0] == ' ') || (tok[0] == ',')))
  382.             tok = strtok(NULL, "\t\"");
  383.         /* should by now have the long description */
  384.         long_desc = strdup(tok);
  385.  
  386.         /* add it now */
  387.         new = (sector_type *)malloc(sizeof(sector_type));
  388.         assert(new);
  389.         new->shortname = short_desc;
  390.         new->longname = long_desc;
  391.         new->type = type;
  392.         new->next = (sector_type *)NULL;
  393.  
  394.         for(p = current_sector_class->types; (p && p->next); p = p->next);
  395.  
  396.         if(p)
  397.             p->next = new;
  398.         else
  399.             current_sector_class->types = new;
  400.     }
  401. }
  402.  
  403. void add_levels(char *line)
  404. {
  405.     char *tok;
  406.  
  407.     tok = strtok(line, "\t ,");
  408.     while(tok) {
  409.         /* add a level */
  410.         LevelNames = SList_append(LevelNames, tok);
  411.  
  412.         tok = strtok(NULL, "\t ,");
  413.     }
  414. }
  415.  
  416. void add_texture_sections(char *line)
  417. {
  418.     char *tok;
  419.  
  420.     tok = strtok(line, "\t ,");
  421.     while(tok) {
  422.         /* add it to list */
  423.         Texture_sections = SList_append(Texture_sections, tok);
  424.  
  425.         tok = strtok(NULL, "\t ,");
  426.     }
  427. }
  428.  
  429. void add_ftexture_sections(char *line)
  430. {
  431.     char *tok;
  432.  
  433.     tok = strtok(line, "\t ,");
  434.     while(tok) {
  435.         /* add it to list */
  436.         Ftexture_sections = SList_append(Ftexture_sections, tok);
  437.  
  438.         tok = strtok(NULL, "\t ,");
  439.     }
  440. }
  441.  
  442. void get_palette_colour(char *line)
  443. {
  444.     char *tok;
  445.     BCINT color = -1;
  446.     BCINT palette_index;
  447.     
  448.     tok = strtok(line, "\t ,=");
  449.     if(tok) {
  450.         color = getcol(tok);
  451.         if(color == -1)
  452.             return;
  453.  
  454.         tok = strtok(NULL, "\t ,=");
  455.         palette_index = atoi(tok);
  456.  
  457.         Palette[color] = palette_index;
  458.     }
  459. }
  460.  
  461.         
  462.  
  463. /* read a line in from the current file
  464.    return zero if we hit the end of the file */
  465. int read_line(FILE *f, char *buf, int buflen)
  466. {
  467.     int eof = 0, eol = 0;
  468.     int c;
  469.  
  470.     while(((c = fgetc(f)) == '\n') ||
  471.           (c == '\r'));
  472.  
  473.     while(!(eof || eol) && (buflen > 0)) {
  474.         if(c == EOF)
  475.             eof = 1;
  476.         else if((c == '\n') || (c == '\r'))
  477.             eol = 1;
  478.         else {
  479.             *buf++ = (char)c;
  480.             buflen--;
  481.             c = fgetc(f);
  482.         }
  483.     }
  484.     *buf = 0; /* bung a terminator on it */
  485.  
  486.     return(1 - eof);
  487. }
  488.  
  489. SList SList_append(SList l, char *str)
  490. {
  491.     SList new, head = l;
  492.  
  493.     while(l->next)
  494.         l = l->next;
  495.  
  496.     new = (SList)malloc(sizeof(struct _SList));
  497.     if(head)
  498.         l->next = new;
  499.     else
  500.         head = new;
  501.  
  502.     new->string = strdup(str);
  503.  
  504.     return head;
  505. }
  506.  
  507. SList SList_find(SList l, char *str)
  508. {
  509.     while(l)
  510.         if(!strcmp(l->string, str))
  511.             return l;
  512.         else
  513.             l = l->next;
  514.  
  515.     return (SList)NULL;
  516. }
  517.  
  518.