1 /* curve.c
2    Original code by rlk
3    Additional code by Dave
4    code cleanup by paxed
5 */
6 
7 #include <ctype.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <math.h>
12 #include <time.h>
13 
14 /*
15 
16   To compile this on unixen, do
17 
18     cc -lm curve.c -o curve
19 
20  */
21 
22 #define MAX_HELP_TXTS 17
23 
24 #ifndef M_PI
25 #define M_PI 3.14159265358979323846
26 #endif
27 
28 int thickness;
29 int usesteps;
30 int totalstep;
31 int innerdrop, outerdrop, hill;
32 int ct;
33 int r2,r3;
34 int manual;
35 int seed;
36 int lots;
37 int iter;
38 
39 char toptex[256];
40 char intex [256];
41 char outtex[256];
42 char bottex[256];
43 char blanktex[256];
44 
45 const char *helptxt[MAX_HELP_TXTS] = {
46     /* 0: nothing */ "",
47 
48     /* 1: inner radius */
49     "   -The inner radius can be any number from zero on up.\n"
50     "   -You might choose a value of 0, if you wanted to do a disc-shaped\n"
51     "    platform, or filled circle (you could join all of the lumps\n"
52     "    together in gtkradiant to keep the lump count low...)",
53 
54     /* 2: outer radius */
55     "   -The outer radius can be any number as long as it is larger than\n"
56     "    the inner radius.",
57 
58     /* 3: choice on radii */
59     "   -You may specify an entirely different set of radii for the ending\n"
60     "    portion of your curve. If you do so, it will be smoothly transitioned\n"
61     "    between the beginning and the end.\n"
62     "   -By using this feature, it is easy to create swirls, and spirals.",
63 
64     /* 4: ending inner radius */
65     "   -The ending inner radius can be any number from zero on up.\n"
66     "   -It can smaller than, larger than, or exactly equal to the\n"
67     "    beginning inner radius.",
68 
69     /* 5: ending outer radius */
70     "   -The ending outer radius can be any number as long as it is\n"
71     "    larger than the ending inner radius.\n"
72     "   -It can smaller than, larger than, or exactly equal to the\n"
73     "    beginning outer radius.",
74 
75     /* 6: number of lumps */
76     "   -The number of lumps will determine the \"coarseness\" of the curve.\n"
77     "    Less lumps = coarser    -    More lumps = smoother\n"
78     "    Be careful not to use too many lumps, though, as this can actually\n"
79     "    lead to certain sloped curves being even more coarse due to the alignment\n"
80     "    on the 1-unit grid.\n"
81     "   -If you go into the \"advanced\" curve settings, the number of lumps you\n"
82     "    specify in this step will be doubled, as each lump will be split into\n"
83     "    two triangular sections. This can be desirable even when you are not going\n"
84     "    to create a sloped/angled/hilled curve, if you plan on rotating your curve\n"
85     "    in gtkradiant in some other fashion than the typical 90-degree angles.",
86 
87     /* 7: beginning angle */
88     "   -The beginning angle is given in degrees and can be any value(+ or -).",
89 
90     /* 8: ending radius */
91     "   -The ending angle is given in degrees and can be any value(+ or -).\n"
92     "   -You can specify greater than 360 degrees, most useful for creating spirals-\n"
93     "    simple \"snail-shell\"-style spirals, or sloped \"cork screw\"-style spirals.",
94 
95     /* 9: thickness */
96     "   -Thickness can be any value greater than zero.\n"
97     "   -If you plan on doing an angled curve(with inner or outer drop), or hill,\n"
98     "    you should take into account how much drop or hill value you desire, as\n"
99     "    that figure will be subtracted from the thickness you specify in this step.",
100 
101     /* 10: advanced or not? */
102     "   -In the advanced settings, you can specify slope, inner an outer drop,\n"
103     "    hill value, and whether or not to use constant thickness.\n"
104     "   -Also, if you go into the advanced settings section of the questions, the\n"
105     "    number of lumps will automatically double, as each lump will be split in\n"
106     "    two triangular pieces.\n"
107     "   -You do not have to use any of the advanced settings available if you\n"
108     "    go into that section - you might just want the lumps split in two.\n"
109     "    This is useful if you plan on rotating your curve in some other fashion\n"
110     "    than the typical 90-degree angles.",
111 
112     /* 11: slope */
113     "   -The slope of the curve specifies the number of vertical units total,\n"
114     "    from the start to the end, that you wish the curve to ascend or descend.\n"
115     "   -This number can be positive(ascend), negative(descend), or zero.\n"
116     "   -Best results are achieved when the number of units specified in this step\n"
117     "    is a multiple of the number of lumps (e.g. lumps = 8, slope = 64),\n"
118     "    although it will still produce a very even slope if the numbers don't\n"
119     "    have this relationship.\n"
120     "   -To create a loop de loop, simply create a sloped, 360 degree curve where\n"
121     "    the slope value is higher than the thickness of the curve.\n"
122     "    Then rotate it on the x or y axis in gtkradiant.",
123 
124     /* 12: inner drop */
125     "   -Inner drop must be at least one unit smaller than the thickness value.\n"
126     "    It can also be zero.\n"
127     "   -This determines how much to \"drop\" the inner, top portion of the curve.\n"
128     "    This results in a curve which is angled inwards.\n"
129     "   -You can combine this option with the \"hill\" option to get banked curves,\n"
130     "    similar to those you might find at a race-track.",
131 
132     /* 13: outer drop */
133     "   -Outer drop must be at least one unit smaller than the thickness value.\n"
134     "    It can also be zero.\n"
135     "   -This determines how much to \"drop\" the outer, top portion of the curve.\n"
136     "    This results in a curve which is angled outwards.",
137 
138     /* 14: hill */
139     "   -Hill must be at least one unit smaller than the thickness value.\n"
140     "    It can also be zero.\n"
141     "   -This figure determines how much to lower the ends of the curve. They will\n"
142     "    rise from the ends toward the middle, in a smooth sine-wave shaped hill.\n"
143     "   -This can be combined with the inner or outer drop option, creating a \"hill\"\n"
144     "    which rises on only one side. In this case, it is best to use the same\n"
145     "    value for \"hill\" as you did for inner or outer drop.",
146 
147     /* 15: constant thickness */
148     "   -By default, the curve generator will attempt to give a constant thickness\n"
149     "    in the lumps, by raising or lowering opposite corners by similar amounts.\n"
150     "   -By deselecting this feature, the bottom portions of the lump will not be\n"
151     "    adjusted, which can be desirable for variety of reasons, which is why\n"
152     "    this option is available.\n"
153     "   -The best way to understand how this feature works is to create either\n"
154     "    an angled(inner or outer drop) or hill-shaped curve, and do one with\n"
155     "    constant thickness on, and then another one with it turned off.",
156 
157     /* 16: filename */
158     "   -It is recommended to end your filename with \".map\", so that you can\n"
159     "    import immediately into gtkradiant. You can, of course, rename the file\n"
160     "    manually after it is created.\n"
161     "   -Do not include spaces when entering the filename, or your filename will\n"
162     "    only be that which occurs before the first space.\n"
163     "   -If you specify a filename which already exists, it will be overwritten.\n"
164     "    Be aware that if you have already imported that file into gtkradiant,\n"
165     "    you will either need to rename the file, or close and re-open your map,\n"
166     "    in order to avoid the \"cached\" version of the file used by gtkradiant."
167 };
168 
showhelp(int which)169 void showhelp(int which)
170 {
171     if (which > 0 && which < MAX_HELP_TXTS)
172 	printf("\n%s\n\n", helptxt[which]);
173 }
174 
showusage(FILE * fp,char * fn)175 void showusage(FILE *fp, char *fn)
176 {
177     fprintf(fp, "Usage: %s <r0> <r1> <n> <a0> <a1> <t> <r2> <r3> <s> <id> <od> <h> <ct> \n"
178                         "r0 - inner radius\n"
179                         "r1 - outer radius\n"
180                         "n  - number of lumps (will be doubled if sloped,angled,or hill-shaped)\n"
181                         "a0 - beginning angle\n"
182                         "a1 - ending angle\n"
183                         "t  - thickness of curve\n"
184                         "r2 - ending inner radius(can be >,<, or = r0)\n"
185                         "r3 - ending outer radius(can be >,<, or = r1)\n"
186                         "s  - vertical slope from beginning to end\n"
187                         "id - vertical drop of curve's inner radius(inward angled)\n"
188                         "od - vertical drop of curve's outer radius(outward angled)\n"
189                         "h  - vertical drop for both ends of curve (hill)\n"
190                         "ct - zero will override default of constant thickness for angle/hill curves\n",fn );
191 
192     return ;
193 }
194 
195 int
get_input_num(char * name,int defaultval,int helpnum,int minval,int maxval,int * retval)196 get_input_num(char *name, int defaultval, int helpnum, int minval, int maxval, int *retval)
197 {
198     char str[80];
199     int i;
200 
201     for (;;) {
202 	printf("\nPlease enter %s (default = %d) -> ", name, defaultval);
203 	scanf("%s", str);
204 
205 	if (str[0] == 'x') return 1;
206 
207 	if (str[0] == '?') showhelp(helpnum);
208 	else if (isdigit(str[0]) || (str[0] == '-') || str[0] == 'd') {
209 	    if (str[0] == 'd') i = defaultval;
210 	    else i = atoi(str);
211 	    if (i < minval || i > maxval) printf("Please enter \"?\", \"x\", \"d\" or an integer value between %d and %d.", minval, maxval);
212 	    else {
213 		*retval = i;
214 		return 0;
215 	    }
216 	} else printf("Please enter \"?\", \"x\", \"d\" or an integer value between %d and %d.", minval, maxval);
217     }
218 }
219 
220 char
get_input_yn(char * question,char defval,int helpnum)221 get_input_yn(char *question, char defval, int helpnum)
222 {
223     char str[80];
224 
225     for (;;) {
226 	printf("\n%s? (y/n/?) -> ", question);
227 	scanf("%s", str);
228 
229 	if (str[0] == '?') showhelp(helpnum);
230 	else if (str[0] == 'y' || str[0] == 'n') return str[0];
231 	else return defval;
232     }
233 }
234 
rndnum(int low,int high)235 static int rndnum(int low, int high)
236 {
237     if (seed == 0)
238     {
239         srand((unsigned int) time(NULL));
240         seed = 1;
241     }
242 
243     return (rand() % ((high-low) +1)) + low;
244 }
245 
side(double x0,double y0,double z0,double x1,double y1,double z1,double x2,double y2,double z2,char * tex)246 static void side(double x0, double y0, double z0,
247                  double x1, double y1, double z1,
248                  double x2, double y2, double z2, char *tex)
249 {
250     double modx, mody, modz; /*for doing a grid of curves*/
251     modx = 0;
252     mody = 0;
253     modz = 0;
254 
255     if (lots > 1)
256     {
257         int row = iter / 4;
258         int col = iter % 4;
259         modz = ((row + col) % 2) * 256.0;
260         modx = row * 768.0;
261         mody = col * 768.0;
262     }
263     printf("( %f %f %f ) ( %f %f %f ) ( %f %f %f ) "
264            "%s 0 0 0 0.500000 0.500000 0 0 0\n",
265            x0+modx, y0+mody, z0+modz,
266            x1+modx, y1+mody, z1+modz,
267            x2+modx, y2+mody, z2+modz, tex);
268 }
269 
lump(int r0,int r1,double a0,double a1,int i,int n)270 static void lump(int r0, int r1, double a0, double a1, int i, int n)
271 {
272     double x00 = (r0+((double)(r2-r0)*((i)/(double)n))) * cos(M_PI * a0 / 180.0);
273     double y00 = (r0+((double)(r2-r0)*((i)/(double)n))) * sin(M_PI * a0 / 180.0);
274 
275     double x10 = (r1+((double)(r3-r1)*((i)/(double)n))) * cos(M_PI * a0 / 180.0);
276     double y10 = (r1+((double)(r3-r1)*((i)/(double)n))) * sin(M_PI * a0 / 180.0);
277 
278     double x01 = (r0+((double)(r2-r0)*((i+1.0f)/(double)n))) * cos(M_PI * a1 / 180.0);
279     double y01 = (r0+((double)(r2-r0)*((i+1.0f)/(double)n))) * sin(M_PI * a1 / 180.0);
280 
281     double x11 = (r1+((double)(r3-r1)*((i+1.0f)/(double)n))) * cos(M_PI * a1 / 180.0);
282     double y11 = (r1+((double)(r3-r1)*((i+1.0f)/(double)n))) * sin(M_PI * a1 / 180.0);
283 
284     double z0  = 0;
285     double z1  = thickness;
286 
287     printf("{\n");
288 
289     if (!usesteps)
290     {
291         /*just use rlk's code    */
292         side(x00, y00, z0, x01, y01, z0, x00, y00, z1, intex);
293         side(x10, y10, z1, x11, y11, z1, x10, y10, z0, outtex);
294         side(x00, y00, z1, x10, y10, z1, x00, y00, z0, blanktex);
295         side(x01, y01, z0, x11, y11, z0, x01, y01, z1, blanktex);
296 
297         side(0, 0, z0, 1, 0, z0, 0, 1, z0, bottex);
298         side(0, 0, z1, 0, 1, z1, 1, 0, z1, toptex);
299     }
300     else
301     {
302         /*use Dave's code! */
303         double stepsize = totalstep/(double)n;
304         double zmod0=(double)i * stepsize;
305         double zmod1=(double)(i+1) * stepsize; /*this goes up!  */
306         double hillmodinside=0,hillmodoutside=0;
307         double hmi2=0,hmo2=0;
308         double cthi1=0,cthi2=0,ctho1=0,ctho2=0;
309 
310         if (hill != 0)
311         {
312             /*do one based on sinewave. */
313             double mult1=((sin((((360.0f/(double)n)*(double)i)-90.0) * M_PI / 180.0)+1.0)/2.0);
314             double mult2=((sin((((360.0f/(double)n)*(double)(i+1))-90.0) * M_PI / 180.0)+1.0)/2.0);
315             if (innerdrop>=outerdrop)
316             {
317                 /*then it's the outside needs altered   */
318                 hillmodoutside=hill-(mult1*(double)hill) ;
319                 hmo2=hill-(mult2*(double)hill) ;
320                 ctho1=hill-hillmodoutside;
321                 ctho2=hill-hmo2;
322             }
323             if (outerdrop>=innerdrop)
324             {
325                 hillmodinside=hill-(mult1*(double)hill) ;
326                 hmi2=hill-(mult2*(double)hill) ;
327                 cthi1=hill-hillmodinside;
328                 cthi2=hill-hmi2;
329             }
330                /*end of sinewave hill code*/
331             if (innerdrop>outerdrop)
332             {
333                 cthi1-=hillmodoutside; cthi2-=hmo2;
334                 ctho1=0; ctho2=0;
335             }
336              if (outerdrop>innerdrop )
337                          {ctho1-=hillmodinside; ctho2-=hmi2;
338                           cthi1=0; cthi2=0; }
339         } /*end of "hill" code */
340 
341         /*
342             00 is bottom left
343             10 is bottom right
344             11 is top right
345             01 is top left
346         */
347 
348         side(x11, y11, ((z1+zmod1)-outerdrop)-hmo2,             x10, y10, ((z1+zmod0)-outerdrop)-hillmodoutside, x00, y00, ((z1+zmod0)-innerdrop)-hillmodinside, toptex);
349         side(x00, y00, z0+zmod0+((outerdrop+ctho1)*ct),         x10, y10, z0+zmod0+((innerdrop+cthi1)*ct),      x11, y11, z0+zmod1+((innerdrop+cthi2)*ct),       bottex);
350         side(x11, y11, ((z1+zmod1)-outerdrop)-hmo2,             x11, y11, z0+zmod1+((innerdrop+cthi2)*ct),      x10, y10, z0+zmod0+((innerdrop+cthi1)*ct),       outtex);
351         side(x10, y10, ((z1+zmod0)-outerdrop)-hillmodoutside,   x10, y10, z0+zmod0+((innerdrop+cthi1)*ct),      x00, y00, z0+zmod0+((outerdrop+ctho1)*ct),       blanktex);
352         side(x11, y11, ((z1+zmod1)-outerdrop)-hmo2,             x00, y00, z0+zmod0+((outerdrop+ctho1)*ct),      x11, y11, z0+zmod1+((innerdrop+cthi2)*ct),       blanktex);
353 
354         printf("}\n{\n"); /*next one...   */
355 
356         side(x00, y00, ((z1+zmod0)-innerdrop)-hillmodinside,    x01, y01, ((z1+zmod1)-innerdrop)-hmi2,          x11, y11, ((z1+zmod1)-outerdrop)-hmo2,           toptex);
357         side(x11, y11, z0+zmod1+((innerdrop+cthi2)*ct),         x01, y01, z0+zmod1+((outerdrop+ctho2)*ct),      x00, y00, z0+zmod0+((outerdrop+ctho1)*ct),       bottex);
358         side(x00, y00, ((z1+zmod0)-innerdrop)-hillmodinside,    x00, y00, z0+zmod0+((outerdrop+ctho1)*ct),      x01, y01, z0+zmod1+((outerdrop+ctho2)*ct),       intex);
359         side(x01, y01, ((z1+zmod1)-innerdrop)-hmi2,             x01, y01, z0+zmod1+((outerdrop+ctho2)*ct),      x11, y11, z0+zmod1+((innerdrop+cthi2)*ct),       blanktex);
360         side(x00, y00, ((z1+zmod0)-innerdrop)-hillmodinside,    x11, y11, z0+zmod1+((innerdrop+cthi2)*ct),      x00, y00, z0+zmod0+((outerdrop+ctho1)*ct),       blanktex);
361 
362          /*end of Dave's code! */
363     }
364 
365     printf("}\n");
366 }
367 
gettextures(void)368 void gettextures(void)
369 {
370     /*default = mtrl/invisible*/
371     FILE *fp;
372     char c1[256],c2[256];
373 
374     strcpy(toptex,"mtrl/invisible");
375     strcpy(bottex,"mtrl/invisible");
376     strcpy(intex, "mtrl/invisible");
377     strcpy(outtex,"mtrl/invisible");
378     strcpy(blanktex,"mtrl/invisible");
379 
380     fp = fopen("textures.txt","r");
381     if (fp)
382     {
383         int i;
384         int huh;
385         for (i = 0; i<4; i++)
386         {
387             huh = fscanf(fp,"%s %s",c1,c2);
388             if (huh == 2)
389             {
390                 if (strcmp(c1,"TOP") == 0) sprintf(toptex,"mtrl/%s",c2);
391                 if (strcmp(c1,"BOT") == 0) sprintf(bottex,"mtrl/%s",c2);
392                 if (strcmp(c1,"IN") == 0)  sprintf(intex, "mtrl/%s",c2);
393                 if (strcmp(c1,"OUT") == 0) sprintf(outtex,"mtrl/%s",c2);
394             }
395             else
396                 break;
397         }
398         fclose(fp);
399     }
400 }
401 
main(int argc,char * argv[])402 int main(int argc, char *argv[])
403 {
404     int i     = 0 ;
405     int r0    = 128;
406     int r1    = 256;
407     int n     = 8;
408     int a0    = 0;
409     int a1    = 90;
410     thickness = 16;
411     usesteps  = 0;
412     totalstep = 0;
413     innerdrop = 0;
414     outerdrop = 0;
415     hill      = 0;
416     ct        = 1;
417     r2        = 128;
418     r3        = 256;
419 	manual    = 0;
420 
421     lots      = 0;
422     seed      = 0;
423     iter      = 0;
424 
425     if (argc > 1 && strcmp(argv[1], "-?") == 0)
426     {
427         showusage(stderr, argv[0]);
428         fprintf(stderr, "\nOther ways to use this program :\n"
429                         "%s -? : This help screen.\n"
430                         "%s -readme   : creates a readme.txt file with detailed help information.\n"
431                         "%s -textures : creates a textures.txt, editable for auto-texture placement.\n"
432                         "%s -random   : creates a random curve; add -lots for a grid of 16 curves.\n"
433                         "%s : (no parameters) runs a basic user-interface to aid your curve creation.\n",
434                         argv[0],argv[0],argv[0],argv[0],argv[0]);
435     }
436     else if (argc > 1 && strcmp(argv[1], "-readme") == 0)
437     {
438         fprintf(stderr, "Detailed information about each setting has been placed in readme.txt\n");
439         freopen("readme.txt", "w" ,stdout);
440         showusage(stdout,argv[0]);
441         for ( i=0; i<MAX_HELP_TXTS; i++) showhelp(i);
442     }
443     else if (argc > 1 && strcmp(argv[1], "-textures") == 0)
444     {
445         FILE *f;
446         fprintf(stderr, "textures.txt can be edited to specify the textures that you wish to apply to\n"
447                         "the top, bottom, inside, and outside of the subsequently generated curves.");
448         f = fopen("textures.txt", "w");
449         fprintf(f,"TOP invisible\n"
450                   "BOT invisible\n"
451                   "IN invisible\n"
452                   "OUT invisible");
453         fclose(f);
454     }
455     else
456     {
457         if (argc == 1)
458         {
459             /*Engage the so called user-interface... */
460             char str[80];
461             int okay = 0;
462 	    int retval = 0;
463 	    char ynchar;
464             manual = 1;
465 
466             printf("During the input process, typing a lowercase \"x\" and pressing Enter will\n");
467 	    printf("  accept the default for that question and all of the remaining questions,\n"
468 		   "  and proceed to the file output step.\n");
469 	    printf("Typing \"d\" and Enter will accept the default for that particular question.\n");
470 	    printf("Typing a \"?\" and pressing Enter will give you a description of that variable.\n\n");
471 
472 	    okay = get_input_num("INNER RADIUS", r0, 1, 0, 65536, &retval);
473 	    if (okay) goto getfilename;
474 	    r0 = retval; r2 = r0;
475 
476 	    okay = get_input_num("OUTER RADIUS", r1, 2, r0+1, 65535, &retval);
477 	    if (okay) goto getfilename;
478 	    r1 = retval; r3 = r1;
479 
480 	    ynchar = get_input_yn("Do you wish to have the same radii from beginning to end", 'y', 3);
481 	    if (ynchar == 'n') {
482 		okay = get_input_num("ENDING INNER RADIUS", r2, 4, 0, 65535, &retval);
483 		if (okay) goto getfilename;
484 		r2 = retval;
485 
486 		okay = get_input_num("ENDING OUTER RADIUS", r3, 5, r2+1, 65535, &retval);
487 		if (okay) goto getfilename;
488 		r3 = retval;
489 	    }
490 
491 	    okay = get_input_num("NUMBER OF LUMPS", n, 6, 1, 65535, &retval);
492 	    if (okay) goto getfilename;
493 	    n = retval;
494 
495 	    okay = get_input_num("BEGINNING ANGLE", a0, 7, -65535, 65535, &retval);
496 	    if (okay) goto getfilename;
497 	    a0 = retval;
498 
499 	    okay = get_input_num("ENDING ANGLE", a1, 8, -65535, 65535, &retval);
500 	    if (okay) goto getfilename;
501 	    a1 = retval;
502 
503 	    okay = get_input_num("THICKNESS", thickness, 9, 1, 65536, &retval);
504 	    if (okay) goto getfilename;
505 	    thickness = retval;
506 
507 	    ynchar = get_input_yn("Do you wish to use any advanced curve settings", 'n', 10);
508 	    if (ynchar == 'n') goto getfilename;
509 
510 	    okay = get_input_num("SLOPE", totalstep, 11, -65535, 65535, &retval);
511 	    usesteps = 1;
512 	    if (okay) goto getfilename;
513 	    totalstep = retval;
514 
515 	    okay = get_input_num("INNER DROP", innerdrop, 12, 0, thickness - 1, &retval);
516 	    if (okay) goto getfilename;
517 	    innerdrop = retval;
518 
519 	    okay = get_input_num("OUTER DROP", outerdrop, 13, 0, thickness - 1, &retval);
520 	    if (okay) goto getfilename;
521 	    outerdrop = retval;
522 
523 	    okay = get_input_num("HILL", hill, 14, 0, thickness - 1, &retval);
524 	    if (okay) goto getfilename;
525 	    hill = retval;
526 
527 	    ynchar = get_input_yn("Would you like to use the CONSTANT THICKNESS feature", 'y', 15);
528 	    ct = (ynchar == 'y') ? 1 : 0;
529 
530 getfilename:
531 
532 	    do {
533 		okay=0;
534 		printf("\nPlease enter filename for your curve -> ");
535 		scanf("%s",str);
536 		if (str[0]=='?')
537 		    showhelp(16);
538 		else
539 		    okay=1; /*accept what they typed...  */
540 	    } while (okay!=1);
541 
542 	    freopen(str, "w", stdout); /*setup stdout redirect */
543 
544         } /* end of interactive user input */
545         else
546         {
547             if (strcmp(argv[1],"-random") != 0)
548             { /* use the command line inputs...  */
549                 if (argc > 1)
550                 {
551                     r0 = atoi(argv[1]); r2=r0;
552                 }
553                 if (argc > 2)
554                 {
555                     r1 = atoi(argv[2]); r3=r1;
556                 }
557                 if (argc > 3)
558                     n  = atoi(argv[3]);
559                 if (argc > 4)
560                     a0 = atoi(argv[4]);
561                 if (argc > 5)
562                     a1 = atoi(argv[5]);
563                 if (argc > 6)
564                     thickness = atoi(argv[6]);
565                 if (argc > 7)
566                     r2=atoi(argv[7]);
567                 if (argc > 8)
568                     r3=atoi(argv[8]);
569                 if (argc > 9)
570                 {   /*can specify 0, for segmentation, but no slope.  */
571                     totalstep = atoi(argv[9]); usesteps=1;
572                 }
573                 if (argc >10)
574                     innerdrop= atoi(argv[10]);
575                 if (argc >11)
576                     outerdrop= atoi(argv[11]);
577                 if (argc >12)
578                     hill= atoi(argv[12]);
579                 if (argc >13)
580                     ct=atoi(argv[13]); /*any non-zero number keeps curves constant thickness.. */
581                 if (ct!=0)
582                     ct=1;
583             }
584             else
585             {
586                 /*it's the random curve generator */
587                 lots = 1; /*just an indicator that we need a random number*/
588                 if ((argc > 2) && (strcmp(argv[2],"-lots")==0))
589                     lots = 16;
590             }
591 
592         } /* end of command line input  */
593 
594         do
595         {
596             if (lots > 0)
597             {
598                 r0 = rndnum(0, 256/8) * 8; r2=r0;
599 
600                 r1 = r0 + rndnum(8/8, 256/8) * 8; r3=r1;
601 
602                 if (rndnum(1,100)<=40)
603                     r2 = rndnum(0,256/8) * 8;
604                 if (rndnum(1,100)<=40)
605                     r3 = r2 + rndnum(8/8,256/8) * 8;
606 
607                 a0 = rndnum(0,7) * 45;
608                 a1 = a0 + (rndnum(2,16) * 45);
609 
610                 n = (a1-a0) / 12;
611 
612                 if (rndnum(1,100)<=50)
613                     thickness = rndnum(8/8,64/8) * 8;
614                 else
615                     thickness = rndnum(1,2) * 128;
616 
617                 if (rndnum(1,100)<=40)
618                     totalstep = rndnum(1,16) * 32;
619                 else
620                     totalstep = 0;
621 
622                 innerdrop = 0;
623                 outerdrop = 0;
624                 if (rndnum(1,100)<=40)
625                 {
626                     if (rndnum(1,100)<=50)
627                     {
628                         if (thickness>8)
629                         {
630                             innerdrop = rndnum(1,(thickness - 8)/8) * 8;
631                             usesteps = 1;
632                         }
633                     }
634                     else
635                     {
636                         if (thickness>8)
637                         {
638                             outerdrop = rndnum(1,(thickness - 8)/8) * 8;
639                             usesteps = 1;
640                         }
641                     }
642                 }
643 
644                 hill = 0;
645                 if (rndnum(1,100)<=40)
646                 {
647                     if (thickness>16)
648                     {
649                         hill = rndnum(2,(thickness - 16)/8) * 8;
650                         usesteps = 1;
651                     }
652                 }
653 
654                 ct = 1;
655                 if (rndnum(1,100)<=25)
656                     ct=0;
657             }
658 
659             printf("{\n");
660             printf("\"classname\" \"worldspawn\"\n");
661             printf("// This curve was created with the following parameters :\n"
662                    "// curve %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
663                    r0,r1,n,a0,a1,thickness,r2,r3,totalstep,innerdrop,outerdrop,hill,ct);
664             gettextures();
665             for (i = 0; i < n; i++)
666             {
667                 double ai0 = (double) (i    ) * (a1 - a0) / n + a0;
668                 double ai1 = (double) (i + 1) * (a1 - a0) / n + a0;
669 
670                 lump(r0, r1, ai0, ai1, i, n);
671             }
672             printf("}\n");
673 
674             iter += 1;
675         } while (iter < lots);
676     }
677     return 0;
678 }
679