1 %{
2 #include <math.h>		/* For math functions, cos(), sin(), etc. */
3 #include <time.h>
4 #include "ou.h"
5 
6 
7     void yyerror(char *s);
8     void SetUpRings(int, char *, float, float, float),
9 	SetUpAtmosphere(int, char *, float, int),
10         SetUpBody(int, char *, int),
11 	SetUpAsteroid(int, char *),
12 	SetUpOrbiter(int, char *),
13 	SetUpSpaceShip(int, char *),
14 	SetUpComet(int, char *, float, float, int),
15 	InitSun(char *, double, int);
16     int yylex(void);
17     int yylineno = 0;
18     int body_index = 1, last_planet = 0, last_satellite = 0, currblock =
19 	PLANET;
20     double v[3];
21     extern planetdata planets[MAXBODIES];
22     extern FILE *cfgin;
23     extern GLenum smodel;
24     extern int border, filter, paused, demomode, demostep, plabels, slabels,
25         realtime, cmode, currtarget, currsource, jpeg_quality, mipmap, info,
26         mipmap_filter, fonttype, LOD, tex_compr, color_depth;
27     extern GLenum cd_rgb, cd_lum, cd_rgba, cd_luma;
28     extern float speed, star_mag;
29     struct tm date;
30 %}
31 
32 %union {
33     int ival;
34     double dval;
35     char name[100];
36 }
37 
38 %token < ival > INTEGER_NUM
39 %token < dval > DOUBLE_NUM
40 %token < name > NAME
41 %token < name > SUN PLANET ASTEROID COMET SATELLITE ORBITER SPACESHIP RING ATMOSPHERE
42 %token < name > SPLASHBITMAP BORDER FILTER SHADING SIM_DATE PAUSE REALTIME
43 %token < name > PLANETS_LABELS STARS_LABELS INFO STAR_BRIGHT STAR_SIZE CAM_SPEED
44 %token < name > ATMOSPHERES CAM_MODE TARGET SOURCE SLICES STACKS JPEG_QUALITY
45 %token < name > MIPMAP MIPMAP_FILTER FONT LEVELOFDETAIL COLORDEPTH LOGO EOL
46 %token < name > MILKYWAY MESSIER DEMO DEMOSTEP TEXTURECOMPRESSION
47 
48 %expect 5
49 
50 %%
51 
52 input: |input line;
53 
54 line:
55 
56 SPLASHBITMAP '=' INTEGER_NUM {
57     splashbitmap = $3;
58 }
59 
60 |ATMOSPHERES '=' INTEGER_NUM {
61     atmospheres = $3;
62 }
63 
64 |BORDER '=' INTEGER_NUM {
65     border = $3;
66 }
67 
68 |FILTER '=' NAME {
69     if (!strcmp($3, "GL_NEAREST"))
70 	filter = GL_NEAREST;
71     if (!strcmp($3, "GL_LINEAR"))
72 	filter = GL_LINEAR;
73 }
74 
75 |SHADING '=' NAME {
76     if (strcmp($3, "GL_FLAT"))
77 	smodel = GL_SMOOTH;
78     else
79 	smodel = GL_FLAT;
80 }
81 
82 |SIM_DATE '=' NAME NAME {
83     sscanf($3, "%d-%d-%d", &date.tm_mon, &date.tm_mday, &date.tm_year);
84     sscanf($4, "%d:%d:%d", &date.tm_hour, &date.tm_min, &date.tm_sec);
85     date.tm_mon--;
86     date.tm_year-=1900;
87     days = mktime(&date) / 3600.0 / 24.0 - 10092.0;
88 }
89 
90 |PAUSE '=' INTEGER_NUM {
91     paused = $3;
92 }
93 
94 |REALTIME '=' INTEGER_NUM {
95     realtime = $3;
96 }
97 
98 |DEMO '=' INTEGER_NUM {
99     demomode = $3;
100 }
101 
102 |DEMOSTEP '=' INTEGER_NUM {
103     demostep = $3;
104 }
105 
106 |PLANETS_LABELS '=' INTEGER_NUM {
107     plabels = $3;
108 }
109 
110 |STARS_LABELS '=' INTEGER_NUM {
111     slabels = $3;
112 }
113 
114 |INFO '=' INTEGER_NUM {
115     info = $3;
116 }
117 
118 |STAR_BRIGHT '=' DOUBLE_NUM {
119     star_mag = $3;
120 }
121 
122 |STAR_SIZE '=' DOUBLE_NUM {
123     star_size = $3;
124 }
125 
126 |CAM_SPEED '=' DOUBLE_NUM {
127     speed = $3;
128 }
129 
130 |CAM_MODE '=' INTEGER_NUM {
131     cmode = $3;
132 }
133 
134 |TARGET '=' INTEGER_NUM {
135     currtarget = $3;
136 }
137 
138 |SOURCE '=' INTEGER_NUM {
139     currsource = $3;
140 }
141 
142 |SLICES '=' INTEGER_NUM {
143     slices = $3;
144 }
145 
146 |STACKS '=' INTEGER_NUM {
147     stacks = $3;
148 }
149 
150 |JPEG_QUALITY '=' INTEGER_NUM {
151     jpeg_quality = $3;
152     if ((jpeg_quality < 0) || (jpeg_quality > 100)) {
153 	error("Invalid jpeg_quality value\n");
154 	shutdown(1);
155     }
156 }
157 
158 |MIPMAP '=' INTEGER_NUM {
159     mipmap = $3;
160 }
161 
162 |MIPMAP_FILTER '=' NAME {
163     if (!strcmp($3, "GL_NEAREST_MIPMAP_NEAREST"))
164 	mipmap_filter = GL_NEAREST_MIPMAP_NEAREST;
165     if (!strcmp($3, "GL_LINEAR_MIPMAP_NEAREST"))
166 	mipmap_filter = GL_LINEAR_MIPMAP_NEAREST;
167     if (!strcmp($3, "GL_NEAREST_MIPMAP_LINEAR"))
168 	mipmap_filter = GL_NEAREST_MIPMAP_LINEAR;
169     if (!strcmp($3, "GL_NEAREST_MIPMAP_LINEAR"))
170 	mipmap_filter = GL_NEAREST_MIPMAP_LINEAR;
171     if (!strcmp($3, "GL_LINEAR_MIPMAP_LINEAR"))
172 	mipmap_filter = GL_LINEAR_MIPMAP_LINEAR;
173 }
174 
175 |FONT '=' INTEGER_NUM {
176 fonttype = $3}
177 
178 |LEVELOFDETAIL '=' INTEGER_NUM {
179 LOD = $3}
180 
181 |TEXTURECOMPRESSION '=' INTEGER_NUM {
182 tex_compr *= $3}
183 
184 |COLORDEPTH '=' INTEGER_NUM {
185     color_depth = $3;
186     switch (color_depth) {
187       default:
188       case 16:
189 	cd_rgb = GL_RGB5;
190 	cd_lum = GL_LUMINANCE8;
191 	cd_rgba = GL_RGBA4;
192 	cd_luma = GL_LUMINANCE8_ALPHA8;
193 	break;
194       case 32:
195 	cd_rgb = GL_RGB8;
196 	cd_lum = GL_LUMINANCE8;
197 	cd_rgba = GL_RGBA8;
198 	cd_luma = GL_LUMINANCE8_ALPHA8;
199 	break;
200     }
201 }
202 
203 |LOGO '=' INTEGER_NUM {
204     logo = $3;
205 }
206 
207 |MILKYWAY '=' INTEGER_NUM {
208     milkyway = $3;
209 }
210 
211 |MESSIER '=' INTEGER_NUM {
212     messier = $3;
213 }
214 
215 |sun | body | spaceship;
216 
217 sun:SUN '{' NAME DOUBLE_NUM INTEGER_NUM DOUBLE_NUM '}' {
218     sprintf(planets[0].Name, "The Sun");
219     planets[0].Mass = $6;
220     LOG("Initializing Sun", InitSun($3, $4, $5))
221 }
222 
223 body:planet | asteroid | comet;
224 
225 planet:PLANET NAME '{' NAME INTEGER_NUM INTEGER_NUM INTEGER_NUM DOUBLE_NUM
226     DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM INTEGER_NUM DOUBLE_NUM DOUBLE_NUM
227     DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM
228     DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM INTEGER_NUM {
229     strcpy(planets[body_index].Name, $2);
230     INITVECTOR(planets[body_index].Color, $5 / 255.0, $6 / 255.0,
231 	       $7 / 255.0);
232     planets[body_index].Radius = $8;
233     planets[body_index].xflat = $9;
234     planets[body_index].yflat = $10;
235     planets[body_index].zflat = $11;
236     planets[body_index].Degrees = $13;
237     planets[body_index].Rotation = $14;
238     planets[body_index].Inclination = $15 * M_PI / 180.0;
239     planets[body_index].AscendingNode = $16 * M_PI / 180.0;
240     planets[body_index].Perihelion = $17 * M_PI / 180.0;
241     planets[body_index].MeanDistance = DISTCORRECTION($18);
242     planets[body_index].DailyMotion = $19 * M_PI / 180.0;
243     planets[body_index].OrbitalPeriod = $20;
244     planets[body_index].Eccentricity = $21;
245     planets[body_index].MeanLongitude = $22 * M_PI / 180.0;
246     planets[body_index].Mass = $23;
247     planets[body_index].CustomFunction = $24;
248     planets[body_index].Sat = 0;
249     planets[body_index].TrailEnabled = 0;
250     planets[body_index].Type = PLANET;
251     LOG($2, SetUpBody(body_index, $4, $12));
252     last_planet = body_index;
253     body_index++;
254 }
255 atmosphere rings satellites orbiters '}';
256 
257 satellites:
258         | satellite
259         | satellites satellite
260 
261 satellite: SATELLITE NAME '{' NAME INTEGER_NUM INTEGER_NUM INTEGER_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM
262                 INTEGER_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM
263                 DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM
264                 INTEGER_NUM {
265     currblock = SATELLITE;
266     strcpy(planets[body_index].Name, $2);
267     INITVECTOR(planets[body_index].Color, $5 / 255.0, $6 / 255.0,
268 	       $7 / 255.0);
269     planets[body_index].Radius = $8;
270     planets[body_index].xflat = $9;
271     planets[body_index].yflat = $10;
272     planets[body_index].zflat = $11;
273     planets[body_index].Degrees = $13;
274     planets[body_index].Rotation = $14;
275     planets[body_index].Inclination = $15 * M_PI / 180.0;
276     planets[body_index].AscendingNode = $16 * M_PI / 180.0;
277     planets[body_index].Perihelion = $17 * M_PI / 180.0;
278     planets[body_index].MeanDistance = $18;
279     planets[body_index].DailyMotion = $19 * M_PI / 180.0;
280     planets[body_index].OrbitalPeriod = $20;
281     planets[body_index].Eccentricity = $21;
282     planets[body_index].MeanLongitude = $22 * M_PI / 180.0;
283     planets[body_index].Mass = $23;
284     planets[body_index].Type = SATELLITE;
285     planets[body_index].Sat = last_planet;
286     planets[body_index].CustomFunction = $24;
287     LOG($2, SetUpBody(body_index, $4, $12));
288     last_satellite = body_index;
289     body_index++;
290 }
291 
292 atmosphere orbiters {
293     currblock = PLANET;
294 } '}';
295 
296 orbiters:
297         |orbiter
298         | orbiters orbiter
299 
300 orbiter:ORBITER NAME '{' NAME DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM
301                               DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM  {
302     strcpy(planets[body_index].Name, $2);
303     planets[body_index].Type = ORBITER;
304     planets[body_index].Radius = $5;
305     INITVECTOR(planets[body_index].Color, 1.0, 1.0, 1.0);
306     planets[body_index].Sat =
307 	(currblock == SATELLITE) ? last_satellite : last_planet;
308     planets[body_index].up[0] = $6;
309     planets[body_index].up[1] = $7;
310     planets[body_index].up[2] = $8;
311     planets[body_index].dir[0] = $9;
312     planets[body_index].dir[1] = $10;
313     planets[body_index].dir[2] = $11;
314     planets[body_index].Rotation = 0.0;
315     planets[body_index].Inclination = $12;
316     planets[body_index].AscendingNode = $13;
317     planets[body_index].Perihelion = $14;
318     planets[body_index].MeanDistance = $15;
319     planets[body_index].DailyMotion = $16;
320     planets[body_index].OrbitalPeriod = $17;
321     planets[body_index].Eccentricity = $18;
322     planets[body_index].MeanLongitude = $19;
323     planets[body_index].CustomFunction = 0;
324     LOG($2, SetUpOrbiter(body_index, $4));
325     body_index++;
326 }
327 
328 '}';
329 
330 
331 asteroid:ASTEROID NAME '{' NAME DOUBLE_NUM INTEGER_NUM INTEGER_NUM
332     INTEGER_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM
333     DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM
334     DOUBLE_NUM INTEGER_NUM {
335     strcpy(planets[body_index].Name, $2);
336     planets[body_index].Radius = $5;
337     INITVECTOR(planets[body_index].Color, $6 / 255.0, $7 / 255.0,
338 	       $8 / 255.0);
339     planets[body_index].xflat = $9;
340     planets[body_index].yflat = $10;
341     planets[body_index].zflat = $11;
342     planets[body_index].Rotation = $12;
343     planets[body_index].Inclination = $13 * M_PI / 180.0;
344     planets[body_index].AscendingNode = $14 * M_PI / 180.0;
345     planets[body_index].Perihelion = $15 * M_PI / 180.0;
346     planets[body_index].MeanDistance = DISTCORRECTION($16);
347     planets[body_index].DailyMotion = $17 * M_PI / 180.0;
348     planets[body_index].OrbitalPeriod = $18;
349     planets[body_index].Eccentricity = $19;
350     planets[body_index].MeanLongitude = $20 * M_PI / 180.0;
351     planets[body_index].Sat = 0;
352     planets[body_index].CustomFunction = $21;
353     planets[body_index].Type = ASTEROID;
354     planets[body_index].up[0] = 0.0;
355     planets[body_index].up[1] = 1.0;
356     planets[body_index].up[2] = 0.0;
357     planets[body_index].dir[0] = 0.0;
358     planets[body_index].dir[1] = 0.0;
359     planets[body_index].dir[2] = -1.0;
360     LOG($2, SetUpAsteroid(body_index, $4));
361     last_planet = body_index;
362     body_index++;
363 }
364 
365 satellites '}';
366 
367 comet:COMET NAME '{' NAME INTEGER_NUM INTEGER_NUM INTEGER_NUM DOUBLE_NUM
368     DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM
369     DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM
370     DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM INTEGER_NUM INTEGER_NUM {
371     strcpy(planets[body_index].Name, $2);
372     INITVECTOR(planets[body_index].Color, $5 / 255.0, $6 / 255.0,
373 	       $7 / 255.0);
374     planets[body_index].Radius = $8;
375     planets[body_index].xflat = $9;
376     planets[body_index].yflat = $10;
377     planets[body_index].zflat = $11;
378     planets[body_index].Degrees = $13;
379     planets[body_index].Rotation = $14;
380     planets[body_index].Inclination = $15 * M_PI / 180.0;
381     planets[body_index].AscendingNode = $16 * M_PI / 180.0;
382     planets[body_index].Perihelion = $17 * M_PI / 180.0;
383     planets[body_index].MeanDistance = DISTCORRECTION($18);
384     planets[body_index].DailyMotion = $19 * M_PI / 180.0;
385     planets[body_index].OrbitalPeriod = $20;
386     planets[body_index].Eccentricity = $21;
387     planets[body_index].MeanLongitude = $22 * M_PI / 180.0;
388     planets[body_index].Sat = 0;
389     planets[body_index].CustomFunction = $25;
390     planets[body_index].Type = COMET;
391     LOG($2, SetUpComet(body_index, $4, $12, $23, $24));
392     last_planet = body_index;
393     body_index++;
394 }
395 
396 '}';
397 
398 
399 atmosphere:
400 |ATMOSPHERE '{' NAME INTEGER_NUM INTEGER_NUM INTEGER_NUM DOUBLE_NUM
401     DOUBLE_NUM DOUBLE_NUM INTEGER_NUM '}' {
402     INITVECTOR(planets[body_index].Color, $4 / 255.0, $5 / 255.0,
403 	       $6 / 255.0);
404     planets[body_index].Radius = $7;
405     planets[body_index].Rotation = $8;
406     planets[body_index].Sat = last_planet;
407     planets[body_index].Type = ATMOSPHERE;
408     LOG("Atmosphere", SetUpAtmosphere(body_index, $3, $9, $10));
409     body_index++;
410 }
411 
412 ;
413 
414 rings:
415 |ring | rings ring;
416 
417 ring:RING '{' NAME INTEGER_NUM INTEGER_NUM INTEGER_NUM DOUBLE_NUM DOUBLE_NUM
418     DOUBLE_NUM '}' {
419     planets[body_index].Color[0] = $4 / 255.0;
420     planets[body_index].Color[1] = $5 / 255.0;
421     planets[body_index].Color[2] = $6 / 255.0;
422     planets[body_index].Sat = last_planet;
423     planets[body_index].Type = RING;
424     planets[body_index].InnerRadius = $7;
425     planets[body_index].Radius = $8;
426     planets[body_index].initialized = 0;
427     LOG("Ring", SetUpRings(body_index, $3, $7, $8, $9));
428     body_index++;
429 }
430 
431 ;
432 
433 
434 spaceship:SPACESHIP NAME '{' NAME DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM
435     DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM
436     DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM DOUBLE_NUM {
437     strcpy(planets[body_index].Name, $2);
438     INITVECTOR(planets[body_index].Color, 1.0, 1.0, 1.0);
439     planets[body_index].Type = SPACESHIP;
440     planets[body_index].Radius = $5;
441     planets[body_index].Sat = 0;
442     INITVECTOR(planets[body_index].pos,
443 	       $6 * AU, $7 * AU, $8 * AU);
444     INITVECTOR(planets[body_index].up, $9, $10, $11);
445     INITVECTOR(planets[body_index].dir, $12, $13, $14);
446     INITVECTOR(planets[body_index].vel, $15, $16, $17);
447     LOG($2, SetUpSpaceShip(body_index, $4));
448     body_index++;
449 }
450 
451 '}';
452 
453 
454 %%
455 
456 void yyerror(char *s)
457 {
458     fprintf(stderr, "%s in line %d of configuration file\n", s, yylineno);
459     shutdown(1);
460 }
461 
462 /* Read configuration file */
ReadConfigFile(void)463 void ReadConfigFile(void)
464 {
465     char s[200];
466 
467     sprintf(s, "ou.conf");
468     cfgin = fopen(s, "rt");
469     if (cfgin == NULL) {
470     	sprintf(s, "%s/ou.conf", confpath);
471     	cfgin = fopen(s, "rt");
472 	if (cfgin == NULL) {
473 	    error("Couldn't find configuration file");
474 	    shutdown(1);
475 	}
476     }
477     yyparse();
478     fclose(cfgin);
479     NUMBODIES = body_index;
480 }
481