diff --git a/globe.h b/globe.h index b2d3d2a..e2f1665 100644 --- a/globe.h +++ b/globe.h @@ -89,26 +89,33 @@ void draw_globe(double t, double zoom) double theta = atan2(z, sqrt(x*x + y*y)); double phi = fmod(atan2(y, x) + rotation, 2.*M_PI); - double elevation = hillnoise(theta*5., phi*5.); - double clouds = hillnoise(theta*5., phi*5. - 1.*rotation - 100.); + double elevation = hillnoise(theta*4., phi*4.); + double clouds = hillnoise(theta*16., phi*7. - 1.*rotation - 100.); int color; int ch; if ((fabs(z)/rho) > .9) { elevation = elevation + mix(.0, 1., 10.*(fabs(z)/rho - .9)) > .6 ? 1. : 0.; } if (clouds < .4) { - ch = (clouds < .3 ? '0' : '%') | A_BOLD; - color = COLOR_PAIR(WHITE); + continue; } else if (elevation < .55) { + // Water ch = '~'; color = COLOR_PAIR(BLUE); - } else if (elevation < .6) { + } else if (elevation < .65) { + // Sand ch = ':'; color = COLOR_PAIR(YELLOW); + } else if (elevation < .75) { + // Grass + ch = ',' | A_BOLD; + color = COLOR_PAIR(GREEN); } else if (elevation < .85) { - ch = 'S'; + // Forest + ch = '&'; color = COLOR_PAIR(GREEN); } else { + // Mountain ch = '#'; color = COLOR_PAIR(WHITE); } @@ -119,22 +126,57 @@ void draw_globe(double t, double zoom) } } -// return 1 if visible, else 0 -int get_target_pos(double t, double zoom, int *targetr, int *targetc) +void draw_clouds(double t, double zoom) { int rows,cols; getmaxyx(stdscr,rows,cols); double rotation = get_rotation(t); const double rho = rows/2.; + for (int r = 0; r < rows; r++) { + for (int c = 0; c < cols; c++) { + double y = (c - cols/2) * 0.5 / zoom; + double z = (r - rows/2) * 1.0 / zoom; + double x = sqrt(rho*rho - z*z - y*y); - double theta = M_PI/2*1.00; - double phi = M_PI + rotation + 2.3; + if (z*z + y*y > rho*rho) { + continue; + } + + double theta = atan2(z, sqrt(x*x + y*y)); + double phi = fmod(atan2(y, x) + rotation, 2.*M_PI); + double clouds = hillnoise(theta*16., phi*7. - 1.*rotation - 100.); + int color; + int ch; + if (clouds < .4) { + ch = (clouds < .3 ? '0' : '%') | A_BOLD; + color = COLOR_PAIR(WHITE); + attron(color); + mvaddch(r,c,ch); + attroff(color); + } + } + } +} + +int latlon_to_rc(double t, double zoom, double lat, double lon, int *r, int *c) +{ + int rows,cols; + getmaxyx(stdscr,rows,cols); + const double rho = rows/2.; + double theta = lat; + double phi = lon + get_rotation(t); double x = rho*sin(theta)*cos(phi); double y = rho*sin(theta)*sin(phi); double z = rho*cos(theta); - int r = z / (1.0/zoom) + rows/2; - int c = y / (.5/zoom) + cols/2; - *targetr = r; - *targetc = c; + *r = z / (1.0/zoom) + rows/2; + *c = y / (.5/zoom) + cols/2; return x < 0; } + +const double target_lat = M_PI/2*1.01; +const double target_lon = M_PI + 2.6; +// return 1 if visible, else 0 +int get_target_pos(double t, double zoom, int *targetr, int *targetc) +{ + return latlon_to_rc(t, zoom, target_lat, target_lon, targetr, targetc); +} diff --git a/nuke.c b/nuke.c index 9fb48e3..53c1b75 100644 --- a/nuke.c +++ b/nuke.c @@ -304,7 +304,7 @@ int main(int argc, char *argv[]) const double anticipation = 0.5; const double firing_time = 1.0; const double nuking_time = .5; - const double aftermath = 1.0; + const double aftermath = 100.0; int f = 0; int targetr, targetc; @@ -319,6 +319,7 @@ int main(int argc, char *argv[]) mvaddch(targetr,targetc, '*' | A_BOLD); attroff(COLOR_PAIR(YELLOW)); } + draw_clouds(t, zoom); // Draw crosshair double wobble = t > targeting_time ? 0. : targeting_time - t; int r = targetr, c = targetc; @@ -393,23 +394,34 @@ int main(int argc, char *argv[]) // Draw crater if (get_target_pos(t, zoom, &targetr, &targetc)) { attron(COLOR_PAIR(BLACK) | A_BOLD); + for (int i = 31; i >= 0; i--) { + double rad = 4./31.*i; + double a = i*2*M_PI*GOLDEN_RATIO; + int r = targetr+(int)(rad*sin(a)/2), c = targetc+(int)(rad*cos(a)); + if ((r-rows/2)*(r-rows/2) + (c/2-cols/4)*(c/2-cols/4) <= (zoom*rows/2)*(zoom*rows/2)) + mvaddch(r, c, " #*."[i*4/31]); + } + attroff(COLOR_PAIR(BLACK) | A_BOLD); + /* + for (double =target_lat mvprintw(targetr-1,targetc-1,"****"); mvprintw(targetr,targetc-2, "** **"); mvprintw(targetr+1,targetc-1,"****"); - attroff(COLOR_PAIR(BLACK) | A_BOLD); + */ + } + draw_clouds(t, zoom); + if (get_target_pos(t, zoom, &targetr, &targetc)) { + // Draw label + attron(COLOR_PAIR(GREEN)); + mvaddch(targetr-1,targetc+1,'/'); + attroff(COLOR_PAIR(GREEN)); + attron(COLOR_PAIR(BLACK_ON_GREEN)); + mvprintw(targetr-2,targetc+2," DELETED "); + attroff(COLOR_PAIR(BLACK_ON_GREEN)); } - // Draw label - attron(COLOR_PAIR(GREEN)); - mvaddch(targetr-1,targetc+1,'/'); - attroff(COLOR_PAIR(GREEN)); - attron(COLOR_PAIR(BLACK_ON_GREEN)); - mvprintw(targetr-2,targetc+2," DELETED "); - attroff(COLOR_PAIR(BLACK_ON_GREEN)); refresh(); - int ch = getch(); - if (ch == 'q' || ch == 27) { + if (getch() != -1) goto exit_success; - } usleep(33333); // 30 FPS }