From e066250c1f95eaec16c830d98923979d102f270e Mon Sep 17 00:00:00 2001
From: Allanis <allanis@saracraft.net>
Date: Sun, 21 Jul 2013 15:58:58 +0100
Subject: [PATCH] [Change] Improved nebulae system.

---
 src/menu.c    |   1 +
 src/nebulae.c | 115 +++++++++++++++++++++++++++-----------------------
 src/nebulae.h |   3 +-
 src/space.c   |  32 +++++++++-----
 4 files changed, 86 insertions(+), 65 deletions(-)

diff --git a/src/menu.c b/src/menu.c
index 935c77d..6466e34 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -69,6 +69,7 @@ void menu_main(void) {
   glTexture* tex;
 
   tex = gl_newImage("../gfx/saracraft_logo1.png");
+  nebu_prep(300., 0.); /* Needed for nebuale to not spaz out. */
 
   /* Create background image window. */
   bwid = window_create("BG", -1, -1, SCREEN_W, SCREEN_H);
diff --git a/src/nebulae.c b/src/nebulae.c
index d4654ed..051da08 100644
--- a/src/nebulae.c
+++ b/src/nebulae.c
@@ -11,8 +11,6 @@
 #include "menu.h"
 #include "perlin.h"
 
-#define NEBU_DT_MAX           5.
-
 #define NEBULAE_Z             16  /* Z plane. */
 #define NEBULAE_PATH          "gen/nebu_%02d.png"
 
@@ -30,6 +28,10 @@ static int nebu_pw, nebu_ph;
 static int cur_nebu[2] = { 0, 1 };
 static unsigned int last_render = 0;
 
+/* Nebuale properties. */
+static double nebu_view = 0.;
+static double nebu_dt   = 0.;
+
 static int nebu_checkCompat(const char* file);
 static void saveNebulae(float* map, const uint32_t w, const uint32_t h,
     const char* file);
@@ -112,7 +114,7 @@ void nebu_render(void) {
   /* Calculate frame to draw. */
   t = SDL_GetTicks();
   dt = (t - last_render) / 1000.;
-  if(dt > NEBU_DT_MAX) { /* Time to change. */
+  if(dt > nebu_dt) { /* Time to change. */
     tmp = cur_nebu[0];
     cur_nebu[0] += cur_nebu[0] - cur_nebu[1];
     cur_nebu[1] = tmp;
@@ -128,7 +130,7 @@ void nebu_render(void) {
   col[0] = cPurple.r;
   col[1] = cPurple.g;
   col[2] = cPurple.b;
-  col[3] = dt / NEBU_DT_MAX;
+  col[3] = dt / nebu_dt;
 
   tw = (double)nebu_w / (double)nebu_pw;
   th = (double)nebu_h / (double)nebu_ph;
@@ -206,7 +208,7 @@ void nebu_render(void) {
   gl_checkErr();
 }
 
-void nebu_renderOverlay(double density) {
+void nebu_renderOverlay(void) {
 #define ANG45   0.70710678118654757
 #define COS225  0.92387953251128674
 #define SIN225  0.38268343236508978
@@ -217,26 +219,26 @@ void nebu_renderOverlay(double density) {
 
   /* Stuff player partially sees. */
   glBegin(GL_TRIANGLE_FAN);
-    ACOLOUR(cPurple,              0.);
-    glVertex2d(0.,                0.);
-    ACOLOUR(cPurple,              1.);
-    glVertex2d(-density,          0.);
-    glVertex2d(-density*COS225,   density*SIN225);
-    glVertex2d(-density*ANG45,    density*ANG45);
-    glVertex2d(-density*SIN225,   density*COS225);
-    glVertex2d( 0.,               density);
-    glVertex2d( density*SIN225,   density*COS225);
-    glVertex2d( density*ANG45,    density*ANG45);
-    glVertex2d( density*COS225,   density*SIN225);
-    glVertex2d( density,          0.);
-    glVertex2d( density*COS225,   -density*SIN225);
-    glVertex2d( density*ANG45,    -density*ANG45);
-    glVertex2d( density*SIN225,   -density*COS225);
-    glVertex2d( 0.,               -density);
-    glVertex2d(-density*SIN225,   -density*COS225);
-    glVertex2d(-density*ANG45,    -density*ANG45);
-    glVertex2d(-density*COS225,   -density*SIN225);
-    glVertex2d(-density,          0.);
+    ACOLOUR(cPurple,                0.);
+    glVertex2d(0.,                  0.);
+    ACOLOUR(cPurple,                1.);
+    glVertex2d(-nebu_view,          0.);
+    glVertex2d(-nebu_view*COS225,   nebu_view*SIN225);
+    glVertex2d(-nebu_view*ANG45,    nebu_view*ANG45);
+    glVertex2d(-nebu_view*SIN225,   nebu_view*COS225);
+    glVertex2d( 0.,                 nebu_view);
+    glVertex2d( nebu_view*SIN225,   nebu_view*COS225);
+    glVertex2d( nebu_view*ANG45,    nebu_view*ANG45);
+    glVertex2d( nebu_view*COS225,   nebu_view*SIN225);
+    glVertex2d( nebu_view,          0.);
+    glVertex2d( nebu_view*COS225,   -nebu_view*SIN225);
+    glVertex2d( nebu_view*ANG45,    -nebu_view*ANG45);
+    glVertex2d( nebu_view*SIN225,   -nebu_view*COS225);
+    glVertex2d( 0.,                 -nebu_view);
+    glVertex2d(-nebu_view*SIN225,   -nebu_view*COS225);
+    glVertex2d(-nebu_view*ANG45,    -nebu_view*ANG45);
+    glVertex2d(-nebu_view*COS225,   -nebu_view*SIN225);
+    glVertex2d(-nebu_view,          0.);
   glEnd(); /* GL_TRIANGLE_FAN */
 
   glShadeModel(GL_FLAT);
@@ -245,43 +247,43 @@ void nebu_renderOverlay(double density) {
   /* Stuff player can't see. */
   glBegin(GL_TRIANGLE_FAN);
     /* Top left. */
-    glVertex2d(-SCREEN_W/2.-gui_xoff,   SCREEN_H/2.-gui_yoff);
-    glVertex2d(-density,                0.);
-    glVertex2d(-density*COS225,         density*SIN225);
-    glVertex2d(-density*ANG45,          density*ANG45);
-    glVertex2d(-density*SIN225,         density*COS225);
-    glVertex2d(0.,                      density);
-    glVertex2d( SCREEN_W/2.-gui_xoff,   SCREEN_H/2.-gui_yoff);
+    glVertex2d(-SCREEN_W/2.-gui_xoff,     SCREEN_H/2.-gui_yoff);
+    glVertex2d(-nebu_view,                0.);
+    glVertex2d(-nebu_view*COS225,         nebu_view*SIN225);
+    glVertex2d(-nebu_view*ANG45,          nebu_view*ANG45);
+    glVertex2d(-nebu_view*SIN225,         nebu_view*COS225);
+    glVertex2d(0.,                        nebu_view);
+    glVertex2d( SCREEN_W/2.-gui_xoff,     SCREEN_H/2.-gui_yoff);
   glEnd(); /* GL_TRIANGLE_FAN */
   glBegin(GL_TRIANGLE_FAN);
     /* Top right. */
-    glVertex2d( SCREEN_W/2.-gui_xoff,   SCREEN_H/2.-gui_yoff);
-    glVertex2d( 0.,                     density);
-    glVertex2d( density*SIN225,         density*COS225);
-    glVertex2d( density*ANG45,          density*ANG45);
-    glVertex2d( density*COS225,         density*SIN225);
-    glVertex2d( density,                0.);
-    glVertex2d( SCREEN_W/2.-gui_xoff,   -SCREEN_H/2.-gui_yoff);
+    glVertex2d( SCREEN_W/2.-gui_xoff,     SCREEN_H/2.-gui_yoff);
+    glVertex2d( 0.,                       nebu_view);
+    glVertex2d( nebu_view*SIN225,         nebu_view*COS225);
+    glVertex2d( nebu_view*ANG45,          nebu_view*ANG45);
+    glVertex2d( nebu_view*COS225,         nebu_view*SIN225);
+    glVertex2d( nebu_view,                0.);
+    glVertex2d( SCREEN_W/2.-gui_xoff,     -SCREEN_H/2.-gui_yoff);
   glEnd(); /* GL_TRIANGLE_FAN */
   glBegin(GL_TRIANGLE_FAN);
     /* Bottom right. */
-    glVertex2d( SCREEN_W/2.-gui_xoff,   -SCREEN_H/2.-gui_yoff);
-    glVertex2d( density,                0.);
-    glVertex2d( density*COS225,         -density*SIN225);
-    glVertex2d( density*ANG45,          -density*ANG45);
-    glVertex2d( density*SIN225,         -density*COS225);
-    glVertex2d( 0.,                     -density);
-    glVertex2d( -SCREEN_W/2.-gui_xoff,  -SCREEN_H/2.-gui_yoff);
+    glVertex2d( SCREEN_W/2.-gui_xoff,     -SCREEN_H/2.-gui_yoff);
+    glVertex2d( nebu_view,                0.);
+    glVertex2d( nebu_view*COS225,         -nebu_view*SIN225);
+    glVertex2d( nebu_view*ANG45,          -nebu_view*ANG45);
+    glVertex2d( nebu_view*SIN225,         -nebu_view*COS225);
+    glVertex2d( 0.,                       -nebu_view);
+    glVertex2d( -SCREEN_W/2.-gui_xoff,    -SCREEN_H/2.-gui_yoff);
   glEnd(); /* GL_TRIANGLE_FAN */
   glBegin(GL_TRIANGLE_FAN);
     /* Bottom left */
-    glVertex2d( -SCREEN_W/2.-gui_xoff,  -SCREEN_H/2.-gui_yoff);
-    glVertex2d( 0.,                     -density);
-    glVertex2d(-density*SIN225,         -density*COS225);
-    glVertex2d(-density*ANG45,          -density*ANG45);
-    glVertex2d(-density*COS225,         -density*SIN225);
-    glVertex2d(-density,                0.);
-    glVertex2d(-SCREEN_W/2.-gui_xoff,   SCREEN_H/2.-gui_yoff);
+    glVertex2d( -SCREEN_W/2.-gui_xoff,    -SCREEN_H/2.-gui_yoff);
+    glVertex2d( 0.,                       -nebu_view);
+    glVertex2d(-nebu_view*SIN225,         -nebu_view*COS225);
+    glVertex2d(-nebu_view*ANG45,          -nebu_view*ANG45);
+    glVertex2d(-nebu_view*COS225,         -nebu_view*SIN225);
+    glVertex2d(-nebu_view,                0.);
+    glVertex2d(-SCREEN_W/2.-gui_xoff,     SCREEN_H/2.-gui_yoff);
   glEnd(); /* GL_TRIANGLE_FAN */
 
   glPopMatrix();
@@ -293,6 +295,13 @@ void nebu_renderOverlay(double density) {
 #undef SIN225
 }
 
+/* Prepare the nebulae. */
+void nebu_prep(double density, double volatility) {
+  (void)volatility;
+  nebu_view = 1000. - density;        /* At density 1000 you're blind. */
+  nebu_dt = 2000. / (density + 100.); /* Faster at higher density. */
+}
+
 /* Force generation of new nebulae. */
 void nebu_forceGenerate(void) {
   nebu_w = nebu_h = -9;
diff --git a/src/nebulae.h b/src/nebulae.h
index b32c043..4b8b0ea 100644
--- a/src/nebulae.h
+++ b/src/nebulae.h
@@ -6,8 +6,9 @@ void nebu_exit(void);
 
 /* Render. */
 void nebu_render(void);
-void nebu_renderOverlay(double density);
+void nebu_renderOverlay(void);
 
 /* Misc. */
+void nebu_prep(double density, double volatility);
 void nebu_forceGenerate(void);
 
diff --git a/src/space.c b/src/space.c
index 873c6db..c92ef30 100644
--- a/src/space.c
+++ b/src/space.c
@@ -411,14 +411,20 @@ void space_init(const char* sysname) {
     player_message("Entering System %s on %s", sysname, lt);
     free(lt);
 
-    /* Set up stars. */
-    nstars = (cur_system->stars*SCREEN_W*SCREEN_H+STAR_BUF*STAR_BUF)/(800*640);
-    if(mstars < nstars)
-      stars = realloc(stars, sizeof(Star)*nstars); /* should realloc not malloc. */
-    for(i = 0; i < nstars; i++) {
-      stars[i].brightness = (double)RNG(50, 200)/256.;
-      stars[i].x = (double)RNG(-STAR_BUF, SCREEN_W + STAR_BUF);
-      stars[i].y = (double)RNG(-STAR_BUF, SCREEN_H + STAR_BUF);
+    /* Handle background. */
+    if(cur_system->nebu_density > 0.) {
+      /* Background is nebulae. */
+      nebu_prep(cur_system->nebu_density, cur_system->nebu_volatility);
+    } else {
+      /* Background is stary. */
+      nstars = (cur_system->stars*SCREEN_W*SCREEN_H+STAR_BUF*STAR_BUF)/(800*640);
+      if(mstars < nstars)
+        stars = realloc(stars, sizeof(Star)*nstars); /* Should realloc, not malloc. */
+      for(i = 0; i < nstars; i++) {
+        stars[i].brightness = (double)RNG(50, 200)/256.;
+        stars[i].x = (double)RNG(-STAR_BUF, SCREEN_W + STAR_BUF);
+        stars[i].y = (double)RNG(-STAR_BUF, SCREEN_H + STAR_BUF);
+      }
     }
   }
   /* Set up fleets -> pilots. */
@@ -800,7 +806,9 @@ int space_load(void) {
 
 /* Render the system. -- Just playing god now. */
 void space_render(double dt) {
-  if((cur_system != NULL) && (cur_system->nebu_density > 0.))
+  if(cur_system == NULL) return;
+
+  if(cur_system->nebu_density > 0.)
     nebu_render();
   else
     space_renderStars(dt);
@@ -808,8 +816,10 @@ void space_render(double dt) {
 
 /* Render the overlay. */
 void space_renderOverlay(void) {
-  if((cur_system != NULL) && (cur_system->nebu_density > 0.))
-    nebu_renderOverlay(cur_system->nebu_density);
+  if(cur_system == NULL) return; 
+
+  if(cur_system->nebu_density > 0.)
+    nebu_renderOverlay();
 }
 
 /* Render stars. */