Просмотр исходного кода

Add SoundWorld::pause_all/resume_all/stop_all() and add LuaSoundWorld

Daniele Bartolini 12 лет назад
Родитель
Сommit
3904b035fe

+ 1 - 0
engine/CMakeLists.txt

@@ -366,6 +366,7 @@ set (LUA_SRC
 	lua/LuaPhysicsWorld.cpp
 	lua/LuaQuaternion.cpp
 	lua/LuaResourcePackage.cpp
+	lua/LuaSoundWorld.cpp
 	lua/LuaSprite.cpp
 	lua/LuaStack.cpp
 	lua/LuaStringSetting.cpp

+ 10 - 1
engine/audio/SoundWorld.h

@@ -47,12 +47,21 @@ public:
 
 	/// Plays the sound @a name at the given @a volume [0 .. 1].
 	/// If loop is true the sound will be played looping.
-	virtual SoundInstanceId play(const char* name, bool loop, float volume) = 0;
+	virtual SoundInstanceId play(const char* name, bool loop, float volume, const Vector3& pos) = 0;
 
 	/// Stops the sound with the given @a id.
 	/// After this call, the instance will be destroyed.
 	virtual void stop(SoundInstanceId id) = 0;
 
+	/// Stops all the sounds in the world.
+	virtual void stop_all() = 0;
+
+	/// Pauses all the sounds in the world
+	virtual void pause_all() = 0;
+
+	/// Resumes all previously paused sounds in the world.
+	virtual void resume_all() = 0;
+
 	/// Sets the @a positions (in world space) of @a count sound instances @a ids.
 	virtual void set_sound_positions(uint32_t count, const SoundInstanceId* ids, const Vector3* positions) = 0;
 

+ 55 - 10
engine/audio/backend/ALSoundWorld.cpp

@@ -68,9 +68,10 @@ static const char* al_error_to_string(ALenum error)
 //-----------------------------------------------------------------------------
 struct SoundInstance
 {
-	void create(SoundResource* sr)
+	void create(SoundResource* sr, const Vector3& pos)
 	{
 		AL_CHECK(alGenSources(1, &m_source));
+		CE_ASSERT(alIsSource(m_source), "Bad OpenAL source");
 
 		// AL_CHECK(alSourcef(m_source, AL_PITCH, 1.0f));
 		// AL_CHECK(alSourcef(m_source, AL_REFERENCE_DISTANCE, 0.1f));
@@ -78,6 +79,7 @@ struct SoundInstance
 
 		// Generates AL buffers
 		AL_CHECK(alGenBuffers(1, &m_buffer));
+		CE_ASSERT(alIsBuffer(m_buffer), "Bad OpenAL buffer");
 
 		ALenum format;
 		switch (sr->bits_ps())
@@ -89,11 +91,13 @@ struct SoundInstance
 		AL_CHECK(alBufferData(m_buffer, format, sr->data(), sr->size(), sr->sample_rate()));
 
 		m_resource = sr;
+		set_position(pos);
 	}
 
 	void destroy()
 	{
 		stop();
+		AL_CHECK(alSourcei(m_source, AL_BUFFER, 0));
 		AL_CHECK(alDeleteBuffers(1, &m_buffer));
 		AL_CHECK(alDeleteSources(1, &m_source));
 	}
@@ -101,7 +105,7 @@ struct SoundInstance
 	void reload(SoundResource* new_sr)
 	{
 		destroy();
-		create(new_sr);
+		create(new_sr, m_position);
 	}
 
 	void play(bool loop, float volume)
@@ -117,26 +121,41 @@ struct SoundInstance
 		AL_CHECK(alSourcePause(m_source));
 	}
 
+	void resume()
+	{
+		AL_CHECK(alSourcePlay(m_source));
+	}
+
 	void stop()
 	{
-		ALuint buffer;
-		AL_CHECK(alSourceUnqueueBuffers(m_source, 1, &buffer));
+		AL_CHECK(alSourceStop(m_source));
+		AL_CHECK(alSourceRewind(m_source)); // Workaround
+		ALint processed;
+		AL_CHECK(alGetSourcei(m_source, AL_BUFFERS_PROCESSED, &processed));
+
+		if (processed > 0)
+		{
+			ALuint removed;
+			AL_CHECK(alSourceUnqueueBuffers(m_source, 1, &removed));
+		}
 	}
 
 	bool finished()
 	{
 		ALint state;
 		AL_CHECK(alGetSourcei(m_source, AL_SOURCE_STATE, &state));
-		return !(state == AL_PLAYING);
+		return (state != AL_PLAYING && state != AL_PAUSED);
 	}
 
 	void set_position(const Vector3& pos)
 	{
 		AL_CHECK(alSourcefv(m_source, AL_POSITION, pos.to_float_ptr()));
+		m_position = pos;
 	}
 
 	void set_range(float range)
 	{
+		AL_CHECK(alSourcef(m_source, AL_MAX_DISTANCE, range));
 	}
 
 	void set_volume(float volume)
@@ -153,6 +172,7 @@ public:
 
 	SoundInstanceId m_id;
 	SoundResource* m_resource;
+	Vector3 m_position;
 	ALuint m_buffer;
 	ALuint m_source;
 };
@@ -185,18 +205,19 @@ public:
 	    alcCloseDevice(m_device);
 	}
 
-	virtual SoundInstanceId play(const char* name, bool loop, float volume)
+	virtual SoundInstanceId play(const char* name, bool loop, float volume, const Vector3& pos)
 	{
-		return play((SoundResource*) device()->resource_manager()->lookup(SOUND_EXTENSION, name), loop, volume);
+		return play((SoundResource*) device()->resource_manager()->lookup(SOUND_EXTENSION, name), loop, volume, pos);
 	}
 
-	SoundInstanceId play(SoundResource* sr, bool loop, float volume)
+	SoundInstanceId play(SoundResource* sr, bool loop, float volume, const Vector3& pos)
 	{
 		SoundInstance instance;
-		instance.create(sr);
+		instance.create(sr, pos);
 		SoundInstanceId id = m_playing_sounds.create(instance);
 		m_playing_sounds.lookup(id).m_id = id;
 		instance.play(loop, volume);
+		return id;
 	}
 
 	virtual void stop(SoundInstanceId id)
@@ -206,6 +227,30 @@ public:
 		m_playing_sounds.destroy(id);
 	}
 
+	virtual void stop_all()
+	{
+		for (uint32_t i = 0; i < m_playing_sounds.size(); i++)
+		{
+			m_playing_sounds[i].stop();
+		}
+	}
+
+	virtual void pause_all()
+	{
+		for (uint32_t i = 0; i < m_playing_sounds.size(); i++)
+		{
+			m_playing_sounds[i].pause();
+		}
+	}
+
+	virtual void resume_all()
+	{
+		for (uint32_t i = 0; i < m_playing_sounds.size(); i++)
+		{
+			m_playing_sounds[i].resume();
+		}
+	}
+
 	virtual void set_sound_positions(uint32_t count, const SoundInstanceId* ids, const Vector3* positions)
 	{
 		for (uint32_t i = 0; i < m_playing_sounds.size(); i++)
@@ -245,7 +290,7 @@ public:
 	{
 		const Vector3 pos = pose.translation();
 		const Vector3 up = pose.y();
-		const Vector3 at = -pose.z();
+		const Vector3 at = pose.z();
 
 		AL_CHECK(alListener3f(AL_POSITION, pos.x, pos.y, pos.z));
 		//AL_CHECK(alListener3f(AL_VELOCITY, vel.x, vel.y, vel.z));

+ 1 - 0
engine/lua/LuaEnvironment.cpp

@@ -82,6 +82,7 @@ CE_EXPORT int luaopen_libcrown(lua_State* /*L*/)
 	load_actor(*env);
 	load_controller(*env);
 	load_physics_world(*env);
+	load_sound_world(*env);
 
 	load_gui(*env);
 

+ 20 - 19
engine/lua/LuaEnvironment.h

@@ -90,31 +90,32 @@ private:
 
 };
 
-void load_int_setting(LuaEnvironment& env);
-void load_float_setting(LuaEnvironment& env);
-void load_string_setting(LuaEnvironment& env);
 
-void load_vector2(LuaEnvironment& env);
-void load_vector3(LuaEnvironment& env);
-void load_matrix4x4(LuaEnvironment& env);
-void load_quaternion(LuaEnvironment& env);
-void load_math(LuaEnvironment& env);
-void load_mouse(LuaEnvironment& env);
-void load_keyboard(LuaEnvironment& env);
-void load_touch(LuaEnvironment& env);
 void load_accelerometer(LuaEnvironment& env);
+void load_actor(LuaEnvironment& env);
+void load_camera(LuaEnvironment& env);
+void load_controller(LuaEnvironment& env);
 void load_device(LuaEnvironment& env);
-void load_window(LuaEnvironment& env);
+void load_float_setting(LuaEnvironment& env);
+void load_gui(LuaEnvironment& env);
+void load_int_setting(LuaEnvironment& env);
+void load_keyboard(LuaEnvironment& env);
+void load_math(LuaEnvironment& env);
+void load_matrix4x4(LuaEnvironment& env);
+void load_mesh(LuaEnvironment& env);
+void load_mouse(LuaEnvironment& env);
+void load_physics_world(LuaEnvironment& env);
+void load_quaternion(LuaEnvironment& env);
 void load_resource_package(LuaEnvironment& env);
+void load_sound_world(LuaEnvironment& env);
+void load_sprite(LuaEnvironment& env);
+void load_string_setting(LuaEnvironment& env);
+void load_touch(LuaEnvironment& env);
 void load_unit(LuaEnvironment& env);
-void load_camera(LuaEnvironment& env);
+void load_vector2(LuaEnvironment& env);
+void load_vector3(LuaEnvironment& env);
+void load_window(LuaEnvironment& env);
 void load_world(LuaEnvironment& env);
-void load_mesh(LuaEnvironment& env);
-void load_sprite(LuaEnvironment& env);
-void load_actor(LuaEnvironment& env);
-void load_controller(LuaEnvironment& env);
-void load_physics_world(LuaEnvironment& env);
-void load_gui(LuaEnvironment& env);
 
 CE_EXPORT int32_t luaopen_libcrown(lua_State* L);
 

+ 71 - 0
engine/lua/LuaSoundWorld.cpp

@@ -0,0 +1,71 @@
+/*
+Copyright (c) 2013 Daniele Bartolini, Michele Rossi
+Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "LuaStack.h"
+#include "LuaEnvironment.h"
+#include "SoundWorld.h"
+
+namespace crown
+{
+
+//-----------------------------------------------------------------------------
+CE_EXPORT int sound_world_stop_all(lua_State* L)
+{
+	LuaStack stack(L);
+
+	SoundWorld* sw = stack.get_sound_world(1);
+	sw->stop_all();
+	return 0;
+}
+
+//-----------------------------------------------------------------------------
+CE_EXPORT int sound_world_pause_all(lua_State* L)
+{
+	LuaStack stack(L);
+
+	SoundWorld* sw = stack.get_sound_world(1);
+	sw->pause_all();
+	return 0;
+}
+
+CE_EXPORT int sound_world_resume_all(lua_State* L)
+{
+	LuaStack stack(L);
+
+	SoundWorld* sw = stack.get_sound_world(1);
+	sw->resume_all();
+	return 0;
+}
+
+//-----------------------------------------------------------------------------
+void load_sound_world(LuaEnvironment& env)
+{
+	env.load_module_function("SoundWorld", "stop_all",    sound_world_stop_all);
+	env.load_module_function("SoundWorld", "pause_all",   sound_world_pause_all);
+	env.load_module_function("SoundWorld", "resume_all",  sound_world_resume_all);
+}
+
+} // namespace crown

+ 23 - 10
engine/lua/LuaStack.h

@@ -33,20 +33,21 @@ OTHER DEALINGS IN THE SOFTWARE.
 namespace crown
 {
 
-struct Vector2;
-struct Vector3;
-struct Matrix4x4;
-struct Quaternion;
-struct Unit;
-struct Camera;
-class World;
-struct Mesh;
-struct Sprite;
 class PhysicsWorld;
+class SoundWorld;
+class World;
 struct Actor;
+struct Camera;
 struct Controller;
-class ResourcePackage;
 struct Gui;
+struct Matrix4x4;
+struct Mesh;
+struct Quaternion;
+struct ResourcePackage;
+struct Sprite;
+struct Unit;
+struct Vector2;
+struct Vector3;
 
 typedef Id SoundInstanceId;
 typedef Id GuiId;
@@ -212,6 +213,18 @@ public:
 		return (World*) lua_touserdata(m_state, index);
 	}
 
+	//-----------------------------------------------------------------------------
+	void push_sound_world(SoundWorld* sw)
+	{
+		lua_pushlightuserdata(m_state, sw);
+	}
+
+	//-----------------------------------------------------------------------------
+	SoundWorld* get_sound_world(int32_t index)
+	{
+		return (SoundWorld*) lua_touserdata(m_state, index);
+	}
+
 	//-----------------------------------------------------------------------------
 	void push_unit(Unit* unit)
 	{

+ 12 - 0
engine/lua/LuaWorld.cpp

@@ -217,6 +217,17 @@ CE_EXPORT int world_physics_world(lua_State* L)
 	return 1;
 }
 
+//-----------------------------------------------------------------------------
+CE_EXPORT int world_sound_world(lua_State* L)
+{
+	LuaStack stack(L);
+
+	World* world = stack.get_world(1);
+
+	stack.push_sound_world(world->sound_world());
+	return 1;
+}
+
 //-----------------------------------------------------------------------------
 void load_world(LuaEnvironment& env)
 {
@@ -237,6 +248,7 @@ void load_world(LuaEnvironment& env)
 	env.load_module_function("World", "lookup_gui",			world_lookup_gui);
 
 	env.load_module_function("World", "physics_world",		world_physics_world);
+	env.load_module_function("World", "sound_world",        world_sound_world);
 }
 
 } // namespace crown

+ 2 - 1
engine/world/World.cpp

@@ -190,7 +190,7 @@ void World::destroy_camera(CameraId id)
 //-----------------------------------------------------------------------------
 SoundInstanceId World::play_sound(const char* name, const bool loop, const float volume, const Vector3& pos, const float range)
 {
-	m_sound_world->play(name, loop, volume);
+	m_sound_world->play(name, loop, volume, pos);
 }
 
 //-----------------------------------------------------------------------------
@@ -219,6 +219,7 @@ void World::set_sound_position(SoundInstanceId id, const Vector3& pos)
 //-----------------------------------------------------------------------------
 void World::set_sound_range(SoundInstanceId id, float range)
 {
+	m_sound_world->set_sound_ranges(1, &id, &range);
 }
 
 //-----------------------------------------------------------------------------