From 56b0856541446cbafee4eed9ef0ee9fb69af565a Mon Sep 17 00:00:00 2001
From: Stijn Buys <ingar@osirion.org>
Date: Fri, 8 Aug 2008 22:17:29 +0000
Subject: improved truster indicator, impulse engine sounds

---
 src/audio/audio.cc      |  74 +++++++++++++++++++++++++++-------
 src/audio/audio.h       |  12 ++++--
 src/client/input.cc     |  40 ++++++++++--------
 src/client/input.h      |   2 +
 src/client/targets.cc   |  92 +++++++++++++++++++++++++++++++-----------
 src/client/video.cc     |   7 +++-
 src/client/view.cc      |  17 +++++++-
 src/core/clientstate.cc |  30 +++++++++++---
 src/core/clientstate.h  |  18 ++++++++-
 src/game/ship.cc        | 105 +++++++++++++++++++++++++++++-------------------
 src/game/ship.h         |   7 ++--
 src/render/dust.cc      |   4 +-
 12 files changed, 295 insertions(+), 113 deletions(-)

diff --git a/src/audio/audio.cc b/src/audio/audio.cc
index 50d15c8..81a260c 100644
--- a/src/audio/audio.cc
+++ b/src/audio/audio.cc
@@ -81,19 +81,19 @@ void shutdown()
 	}	
 }
 
-void play(const char *name)
+size_t play(const char *name)
 {
 	if (!audio_context)
-		return;
+		return 0;
 
-	size_t buffer = Buffers::load(std::string(name));
+	size_t buffer_index = Buffers::load(std::string(name));
 
 	for (size_t i = 0; i < MAXUISOURCES; i++) {	
 		ALint srcstate = 0;
 		ALuint source = Sources::source(i);
 		alGetSourcei(source , AL_SOURCE_STATE , &srcstate);
 		if (srcstate != AL_PLAYING) {
-			Buffers::bind(source, buffer);
+			Buffers::bind(source, buffer_index);
  			alSourcef(source, AL_PITCH, 1.0);
     			alSourcef(source, AL_GAIN, 1.0);
 			alSourcei(source, AL_SOURCE_RELATIVE, AL_TRUE);
@@ -101,30 +101,49 @@ void play(const char *name)
 			alSourcefv(source, AL_POSITION, location);
 			alSourceRewind(source);
 			alSourcePlay(source);
-			return;
+			return buffer_index;
 		}
 	}
+
+	return 0;
 }
 
-void update_source(size_t source_index, math::Vector3f const & location, math::Vector3f const & velocity, float pitch, float gain)
+size_t play(size_t source_index, size_t buffer_index, float pitch, float gain) 
 {
-	if (!audio_context)
-		return;
+	if (!audio_context || !buffer_index)
+		return 0;
 
 	ALuint source = Sources::source(source_index);
-	alSourcefv(source, AL_POSITION, location.ptr());
-	//alSourcefv(source, AL_VELOCITY, velocity.ptr());
+	ALint srcstate = 0;
+	alGetSourcei(source , AL_SOURCE_STATE , &srcstate);
+	if (srcstate == AL_PLAYING) {
+		alSourceStop(source);
+	}
+	Buffers::bind(source, buffer_index);
+	alSourcei(source, AL_SOURCE_RELATIVE, AL_FALSE);
 	alSourcef(source, AL_PITCH, pitch);
     	alSourcef(source, AL_GAIN, gain);
+
+ 	alSourcei(source, AL_LOOPING,  AL_FALSE);
+	alSourceRewind(source);
+	alSourcePlay(source);
+
+	return buffer_index;
 }
 
-void loop( size_t source_index, const char *name, float pitch, float gain)
+size_t loop(size_t source_index, size_t buffer_index, float pitch, float gain)
 {
-	if (!audio_context)
-		return;
+	if (!audio_context || !buffer_index)
+		return 0;
 
 	ALuint source = Sources::source(source_index);
-	Buffers::bind(source, Buffers::load(std::string(name)));
+	ALint srcstate = 0;
+	alGetSourcei(source , AL_SOURCE_STATE , &srcstate);
+	if (srcstate == AL_PLAYING) {
+		alSourceStop(source);
+	}
+
+	Buffers::bind(source, buffer_index);
 
 	//alSourcef(source, AL_REFERENCE_DISTANCE, 2.0f); // might be the cause of cracks in the sound
 	alSourcei(source, AL_SOURCE_RELATIVE, AL_FALSE);
@@ -134,6 +153,20 @@ void loop( size_t source_index, const char *name, float pitch, float gain)
  	alSourcei(source, AL_LOOPING,  AL_TRUE);
 	alSourceRewind(source);
 	alSourcePlay(source);
+
+	return buffer_index;
+}
+
+size_t loop(size_t source_index, const char *name, float pitch, float gain)
+{
+	if (!audio_context)
+		return 0;
+
+	size_t buffer_index = Buffers::load(std::string(name));
+	if (buffer_index)
+		loop(source_index, buffer_index, pitch, gain);
+
+	return buffer_index;
 }
 
 void update_listener(math::Vector3f const &location, math::Axis const &axis, math::Vector3f const & velocity)
@@ -151,5 +184,18 @@ void update_listener(math::Vector3f const &location, math::Axis const &axis, mat
 	alListenerfv(AL_ORIENTATION, orientation);
 	//alListenerfv(AL_VELOCITY, velocity.ptr());
 }
+
+
+void update_source(size_t source_index, math::Vector3f const & location, math::Vector3f const & velocity, float pitch, float gain)
+{
+	if (!audio_context)
+		return;
+
+	ALuint source = Sources::source(source_index);
+	alSourcefv(source, AL_POSITION, location.ptr());
+	//alSourcefv(source, AL_VELOCITY, velocity.ptr());
+	alSourcef(source, AL_PITCH, pitch);
+    	alSourcef(source, AL_GAIN, gain);
+}
 	
 }
diff --git a/src/audio/audio.h b/src/audio/audio.h
index a3d4010..c0479d3 100644
--- a/src/audio/audio.h
+++ b/src/audio/audio.h
@@ -32,11 +32,17 @@ void shutdown();
 /// load an audio sample
 void load(const char *name);
 
-/// play a previously loaded audio sample
-void play(const char *name);
+/// play a previously loaded audio sample on the ui channel
+size_t play(const char *name);
+
+/// playe a sound from a specific buffer on a specific source
+size_t play(size_t source_index, size_t buffer_index, float pitch=1.0f, float gain=1.0f);
 
 /// play a looping sound on a specified source
-void loop( size_t source_index, const char *name, float pitch=1.0f, float gain=1.0f);
+size_t loop( size_t source_index, const char *name, float pitch=1.0f, float gain=1.0f);
+
+/// play a looping sound from a specified buffer on a specified source
+size_t loop(size_t source_index, size_t buffer_index, float pitch, float gain);
 
 /// update source parameters
 void update_source(size_t source_index, math::Vector3f const & location, math::Vector3f const & velocity, float pitch=1.0f, float gain=1.0f);
diff --git a/src/client/input.cc b/src/client/input.cc
index 7812d7e..963dd9f 100644
--- a/src/client/input.cc
+++ b/src/client/input.cc
@@ -59,8 +59,6 @@ float mouse_pitch = 0;
 float mouse_direction = 0;
 
 
-
-
 // true if the mouse has control
 const float mouse_timeout = 0.200f; // 200 ms select time-out
 float mouse_control_override_time = 0;
@@ -355,8 +353,10 @@ void action_press(Key const *key, std::string const &action)
 	
 	/* -- mouse control ------------------------------- */
 	} else if (action.compare("+control") == 0) {
-		mouse_control_override = true;
-		mouse_control_override_time = key->pressed();
+		if (!mouse_control_override) {
+			mouse_control_override = true;
+			mouse_control_override_time = key->pressed();
+		}
 
 	/* -- directional control ------------------------- */
 	} else if (action.compare("+left") == 0) {
@@ -404,17 +404,19 @@ void action_release(Key *key, std::string const &action)
 
 	/* -- mouse control ------------------------------- */
 	} else if (action.compare("+control") == 0) {
-		mouse_control_override = false;
-		mouse_control_override_time = 0;
-
-		if (!input_mousecontrol->value() || (joystick_control && mouse_control && 
-			(render::Camera::mode() == render::Camera::Track ||  render::Camera::mode() == render::Camera::Cockpit))) {
-			local_direction = 0.0f;
-			local_pitch = 0.0f;
-			local_roll = 0.0f;
-
-			render::Camera::set_direction(0.0f);
-			render::Camera::set_pitch(0.0f);
+		if (mouse_control_override) {
+			mouse_control_override = false;
+			mouse_control_override_time = 0;
+	
+			if (!input_mousecontrol->value() || (joystick_control && mouse_control && 
+				(render::Camera::mode() == render::Camera::Track ||  render::Camera::mode() == render::Camera::Cockpit))) {
+				local_direction = 0.0f;
+				local_pitch = 0.0f;
+				local_roll = 0.0f;
+	
+				render::Camera::set_direction(0.0f);
+				render::Camera::set_pitch(0.0f);
+			}
 		}
 
 	/* -- directional control ------------------------- */
@@ -524,7 +526,7 @@ void key_pressed(Key *key)
 
 void key_released(Key *key)
 {
-	if (core::application()->connected() && core::localcontrol() && !console()->visible() && !chat::visible()) {
+	if (core::application()->connected() && core::localcontrol()) {
 
 		if ((key->sym() ==  512 + SDL_BUTTON_LEFT) && targets::hover() && (key->waspressed() <= mouse_timeout) ) {
 			// hovering target selected
@@ -657,6 +659,10 @@ void frame(float seconds)
 		render::reset();	
 	}
 
+	if (core::localcontrol() && (core::localcontrol()->eventstate() != core::Entity::Normal)) {
+		local_thrust = core::localcontrol()->thrust();
+	}
+
 	/* -- detect joystick stat changes ---------------- */
 	Joystick::frame();
 	joystick_control = Joystick::is_enabled();
@@ -761,7 +767,7 @@ void frame(float seconds)
 	
 	for (Keyboard::iterator it = keyboard->begin(); it != keyboard->end(); it++) {
 		key = (*it).second;
-		if (key && key->sym() < 512 && key->pressed()) {
+		if (key && key->pressed()) {
 			while ((key->pressed()+delay < core::application()->time()) && (key->lastpressed()+repeat < core::application()->time())) {
 				if (key->lastpressed() > key->pressed())
 					key->key_lastpressed += repeat;
diff --git a/src/client/input.h b/src/client/input.h
index cf4c169..a954040 100644
--- a/src/client/input.h
+++ b/src/client/input.h
@@ -47,6 +47,8 @@ extern bool mouse_deadzone;
 extern bool mouse_control;
 extern bool joystick_control;
 
+extern float local_thrust;
+
 } // namespace input
 
 } // namespace client
diff --git a/src/client/targets.cc b/src/client/targets.cc
index f922199..384c793 100644
--- a/src/client/targets.cc
+++ b/src/client/targets.cc
@@ -10,6 +10,8 @@
 #include <iomanip>
 
 #include "audio/audio.h"
+#include "audio/buffers.h"
+#include "audio/sources.h"
 #include "auxiliary/functions.h"
 #include "audio/sources.h"
 #include "client/input.h"
@@ -292,7 +294,7 @@ void render_listener_sound()
 	audio::update_listener(render::Camera::eye(), render::Camera::axis(), velocity);
 }
 
-void render_entity_sound(core::Entity *entity)
+void render_entity_sound(core::EntityControlable *entity)
 {
 	if (!(entity->type() == core::Entity::Controlable))
 		return;
@@ -302,34 +304,77 @@ void render_entity_sound(core::Entity *entity)
 		return;
 	}
 
-	core::EntityControlable *entitycontrolable = (core::EntityControlable *) entity;
 	core::ClientState *state = entity->state();
+	if (!(entity->model() && state->detailvisible())) {
+		entity->state()->clearsound();
+		return;
+	}
 
-	if (entity->model() && state->detailvisible() && entitycontrolable->thrust() > 0 ) {
+	if (!state->state_thusterloopbuffer || ! state->state_impulseloopbuffer) {
+		// load engine sound
+		size_t enginesound = 0;
+		if (entity->model())
+			enginesound = entity->model()->enginesound();
+			
+		std::stringstream soundname;
+		soundname << "engines/loop" << std::setfill('0') << std::setw(2) << enginesound;
+		state->state_thusterloopbuffer = audio::Buffers::load(soundname.str());
+
+		// load impulse sound
+		// FIXME read impulse sound set from model
+		state->state_impulseloopbuffer = audio::Buffers::load("engines/impulse_loop00");
+		state->state_impulsestartbuffer = audio::Buffers::load("engines/impulse_start00");
+		state->state_impulsestopbuffer = audio::Buffers::load("engines/impulse_stop00");
+	}
 
-		float speed = entitycontrolable->speed();
-		float pitch = 0.2f + entitycontrolable->thrust() * 0.8f;
-		
-		if (!state->state_enginesound) {
-			if ((state->state_enginesound = audio::Sources::get()) > 0 ) {
-
-				size_t enginesound = 0;
-				if (entity->model())
-					enginesound = entity->model()->enginesound();
-				
-				std::stringstream soundname;
-				soundname << "engines/loop" << std::setfill('0') << std::setw(2) << enginesound;
-				audio::loop(state->state_enginesound, soundname.str().c_str(), pitch, 0);
-			}
+	
+	if (!state->state_engineloopsource) {
+		state->state_engineloopsource = audio::Sources::get();
+		state->state_engineeventsource = audio::Sources::get();
+	}
+
+	float speed = entity->speed();
+	float pitch = 0.2f + entity->thrust() * 0.8f;
+	float gain = 0.0;
+	if (entity->thrust() > 0 ) {
+		gain = 1.0f;
+	}
+
+	if (entity->eventstate() == core::Entity::ImpulseInitiate ) {
+
+		if (state->state_engineeventbuffer != state->state_impulsestartbuffer) {
+			audio::update_source(state->state_engineeventsource,
+				state->location() - state->axis().forward() * entity->model()->maxbbox().y , state->axis().forward() * speed);
+			state->state_engineeventbuffer = audio::play(state->state_engineeventsource, state->state_impulsestartbuffer);
 		}
+	} else if (entity->eventstate() == core::Entity::Impulse) {
 
-		if (state->state_enginesound) {
-			audio::update_source(state->state_enginesound,
-				state->location() - state->axis().forward() * entity->model()->maxbbox().y , state->axis().forward() * speed, pitch);
+		state->state_engineeventbuffer = state->state_impulseloopbuffer;
+
+		if (state->state_engineloopbuffer != state->state_impulseloopbuffer) {
+			state->state_engineloopbuffer = audio::loop(state->state_engineloopsource, state->state_impulseloopbuffer, pitch, 0);
 		}
+		pitch = 1.0f;
 	} else {
-		entity->state()->clearsound();
+
+		if (state->state_engineeventbuffer == state->state_impulseloopbuffer) {
+			audio::update_source(state->state_engineeventsource,
+				state->location() - state->axis().forward() * entity->model()->maxbbox().y , state->axis().forward() * speed);
+			state->state_engineeventbuffer = audio::play(state->state_engineeventsource, state->state_impulsestopbuffer);
+		}
+		state->state_engineeventbuffer = 0;
+
+		if (state->state_engineloopbuffer != state->state_thusterloopbuffer) {
+			state->state_engineloopbuffer = audio::loop(state->state_engineloopsource, state->state_thusterloopbuffer, pitch, 0);
+		}
 	}
+
+
+	audio::update_source(state->state_engineloopsource,
+	state->location() - state->axis().forward() * entity->model()->maxbbox().y , state->axis().forward() * speed, pitch, gain);
+
+	audio::update_source(state->state_engineeventsource,
+	state->location() - state->axis().forward() * entity->model()->maxbbox().y , state->axis().forward() * speed);
 }
 
 void draw_entity_offscreen_target(core::Entity *entity, bool is_active_target)
@@ -511,8 +556,9 @@ void draw()
 		core::Entity *entity = (*it);
 		
 		// render entity sound
-		render_entity_sound(entity);
-
+		if (entity->type() == core::Entity::Controlable) {
+			render_entity_sound(static_cast<core::EntityControlable *>(entity));
+		}
 		// find the current target
 		if (core::localcontrol() && is_legal_target(entity)) {
 
diff --git a/src/client/video.cc b/src/client/video.cc
index 5a4e535..2c1fe6b 100644
--- a/src/client/video.cc
+++ b/src/client/video.cc
@@ -126,6 +126,9 @@ bool init()
 			return false;
 	}
 	con_print << "  video mode " << width << "x" << height << "x" << bpp << "bpp" << std::endl;
+
+#ifdef HAVE_DEBUG_MESSAGES
+
 	int red, green, blue, alpha, depth;
 
 	SDL_GL_GetAttribute( SDL_GL_RED_SIZE, &red);
@@ -135,7 +138,9 @@ bool init()
 	SDL_GL_GetAttribute( SDL_GL_DEPTH_SIZE, &depth);
 
 	con_debug << "  visual r: " << red << " g: " << green << " blue: " << blue << " alpha: " << alpha << " depth: " << depth << std::endl;
-	
+
+#endif // HAVE_DEBUG_MESSAGES
+
 	render::Camera::set_aspect(width,  height);
 	(*r_width) = width;
 	(*r_height) = height;
diff --git a/src/client/view.cc b/src/client/view.cc
index e1e0820..1fdbcdc 100644
--- a/src/client/view.cc
+++ b/src/client/view.cc
@@ -177,7 +177,7 @@ void draw_status()
 			if (state == core::Entity::ImpulseInitiate) {
 				statestr << "^FInitializing kinetic impulse drive " << core::localcontrol()->timer();
 			} else if (state == core::Entity::Impulse) {
-				statestr << "^FKinetic impulse";
+				//statestr << "^FKinetic impulse";
 			} else if (state == core::Entity::JumpInitiate) {
 				statestr << "^FInitializing hyperspace jump drive "<< core::localcontrol()->timer();
 			} else if (state == core::Entity::Jump) {
@@ -239,7 +239,17 @@ void draw_status()
 		gl::end();
 
 		float u = core::localcontrol()->thrust();
-		if ( u > 0) {
+		if (( u > 0) || (core::localcontrol()->eventstate() == core::Entity::Impulse)) {
+
+			if (core::localcontrol()->eventstate() == core::Entity::Impulse) {
+				gl::color(0, .8, 0);
+			} else {
+				float d  = math::absf(input::local_thrust - u);
+				if (d > 0.1)  {
+					d = 0.1f;
+				}
+				gl::color(1, 1, .5f + d * 5.0f);
+			}
 			Textures::bind("bitmaps/hud/thruster_indicator"); // 316 x 32 bitmap
 			gl::begin(render::gl::Quads);
 			glTexCoord2f(0, 0);
@@ -256,7 +266,10 @@ void draw_status()
 	
 			gl::end();
 		}
+
 		Text::setfont("bitmaps/fonts/gui", 14, 24);
+		Text::setcolor('B'); //set normal color
+
 		std::stringstream speedstr;
 		speedstr << "^B" << roundf(core::localcontrol()->speed() * 100.0f);
 		Text::draw( 316+4+10, video::height - 6 -16 - render::Text::fontwidth() /2, speedstr);
diff --git a/src/core/clientstate.cc b/src/core/clientstate.cc
index 8e9c2e5..84e1fe0 100644
--- a/src/core/clientstate.cc
+++ b/src/core/clientstate.cc
@@ -16,7 +16,16 @@ ClientState::ClientState()
 	state_detailvisible = false;
 	state_targetable = false;
 
-	state_enginesound = 0;
+	state_thusterloopbuffer = 0;
+	state_impulseloopbuffer = 0;
+	state_impulsestartbuffer = 0;
+	state_impulsestopbuffer = 0;
+
+	state_engineloopbuffer = 0;
+	state_engineloopsource = 0;
+	state_engineeventbuffer = 0;
+	state_engineeventsource = 0;
+
 	state_engine_trail_offset = 0;
 
 	state_fuzz = math::randomf();
@@ -29,7 +38,16 @@ ClientState::ClientState(Entity *entity)
 	state_detailvisible = false;
 	state_targetable = false;
 
-	state_enginesound = 0;
+	state_thusterloopbuffer = 0;
+	state_impulseloopbuffer = 0;
+	state_impulsestartbuffer = 0;
+	state_impulsestopbuffer = 0;
+
+	state_engineloopbuffer = 0;
+	state_engineloopsource = 0;
+	state_engineeventbuffer = 0;
+	state_engineeventsource = 0;
+
 	state_engine_trail_offset = 0;
 
 	state_fuzz = math::randomf();
@@ -45,9 +63,11 @@ ClientState::~ClientState()
 
 void ClientState::clearsound()
 {
-	if (state_enginesound) {
-		application()->notify_remove_sound(state_enginesound);
-		state_enginesound = 0;
+	if (state_engineloopsource) {
+		application()->notify_remove_sound(state_engineloopsource);
+		application()->notify_remove_sound(state_engineeventsource);
+		state_engineloopsource = 0;
+		state_engineloopbuffer = 0;
 	}
 }
 
diff --git a/src/core/clientstate.h b/src/core/clientstate.h
index f914d0e..ffd6331 100644
--- a/src/core/clientstate.h
+++ b/src/core/clientstate.h
@@ -70,7 +70,23 @@ public:
 	/// distance from the camera eye to the entity
 	float			state_distance;
 
-	size_t			state_enginesound;
+	/// index of the audio buffer containing the thruster sound loop
+	size_t			state_thusterloopbuffer;
+	/// index of the audio buffer containing the impulse sound loop
+	size_t			state_impulseloopbuffer;
+	/// index of the audio buffer containing the impulse drive start sound
+	size_t			state_impulsestartbuffer;
+	/// index of the audio buffer containing the impulse drive stop sound
+	size_t			state_impulsestopbuffer;
+
+	/// index of the audio buffer currently looping in enginesource
+	size_t			state_engineloopbuffer;
+	/// index of the audio source used to play the engine sound loop
+	size_t			state_engineloopsource;
+	/// index of the audio last played on the event source
+	size_t			state_engineeventbuffer;
+	/// index of the audio source used to play engine sound events
+	size_t			state_engineeventsource;
 };
 
 }
diff --git a/src/game/ship.cc b/src/game/ship.cc
index f8a1143..4ddd118 100644
--- a/src/game/ship.cc
+++ b/src/game/ship.cc
@@ -40,12 +40,11 @@ Ship::Ship(core::Player *owner, ShipModel *shipmodel) :
 
 	ship_shipmodel = shipmodel;
 	ship_jumpdrive = shipmodel->shipmodel_jumpdrive;
-	ship_jumpdrive_activated = 0;
+	
 	ship_jumptargetzone = 0;
 
-	ship_countdown = 0;
-
-	ship_impulse = false;
+	ship_impulsedrive_timer = 0;
+	ship_jumpdrive_timer = 0;
 }
 
 Ship::~Ship() 
@@ -55,19 +54,26 @@ Ship::~Ship()
 
 void Ship::impulse()
 {
-	if (ship_impulse) {
-		ship_impulse = false;
+	if (entity_eventstate == core::Entity::Jump) {
+		return;
+
+	} else if ((entity_eventstate == core::Entity::Impulse) || (entity_eventstate == core::Entity::ImpulseInitiate)) {
 		entity_eventstate = core::Entity::Normal;
+		
 	} else { 
-		if (ship_jumpdrive_activated) {
-			ship_jumpdrive_activated = 0;
+
+		if (entity_eventstate == core::Entity::JumpInitiate) {
+			ship_jumpdrive_timer = 0;
 			ship_jumptargetzone = 0;
-			ship_countdown = 0;
+			entity_timer = 0;
 		}
 	
-		entity_eventstate = core::Entity::Impulse;
-		ship_impulse = true;
+		entity_eventstate = core::Entity::ImpulseInitiate;
+		entity_timer = 3;
+		ship_impulsedrive_timer = core::server()->time();
+		entity_dirty = true;
 	}
+
 	entity_dirty = true;
 }
 
@@ -76,13 +82,15 @@ void Ship::jump(std::string const &args)
 	if (!jumpdrive()) {
 		core::server()->send(owner(), "This ship is not equiped with a hyperspace drive!");
 		return;
-	}
-	
-	if (ship_jumpdrive_activated) {
+
+	} else 	if (entity_eventstate == core::Entity::Jump) {
+		return;
+
+	} else if (entity_eventstate == core::Entity::JumpInitiate) {
 		core::server()->send(owner(), "Jump aborted, hyperspace drive deactivated.");
-		ship_jumpdrive_activated = 0;
 		ship_jumptargetzone = 0;
-		ship_countdown = 0;
+		ship_jumpdrive_timer = 0;
+		entity_timer = 0;
 		entity_eventstate = core::Entity::Normal;
 		return;
 	}
@@ -115,16 +123,9 @@ void Ship::jump(std::string const &args)
 		return;
 	}
 
-	ship_jumpdrive_activated = core::server()->time();
-	ship_countdown = 10;
-	ship_impulse = false;
-
-	std::stringstream msg("");
-	msg << "Initializing hyperspace jump drive...";
-	core::server()->send(owner(), msg.str());
-
 	entity_eventstate = core::Entity::JumpInitiate;
-	entity_timer = ship_countdown; // countdown to jump, in seconds
+	entity_timer = 10;
+	ship_jumpdrive_timer = core::server()->time();
 	entity_dirty = true;
 }
 
@@ -147,34 +148,29 @@ void Ship::frame(float seconds)
 	// target axis
 	math::Axis target_axis(entity_axis);
 
-	if (ship_jumpdrive_activated) {
+	if (entity_eventstate == core::Entity::JumpInitiate) {
 
-		if (ship_jumpdrive_activated + 1.0f <= core::server()->time()) {
-			ship_countdown -= 1.0f;
-			entity_timer = ship_countdown;
+		if (ship_jumpdrive_timer + 1.0f <= core::server()->time()) {
+			entity_timer -= 1.0f;
 
-			if (ship_countdown <= 0) {
+			if (entity_timer <= 0) {
 				core::server()->send(owner(), "Jumping to '" + ship_jumptargetzone->name() + '\'');
 				set_zone(ship_jumptargetzone);
 				if (owner()->control() == (EntityControlable*) this)
 					owner()->set_zone(ship_jumptargetzone);
-				ship_jumpdrive_activated = 0;
+				ship_jumpdrive_timer = 0;
 				ship_jumptargetzone = 0;
-				entity_dirty = true;
+				entity_timer = 0;
 				entity_eventstate = core::Entity::Jump;
+				entity_dirty = true;
 				return;
 			} else {
-				if (ship_countdown <= 5) {
-					std::stringstream msg("");
-					msg << ship_countdown << "...";
-					core::server()->send(owner(), msg.str());
-				}
-				ship_jumpdrive_activated = core::server()->time();
+				ship_jumpdrive_timer = core::server()->time();
 				entity_dirty = true;
 			}
 		}
 
-		// control is disables while the jumpdrive is activated
+		// control is disabled while the jumpdrive is activated
 		target_thrust = 0;
 		target_pitch = 0;
 		target_roll = 0;
@@ -189,7 +185,32 @@ void Ship::frame(float seconds)
 		// FIXME 5 second cooldown
 		entity_eventstate =  core::Entity::Normal;
 
-	} else if (ship_impulse) {
+	} else if  (entity_eventstate == core::Entity::ImpulseInitiate) {
+
+		if (ship_impulsedrive_timer + 1.0f <= core::server()->time()) {
+			entity_timer -= 1.0f;
+
+			if (entity_timer <= 0) {
+				actual_maxspeed = Game::instance()->g_impulsespeed->value();
+				actual_acceleration = Game::instance()->g_impulseacceleration->value();
+				entity_eventstate = core::Entity::Impulse;
+				entity_timer = 0;
+				entity_dirty = true;
+			} else {
+				ship_impulsedrive_timer = core::server()->time();
+				entity_dirty = true;
+			}
+		}
+
+		// clamp input values
+		target_thrust = 1.0f;
+		math::clamp(target_pitch, -1.0f, 1.0f);
+		math::clamp(target_roll, -1.0f, 1.0f);
+		math::clamp(target_direction, -1.0f, 1.0f);
+
+		actual_turnspeed *= 0.5;
+
+	} else if (entity_eventstate == core::Entity::Impulse) {
 
 		// clamp input values
 		target_thrust = 1.0f;
@@ -201,7 +222,8 @@ void Ship::frame(float seconds)
 		actual_acceleration = Game::instance()->g_impulseacceleration->value();
 		actual_turnspeed *= 0.5;
 
-	} else {
+	} else if (entity_eventstate == core::Entity::Normal) {
+
 		// clamp input values
 		math::clamp(target_thrust, 0.0f, 1.0f);
 		math::clamp(target_pitch, -1.0f, 1.0f);
@@ -212,6 +234,7 @@ void Ship::frame(float seconds)
 			actual_acceleration = Game::instance()->g_impulseacceleration->value();
 			actual_turnspeed *= 0.5;
 		}
+
 	}
 
 	// update thrust
diff --git a/src/game/ship.h b/src/game/ship.h
index bd7f79e..16c0c14 100644
--- a/src/game/ship.h
+++ b/src/game/ship.h
@@ -41,12 +41,11 @@ private:
 	float 			current_target_roll;
 
 	bool			ship_jumpdrive;
-	float			ship_jumpdrive_activated;
-	core::Zone		*ship_jumptargetzone;
+	float			ship_jumpdrive_timer;
 
-	float			ship_countdown;
+	float			ship_impulsedrive_timer;
 
-	bool			ship_impulse;
+	core::Zone		*ship_jumptargetzone;
 };
 
 }
diff --git a/src/render/dust.cc b/src/render/dust.cc
index 96a9d67..25df9f9 100644
--- a/src/render/dust.cc
+++ b/src/render/dust.cc
@@ -113,8 +113,8 @@ void Dust::draw()
 	color.a	= alpha;
 
 	traillength = core::localcontrol()->speed() / LOWSPEEDLIMIT;
-	if (traillength > 1)
-		traillength = 1.0f;
+	/*if (traillength > 1)
+		traillength = 1.0f; */
 	traillength *= TRAILLENGHT;
 
 	gl::color(color);
-- 
cgit v1.2.3