home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / msdos / raytrace / pov / gen / animdat / animdat.c next >
Encoding:
C/C++ Source or Header  |  1992-07-29  |  10.4 KB  |  407 lines

  1. /*--------------------------------------------------------------*/
  2. /*            ANIMDAT 1.1                */
  3. /*        copyright 1992 - TODD SANKEY            */
  4. /*                                */
  5. /*  The author hereby grants permission for the use and sharing    */
  6. /* of both source code end executable versions of this software    */
  7. /* at no charge. This software is not for sale and no other    */
  8. /* shall charge for it without the expressed consent of the    */
  9. /* author.                            */
  10. /*                                */
  11. /*  The source code can be freely modified, but it must retain    */
  12. /* the original copyright notice, and the author must be    */
  13. /* notified of these changes if the altered code is to be    */
  14. /* distributed.                            */
  15. /*--------------------------------------------------------------*/
  16.  
  17.  
  18. /*--------------------------------------------------------------*/
  19. /* animdat.c        Main file for animdat program.        */
  20. /*--------------------------------------------------------------*/
  21.  
  22. #include <stdio.h>
  23. #include <string.h>
  24. #include <ctype.h>
  25. #include <math.h>
  26. #include "common.h"
  27.  
  28. /*  This definition controls what filenames are used for the generated    */
  29. /* files. If LONG_FILENAMES is not defined, then the generated files    */
  30. /* are named SCENEnnn.DAT where nnn is the number of the scene. If    */
  31. /* LONG_FILENAMES is defined, the generated filenames use the root name    */
  32. /* given on the command line and add _nnn.DAT .                */
  33. /*  This option is given because DOS machines have the limit of 8    */
  34. /* characters in the filename, so LONG_FILENAMES should not be used.    */
  35.  
  36. /* #define    LONG_FILENAMES */
  37.  
  38. #ifdef LONG_FILENAMES
  39. #define MAX_FNAME_SIZE 100
  40. #else
  41. #define MAX_FNAME_SIZE 13
  42. #endif
  43.  
  44. #define NAMELEN 20
  45. #define NUMLEN 20
  46. #define MAXSCENES 100
  47. #define VARCHAR '@'
  48. #define GATECHAR '&'
  49. #define MAX_LINE_SIZE 256
  50.  
  51.  
  52. /* Globals used in other modules */
  53. int        numscenes = -1;
  54. sym_ptr        symbol_table = NULL;
  55. char        cur_line[MAX_LINE_SIZE];
  56. char        *cur_file = NULL;
  57. unsigned int    cur_line_num = 0;
  58.  
  59.  
  60. /* Used within animdat.c */
  61. static sym_ptr    x_symbol = NULL;
  62. static sym_ptr    cur_sc_symbol = NULL;
  63. static sym_ptr    num_sc_symbol = NULL;
  64. static char    *cur_symbol = NULL;
  65. static int    gate_closed = 0;
  66.  
  67.  
  68. /*--------------------------------------------------------------*/
  69. /* parse_equation    Attaches a binary tree representation    */
  70. /*            of a mathematical expression to a symbol*/
  71. /*            given that the scanner module is    */
  72. /*            initialized to the first token in the    */
  73. /*            expression.                */
  74. /*--------------------------------------------------------------*/
  75. void parse_equation(sym_ptr new_symbol)
  76. {
  77.  new_symbol->sym_info = (void *)expression();
  78.  new_symbol->sym_type = SYM_DOUBLE;
  79.  if (token == COMMA) {
  80.     double sign_flag = 1.0;
  81.     get_token();
  82.     if (token == MINUS) {
  83.         sign_flag = (-1.0);
  84.         get_token();
  85.         }
  86.     else if (token == PLUS)
  87.         get_token();
  88.  
  89.     if (token == NUMBER)
  90.         new_symbol->cur_val = sign_flag * literal_value;
  91.     else
  92.         error(SYNTAX_ERROR,cur_line);
  93.     }
  94.  
  95. }
  96.  
  97.  
  98.  
  99. /*--------------------------------------------------------------*/
  100. /* parse_filename    Attaches a file pointer to a symbol.    */
  101. /*--------------------------------------------------------------*/
  102. void parse_filename(sym_ptr new_symbol)
  103. {
  104.  get_token();
  105.  new_symbol->sym_type = SYM_FILE;
  106.  new_symbol->sym_info = (void *)fopen(word_string,"r");
  107.  if (new_symbol->sym_info == NULL)
  108.     error(FILE_ERROR,word_string);
  109.  get_token();
  110. }
  111.  
  112.  
  113. /*--------------------------------------------------------------*/
  114. /* parse_string        Attaches a string pointer to a symbol.    */
  115. /*--------------------------------------------------------------*/
  116. void parse_string(sym_ptr new_symbol)
  117. {
  118.  char *quote;
  119.  
  120.  quote=(char *)malloc(strlen(word_string)+1);
  121.  if (quote == NULL)
  122.     error(FAILED_MALLOC,NULL);
  123.  
  124.  strcpy(quote,word_string);
  125.  new_symbol->sym_type = SYM_STRING;
  126.  new_symbol->sym_info = (void *)quote;
  127.  get_token();
  128. }
  129.  
  130.  
  131.  
  132.  
  133. /*--------------------------------------------------------------*/
  134. /* parsevarfile        Attempts to parse a file as a sequence    */
  135. /*            of lines each containing a symbol name    */
  136. /*            and a definition.            */
  137. /*--------------------------------------------------------------*/
  138. void parsevarfile(FILE *varfile)
  139. {
  140.  int i;
  141.  sym_ptr new_symbol;
  142.  
  143.  cur_line_num = 0;
  144.  while (!feof(varfile)) {
  145.     /* Read the current line of the file into a buffer */
  146.     if (fgets(cur_line,MAX_LINE_SIZE,varfile) != NULL) {
  147.         cur_line_num++;
  148.         for (i=0; i<MAX_LINE_SIZE && cur_line[i]!='\0'; i++);
  149.         if (cur_line[i]!='\0' || i>=MAX_LINE_SIZE)
  150.             error(LINE_TOO_LONG,cur_line);
  151.  
  152.         init_scanner(cur_line);
  153.  
  154.         if (token == IDENTIFIER) {
  155.             new_symbol = add_symbol(&symbol_table, word_string);
  156.             get_token();
  157.             if (token != EQUAL)
  158.                 error(SYNTAX_ERROR,cur_line);
  159.             get_token();
  160.             switch (token) {
  161.                 case POUND : parse_filename(new_symbol);break;
  162.                 case QUOTE : parse_string(new_symbol);    break;
  163.                 default    : parse_equation(new_symbol);
  164.                 }
  165.             }
  166.         else if (token == NUMSCENE) {
  167.             get_token();
  168.             if (token != EQUAL)
  169.                 error(SYNTAX_ERROR,cur_line);
  170.             get_token();
  171.             if (token != NUMBER)
  172.                 error(SYNTAX_ERROR,cur_line);
  173.             numscenes = (int)literal_value;
  174.             get_token();
  175.             }
  176.         else if (token != END_OF_FILE)
  177.             error(SYNTAX_ERROR,cur_line);
  178.         }
  179.     }
  180.  
  181.  cur_line_num = 0;
  182. }
  183.  
  184.  
  185. /*--------------------------------------------------------------*/
  186. /* add_system_variables        Creates the predefined symbols    */
  187. /*                but leaves them undefined.    */
  188. /*--------------------------------------------------------------*/
  189. void add_system_variables()
  190. {
  191.  sym_ptr symbol;
  192.  
  193.  num_sc_symbol = add_symbol(&symbol_table,"num_scenes");
  194.  x_symbol = add_symbol(&symbol_table,"x");
  195.  cur_sc_symbol = add_symbol(&symbol_table,"cur_scene");
  196. }
  197.  
  198.  
  199.  
  200.  
  201. /*--------------------------------------------------------------*/
  202. /* update_system_variables    Defines the system variables.    */
  203. /*--------------------------------------------------------------*/
  204. void update_system_variables()
  205. {
  206.  char eq[MAX_LINE_SIZE];
  207.  double xinc;
  208.  sym_ptr symbol;
  209.  
  210.  xinc = 1.0 / ((double)numscenes);
  211.  sprintf(eq,"x + %lf \0",xinc);
  212.  init_scanner(eq);
  213.  x_symbol->sym_info = (void *)expression();
  214.  x_symbol->cur_val = 0.0;
  215.  x_symbol->sym_type = SYM_DOUBLE;
  216.  
  217.  sprintf(eq,"cur_scene + 1 \0");
  218.  init_scanner(eq);
  219.  cur_sc_symbol->sym_info = (void *)expression();
  220.  cur_sc_symbol->cur_val = 0.0;
  221.  cur_sc_symbol->sym_type = SYM_DOUBLE;
  222.  
  223.  sprintf(eq,"%d \0",numscenes);
  224.  init_scanner(eq);
  225.  num_sc_symbol->sym_info = (void *)expression();
  226.  num_sc_symbol->cur_val = (double)numscenes;
  227.  num_sc_symbol->sym_type = SYM_DOUBLE;
  228. }
  229.  
  230.  
  231.  
  232.  
  233.  
  234. /*--------------------------------------------------------------*/
  235. /* check_btree        Scans a binary tree representation    */
  236. /*            of a mathematical expression checking    */
  237. /*            for undefined symbols.            */
  238. /*--------------------------------------------------------------*/
  239. void check_btree(btree_node_ptr bnode)
  240. {
  241.  if (bnode->node_type == NAMEDVAR) {
  242.     if (search_symtab(symbol_table,bnode->node_data.name) == NULL) {
  243.         sprintf(cur_line,"%s in definition of %s",bnode->node_data.name,cur_symbol);
  244.         error(UNDEFINED_SYMBOL,cur_line);
  245.         }
  246.     }
  247. }
  248.  
  249.  
  250.  
  251.  
  252. /*--------------------------------------------------------------*/
  253. /* check_symbol        Verifies the definition of a symbol.    */
  254. /*--------------------------------------------------------------*/
  255. void check_symbol(sym_ptr symbol)
  256. {
  257.  cur_symbol = symbol->name;
  258.  if (symbol->sym_type == SYM_DOUBLE)
  259.     traverse_btree((btree_node_ptr)(symbol->sym_info),check_btree);
  260. }
  261.  
  262.  
  263.  
  264.  
  265. /*--------------------------------------------------------------*/
  266. /* reset_flags        Clears the flag in a symbol which    */
  267. /*            indicates that the symbol value has    */
  268. /*            already been evaluated for this scene.    */
  269. /*--------------------------------------------------------------*/
  270. void reset_flags(sym_ptr symbol)
  271. {
  272.  symbol->update_flag = 0;
  273. }
  274.  
  275.  
  276.  
  277.  
  278. void main(int argc,char **argv)
  279. {
  280.  int    curscene,inchar,i;
  281.  char    varname[MAX_LINE_SIZE];
  282.  FILE    *datfile,*curscenefile,*varfile;
  283.  sym_ptr symbol;
  284.  char    dat_name[MAX_FNAME_SIZE];
  285.  char    var_name[MAX_FNAME_SIZE];
  286.  char    scene_name[MAX_FNAME_SIZE];
  287.  
  288.  if (argc != 2) {
  289.     printf("ANIMDAT <root file>\n");
  290.     printf("  where rootfile.dat is the template file\n");
  291.     printf("  and   rootfile.var is the variable definition file\n");
  292.     exit(1);
  293.     }
  294.  
  295.  strcpy(dat_name, argv[1]);
  296.  strcat(dat_name,".dat");
  297.  datfile=fopen(dat_name,"r");
  298.  if (datfile == NULL) {
  299.     printf(" Could not open datfile: %s\n", dat_name);
  300.     exit(1);
  301.     }
  302.  
  303.  strcpy(var_name, argv[1]);
  304.  strcat(var_name, ".var");
  305.  varfile=fopen(var_name,"r");
  306.  if (varfile == NULL) {
  307.     printf(" Could not open varfile: %s\n", var_name);
  308.     exit(1);
  309.     }
  310.  
  311.  cur_file = var_name;
  312.  add_system_variables();
  313.  parsevarfile(varfile);
  314.  fclose(varfile);
  315.  update_system_variables();
  316.  traverse_symtab(symbol_table,check_symbol);
  317.  
  318.  if (numscenes<=0)
  319.     error(NO_NUMSCENE,NULL);
  320.  
  321.  cur_file = dat_name;
  322.  cur_line_num = 1;
  323.  
  324. #ifndef LONG_FILENAMES
  325.  strcpy(scene_name,"scene000.dat");
  326. #endif
  327.  
  328.  for (curscene=1;curscene<=numscenes;curscene++) {
  329.  
  330. #ifdef LONG_FILENAMES
  331.     sprintf(scene_name,"%s_%d.dat",argv[1],curscene);
  332. #else
  333.     sprintf(scene_name,"scene%03d.dat",curscene);
  334. #endif
  335.  
  336.     curscenefile=fopen(scene_name,"w");
  337.  
  338.     if (curscenefile==NULL) {
  339.         printf("Could not open file %s\n",scene_name);
  340.         exit(1);
  341.         }
  342.  
  343.     rewind(datfile);
  344.     traverse_symtab(symbol_table,reset_flags);
  345.  
  346.     gate_closed = 0;
  347.     while (!feof(datfile)) {
  348.         inchar=fgetc(datfile);
  349.  
  350.         switch (inchar) {
  351.         case VARCHAR :
  352.             if (!gate_closed) {
  353.                 i = 0;
  354.                 do {
  355.                     inchar=fgetc(datfile);
  356.                     if (inchar != VARCHAR) {
  357.                         varname[i] = inchar;
  358.                         i++;
  359.                         }
  360.                     } while ( i < (MAX_LINE_SIZE - 1) && inchar !=VARCHAR);
  361.  
  362.                 varname[i] = '\0';
  363.                 if (inchar!=VARCHAR)
  364.                     fprintf(curscenefile,"%c%s",VARCHAR,varname);
  365.                 else
  366.                     print_symbol(curscenefile,varname);
  367.                 }
  368.             break;
  369.  
  370.         case GATECHAR :
  371.             inchar = fgetc(datfile);
  372.             if (isalpha(inchar)) {    /* Assume start of gate */
  373.                 i = 0;
  374.                 do {
  375.                     varname[i] = inchar;
  376.                     i++;
  377.                     inchar = fgetc(datfile);
  378.                     } while (i < (MAX_LINE_SIZE - 1) && (isalnum(inchar) || inchar=='_') );
  379.                 varname[i] = '\0';
  380.                 if ( (eval_symbol(varname) <= 0.0) || gate_closed)
  381.                     gate_closed++;
  382.                 }
  383.  
  384.             else if (gate_closed)
  385.                 gate_closed--; /* End of gate */
  386.             break;
  387.  
  388.         case EOF :
  389.             break;
  390.  
  391.         default:
  392.             if (!gate_closed) {
  393.                 fputc(inchar,curscenefile);
  394.                 if (inchar == '\n')
  395.                     cur_line_num++;
  396.                 }
  397.  
  398.  
  399.  
  400.             }
  401.         }
  402.  
  403.     fclose(curscenefile);
  404.     }
  405.  
  406. }
  407.