diff options
Diffstat (limited to 'src/client')
| -rw-r--r-- | src/client/Makefile.am | 10 | ||||
| -rw-r--r-- | src/client/client.cc | 15 | ||||
| -rw-r--r-- | src/client/client.h | 17 | ||||
| -rw-r--r-- | src/client/clientext.cc | 23 | ||||
| -rw-r--r-- | src/client/clientext.h | 30 | ||||
| -rw-r--r-- | src/client/soundext.cc | 147 | ||||
| -rw-r--r-- | src/client/soundext.h | 49 | ||||
| -rw-r--r-- | src/client/targets.cc | 108 | ||||
| -rw-r--r-- | src/client/view.cc | 31 | 
9 files changed, 314 insertions, 116 deletions
diff --git a/src/client/Makefile.am b/src/client/Makefile.am index c855ad8..1d015a3 100644 --- a/src/client/Makefile.am +++ b/src/client/Makefile.am @@ -7,12 +7,12 @@ else  noinst_LTLIBRARIES = libclient.la  endif -libclient_la_SOURCES = action.cc chat.cc client.cc input.cc joystick.cc key.cc \ -	keyboard.cc notifications.cc targets.cc video.cc view.cc +libclient_la_SOURCES = action.cc chat.cc client.cc clientext.cc input.cc joystick.cc key.cc \ +	keyboard.cc notifications.cc soundext.cc targets.cc video.cc view.cc  libclient_la_CFLAGS = $(LIBSDL_CFLAGS) $(GL_CFLAGS)  libclient_la_LDFLAGS = -avoid-version -no-undefined $(GL_LIBS) $(LIBSDL_LIBS) -noinst_HEADERS = action.h chat.h client.h input.h joystick.h key.h keyboard.h \ -	notifications.h targets.h video.h view.h -libclient_la_LIBADD = $(top_builddir)/src/core/libcore.la \ +noinst_HEADERS = action.h chat.h client.h clientext.h input.h joystick.h key.h keyboard.h \ +	notifications.h soundext.h targets.h video.h view.h +libclient_la_LIBADD = $(top_builddir)/src/core/libcore.la  $(top_builddir)/src/audio/libaudio.la \  	$(top_builddir)/src/render/librender.la $(top_builddir)/src/ui/libui.la diff --git a/src/client/client.cc b/src/client/client.cc index 42ee5a0..061f29b 100644 --- a/src/client/client.cc +++ b/src/client/client.cc @@ -309,16 +309,6 @@ void Client::notify_message(const core::Message::Channel channel, const std::str  	con_print << message << std::endl;  } -/* FIXME - -	these notifications are hacks and need to be fixed -*/ - -void Client::notify_remove_sound(size_t source) -{ -	audio::Sources::remove(source); -} -  //--- engine functions --------------------------------------------  void Client::func_snd_restart(std::string const &args) @@ -326,8 +316,9 @@ void Client::func_snd_restart(std::string const &args)  	// unload entity sounds  	for (core::Entity::Registry::iterator it = core::Entity::registry().begin(); it != core::Entity::registry().end(); it++) {  		core::Entity *entity = (*it).second; -		if (entity->state()) -			entity->state()->clearsound(); + +		if (ext_sound(entity)) +			delete ext_sound(entity);  	}  	audio::reset(); diff --git a/src/client/client.h b/src/client/client.h index 33f64e5..8dd00cb 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -8,7 +8,12 @@  #define __INCLUDED_CLIENT_H__  #include "core/application.h" +#include "core/extension.h" +#include "core/entity.h" +#include "client/clientext.h" +#include "client/soundext.h"  #include "client/view.h" +#include "render/renderext.h"  /// client part of the engine  namespace client { @@ -44,9 +49,6 @@ public:  	/// text notifications from the client  	void notify_message(const char *message); -	/// remove sound source notification -	virtual void notify_remove_sound(size_t source); -  	/// clear zone notification  	virtual void notify_zonechange(); @@ -77,6 +79,15 @@ private:  Client *client(); +inline ClientExt *ext_client(core::Entity *entity)  +	{ return static_cast<ClientExt *>(entity->extension(core::Extension::Client)); } + +inline SoundExt *ext_sound(core::Entity *entity)  +	{ return static_cast<SoundExt *>(entity->extension(core::Extension::Sound)); } + +inline render::RenderExt *ext_render(core::Entity *entity)  +	{ return static_cast<render::RenderExt *>(entity->extension(core::Extension::Render)); } +  }  #endif // __INCLUDED_CLIENT_H__ diff --git a/src/client/clientext.cc b/src/client/clientext.cc new file mode 100644 index 0000000..980ecc0 --- /dev/null +++ b/src/client/clientext.cc @@ -0,0 +1,23 @@ +/* +   client/clientext.cc +   This file is part of the Osirion project and is distributed under +   the terms of the GNU General Public License version 2 +*/ + + +#include "client/clientext.h" + +namespace client +{ + +ClientExt::ClientExt(core::Entity *entity) : core::Extension(core::Extension::Client, entity) +{ +} + +ClientExt::~ClientExt() +{ +} + +} // namespace client + + diff --git a/src/client/clientext.h b/src/client/clientext.h new file mode 100644 index 0000000..d76546d --- /dev/null +++ b/src/client/clientext.h @@ -0,0 +1,30 @@ +/* +   client/clientext.h +   This file is part of the Osirion project and is distributed under +   the terms of the GNU General Public License version 2 +*/ + +#ifndef __INCLUDED_CLIENT_CLIENTEXT_H__ +#define __INCLUDED_CLIENT_CLIENTEXT_H__ + +#include "core/extension.h" + +namespace client +{ + +/// the client extension of an entity +class ClientExt :public core::Extension { +public: +	ClientExt(core::Entity *entity); +	~ClientExt(); + +	virtual void frame(float elapsed); + +private: +	 +}; + +} // namespace client + +#endif // __INCLUDED_CLIENT_CLIENTEXT_H__ + diff --git a/src/client/soundext.cc b/src/client/soundext.cc new file mode 100644 index 0000000..421575d --- /dev/null +++ b/src/client/soundext.cc @@ -0,0 +1,147 @@ +/* +   client/soundext.cc +   This file is part of the Osirion project and is distributed under +   the terms of the GNU General Public License version 2 +*/ + + +#include "audio/audio.h" +#include "audio/buffers.h" +#include "audio/sources.h" +#include "auxiliary/functions.h" +#include "core/gameinterface.h" +#include "core/entity.h" +#include "client/soundext.h" +#include "client/client.h" + +#include <sstream> +#include <iomanip> + +namespace client +{ + +SoundExt::SoundExt(core::Entity *entity) : core::Extension(core::Extension::Sound, entity) +{ +	state_thusterloopbuffer = 0; + +	state_impulseloopbuffer = 0; +	state_impulsestartbuffer = 0; +	state_impulsestopbuffer = 0; + +	state_engineloopbuffer = 0; +	state_engineloopsource = 0; + +	state_engineeventbuffer = 0; +	state_engineeventsource = 0; + +	// load engine sound +	if (entity->type() == core::Entity::Controlable) +	{ +		core::EntityControlable *entityco = static_cast<core::EntityControlable *>(entity); +		unsigned int enginesoundset = 0; +		unsigned int impulsesoundset = 0; +		 +		if (entityco->model()) { +			enginesoundset = entityco->model()->enginesound(); +			impulsesoundset = entityco->model()->impulsesound(); +		} +		 +			 +		std::stringstream soundname; +		soundname << "engines/loop" << std::setfill('0') << std::setw(2) << enginesoundset; +		state_thusterloopbuffer = audio::Buffers::load(soundname.str()); + +		// load impulse sound +		// FIXME load impulse sound set +		state_impulseloopbuffer = audio::Buffers::load("engines/impulse_loop00"); +		state_impulsestartbuffer = audio::Buffers::load("engines/impulse_start00"); +		state_impulsestopbuffer = audio::Buffers::load("engines/impulse_stop00"); +	} + +	state_engineloopsource = audio::Sources::get(); +	state_engineeventsource = audio::Sources::get(); +} + +SoundExt::~SoundExt() +{ +	clear(); +} + +void SoundExt::clear() +{ +	if (state_engineloopsource) { +		audio::Sources::remove(state_engineloopsource); +	} + +	if (state_engineeventsource) { +		audio::Sources::remove(state_engineeventsource); +	} + +	state_thusterloopbuffer = 0; +	state_impulseloopbuffer = 0; +	state_impulsestartbuffer = 0; +	state_impulsestopbuffer = 0; + +	state_engineloopbuffer = 0; +	state_engineloopsource = 0; + +	state_engineeventbuffer = 0; +	state_engineeventsource = 0; +} + +void SoundExt::frame(float elapsed) +{ +	core::EntityControlable *entity = static_cast<core::EntityControlable *>(this->entity()); + +	float speed = entity->speed(); +	float pitch = 1.0f; +	float gain = 0.0; +	if (entity->eventstate() == core::Entity::Impulse) { +		pitch = 1.0f; +		gain = 1.0f; +	} else if (entity->thrust() > 0 ) { +		pitch = 0.2f + entity->thrust() * 0.8f; +		gain = 0.8f; +	}	 + +	if (entity->eventstate() == core::Entity::ImpulseInitiate ) { + +		if (state_engineeventbuffer != state_impulsestartbuffer) { +			audio::update_source(state_engineeventsource, +				entity->location() - entity->axis().forward() * entity->model()->maxbbox().y , entity->axis().forward() * speed); +			state_engineeventbuffer = audio::play(state_engineeventsource, state_impulsestartbuffer); +		} +	} else if (entity->eventstate() == core::Entity::Impulse) { + +		state_engineeventbuffer = state_impulseloopbuffer; + +		if (state_engineloopbuffer != state_impulseloopbuffer) { +			state_engineloopbuffer = audio::loop(state_engineloopsource, state_impulseloopbuffer, pitch, 0); +		} +		pitch = 1.0f; +	} else { + +		if (state_engineeventbuffer == state_impulseloopbuffer) { +			audio::update_source(state_engineeventsource, +				entity->location() - entity->axis().forward() * entity->model()->maxbbox().y , entity->axis().forward() * speed); +			state_engineeventbuffer = audio::play(state_engineeventsource, state_impulsestopbuffer); +		} +		state_engineeventbuffer = 0; + +		if (state_engineloopbuffer != state_thusterloopbuffer) { +			state_engineloopbuffer = audio::loop(state_engineloopsource, state_thusterloopbuffer, pitch, 0); +		} +	} + + +	audio::update_source(state_engineloopsource, +	entity->location() - entity->axis().forward() * entity->model()->maxbbox().x , entity->axis().forward() * speed, pitch, gain); + +	audio::update_source(state_engineeventsource, +	entity->location() - entity->axis().forward() * entity->model()->maxbbox().x , entity->axis().forward() * speed); + +} + +} // namespace client + + diff --git a/src/client/soundext.h b/src/client/soundext.h new file mode 100644 index 0000000..d2028dd --- /dev/null +++ b/src/client/soundext.h @@ -0,0 +1,49 @@ +/* +   client/soundext.h +   This file is part of the Osirion project and is distributed under +   the terms of the GNU General Public License version 2 +*/ + +#ifndef __INCLUDED_CLIENT_SOUNDEXT_H__ +#define __INCLUDED_CLIENT_SOUNDEXT_H__ + +#include "core/extension.h" + +namespace client +{ + +/// the sound extension of an entity +class SoundExt :public core::Extension { +public: +	SoundExt(core::Entity *Entity); +	~SoundExt(); + +	virtual void frame(float elapsed); + +private: +	void clear(); + +	/// 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; +}; + +} + //namespace client + // +#endif // __INCLUDED_CLIENT_CLIENTEXT_H__ + diff --git a/src/client/targets.cc b/src/client/targets.cc index 8b77644..3ccea8a 100644 --- a/src/client/targets.cc +++ b/src/client/targets.cc @@ -14,7 +14,9 @@  #include "audio/sources.h"  #include "auxiliary/functions.h"  #include "audio/sources.h" +#include "client/client.h"  #include "client/input.h" +#include "client/soundext.h"  #include "client/view.h"  #include "client/video.h"  #include "core/application.h" @@ -47,13 +49,13 @@ bool is_legal_target(core::Entity *entity)  		return true;  	} else if (entity == core::localcontrol()) {  		return false; -	} else if (entity->state()->distance() < 0.001f) { +	} else if (ext_render(entity)->distance() < 0.001f) {  		return false;  	} else {  		if (entity->type() != core::Entity::Controlable) { -			return entity->state()->visible(); +			return ext_render(entity)->visible(); -		} else if (entity->state()->distance() < core::range::visible) { +		} else if (ext_render(entity)->distance() < core::range::visible) {  			return true;  		}  	} @@ -224,7 +226,7 @@ void func_target_center(std::string const &args)  	for (core::Zone::Content::iterator it=core::localcontrol()->zone()->content().begin(); it != core::localcontrol()->zone()->content().end(); it++) {  		core::Entity *entity = (*it); -		math::Vector3f v(entity->state()->location() - render::Camera::eye()); +		math::Vector3f v(entity->location() - render::Camera::eye());  		v.normalize();  		if (is_legal_target(entity) && math::dotproduct(render::Camera::axis().forward(), v) > 0.85 ) { @@ -291,98 +293,31 @@ void render_listener_sound()  	math::Vector3f velocity(0, 0 ,0);  	if (core::localcontrol()) { -		velocity.assign(core::localcontrol()->state()->axis().forward() * core::localcontrol()->speed()); +		velocity.assign(core::localcontrol()->axis().forward() * core::localcontrol()->speed());  	}  	audio::update_listener(render::Camera::eye(), render::Camera::axis(), velocity);  } -void render_entity_sound(core::EntityControlable *entity) +void render_entity_sound(core::Entity *entity)  { -	if (!(entity->type() == core::Entity::Controlable)) -		return; -  	if (!(snd_engines && snd_engines->value())) { -		entity->state()->clearsound(); +		if (ext_sound(entity)) + 			delete ext_sound(entity);  		return;  	} -	core::ClientState *state = entity->state(); -	if (!(entity->model() && state->detailvisible())) { -		entity->state()->clearsound(); +	if (!ext_render(entity) || !ext_render(entity)->visible()) { +		if (ext_sound(entity)) + 			delete ext_sound(entity);  		return;  	} -	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"); -	} - -	 -	if (!state->state_engineloopsource) { -		state->state_engineloopsource = audio::Sources::get(); -		state->state_engineeventsource = audio::Sources::get(); -	} - -	float speed = entity->speed(); -	float pitch = 1.0f; -	float gain = 0.0; -	if (entity->eventstate() == core::Entity::Impulse) { -		pitch = 1.0f; -		gain = 1.0f; -	} else if (entity->thrust() > 0 ) { -		pitch = 0.2f + entity->thrust() * 0.8f; -		gain = 0.8f; +	if (!ext_sound(entity)) { +		new SoundExt(entity);  	} -	 - -	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) { - -		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 { - -		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); +	entity->extension((size_t) core::Extension::Sound)->frame(0.0f);  } @@ -428,8 +363,9 @@ void draw()  		// render entity sound  		if (entity->type() == core::Entity::Controlable) { -			render_entity_sound(static_cast<core::EntityControlable *>(entity)); +			render_entity_sound(entity);  		} +  		// find the current target  		if (!core::localplayer()->view() && core::localcontrol() && is_legal_target(entity)) { @@ -438,7 +374,7 @@ void draw()  			}  			// check if the mouse is hovering the entity -			Vector3f v(entity->state()->location() - render::Camera::eye()); +			Vector3f v(entity->location() - render::Camera::eye());  			v.normalize();  			if (math::dotproduct(render::Camera::axis().forward(), v) > 0.75 ) { @@ -448,11 +384,11 @@ void draw()  				float r = entity->radius() * 0.5f; -				if (entity->state()->distance() > 512) +				if (ext_render(entity)->distance() > 512.0f)  					math::clamp(r, 8.0f,r); -				else if (entity->state()->distance() > 256) +				else if (ext_render(entity)->distance() > 256.0f)  					math::clamp(r, 4.0f,r); -				else if (entity->state()->distance() > 128.0f) +				else if (ext_render(entity)->distance() > 128.0f)  					math::clamp(r, 2.0f,r);  				// if the cursor-beam hits the entity sphere diff --git a/src/client/view.cc b/src/client/view.cc index 90a30ef..0f981ca 100644 --- a/src/client/view.cc +++ b/src/client/view.cc @@ -77,7 +77,7 @@ void DevInfo::draw()  			  <<  "^Nspeed ^B" << core::localcontrol()->speed() << '\n';  		if (target) { -			d = math::distance(core::localcontrol()->location(), target->state()->location()) - target->radius() - core::localcontrol()->radius(); +			d = math::distance(core::localcontrol()->location(), target->location()) - target->radius() - core::localcontrol()->radius();  			textstream << "^Ndist ^B" << d << '\n';  		}  	} @@ -298,14 +298,14 @@ void draw_entity_world_target(core::Entity *entity)  	if (!model->docks().size())  		return; -	float d = math::distance(core::localcontrol()->location(), entity->state()->location()) - entity->radius() - core::localcontrol()->radius(); +	float d = math::distance(core::localcontrol()->location(), entity->location()) - entity->radius() - core::localcontrol()->radius();  	if (d > 100.0f)  		return;  	gl::enable(GL_DEPTH_TEST);  	gl::push(); -	gl::translate(entity->state()->location()); -	gl::multmatrix(entity->state()->axis()); +	gl::translate(entity->location()); +	gl::multmatrix(entity->axis());  	gl::color(0, 1.0f, 1.0f, 1.0f); @@ -355,7 +355,7 @@ void draw_entity_world_target(core::Entity *entity)  void draw_entity_offscreen_target(core::Entity *entity, bool is_active_target)  { -	math::Vector3f target(entity->state()->location() - render::Camera::eye()); +	math::Vector3f target(entity->location() - render::Camera::eye());  	target = render::Camera::axis().transpose() * target;  	float cx = 0; @@ -414,11 +414,11 @@ void draw_entity_target(core::Entity *entity, bool is_active_target)  	using math::Vector3f;  	// don't draw target if we're very close to it -	if (entity->state()->distance() < 0.001f) +	if (ext_render(entity)->distance() < 0.001f)  		return;  	// don't draw target if it is outside the visible cone -	Vector3f target(entity->state()->location() - render::Camera::eye()); +	Vector3f target(entity->location() - render::Camera::eye());  	if (math::dotproduct(render::Camera::axis().forward(), Vector3f::normalized(target)) < 0.75 ) {  		draw_entity_offscreen_target(entity, is_active_target);  		return; @@ -492,7 +492,7 @@ void draw_entity_target(core::Entity *entity, bool is_active_target)  	if (is_active_target) {  		// entity name	and distance  		std::stringstream strdistance; -		float d = math::distance(core::localcontrol()->location(), entity->state()->location()) - entity->radius() - core::localcontrol()->radius(); +		float d = math::distance(core::localcontrol()->location(), entity->location()) - entity->radius() - core::localcontrol()->radius();  		if (d > 0 ) {  			if (d > 100.0f) {  				strdistance << roundf(d * 0.1f) << "km"; @@ -572,7 +572,7 @@ void draw_hud()  			std::stringstream strtarget;  			strtarget << "^B" << target->name() << "\n^B"; -			d = math::distance(core::localcontrol()->location(), target->state()->location())  +			d = math::distance(core::localcontrol()->location(), target->location())   				- target->radius() - core::localcontrol()->radius();  			if (d > 0 ) { @@ -582,12 +582,23 @@ void draw_hud()  				} else {  					strtarget << roundf(d * 100.0f) << "m";  				} + +				if (core::localcontrol()->speed() > 0.1f) { +					strtarget << "^N eta:^B "; +					float eta = floorf(d / core::localcontrol()->speed() ); +					if (eta > 60.0f) { +						float etamin = floorf(eta / 60.0f); +						strtarget << etamin << "min "; +						eta -= etamin * 60; +					} +					strtarget << eta << "sec"; +				}  			} else {  				strtarget << "      --";  			}  			strtarget << '\n';  			Text::draw(render::State::width() - 4-Text::fontwidth()*32, render::State::height() - Text::fontheight()*2 -4, strtarget); -			y = 3.0f; +			y += 2.0f;  		}  		Text::setcolor('N'); //set normal color  | 
