home *** CD-ROM | disk | FTP | other *** search
- /* read.c - read a TTDDD file and fill the structures
- * - written by Glenn M. Lewis - 7/19/91
- */
-
- static char rcs_id[] = "$Id: read.c,v 1.12 1991/10/14 16:40:43 glewis Exp glewis $";
-
- #include <stdio.h>
- #include <ctype.h>
- #include "ttdddlib.h"
-
- static void process_INFO();
- static void process_OBJ();
- static OBJECT *process_EXTR();
- static void process_DESC();
-
- #define MAXLINE 132
- #define get_UBYTE (UBYTE)get_num
- #define get_UWORD (UWORD)get_num
- #define get_ULONG (ULONG)get_num
-
- static char strin[MAXLINE+1], ps[MAXLINE+1];
-
- /* Here are a few necessary utilities */
-
- static void warn(curline)
- int curline;
- {
- fprintf(stderr, "WARNING: Line %d: ", curline);
- }
-
- static void parse_word(name, lim, up) /* Get next word, optionally limit # of chars */
- register char *name;
- int lim, up;
- {
- register char *c = &strin[0];
- register int i;
- int quote = 0;
-
- while (*c==' ') c++; /* Skip over leading spaces */
- for (i=0; *c; i++,c++) {
- if (lim && i>=lim) break; /* No more characters desired */
- if (*c == '\"') { /* Chop off quotes, ignore spaces */
- if (quote) break; /* Second quote. Stop reading string */
- quote=1;
- i--; /* Don't want i to increment */
- continue;
- }
- if (up && !quote && islower(*c)) *name++ = toupper(*c);
- else {
- if (!quote && *c==' ') break; /* End of the line */
- *name++ = *c; /* Don't modify original case */
- }
- }
- *name = '\0'; /* Truncate the puppy */
- /* Now, delete the command from 'strin' */
- while (*c && *c!=' ') c++; /* Skip the end of the command */
- while (*c==' ') c++; /* Skip mid-word spacing */
- strcpy(strin, c); /* Chop off front of line */
- }
-
- static int get_line(strin, w)
- register char *strin;
- WORLD *w;
- {
- static int comment = 0;
- int quote = 0, start;
- register char *c;
- extern int already_read_header; /* A hack to include characters */
- extern unsigned char header_storage[]; /* that were already read from in */
-
- GET_MORE:
- if (comment) start = 0; else start = -1;
- if (fgets(&strin[already_read_header], MAXLINE, w->inp) == NULL) {
- already_read_header = 0;
- if (comment)
- fprintf(stderr, "WARNING: Line %d: Unterminated comment.\n",w->cur_line);
- return(0); /* EOF */
- }
- already_read_header = 0;
- w->cur_line++;
- for (c=strin; *c; c++) {
- if (*c=='/' && c[1]=='*') { /* Begin of comment */
- if (!quote) {
- if (!comment++) { /* First comment */
- start = (int)(c-strin);
- }
- }
- } else
- if (*c=='*' && c[1]=='/') { /* End of comment */
- if (!quote) {
- comment--;
- if (comment<0) {
- fprintf(stderr, "ERROR! '*/' before '/*'\n*** ABORT ***\n");
- exit(20);
- }
- if (!comment) { /* Chop off front of line */
- strcpy(strin, c+2);
- c = strin-1; /* Pointer will increment */
- }
- }
- } else
- if (*c=='%') { /* Line comment */
- if (!(quote || comment)) {
- *c = '\0'; /* Terminate line */
- break;
- }
- } else
- if (*c =='\"') { /* Quote */
- if (!comment) quote=1-quote; /* Toggle flag */
- } else
- if (*c == '\t') *c = ' '; /* Change tabs to spaces */
- else
- if (!quote && (*c=='[' || *c==']' || *c=='=')) *c = ' ';
- if (*c == '\n') { *c = '\0'; break; }
- }
- if (comment) strin[start] = '\0'; /* Chop off comment */
- /* Skip leading white space to see if this line contains anything */
- for (c=strin; *c==' '; c++) ;
- if (!*c) goto GET_MORE;
- return(1);
- }
-
- static int valid_num;
-
- static long get_num()
- {
- long val = 0;
- char neg = ' ';
- register char *c = &strin[0];
-
- valid_num = 0;
- while (*c == ' ') c++; /* Skip leading space */
- if (*c == '-') neg = *c++; /* Save the negation */
- if (!isdigit(*c)) return(0L);
- while (*c && isdigit(*c))
- val = (val*10) + (*c++ - '0');
- while (*c == ' ') c++; /* Skip trailing space */
- strcpy(strin, c); /* Chop off number */
- valid_num = 1;
- return((neg=='-' ? -val : val));
- }
-
- static int valid_FRACT;
-
- static double get_FRACT()
- {
- register long whole, frac, place;
- register char *s = &strin[0];
- char neg = ' ';
- double f;
-
- valid_FRACT = 0;
- whole = 0;
- while (*s == ' ') s++;
- if (*s == '-') neg = *s++;
- if (!isdigit(*s) && *s!='.') return(0L); /* Invalid FRACT */
- while (*s && isdigit(*s)) /* Handle float before decimal point */
- whole = (whole * 10) + (*s++ - '0');
- if (*s == '.') { /* Handle float after decimal point */
- s++;
- frac = 0;
- for (place=1; *s && isdigit(*s); place*=10)
- frac = (frac * 10) + (*s++ - '0');
- f = (double)whole + ((double)frac/(double)place);
- } else f = (double)whole;
- while (*s == ' ') s++;
- strcpy(strin, s);
- valid_FRACT = 1;
- return((neg=='-' ? -f : f));
- }
-
- static void stuff_XYZ(st)
- XYZ_st *st;
- {
- register char *c = &strin[0];
- register int i, flag, cnt;
-
- flag = 0; /* If they use 'X','Y', or 'Z', they must continue to use it */
- /* On the other hand, if they give only a single parameter, then it applies to all */
- cnt = 0;
- for (i=0; i<3; i++) {
- if (*c=='x' || *c=='X') /* If !valid, it's an ERROR! */
- { *c=' '; st->val[0] = get_FRACT(); if (valid_FRACT) flag=1; }
- else
- if (*c=='y' || *c=='Y')
- { *c=' '; st->val[1] = get_FRACT(); if (valid_FRACT) flag=1; }
- else
- if (*c=='z' || *c=='Z')
- { *c=' '; st->val[2] = get_FRACT(); if (valid_FRACT) flag=1; }
- else if (!flag) {
- st->val[i] = get_FRACT();
- if (valid_FRACT) cnt++;
- }
- }
- if (!flag && cnt==1) { /* Copy value into other two elements */
- st->val[1] = st->val[2] = st->val[0];
- }
- }
-
- static void stuff_RGB(st)
- RGB_st *st;
- {
- register char *c = &strin[0];
- register int i, flag, cnt;
-
- flag = 0; /* If they use 'R','G', or 'B', they must continue to use it */
- /* On the other hand, if they give only a single parameter, then it applies to all */
- cnt = 0;
- for (i=0; i<3; i++) {
- if (*c=='r' || *c=='R') /* If !valid, it's an ERROR! */
- { *c=' '; st->val[0] = get_UBYTE(); if (valid_num) flag=1; }
- else
- if (*c=='g' || *c=='G')
- { *c=' '; st->val[1] = get_UBYTE(); if (valid_num) flag=1; }
- else
- if (*c=='b' || *c=='B')
- { *c=' '; st->val[2] = get_UBYTE(); if (valid_num) flag=1; }
- else if (!flag) {
- st->val[i] = get_UBYTE();
- if (valid_num) cnt++;
- }
- }
- if (!flag && cnt==1) { /* Copy value into other two elements */
- st->val[1] = st->val[2] = st->val[0];
- }
- }
-
- /********************/
- /* The MAIN section */
- /********************/
-
- WORLD *read_TTDDD(file)
- FILE *file;
- {
- char name[5];
- int i;
- WORLD *world;
-
- if (!file) return(0L); /* File not open */
-
- if (!(world = (WORLD*)malloc(sizeof(WORLD)))) { OUT_MEM("WORLD"); }
- bzero((char*)world, sizeof(WORLD));
- world->inp = file;
-
- /* Here is the main loop: */
- while (get_line(strin, world)) {
- parse_word(name, 4, 1); /* And chop it out of the string */
-
- if (strcmp(name, "INFO")==0) process_INFO(world);
- else if (strcmp(name, "OBJ") ==0) process_OBJ(world);
- else {
- fprintf(stderr, "Invalid chunk on line %d: '%s' (skipped)\n",
- world->cur_line, name);
- continue;
- }
- }
-
- /* All done. Close up shop. */
- return(world);
- }
-
- static void process_INFO(world)
- WORLD *world;
- {
- register INFO *info;
- register ULONG i;
- char this_level[MAXLINE], name[5];
-
- if (world->info) {
- fprintf(stderr, "Parse error: More than one INFO chunk!\n"); exit(-1); }
- if (!(info = world->info = (INFO*)malloc(sizeof(INFO)))) { OUT_MEM("INFO"); }
- bzero((char *)world->info, sizeof(INFO));
-
- parse_word(this_level, 0, 1); /* No limit, uppercase. */
- if (strcmp(this_level, "BEGIN") != 0) {
- fprintf(stderr, "WARNING: Line %d: Bad syntax. Missing 'Begin' after 'INFO'\n",
- world->cur_line);
- }
- parse_word(this_level, 0, 0); /* No limit, original case */
-
- while (get_line(strin, world)) {
- parse_word(name, 4, 1); /* Get command */
- if (strcmp(name, "BRSH")==0) {
- i = get_UWORD();
- if (i<0 || i>7) fputs("BRSH error.\n", stderr);
- parse_word(ps, 0, 0);
- strncpy(info->brsh[i], ps, 80);
- info->brsh[i][80]='\0';
- } else
- if (strcmp(name, "STNC")==0) {
- i = get_UWORD();
- if (i<0 || i>7) fputs("STNC error.\n", stderr);
- parse_word(ps, 0, 0);
- strncpy(info->stnc[i], ps, 80);
- info->stnc[i][80]='\0';
- } else
- if (strcmp(name, "TXTR")==0) {
- i = get_UWORD();
- if (i<0 || i>7) fputs("TXTR error.\n", stderr);
- parse_word(ps, 0, 0);
- strncpy(info->txtr[i], ps, 80);
- info->txtr[i][80]='\0';
- } else
- if (strcmp(name, "OBSV")==0) {
- if (!info->obsv) info->obsv=(OBSV*)malloc(sizeof(OBSV));
- if (!info->obsv) { OUT_MEM("OBSV"); }
- parse_word(name, 4, 1); /* Get field */
- if (strcmp(name, "CAME")==0) stuff_XYZ(&info->obsv->came);
- else if (strcmp(name, "ROTA")==0) stuff_XYZ(&info->obsv->rota);
- else if (strcmp(name, "FOCA")==0) info->obsv->foca = get_FRACT();
- else {
- fprintf(stderr, "WARNING: Line %d: Unknown OBSV field: '%s'\n", world->cur_line, name);
- continue;
- }
- } else
- if (strcmp(name, "OTRK")==0) {
- parse_word(ps, 0, 0);
- strncpy(info->otrk, ps, 18);
- info->otrk[18]='\0';
- } else
- if (strcmp(name, "OSTR")==0) {
- if (!info->ostr) info->ostr=(STRY*)malloc(sizeof(STRY));
- if (!info->ostr) { OUT_MEM("OSTR"); }
- parse_word(name, 4, 1); /* Get field */
- if (strcmp(name, "PATH")==0) parse_word(info->ostr->path, 18, 0);
- else if (strcmp(name, "TRAN")==0) stuff_XYZ(&info->ostr->tran);
- else if (strcmp(name, "ROTA")==0) stuff_XYZ(&info->ostr->rota);
- else if (strcmp(name, "SCAL")==0) stuff_XYZ(&info->ostr->scal);
- else
- if (strcmp(name, "INFO")==0) {
- info->ostr->info = 0;
- while (strin[0]) {
- parse_word(ps, 7, 1);
- if (strcmp(ps, "ABS_TRA")==0) info->ostr->info|=(1<<0);
- else if (strcmp(ps, "ABS_ROT")==0) info->ostr->info|=(1<<1);
- else if (strcmp(ps, "ABS_SCL")==0) info->ostr->info|=(1<<2);
- else if (strcmp(ps, "LOC_TRA")==0) info->ostr->info|=(1<<4);
- else if (strcmp(ps, "LOC_ROT")==0) info->ostr->info|=(1<<5);
- else if (strcmp(ps, "LOC_SCL")==0) info->ostr->info|=(1<<6);
- else if (strcmp(ps, "X_ALIGN")==0) info->ostr->info|=(1<<8);
- else if (strcmp(ps, "Y_ALIGN")==0) info->ostr->info|=(1<<9);
- else if (strcmp(ps, "Z_ALIGN")==0) info->ostr->info|=(1<<10);
- else if (strcmp(ps, "FOLLOW_")==0) info->ostr->info|=(1<<12);
- else {
- fprintf(stderr, "WARNING: Line %d: Unknown OSTR INFO flag: '%s'\n", world->cur_line, ps);
- continue;
- }
- }
- } else {
- fprintf(stderr, "WARNING: Line %d: Unknown OSTR field: '%s'\n", world->cur_line, name);
- continue;
- }
- } else
- if (strcmp(name, "FADE")==0) {
- if (!info->fade) info->fade=(FADE*)malloc(sizeof(FADE));
- if (!info->fade) { OUT_MEM("FADE"); }
- parse_word(ps, 6, 1); /* Get field */
- if (strcmp(ps, "FADEAT")==0) info->fade->at = get_FRACT();
- else if (strcmp(ps, "FADEBY")==0) info->fade->by = get_FRACT();
- else if (strcmp(ps, "FADETO")==0) stuff_RGB(&info->fade->to);
- else {
- fprintf(stderr, "WARNING: Line %d: Unknown FADE field: '%s'\n", world->cur_line, ps);
- continue;
- }
- } else
- if (strcmp(name, "SKYC")==0) {
- if (!info->skyc) info->skyc=(SKYC*)malloc(sizeof(SKYC));
- if (!info->skyc) { OUT_MEM("SKYC"); }
- parse_word(name, 4, 1); /* Get field */
- if (strcmp(name, "HORI")==0) stuff_RGB(&info->skyc->hori);
- else if (strcmp(name, "ZENI")==0) stuff_RGB(&info->skyc->zeni);
- else {
- fprintf(stderr, "WARNING: Line %d: Unknown SKYC field: '%s'\n", world->cur_line, name);
- continue;
- }
- } else
- if (strcmp(name, "AMBI")==0) {
- if (!info->ambi) info->ambi=(RGB_st*)malloc(sizeof(RGB_st));
- if (!info->ambi) { OUT_MEM("AMBI"); }
- stuff_RGB(info->ambi);
- } else
- if (strcmp(name, "GLB0")==0) {
- if (!info->glb0) info->glb0=(BYTE*)malloc(8*sizeof(BYTE));
- if (!info->glb0) { OUT_MEM("GLB0"); }
- i = get_ULONG(); /* Index into array */
- if (i>=0 && i<8) {
- info->glb0[i] = (BYTE) get_ULONG();
- } else
- fprintf(stderr, "WARNING: Line %d: Bad index: GLB0[%d] should be [0..7]\n", world->cur_line, i);
- } else if (strcmp(name, "END")==0) {
- parse_word(name, 4, 1);
- if (strcmp(name, "INFO")!=0)
- fprintf(stderr, "WARNING: Line %d: Expected 'END INFO' but got: 'END %s'\n", world->cur_line, name);
- parse_word(ps, 0, 0); /* Get the quote, if any */
- if (strcmp(this_level, ps)!=0)
- fprintf(stderr, "WARNING: Line %d: 'INFO Begin' and 'End INFO' quoted comments do not match\n", world->cur_line);
- break;
- } else fprintf(stderr, "WARNING: Line %d: Unknown INFO sub-sub-chunk: '%s'\n", world->cur_line, name);
- }
- }
-
- OBJECT *create_object()
- {
- OBJECT *p;
- p = (OBJECT*)malloc(sizeof(OBJECT));
- if (!p) { OUT_MEM("Create"); }
- bzero((char*)p,sizeof(OBJECT));
- return(p);
- }
-
- static void process_OBJ(world)
- WORLD *world;
- {
- char this_level[MAXLINE], name[5];
- register OBJECT *p;
- int depth;
-
- parse_word(this_level, 0, 1); /* No limit, uppercase. */
- if (strcmp(this_level, "BEGIN") != 0) {
- fprintf(stderr, "WARNING: Line %d: Bad syntax. Missing 'Begin' after 'OBJ'\n",
- world->cur_line);
- }
- parse_word(this_level, 0, 0); /* No limit, original case */
-
- depth=0;
- while (get_line(strin, world)) {
- parse_word(name, 4, 1); /* Get command */
- if (strcmp(name, "EXTR")==0) {
- p = process_EXTR(create_object(), world);
- if (world->curobj) {
- world->curobj->next = p;
- p->parent = world->curobj->parent;
- } else {
- world->object = p;
- p->parent = 0;
- }
- world->curobj = p;
- } else if (strcmp(name, "DESC")==0) {
- p = create_object();
- if (world->num_DESC > world->num_TOBJ+depth) { /* This is a child */
- depth++; /* Down one in the hierarchy */
- world->curobj->child = p;
- p->parent = world->curobj;
- } else {
- if (world->curobj) {
- world->curobj->next = p;
- p->parent = world->curobj->parent;
- } else {
- world->object = p;
- p->parent = 0;
- }
- }
- world->curobj = p;
- process_DESC(&p->desc, world);
- } else if (strcmp(name, "TOBJ")==0) {
- world->num_TOBJ++;
- if (world->num_TOBJ > world->num_DESC) {
- warn(world->cur_line);
- fprintf(stderr, "TOBJ without DESC. Ignored.\n");
- }
- if (world->num_TOBJ+depth > world->num_DESC) { /* Go back up a level */
- depth--;
- world->curobj=world->curobj->parent;
- }
- } else if (strcmp(name, "END" )==0) {
- if (world->num_DESC > world->num_TOBJ) {
- int i;
- warn(world->cur_line);
- i = world->num_DESC - world->num_TOBJ;
- fprintf(stderr, "Missing %d 'TOBJ'. Inserted.\n", i);
- }
- parse_word(name, 4, 1);
- if (strcmp(name, "OBJ")!=0)
- fprintf(stderr, "WARNING: Line %d: Expected 'END OBJ' but got: 'END %s'\n", world->cur_line, name);
- parse_word(ps, 0, 0); /* Get the quote, if any */
- if (strcmp(this_level, ps)!=0)
- fprintf(stderr, "WARNING: Line %d: 'OBJ Begin' and 'End OBJ' quoted comments do not match\n", world->cur_line);
- break;
- } else
- fprintf(stderr, "WARNING: Line %d: Unknown OBJ sub-sub-chunk: '%s'\n",
- world->cur_line, name);
- }
- }
-
- static OBJECT *process_EXTR(obj, world)
- OBJECT *obj;
- WORLD *world;
- {
- register EXTR *extr;
- register OBJECT *p;
- char this_level[MAXLINE], name[5];
- MTRX *mtrx;
- WORLD *new;
- FILE *newinp;
-
- if (!(extr = obj->extr = (EXTR*)malloc(sizeof(EXTR)))) { OUT_MEM("EXTR"); }
- bzero((char*)extr, sizeof(EXTR));
- mtrx = &extr->mtrx;
- /* Initialize structure */
- mtrx->tran.val[0] = mtrx->tran.val[1] = mtrx->tran.val[2] = 0.0;
- mtrx->scal.val[0] = mtrx->scal.val[1] = mtrx->scal.val[2] = 1.0;
- mtrx->rota1.val[1] = mtrx->rota1.val[2] = 0.0;
- mtrx->rota2.val[0] = mtrx->rota2.val[2] = 0.0;
- mtrx->rota3.val[0] = mtrx->rota3.val[1] = 0.0;
- mtrx->rota1.val[0] = mtrx->rota2.val[1] = mtrx->rota3.val[2] = 1.0;
-
- parse_word(this_level, 0, 1); /* No limit, uppercase. */
- if (strcmp(this_level, "BEGIN") != 0) {
- fprintf(stderr, "WARNING: Line %d: Bad syntax. Missing 'Begin' after 'EXTR'\n",
- world->cur_line);
- }
- parse_word(this_level, 0, 0); /* No limit, original case */
-
- while (get_line(strin, world)) {
- parse_word(name, 4, 1); /* Get command */
- if (strcmp(name, "MTRX")==0) {
- parse_word(name, 4, 1); /* Get field */
- if (strcmp(name, "TRAN")==0) stuff_XYZ(&mtrx->tran);
- else if (strcmp(name, "SCAL")==0) stuff_XYZ(&mtrx->scal);
- else if (strcmp(name, "ROTA")==0) {
- stuff_XYZ(&mtrx->rota1);
- stuff_XYZ(&mtrx->rota2);
- stuff_XYZ(&mtrx->rota3);
- } else {
- fprintf(stderr, "WARNING: Line %d: Unknown MTRX field: '%s'\n", world->cur_line, name);
- continue;
- }
- } else if (strcmp(name, "LOAD")==0) {
- parse_word(extr->filename, 80, 0);
- } else if (strcmp(name, "END" )==0) {
- parse_word(name, 4, 1);
- if (strcmp(name, "EXTR")!=0)
- fprintf(stderr, "WARNING: Line %d: Expected 'END EXTR' but got: 'END %s'\n", world->cur_line, name);
- parse_word(ps, 0, 0); /* Get the quote, if any */
- if (strcmp(this_level, ps)!=0)
- fprintf(stderr, "WARNING: Line %d: 'EXTR Begin' and 'End EXTR' quoted comments do not match\n", world->cur_line);
- break;
- } else fprintf(stderr, "WARNING: Line %d: Unknown EXTR sub-sub-chunk: '%s'\n", world->cur_line, name);
- }
- /* Now, load in the external object */
- if (!(newinp=fopen(extr->filename, "r"))) {
- fprintf(stderr, "Can't load in EXTR object: '%s'... ignored.\n",
- extr->filename);
- return(obj);
- }
- new = read_World(newinp);
- fclose(newinp);
- /* scale, rotate, and translate new object hierarchy */
- for (p=new->object; p; p=p->next)
- move_extr(p, mtrx);
- /* Free up unused memory */
- free((char*)obj->extr);
- free((char*)obj);
- obj = new->object;
- free((char*)new);
- return(obj);
- }
-
- void move_extr(obj, mtrx)
- register OBJECT *obj;
- register MTRX *mtrx;
- {
- register XYZ_st *p;
- register int i;
- register double x, y, z;
- if (obj->desc)
- for (p=obj->desc->pnts,i=obj->desc->pcount; i--; p++) {
- x = (p->val[0]*mtrx->scal.val[0]);
- y = (p->val[1]*mtrx->scal.val[1]);
- z = (p->val[2]*mtrx->scal.val[2]);
- p->val[0] = x*mtrx->rota1.val[0] +
- y*mtrx->rota1.val[1] +
- z*mtrx->rota1.val[2] +
- mtrx->tran.val[0];
- p->val[1] = x*mtrx->rota2.val[0] +
- y*mtrx->rota2.val[1] +
- z*mtrx->rota2.val[2] +
- mtrx->tran.val[1];
- p->val[2] = x*mtrx->rota3.val[0] +
- y*mtrx->rota3.val[1] +
- z*mtrx->rota3.val[2] +
- mtrx->tran.val[2];
- }
- for (obj=obj->child; obj; obj=obj->next)
- move_extr(obj, mtrx); /* Process all children */
- }
-
- void OUT_MEM(s)
- char *s;
- {
- if (s)
- fprintf(stderr, "Ran out of memory while processing '%s'. Sorry.\n", s);
- exit(-1);
- }
-
- static UBYTE defclst[3], defrlst[3], deftlst[3], defspc1[3];
-
- static void process_DESC(orig, world)
- DESC **orig;
- WORLD *world;
- {
- register DESC *desc;
- register int i;
- char this_level[MAXLINE], name[5];
-
- if (!(desc = *orig = (DESC*)malloc(sizeof(DESC)))) { OUT_MEM("DESC"); }
- bzero((char*)desc, sizeof(DESC));
-
- /* Set up defaults: */
- defclst[0] = defclst[1] = defclst[2] = 240; /* TS default */
- defrlst[0] = defrlst[1] = defrlst[2] = 0;
- deftlst[0] = deftlst[1] = deftlst[2] = 0;
- defspc1[0] = defspc1[1] = defspc1[2] = 0;
-
- parse_word(this_level, 0, 1); /* No limit, uppercase. */
- if (strcmp(this_level, "BEGIN") != 0) {
- fprintf(stderr, "WARNING: Line %d: Bad syntax. Missing 'Begin' after 'DESC'\n",
- world->cur_line);
- }
- parse_word(this_level, 0, 0); /* No limit, original case */
-
- world->num_DESC++;
-
- while (get_line(strin, world)) {
- parse_word(name, 4, 1); /* Get command */
- /* Put most-frequent commands near the front of this list */
- if (strcmp(name, "PNTS")==0) {
- parse_word(name, 4, 1); /* Get field */
- if (strcmp(name, "POIN")==0) {
- if (!desc->pcount) {
- fprintf(stderr, "ERROR: Line %d: 'PNTS Point' encountered before 'PNTS PCount'\n", world->cur_line);
- OUT_MEM((char*)0);
- }
- i = get_UWORD();
- if (i<0 || i>=desc->pcount) {
- fprintf(stderr, "WARNING: Line %d: Bad index: PNTS Point[%d] should be [0..%d]\n", world->cur_line, i, desc->pcount);
- continue;
- }
- stuff_XYZ(&desc->pnts[i]);
- } else if (strcmp(name, "PCOU")==0) {
- if (!desc->pcount) {
- desc->pcount = get_UWORD();
- if (!(desc->pnts = (XYZ_st*)malloc(desc->pcount*sizeof(XYZ_st))))
- OUT_MEM("PNTS");
- /* Initialize array */
- for (i=0; i<desc->pcount; i++) {
- desc->pnts[i].val[0] = 0;
- desc->pnts[i].val[1] = 0;
- desc->pnts[i].val[2] = 0;
- }
- } else {
- fprintf(stderr, "WARNING: Line %d: PNTS Pcount defined more than once.\n", world->cur_line);
- }
- } else {
- fprintf(stderr, "WARNING: Line %d: Unknown PNTS field: '%s'\n", world->cur_line, name);
- continue;
- }
- } else
- if (strcmp(name, "EDGE")==0) {
- parse_word(name, 4, 1); /* Get field */
- if (strcmp(name, "EDGE")==0) {
- if (!desc->ecount) {
- fprintf(stderr, "ERROR: Line %d: 'EDGE Edge' encountered before 'EDGE ECount'\n", world->cur_line);
- OUT_MEM((char*)0);
- }
- i = get_UWORD();
- if (i<0 || i>=desc->ecount) {
- fprintf(stderr, "WARNING: Line %d: Bad index: EDGE Edge[%d] should be [0..%d]\n", world->cur_line, i, desc->ecount);
- continue;
- }
- desc->edge[2*i] = get_UWORD();
- desc->edge[2*i+1] = get_UWORD();
- } else if (strcmp(name, "ECOU")==0) {
- if (!desc->ecount) {
- desc->ecount = get_UWORD();
- if (!(desc->edge = (UWORD*)malloc(2*desc->ecount*sizeof(UWORD))))
- OUT_MEM("EDGE");
- /* Initialize array */
- for (i=0; i<2*desc->ecount; i++)
- desc->edge[i] = 0;
- } else {
- fprintf(stderr, "WARNING: Line %d: EDGE Ecount defined more than once.\n", world->cur_line);
- }
- } else {
- fprintf(stderr, "WARNING: Line %d: Unknown EDGE field: '%s'\n", world->cur_line, name);
- continue;
- }
- } else
- if (strcmp(name, "FACE")==0) {
- parse_word(name, 4, 1); /* Get field */
- if (strcmp(name, "CONN")==0) {
- if (!desc->fcount) {
- fprintf(stderr, "ERROR: Line %d: 'FACE Connects' encountered before 'FACE TCount'\n", world->cur_line);
- OUT_MEM((char*)0);
- }
- i = get_UWORD();
- if (i<0 || i>=desc->fcount) {
- fprintf(stderr, "WARNING: Line %d: Bad index: FACE Connects[%d] should be [0..%d]\n", world->cur_line, i, desc->fcount);
- continue;
- }
- desc->face[3*i] = get_UWORD();
- desc->face[3*i+1] = get_UWORD();
- desc->face[3*i+2] = get_UWORD();
- } else if (strcmp(name, "TCOU")==0) {
- i = get_UWORD();
- malloc_arrays(i, desc);
- } else {
- fprintf(stderr, "WARNING: Line %d: Unknown FACE field: '%s'\n", world->cur_line, name);
- continue;
- }
- } else
- if (strcmp(name, "CLST")==0) {
- parse_word(name, 4, 1); /* Get field */
- if (strcmp(name, "COLO")==0) {
- if (!desc->fcount) {
- fprintf(stderr, "ERROR: Line %d: 'CLST Color' encountered before 'CLST Count'\n", world->cur_line);
- OUT_MEM((char*)0);
- }
- i = get_UWORD();
- if (i<0 || i>=desc->fcount) {
- fprintf(stderr, "WARNING: Line %d: Bad index: CLST Color[%d] should be [0..%d]\n", world->cur_line, i, desc->fcount);
- continue;
- }
- stuff_RGB((RGB_st*)&desc->clst[3*i]); /* Place 3 UBYTE's into array */
- } else if (strcmp(name, "COUN")==0) {
- i = get_UWORD();
- malloc_arrays(i, desc);
- } else {
- fprintf(stderr, "WARNING: Line %d: Unknown CLST field: '%s'\n", world->cur_line, name);
- continue;
- }
- } else
- if (strcmp(name, "RLST")==0) {
- parse_word(name, 4, 1); /* Get field */
- if (strcmp(name, "COLO")==0) {
- if (!desc->fcount) {
- fprintf(stderr, "ERROR: Line %d: 'RLST Color' encountered before 'RLST Count'\n", world->cur_line);
- OUT_MEM((char*)0);
- }
- i = get_UWORD();
- if (i<0 || i>=desc->fcount) {
- fprintf(stderr, "WARNING: Line %d: Bad index: RLST Color[%d] should be [0..%d]\n", world->cur_line, i, desc->fcount);
- continue;
- }
- stuff_RGB((RGB_st*)&desc->rlst[3*i]); /* Place three UBYTE's into array */
- } else if (strcmp(name, "COUN")==0) {
- i = get_UWORD();
- malloc_arrays(i, desc);
- } else {
- fprintf(stderr, "WARNING: Line %d: Unknown RLST field: '%s'\n", world->cur_line, name);
- continue;
- }
- } else
- if (strcmp(name, "TLST")==0) {
- parse_word(name, 4, 1); /* Get field */
- if (strcmp(name, "COLO")==0) {
- if (!desc->fcount) {
- fprintf(stderr, "ERROR: Line %d: 'TLST Color' encountered before 'TLST Count'\n", world->cur_line);
- OUT_MEM((char*)0);
- }
- i = get_UWORD();
- if (i<0 || i>=desc->fcount) {
- fprintf(stderr, "WARNING: Line %d: Bad index: TLST Color[%d] should be [0..%d]\n", world->cur_line, i, desc->fcount);
- continue;
- }
- stuff_RGB((RGB_st*)&desc->tlst[3*i]); /* Place three UBYTE's into array */
- } else if (strcmp(name, "COUN")==0) {
- i = get_UWORD();
- malloc_arrays(i, desc);
- } else {
- fprintf(stderr, "WARNING: Line %d: Unknown TLST field: '%s'\n", world->cur_line, name);
- continue;
- }
- } else
- if (strcmp(name, "NAME")==0) {
- parse_word(ps, 0, 0);
- strncpy(desc->name, ps, 18);
- desc->name[18]='\0';
- } else
- if (strcmp(name, "SHAP")==0) {
- if (!desc->shap) {
- if (!(desc->shap=(WORD*)malloc(2*sizeof(WORD))))
- { OUT_MEM("SHAP"); }
- desc->shap[0] = 1; /* TS defaults */
- desc->shap[1] = 0;
- }
- parse_word(name, 4, 1); /* Get field */
- if (strcmp(name, "SHAP")==0) desc->shap[0] = get_UWORD();
- else if (strcmp(name, "LAMP")==0) desc->shap[1] = get_UWORD();
- else {
- fprintf(stderr, "WARNING: Line %d: Unknown SHAP field: '%s'\n", world->cur_line, name);
- continue;
- }
- } else
- if (strcmp(name, "POSI")==0) {
- if (!desc->posi) {
- if (!(desc->posi=(XYZ_st*)malloc(sizeof(XYZ_st))))
- { OUT_MEM("POSI"); }
- }
- stuff_XYZ(desc->posi);
- } else
- if (strcmp(name, "AXIS")==0) {
- if (!desc->axis) {
- if (!(desc->axis=(AXIS*)malloc(sizeof(AXIS))))
- { OUT_MEM("AXIS"); }
- bzero((char*)desc->axis, sizeof(AXIS));
- desc->axis->xaxi.val[0] = 1;
- desc->axis->yaxi.val[1] = 1;
- desc->axis->zaxi.val[2] = 1;
- }
- parse_word(name, 4, 1); /* Get field */
- if (strcmp(name, "XAXI")==0) stuff_XYZ(&desc->axis->xaxi);
- else if (strcmp(name, "YAXI")==0) stuff_XYZ(&desc->axis->yaxi);
- else if (strcmp(name, "ZAXI")==0) stuff_XYZ(&desc->axis->zaxi);
- else {
- fprintf(stderr, "WARNING: Line %d: Unknown AXIS field: '%s'\n", world->cur_line, name);
- continue;
- }
- } else
- if (strcmp(name, "SIZE")==0) {
- if (!desc->size) {
- if (!(desc->size=(XYZ_st*)malloc(sizeof(XYZ_st))))
- { OUT_MEM("SIZE"); }
- }
- stuff_XYZ(desc->size);
- } else
- if (strcmp(name, "COLR")==0) {
- if (!desc->colr) {
- if (!(desc->colr = (RGB_st*)malloc(sizeof(RGB_st))))
- { OUT_MEM("COLR"); }
- }
- stuff_RGB((RGB_st*)&defclst[0]);
- desc->colr->val[0] = defclst[0];
- desc->colr->val[1] = defclst[1];
- desc->colr->val[2] = defclst[2];
- #ifdef DO_I_REALLY_WANT_TO_DO_THIS
- if (desc->fcount) { /* Already initialized... rewrite */
- for (i=3*desc->fcount; i; ) { /* Reverse - efficiency */
- desc->clst[--i] = defclst[2];
- desc->clst[--i] = defclst[1];
- desc->clst[--i] = defclst[0];
- }
- }
- #endif
- } else
- if (strcmp(name, "REFL")==0) {
- if (!desc->refl) {
- if (!(desc->refl = (RGB_st*)malloc(sizeof(RGB_st))))
- { OUT_MEM("REFL"); }
- }
- stuff_RGB((RGB_st*)&defrlst[0]);
- desc->refl->val[0] = defrlst[0];
- desc->refl->val[1] = defrlst[1];
- desc->refl->val[2] = defrlst[2];
- #ifdef DO_I_REALLY_WANT_TO_DO_THIS
- if (desc->fcount) { /* Already initialized... rewrite */
- for (i=3*desc->fcount; i; ) { /* Reverse - efficiency */
- desc->rlst[--i] = defrlst[2];
- desc->rlst[--i] = defrlst[1];
- desc->rlst[--i] = defrlst[0];
- }
- }
- #endif
- } else
- if (strcmp(name, "TRAN")==0) {
- if (!desc->tran) {
- if (!(desc->tran = (RGB_st*)malloc(sizeof(RGB_st))))
- { OUT_MEM("TRAN"); }
- }
- stuff_RGB((RGB_st*)&deftlst[0]);
- desc->tran->val[0] = deftlst[0];
- desc->tran->val[1] = deftlst[1];
- desc->tran->val[2] = deftlst[2];
- #ifdef DO_I_REALLY_WANT_TO_DO_THIS
- if (desc->fcount) { /* Already initialized... rewrite */
- for (i=3*desc->fcount; i; ) { /* Reverse - efficiency */
- desc->tlst[--i] = deftlst[2];
- desc->tlst[--i] = deftlst[1];
- desc->tlst[--i] = deftlst[0];
- }
- }
- #endif
- } else
- if (strcmp(name, "SPC1")==0) {
- if (!desc->spc1) {
- if (!(desc->spc1 = (RGB_st*)malloc(sizeof(RGB_st))))
- { OUT_MEM("SPC1"); }
- }
- stuff_RGB((RGB_st*)&defspc1[0]);
- desc->spc1->val[0] = defspc1[0];
- desc->spc1->val[1] = defspc1[1];
- desc->spc1->val[2] = defspc1[2];
- } else
- if (strcmp(name, "TPAR")==0) {
- if (!desc->tpar) {
- if (!(desc->tpar=(double*)malloc(16*sizeof(double))))
- { OUT_MEM("TPAR"); }
- bzero((char*)desc->tpar, 16*sizeof(double));
- }
- i = get_UWORD();
- if (i<0 || i>15) {
- fprintf(stderr, "WARNING: Line %d: Bad index: TPAR[%d] should be [0..15]\n", world->cur_line, i);
- continue;
- }
- desc->tpar[i] = get_FRACT();
- } else
- if (strcmp(name, "SURF")==0) {
- if (!desc->surf) {
- if (!(desc->surf=(UBYTE*)malloc(5*sizeof(UBYTE))))
- { OUT_MEM("SURF"); }
- bzero((char*)desc->surf, 5*sizeof(UBYTE));
- }
- i = get_UWORD();
- if (i<0 || i>4) {
- fprintf(stderr, "WARNING: Line %d: Bad index: SURF[%d] should be [0..4]\n", world->cur_line, i);
- continue;
- }
- desc->surf[i] = get_UBYTE();
- } else
- if (strcmp(name, "MTTR")==0) {
- if (!desc->mttr) {
- if (!(desc->mttr=(MTTR*)malloc(sizeof(MTTR))))
- { OUT_MEM("MTTR"); }
- bzero((char*)desc->mttr, sizeof(MTTR));
- }
- parse_word(name, 4, 1); /* Get field */
- if (strcmp(name, "TYPE")==0) {
- desc->mttr->type = get_UBYTE();
- if (desc->mttr->type>4) {
- fprintf(stderr, "WARNING: Line %d: Invalid MTTR refraction Type %d. Must be [0..4]\n", world->cur_line, desc->mttr->type);
- desc->mttr->type = 0;
- continue;
- }
- } else if (strcmp(name, "INDE")==0) { /* Must be between 1.0 and 3.55 inclusive */
- desc->mttr->indx = get_FRACT();
- if (desc->mttr->indx<1.0 || desc->mttr->indx>3.55) {
- fprintf(stderr, "WARNING: Line %d: Invalid MTTR Index of refraction. Must be (1.0 - 3.55)\n", world->cur_line);
- desc->mttr->indx = 1.0;
- continue;
- }
- } else {
- fprintf(stderr, "WARNING: Line %d: Unknown MTTR field: '%s'\n", world->cur_line, name);
- continue;
- }
- } else
- if (strcmp(name, "SPEC")==0) {
- if (!desc->spec) {
- if (!(desc->spec=(UBYTE*)malloc(2*sizeof(UBYTE))))
- { OUT_MEM("SPEC"); }
- bzero((char*)desc->spec, 2*sizeof(UBYTE));
- }
- parse_word(name, 4, 1); /* Get field */
- if (strcmp(name, "SPEC")==0) desc->spec[0] = get_UBYTE();
- else if (strcmp(name, "HARD")==0) desc->spec[1] = get_UBYTE();
- else {
- fprintf(stderr, "WARNING: Line %d: Unknown SPEC field: '%s'\n", world->cur_line, name);
- continue;
- }
- } else
- if (strcmp(name, "PRP0")==0) {
- if (!desc->prp0) {
- if (!(desc->prp0=(UBYTE*)malloc(6*sizeof(UBYTE))))
- { OUT_MEM("PRP0"); }
- bzero((char*)desc->prp0, 6*sizeof(UBYTE));
- desc->prp0[0] = 255; /* TS defaults */
- desc->prp0[3] = 1;
- }
- i = get_UWORD();
- if (i<0 || i>5) {
- fprintf(stderr, "WARNING: Line %d: Bad index: PRP0[%d] should be [0..5]\n", world->cur_line, i);
- continue;
- }
- desc->prp0[i] = get_UBYTE();
- } else
- if (strcmp(name, "PRP1")==0) {
- if (!desc->prp1) {
- if (!(desc->prp1=(UBYTE*)malloc(8*sizeof(UBYTE))))
- { OUT_MEM("PRP1"); }
- bzero((char*)desc->prp1, 8*sizeof(UBYTE));
- }
- i = get_UWORD();
- if (i<0 || i>7) {
- fprintf(stderr, "WARNING: Line %d: Bad index: PRP1[%d] should be [0..7]\n", world->cur_line, i);
- continue;
- }
- desc->prp1[i] = get_UBYTE();
- } else
- if (strcmp(name, "INTS")==0) {
- if (!desc->ints) {
- if (!(desc->ints=(double*)malloc(sizeof(double))))
- { OUT_MEM("INTS"); }
- }
- *desc->ints = get_FRACT();
- } else
- if (strcmp(name, "INT1")==0) {
- if (!desc->int1) desc->int1=(RGB_st*)malloc(sizeof(RGB_st));
- if (!desc->int1) { OUT_MEM("INT1"); }
- stuff_RGB(desc->int1);
- } else
- if (strcmp(name, "STRY")==0) {
- parse_word(name, 4, 1); /* Get field */
- if (strcmp(name, "PATH")==0) parse_word(desc->stry->path,18,0);
- else if (strcmp(name, "TRAN")==0) stuff_XYZ(&desc->stry->tran);
- else if (strcmp(name, "ROTA")==0) stuff_XYZ(&desc->stry->rota);
- else if (strcmp(name, "SCAL")==0) stuff_XYZ(&desc->stry->scal);
- else
- if (strcmp(name, "INFO")==0) {
- desc->stry->info = 0;
- while (strin[0]) {
- parse_word(ps, 7, 1);
- if (strcmp(ps, "ABS_TRA")==0) desc->stry->info|=(1<<0);
- else if (strcmp(ps, "ABS_ROT")==0) desc->stry->info|=(1<<1);
- else if (strcmp(ps, "ABS_SCL")==0) desc->stry->info|=(1<<2);
- else if (strcmp(ps, "LOC_TRA")==0) desc->stry->info|=(1<<4);
- else if (strcmp(ps, "LOC_ROT")==0) desc->stry->info|=(1<<5);
- else if (strcmp(ps, "LOC_SCL")==0) desc->stry->info|=(1<<6);
- else if (strcmp(ps, "X_ALIGN")==0) desc->stry->info|=(1<<8);
- else if (strcmp(ps, "Y_ALIGN")==0) desc->stry->info|=(1<<9);
- else if (strcmp(ps, "Z_ALIGN")==0) desc->stry->info|=(1<<10);
- else if (strcmp(ps, "FOLLOW_")==0) desc->stry->info|=(1<<12);
- else {
- fprintf(stderr, "WARNING: Line %d: Unknown STRY INFO flag: '%s'\n", world->cur_line, ps);
- continue;
- }
- }
- } else {
- fprintf(stderr, "WARNING: Line %d: Unknown STRY field: '%s'\n", world->cur_line, name);
- continue;
- }
- } else
- if (strcmp(name, "END")==0) {
- parse_word(name, 4, 1);
- if (strcmp(name, "DESC")!=0)
- fprintf(stderr, "WARNING: Line %d: Expected 'END DESC' but got: 'END %s'\n", world->cur_line, name);
- parse_word(ps, 0, 0); /* Get the quote, if any */
- if (strcmp(this_level, ps)!=0)
- fprintf(stderr, "WARNING: Line %d: 'DESC Begin' and 'End DESC' quoted comments do not match\n", world->cur_line);
- break;
- } else fprintf(stderr, "WARNING: Line %d: Unknown DESC sub-sub-chunk: '%s'\n", world->cur_line, name);
- }
- }
-
-