From f271a2cbb80df6943ff5de9caba8bbfc2115bcae Mon Sep 17 00:00:00 2001
From: Allanis <allanis@saracraft.net>
Date: Sat, 18 May 2013 15:40:18 +0100
Subject: [PATCH] [Add] Let's get ready to RUUUMMMBLLLEEEEE!!

---
 src/lephisto.c |  2 ++
 src/pilot.c    |  3 ++-
 src/player.c   |  2 ++
 src/spfx.c     | 60 +++++++++++++++++++++++++++++++++++++++++++++++++-
 src/spfx.h     |  7 ++++++
 5 files changed, 72 insertions(+), 2 deletions(-)

diff --git a/src/lephisto.c b/src/lephisto.c
index 7c4ae45..0d1e035 100644
--- a/src/lephisto.c
+++ b/src/lephisto.c
@@ -301,6 +301,8 @@ static void update_all(void) {
 //        | Text and GUI.
 // ========================================================
 static void render_all(void) {
+  // Setup.
+  spfx_start(dt);
   // BG.
   space_render(dt);
   planets_render();
diff --git a/src/pilot.c b/src/pilot.c
index ef84866..0ca75ef 100644
--- a/src/pilot.c
+++ b/src/pilot.c
@@ -425,7 +425,8 @@ static void pilot_update(Pilot* pilot, const double dt) {
       limit_speed(&pilot->solid->vel,
                   pilot->speed * pilot->afterburner->outfit->u.afb.speed_perc +
                   pilot->afterburner->outfit->u.afb.speed_abs, dt);
-      pilot->energy -= pilot->afterburner->outfit->u.afb.energy * dt;
+    spfx_shake(SHAKE_DECAY/2. * dt); // Shake goes down at half speed.
+    pilot->energy -= pilot->afterburner->outfit->u.afb.energy * dt; // Energy loss.
     } else
       limit_speed(&pilot->solid->vel, pilot->speed, dt);
   }
diff --git a/src/player.c b/src/player.c
index 8542acb..a87cee5 100644
--- a/src/player.c
+++ b/src/player.c
@@ -21,6 +21,7 @@
 #include "hook.h"
 #include "map.h"
 #include "lfile.h"
+#include "spfx.h"
 #include "player.h"
 
 #define XML_GUI_ID    "GUIs" // XML section identifier.
@@ -1319,6 +1320,7 @@ void player_afterburn(void) {
   if(player->afterburner != NULL) {
     player_setFlag(PLAYER_AFTERBURNER);
     pilot_setFlag(player, PILOT_AFTERBURNER);
+    spfx_shake(50.);
   }
 }
 
diff --git a/src/spfx.c b/src/spfx.c
index bf14da3..10548a0 100644
--- a/src/spfx.c
+++ b/src/spfx.c
@@ -6,11 +6,21 @@
 #include "physics.h"
 #include "opengl.h"
 #include "pause.h"
+#include "rng.h"
 #include "spfx.h"
 
 #define SPFX_GFX "../gfx/spfx/" // Graphics location.
-#define SPFX_CHUNK 10 // Chunk to allocate when needed.
+#define SPFX_CHUNK 32           // Chunk to allocate when needed.
 
+// Special hardcoded effects..
+
+// Shake, AKA RUMBLE!
+static double shake_rad = 0.;
+static Vec2 shake_pos = { .x = 0., .y = 0. };
+static Vec2 shake_vel = { .x = 0., .y = 0. };
+static int shake_off = 1;
+
+// Generic SPFX template.
 typedef struct SPFX_Base_ {
   char* name;
 
@@ -171,6 +181,54 @@ static void spfx_update_layer(SPFX* layer, int* nlayer, const double dt) {
   }
 }
 
+// Prepare the rendering for special affects.
+void spfx_start(double dt) {
+  GLdouble bx, by, x, y;
+  double inc;
+
+  if(shake_off == 1) return; // Save the cycles.
+  bx = SCREEN_W / 2;
+  by = SCREEN_H / 2;
+
+  if(!paused) {
+    inc = dt*100000.;
+
+    // Calculate new position.
+    if(shake_rad > 0.01) {
+      vect_cadd(&shake_pos, shake_vel.x * inc, shake_vel.y * inc);
+      
+      if(VMOD(shake_pos) > shake_rad) {
+        // Change direction.
+        vect_pset(&shake_pos, shake_rad, VANGLE(shake_pos));
+        vect_pset(&shake_vel, shake_rad,
+            -VANGLE(shake_pos) + (RNGF()-0.5) * M_PI);
+      }
+      shake_rad -= SHAKE_DECAY * dt;
+      if(shake_rad < 0.) shake_rad = 0.;
+
+      x = shake_pos.x;
+      y = shake_pos.y;
+    } else {
+      shake_rad = 0.;
+      shake_off = 1;
+      x = 0.;
+      y = 0.;
+    }
+  }
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  glOrtho(-bx+x, bx+x,  -by+y, by+y, -1., 1.);
+}
+
+// Add ruuumble!!
+void spfx_shake(double mod) {
+  shake_rad += mod;
+  if(shake_rad > SHAKE_MAX) shake_rad = SHAKE_MAX;
+  shake_off = 0;
+
+  vect_pset(&shake_vel, shake_rad, RNGF() * 2. * M_PI);
+}
+
 void spfx_render(const int layer) {
   SPFX* spfx_stack;
   int i, spfx_nstack;
diff --git a/src/spfx.h b/src/spfx.h
index b40dff0..e3fe43d 100644
--- a/src/spfx.h
+++ b/src/spfx.h
@@ -4,6 +4,9 @@
 #define SPFX_LAYER_FRONT  0
 #define SPFX_LAYER_BACK  1
 
+#define SHAKE_DECAY 50. // Decay parameter.
+#define SHAKE_MAX   50. // Max parameter.
+
 // Stack manipulation.
 int spfx_get(char* name);
 void spfx_add(const int effect,
@@ -16,6 +19,10 @@ void spfx_update(const double dt);
 void spfx_render(const int layer);
 void spfx_clear(void);
 
+// Get ready to rumble!
+void spfx_start(double dt);
+void spfx_shake(double mod);
+
 // Load/free.
 int spfx_load(void);
 void spfx_free(void);