1 
2 #include <stdlib.h>
3 #include <math.h>
4 #include <string.h>
5 #include <limits.h>
6 #include <SDL.h>
7 #include "asc.h"
8 #include "sky.h"
9 #include "draw_scene.h"
10 #include "elconfig.h"
11 #include "errors.h"
12 #include "gl_init.h"
13 #include "lights.h"
14 #include "map.h"
15 #include "multiplayer.h"
16 #include "reflection.h"
17 #include "shadows.h"
18 #include "textures.h"
19 #include "vmath.h"
20 #include "weather.h"
21 
22 float skybox_clouds[360][4];
23 float skybox_clouds_detail[360][4];
24 float skybox_clouds_sunny[360][4];
25 float skybox_clouds_detail_sunny[360][4];
26 float skybox_clouds_rainy[360][4];
27 float skybox_clouds_detail_rainy[360][4];
28 float skybox_sky1[360][4];
29 float skybox_sky2[360][4];
30 float skybox_sky3[360][4];
31 float skybox_sky4[360][4];
32 float skybox_sky5[360][4];
33 float skybox_sky1_sunny[360][4];
34 float skybox_sky2_sunny[360][4];
35 float skybox_sky3_sunny[360][4];
36 float skybox_sky4_sunny[360][4];
37 float skybox_sky5_sunny[360][4];
38 float skybox_sun[360][4];
39 float skybox_fog[360][4];
40 float skybox_fog_sunny[360][4];
41 float skybox_fog_rainy[360][4];
42 float skybox_light_ambient[360][4];
43 float skybox_light_diffuse[360][4];
44 float skybox_light_ambient_rainy[360][4];
45 float skybox_light_diffuse_rainy[360][4];
46 float skybox_sky_color[4] = {0.0, 0.0, 0.0, 0.0};
47 float skybox_fog_color[4] = {0.0, 0.0, 0.0, 0.0};
48 float skybox_fog_density = 0.0;
49 float skybox_light_ambient_color[4];
50 float skybox_light_diffuse_color[4];
51 int skybox_no_clouds = 1;
52 int skybox_no_sun = 1;
53 int skybox_no_moons = 1;
54 int skybox_no_stars = 1;
55 int skybox_clouds_tex = -1;
56 int skybox_clouds_detail_tex = -1;
57 
58 int skybox_show_sky = 1;
59 int skybox_show_clouds = 1;
60 int skybox_show_sun = 1;
61 int skybox_show_moons = 1;
62 int skybox_show_stars = 1;
63 float skybox_sunny_sky_bias = -0.3;
64 float skybox_sunny_clouds_bias = -0.3;
65 float skybox_sunny_fog_bias = -0.3;
66 float skybox_moonlight1_bias = 0.92;
67 float skybox_moonlight2_bias = 0.98;
68 
69 float skybox_sun_position[4] = {0.0, 0.0, 0.0, 0.0};
70 float skybox_sun_projection[2] = {0.0, 0.0};
71 double skybox_time_d = 0.0;
72 double skybox_view[16];
73 
74 float skybox_z = 0.0;
75 
76 typedef struct
77 {
78 	int slices_count;
79 	int stacks_count;
80 	int vertices_count;
81 	int faces_count;
82 	GLfloat *vertices;
83 	GLfloat *normals;
84 	GLfloat *colors;
85 	GLfloat *tex_coords;
86 	GLuint *faces;
87 	float radius;
88 	float real_radius;
89 	float opening;
90 	float height;
91 	float texture_size;
92 	float tex_coords_conversion_factor;
93 	float conversion_factor;
94 } sky_dome;
95 
96 typedef struct
97 {
98 	int vertices_count;
99 	int faces_count;
100 	GLfloat *vertices;
101 	GLfloat *tex_coords;
102 	GLuint *faces;
103 } sky_sphere;
104 
105 sky_dome dome_sky = {0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
106 sky_dome dome_clouds = {0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
107 
108 GLfloat *dome_clouds_detail_colors = NULL;
109 GLfloat *dome_clouds_colors_bis = NULL;
110 GLfloat *dome_clouds_detail_colors_bis = NULL;
111 GLfloat *dome_clouds_tex_coords_bis = NULL;
112 
113 sky_sphere moon_mesh = {0, 0, NULL, NULL, NULL};
114 
115 GLfloat moon1_direction[3];
116 GLfloat moon2_direction[3];
117 GLfloat moon1_color[3];
118 GLfloat moon2_color[3];
119 GLfloat sun_color[4];
120 double moon_spin = 0.0;
121 float rain_coef = 0.0;
122 float day_alpha = 0.0;
123 skybox_type current_sky = SKYBOX_NONE;
124 
125 #define NUM_STARS 3000
126 GLuint sky_lists;
127 int thick_clouds_tex;
128 int thick_clouds_detail_tex;
129 int moon_tex;
130 int sun_tex;
131 
create_dome(int slices,int stacks,float radius,float opening,int fake_opening,float first_angle,float texture_size)132 sky_dome create_dome(int slices, int stacks, float radius, float opening, int fake_opening, float first_angle, float texture_size)
133 {
134 	sky_dome dome = {0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
135     int i, j;
136     float angle, angle_step;
137     int idx, vtx_idx;
138 	float max_sin_angle;
139 	float max_cos_angle;
140 
141     dome.slices_count = slices;
142     dome.stacks_count = stacks;
143 
144     dome.vertices_count = dome.slices_count*(dome.stacks_count+1)+1;
145     dome.faces_count = dome.slices_count*(1+2*dome.stacks_count);
146 
147     dome.vertices = (GLfloat*)malloc(3*dome.vertices_count*sizeof(GLfloat));
148     dome.normals = (GLfloat*)malloc(3*dome.vertices_count*sizeof(GLfloat));
149     dome.colors = (GLfloat*)malloc(4*dome.vertices_count*sizeof(GLfloat));
150     dome.tex_coords = (GLfloat*)malloc(2*dome.vertices_count*sizeof(GLfloat));
151     dome.faces = (GLuint*)malloc(3*dome.faces_count*sizeof(GLuint));
152 
153 	dome.radius = radius;
154     dome.opening = opening;
155 
156 	angle = dome.opening * M_PI / 180.0;
157 	max_sin_angle = sinf(angle);
158 	max_cos_angle = cosf(angle);
159 
160     dome.real_radius = dome.radius/max_sin_angle;
161     dome.height = dome.real_radius - dome.real_radius*max_cos_angle;
162 	dome.texture_size = texture_size;
163 	dome.tex_coords_conversion_factor = dome.radius / texture_size;
164 
165 	texture_size *= dome.radius * max_cos_angle / (max_sin_angle * dome.real_radius);
166 
167 	dome.conversion_factor = max_cos_angle * dome.radius;
168 
169     // we compute the vertices positions and normals
170     i = idx = 0;
171 	if (first_angle > 0.0)
172 	{
173 		float cos_angle = cosf(angle);
174 		float sin_angle = sinf(angle);
175         float z_pos = cos_angle * dome.real_radius + dome.height - dome.real_radius;
176 		float tmp = texture_size * sin_angle/cos_angle;
177 		float fake_angle = angle * fake_opening / opening;
178 		float fake_cos_angle = cosf(fake_angle);
179 		float fake_sin_angle = sinf(fake_angle);
180         for (j = 0; j < dome.slices_count; ++j)
181         {
182             float teta = j * 2.0 * M_PI / (float)dome.slices_count;
183 			float cos_teta = cosf(teta);
184 			float sin_teta = sinf(teta);
185 			int idx3 = idx*3;
186             dome.vertices[idx3  ] = sin_angle * cos_teta * dome.real_radius;
187             dome.vertices[idx3+1] = sin_angle * sin_teta * dome.real_radius;
188             dome.vertices[idx3+2] = z_pos;
189 			dome.normals[idx3  ] = fake_sin_angle * cos_teta;
190 			dome.normals[idx3+1] = fake_sin_angle * sin_teta;
191 			dome.normals[idx3+2] = fake_cos_angle;
192 			dome.tex_coords[idx*2  ] = 0.5 + tmp * cos_teta;
193 			dome.tex_coords[idx*2+1] = 0.5 + tmp * sin_teta;
194 			++idx;
195         }
196         angle -= first_angle * M_PI / 180.0;
197 		angle_step = angle / (float)dome.stacks_count;
198 		++i;
199 	}
200 	else
201 	{
202 		angle_step = angle / (float)(dome.stacks_count+1);
203 	}
204     for (; i <= dome.stacks_count; ++i)
205     {
206 		float cos_angle = cosf(angle);
207 		float sin_angle = sinf(angle);
208         float z_pos = cos_angle * dome.real_radius + dome.height - dome.real_radius;
209 		float tmp = texture_size * sin_angle/cos_angle;
210 		float fake_angle = angle * fake_opening / opening;
211 		float fake_cos_angle = cosf(fake_angle);
212 		float fake_sin_angle = sinf(fake_angle);
213         for (j = 0; j < dome.slices_count; ++j)
214         {
215             float teta = j * 2.0 * M_PI / (float)dome.slices_count;
216 			float cos_teta = cosf(teta);
217 			float sin_teta = sinf(teta);
218 			int idx3 = idx*3;
219             dome.vertices[idx3  ] = sin_angle * cos_teta * dome.real_radius;
220             dome.vertices[idx3+1] = sin_angle * sin_teta * dome.real_radius;
221             dome.vertices[idx3+2] = z_pos;
222 			dome.normals[idx3  ] = fake_sin_angle * cos_teta;
223 			dome.normals[idx3+1] = fake_sin_angle * sin_teta;
224 			dome.normals[idx3+2] = fake_cos_angle;
225 			dome.tex_coords[idx*2  ] = 0.5 + tmp * cos_teta;
226 			dome.tex_coords[idx*2+1] = 0.5 + tmp * sin_teta;
227 			++idx;
228         }
229         angle -= angle_step;
230     }
231 
232     // the vertex at the top of the dome
233     dome.vertices[idx*3  ] = 0.0;
234     dome.vertices[idx*3+1] = 0.0;
235     dome.vertices[idx*3+2] = dome.height;
236 	dome.normals[idx*3  ] = 0.0;
237 	dome.normals[idx*3+1] = 0.0;
238 	dome.normals[idx*3+2] = 1.0;
239 	dome.tex_coords[idx*2  ] = 0.5;
240 	dome.tex_coords[idx*2+1] = 0.5;
241 
242     // we build the faces of the dome
243     idx = 0;
244 	vtx_idx = 0;
245     for (i = 0; i < dome.stacks_count; ++i)
246     {
247         for (j = 0; j < dome.slices_count; ++j)
248         {
249             int next = (j+1)%dome.slices_count;
250             dome.faces[idx++] = vtx_idx+j;
251             dome.faces[idx++] = vtx_idx+j+dome.slices_count;
252             dome.faces[idx++] = vtx_idx+next;
253             dome.faces[idx++] = vtx_idx+next;
254             dome.faces[idx++] = vtx_idx+j+dome.slices_count;
255             dome.faces[idx++] = vtx_idx+next+dome.slices_count;
256         }
257         vtx_idx += dome.slices_count;
258     }
259 
260     // the last stack of faces at the top of the dome
261     for (j = 0; j < dome.slices_count; ++j)
262     {
263         int next = (j+1)%dome.slices_count;
264         dome.faces[idx++] = vtx_idx+j;
265         dome.faces[idx++] = vtx_idx+dome.slices_count;
266         dome.faces[idx++] = vtx_idx+next;
267     }
268 
269 	return dome;
270 }
271 
create_sphere(int slices,int stacks)272 sky_sphere create_sphere(int slices, int stacks)
273 {
274 	sky_sphere sphere;
275     int i, j;
276     int idx, vtx_idx;
277 
278     sphere.vertices_count = (slices+1)*(stacks+1);
279     sphere.faces_count = slices*stacks*2;
280 
281     sphere.vertices = (GLfloat*)malloc(3*sphere.vertices_count*sizeof(GLfloat));
282     sphere.tex_coords = (GLfloat*)malloc(2*sphere.vertices_count*sizeof(GLfloat));
283     sphere.faces = (GLuint*)malloc(3*sphere.faces_count*sizeof(GLuint));
284 
285     // we compute the vertices positions and normals
286     idx = 0;
287     for (j = 0; j <= stacks; ++j)
288     {
289 		float angle = j * M_PI / (float)stacks;
290 		float cos_angle = cosf(angle);
291 		float sin_angle = sinf(angle);
292 		float tex_j = j / (float)stacks;
293         for (i = 0; i <= slices; ++i)
294         {
295             float teta = i * 2.0 * M_PI / (float)slices;
296 			float cos_teta = cosf(teta);
297 			float sin_teta = sinf(teta);
298 			int idx3 = idx*3;
299             sphere.vertices[idx3  ] = sin_angle * cos_teta;
300             sphere.vertices[idx3+1] = sin_angle * sin_teta;
301             sphere.vertices[idx3+2] = cos_angle;
302 			sphere.tex_coords[idx*2  ] = i / (float)slices;
303 			sphere.tex_coords[idx*2+1] = tex_j;
304 			++idx;
305         }
306     }
307 
308     // we build the faces of the dome
309     idx = 0;
310 	vtx_idx = 0;
311     for (j = 0; j < stacks; ++j)
312     {
313         for (i = 0; i < slices; ++i)
314         {
315             sphere.faces[idx++] = vtx_idx + i;
316             sphere.faces[idx++] = vtx_idx + i   + slices+1;
317             sphere.faces[idx++] = vtx_idx + i+1;
318             sphere.faces[idx++] = vtx_idx + i+1;
319             sphere.faces[idx++] = vtx_idx + i   + slices+1;
320             sphere.faces[idx++] = vtx_idx + i+1 + slices+1;
321         }
322         vtx_idx += slices+1;
323     }
324 
325 	return sphere;
326 }
327 
destroy_dome(sky_dome * dome)328 void destroy_dome(sky_dome *dome)
329 {
330     if (dome->vertices  ) { free(dome->vertices  ); dome->vertices   = NULL; }
331     if (dome->normals   ) { free(dome->normals   ); dome->normals    = NULL; }
332     if (dome->colors    ) { free(dome->colors    ); dome->colors     = NULL; }
333     if (dome->tex_coords) { free(dome->tex_coords); dome->tex_coords = NULL; }
334     if (dome->faces     ) { free(dome->faces     ); dome->faces      = NULL; }
335 }
336 
destroy_sphere(sky_sphere * sphere)337 void destroy_sphere(sky_sphere *sphere)
338 {
339     if (sphere->vertices  ) { free(sphere->vertices  ); sphere->vertices   = NULL; }
340     if (sphere->tex_coords) { free(sphere->tex_coords); sphere->tex_coords = NULL; }
341     if (sphere->faces     ) { free(sphere->faces     ); sphere->faces      = NULL; }
342 }
343 
draw_sphere(sky_sphere * sphere)344 static __inline__ void draw_sphere(sky_sphere *sphere)
345 {
346 	glEnableClientState(GL_VERTEX_ARRAY);
347 	glEnableClientState(GL_NORMAL_ARRAY);
348 	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
349 
350 	glVertexPointer(3, GL_FLOAT, 0, sphere->vertices);
351 	glNormalPointer(GL_FLOAT, 0, sphere->vertices);
352 	glTexCoordPointer(2, GL_FLOAT, 0, sphere->tex_coords);
353 
354 	glDrawElements(GL_TRIANGLES, sphere->faces_count*3, GL_UNSIGNED_INT, sphere->faces);
355 
356 	glDisableClientState(GL_VERTEX_ARRAY);
357 	glDisableClientState(GL_NORMAL_ARRAY);
358 	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
359 }
360 
skybox_compute_z_position()361 void skybox_compute_z_position()
362 {
363 	if (far_plane < 500.0)
364 	{
365 		float zl = first_person ? 0.0 : zoom_level;
366 		float cos_rx = cosf(-rx*M_PI/180.0);
367 		float sin_rx = sinf(-rx*M_PI/180.0);
368 		float eye_xy = sin_rx*zl*camera_distance;
369 		float eye_z = cos_rx*zl*camera_distance-camera_z;
370 		float water_end = sin_rx*far_plane+(far_plane*cos_rx-eye_z)*cos_rx/sin_rx;
371 
372 		skybox_z = eye_z*(water_end-500.0+eye_xy)/water_end;
373 
374 		//printf("camera_z=%f rx=%f zoom_level=%f camera_distance=%f eye_xy=%f eye_z=%f water_end=%f skybox_z=%f\n", camera_z, rx, zoom_level, camera_distance, eye_xy, eye_z, water_end, skybox_z);
375 	}
376 	else
377 		skybox_z = 0.0;
378 }
379 
skybox_get_z_position()380 float skybox_get_z_position()
381 {
382 	return skybox_z;
383 }
384 
skybox_vertex_to_ground_coords(sky_dome * dome,int i,float * gx,float * gy)385 static __inline__ void skybox_vertex_to_ground_coords(sky_dome *dome, int i, float *gx, float *gy)
386 {
387 	*gx = dome->tex_coords_conversion_factor * (dome->tex_coords[i*2  ] - dome->tex_coords[dome->vertices_count*2-2]);
388 	*gy = dome->tex_coords_conversion_factor * (dome->tex_coords[i*2+1] - dome->tex_coords[dome->vertices_count*2-1]);
389 }
390 
skybox_direction_to_ground_coords(float dir[3],float * gx,float * gy)391 void skybox_direction_to_ground_coords(float dir[3], float *gx, float *gy)
392 {
393 	float sd = sqrtf(dir[0]*dir[0] + dir[1]*dir[1]);
394 	float t = sd / (dir[2] - dome_sky.height + dome_sky.real_radius);
395 	float gd = t * dome_clouds.conversion_factor;
396 
397 	*gx = gd * dir[0] / sd;
398 	*gy = gd * dir[1] / sd;
399 
400 	//printf("dir=%f,%f,%f t=%f gx=%f gy=%f\n", dir[0], dir[1], dir[2], t, *gx, *gy);
401 }
402 
skybox_coords_from_ground_coords(float sky_coords[3],float gx,float gy)403 void skybox_coords_from_ground_coords(float sky_coords[3], float gx, float gy)
404 {
405 	float gd = sqrtf(gx*gx + gy*gy);
406 	float t = gd / dome_clouds.conversion_factor;
407 	float sd = dome_clouds.real_radius * t / sqrtf(1.0 + t*t);
408 
409 	sky_coords[0] = sd * gx / gd;
410 	sky_coords[1] = sd * gy / gd;
411 	sky_coords[2] = sd / t + dome_sky.height - dome_sky.real_radius;
412 }
413 
skybox_compute_element_projection(float proj[3],float pos[3])414 void skybox_compute_element_projection(float proj[3], float pos[3])
415 {
416 	float coef, a, b, c, delta;
417 	float r2 = dome_sky.real_radius*dome_sky.real_radius;
418 	float z = dome_sky.height - dome_sky.real_radius;
419 
420 	c = z*z - r2;
421 
422 	if (pos[0] != 0.0)
423 	{
424 		coef = pos[2]/pos[0];
425 		a = 1.0 + coef*coef;
426 		b = -2.0*coef*z;
427 		delta = b*b - 4*a*c;
428 		if (delta <= 0.0) fprintf(stderr, "delta=%f\n", delta);
429 
430 		if (pos[0] < 0.0)
431 			proj[0] = (-b - sqrtf(delta)) / (2.0*a);
432 		else
433 			proj[0] = (-b + sqrtf(delta)) / (2.0*a);
434 	}
435 	else proj[0] = 0.0;
436 
437 	if (pos[1] != 0.0)
438 	{
439 		coef = pos[2]/pos[1];
440 		a = 1.0 + coef*coef;
441 		b = -2.0*coef*z;
442 		delta = b*b - 4*a*c;
443 		if (delta <= 0.0) fprintf(stderr, "delta=%f\n", delta);
444 
445 		if (pos[1] < 0.0)
446 			proj[1] = (-b - sqrtf(delta)) / (2.0*a);
447 		else
448 			proj[1] = (-b + sqrtf(delta)) / (2.0*a);
449 	}
450 	else proj[1] = 0.0;
451 
452 	proj[2] = sqrtf(r2 - proj[0]*proj[0] - proj[1]*proj[1]) + z;
453 }
454 
skybox_get_height(float x,float y)455 float skybox_get_height(float x, float y)
456 {
457 	float d2 = dome_sky.real_radius*dome_sky.real_radius - x*x - y*y;
458 	float d = d2 <= 0.0 ? 0.0 : sqrtf(d2);
459 	return (d +	dome_sky.height - dome_sky.real_radius);
460 }
461 
skybox_set_type(skybox_type sky)462 void skybox_set_type(skybox_type sky)
463 {
464     current_sky = sky;
465 }
466 
467 void cloudy_sky();
468 void underworld_sky();
469 
skybox_display()470 void skybox_display()
471 {
472 	glMatrixMode(GL_PROJECTION);
473 	glPushMatrix();
474 	glLoadMatrixd(skybox_view);
475 	glMatrixMode(GL_MODELVIEW);
476 	glPushMatrix();
477 
478 	// we center the sky on the camera, not on the world
479 	glTranslatef(-camera_x, -camera_y, 0.0);
480 
481 	switch (current_sky)
482 	{
483 	case SKYBOX_CLOUDY:
484 		cloudy_sky();
485 		break;
486 
487 	case SKYBOX_UNDERWORLD:
488 		underworld_sky();
489 		break;
490 
491 	case SKYBOX_NONE:
492 	default:
493 		break;
494 	}
495 
496 	glPopMatrix();
497 	glMatrixMode(GL_PROJECTION);
498 	glPopMatrix();
499 	glMatrixMode(GL_MODELVIEW);
500 }
501 
502 void update_cloudy_sky_positions();
503 
skybox_update_positions()504 void skybox_update_positions()
505 {
506 	switch(current_sky)
507 	{
508 	case SKYBOX_CLOUDY:
509 		update_cloudy_sky_positions();
510 		break;
511 
512 	case SKYBOX_UNDERWORLD:
513 	case SKYBOX_NONE:
514 	default:
515 		break;
516 	}
517 }
518 
519 void update_cloudy_sky_colors();
520 void update_cloudy_sky_local_colors();
521 void update_underworld_sky_colors();
522 
skybox_update_colors()523 void skybox_update_colors()
524 {
525 	switch(current_sky)
526 	{
527 	case SKYBOX_CLOUDY:
528 		if (skybox_local_weather)
529 			update_cloudy_sky_local_colors();
530 		else
531 			update_cloudy_sky_colors();
532 		break;
533 
534 	case SKYBOX_UNDERWORLD:
535 		update_underworld_sky_colors();
536 		break;
537 
538 	case SKYBOX_NONE:
539 		skybox_sky_color[0] = 0.0;
540 		skybox_sky_color[1] = 0.0;
541 		skybox_sky_color[2] = 0.0;
542 		skybox_sky_color[3] = 1.0;
543 		skybox_fog_color[0] = 0.0;
544 		skybox_fog_color[1] = 0.0;
545 		skybox_fog_color[2] = 0.0;
546 		skybox_fog_color[3] = 1.0;
547 		skybox_fog_density = 0.01;
548 	default:
549 		break;
550 	}
551 }
552 
update_cloudy_sky_positions()553 void update_cloudy_sky_positions()
554 {
555 	float rot1[9], rot2[9], rot3[9];
556 	float moon1_vect[3] = {0.0, 0.0, 1.0};
557 	float moon2_vect[3] = {0.0, 0.0, 1.0};
558 
559 	if (is_day)
560 	{
561 		float dir[3] = {skybox_sun_position[0] * 480.0,
562 						skybox_sun_position[1] * 480.0,
563 						skybox_sun_position[2] * 480.0};
564 		skybox_direction_to_ground_coords(dir, &skybox_sun_projection[0], &skybox_sun_projection[1]);
565 	}
566 	else
567 	{
568 		skybox_sun_projection[0] = skybox_sun_projection[1] = 0.0;
569 	}
570 
571 	moon_spin = cur_time % (1296000*1000);
572 	moon_spin *= 360.0/(1296000.0/*seconds in large month*/ * 1000.0/*millisecond bump*/);
573 	moon_spin += skybox_time_d;
574 
575 	MAT3_ROT_Y(rot1, -((float)game_minute+(float)game_second/60.0)*M_PI/180.0);
576 	MAT3_ROT_Y(rot2, moon_spin*M_PI/180.0);
577 	MAT3_MULT(rot3, rot1, rot2);
578 	MAT3_VECT3_MULT(moon1_direction, rot3, moon1_vect);
579 
580 	MAT3_ROT_Z(rot2, M_PI/9.0);
581 	MAT3_MULT(rot3, rot1, rot2);
582 	MAT3_ROT_Y(rot1, moon_spin*M_PI/18.0);
583 	MAT3_MULT(rot2, rot3, rot1);
584 	MAT3_VECT3_MULT(moon2_direction, rot2, moon2_vect);
585 }
586 
get_sky_sunlight(const GLfloat normal[3])587 static __inline__ float get_sky_sunlight(const GLfloat normal[3])
588 {
589 	GLfloat dot = normal[0]*sun_position[0]+normal[1]*sun_position[1]+normal[2]*sun_position[2];
590     if (skybox_show_sun && !skybox_no_sun)
591         return (dot > skybox_sunny_sky_bias ? (dot-skybox_sunny_sky_bias)/(1.0-skybox_sunny_sky_bias) : 0.0);
592     else
593         return 0.0;
594 }
595 
get_clouds_sunlight(const GLfloat normal[3])596 static __inline__ float get_clouds_sunlight(const GLfloat normal[3])
597 {
598 	GLfloat dot = normal[0]*sun_position[0]+normal[1]*sun_position[1]+normal[2]*sun_position[2];
599     if (skybox_show_sun && !skybox_no_sun)
600         return (dot > skybox_sunny_clouds_bias ? (dot-skybox_sunny_clouds_bias)/(1.0-skybox_sunny_clouds_bias) : 0.0);
601     else
602         return 0.0;
603 }
604 
get_fog_sunlight(const GLfloat normal[3])605 static __inline__ float get_fog_sunlight(const GLfloat normal[3])
606 {
607 	GLfloat dot = normal[0]*sun_position[0]+normal[1]*sun_position[1]+normal[2]*sun_position[2];
608     if (skybox_show_sun && !skybox_no_sun)
609         return (dot > skybox_sunny_fog_bias ? (dot-skybox_sunny_fog_bias)/(1.0-skybox_sunny_fog_bias) : 0.0);
610     else
611         return 0.0;
612 }
613 
get_moonlight1(const GLfloat normal[3])614 static __inline__ float get_moonlight1(const GLfloat normal[3])
615 {
616 	GLfloat dot1 = normal[0]*moon1_direction[0]+normal[1]*moon1_direction[1]+normal[2]*moon1_direction[2];
617 	GLfloat dot2 = -(sun_position[0]*moon1_direction[0]+sun_position[1]*moon1_direction[1]+sun_position[2]*moon1_direction[2])*0.5+0.5;
618 	dot1 = (dot1 > skybox_moonlight1_bias ? (dot1-skybox_moonlight1_bias)/(1.0-skybox_moonlight1_bias) : 0.0);
619     if (skybox_show_moons && !skybox_no_moons)
620         return dot1*dot2;
621     else
622         return 0.0;
623 }
624 
get_moonlight2(const GLfloat normal[3])625 static __inline__ float get_moonlight2(const GLfloat normal[3])
626 {
627 	GLfloat dot1 = normal[0]*moon2_direction[0]+normal[1]*moon2_direction[1]+normal[2]*moon2_direction[2];
628 	GLfloat dot2 = -(sun_position[0]*moon2_direction[0]+sun_position[1]*moon2_direction[1]+sun_position[2]*moon2_direction[2])*0.5+0.5;
629 	dot1 = (dot1 > skybox_moonlight2_bias ? (dot1-skybox_moonlight2_bias)/(1.0-skybox_moonlight2_bias) : 0.0);
630     if (skybox_show_moons && !skybox_no_moons)
631         return dot1*dot2;
632     else
633         return 0.0;
634 }
635 
update_cloudy_sky_colors()636 void update_cloudy_sky_colors()
637 {
638     int i, idx, end;
639 	GLfloat color_sun[4];
640 	GLfloat color_sky[4];
641 	GLfloat color[4];
642 	float abs_light;
643 	float *normal, ml1, ml2;
644 	float x, y, lg;
645 
646 	abs_light = light_level;
647 	if(light_level > 59)
648 	{
649 		abs_light = 119 - light_level;
650 	}
651 	abs_light = 1.0f - abs_light/59.0f;
652 
653 	rain_coef = weather_get_density();
654 
655 	// alpha adjustment for objects that should fade in daylight
656 	day_alpha = (1.0-abs_light)*(1.0-rain_coef);
657 
658 	// color of the moons
659 	moon1_color[0] = 0.9;
660 	moon1_color[1] = 0.9;
661 	moon1_color[2] = 0.9;
662 	moon2_color[0] = 0.9;
663 	moon2_color[1] = 0.8;
664 	moon2_color[2] = 0.7;
665 
666 	// color of the sun
667 	skybox_get_current_color(sun_color, skybox_sun);
668 	sun_color[0] *= 1.0 - rain_coef;
669 	sun_color[1] *= 1.0 - rain_coef;
670 	sun_color[2] *= 1.0 - rain_coef;
671 	sun_color[3] *= 1.0 - rain_coef;
672 
673 	// color of the light
674 	skybox_blend_current_colors(skybox_light_ambient_color, skybox_light_ambient, skybox_light_ambient_rainy, rain_coef);
675 	skybox_blend_current_colors(skybox_light_diffuse_color, skybox_light_diffuse, skybox_light_diffuse_rainy, rain_coef);
676 
677     // we compute the color and the density of the fog
678 	skybox_blend_current_colors(skybox_fog_color, skybox_fog, skybox_fog_rainy, rain_coef);
679 	if (rain_coef > 0.0)
680 	{
681 		float fog_density;
682 		blend_colors(&fog_density, &skybox_fog[game_minute][3], &skybox_fog[(game_minute+1)%360][3], (float)game_second/60.0, 1);
683 		skybox_fog_color[0] *= (1.0-rain_coef) + rain_coef*weather_color[0];
684 		skybox_fog_color[1] *= (1.0-rain_coef) + rain_coef*weather_color[1];
685 		skybox_fog_color[2] *= (1.0-rain_coef) + rain_coef*weather_color[2];
686 		skybox_fog_color[3] = (1.0-rain_coef)*fog_density + rain_coef*skybox_fog_color[3];
687 	}
688 	skybox_fog_density = skybox_fog_color[3];
689 	skybox_fog_color[3] = 1.0;
690 
691 	i = idx = 0;
692 
693 	// clouds color
694 	skybox_blend_current_colors(color_sky, skybox_clouds, skybox_clouds_rainy, rain_coef);
695 	skybox_blend_current_colors(color_sun, skybox_clouds_sunny, skybox_clouds_rainy, rain_coef);
696     while (i < dome_clouds.slices_count * 2)
697     {
698 		normal = &dome_clouds.normals[i*3];
699 		ml1 = get_moonlight1(normal)*0.3*day_alpha;
700 		ml2 = get_moonlight2(normal)*0.2*day_alpha;
701 
702 		blend_colors(color, color_sky, color_sun, get_clouds_sunlight(normal), 3);
703 
704 		color[0] *= (1.0 - rain_coef) + rain_coef*weather_color[0];
705 		color[1] *= (1.0 - rain_coef) + rain_coef*weather_color[1];
706 		color[2] *= (1.0 - rain_coef) + rain_coef*weather_color[2];
707 
708 		if (lightning_falling) {
709 			skybox_vertex_to_ground_coords(&dome_clouds, i, &x, &y);
710 			lg = weather_get_lightning_intensity(x-camera_x, y-camera_y);
711 			color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
712 			color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
713 			color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
714 		}
715 
716 		dome_clouds.colors[idx] = color[0] + ml1*moon1_color[0] + ml2*moon2_color[0];
717 		dome_clouds_colors_bis[idx++] = color[0];
718 		dome_clouds.colors[idx] = color[1] + ml1*moon1_color[1] + ml2*moon2_color[1];
719 		dome_clouds_colors_bis[idx++] = color[1];
720 		dome_clouds.colors[idx] = color[2] + ml1*moon1_color[2] + ml2*moon2_color[2];
721 		dome_clouds_colors_bis[idx++] = color[2];
722         dome_clouds.colors[idx] = 0.0;
723 		dome_clouds_colors_bis[idx++] = 0.0;
724 		++i;
725     }
726     while (i < dome_clouds.vertices_count)
727     {
728 		normal = &dome_clouds.normals[i*3];
729 		ml1 = get_moonlight1(normal)*0.3*day_alpha;
730 		ml2 = get_moonlight2(normal)*0.2*day_alpha;
731 
732 		blend_colors(color, color_sky, color_sun, get_clouds_sunlight(normal), 3);
733 
734 		color[0] *= (1.0 - rain_coef) + rain_coef*weather_color[0];
735 		color[1] *= (1.0 - rain_coef) + rain_coef*weather_color[1];
736 		color[2] *= (1.0 - rain_coef) + rain_coef*weather_color[2];
737 
738 		if (lightning_falling) {
739 			skybox_vertex_to_ground_coords(&dome_clouds, i, &x, &y);
740 			lg = weather_get_lightning_intensity(x-camera_x, y-camera_y);
741 			color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
742 			color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
743 			color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
744 		}
745 
746 		dome_clouds.colors[idx] = color[0] + ml1*moon1_color[0] + ml2*moon2_color[0];
747 		dome_clouds_colors_bis[idx++] = color[0];
748 		dome_clouds.colors[idx] = color[1] + ml1*moon1_color[1] + ml2*moon2_color[1];
749 		dome_clouds_colors_bis[idx++] = color[1];
750 		dome_clouds.colors[idx] = color[2] + ml1*moon1_color[2] + ml2*moon2_color[2];
751 		dome_clouds_colors_bis[idx++] = color[2];
752         dome_clouds.colors[idx] = 1.0;
753 		dome_clouds_colors_bis[idx++] = rain_coef;
754 		++i;
755     }
756 
757 	i = idx = 0;
758 
759 	// clouds detail color
760 	skybox_blend_current_colors(color_sky, skybox_clouds_detail, skybox_clouds_detail_rainy, rain_coef);
761 	skybox_blend_current_colors(color_sun, skybox_clouds_detail_sunny, skybox_clouds_detail_rainy, rain_coef);
762     while (i < dome_clouds.slices_count * 2)
763     {
764 		blend_colors(color, color_sky, color_sun, get_clouds_sunlight(&dome_clouds.normals[i*3]), 3);
765 
766 		color[0] *= (1.0 - rain_coef) + rain_coef*weather_color[0];
767 		color[1] *= (1.0 - rain_coef) + rain_coef*weather_color[1];
768 		color[2] *= (1.0 - rain_coef) + rain_coef*weather_color[2];
769 
770 		if (lightning_falling) {
771 			skybox_vertex_to_ground_coords(&dome_clouds, i, &x, &y);
772 			lg = weather_get_lightning_intensity(x-camera_x, y-camera_y);
773 			color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
774 			color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
775 			color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
776 		}
777 
778 		dome_clouds_detail_colors[idx] = color[0];
779 		dome_clouds_detail_colors_bis[idx++] = color[0];
780 		dome_clouds_detail_colors[idx] = color[1];
781 		dome_clouds_detail_colors_bis[idx++] = color[1];
782 		dome_clouds_detail_colors[idx] = color[2];
783 		dome_clouds_detail_colors_bis[idx++] = color[2];
784         dome_clouds_detail_colors[idx] = 0.0;
785 		dome_clouds_detail_colors_bis[idx++] = 0.0;
786 		++i;
787     }
788     while (i < dome_clouds.vertices_count)
789     {
790 		blend_colors(color, color_sky, color_sun, get_clouds_sunlight(&dome_clouds.normals[i*3]), 3);
791 
792 		color[0] *= (1.0 - rain_coef) + rain_coef*weather_color[0];
793 		color[1] *= (1.0 - rain_coef) + rain_coef*weather_color[1];
794 		color[2] *= (1.0 - rain_coef) + rain_coef*weather_color[2];
795 
796 		if (lightning_falling) {
797 			skybox_vertex_to_ground_coords(&dome_clouds, i, &x, &y);
798 			lg = weather_get_lightning_intensity(x-camera_x, y-camera_y);
799 			color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
800 			color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
801 			color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
802 		}
803 
804 		dome_clouds_detail_colors[idx] = color[0];
805 		dome_clouds_detail_colors_bis[idx++] = color[0];
806 		dome_clouds_detail_colors[idx] = color[1];
807 		dome_clouds_detail_colors_bis[idx++] = color[1];
808 		dome_clouds_detail_colors[idx] = color[2];
809 		dome_clouds_detail_colors_bis[idx++] = color[2];
810         dome_clouds_detail_colors[idx] = 1.0;
811 		dome_clouds_detail_colors_bis[idx++] = rain_coef;
812 		++i;
813     }
814 
815 	i = idx = 0;
816 
817 	// sky color
818 	skybox_blend_current_colors(color_sky, skybox_sky1, skybox_fog_rainy, rain_coef);
819 	skybox_blend_current_colors(color_sun, skybox_sky1_sunny, skybox_fog_rainy, rain_coef);
820 	end = dome_sky.slices_count;
821     while (i < end)
822     {
823 		normal = &dome_sky.normals[i*3];
824 		ml1 = get_moonlight1(normal)*0.15*day_alpha;
825 		ml2 = get_moonlight2(normal)*0.1*day_alpha;
826 
827 		blend_colors(color, color_sky, color_sun, get_sky_sunlight(normal), 3);
828 
829 		color[0] *= (1.0 - rain_coef) + rain_coef*weather_color[0];
830 		color[1] *= (1.0 - rain_coef) + rain_coef*weather_color[1];
831 		color[2] *= (1.0 - rain_coef) + rain_coef*weather_color[2];
832 
833 		if (lightning_falling) {
834 			skybox_vertex_to_ground_coords(&dome_sky, i, &x, &y);
835 			lg = weather_get_lightning_intensity(x-camera_x, y-camera_y);
836 			color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
837 			color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
838 			color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
839 		}
840 
841 		dome_sky.colors[idx++] = color[0] + ml1*moon1_color[0] + ml2*moon2_color[0];
842 		dome_sky.colors[idx++] = color[1] + ml1*moon1_color[1] + ml2*moon2_color[1];
843 		dome_sky.colors[idx++] = color[2] + ml1*moon1_color[2] + ml2*moon2_color[2];
844 		dome_sky.colors[idx++] = 1.0;
845 		++i;
846     }
847 
848 	skybox_blend_current_colors(color_sky, skybox_sky2, skybox_fog_rainy, rain_coef);
849 	skybox_blend_current_colors(color_sun, skybox_sky2_sunny, skybox_fog_rainy, rain_coef);
850 	end += dome_sky.slices_count;
851     while (i < end)
852     {
853 		normal = &dome_sky.normals[i*3];
854 		ml1 = get_moonlight1(normal)*0.15*day_alpha;
855 		ml2 = get_moonlight2(normal)*0.1*day_alpha;
856 
857 		blend_colors(color, color_sky, color_sun, get_sky_sunlight(normal), 3);
858 
859 		color[0] *= (1.0 - rain_coef) + rain_coef*weather_color[0];
860 		color[1] *= (1.0 - rain_coef) + rain_coef*weather_color[1];
861 		color[2] *= (1.0 - rain_coef) + rain_coef*weather_color[2];
862 
863 		if (lightning_falling) {
864 			skybox_vertex_to_ground_coords(&dome_sky, i, &x, &y);
865 			lg = weather_get_lightning_intensity(x-camera_x, y-camera_y);
866 			color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
867 			color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
868 			color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
869 		}
870 
871 		dome_sky.colors[idx++] = color[0] + ml1*moon1_color[0] + ml2*moon2_color[0];
872 		dome_sky.colors[idx++] = color[1] + ml1*moon1_color[1] + ml2*moon2_color[1];
873 		dome_sky.colors[idx++] = color[2] + ml1*moon1_color[2] + ml2*moon2_color[2];
874 		dome_sky.colors[idx++] = 1.0;
875 		++i;
876     }
877 
878 	skybox_blend_current_colors(color_sky, skybox_sky3, skybox_fog_rainy, rain_coef);
879 	skybox_blend_current_colors(color_sun, skybox_sky3_sunny, skybox_fog_rainy, rain_coef);
880 	end += dome_sky.slices_count;
881     while (i < end)
882     {
883 		normal = &dome_sky.normals[i*3];
884 		ml1 = get_moonlight1(normal)*0.15*day_alpha;
885 		ml2 = get_moonlight2(normal)*0.1*day_alpha;
886 
887 		blend_colors(color, color_sky, color_sun, get_sky_sunlight(normal), 3);
888 
889 		color[0] *= (1.0 - rain_coef) + rain_coef*weather_color[0];
890 		color[1] *= (1.0 - rain_coef) + rain_coef*weather_color[1];
891 		color[2] *= (1.0 - rain_coef) + rain_coef*weather_color[2];
892 
893 		if (lightning_falling) {
894 			skybox_vertex_to_ground_coords(&dome_sky, i, &x, &y);
895 			lg = weather_get_lightning_intensity(x-camera_x, y-camera_y);
896 			color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
897 			color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
898 			color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
899 		}
900 
901 		dome_sky.colors[idx++] = color[0] + ml1*moon1_color[0] + ml2*moon2_color[0];
902 		dome_sky.colors[idx++] = color[1] + ml1*moon1_color[1] + ml2*moon2_color[1];
903 		dome_sky.colors[idx++] = color[2] + ml1*moon1_color[2] + ml2*moon2_color[2];
904 		dome_sky.colors[idx++] = 1.0;
905 		++i;
906     }
907 
908 	skybox_blend_current_colors(color_sky, skybox_sky4, skybox_fog_rainy, rain_coef);
909 	skybox_blend_current_colors(color_sun, skybox_sky4_sunny, skybox_fog_rainy, rain_coef);
910 	end += dome_sky.slices_count;
911     while (i < end)
912     {
913 		normal = &dome_sky.normals[i*3];
914 		ml1 = get_moonlight1(normal)*0.15*day_alpha;
915 		ml2 = get_moonlight2(normal)*0.1*day_alpha;
916 
917 		blend_colors(color, color_sky, color_sun, get_sky_sunlight(normal), 3);
918 
919 		color[0] *= (1.0 - rain_coef) + rain_coef*weather_color[0];
920 		color[1] *= (1.0 - rain_coef) + rain_coef*weather_color[1];
921 		color[2] *= (1.0 - rain_coef) + rain_coef*weather_color[2];
922 
923 		if (lightning_falling) {
924 			skybox_vertex_to_ground_coords(&dome_sky, i, &x, &y);
925 			lg = weather_get_lightning_intensity(x-camera_x, y-camera_y);
926 			color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
927 			color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
928 			color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
929 		}
930 
931 		dome_sky.colors[idx++] = color[0] + ml1*moon1_color[0] + ml2*moon2_color[0];
932 		dome_sky.colors[idx++] = color[1] + ml1*moon1_color[1] + ml2*moon2_color[1];
933 		dome_sky.colors[idx++] = color[2] + ml1*moon1_color[2] + ml2*moon2_color[2];
934 		dome_sky.colors[idx++] = 1.0;
935 		++i;
936     }
937 
938 	skybox_blend_current_colors(color_sky, skybox_sky5, skybox_fog_rainy, rain_coef);
939 	skybox_blend_current_colors(color_sun, skybox_sky5_sunny, skybox_fog_rainy, rain_coef);
940     while (i < dome_sky.vertices_count)
941     {
942 		normal = &dome_sky.normals[i*3];
943 		ml1 = get_moonlight1(normal)*0.15*day_alpha;
944 		ml2 = get_moonlight2(normal)*0.1*day_alpha;
945 
946 		blend_colors(color, color_sky, color_sun, get_sky_sunlight(normal), 3);
947 
948 		color[0] *= (1.0 - rain_coef) + rain_coef*weather_color[0];
949 		color[1] *= (1.0 - rain_coef) + rain_coef*weather_color[1];
950 		color[2] *= (1.0 - rain_coef) + rain_coef*weather_color[2];
951 
952 		if (lightning_falling) {
953 			skybox_vertex_to_ground_coords(&dome_sky, i, &x, &y);
954 			lg = weather_get_lightning_intensity(x-camera_x, y-camera_y);
955 			color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
956 			color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
957 			color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
958 		}
959 
960 		dome_sky.colors[idx++] = color[0] + ml1*moon1_color[0] + ml2*moon2_color[0];
961 		dome_sky.colors[idx++] = color[1] + ml1*moon1_color[1] + ml2*moon2_color[1];
962 		dome_sky.colors[idx++] = color[2] + ml1*moon1_color[2] + ml2*moon2_color[2];
963 		dome_sky.colors[idx++] = 1.0;
964 		++i;
965     }
966 
967 	memcpy(skybox_sky_color, color_sun, 4*sizeof(float));
968 
969 	// color of the moons update
970 	moon1_color[0] *= (0.5 + 0.5*day_alpha)*(1.0-rain_coef);
971 	moon1_color[1] *= (0.5 + 0.5*day_alpha)*(1.0-rain_coef);
972 	moon1_color[2] *= (0.5 + 0.5*day_alpha)*(1.0-rain_coef);
973 	moon2_color[0] *= (0.5 + 0.5*day_alpha)*(1.0-rain_coef);
974 	moon2_color[1] *= (0.5 + 0.5*day_alpha)*(1.0-rain_coef);
975 	moon2_color[2] *= (0.5 + 0.5*day_alpha)*(1.0-rain_coef);
976 }
977 
update_cloudy_sky_local_colors()978 void update_cloudy_sky_local_colors()
979 {
980     int i, idx, end;
981 	GLfloat color_sun[4];
982 	GLfloat color_sky[4];
983 	GLfloat color[4];
984 	GLfloat local_color[4];
985 	float abs_light;
986 	float ratios[MAX_WEATHER_TYPES];
987 	float *normal, ml1, ml2, x, y, lg;
988 
989 	abs_light = light_level;
990 	if(light_level > 59)
991 	{
992 		abs_light = 119 - light_level;
993 	}
994 	abs_light = 1.0f - abs_light/59.0f;
995 
996 	// alpha adjustment for objects that should fade in daylight
997 	day_alpha = (1.0-abs_light);
998 
999 	// color of the moons
1000 	moon1_color[0] = 0.9;
1001 	moon1_color[1] = 0.9;
1002 	moon1_color[2] = 0.9;
1003 	moon2_color[0] = 0.9;
1004 	moon2_color[1] = 0.8;
1005 	moon2_color[2] = 0.7;
1006 
1007 	// color of the sun
1008 	skybox_get_current_color(sun_color, skybox_sun);
1009 	weather_compute_ratios(ratios, skybox_sun_projection[0]-camera_x, skybox_sun_projection[1]-camera_y);
1010 	rain_coef = weather_get_density_from_ratios(ratios);
1011 	sun_color[0] *= 1.0 - rain_coef;
1012 	sun_color[1] *= 1.0 - rain_coef;
1013 	sun_color[2] *= 1.0 - rain_coef;
1014 	sun_color[3] *= 1.0 - rain_coef;
1015 
1016 	// color of the light
1017 	skybox_blend_current_colors(skybox_light_ambient_color, skybox_light_ambient, skybox_light_ambient_rainy, rain_coef);
1018 	skybox_blend_current_colors(skybox_light_diffuse_color, skybox_light_diffuse, skybox_light_diffuse_rainy, rain_coef);
1019 
1020     // we compute the color and the density of the fog
1021 	rain_coef = weather_get_intensity();
1022 	skybox_blend_current_colors(skybox_fog_color, skybox_fog, skybox_fog_rainy, rain_coef);
1023 	if (rain_coef > 0.0)
1024 	{
1025 		float fog_density;
1026 		rain_coef = weather_get_density();
1027 		blend_colors(&fog_density, &skybox_fog[game_minute][3], &skybox_fog[(game_minute+1)%360][3], (float)game_second/60.0, 1);
1028 		skybox_fog_color[0] *= (1.0-rain_coef) + rain_coef*weather_color[0];
1029 		skybox_fog_color[1] *= (1.0-rain_coef) + rain_coef*weather_color[1];
1030 		skybox_fog_color[2] *= (1.0-rain_coef) + rain_coef*weather_color[2];
1031 		skybox_fog_color[3] = (1.0-rain_coef)*fog_density + rain_coef*skybox_fog_color[3];
1032 	}
1033 	skybox_fog_density = skybox_fog_color[3];
1034 	skybox_fog_color[3] = 1.0;
1035 
1036 	i = idx = 0;
1037 
1038 	// clouds color
1039     while (i < dome_clouds.slices_count * 2)
1040     {
1041 		normal = &dome_clouds.normals[i*3];
1042 		ml1 = get_moonlight1(normal)*0.3*day_alpha;
1043 		ml2 = get_moonlight2(normal)*0.2*day_alpha;
1044 
1045 		skybox_vertex_to_ground_coords(&dome_clouds, i, &x, &y);
1046 		x -= camera_x;
1047 		y -= camera_y;
1048 		lg = weather_get_lightning_intensity(x, y);
1049 		weather_compute_ratios(ratios, x, y);
1050 		rain_coef = weather_get_density_from_ratios(ratios);
1051 		weather_get_color_from_ratios(local_color, ratios);
1052 
1053 		ml1 *= 1.0 - rain_coef;
1054 		ml2 *= 1.0 - rain_coef;
1055 
1056 		skybox_blend_current_colors(color_sky, skybox_clouds, skybox_clouds_rainy, rain_coef);
1057 		skybox_blend_current_colors(color_sun, skybox_clouds_sunny, skybox_clouds_rainy, rain_coef);
1058 
1059 		blend_colors(color, color_sky, color_sun, get_clouds_sunlight(normal), 3);
1060 
1061 		color[0] *= (1.0 - rain_coef) + rain_coef*local_color[0];
1062 		color[1] *= (1.0 - rain_coef) + rain_coef*local_color[1];
1063 		color[2] *= (1.0 - rain_coef) + rain_coef*local_color[2];
1064 
1065 		color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
1066 		color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
1067 		color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
1068 
1069 		dome_clouds.colors[idx] = color[0] + ml1*moon1_color[0] + ml2*moon2_color[0];
1070 		dome_clouds_colors_bis[idx++] = color[0];
1071 		dome_clouds.colors[idx] = color[1] + ml1*moon1_color[1] + ml2*moon2_color[1];
1072 		dome_clouds_colors_bis[idx++] = color[1];
1073 		dome_clouds.colors[idx] = color[2] + ml1*moon1_color[2] + ml2*moon2_color[2];
1074 		dome_clouds_colors_bis[idx++] = color[2];
1075         dome_clouds.colors[idx] = 0.0;
1076 		dome_clouds_colors_bis[idx++] = rain_coef;
1077 		++i;
1078     }
1079     while (i < dome_clouds.vertices_count)
1080     {
1081 		normal = &dome_clouds.normals[i*3];
1082 		ml1 = get_moonlight1(normal)*0.3*day_alpha;
1083 		ml2 = get_moonlight2(normal)*0.2*day_alpha;
1084 
1085 		skybox_vertex_to_ground_coords(&dome_clouds, i, &x, &y);
1086 		x -= camera_x;
1087 		y -= camera_y;
1088 		lg = weather_get_lightning_intensity(x, y);
1089 		weather_compute_ratios(ratios, x, y);
1090 		rain_coef = weather_get_density_from_ratios(ratios);
1091 		weather_get_color_from_ratios(local_color, ratios);
1092 
1093 		ml1 *= 1.0 - rain_coef;
1094 		ml2 *= 1.0 - rain_coef;
1095 
1096 		skybox_blend_current_colors(color_sky, skybox_clouds, skybox_clouds_rainy, rain_coef);
1097 		skybox_blend_current_colors(color_sun, skybox_clouds_sunny, skybox_clouds_rainy, rain_coef);
1098 
1099 		blend_colors(color, color_sky, color_sun, get_clouds_sunlight(normal), 3);
1100 
1101 		color[0] *= (1.0 - rain_coef) + rain_coef*local_color[0];
1102 		color[1] *= (1.0 - rain_coef) + rain_coef*local_color[1];
1103 		color[2] *= (1.0 - rain_coef) + rain_coef*local_color[2];
1104 
1105 		color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
1106 		color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
1107 		color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
1108 
1109 		dome_clouds.colors[idx] = color[0] + ml1*moon1_color[0] + ml2*moon2_color[0];
1110 		dome_clouds_colors_bis[idx++] = color[0];
1111 		dome_clouds.colors[idx] = color[1] + ml1*moon1_color[1] + ml2*moon2_color[1];
1112 		dome_clouds_colors_bis[idx++] = color[1];
1113 		dome_clouds.colors[idx] = color[2] + ml1*moon1_color[2] + ml2*moon2_color[2];
1114 		dome_clouds_colors_bis[idx++] = color[2];
1115         dome_clouds.colors[idx] = 1.0;
1116 		dome_clouds_colors_bis[idx++] = rain_coef;
1117 		++i;
1118     }
1119 
1120 	i = idx = 0;
1121 
1122 	// clouds detail color
1123     while (i < dome_clouds.slices_count * 2)
1124     {
1125 		skybox_vertex_to_ground_coords(&dome_clouds, i, &x, &y);
1126 		x -= camera_x;
1127 		y -= camera_y;
1128 		weather_compute_ratios(ratios, x, y);
1129 		rain_coef = weather_get_density_from_ratios(ratios);
1130 		weather_get_color_from_ratios(local_color, ratios);
1131 
1132 		skybox_blend_current_colors(color_sky, skybox_clouds_detail, skybox_clouds_detail_rainy, rain_coef);
1133 		skybox_blend_current_colors(color_sun, skybox_clouds_detail_sunny, skybox_clouds_detail_rainy, rain_coef);
1134 
1135 		blend_colors(color, color_sky, color_sun, get_clouds_sunlight(&dome_clouds.normals[i*3]), 3);
1136 
1137 		color[0] *= (1.0 - rain_coef) + rain_coef*local_color[0];
1138 		color[1] *= (1.0 - rain_coef) + rain_coef*local_color[1];
1139 		color[2] *= (1.0 - rain_coef) + rain_coef*local_color[2];
1140 
1141 		dome_clouds_detail_colors[idx] = color[0];
1142 		dome_clouds_detail_colors_bis[idx++] = color[0];
1143 		dome_clouds_detail_colors[idx] = color[1];
1144 		dome_clouds_detail_colors_bis[idx++] = color[1];
1145 		dome_clouds_detail_colors[idx] = color[2];
1146 		dome_clouds_detail_colors_bis[idx++] = color[2];
1147         dome_clouds_detail_colors[idx] = 0.0;
1148 		dome_clouds_detail_colors_bis[idx++] = 0.0;
1149 		++i;
1150     }
1151     while (i < dome_clouds.vertices_count)
1152     {
1153 		skybox_vertex_to_ground_coords(&dome_clouds, i, &x, &y);
1154 		x -= camera_x;
1155 		y -= camera_y;
1156 		weather_compute_ratios(ratios, x, y);
1157 		rain_coef = weather_get_density_from_ratios(ratios);
1158 		weather_get_color_from_ratios(local_color, ratios);
1159 
1160 		skybox_blend_current_colors(color_sky, skybox_clouds_detail, skybox_clouds_detail_rainy, rain_coef);
1161 		skybox_blend_current_colors(color_sun, skybox_clouds_detail_sunny, skybox_clouds_detail_rainy, rain_coef);
1162 
1163 		blend_colors(color, color_sky, color_sun, get_clouds_sunlight(&dome_clouds.normals[i*3]), 3);
1164 
1165 		color[0] *= (1.0 - rain_coef) + rain_coef*local_color[0];
1166 		color[1] *= (1.0 - rain_coef) + rain_coef*local_color[1];
1167 		color[2] *= (1.0 - rain_coef) + rain_coef*local_color[2];
1168 
1169 		dome_clouds_detail_colors[idx] = color[0];
1170 		dome_clouds_detail_colors_bis[idx++] = color[0];
1171 		dome_clouds_detail_colors[idx] = color[1];
1172 		dome_clouds_detail_colors_bis[idx++] = color[1];
1173 		dome_clouds_detail_colors[idx] = color[2];
1174 		dome_clouds_detail_colors_bis[idx++] = color[2];
1175         dome_clouds_detail_colors[idx] = 1.0;
1176 		dome_clouds_detail_colors_bis[idx++] = rain_coef;
1177 		++i;
1178     }
1179 
1180 	i = idx = 0;
1181 
1182 	// sky color
1183 	end = dome_sky.slices_count;
1184     while (i < end)
1185     {
1186 		normal = &dome_sky.normals[i*3];
1187 		ml1 = get_moonlight1(normal)*0.15*day_alpha;
1188 		ml2 = get_moonlight2(normal)*0.1*day_alpha;
1189 
1190 		skybox_vertex_to_ground_coords(&dome_sky, i, &x, &y);
1191 		x -= camera_x;
1192 		y -= camera_y;
1193 		lg = weather_get_lightning_intensity(x, y);
1194 		weather_compute_ratios(ratios, x, y);
1195 		rain_coef = weather_get_density_from_ratios(ratios);
1196 		weather_get_color_from_ratios(local_color, ratios);
1197 
1198 		ml1 *= 1.0 - rain_coef;
1199 		ml2 *= 1.0 - rain_coef;
1200 
1201 		skybox_blend_current_colors(color_sky, skybox_sky1, skybox_fog_rainy, rain_coef);
1202 		skybox_blend_current_colors(color_sun, skybox_sky1_sunny, skybox_fog_rainy, rain_coef);
1203 
1204 		blend_colors(color, color_sky, color_sun, get_sky_sunlight(normal), 3);
1205 
1206 		color[0] *= (1.0 - rain_coef) + rain_coef*local_color[0];
1207 		color[1] *= (1.0 - rain_coef) + rain_coef*local_color[1];
1208 		color[2] *= (1.0 - rain_coef) + rain_coef*local_color[2];
1209 
1210 		color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
1211 		color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
1212 		color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
1213 
1214 		dome_sky.colors[idx++] = color[0] + ml1*moon1_color[0] + ml2*moon2_color[0];
1215 		dome_sky.colors[idx++] = color[1] + ml1*moon1_color[1] + ml2*moon2_color[1];
1216 		dome_sky.colors[idx++] = color[2] + ml1*moon1_color[2] + ml2*moon2_color[2];
1217 		dome_sky.colors[idx++] = 1.0;
1218 		++i;
1219     }
1220 
1221 	end += dome_sky.slices_count;
1222     while (i < end)
1223     {
1224 		normal = &dome_sky.normals[i*3];
1225 		ml1 = get_moonlight1(normal)*0.15*day_alpha;
1226 		ml2 = get_moonlight2(normal)*0.1*day_alpha;
1227 
1228 		skybox_vertex_to_ground_coords(&dome_sky, i, &x, &y);
1229 		x -= camera_x;
1230 		y -= camera_y;
1231 		lg = weather_get_lightning_intensity(x, y);
1232 		weather_compute_ratios(ratios, x, y);
1233 		rain_coef = weather_get_density_from_ratios(ratios);
1234 		weather_get_color_from_ratios(local_color, ratios);
1235 
1236 		ml1 *= 1.0 - rain_coef;
1237 		ml2 *= 1.0 - rain_coef;
1238 
1239 		skybox_blend_current_colors(color_sky, skybox_sky2, skybox_fog_rainy, rain_coef);
1240 		skybox_blend_current_colors(color_sun, skybox_sky2_sunny, skybox_fog_rainy, rain_coef);
1241 
1242 		blend_colors(color, color_sky, color_sun, get_sky_sunlight(normal), 3);
1243 
1244 		color[0] *= (1.0 - rain_coef) + rain_coef*local_color[0];
1245 		color[1] *= (1.0 - rain_coef) + rain_coef*local_color[1];
1246 		color[2] *= (1.0 - rain_coef) + rain_coef*local_color[2];
1247 
1248 		color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
1249 		color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
1250 		color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
1251 
1252 		dome_sky.colors[idx++] = color[0] + ml1*moon1_color[0] + ml2*moon2_color[0];
1253 		dome_sky.colors[idx++] = color[1] + ml1*moon1_color[1] + ml2*moon2_color[1];
1254 		dome_sky.colors[idx++] = color[2] + ml1*moon1_color[2] + ml2*moon2_color[2];
1255 		dome_sky.colors[idx++] = 1.0;
1256 		++i;
1257     }
1258 
1259 	end += dome_sky.slices_count;
1260     while (i < end)
1261     {
1262 		normal = &dome_sky.normals[i*3];
1263 		ml1 = get_moonlight1(normal)*0.15*day_alpha;
1264 		ml2 = get_moonlight2(normal)*0.1*day_alpha;
1265 
1266 		skybox_vertex_to_ground_coords(&dome_sky, i, &x, &y);
1267 		x -= camera_x;
1268 		y -= camera_y;
1269 		lg = weather_get_lightning_intensity(x, y);
1270 		weather_compute_ratios(ratios, x, y);
1271 		rain_coef = weather_get_density_from_ratios(ratios);
1272 		weather_get_color_from_ratios(local_color, ratios);
1273 
1274 		ml1 *= 1.0 - rain_coef;
1275 		ml2 *= 1.0 - rain_coef;
1276 
1277 		skybox_blend_current_colors(color_sky, skybox_sky3, skybox_fog_rainy, rain_coef);
1278 		skybox_blend_current_colors(color_sun, skybox_sky3_sunny, skybox_fog_rainy, rain_coef);
1279 
1280 		blend_colors(color, color_sky, color_sun, get_sky_sunlight(normal), 3);
1281 
1282 		color[0] *= (1.0 - rain_coef) + rain_coef*local_color[0];
1283 		color[1] *= (1.0 - rain_coef) + rain_coef*local_color[1];
1284 		color[2] *= (1.0 - rain_coef) + rain_coef*local_color[2];
1285 
1286 		color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
1287 		color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
1288 		color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
1289 
1290 		dome_sky.colors[idx++] = color[0] + ml1*moon1_color[0] + ml2*moon2_color[0];
1291 		dome_sky.colors[idx++] = color[1] + ml1*moon1_color[1] + ml2*moon2_color[1];
1292 		dome_sky.colors[idx++] = color[2] + ml1*moon1_color[2] + ml2*moon2_color[2];
1293 		dome_sky.colors[idx++] = 1.0;
1294 		++i;
1295     }
1296 
1297 	end += dome_sky.slices_count;
1298     while (i < end)
1299     {
1300 		normal = &dome_sky.normals[i*3];
1301 		ml1 = get_moonlight1(normal)*0.15*day_alpha;
1302 		ml2 = get_moonlight2(normal)*0.1*day_alpha;
1303 
1304 		skybox_vertex_to_ground_coords(&dome_sky, i, &x, &y);
1305 		x -= camera_x;
1306 		y -= camera_y;
1307 		lg = weather_get_lightning_intensity(x, y);
1308 		weather_compute_ratios(ratios, x, y);
1309 		rain_coef = weather_get_density_from_ratios(ratios);
1310 		weather_get_color_from_ratios(local_color, ratios);
1311 
1312 		ml1 *= 1.0 - rain_coef;
1313 		ml2 *= 1.0 - rain_coef;
1314 
1315 		skybox_blend_current_colors(color_sky, skybox_sky4, skybox_fog_rainy, rain_coef);
1316 		skybox_blend_current_colors(color_sun, skybox_sky4_sunny, skybox_fog_rainy, rain_coef);
1317 
1318 		blend_colors(color, color_sky, color_sun, get_sky_sunlight(normal), 3);
1319 
1320 		color[0] *= (1.0 - rain_coef) + rain_coef*local_color[0];
1321 		color[1] *= (1.0 - rain_coef) + rain_coef*local_color[1];
1322 		color[2] *= (1.0 - rain_coef) + rain_coef*local_color[2];
1323 
1324 		color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
1325 		color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
1326 		color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
1327 
1328 		dome_sky.colors[idx++] = color[0] + ml1*moon1_color[0] + ml2*moon2_color[0];
1329 		dome_sky.colors[idx++] = color[1] + ml1*moon1_color[1] + ml2*moon2_color[1];
1330 		dome_sky.colors[idx++] = color[2] + ml1*moon1_color[2] + ml2*moon2_color[2];
1331 		dome_sky.colors[idx++] = 1.0;
1332 		++i;
1333     }
1334 
1335     while (i < dome_sky.vertices_count)
1336     {
1337 		normal = &dome_sky.normals[i*3];
1338 		ml1 = get_moonlight1(normal)*0.15*day_alpha;
1339 		ml2 = get_moonlight2(normal)*0.1*day_alpha;
1340 
1341 		skybox_vertex_to_ground_coords(&dome_sky, i, &x, &y);
1342 		x -= camera_x;
1343 		y -= camera_y;
1344 		lg = weather_get_lightning_intensity(x, y);
1345 		weather_compute_ratios(ratios, x, y);
1346 		rain_coef = weather_get_density_from_ratios(ratios);
1347 		weather_get_color_from_ratios(local_color, ratios);
1348 
1349 		ml1 *= 1.0 - rain_coef;
1350 		ml2 *= 1.0 - rain_coef;
1351 
1352 		skybox_blend_current_colors(color_sky, skybox_sky5, skybox_fog_rainy, rain_coef);
1353 		skybox_blend_current_colors(color_sun, skybox_sky5_sunny, skybox_fog_rainy, rain_coef);
1354 
1355 		blend_colors(color, color_sky, color_sun, get_sky_sunlight(normal), 3);
1356 
1357 		color[0] *= (1.0 - rain_coef) + rain_coef*local_color[0];
1358 		color[1] *= (1.0 - rain_coef) + rain_coef*local_color[1];
1359 		color[2] *= (1.0 - rain_coef) + rain_coef*local_color[2];
1360 
1361 		color[0] = color[0]*(1.0-lg) + lightning_color[0]*lg;
1362 		color[1] = color[1]*(1.0-lg) + lightning_color[1]*lg;
1363 		color[2] = color[2]*(1.0-lg) + lightning_color[2]*lg;
1364 
1365 		dome_sky.colors[idx++] = color[0] + ml1*moon1_color[0] + ml2*moon2_color[0];
1366 		dome_sky.colors[idx++] = color[1] + ml1*moon1_color[1] + ml2*moon2_color[1];
1367 		dome_sky.colors[idx++] = color[2] + ml1*moon1_color[2] + ml2*moon2_color[2];
1368 		dome_sky.colors[idx++] = 1.0;
1369 		++i;
1370     }
1371 
1372 	skybox_blend_current_colors(skybox_sky_color, skybox_sky5_sunny, skybox_fog_rainy, weather_get_density());
1373 
1374 	// color of the moons update
1375 	moon1_color[0] *= (0.5 + 0.5*day_alpha);
1376 	moon1_color[1] *= (0.5 + 0.5*day_alpha);
1377 	moon1_color[2] *= (0.5 + 0.5*day_alpha);
1378 	moon2_color[0] *= (0.5 + 0.5*day_alpha);
1379 	moon2_color[1] *= (0.5 + 0.5*day_alpha);
1380 	moon2_color[2] *= (0.5 + 0.5*day_alpha);
1381 }
1382 
update_underworld_sky_colors()1383 void update_underworld_sky_colors()
1384 {
1385 	int i, idx, end;
1386 
1387 	i = idx = 0;
1388 
1389 	end = dome_sky.slices_count;
1390 	while (i < end)
1391 	{
1392 		dome_sky.colors[idx++] = 230/255.0;
1393 		dome_sky.colors[idx++] = 104/255.0;
1394 		dome_sky.colors[idx++] =  11/255.0;
1395 		dome_sky.colors[idx++] = 1.0;
1396 		++i;
1397 	}
1398 
1399 	end += dome_sky.slices_count;
1400 	while (i < end)
1401 	{
1402 		dome_sky.colors[idx++] = 230/255.0;
1403 		dome_sky.colors[idx++] = 104/255.0;
1404 		dome_sky.colors[idx++] =  11/255.0;
1405 		dome_sky.colors[idx++] = 1.0;
1406 		++i;
1407 	}
1408 
1409 	end += dome_sky.slices_count;
1410 	while (i < end)
1411 	{
1412 		dome_sky.colors[idx++] = 201/255.0;
1413 		dome_sky.colors[idx++] =  58/255.0;
1414 		dome_sky.colors[idx++] =  13/255.0;
1415 		dome_sky.colors[idx++] = 0.8;
1416 		++i;
1417 	}
1418 
1419 	end += dome_sky.slices_count;
1420 	while (i < end)
1421 	{
1422 		dome_sky.colors[idx++] =  83/255.0;
1423 		dome_sky.colors[idx++] =  31/255.0;
1424 		dome_sky.colors[idx++] =  23/255.0;
1425 		dome_sky.colors[idx++] = 0.6;
1426 		++i;
1427 	}
1428 
1429     while (i < dome_sky.vertices_count)
1430     {
1431 		dome_sky.colors[idx++] =  33/255.0;
1432 		dome_sky.colors[idx++] =   6/255.0;
1433 		dome_sky.colors[idx++] =  16/255.0;
1434 		dome_sky.colors[idx++] = 0.0;
1435 		++i;
1436 	}
1437 
1438 	memcpy(skybox_fog_color, &dome_sky.colors[(dome_sky.vertices_count-1)*4], 3*sizeof(float));
1439 	skybox_fog_color[3] = 1.0;
1440 	skybox_fog_density = 0.01;
1441 	memcpy(skybox_sky_color, skybox_fog_color, 4*sizeof(float));
1442 }
1443 
cloudy_sky()1444 void cloudy_sky()
1445 {
1446 	static Uint32 last_cloud_time = 0;
1447 	int i;
1448 	GLfloat black_color[] = {0.0, 0.0, 0.0, 0.0};
1449 
1450 	// disable lights not used for sky just in case
1451 	switch(show_lights)
1452 	{
1453 	case 6:
1454 		glDisable(GL_LIGHT6);
1455 		// fall-through - suppress the compile warning with this comment
1456 	case 5:
1457 		glDisable(GL_LIGHT5);
1458 		// fall-through
1459 	case 4:
1460 		glDisable(GL_LIGHT4);
1461 		// fall-through
1462 	case 3:
1463 		glDisable(GL_LIGHT3);
1464 		// fall-through
1465 	case 2:
1466 		glDisable(GL_LIGHT2);
1467 		// fall-through
1468 	case 1:
1469 		glDisable(GL_LIGHT1);
1470 		// fall-through
1471 	default:
1472 		glDisable(GL_LIGHT0);
1473 		break;
1474 	}
1475 
1476 	glPushAttrib(GL_TEXTURE_BIT|GL_ENABLE_BIT);
1477 
1478 	glEnable(GL_CULL_FACE);
1479 	glDisable(GL_LIGHTING);
1480 	glDisable(GL_FOG);
1481 	glDisable(GL_BLEND);
1482 	glDisable(GL_TEXTURE_2D);
1483     glDisable(GL_ALPHA_TEST);
1484 	glEnable(GL_COLOR_MATERIAL);
1485 
1486     glDisable(GL_DEPTH_TEST);
1487 
1488 	// we draw a ring to continue the sky a bit under the horizon
1489 	glBegin(GL_QUAD_STRIP);
1490 	for (i = 0; i < dome_sky.slices_count; ++i)
1491 	{
1492 		const GLfloat *vtx = &dome_sky.vertices[i*3];
1493 		glColor3fv(&dome_sky.colors[i*4]);
1494 		glVertex3f(vtx[0]*0.9, vtx[1]*0.9, -dome_sky.height*0.1);
1495 		glVertex3fv(vtx);
1496 	}
1497 	glColor3fv(&dome_sky.colors[0]);
1498 	glVertex3f(dome_sky.vertices[0]*0.9, dome_sky.vertices[1]*0.9, -dome_sky.height*0.1);
1499 	glVertex3fv(&dome_sky.vertices[0]);
1500 	glEnd();
1501 
1502 	// we draw the sky background
1503     glEnableClientState(GL_VERTEX_ARRAY);
1504     glEnableClientState(GL_COLOR_ARRAY);
1505 
1506     glVertexPointer(3, GL_FLOAT, 0, dome_sky.vertices);
1507     glColorPointer(4, GL_FLOAT, 0, dome_sky.colors);
1508 
1509     glDrawElements(GL_TRIANGLES, dome_sky.faces_count*3, GL_UNSIGNED_INT, dome_sky.faces);
1510 
1511     glDisableClientState(GL_VERTEX_ARRAY);
1512     glDisableClientState(GL_COLOR_ARRAY);
1513 
1514 	glEnable(GL_BLEND);
1515 
1516     glEnable(GL_DEPTH_TEST); // we need it to draw moons and stars
1517     glClear(GL_DEPTH_BUFFER_BIT);
1518 	glEnable(GL_TEXTURE_2D);
1519 	glBlendFunc(GL_SRC_COLOR, GL_ONE);
1520 
1521 	// we draw the moons
1522 	if(skybox_show_moons && !skybox_no_moons)
1523 	{
1524 		// the current light color is black so we change it to light the moons
1525 		GLfloat light_color[] = {0.8, 0.8, 0.8, 1.0};
1526 		glLightfv(GL_LIGHT7, GL_DIFFUSE, light_color);
1527 
1528 		glPushMatrix();
1529 		glRotatef((float)game_minute+(float)game_second/60.0, 0.0, -1.0, 0.0);
1530 
1531 		glEnable(GL_LIGHTING);
1532 		glDisable(GL_COLOR_MATERIAL);
1533 		bind_texture(moon_tex);
1534 		glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, black_color);
1535 
1536 		glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, moon1_color);
1537 
1538 		glPushMatrix();
1539 		glRotatef(moon_spin, 0.0, 1.0, 0.0);
1540 		glTranslatef(0.0, 0.0, 450.0);
1541 		glRotatef(90.0, 1.0, 0.0, 0.0);
1542 		glRotatef(moon_spin, 0.0, 0.0, 1.0);
1543 		glScalef(20.0, 20.0, 20.0);
1544 		//glCallList(sky_lists+3);
1545 		draw_sphere(&moon_mesh);
1546 		glPopMatrix();
1547 
1548 		glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, moon2_color);
1549 
1550 		glPushMatrix();
1551 		glRotatef(20.0, 0.0, 0.0, 1.0);
1552 		glRotatef(10.0*moon_spin, 0.0, 1.0, 0.0);
1553 		glTranslatef(0.0, 0.0, 480.0);
1554 		glRotatef(90.0, 1.0, 0.0, 0.0);
1555 		glRotatef(10.0*moon_spin, 0.0, 0.0, 1.0);
1556 		glScalef(12.0, 12.0, 12.0);
1557 		//glCallList(sky_lists+3);
1558 		draw_sphere(&moon_mesh);
1559 		glPopMatrix();
1560 
1561 		glPopMatrix();
1562 		glLightfv(GL_LIGHT7, GL_DIFFUSE, diffuse_light); // we restore the light color
1563 		glEnable(GL_COLOR_MATERIAL);
1564 		glDisable(GL_LIGHTING);
1565 	}
1566 
1567 	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1568     glDepthMask(GL_FALSE); // we don't want the stars to update the depth buffer
1569     glDisable(GL_TEXTURE_2D);
1570 
1571 	// we draw the stars
1572 	if (skybox_show_stars && !skybox_no_stars && day_alpha > 0.0)
1573 	{
1574 		glPushMatrix();
1575 		glPointSize(1.0);
1576 		glRotatef((float)game_minute+(float)game_second/60.0, 0.0, -1.0, 0.0);
1577 		glColor4f(1.0, 1.0, 1.0, day_alpha);
1578 		glCallList(sky_lists);
1579 		glColor4f(1.0, 1.0, 1.0, day_alpha*0.5);
1580 		glCallList(sky_lists+1);
1581 		glColor4f(1.0, 1.0, 1.0, day_alpha*0.25);
1582 		glCallList(sky_lists+2);
1583 		glPopMatrix();
1584 	}
1585 
1586     glDepthMask(GL_TRUE);
1587 	glDisable(GL_DEPTH_TEST);
1588 	glEnable(GL_TEXTURE_2D);
1589 
1590 	// we draw the clouds
1591 	if (skybox_show_clouds && !skybox_no_clouds)
1592 	{
1593 		float clouds_step = (cur_time - last_cloud_time)*2E-6;
1594 
1595 		// we update the tex coords for the first clouds layer
1596 		if (dome_clouds.tex_coords[0] <= 1.0)
1597 		{
1598 			for (i = dome_clouds.vertices_count; i--; )
1599 				dome_clouds.tex_coords[i*2] += clouds_step;
1600 		}
1601 		else
1602 		{
1603 			for (i = dome_clouds.vertices_count; i--; )
1604 				dome_clouds.tex_coords[i*2] += clouds_step - 1.0;
1605 		}
1606 
1607 		// we update the tex coords for the second clouds layer
1608 		if (dome_clouds_tex_coords_bis[0] <= 1.0)
1609 		{
1610 			for (i = dome_clouds.vertices_count; i--; )
1611 				dome_clouds_tex_coords_bis[i*2] += clouds_step*2.0;
1612 		}
1613 		else
1614 		{
1615 			for (i = dome_clouds.vertices_count; i--; )
1616 				dome_clouds_tex_coords_bis[i*2] += clouds_step*2.0 - 1.0;
1617 		}
1618 
1619 		glEnableClientState(GL_VERTEX_ARRAY);
1620 		glEnableClientState(GL_COLOR_ARRAY);
1621 		glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1622 
1623 		glVertexPointer(3, GL_FLOAT, 0, dome_clouds.vertices);
1624 		glColorPointer(4, GL_FLOAT, 0, dome_clouds.colors);
1625 		glTexCoordPointer(2, GL_FLOAT, 0, dome_clouds.tex_coords);
1626 
1627 		bind_texture(skybox_clouds_tex);
1628 
1629 		glDrawElements(GL_TRIANGLES, dome_clouds.faces_count*3, GL_UNSIGNED_INT, dome_clouds.faces);
1630 
1631 		{
1632 			// we draw the second clouds layer
1633 			bind_texture(thick_clouds_tex);
1634 			glColorPointer(4, GL_FLOAT, 0, dome_clouds_colors_bis);
1635 			glTexCoordPointer(2, GL_FLOAT, 0, dome_clouds_tex_coords_bis);
1636 			glPushMatrix();
1637 			glScalef(1.0, 1.0, 0.95);
1638 			glDrawElements(GL_TRIANGLES, dome_clouds.faces_count*3, GL_UNSIGNED_INT, dome_clouds.faces);
1639 			glPopMatrix();
1640 		}
1641 
1642 		glDisableClientState(GL_VERTEX_ARRAY);
1643 		glDisableClientState(GL_COLOR_ARRAY);
1644 		glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1645 	}
1646 
1647 	glBlendFunc(GL_SRC_COLOR, GL_ONE);
1648 
1649 	// draw the sun
1650 	if (skybox_show_sun && !skybox_no_sun &&
1651 		(skybox_sun_position[0] != 0.0 ||
1652 		 skybox_sun_position[1] != 0.0 ||
1653 		 skybox_sun_position[2] != 0.0))
1654 	{
1655 		glColor4fv(sun_color);
1656 		bind_texture(sun_tex);
1657 		glPushMatrix();
1658 		glScalef(480.0, 480.0, 480.0);
1659 		glBegin(GL_QUADS);
1660 		{
1661 			//two cross products. Dangerous to use these functions. Float type essential.
1662 			//Better to robustly produce two vectors in perpendicular plane elsewhere.
1663 			VECTOR3 perp1, perp2, someVec = {0.0, 1.0, 0.0};
1664 			VCross(perp1, someVec, skybox_sun_position);
1665 			VCross(perp2, perp1, skybox_sun_position);
1666 			glTexCoord2f(0,0);
1667 			glVertex3f(skybox_sun_position[0]+.08*(perp1[0]+perp2[0]),
1668 					   skybox_sun_position[1]+.08*(perp1[1]+perp2[1]),
1669 					   skybox_sun_position[2]+.08*(perp1[2]+perp2[2]));
1670 			glTexCoord2f(1,0);
1671 			glVertex3f(skybox_sun_position[0]+.08*(-perp1[0]+perp2[0]),
1672 					   skybox_sun_position[1]+.08*(-perp1[1]+perp2[1]),
1673 					   skybox_sun_position[2]+.08*(-perp1[2]+perp2[2]));
1674 			glTexCoord2f(1,1);
1675 			glVertex3f(skybox_sun_position[0]+.08*(-perp1[0]-perp2[0]),
1676 					   skybox_sun_position[1]+.08*(-perp1[1]-perp2[1]),
1677 					   skybox_sun_position[2]+.08*(-perp1[2]-perp2[2]));
1678 			glTexCoord2f(0,1);
1679 			glVertex3f(skybox_sun_position[0]+.08*(perp1[0]-perp2[0]),
1680 					   skybox_sun_position[1]+.08*(perp1[1]-perp2[1]),
1681 					   skybox_sun_position[2]+.08*(perp1[2]-perp2[2]));
1682 		}
1683 		glEnd();
1684 		glPopMatrix();
1685 	}
1686 
1687 	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1688 
1689 	// we draw the clouds detail
1690 	if (skybox_show_clouds && !skybox_no_clouds)
1691 	{
1692 		glEnableClientState(GL_VERTEX_ARRAY);
1693 		glEnableClientState(GL_COLOR_ARRAY);
1694 		glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1695 
1696 		bind_texture(skybox_clouds_detail_tex);
1697 		glVertexPointer(3, GL_FLOAT, 0, dome_clouds.vertices);
1698 		glColorPointer(4, GL_FLOAT, 0, dome_clouds_detail_colors);
1699 		glTexCoordPointer(2, GL_FLOAT, 0, dome_clouds.tex_coords);
1700 
1701 		glPushMatrix();
1702 		glScalef(1.0, 1.0, 0.98);
1703 		glDrawElements(GL_TRIANGLES, dome_clouds.faces_count*3, GL_UNSIGNED_INT, dome_clouds.faces);
1704 		glPopMatrix();
1705 
1706 		{
1707 			bind_texture(thick_clouds_detail_tex);
1708 			glColorPointer(4, GL_FLOAT, 0, dome_clouds_detail_colors_bis);
1709 			glTexCoordPointer(2, GL_FLOAT, 0, dome_clouds_tex_coords_bis);
1710 			glPushMatrix();
1711 			glScalef(1.0, 1.0, 0.93);
1712 			glDrawElements(GL_TRIANGLES, dome_clouds.faces_count*3, GL_UNSIGNED_INT, dome_clouds.faces);
1713 			glPopMatrix();
1714 		}
1715 
1716 		glDisableClientState(GL_VERTEX_ARRAY);
1717 		glDisableClientState(GL_COLOR_ARRAY);
1718 		glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1719 	}
1720 
1721 	glDisable(GL_TEXTURE_2D);
1722 
1723 	// we fade the sky that is under the horizon
1724 	glBegin(GL_QUAD_STRIP);
1725 	for (i = 0; i < dome_sky.slices_count; ++i)
1726 	{
1727 		const GLfloat *vtx = &dome_sky.vertices[i*3];
1728 		glColor4fv(skybox_fog_color);
1729 		glVertex3f(vtx[0]*0.9, vtx[1]*0.9, -dome_sky.height*0.1);
1730 		glColor4f(skybox_fog_color[0], skybox_fog_color[1], skybox_fog_color[2], 0.0);
1731 		glVertex3fv(vtx);
1732 	}
1733 	glColor4fv(skybox_fog_color);
1734 	glVertex3f(dome_sky.vertices[0]*0.9, dome_sky.vertices[1]*0.9, -dome_sky.height*0.1);
1735 	glColor4f(skybox_fog_color[0], skybox_fog_color[1], skybox_fog_color[2], 0.0);
1736 	glVertex3fv(&dome_sky.vertices[0]);
1737 	glEnd();
1738 
1739 	// we mask all the elements that are under the horizon with the fog color
1740 	glBegin(GL_TRIANGLE_FAN);
1741 	glColor3fv(skybox_fog_color);
1742 	glVertex3f(0.0, 0.0, -dome_sky.height);
1743 	for (i = 0; i < dome_sky.slices_count; ++i)
1744 	{
1745 		const GLfloat *vtx = &dome_sky.vertices[i*3];
1746 		glVertex3f(vtx[0]*0.9, vtx[1]*0.9, -dome_sky.height*0.1);
1747 	}
1748 	glVertex3f(dome_sky.vertices[0]*0.9, dome_sky.vertices[1]*0.9, -dome_sky.height*0.1);
1749 	glEnd();
1750 
1751 	glPopAttrib();
1752 	reset_material();
1753 	last_texture = -1;
1754 
1755     // we restore the lights
1756 	if(!is_day||dungeon)
1757 	{
1758 		switch(show_lights)
1759 		{
1760 		case 6:
1761 			glEnable(GL_LIGHT6);
1762 			// fall-through - suppress the compile warning with this comment
1763 		case 5:
1764 			glEnable(GL_LIGHT5);
1765 			// fall-through
1766 		case 4:
1767 			glEnable(GL_LIGHT4);
1768 			// fall-through
1769 		case 3:
1770 			glEnable(GL_LIGHT3);
1771 			// fall-through
1772 		case 2:
1773 			glEnable(GL_LIGHT2);
1774 			// fall-through
1775 		case 1:
1776 			glEnable(GL_LIGHT1);
1777 			// fall-through
1778 		default:
1779 			glEnable(GL_LIGHT0);
1780 			break;
1781 		}
1782 	}
1783 
1784 	last_cloud_time = cur_time;
1785 }
1786 
underworld_sky()1787 void underworld_sky()
1788 {
1789 	static Uint32 last_cloud_time = 0;
1790 	int i;
1791 
1792 	glTranslatef(0.0, 0.0, -40.0);
1793 
1794 	glPushAttrib(GL_TEXTURE_BIT|GL_ENABLE_BIT);
1795 	glClear(GL_DEPTH_BUFFER_BIT);
1796 
1797 /* 	if(use_shadow_mapping) */
1798 /* 	{ */
1799 /* 		glDisable(GL_TEXTURE_2D); */
1800 /* 		ELglActiveTextureARB(shadow_unit); */
1801 /* 		glDisable(depth_texture_target); */
1802 /* 		disable_texgen(); */
1803 /* 		ELglActiveTextureARB(GL_TEXTURE0); */
1804 /* 		glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); */
1805 /* 	} */
1806 
1807 	glDisable(GL_LIGHTING);
1808 	glDisable(GL_FOG);
1809 	glEnable(GL_COLOR_MATERIAL);
1810 	glDisable(GL_TEXTURE_2D);
1811 	glDisable(GL_DEPTH_TEST);
1812 	glEnable(GL_BLEND);
1813 
1814 	if (skybox_show_clouds)
1815 	{
1816 		float clouds_step = (cur_time - last_cloud_time)*1E-5;
1817 
1818 		// we update the tex coords for the first clouds layer
1819 		if (dome_clouds.tex_coords[0] <= 1.0)
1820 		{
1821 			for (i = dome_clouds.vertices_count; i--; )
1822 				dome_clouds.tex_coords[i*2] += clouds_step*2.0;
1823 		}
1824 		else
1825 		{
1826 			for (i = dome_clouds.vertices_count; i--; )
1827 				dome_clouds.tex_coords[i*2] += clouds_step*2.0 - 1.0;
1828 		}
1829 
1830 		// we update the tex coords for the second clouds layer
1831 		if (dome_clouds_tex_coords_bis[0] <= 1.0)
1832 		{
1833 			for (i = dome_clouds.vertices_count; i--; )
1834 				dome_clouds_tex_coords_bis[i*2] += clouds_step;
1835 		}
1836 		else
1837 		{
1838 			for (i = dome_clouds.vertices_count; i--; )
1839 				dome_clouds_tex_coords_bis[i*2] += clouds_step - 1.0;
1840 		}
1841 
1842 		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1843 		glEnable(GL_TEXTURE_2D);
1844 		bind_texture(thick_clouds_detail_tex);
1845 
1846 		glEnableClientState(GL_VERTEX_ARRAY);
1847 		glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1848 
1849 		glVertexPointer(3, GL_FLOAT, 0, dome_clouds.vertices);
1850 
1851 		glColor3f(0.8, 0.0, 0.0);
1852 		glTexCoordPointer(2, GL_FLOAT, 0, dome_clouds_tex_coords_bis);
1853 		glPushMatrix();
1854 		glRotatef(90.0, 0.0, 0.0, 1.0);
1855 		glDrawElements(GL_TRIANGLES, dome_clouds.faces_count*3, GL_UNSIGNED_INT, dome_clouds.faces);
1856 		glPopMatrix();
1857 
1858 		glColor3f(0.8, 0.2, 0.0);
1859 		glTexCoordPointer(2, GL_FLOAT, 0, dome_clouds.tex_coords);
1860 		glDrawElements(GL_TRIANGLES, dome_clouds.faces_count*3, GL_UNSIGNED_INT, dome_clouds.faces);
1861 
1862 		glDisableClientState(GL_VERTEX_ARRAY);
1863 		glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1864 		glDisable(GL_TEXTURE_2D);
1865 	}
1866 
1867 	glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1868 	glEnableClientState(GL_VERTEX_ARRAY);
1869 	glEnableClientState(GL_COLOR_ARRAY);
1870 
1871 	glVertexPointer(3, GL_FLOAT, 0, dome_sky.vertices);
1872 	glColorPointer(4, GL_FLOAT, 0, dome_sky.colors);
1873 
1874 	glDrawElements(GL_TRIANGLES, dome_sky.faces_count*3, GL_UNSIGNED_INT, dome_sky.faces);
1875 
1876 	glDisableClientState(GL_VERTEX_ARRAY);
1877 	glDisableClientState(GL_COLOR_ARRAY);
1878 
1879 	glBegin(GL_QUAD_STRIP);
1880 	for (i = 0; i < dome_sky.slices_count; ++i)
1881 	{
1882 		const GLfloat *vtx = &dome_sky.vertices[i*3];
1883 		glColor3fv(&dome_sky.colors[i*4]);
1884 		glVertex4f(vtx[0], vtx[1], vtx[2], 500.0);
1885 		glVertex3fv(vtx);
1886 	}
1887 	glColor3fv(&dome_sky.colors[0]);
1888 	glVertex4f(dome_sky.vertices[0], dome_sky.vertices[1], dome_sky.vertices[2], 500.0);
1889 	glVertex3fv(&dome_sky.vertices[0]);
1890 	glEnd();
1891 
1892 	glPopAttrib();
1893 	reset_material();
1894 	last_texture = -1;
1895 
1896 	last_cloud_time = cur_time;
1897 }
1898 
1899 #define XML_BOOL(s) (!xmlStrcasecmp((s), (xmlChar*)"yes") ||\
1900 					 !xmlStrcasecmp((s), (xmlChar*)"true") ||\
1901 					 !xmlStrcasecmp((s), (xmlChar*)"1"))
1902 
skybox_parse_color_properties(xmlNode * node,float container[360][4])1903 int skybox_parse_color_properties(xmlNode *node, float container[360][4])
1904 {
1905 	xmlAttr *attr;
1906 	int t = -1;
1907 	float r = 0.0, g = 0.0, b = 0.0, a = 1.0;
1908 	int ok = 1;
1909 
1910 	for (attr = node->properties; attr; attr = attr->next)
1911 	{
1912 		if (attr->type == XML_ATTRIBUTE_NODE)
1913 		{
1914 			if (xmlStrcasecmp (attr->name, (xmlChar*)"t") == 0)
1915 				t =  atoi((char*)attr->children->content);
1916 			else if (xmlStrcasecmp (attr->name, (xmlChar*)"r") == 0)
1917 				r =  atof((char*)attr->children->content);
1918 			else if (xmlStrcasecmp (attr->name, (xmlChar*)"g") == 0)
1919 				g =  atof((char*)attr->children->content);
1920 			else if (xmlStrcasecmp (attr->name, (xmlChar*)"b") == 0)
1921 				b =  atof((char*)attr->children->content);
1922 			else if (xmlStrcasecmp (attr->name, (xmlChar*)"a") == 0)
1923 				a =  atof((char*)attr->children->content);
1924 			else {
1925 				LOG_ERROR("unknown attribute for color: %s", (char*)attr->name);
1926 				ok = 0;
1927 			}
1928 		}
1929 	}
1930 
1931 	if (t >= 0 && t < 360)
1932 	{
1933 		container[t][0] = r <= 1.0 ? r : r / 255.0;
1934 		container[t][1] = g <= 1.0 ? g : g / 255.0;
1935 		container[t][2] = b <= 1.0 ? b : b / 255.0;
1936 		container[t][3] = a <= 1.0 ? a : a / 255.0;
1937 	}
1938 	else
1939 	{
1940 		LOG_ERROR("the time attribute of the color doesn't exist or is wrong!");
1941 		ok = 0;
1942 	}
1943 
1944 	return ok;
1945 }
1946 
skybox_parse_colors(xmlNode * node,float container[360][4])1947 int skybox_parse_colors(xmlNode *node, float container[360][4])
1948 {
1949 	xmlNode	*item;
1950 	xmlAttr *attr;
1951 	int	ok = 1;
1952     int i, t;
1953     int reset = 0;
1954 
1955 	if(node == NULL || node->children == NULL) return 0;
1956 
1957 	for (attr = node->properties; attr; attr = attr->next) {
1958 		if (attr->type == XML_ATTRIBUTE_NODE &&
1959 			(!xmlStrcasecmp(attr->name, (xmlChar*)"reset") ||
1960 			 !xmlStrcasecmp(attr->name, (xmlChar*)"overwrite"))) {
1961 			reset = XML_BOOL(attr->children->content);
1962 		}
1963 		else {
1964 			LOG_ERROR("unknown attribute for element: %s", (char*)attr->name);
1965 			ok = 0;
1966 		}
1967 	}
1968 
1969     if (reset)
1970     {
1971         // we erase the previous color keys
1972         for (t = 360; t--; )
1973         {
1974             for (i = 3; i--; )
1975             {
1976                 container[t][i] = 0.0;
1977             }
1978             container[t][3] = -1.0;
1979         }
1980     }
1981 
1982 	for(item = node->children; item; item = item->next) {
1983 		if(item->type == XML_ELEMENT_NODE) {
1984 			if(xmlStrcasecmp(item->name, (xmlChar*)"color") == 0) {
1985 				ok &= skybox_parse_color_properties(item, container);
1986 			}
1987 			else {
1988 				LOG_ERROR("unknown node for element: %s", item->name);
1989 				ok = 0;
1990 			}
1991 		}
1992 		else if (item->type == XML_ENTITY_REF_NODE) {
1993 			ok &= skybox_parse_colors(item->children, container);
1994 		}
1995 	}
1996 
1997 	return ok;
1998 }
1999 
skybox_parse_properties(xmlNode * node)2000 int skybox_parse_properties(xmlNode *node)
2001 {
2002 	xmlNode *item;
2003 	xmlAttr *attr;
2004 	int ok = 1;
2005 
2006 	for(item = node->children; item; item = item->next) {
2007 		if(item->type == XML_ELEMENT_NODE) {
2008 			if(xmlStrcasecmp(item->name, (xmlChar*)"clouds") == 0) {
2009 				for (attr = item->properties; attr; attr = attr->next)
2010 				{
2011 					if (attr->type == XML_ATTRIBUTE_NODE)
2012 					{
2013 						if (!xmlStrcasecmp (attr->name, (xmlChar*)"show"))
2014 							skybox_no_clouds = !XML_BOOL(attr->children->content);
2015 						else if (xmlStrcasecmp (attr->name, (xmlChar*)"texture") == 0)
2016 							skybox_clouds_tex = load_texture_cached((char*)attr->children->content, tt_mesh);
2017 						else if (xmlStrcasecmp (attr->name, (xmlChar*)"texture_detail") == 0)
2018 							skybox_clouds_detail_tex = load_texture_cached((char*)attr->children->content, tt_mesh);
2019 						else {
2020 							LOG_ERROR("unknown attribute for clouds: %s", (char*)attr->name);
2021 							ok = 0;
2022 						}
2023 					}
2024 				}
2025 			}
2026 			else if(xmlStrcasecmp(item->name, (xmlChar*)"sun") == 0) {
2027 				for (attr = item->properties; attr; attr = attr->next)
2028 					if (attr->type == XML_ATTRIBUTE_NODE) {
2029 						if (!xmlStrcasecmp (attr->name, (xmlChar*)"show"))
2030 							skybox_no_sun = !XML_BOOL(attr->children->content);
2031 						else {
2032 							LOG_ERROR("unknown attribute for sun: %s", (char*)attr->name);
2033 							ok = 0;
2034 						}
2035 					}
2036 			}
2037 			else if(xmlStrcasecmp(item->name, (xmlChar*)"moons") == 0) {
2038 				for (attr = item->properties; attr; attr = attr->next)
2039 					if (attr->type == XML_ATTRIBUTE_NODE) {
2040 						if (!xmlStrcasecmp (attr->name, (xmlChar*)"show"))
2041 							skybox_no_moons = !XML_BOOL(attr->children->content);
2042 						else {
2043 							LOG_ERROR("unknown attribute for moons: %s", (char*)attr->name);
2044 							ok = 0;
2045 						}
2046 					}
2047 			}
2048 			else if(xmlStrcasecmp(item->name, (xmlChar*)"stars") == 0) {
2049 				for (attr = item->properties; attr; attr = attr->next)
2050 					if (attr->type == XML_ATTRIBUTE_NODE) {
2051 						if (!xmlStrcasecmp (attr->name, (xmlChar*)"show"))
2052 							skybox_no_stars = !XML_BOOL(attr->children->content);
2053 						else {
2054 							LOG_ERROR("unknown attribute for stars: %s", (char*)attr->name);
2055 							ok = 0;
2056 						}
2057 					}
2058 			}
2059 			else if(xmlStrcasecmp(item->name, (xmlChar*)"freeze_time") == 0) {
2060 				int value = get_int_value(item);
2061 				if (value >= 0 && value <= 359) {
2062 					freeze_time = 1;
2063 					game_minute = value;
2064 					game_second = 0;
2065 				}
2066 				else {
2067 					freeze_time = 0;
2068 					game_minute = real_game_minute;
2069 					game_second = real_game_second;
2070 				}
2071 			}
2072 			else {
2073 				LOG_ERROR("unknown node for properties: %s", item->name);
2074 				ok = 0;
2075 			}
2076 		}
2077 		else if (item->type == XML_ENTITY_REF_NODE) {
2078 			ok &= skybox_parse_properties(item->children);
2079 		}
2080 	}
2081 
2082 	return ok;
2083 }
2084 
skybox_parse_defs(xmlNode * node,const char * map_name)2085 int skybox_parse_defs(xmlNode *node, const char *map_name)
2086 {
2087 	xmlNode *def;
2088 	int ok = 1;
2089 
2090 	for (def = node->children; def; def = def->next) {
2091 		if (def->type == XML_ELEMENT_NODE)
2092 		{
2093 			if (xmlStrcasecmp(def->name, (xmlChar*)"properties") == 0) {
2094 				ok &= skybox_parse_properties(def);
2095 			}
2096 			else if (xmlStrcasecmp(def->name, (xmlChar*)"clouds") == 0) {
2097 				ok &= skybox_parse_colors(def, skybox_clouds);
2098 			}
2099 			else if (xmlStrcasecmp(def->name, (xmlChar*)"clouds_detail") == 0) {
2100 				ok &= skybox_parse_colors(def, skybox_clouds_detail);
2101 			}
2102 			else if (xmlStrcasecmp(def->name, (xmlChar*)"clouds_sunny") == 0) {
2103 				ok &= skybox_parse_colors(def, skybox_clouds_sunny);
2104 			}
2105 			else if (xmlStrcasecmp(def->name, (xmlChar*)"clouds_detail_sunny") == 0) {
2106 				ok &= skybox_parse_colors(def, skybox_clouds_detail_sunny);
2107 			}
2108 			else if (xmlStrcasecmp(def->name, (xmlChar*)"clouds_rainy") == 0) {
2109 				ok &= skybox_parse_colors(def, skybox_clouds_rainy);
2110 			}
2111 			else if (xmlStrcasecmp(def->name, (xmlChar*)"clouds_detail_rainy") == 0) {
2112 				ok &= skybox_parse_colors(def, skybox_clouds_detail_rainy);
2113 			}
2114 			else if (xmlStrcasecmp(def->name, (xmlChar*)"sky1") == 0) {
2115 				ok &= skybox_parse_colors(def, skybox_sky1);
2116 			}
2117 			else if (xmlStrcasecmp(def->name, (xmlChar*)"sky2") == 0) {
2118 				ok &= skybox_parse_colors(def, skybox_sky2);
2119 			}
2120 			else if (xmlStrcasecmp(def->name, (xmlChar*)"sky3") == 0) {
2121 				ok &= skybox_parse_colors(def, skybox_sky3);
2122 			}
2123 			else if (xmlStrcasecmp(def->name, (xmlChar*)"sky4") == 0) {
2124 				ok &= skybox_parse_colors(def, skybox_sky4);
2125 			}
2126 			else if (xmlStrcasecmp(def->name, (xmlChar*)"sky5") == 0) {
2127 				ok &= skybox_parse_colors(def, skybox_sky5);
2128 			}
2129 			else if (xmlStrcasecmp(def->name, (xmlChar*)"sky1_sunny") == 0) {
2130 				ok &= skybox_parse_colors(def, skybox_sky1_sunny);
2131 			}
2132 			else if (xmlStrcasecmp(def->name, (xmlChar*)"sky2_sunny") == 0) {
2133 				ok &= skybox_parse_colors(def, skybox_sky2_sunny);
2134 			}
2135 			else if (xmlStrcasecmp(def->name, (xmlChar*)"sky3_sunny") == 0) {
2136 				ok &= skybox_parse_colors(def, skybox_sky3_sunny);
2137 			}
2138 			else if (xmlStrcasecmp(def->name, (xmlChar*)"sky4_sunny") == 0) {
2139 				ok &= skybox_parse_colors(def, skybox_sky4_sunny);
2140 			}
2141 			else if (xmlStrcasecmp(def->name, (xmlChar*)"sky5_sunny") == 0) {
2142 				ok &= skybox_parse_colors(def, skybox_sky5_sunny);
2143 			}
2144 			else if (xmlStrcasecmp(def->name, (xmlChar*)"sun") == 0) {
2145 				ok &= skybox_parse_colors(def, skybox_sun);
2146 			}
2147 			else if (xmlStrcasecmp(def->name, (xmlChar*)"fog") == 0) {
2148 				ok &= skybox_parse_colors(def, skybox_fog);
2149 			}
2150 			else if (xmlStrcasecmp(def->name, (xmlChar*)"fog_sunny") == 0) {
2151 				ok &= skybox_parse_colors(def, skybox_fog_sunny);
2152 			}
2153 			else if (xmlStrcasecmp(def->name, (xmlChar*)"fog_rainy") == 0) {
2154 				ok &= skybox_parse_colors(def, skybox_fog_rainy);
2155 			}
2156 			else if (xmlStrcasecmp(def->name, (xmlChar*)"light_ambient") == 0) {
2157 				ok &= skybox_parse_colors(def, skybox_light_ambient);
2158 			}
2159 			else if (xmlStrcasecmp(def->name, (xmlChar*)"light_diffuse") == 0) {
2160 				ok &= skybox_parse_colors(def, skybox_light_diffuse);
2161 			}
2162 			else if (xmlStrcasecmp(def->name, (xmlChar*)"light_ambient_rainy") == 0) {
2163 				ok &= skybox_parse_colors(def, skybox_light_ambient_rainy);
2164 			}
2165 			else if (xmlStrcasecmp(def->name, (xmlChar*)"light_diffuse_rainy") == 0) {
2166 				ok &= skybox_parse_colors(def, skybox_light_diffuse_rainy);
2167 			}
2168 			else if (xmlStrcasecmp(def->name, (xmlChar*)"map") == 0) {
2169 				const char *name = get_string_property(def, "name");
2170 				if (!strcasecmp(name, map_name)) {
2171 					//printf("Found custom sky defs for the current map!\n");
2172 					ok &= skybox_parse_defs(def, "");
2173 				}
2174 			}
2175 			else {
2176 				LOG_ERROR("unknown element for skybox: %s", def->name);
2177 				ok = 0;
2178 			}
2179 		}
2180 		else if (def->type == XML_ENTITY_REF_NODE) {
2181 			ok &= skybox_parse_defs(def->children, map_name);
2182 		}
2183 	}
2184 
2185 	return ok;
2186 }
2187 
skybox_read_defs(const char * file_name,const char * map_name)2188 int skybox_read_defs(const char *file_name, const char *map_name)
2189 {
2190 	xmlNode *root;
2191 	xmlDoc *doc;
2192 	int ok = 1;
2193 
2194 	doc = xmlReadFile(file_name, NULL, XML_PARSE_NOENT);
2195 	if (doc == NULL) {
2196 		LOG_ERROR("Unable to read skybox definition file %s", file_name);
2197 		return 0;
2198 	}
2199 
2200 	root = xmlDocGetRootElement(doc);
2201 	if (root == NULL) {
2202 		LOG_ERROR("Unable to parse skybox definition file %s", file_name);
2203 		ok = 0;
2204 	} else if (xmlStrcasecmp(root->name, (xmlChar*)"skybox") != 0) {
2205 		LOG_ERROR("Unknown key \"%s\" (\"skybox\" expected).", root->name);
2206 		ok = 0;
2207 	} else {
2208 		ok = skybox_parse_defs(root, map_name);
2209 	}
2210 
2211 	xmlFreeDoc(doc);
2212 	return ok;
2213 }
2214 
skybox_build_gradients(float container[360][4])2215 int skybox_build_gradients(float container[360][4])
2216 {
2217 	int t;
2218 	int first = 0;
2219 	int prev, next, diff;
2220 
2221 	while (first < 360 && container[first][3] < 0.0) ++first;
2222 
2223 	if (first >= 360) return 0;
2224 
2225 	prev = first;
2226 	do
2227 	{
2228 		next = (prev+1)%360;
2229 		while (container[next][3] < 0.0) next = (next+1)%360;
2230 		diff = (next-prev+360)%360;
2231 		if (diff) // prev != next
2232 		{
2233 			for (t = prev+1; t != next; t = (t+1)%360)
2234 				blend_colors(container[t], container[prev], container[next],
2235 							 (float)((t-prev+360)%360)/(float)diff, 4);
2236 		}
2237 		else // prev == next
2238 		{
2239 			for (t = prev+1; t != next; t = (t+1)%360)
2240 				memcpy(container[t], container[prev], 4*sizeof(float));
2241 		}
2242 		prev = next;
2243 	}
2244 	while (prev != first);
2245 
2246 	return 1;
2247 }
2248 
skybox_init_defs(const char * map_name)2249 void skybox_init_defs(const char *map_name)
2250 {
2251     static char last_map[256] = "\0";
2252 	int t;
2253 	int i;
2254 
2255 	for (t = 360; t--; )
2256 	{
2257 		for (i = 3; i--; )
2258 		{
2259 			skybox_clouds[t][i] = 0.0;
2260 			skybox_clouds_detail[t][i] = 0.0;
2261 			skybox_clouds_sunny[t][i] = 0.0;
2262 			skybox_clouds_detail_sunny[t][i] = 0.0;
2263 			skybox_clouds_rainy[t][i] = 0.0;
2264 			skybox_clouds_detail_rainy[t][i] = 0.0;
2265 			skybox_sky1[t][i] = 0.0;
2266 			skybox_sky2[t][i] = 0.0;
2267 			skybox_sky3[t][i] = 0.0;
2268 			skybox_sky4[t][i] = 0.0;
2269 			skybox_sky5[t][i] = 0.0;
2270 			skybox_sky1_sunny[t][i] = 0.0;
2271 			skybox_sky2_sunny[t][i] = 0.0;
2272 			skybox_sky3_sunny[t][i] = 0.0;
2273 			skybox_sky4_sunny[t][i] = 0.0;
2274 			skybox_sky5_sunny[t][i] = 0.0;
2275 			skybox_sun[t][i] = 0.0;
2276 			skybox_fog[t][i] = 0.0;
2277 			skybox_fog_sunny[t][i] = 0.0;
2278 			skybox_fog_rainy[t][i] = 0.0;
2279 			skybox_light_ambient[t][i] = 0.0;
2280 			skybox_light_diffuse[t][i] = 0.0;
2281 			skybox_light_ambient_rainy[t][i] = 0.0;
2282 			skybox_light_diffuse_rainy[t][i] = 0.0;
2283 		}
2284 		skybox_clouds[t][3] = -1.0;
2285 		skybox_clouds_detail[t][3] = -1.0;
2286 		skybox_clouds_sunny[t][3] = -1.0;
2287 		skybox_clouds_detail_sunny[t][3] = -1.0;
2288 		skybox_clouds_rainy[t][3] = -1.0;
2289 		skybox_clouds_detail_rainy[t][3] = -1.0;
2290 		skybox_sky1[t][3] = -1.0;
2291 		skybox_sky2[t][3] = -1.0;
2292 		skybox_sky3[t][3] = -1.0;
2293 		skybox_sky4[t][3] = -1.0;
2294 		skybox_sky5[t][3] = -1.0;
2295 		skybox_sky1_sunny[t][3] = -1.0;
2296 		skybox_sky2_sunny[t][3] = -1.0;
2297 		skybox_sky3_sunny[t][3] = -1.0;
2298 		skybox_sky4_sunny[t][3] = -1.0;
2299 		skybox_sky5_sunny[t][3] = -1.0;
2300 		skybox_sun[t][3] = -1.0;
2301 		skybox_fog[t][3] = -1.0;
2302 		skybox_fog_sunny[t][3] = -1.0;
2303 		skybox_fog_rainy[t][3] = -1.0;
2304 		skybox_light_ambient[t][3] = -1.0;
2305 		skybox_light_diffuse[t][3] = -1.0;
2306 		skybox_light_ambient_rainy[t][3] = -1.0;
2307 		skybox_light_diffuse_rainy[t][3] = -1.0;
2308 	}
2309 
2310 	skybox_no_clouds = 1;
2311 	skybox_no_sun = 1;
2312 	skybox_no_moons = 1;
2313 	skybox_no_stars = 1;
2314 	skybox_clouds_tex = -1;
2315 	skybox_clouds_detail_tex = -1;
2316 	freeze_time = 0;
2317 	game_minute = real_game_minute;
2318 	game_second = real_game_second;
2319 
2320     if (map_name) {
2321         int pos = strlen(map_name)-1;
2322         while (pos >= 0 && map_name[pos] != '/') --pos;
2323         strcpy(last_map, map_name+pos+1);
2324     }
2325 
2326     //printf("Loading sky defs for map '%s'\n", last_map);
2327 	if (!skybox_read_defs("skybox/skybox_defs.xml", last_map))
2328 		LOG_ERROR("Error while loading the skybox definitions.");
2329 
2330 	if (!skybox_build_gradients(skybox_clouds))
2331 		LOG_ERROR("no color key defined for 'clouds' element!");
2332 	if (!skybox_build_gradients(skybox_clouds_detail))
2333 		LOG_ERROR("no color key defined for 'clouds_detail' element!");
2334 	if (!skybox_build_gradients(skybox_clouds_sunny))
2335 		LOG_ERROR("no color key defined for 'clouds_sunny' element!");
2336 	if (!skybox_build_gradients(skybox_clouds_detail_sunny))
2337 		LOG_ERROR("no color key defined for 'clouds_detail_sunny' element!");
2338 	if (!skybox_build_gradients(skybox_clouds_rainy))
2339 		LOG_ERROR("no color key defined for 'clouds_rainy' element!");
2340 	if (!skybox_build_gradients(skybox_clouds_detail_rainy))
2341 		LOG_ERROR("no color key defined for 'clouds_detail_rainy' element!");
2342 	if (!skybox_build_gradients(skybox_sky1))
2343 		LOG_ERROR("no color key defined for 'sky1' element!");
2344 	if (!skybox_build_gradients(skybox_sky2))
2345 		LOG_ERROR("no color key defined for 'sky2' element!");
2346 	if (!skybox_build_gradients(skybox_sky3))
2347 		LOG_ERROR("no color key defined for 'sky3' element!");
2348 	if (!skybox_build_gradients(skybox_sky4))
2349 		LOG_ERROR("no color key defined for 'sky4' element!");
2350 	if (!skybox_build_gradients(skybox_sky5))
2351 		LOG_ERROR("no color key defined for 'sky5' element!");
2352 	if (!skybox_build_gradients(skybox_sky1_sunny))
2353 		LOG_ERROR("no color key defined for 'sky1_sunny' element!");
2354 	if (!skybox_build_gradients(skybox_sky2_sunny))
2355 		LOG_ERROR("no color key defined for 'sky2_sunny' element!");
2356 	if (!skybox_build_gradients(skybox_sky3_sunny))
2357 		LOG_ERROR("no color key defined for 'sky3_sunny' element!");
2358 	if (!skybox_build_gradients(skybox_sky4_sunny))
2359 		LOG_ERROR("no color key defined for 'sky4_sunny' element!");
2360 	if (!skybox_build_gradients(skybox_sky5_sunny))
2361 		LOG_ERROR("no color key defined for 'sky5_sunny' element!");
2362 	if (!skybox_build_gradients(skybox_sun))
2363 		LOG_ERROR("no color key defined for 'sun' element!");
2364 	if (!skybox_build_gradients(skybox_fog))
2365 		LOG_ERROR("no color key defined for 'fog' element!");
2366 	if (!skybox_build_gradients(skybox_fog_sunny))
2367 		LOG_ERROR("no color key defined for 'fog_sunny' element!");
2368 	if (!skybox_build_gradients(skybox_fog_rainy))
2369 		LOG_ERROR("no color key defined for 'fog_rainy' element!");
2370 	if (!skybox_build_gradients(skybox_light_ambient))
2371 		LOG_ERROR("no color key defined for 'light_ambient' element!");
2372 	if (!skybox_build_gradients(skybox_light_diffuse))
2373 		LOG_ERROR("no color key defined for 'light_diffuse' element!");
2374 	if (!skybox_build_gradients(skybox_light_ambient_rainy))
2375 		LOG_ERROR("no color key defined for 'light_ambient_rainy' element!");
2376 	if (!skybox_build_gradients(skybox_light_diffuse_rainy))
2377 		LOG_ERROR("no color key defined for 'light_diffuse_rainy' element!");
2378 
2379 	skybox_update_positions();
2380 	skybox_update_colors();
2381 }
2382 
skybox_init_gl()2383 void skybox_init_gl()
2384 {
2385 /* 	GLUquadricObj *qobj; */
2386 	GLfloat randx,randy,randz;
2387 	int i;
2388 	float maxr;
2389 	float strs[NUM_STARS][3];
2390 
2391 	thick_clouds_tex = load_texture_cached("textures/thick_clouds", tt_mesh);
2392 	thick_clouds_detail_tex = load_texture_cached("textures/thick_clouds_detail", tt_mesh);
2393 	moon_tex = load_texture_cached("textures/moonmap", tt_mesh);
2394 	sun_tex = load_texture_cached("textures/BrightSun", tt_mesh);
2395 
2396 	sky_lists = glGenLists(3);
2397 
2398 /* 	qobj = gluNewQuadric(); */
2399 /* 	gluQuadricOrientation(qobj, GLU_OUTSIDE);	 */
2400 /* 	gluQuadricNormals(qobj, GLU_SMOOTH); */
2401 /* 	gluQuadricTexture(qobj, GL_TRUE); */
2402 /* 	glNewList(sky_lists, GL_COMPILE); */
2403 /* 	gluSphere(qobj, 1.0, 32, 16); */
2404 /* 	glEndList(); */
2405 /* 	gluDeleteQuadric(qobj); */
2406 
2407 	srand(0);
2408 	maxr = 1.0/RAND_MAX;
2409 	for (i = 0; i < NUM_STARS; i++)
2410 	{
2411 		float norm;
2412 		do
2413 		{
2414 			randx = rand()*(float)(maxr)-0.5f;
2415 			randy = rand()*(float)(maxr)-0.5f;
2416 			randz = rand()*(float)(maxr)-0.5f;
2417 			norm = sqrt(randx*randx + randy*randy + randz*randz);
2418 		} while (norm > 0.5f);
2419 
2420 		strs[i][0] = 500 * randx / norm;
2421 		strs[i][1] = 500 * randy / norm;
2422 		strs[i][2] = 500 * randz / norm;
2423 	}
2424 	glNewList(sky_lists,GL_COMPILE);
2425 	glBegin(GL_POINTS);
2426 	for (i = 0; i < NUM_STARS/3; i++)
2427 	{
2428 		glVertex3fv(strs[i]);
2429 	}
2430 	glEnd();
2431 	glEndList();
2432 	glNewList(sky_lists+1,GL_COMPILE);
2433 	glBegin(GL_POINTS);
2434 	for (i = 1*NUM_STARS/3; i < 2*NUM_STARS/3; i++)
2435 	{
2436 		glVertex3fv(strs[i]);
2437 	}
2438 	glEnd();
2439 	glEndList();
2440 	glNewList(sky_lists+2,GL_COMPILE);
2441 	glBegin(GL_POINTS);
2442 	for (i = 2*NUM_STARS/3; i < NUM_STARS; i++)
2443 	{
2444 		glVertex3fv(strs[i]);
2445 	}
2446 	glEnd();
2447 	glEndList();
2448 
2449 	destroy_dome(&dome_sky);
2450 	destroy_dome(&dome_clouds);
2451 	destroy_sphere(&moon_mesh);
2452 	if (dome_clouds_detail_colors) free(dome_clouds_detail_colors);
2453 	if (dome_clouds_colors_bis) free(dome_clouds_colors_bis);
2454 	if (dome_clouds_detail_colors_bis) free(dome_clouds_detail_colors_bis);
2455 	if (dome_clouds_tex_coords_bis) free(dome_clouds_tex_coords_bis);
2456 
2457 	dome_sky = create_dome(24, 12, 500.0, 80.0, 90.0, 3.5, 1.0);
2458 	dome_clouds = create_dome(24, 12, 500.0, 80.0, 90.0, 2.0, 1.0);
2459 	moon_mesh = create_sphere(24, 12);
2460 	dome_clouds_detail_colors = (GLfloat*)malloc(4*dome_clouds.vertices_count*sizeof(GLfloat));
2461 	dome_clouds_colors_bis = (GLfloat*)malloc(4*dome_clouds.vertices_count*sizeof(GLfloat));
2462 	dome_clouds_detail_colors_bis = (GLfloat*)malloc(4*dome_clouds.vertices_count*sizeof(GLfloat));
2463 	dome_clouds_tex_coords_bis = (GLfloat*)malloc(2*dome_clouds.vertices_count*sizeof(GLfloat));
2464 
2465 	for (i = dome_clouds.vertices_count; i--; )
2466 	{
2467 		int idx = i*2;
2468 		dome_clouds_tex_coords_bis[idx] = dome_clouds.tex_coords[idx];
2469 		dome_clouds_tex_coords_bis[idx+1] = dome_clouds.tex_coords[idx+1]+0.5;
2470 	}
2471 }
2472 
free_skybox()2473 void free_skybox()
2474 {
2475 	destroy_dome(&dome_sky);
2476 	destroy_dome(&dome_clouds);
2477 	destroy_sphere(&moon_mesh);
2478 	if (dome_clouds_detail_colors) free(dome_clouds_detail_colors);
2479 	if (dome_clouds_colors_bis) free(dome_clouds_colors_bis);
2480 	if (dome_clouds_detail_colors_bis) free(dome_clouds_detail_colors_bis);
2481 	if (dome_clouds_tex_coords_bis) free(dome_clouds_tex_coords_bis);
2482 }
2483 
2484