Răsfoiți Sursa

Add sounds to LevelResource

Daniele Bartolini 11 ani în urmă
părinte
comite
74b48c418a

+ 37 - 1
engine/resource/LevelResource.cpp

@@ -35,6 +35,7 @@ namespace crown
 namespace level_resource
 {
 
+//-----------------------------------------------------------------------------
 void parse_units(JSONElement root, Array<LevelUnit>& units)
 {
 	JSONElement units_arr = root.key("units");
@@ -58,6 +59,32 @@ void parse_units(JSONElement root, Array<LevelUnit>& units)
 	}
 }
 
+//-----------------------------------------------------------------------------
+void parse_sounds(JSONElement root, Array<LevelSound>& sounds)
+{
+	JSONElement sounds_arr = root.key("sounds");
+	const uint32_t size = sounds_arr.size();
+
+	for (uint32_t i = 0; i < size; i++)
+	{
+		JSONElement e = sounds_arr[i];
+
+		LevelSound ls;
+
+		DynamicString name;
+		e.key("name").to_string(name);
+		name += ".sound";
+
+		ls.name = ResourceId(name.c_str());
+		ls.position = e.key("position").to_vector3();
+		ls.volume = e.key("volume").to_float();
+		ls.range = e.key("range").to_float();
+		ls.loop = e.key("loop").to_bool();
+
+		array::push_back(sounds, ls);
+	}
+}
+
 //-----------------------------------------------------------------------------
 void compile(Filesystem& fs, const char* resource_path, File* out_file)
 {
@@ -69,16 +96,21 @@ void compile(Filesystem& fs, const char* resource_path, File* out_file)
 	JSONElement root = json.root();
 
 	Array<LevelUnit> units(default_allocator());
+	Array<LevelSound> sounds(default_allocator());
 
 	parse_units(root, units);
+	parse_sounds(root, sounds);
 
 	fs.close(file);
 	default_allocator().deallocate(buf);
 
 	LevelHeader lh;
 	lh.num_units = array::size(units);
+	lh.num_sounds = array::size(sounds);
+
 	uint32_t offt = sizeof(LevelHeader);
-	lh.units_offset = offt;
+	lh.units_offset = offt; offt += sizeof(LevelUnit) * lh.num_units;
+	lh.sounds_offset = offt;
 
 	out_file->write((char*) &lh, sizeof(LevelHeader));
 
@@ -86,6 +118,10 @@ void compile(Filesystem& fs, const char* resource_path, File* out_file)
 	{
 		out_file->write((char*) array::begin(units), sizeof(LevelUnit) * lh.num_units);
 	}
+	if (lh.num_sounds)
+	{
+		out_file->write((char*) array::begin(sounds), sizeof(LevelSound) * lh.num_sounds);
+	}
 }
 
 } // namespace level_resource

+ 27 - 0
engine/resource/LevelResource.h

@@ -42,6 +42,8 @@ struct LevelHeader
 {
 	uint32_t num_units;
 	uint32_t units_offset;
+	uint32_t num_sounds;
+	uint32_t sounds_offset;
 };
 
 struct LevelUnit
@@ -51,6 +53,15 @@ struct LevelUnit
 	Quaternion rotation;
 };
 
+struct LevelSound
+{
+	ResourceId name;
+	Vector3 position;
+	float volume;
+	float range;
+	bool loop;
+};
+
 struct LevelResource
 {
 	//-----------------------------------------------------------------------------
@@ -99,6 +110,22 @@ struct LevelResource
 		const LevelUnit* begin = (LevelUnit*) (((char*) this) + h->units_offset);
 		return &begin[i];
 	}
+
+	//-----------------------------------------------------------------------------
+	uint32_t num_sounds() const
+	{
+		return ((LevelHeader*) this)->num_sounds;
+	}
+
+	//-----------------------------------------------------------------------------
+	const LevelSound* get_sound(uint32_t i) const
+	{
+		CE_ASSERT(i < num_sounds(), "Index out of bounds");
+
+		const LevelHeader* h = (LevelHeader*) this;
+		const LevelSound* begin = (LevelSound*) (((char*) this) + h->sounds_offset);
+		return &begin[i];
+	}
 };
 
 } // namespace crown

+ 21 - 1
engine/world/World.cpp

@@ -202,7 +202,21 @@ 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)
 {
-	return m_sound_world->play(name, loop, volume, pos);
+	ResourceId id(SOUND_EXTENSION, name);
+	return play_sound(id, loop, volume, pos, range);
+}
+
+//-----------------------------------------------------------------------------
+SoundInstanceId World::play_sound(ResourceId id, const bool loop, const float volume, const Vector3& pos, const float range)
+{
+	SoundResource* sr = (SoundResource*) device()->resource_manager()->get(id);
+	return play_sound(sr, loop, volume, pos, range);
+}
+
+//-----------------------------------------------------------------------------
+SoundInstanceId World::play_sound(SoundResource* sr, const bool loop, const float volume, const Vector3& pos, const float range)
+{
+	return m_sound_world->play(sr, loop, volume, pos);
 }
 
 //-----------------------------------------------------------------------------
@@ -280,6 +294,12 @@ void World::load_level(const char* name)
 		const LevelUnit* lu = res->get_unit(i);
 		spawn_unit(lu->name, lu->position, lu->rotation);
 	}
+
+	for (uint32_t i = 0; i < res->num_sounds(); i++)
+	{
+		const LevelSound* ls = res->get_sound(i);
+		play_sound(ls->name, ls->loop, ls->volume, ls->position, ls->range);
+	}
 }
 
 //-----------------------------------------------------------------------------

+ 2 - 0
engine/world/World.h

@@ -104,6 +104,8 @@ public:
 	/// Plays the sound with the given @æ name at the given @a position, with the given
 	/// @a volume and @a range. @a loop controls whether the sound must loop or not.
 	SoundInstanceId play_sound(const char* name, bool loop = false, float volume = 1.0f, const Vector3& position = vector3::ZERO, float range = 50.0f);
+	SoundInstanceId play_sound(ResourceId id, const bool loop, const float volume, const Vector3& pos, const float range);
+	SoundInstanceId play_sound(SoundResource* sr, const bool loop, const float volume, const Vector3& pos, const float range);
 
 	/// Stops the sound with the given @a id.
 	void stop_sound(SoundInstanceId id);