home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
- #ifdef __TURBOC__
- #include <alloc.h>
- #else
- #include <malloc.h>
- #endif
- #include "fractint.h"
- #include "prototyp.h"
- #include "lsys.h"
-
- struct lsys_cmd {
- void (*f)(struct lsys_turtlestatei *);
- long n;
- char ch;
- };
-
- static int _fastcall readLSystemFile(char *);
- static void _fastcall free_rules_mem(void);
- static int _fastcall save_rule(char *,char far **);
- static void free_lcmds(void);
- static struct lsys_cmd far * _fastcall findsize(struct lsys_cmd far *,struct lsys_turtlestatei *, struct lsys_cmd far **,int);
- static struct lsys_cmd far * drawLSysI(struct lsys_cmd far *command,struct lsys_turtlestatei *ts, struct lsys_cmd far **rules,int depth);
- static int lsysi_findscale(struct lsys_cmd far *command, struct lsys_turtlestatei *ts, struct lsys_cmd far **rules, int depth);
- static struct lsys_cmd far *LSysISizeTransform(char far *s, struct lsys_turtlestatei *ts);
- static struct lsys_cmd far *LSysIDrawTransform(char far *s, struct lsys_turtlestatei *ts);
- static void _fastcall lsysi_dosincos(void);
-
- static void lsysi_doslash(struct lsys_turtlestatei *cmd);
- static void lsysi_dobslash(struct lsys_turtlestatei *cmd);
- static void lsysi_doat(struct lsys_turtlestatei *cmd);
- static void lsysi_dopipe(struct lsys_turtlestatei *cmd);
- static void lsysi_dosizedm(struct lsys_turtlestatei *cmd);
- static void lsysi_dosizegf(struct lsys_turtlestatei *cmd);
- static void lsysi_dodrawd(struct lsys_turtlestatei *cmd);
- static void lsysi_dodrawm(struct lsys_turtlestatei *cmd);
- static void lsysi_dodrawg(struct lsys_turtlestatei *cmd);
- static void lsysi_dodrawf(struct lsys_turtlestatei *cmd);
- static void lsysi_dodrawc(struct lsys_turtlestatei *cmd);
- static void lsysi_dodrawgt(struct lsys_turtlestatei *cmd);
- static void lsysi_dodrawlt(struct lsys_turtlestatei *cmd);
-
- /* Some notes to Adrian from PB, made when I integrated with v15:
- printfs changed to work with new user interface
- bug at end of readLSystemFile, the line which said rulind=0 fixed
- to say *rulind=0
- the calloc was not worthwhile, it was just for a 54 byte area, cheaper
- to keep it as a static; but there was a static 201 char buffer I
- changed to not be static
- use of strdup was a nono, caused problems running out of space cause
- the memory allocated each time was never freed; I've changed to
- use far memory and to free when done
- */
-
- #define sins ((long *)(boxy))
- #define coss (((long *)(boxy)+50)) /* 50 after the start of sins */
- static char far *ruleptrs[MAXRULES];
- static struct lsys_cmd far *rules2[MAXRULES];
- char maxangle;
- static char loaded=0;
-
-
- int _fastcall ispow2(int n)
- {
- return (n == (n & -n));
- }
-
- LDBL _fastcall getnumber(char far **str)
- {
- char numstr[30];
- LDBL ret;
- int i,root,inverse;
-
- root=0;
- inverse=0;
- strcpy(numstr,"");
- (*str)++;
- switch (**str)
- {
- case 'q':
- root=1;
- (*str)++;
- break;
- case 'i':
- inverse=1;
- (*str)++;
- break;
- }
- switch (**str)
- {
- case 'q':
- root=1;
- (*str)++;
- break;
- case 'i':
- inverse=1;
- (*str)++;
- break;
- }
- i=0;
- while ((**str<='9' && **str>='0') || **str=='.')
- {
- numstr[i++]= **str;
- (*str)++;
- }
- (*str)--;
- numstr[i]=0;
- ret=atof(numstr);
- if (ret <= 0.0) /* this is a sanity check, JCO 8/31/94 */
- return 0;
- if (root)
- ret=sqrtl(ret);
- if (inverse)
- ret = 1.0/ret;
- return ret;
- }
-
- static int _fastcall readLSystemFile(char *str)
- {
- int c;
- char far **rulind;
- int err=0;
- int linenum,check=0;
- char inline[161],fixed[161],*word;
- FILE *infile;
- char msgbuf[481]; /* enough for 6 full lines */
-
- if (find_file_item(LFileName,str,&infile) < 0)
- return -1;
- while ((c = fgetc(infile)) != '{')
- if (c == EOF) return -1;
- maxangle=0;
- for(linenum=0;linenum<MAXRULES;++linenum) ruleptrs[linenum]=NULL;
- rulind= &ruleptrs[1];
- msgbuf[0]=(char)(linenum=0);
-
- while(file_gets(inline,160,infile) > -1) /* Max line length 160 chars */
- {
- linenum++;
- if ((word = strchr(inline,';')) != NULL) /* strip comment */
- *word = 0;
- strlwr(inline);
-
- if (strspn(inline," \t\n") < strlen(inline)) /* not a blank line */
- {
- word=strtok(inline," =\t\n");
- if (!strcmp(word,"axiom"))
- {
- if (save_rule(strtok(NULL," \t\n"),&ruleptrs[0])) {
- strcat(msgbuf,"Error: out of memory\n");
- ++err;
- break;
- }
- check=1;
- }
- else if (!strcmp(word,"angle"))
- {
- maxangle=(char)atoi(strtok(NULL," \t\n"));
- check=1;
- }
- else if (!strcmp(word,"}"))
- break;
- else if (strcspn(word,"+-/\\@|!c<>][") == 0 && strlen(word) == 1)
- {
- sprintf(&msgbuf[strlen(msgbuf)],
- "Syntax error line %d: Redefined reserved symbol %s\n",linenum,word);
- ++err;
- break;
- }
- else if (strlen(word)==1)
- {
- strcat(strcpy(fixed,word),strtok(NULL," \t\n"));
- if (save_rule(fixed,rulind++)) {
- strcat(msgbuf, "Error: out of memory\n");
- ++err;
- break;
- }
- check=1;
- }
- else
- if (err<6)
- {
- sprintf(&msgbuf[strlen(msgbuf)],
- "Syntax error line %d: %s\n",linenum,word);
- ++err;
- }
- if (check)
- {
- check=0;
- if((word=strtok(NULL," \t\n"))!=NULL)
- if (err<6)
- {
- sprintf(&msgbuf[strlen(msgbuf)],
- "Extra text after command line %d: %s\n",linenum,word);
- ++err;
- }
- }
- }
- }
- fclose(infile);
- if (!ruleptrs[0] && err<6)
- {
- strcat(msgbuf,"Error: no axiom\n");
- ++err;
- }
- if ((maxangle<3||maxangle>50) && err<6)
- {
- strcat(msgbuf,"Error: illegal or missing angle\n");
- ++err;
- }
- if (err)
- {
- msgbuf[strlen(msgbuf)-1]=0; /* strip trailing \n */
- stopmsg(0,msgbuf);
- return -1;
- }
- *rulind=NULL;
- return 0;
- }
-
- int Lsystem(void)
- {
- int order;
- char far **rulesc;
- struct lsys_cmd far **sc;
- int stackoflow = 0;
-
- if ( (!loaded) && LLoad())
- return -1;
-
- overflow = 0; /* reset integer math overflow flag */
-
- order=(int)param[0];
- if (order<=0)
- order=0;
- if (usr_floatflag)
- overflow = 1;
- else {
- struct lsys_turtlestatei ts;
-
- ts.stackoflow = 0;
- ts.maxangle = maxangle;
- ts.dmaxangle = (char)(maxangle - 1);
-
- sc = rules2;
- for (rulesc = ruleptrs; *rulesc; rulesc++)
- *sc++ = LSysISizeTransform(*rulesc, &ts);
- *sc = NULL;
-
- lsysi_dosincos();
- if (lsysi_findscale(rules2[0], &ts, &rules2[1], order)) {
- ts.realangle = ts.angle = ts.reverse = 0;
-
- free_lcmds();
- sc = rules2;
- for (rulesc = ruleptrs; *rulesc; rulesc++)
- *sc++ = LSysIDrawTransform(*rulesc, &ts);
- *sc = NULL;
-
- /* !! HOW ABOUT A BETTER WAY OF PICKING THE DEFAULT DRAWING COLOR */
- if ((ts.curcolor=15) > colors)
- ts.curcolor=(char)(colors-1);
- drawLSysI(rules2[0], &ts, &rules2[1], order);
- }
- stackoflow = ts.stackoflow;
- }
-
- if (stackoflow) {
- static char far msg[]={"insufficient memory, try a lower order"};
- stopmsg(0,msg);
- }
- else if (overflow) {
- struct lsys_turtlestatef ts;
-
- overflow = 0;
-
- ts.stackoflow = 0;
- ts.maxangle = maxangle;
- ts.dmaxangle = (char)(maxangle - 1);
-
- sc = rules2;
- for (rulesc = ruleptrs; *rulesc; rulesc++)
- *sc++ = LSysFSizeTransform(*rulesc, &ts);
- *sc = NULL;
-
- lsysf_dosincos();
- if (lsysf_findscale(rules2[0], &ts, &rules2[1], order)) {
- ts.realangle = ts.angle = ts.reverse = 0;
-
- free_lcmds();
- sc = rules2;
- for (rulesc = ruleptrs; *rulesc; rulesc++)
- *sc++ = LSysFDrawTransform(*rulesc, &ts);
- *sc = NULL;
-
- /* !! HOW ABOUT A BETTER WAY OF PICKING THE DEFAULT DRAWING COLOR */
- if ((ts.curcolor=15) > colors)
- ts.curcolor=(char)(colors-1);
- lsys_prepfpu(&ts);
- drawLSysF(rules2[0], &ts, &rules2[1], order);
- lsys_donefpu(&ts);
- }
- overflow = 0;
- }
- free_rules_mem();
- free_lcmds();
- loaded=0;
- return 0;
- }
-
- int LLoad(void)
- {
- if (readLSystemFile(LName)) { /* error occurred */
- free_rules_mem();
- loaded=0;
- return -1;
- }
- loaded=1;
- return 0;
- }
-
- static void _fastcall free_rules_mem(void)
- {
- int i;
- for(i=0;i<MAXRULES;++i)
- if(ruleptrs[i]) farmemfree(ruleptrs[i]);
- }
-
- static int _fastcall save_rule(char *rule,char far **saveptr)
- {
- int i;
- char far *tmpfar;
- i=strlen(rule)+1;
- if((tmpfar=farmemalloc((long)i))==NULL) {
- return -1;
- }
- *saveptr=tmpfar;
- while(--i>=0) *(tmpfar++)= *(rule++);
- return 0;
- }
-
- static void free_lcmds(void)
- {
- struct lsys_cmd far **sc = rules2;
-
- while (*sc)
- farmemfree(*sc++);
- }
-
-
-
- #ifdef XFRACT
- #define lsysi_doslash_386 lsysi_doslash
- #define lsysi_dobslash_386 lsysi_dobslash
- #define lsys_doat lsysi_doat
- #define lsys_dosizegf lsysi_dosizegf
- #define lsys_dodrawg lsysi_dodrawg
- void lsys_prepfpu(struct lsys_turtlestatef *x) { }
- void lsys_donefpu(struct lsys_turtlestatef *x) { }
- #endif
-
- /* integer specific routines */
-
- #ifdef XFRACT
- static void lsysi_doplus(struct lsys_turtlestatei *cmd)
- {
- if (cmd->reverse) {
- if (++cmd->angle == cmd->maxangle)
- cmd->angle = 0;
- }
- else {
- if (cmd->angle)
- cmd->angle--;
- else
- cmd->angle = cmd->dmaxangle;
- }
- }
- #else
- extern void lsysi_doplus(struct lsys_turtlestatei *cmd);
- #endif
-
- #ifdef XFRACT
- /* This is the same as lsys_doplus, except maxangle is a power of 2. */
- static void lsysi_doplus_pow2(struct lsys_turtlestatei *cmd)
- {
- if (cmd->reverse) {
- cmd->angle++;
- cmd->angle &= cmd->dmaxangle;
- }
- else {
- cmd->angle--;
- cmd->angle &= cmd->dmaxangle;
- }
- }
- #else
- extern void lsysi_doplus_pow2(struct lsys_turtlestatei *cmd);
- #endif
-
- #ifdef XFRACT
- static void lsysi_dominus(struct lsys_turtlestatei *cmd)
- {
- if (cmd->reverse) {
- if (cmd->angle)
- cmd->angle--;
- else
- cmd->angle = cmd->dmaxangle;
- }
- else {
- if (++cmd->angle == cmd->maxangle)
- cmd->angle = 0;
- }
- }
- #else
- extern void lsysi_dominus(struct lsys_turtlestatei *cmd);
- #endif
-
- #ifdef XFRACT
- static void lsysi_dominus_pow2(struct lsys_turtlestatei *cmd)
- {
- if (cmd->reverse) {
- cmd->angle--;
- cmd->angle &= cmd->dmaxangle;
- }
- else {
- cmd->angle++;
- cmd->angle &= cmd->dmaxangle;
- }
- }
- #else
- extern void lsysi_dominus_pow2(struct lsys_turtlestatei *cmd);
- #endif
-
- static void lsysi_doslash(struct lsys_turtlestatei *cmd)
- {
- if (cmd->reverse)
- cmd->realangle -= cmd->num;
- else
- cmd->realangle += cmd->num;
- }
-
- #ifndef XFRACT
- extern void lsysi_doslash_386(struct lsys_turtlestatei *cmd);
- #endif
-
- static void lsysi_dobslash(struct lsys_turtlestatei *cmd)
- {
- if (cmd->reverse)
- cmd->realangle += cmd->num;
- else
- cmd->realangle -= cmd->num;
- }
-
- #ifndef XFRACT
- extern void lsysi_dobslash_386(struct lsys_turtlestatei *cmd);
- #endif
-
- static void lsysi_doat(struct lsys_turtlestatei *cmd)
- {
- cmd->size = multiply(cmd->size, cmd->num, 19);
- }
-
- static void lsysi_dopipe(struct lsys_turtlestatei *cmd)
- {
- cmd->angle = (char)(cmd->angle + (char)(cmd->maxangle / 2));
- cmd->angle %= cmd->maxangle;
- }
-
- #ifdef XFRACT
- static void lsysi_dopipe_pow2(struct lsys_turtlestatei *cmd)
- {
- cmd->angle += cmd->maxangle >> 1;
- cmd->angle &= cmd->dmaxangle;
- }
- #else
- extern void lsysi_dopipe_pow2(struct lsys_turtlestatei *cmd);
- #endif
-
- #ifdef XFRACT
- static void lsysi_dobang(struct lsys_turtlestatei *cmd)
- {
- cmd->reverse = ! cmd->reverse;
- }
- #else
- extern void lsysi_dobang(struct lsys_turtlestatei *cmd);
- #endif
-
- static void lsysi_dosizedm(struct lsys_turtlestatei *cmd)
- {
- double angle = (double) cmd->realangle * ANGLE2DOUBLE;
- double s, c;
- long fixedsin, fixedcos;
-
- FPUsincos(&angle, &s, &c);
- fixedsin = (long) (s * FIXEDLT1);
- fixedcos = (long) (c * FIXEDLT1);
-
- cmd->xpos = cmd->xpos + (multiply(multiply(cmd->size, cmd->aspect, 19), fixedcos, 29));
- cmd->ypos = cmd->ypos + (multiply(cmd->size, fixedsin, 29));
-
- /* xpos+=size*aspect*cos(realangle*PI/180); */
- /* ypos+=size*sin(realangle*PI/180); */
- if (cmd->xpos>cmd->xmax) cmd->xmax=cmd->xpos;
- if (cmd->ypos>cmd->ymax) cmd->ymax=cmd->ypos;
- if (cmd->xpos<cmd->xmin) cmd->xmin=cmd->xpos;
- if (cmd->ypos<cmd->ymin) cmd->ymin=cmd->ypos;
- }
-
- static void lsysi_dosizegf(struct lsys_turtlestatei *cmd)
- {
- cmd->xpos = cmd->xpos + (multiply(cmd->size, coss[cmd->angle], 29));
- cmd->ypos = cmd->ypos + (multiply(cmd->size, sins[cmd->angle], 29));
- /* xpos+=size*coss[angle]; */
- /* ypos+=size*sins[angle]; */
- if (cmd->xpos>cmd->xmax) cmd->xmax=cmd->xpos;
- if (cmd->ypos>cmd->ymax) cmd->ymax=cmd->ypos;
- if (cmd->xpos<cmd->xmin) cmd->xmin=cmd->xpos;
- if (cmd->ypos<cmd->ymin) cmd->ymin=cmd->ypos;
- }
-
- static void lsysi_dodrawd(struct lsys_turtlestatei *cmd)
- {
- double angle = (double) cmd->realangle * ANGLE2DOUBLE;
- double s, c;
- long fixedsin, fixedcos;
- int lastx, lasty;
-
- FPUsincos(&angle, &s, &c);
- fixedsin = (long) (s * FIXEDLT1);
- fixedcos = (long) (c * FIXEDLT1);
-
- lastx=(int) (cmd->xpos >> 19);
- lasty=(int) (cmd->ypos >> 19);
- cmd->xpos = cmd->xpos + (multiply(multiply(cmd->size, cmd->aspect, 19), fixedcos, 29));
- cmd->ypos = cmd->ypos + (multiply(cmd->size, fixedsin, 29));
- /* xpos+=size*aspect*cos(realangle*PI/180); */
- /* ypos+=size*sin(realangle*PI/180); */
- draw_line(lastx,lasty,(int)(cmd->xpos >> 19),(int)(cmd->ypos >> 19),cmd->curcolor);
- }
-
- static void lsysi_dodrawm(struct lsys_turtlestatei *cmd)
- {
- double angle = (double) cmd->realangle * ANGLE2DOUBLE;
- double s, c;
- long fixedsin, fixedcos;
-
- FPUsincos(&angle, &s, &c);
- fixedsin = (long) (s * FIXEDLT1);
- fixedcos = (long) (c * FIXEDLT1);
-
- /* xpos+=size*aspect*cos(realangle*PI/180); */
- /* ypos+=size*sin(realangle*PI/180); */
- cmd->xpos = cmd->xpos + (multiply(multiply(cmd->size, cmd->aspect, 19), fixedcos, 29));
- cmd->ypos = cmd->ypos + (multiply(cmd->size, fixedsin, 29));
- }
-
- static void lsysi_dodrawg(struct lsys_turtlestatei *cmd)
- {
- cmd->xpos = cmd->xpos + (multiply(cmd->size, coss[cmd->angle], 29));
- cmd->ypos = cmd->ypos + (multiply(cmd->size, sins[cmd->angle], 29));
- /* xpos+=size*coss[angle]; */
- /* ypos+=size*sins[angle]; */
- }
-
- static void lsysi_dodrawf(struct lsys_turtlestatei *cmd)
- {
- int lastx = (int) (cmd->xpos >> 19);
- int lasty = (int) (cmd->ypos >> 19);
- cmd->xpos = cmd->xpos + (multiply(cmd->size, coss[cmd->angle], 29));
- cmd->ypos = cmd->ypos + (multiply(cmd->size, sins[cmd->angle], 29));
- /* xpos+=size*coss[angle]; */
- /* ypos+=size*sins[angle]; */
- draw_line(lastx,lasty,(int)(cmd->xpos >> 19),(int)(cmd->ypos >> 19),cmd->curcolor);
- }
-
- static void lsysi_dodrawc(struct lsys_turtlestatei *cmd)
- {
- cmd->curcolor = (char)(((int) cmd->num) % colors);
- }
-
- static void lsysi_dodrawgt(struct lsys_turtlestatei *cmd)
- {
- cmd->curcolor = (char)(cmd->curcolor - (char)cmd->num);
- if ((cmd->curcolor %= colors) == 0)
- cmd->curcolor = (char)(colors-1);
- }
-
- static void lsysi_dodrawlt(struct lsys_turtlestatei *cmd)
- {
- cmd->curcolor = (char)(cmd->curcolor + (char)cmd->num);
- if ((cmd->curcolor %= colors) == 0)
- cmd->curcolor = 1;
- }
-
- static struct lsys_cmd far * _fastcall
- findsize(struct lsys_cmd far *command, struct lsys_turtlestatei *ts, struct lsys_cmd far **rules, int depth)
- {
- struct lsys_cmd far **rulind;
- int tran;
-
- if (overflow) /* integer math routines overflowed */
- return NULL;
-
- #ifndef __TURBOC__
- if (stackavail() < 400) { /* leave some margin for calling subrtns */
- ts->stackoflow = 1;
- return NULL;
- }
- #endif
-
- while (command->ch && command->ch !=']') {
- if (! (ts->counter++)) {
- /* let user know we're not dead */
- if (thinking(1,"L-System thinking (higher orders take longer)")) {
- ts->counter--;
- return NULL;
- }
- }
- tran=0;
- if (depth) {
- for(rulind=rules;*rulind;rulind++)
- if ((*rulind)->ch==command->ch) {
- tran=1;
- if (findsize((*rulind)+1,ts,rules,depth-1) == NULL)
- return(NULL);
- }
- }
- if (!depth || !tran) {
- if (command->f) {
- ts->num = command->n;
- (*command->f)(ts);
- }
- else if (command->ch == '[') {
- char saveang,saverev;
- long savesize,savex,savey;
- unsigned long saverang;
-
- saveang=ts->angle;
- saverev=ts->reverse;
- savesize=ts->size;
- saverang=ts->realangle;
- savex=ts->xpos;
- savey=ts->ypos;
- if ((command=findsize(command+1,ts,rules,depth)) == NULL)
- return(NULL);
- ts->angle=saveang;
- ts->reverse=saverev;
- ts->size=savesize;
- ts->realangle=saverang;
- ts->xpos=savex;
- ts->ypos=savey;
- }
- }
- command++;
- }
- return command;
- }
-
- static int
- lsysi_findscale(struct lsys_cmd far *command, struct lsys_turtlestatei *ts, struct lsys_cmd far **rules, int depth)
- {
- float horiz,vert;
- double xmin, xmax, ymin, ymax;
- double locsize;
- double locaspect;
- struct lsys_cmd far *fsret;
-
- locaspect=screenaspect*xdots/ydots;
- ts->aspect = FIXEDPT(locaspect);
- ts->xpos =
- ts->ypos =
- ts->xmin =
- ts->xmax =
- ts->ymax =
- ts->ymin =
- ts->realangle =
- ts->angle =
- ts->reverse =
- ts->counter = 0;
- ts->size=FIXEDPT(1L);
- fsret = findsize(command,ts,rules,depth);
- thinking(0, NULL); /* erase thinking message if any */
- xmin = (double) ts->xmin / FIXEDMUL;
- xmax = (double) ts->xmax / FIXEDMUL;
- ymin = (double) ts->ymin / FIXEDMUL;
- ymax = (double) ts->ymax / FIXEDMUL;
- if (fsret == NULL)
- return 0;
- if (xmax == xmin)
- horiz = (float)1E37;
- else
- horiz = (float)((xdots-10)/(xmax-xmin));
- if (ymax == ymin)
- vert = (float)1E37;
- else
- vert = (float)((ydots-6) /(ymax-ymin));
- locsize = (vert<horiz) ? vert : horiz;
-
- if (horiz == 1E37)
- ts->xpos = FIXEDPT(xdots/2);
- else
- /* ts->xpos = FIXEDPT(-xmin*(locsize)+5+((xdots-10)-(locsize)*(xmax-xmin))/2); */
- ts->xpos = FIXEDPT((xdots-locsize*(xmax+xmin))/2);
- if (vert == 1E37)
- ts->ypos = FIXEDPT(ydots/2);
- else
- /* ts->ypos = FIXEDPT(-ymin*(locsize)+3+((ydots-6)-(locsize)*(ymax-ymin))/2); */
- ts->ypos = FIXEDPT((ydots-locsize*(ymax+ymin))/2);
- ts->size = FIXEDPT(locsize);
-
- return 1;
- }
-
- static struct lsys_cmd far *
- drawLSysI(struct lsys_cmd far *command,struct lsys_turtlestatei *ts, struct lsys_cmd far **rules,int depth)
- {
- struct lsys_cmd far **rulind;
- int tran;
-
- if (overflow) /* integer math routines overflowed */
- return NULL;
-
- #ifndef __TURBOC__
- if (stackavail() < 400) { /* leave some margin for calling subrtns */
- ts->stackoflow = 1;
- return NULL;
- }
- #endif
-
- while (command->ch && command->ch !=']') {
- if (!(ts->counter++)) {
- if (keypressed()) {
- ts->counter--;
- return NULL;
- }
- }
- tran=0;
- if (depth) {
- for(rulind=rules;*rulind;rulind++)
- if ((*rulind)->ch == command->ch) {
- tran=1;
- if (drawLSysI((*rulind)+1,ts,rules,depth-1) == NULL)
- return NULL;
- }
- }
- if (!depth||!tran) {
- if (command->f) {
- ts->num = command->n;
- (*command->f)(ts);
- }
- else if (command->ch == '[') {
- char saveang,saverev,savecolor;
- long savesize,savex,savey;
- unsigned long saverang;
-
- saveang=ts->angle;
- saverev=ts->reverse;
- savesize=ts->size;
- saverang=ts->realangle;
- savex=ts->xpos;
- savey=ts->ypos;
- savecolor=ts->curcolor;
- if ((command=drawLSysI(command+1,ts,rules,depth)) == NULL)
- return(NULL);
- ts->angle=saveang;
- ts->reverse=saverev;
- ts->size=savesize;
- ts->realangle=saverang;
- ts->xpos=savex;
- ts->ypos=savey;
- ts->curcolor=savecolor;
- }
- }
- command++;
- }
- return command;
- }
-
- static struct lsys_cmd far *
- LSysISizeTransform(char far *s, struct lsys_turtlestatei *ts)
- {
- struct lsys_cmd far *ret;
- struct lsys_cmd far *doub;
- int maxval = 10;
- int n = 0;
- void (*f)();
- long num;
-
- void (*plus)() = (ispow2(ts->maxangle)) ? lsysi_doplus_pow2 : lsysi_doplus;
- void (*minus)() = (ispow2(ts->maxangle)) ? lsysi_dominus_pow2 : lsysi_dominus;
- void (*pipe)() = (ispow2(ts->maxangle)) ? lsysi_dopipe_pow2 : lsysi_dopipe;
-
- void (*slash)() = (cpu >= 386) ? lsysi_doslash_386 : lsysi_doslash;
- void (*bslash)() = (cpu >= 386) ? lsysi_dobslash_386 : lsysi_dobslash;
- void (*at)() = (cpu >= 386) ? lsysi_doat_386 : lsysi_doat;
- void (*dogf)() = (cpu >= 386) ? lsysi_dosizegf_386 : lsysi_dosizegf;
-
- ret = (struct lsys_cmd far *) farmemalloc((long) maxval * sizeof(struct lsys_cmd));
- if (ret == NULL) {
- ts->stackoflow = 1;
- return NULL;
- }
- while (*s) {
- f = NULL;
- num = 0;
- ret[n].ch = *s;
- switch (*s) {
- case '+': f = plus; break;
- case '-': f = minus; break;
- case '/': f = slash; num = (long) (getnumber(&s) * 11930465L); break;
- case '\\': f = bslash; num = (long) (getnumber(&s) * 11930465L); break;
- case '@': f = at; num = FIXEDPT(getnumber(&s)); break;
- case '|': f = pipe; break;
- case '!': f = lsysi_dobang; break;
- case 'd':
- case 'm': f = lsysi_dosizedm; break;
- case 'g':
- case 'f': f = dogf; break;
- case '[': num = 1; break;
- case ']': num = 2; break;
- default:
- num = 3;
- break;
- }
- #ifdef XFRACT
- ret[n].f = (void (*)())f;
- #else
- ret[n].f = (void (*)(struct lsys_turtlestatei *))f;
- #endif
- ret[n].n = num;
- if (++n == maxval) {
- doub = (struct lsys_cmd far *) farmemalloc((long) maxval*2*sizeof(struct lsys_cmd));
- if (doub == NULL) {
- farmemfree(ret);
- ts->stackoflow = 1;
- return NULL;
- }
- far_memcpy(doub, ret, maxval*sizeof(struct lsys_cmd));
- farmemfree(ret);
- ret = doub;
- maxval <<= 1;
- }
- s++;
- }
- ret[n].ch = 0;
- ret[n].f = NULL;
- ret[n].n = 0;
- n++;
-
- doub = (struct lsys_cmd far *) farmemalloc((long) n*sizeof(struct lsys_cmd));
- if (doub == NULL) {
- farmemfree(ret);
- ts->stackoflow = 1;
- return NULL;
- }
- far_memcpy(doub, ret, n*sizeof(struct lsys_cmd));
- farmemfree(ret);
- return doub;
- }
-
- static struct lsys_cmd far *
- LSysIDrawTransform(char far *s, struct lsys_turtlestatei *ts)
- {
- struct lsys_cmd far *ret;
- struct lsys_cmd far *doub;
- int maxval = 10;
- int n = 0;
- void (*f)();
- long num;
-
- void (*plus)() = (ispow2(ts->maxangle)) ? lsysi_doplus_pow2 : lsysi_doplus;
- void (*minus)() = (ispow2(ts->maxangle)) ? lsysi_dominus_pow2 : lsysi_dominus;
- void (*pipe)() = (ispow2(ts->maxangle)) ? lsysi_dopipe_pow2 : lsysi_dopipe;
-
- void (*slash)() = (cpu >= 386) ? lsysi_doslash_386 : lsysi_doslash;
- void (*bslash)() = (cpu >= 386) ? lsysi_dobslash_386 : lsysi_dobslash;
- void (*at)() = (cpu >= 386) ? lsysi_doat_386 : lsysi_doat;
- void (*drawg)() = (cpu >= 386) ? lsysi_dodrawg_386 : lsysi_dodrawg;
-
- ret = (struct lsys_cmd far *) farmemalloc((long) maxval * sizeof(struct lsys_cmd));
- if (ret == NULL) {
- ts->stackoflow = 1;
- return NULL;
- }
- while (*s) {
- f = NULL;
- num = 0;
- ret[n].ch = *s;
- switch (*s) {
- case '+': f = plus; break;
- case '-': f = minus; break;
- case '/': f = slash; num = (long) (getnumber(&s) * 11930465L); break;
- case '\\': f = bslash; num = (long) (getnumber(&s) * 11930465L); break;
- case '@': f = at; num = FIXEDPT(getnumber(&s)); break;
- case '|': f = pipe; break;
- case '!': f = lsysi_dobang; break;
- case 'd': f = lsysi_dodrawd; break;
- case 'm': f = lsysi_dodrawm; break;
- case 'g': f = drawg; break;
- case 'f': f = lsysi_dodrawf; break;
- case 'c': f = lsysi_dodrawc; num = (long) getnumber(&s); break;
- case '<': f = lsysi_dodrawlt; num = (long) getnumber(&s); break;
- case '>': f = lsysi_dodrawgt; num = (long) getnumber(&s); break;
- case '[': num = 1; break;
- case ']': num = 2; break;
- default:
- num = 3;
- break;
- }
- #ifdef XFRACT
- ret[n].f = (void (*)())f;
- #else
- ret[n].f = (void (*)(struct lsys_turtlestatei *))f;
- #endif
- ret[n].n = num;
- if (++n == maxval) {
- doub = (struct lsys_cmd far *) farmemalloc((long) maxval*2*sizeof(struct lsys_cmd));
- if (doub == NULL) {
- farmemfree(ret);
- ts->stackoflow = 1;
- return NULL;
- }
- far_memcpy(doub, ret, maxval*sizeof(struct lsys_cmd));
- farmemfree(ret);
- ret = doub;
- maxval <<= 1;
- }
- s++;
- }
- ret[n].ch = 0;
- ret[n].f = NULL;
- ret[n].n = 0;
- n++;
-
- doub = (struct lsys_cmd far *) farmemalloc((long) n*sizeof(struct lsys_cmd));
- if (doub == NULL) {
- farmemfree(ret);
- ts->stackoflow = 1;
- return NULL;
- }
- far_memcpy(doub, ret, n*sizeof(struct lsys_cmd));
- farmemfree(ret);
- return doub;
- }
-
- static void _fastcall lsysi_dosincos(void)
- {
- double locaspect;
- double TWOPI = 2.0 * PI;
- double twopimax;
- double twopimaxi;
- double s, c;
- int i;
-
- locaspect=screenaspect*xdots/ydots;
- twopimax = TWOPI / maxangle;
- for(i=0;i<maxangle;i++) {
- twopimaxi = i * twopimax;
- FPUsincos(&twopimaxi, &s, &c);
- sins[i] = (long) (s * FIXEDLT1);
- coss[i] = (long) ((locaspect * c) * FIXEDLT1);
- }
- }
-