/* WMGlobe 1.3 - All the Earth on a WMaker Icon * copyright (C) 1998,99,2000,01 Jerome Dumonteil * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ***************************************************************************/ /* this code was based on XGlobe : renderer.cpp * * This file is part of XGlobe. See README for details. * * Copyright (C) 1998 Thorsten Scheuermann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public Licenses as published by * the Free Software Foundation. ************************************************************************/ /* Some parts of this files should be rewritten to not depend on WindowMaker version */ #include "wmglobe.h" static RColor mygetMapColorLinear (double longitude, double latitude, double angle); /* * static RColor getMapColor(double longitude, double latitude, double angle); */ static void randomPosition(); void setViewPos(double lat, double lon); static void myRPutPixel(int x, int y, RColor * color); #ifdef WITH_MARKERS #if (WITH_MARKERS == 1) static void invertPixel(int x, int y); static void put_cross(int x, int y); static void put_dot_cross(int x, int y, RColor * color); #endif #endif static void getquarter(RImage * image, int x, int y, MPO * m[4], int dx, int dy); static void updateTime(int force); static struct timeval timeaccel(struct timeval t); struct timeval timeaccel(struct timeval t) { struct timeval at; double rr; t = diftimev(t, tini); rr = floor((double) t.tv_sec * time_multi + (double) t.tv_usec * time_multi / 1000000.); /*** something bad may appen if time_multi=max after 41 minutes (overflow) ***/ while (rr > (double) LONG_MAX) rr -= (2.0 * (double) LONG_MAX + 1.0); at.tv_sec = (int) rr; at.tv_usec = (int) (t.tv_usec * time_multi) % 1000000; return addtimev(at, tbase); } static void myRPutPixel(int x, int y, RColor * color) { int ofs; unsigned char *sr, *sg, *sb; ofs = (y * DIAMETRE + x) * 3; sr = small->data + (ofs++); sg = small->data + (ofs++); sb = small->data + (ofs); *sr = color->red; *sg = color->green; *sb = color->blue; return; } #if WITH_MARKERS static void invertPixel(int x, int y) { int ofs; unsigned char *sr, *sg, *sb; ofs = (y * DIAMETRE + x) * 3; sr = small->data + (ofs++); sg = small->data + (ofs++); sb = small->data + (ofs); #if ( CROSS_INVERT == 1 ) *sr = 255 - *sr; *sg = 255 - *sg; *sb = 255 - *sb; #else if (*sb > 127 || *sg > 127 || *sr > 127) *sr = *sg = *sb = 0; else *sr = *sg = *sb = 255; #endif return; } #define T_CADRE(x,y) ((x) < DIAMETRE && (x) >= 0 \ && (y) < DIAMETRE && (y) >= 0 && tabsolu[(x)][(y)]) static void put_cross(int x, int y) { int i, x_cross, y_cross; if (T_CADRE(x, y)) { if (!fun && sens != 1) { x = DIAMETRE - 1 - x; y = DIAMETRE - 1 - y; } for (i = 2; i <= CROSS_LENGTH; i++) { x_cross = x + i; y_cross = y; if (T_CADRE(x_cross, y_cross)) invertPixel(x_cross, y_cross); x_cross = x - i; if (T_CADRE(x_cross, y_cross)) invertPixel(x_cross, y_cross); x_cross = x; y_cross = y - i; if (T_CADRE(x_cross, y_cross)) invertPixel(x_cross, y_cross); y_cross = y + i; if (T_CADRE(x_cross, y_cross)) invertPixel(x_cross, y_cross); } } } static void put_dot_cross(int x, int y, RColor * color) { int i, x_cross, y_cross; if (T_CADRE(x, y)) { if (!fun && sens != 1) { x = DIAMETRE - 1 - x; y = DIAMETRE - 1 - y; } for (i = 2; i <= CROSS_LENGTH; i += 2) { x_cross = x + i; y_cross = y; if (T_CADRE(x_cross, y_cross)) invertPixel(x_cross, y_cross); x_cross = x - i; if (T_CADRE(x_cross, y_cross)) invertPixel(x_cross, y_cross); x_cross = x; y_cross = y - i; if (T_CADRE(x_cross, y_cross)) invertPixel(x_cross, y_cross); y_cross = y + i; if (T_CADRE(x_cross, y_cross)) invertPixel(x_cross, y_cross); x_cross = x + i + 1; y_cross = y; if (T_CADRE(x_cross, y_cross)) myRPutPixel(x_cross, y_cross, color); x_cross = x - i - 1; if (T_CADRE(x_cross, y_cross)) myRPutPixel(x_cross, y_cross, color); x_cross = x; y_cross = y - i - 1; if (T_CADRE(x_cross, y_cross)) myRPutPixel(x_cross, y_cross, color); y_cross = y + i + 1; if (T_CADRE(x_cross, y_cross)) myRPutPixel(x_cross, y_cross, color); } } } #endif static void getquarter(RImage * image, int x, int y, MPO * m[4], int dx, int dy) { int xx; register int ofs; /*** hope this is faster than calculation with floats .... ****/ x %= image->width; xx = x; y %= image->height; ofs = (y * image->width + x) * 3; m[0]->r = image->data[ofs++]; m[0]->g = image->data[ofs++]; m[0]->b = image->data[ofs]; xx++; xx %= image->width; ofs = (y * image->width + xx) * 3; m[1]->r = image->data[ofs++]; m[1]->g = image->data[ofs++]; m[1]->b = image->data[ofs]; y++; y %= image->height; ofs = (y * image->width + x) * 3; m[2]->r = image->data[ofs++]; m[2]->g = image->data[ofs++]; m[2]->b = image->data[ofs]; ofs = (y * image->width + xx) * 3; m[3]->r = image->data[ofs++]; m[3]->g = image->data[ofs++]; m[3]->b = image->data[ofs]; /* * m[0]->r=((m[0]->r*(256-dx)*(256-dy))+ * (m[1]->r*dx*(256-dy))+ * (m[2]->r*(256-dx)*dy)+ * (m[3]->r*dx*dy))>>16; * m[0]->g=((m[0]->g*(256-dx)*(256-dy))+ * (m[1]->g*dx*(256-dy))+ * (m[2]->g*(256-dx)*dy)+ * (m[3]->g*dx*dy))>>16; * m[0]->b=((m[0]->b*(256-dx)*(256-dy))+ * (m[1]->b*dx*(256-dy))+ * (m[2]->b*(256-dx)*dy)+ * (m[3]->b*dx*dy))>>16; */ if ((ofs = m[1]->r - m[0]->r) != 0) m[0]->r += (ofs * dx) >> 8; if ((ofs = m[1]->g - m[0]->g) != 0) m[0]->g += (ofs * dx) >> 8; if ((ofs = m[1]->b - m[0]->b) != 0) m[0]->b += (ofs * dx) >> 8; if ((ofs = m[3]->r - m[2]->r) != 0) m[2]->r += (ofs * dx) >> 8; if ((ofs = m[3]->g - m[2]->g) != 0) m[2]->g += (ofs * dx) >> 8; if ((ofs = m[3]->b - m[2]->b) != 0) m[2]->b += (ofs * dx) >> 8; if ((ofs = m[2]->r - m[0]->r) != 0) m[0]->r += (ofs * dy) >> 8; if ((ofs = m[2]->g - m[0]->g) != 0) m[0]->g += (ofs * dy) >> 8; if ((ofs = m[2]->b - m[0]->b) != 0) m[0]->b += (ofs * dy) >> 8; return; } void calcDistance() { double tan_a; tan_a = (zoom * DIAMETRE / 2.0) / proj_dist; /* * distance of camera to center of earth ( = coordinate origin) */ center_dist = radius / sin(atan(tan_a)); c_coef = center_dist * center_dist - radius * radius; solution = FALSE; return; } void renderFrame() { int py, px; RColor teinte; double dir_x, dir_y, dir_z; /* direction of cast ray */ double hit_x, hit_y, hit_z; /* hit position on earth surface */ double hit2_x, hit2_y, hit2_z; /* mirrored hit position on earth surface */ double sp_x, sp_y, sp_z; /* intersection point of globe and ray */ double a; /* coeff. of quardatic equation */ double udroot; /* racine */ double wurzel; double r; /* r' */ double s1, s2, s; /*distance between intersections and camera position */ double longitude, latitude; /* coordinates of hit position */ double light_angle; /* cosine of angle between sunlight and surface normal */ int startx, endx; /* the region to be painted */ int starty, endy; double m11; double m12; double m13; double m21; double m22; double m23; double m31; double m32; double m33; a = dir_x = dir_y = 0; dir_z = -proj_dist; #ifdef DEBUG fprintf(stdout, "solution : %d\n", solution); #endif /* * clear image */ if (solution == FALSE) RClearImage(small, &noir); /* * rotation matrix */ m11 = cos(v_long); m22 = cos(v_lat); m23 = sin(v_lat); m31 = -sin(v_long); m12 = m23 * m31; m13 = -m22 * m31; m21 = 0.; m32 = -m23 * m11; m33 = m22 * m11; /* * calc. radius of projected sphere */ if (solution == FALSE) { b_coef = 2 * center_dist * dir_z; radius_proj = (int) sqrt(b_coef * b_coef / (4 * c_coef) - dir_z * dir_z) + 1; } if (fun) { starty = DIAMETRE / 2 - radius_proj - 3; endy = DIAMETRE - starty - 1; if ((double) starty < (double) (-funy)) starty = -funy; if ((double) starty > (double) (DIAMETRE - 1 - funy)) starty = DIAMETRE - 1 - funy; if ((double) endy < (double) (-funy)) endy = -funy; if ((double) endy > (double) (DIAMETRE - 1 - funy)) endy = DIAMETRE - 1 - funy; if (solution == FALSE) { int i, j; if (starty + funy > 0) for (j = 0; j < starty + funy; j++) for (i = 0; i < DIAMETRE; i++) tabsolu[i][j] = 0; if (endy + 1 + funy <= DIAMETRE - 1) for (j = endy + funy + 1; j < DIAMETRE; j++) for (i = 0; i < DIAMETRE; i++) tabsolu[i][j] = 0; } for (py = starty; py <= endy; py++) { startx = DIAMETRE / 2 - 6 - (int) sqrt(MAX((radius_proj * radius_proj - (py - DIAMETRE / 2) * (py - DIAMETRE / 2)), 0.0)); endx = DIAMETRE - startx - 1; if ((double) startx < (double) (-funx)) startx = -funx; if ((double) startx > (double) (DIAMETRE - 1 - funx)) startx = DIAMETRE - 1 - funx; if ((double) endx < (double) (-funx)) endx = -funx; if ((double) endx > (double) (DIAMETRE - 1 - funx)) endx = DIAMETRE - 1 - funx; if (solution == FALSE) { int i; if (startx + funx > 0) for (i = 0; i < startx + funx; i++) tabsolu[i][py + funy] = 0; if (endx + 1 + funx <= DIAMETRE - 1) for (i = endx + 1 + funx; i < DIAMETRE; i++) tabsolu[i][py + funy] = 0; } /* * calculate offset into image data */ for (px = startx; px <= endx; px++) { if (solution == FALSE) { dir_x = (double) px - DIAMETRE / 2 + 0.5; dir_y = -(double) py + DIAMETRE / 2 - 0.5; a = dir_x * dir_x + dir_y * dir_y + dir_z * dir_z; udroot = b_coef * b_coef - 4 * a * c_coef; /*what's under the sq.root when solving the quadratic equation */ if (udroot >= 0) { tabsolu[px + funx][py + funy] = 1; wurzel = sqrt(udroot); s1 = (-b_coef + wurzel) / (2. * a); s2 = (-b_coef - wurzel) / (2. * a); s = (s1 < s2) ? s1 : s2; /* smaller solution belongs to nearer intersection */ solu[px + funx][py + funy][0] = s * dir_x; solu[px + funx][py + funy][1] = s * dir_y; solu[px + funx][py + funy][2] = center_dist + s * dir_z; } else { tabsolu[px + funx][py + funy] = 0; } } if (tabsolu[px + funx][py + funy]) { /* solution exists <=> intersection exists */ sp_x = solu[px + funx][py + funy][0]; /* sp = camera pos + s*dir */ sp_y = solu[px + funx][py + funy][1]; sp_z = solu[px + funx][py + funy][2]; hit_x = m11 * sp_x + m12 * sp_y + m13 * sp_z; hit_y = m22 * sp_y + m23 * sp_z; hit_z = m31 * sp_x + m32 * sp_y + m33 * sp_z; hit2_x = -m11 * sp_x + m12 * sp_y + m13 * sp_z; hit2_y = m22 * sp_y + m23 * sp_z; hit2_z = -m31 * sp_x + m32 * sp_y + m33 * sp_z; /*** hope hit_z wont get too close to zero *******/ if (ABS(hit_z) < 0.001) { if (hit_x * hit_z > 0.) longitude = PI / 2.; else longitude = -PI / 2.; if (hit_z > 0.) hit_z = 0.001; else hit_z = -0.001; } else { longitude = atan(hit_x / hit_z); } if (hit_z < 0.) longitude += PI; r = (double) sqrt(hit_x * hit_x + hit_z * hit_z); latitude = atan(-hit_y / r); light_angle = (light_x * hit_x + light_y * hit_y + light_z * hit_z) / radius; /* * Set pixel in image */ teinte = mygetMapColorLinear(longitude, latitude, light_angle); /* here dont use myRPutPixel since we prefer some error detection about limits */ RPutPixel(small, px + funx, py + funy, &teinte); } } /*px */ } /*py */ } /*** not fun : ***/ else { starty = DIAMETRE / 2 - radius_proj - 3; starty = (starty < 0) ? 0 : starty; endy = DIAMETRE - starty - 1; /* * py 0 to 63 max */ if (solution == FALSE) { int i, j; if (starty > 0) for (j = 0; j < starty; j++) for (i = 0; i < DIAMETRE; i++) tabsolu[i][j] = 0; if (endy + 1 <= DIAMETRE - 1) for (j = endy + 1; j < DIAMETRE; j++) for (i = 0; i < DIAMETRE; i++) tabsolu[i][j] = 0; } for (py = starty; py <= endy; py++) { startx = DIAMETRE / 2 - 6 - (int) sqrt(MAX((radius_proj * radius_proj - (py - DIAMETRE / 2) * (py - DIAMETRE / 2)), 0.0)); startx = (startx < 0) ? 0 : startx; /* * 0<= startx <=31 */ if (solution == FALSE) { int i; if (startx > 0) for (i = 0; i < startx; i++) { tabsolu[i][py] = 0; tabsolu[DIAMETRE - 1 - i][py] = 0; } } for (px = startx; px < DIAMETRE / 2; px++) { if (solution == FALSE) { dir_x = (double) px - DIAMETRE / 2 + 0.5; dir_y = -(double) py + DIAMETRE / 2 - 0.5; a = dir_x * dir_x + dir_y * dir_y + dir_z * dir_z; /*what's under the sq.root when solving the quadratic equation */ udroot = b_coef * b_coef - 4 * a * c_coef; if (udroot >= 0) { tabsolu[px][py] = 1; tabsolu[DIAMETRE - 1 - px][py] = 1; wurzel = sqrt(udroot); s1 = (-b_coef + wurzel) / (2. * a); s2 = (-b_coef - wurzel) / (2. * a); s = (s1 < s2) ? s1 : s2; /* smaller solution belongs to nearer intersection */ /* sp = camera pos + s*dir */ solu[px][py][0] = s * dir_x; solu[px][py][1] = s * dir_y; solu[px][py][2] = center_dist + s * dir_z; } else { tabsolu[px][py] = 0; tabsolu[DIAMETRE - 1 - px][py] = 0; } } if (tabsolu[px][py]) { /* solution exists <=> intersection exists */ sp_x = solu[px][py][0]; sp_y = solu[px][py][1]; sp_z = solu[px][py][2]; hit_x = m11 * sp_x + m12 * sp_y + m13 * sp_z; hit_y = m22 * sp_y + m23 * sp_z; hit_z = m31 * sp_x + m32 * sp_y + m33 * sp_z; hit2_x = -m11 * sp_x + m12 * sp_y + m13 * sp_z; hit2_y = m22 * sp_y + m23 * sp_z; hit2_z = -m31 * sp_x + m32 * sp_y + m33 * sp_z; /*** hope hit_z wont get too close to zero *******/ #ifdef DEBUG if (ABS(hit_z) < ABS(minhz)) { minhz = hit_z; fprintf(stdout, "should >>0 : hit_z %f\n", hit_z); fprintf(stdout, " hit_x %f\n", hit_x); fprintf(stdout, " ratio %f\n", hit_x / hit_z); fprintf(stdout, " long %f\n", atan(hit_x / hit_z)); sleep(1); } #endif if (ABS(hit_z) < 0.001) { if (hit_x * hit_z > 0.) longitude = PI / 2.; else longitude = -PI / 2.; if (hit_z > 0.) hit_z = 0.001; else hit_z = -0.001; } else { longitude = atan(hit_x / hit_z); } if (hit_z < 0.) longitude += PI; r = (double) sqrt(hit_x * hit_x + hit_z * hit_z); latitude = atan(-hit_y / r); light_angle = (light_x * hit_x + light_y * hit_y + light_z * hit_z) / radius; if (sens == 1) { /* * Set pixel in image */ teinte = mygetMapColorLinear(longitude, latitude, light_angle); myRPutPixel(px, py, &teinte); /* * mirror the left half-circle of the globe: * we need a new position and have to recalc. the * light intensity */ light_angle = (light_x * hit2_x + light_y * hit2_y + light_z * hit2_z) / radius; teinte = mygetMapColorLinear(2 * v_long - longitude, latitude, light_angle); myRPutPixel(DIAMETRE - px - 1, py, &teinte); } else { /* sens==-1 */ /* * Set pixel in image */ teinte = mygetMapColorLinear(longitude, latitude, light_angle); myRPutPixel(DIAMETRE - px - 1, DIAMETRE - py - 1, &teinte); /* * mirror the left half-circle of the globe: * we need a new position and have * to recalc. the light intensity */ light_angle = (light_x * hit2_x + light_y * hit2_y + light_z * hit2_z) / radius; teinte = mygetMapColorLinear(2 * v_long - longitude, latitude, light_angle); myRPutPixel(px, DIAMETRE - py - 1, &teinte); } } } /*px */ } /*py */ } /*else fun */ #if WITH_MARKERS /* markers */ if (nb_marker) { int i; double mx, my, mz; for (i = 0; i < nb_marker; i++) { mx = m11 * marker[i][0] + m31 * marker[i][2]; mz = -m31 * marker[i][0] + m11 * marker[i][2]; my = m22 * marker[i][1] - m23 * mz; mz = m23 * marker[i][1] + m22 * mz; if (mz > 0) { if (i == sun_marker) { put_dot_cross((int) (mx * radius_proj + DIAMETRE / 2 + funx), (int) (-my * radius_proj + DIAMETRE / 2 + funy), &sun_col); } else if (i == moon_marker) { put_dot_cross((int) (mx * radius_proj + DIAMETRE / 2 + funx), (int) (-my * radius_proj + DIAMETRE / 2 + funy), &moon_col); } else { put_cross((int) (mx * radius_proj + DIAMETRE / 2 + funx), (int) (-my * radius_proj + DIAMETRE / 2 + funy)); } } } } #endif solution = TRUE; return; } static RColor mygetMapColorLinear(double longitude, double latitude, double angle) { RColor point; int x, y, xl, yl, dx, dy, ang; if (longitude < 0.) longitude += 2 * PI; latitude += PI / 2; longitude += PI; if (longitude >= 2 * PI) longitude -= 2 * PI; if (angle > 0) ang = (int) floor((1 - ((1 - angle) * dawn)) * 256); else ang = angle * 256; xl = (int) (longitude * mratiox); yl = (int) (latitude * mratioy); x = xl >> 8; y = yl >> 8; dx = xl - (x << 8); dy = yl - (y << 8); if (use_nightmap) { if (ang > 0) { getquarter(map, x, y, md, dx, dy); getquarter(mapnight, x, y, mn, dx, dy); md[0]->r = ((mn[0]->r * (256 - ang) + md[0]->r * ang)) >> 8; md[0]->g = ((mn[0]->g * (256 - ang) + md[0]->g * ang)) >> 8; md[0]->b = ((mn[0]->b * (256 - ang) + md[0]->b * ang)) >> 8; } else { getquarter(mapnight, x, y, md, dx, dy); } } else { getquarter(map, x, y, md, dx, dy); if (ang > 0) { md[0]->r = ((md[0]->r * aml + md[0]->r * ang / 256 * (256 - aml))) >> 8; md[0]->g = ((md[0]->g * aml + md[0]->g * ang / 256 * (256 - aml))) >> 8; md[0]->b = ((md[0]->b * aml + md[0]->b * ang / 256 * (256 - aml))) >> 8; } else { md[0]->r = (md[0]->r * aml) >> 8; md[0]->g = (md[0]->g * aml) >> 8; md[0]->b = (md[0]->b * aml) >> 8; } } point.red = (unsigned char) md[0]->r; point.green = (unsigned char) md[0]->g; point.blue = (unsigned char) md[0]->b; point.alpha = 255; /* in fun mode, we use original Rputpixel that need alpha?*/ return point; } static void randomPosition() { addlat = ((rand() % 30001) / 30000.) * 180. - 90.; addlong = ((rand() % 30001) / 30000.) * 360. - 180.; return; } static void updateTime(int force) { /* calcul of sun position every minute */ if ((trend.tv_sec - tsunpos) >= 60 || force) { tsunpos = trend.tv_sec; sun_position(tsunpos, &sun_lat, &sun_long); light_x = cos(sun_lat) * sin(sun_long); light_y = sin(sun_lat); light_z = cos(sun_lat) * cos(sun_long); do_something = TRUE; #if WITH_MARKERS if (sun_marker >= 0) { marker[sun_marker][0] = light_x; marker[sun_marker][1] = light_y; marker[sun_marker][2] = light_z; } /* ... and the moon position */ if (moon_marker >= 0 || p_type == PTMOON || force == STRONG) { moon_position(tsunpos, &moon_lat, &moon_long); if (moon_marker >= 0) { marker[moon_marker][1] = moon_lat; marker[moon_marker][0] = moon_long; transform_marker(moon_marker); } } #endif } return; } void transform_marker(int m) { /* long/lat => rotation matrix */ double dtmp1, dtmp2; dtmp1 = sin(marker[m][0]) * cos(marker[m][1]); dtmp2 = sin(marker[m][1]); marker[m][2] = cos(marker[m][0]) * cos(marker[m][1]); marker[m][0] = dtmp1; marker[m][1] = dtmp2; } void setViewPos(double lat, double lon) { double dif; while (lat >= 360.) lat -= 360.; while (lat <= -360.) lat += 360.; while (addlat >= 360.) addlat -= 360.; while (addlat <= -360.) addlat += 360.; if (lat >= 90.) { dif = lat; lat = 180. - lat; addlat += (lat - dif); dlat *= -1; if (!fun && !stable) { lon += 180.; addlong += 180.; } if (!stable) sens *= -1; } if (lat <= -90.) { dif = lat; lat = -180. - lat; addlat += (lat - dif); dlat *= -1; if (!fun && !stable) { lon += 180.; addlong += 180.; } if (!stable) sens *= -1; } if (lat >= 90.) { dif = lat; lat = 180. - lat; addlat += (lat - dif); dlat *= -1; if (!fun && !stable) { lon += 180.; addlong += 180.; } if (!stable) sens *= -1; } if (lat <= -90.) { dif = lat; lat = -180. - lat; addlat += (lat - dif); dlat *= -1; if (!fun && !stable) { lon += 180.; addlong += 180.; } if (!stable) sens *= -1; } while (lon >= 180.) { lon -= 360.; addlong -= 360.; } while (lon <= -180.) { lon += 360.; addlong += 360.; } v_lat = lat * PI / 180.; v_long = lon * PI / 180.; dv_lat = lat; dv_long = lon; return; } void recalc(int force) { double coeff, va, vo; struct timeval tv, tnow; tnow = getimev(); trend = timeaccel(tnow); tv = diftimev(tnow, tlast); if (firstTime) { firstTime = FALSE; updateTime(STRONG); } else { coeff = (double) tv.tv_sec + tv.tv_usec / 1000000.; if (!force) { /** while !clic button rotate earth **/ addlat += dlat * coeff; addlong += dlong * coeff; } } if (addlong != old_dvlong || addlat != old_dvlat || p_type == PTRANDOM) { old_dvlong = addlong; old_dvlat = addlat; do_something = TRUE; } #if WITH_MARKERS if (force) { if (p_type == PTSUN) { va = sun_lat * 180. / PI; vo = sun_long * 180. / PI; updateTime(TRUE); addlat -= sun_lat * 180. / PI - va; addlong -= sun_long * 180. / PI - vo; } else if (p_type == PTMOON) { va = moon_lat * 180. / PI; vo = moon_long * 180. / PI; updateTime(TRUE); addlat -= moon_lat * 180. / PI - va; addlong -= moon_long * 180. / PI - vo; } #else if (force && p_type == PTSUN) { va = sun_lat * 180. / PI; vo = sun_long * 180. / PI; updateTime(TRUE); addlat -= sun_lat * 180. / PI - va; addlong -= sun_long * 180. / PI - vo; #endif } else { updateTime(FALSE); } if (do_something) { switch (p_type) { case PTSUN: setViewPos(sun_lat * 180. / PI + addlat, sun_long * 180. / PI + addlong); break; #if WITH_MARKERS case PTMOON: setViewPos(moon_lat * 180. / PI + addlat, moon_long * 180. / PI + addlong); break; #endif case PTFIXED: setViewPos(addlat, addlong); break; case PTRANDOM: if (stoprand == FALSE) randomPosition(); else stoprand--; setViewPos(addlat, addlong); break; default: break; } #ifdef DEBUG fprintf(stdout, "%s render\n", ctime(&trend.tv_sec)); #endif renderFrame(); } tlast = tnow; tnext = addtimev(tnow, tdelay); return; } /* convert a 4 layers RGBA image to a 3 layer one */ int ripalpha(RImage * image) { int x, y; unsigned char *d, *s, *old; if (image == NULL) return 0; if (image->format == RRGBFormat) return 1; d = malloc(image->width * image->height * 3 + 4); if (!d) { RErrorCode = RERR_NOMEMORY; puts("error in ripalpha"); return 0; } s = image->data; old = image->data; image->data = d; image->format = RRGBFormat; for (y = 0; y < image->height; y++) { for (x = 0; x < image->width; x++) { *d++ = *s++; *d++ = *s++; *d++ = *s++; s++; } } free(old); return 1; }