forked from oerkki/voxelands
ambient sounds, maybe
This commit is contained in:
parent
542b5d5904
commit
3d7bc18030
Binary file not shown.
|
@ -151,20 +151,9 @@ void * MeshUpdateThread::Thread()
|
|||
|
||||
BEGIN_DEBUG_EXCEPTION_HANDLER
|
||||
|
||||
while(getRun())
|
||||
{
|
||||
/*// Wait for output queue to flush.
|
||||
// Allow 2 in queue, this makes less frametime jitter.
|
||||
// Umm actually, there is no much difference
|
||||
if(m_queue_out.size() >= 2)
|
||||
{
|
||||
sleep_ms(3);
|
||||
continue;
|
||||
}*/
|
||||
|
||||
while (getRun()) {
|
||||
QueuedMeshUpdate *q = m_queue_in.pop();
|
||||
if(q == NULL)
|
||||
{
|
||||
if (q == NULL) {
|
||||
sleep_ms(3);
|
||||
continue;
|
||||
}
|
||||
|
@ -178,10 +167,6 @@ void * MeshUpdateThread::Thread()
|
|||
r.mesh = mesh_new;
|
||||
r.ack_block_to_server = q->ack_block_to_server;
|
||||
|
||||
/*infostream<<"MeshUpdateThread: Processed "
|
||||
<<"("<<q->p.X<<","<<q->p.Y<<","<<q->p.Z<<")"
|
||||
<<std::endl;*/
|
||||
|
||||
m_queue_out.push_back(r);
|
||||
|
||||
delete q;
|
||||
|
@ -2261,6 +2246,8 @@ void Client::addUpdateMeshTask(v3s16 p, bool ack_to_server)
|
|||
data->fill(getDayNightRatio(), b);
|
||||
}
|
||||
|
||||
data->m_sounds = &b->m_sounds;
|
||||
|
||||
// Debug wait
|
||||
//while(m_mesh_update_thread.m_queue_in.size() > 0) sleep_ms(10);
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "settings.h"
|
||||
#include "environment.h"
|
||||
#include "nodemetadata.h"
|
||||
#include "sound.h"
|
||||
|
||||
#ifndef SERVER
|
||||
// Create a cuboid.
|
||||
|
@ -484,6 +485,32 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
data->m_temp_mods.get(p,&mod);
|
||||
selected = (mod == NODEMOD_SELECTION);
|
||||
|
||||
if (g_sound) {
|
||||
std::string snd = content_features(n).sound_ambient;
|
||||
std::map<v3s16,MapBlockSound>::iterator i = data->m_sounds->find(p);
|
||||
if (snd != "") {
|
||||
bool add_sound = true;
|
||||
if (i != data->m_sounds->end()) {
|
||||
if (i->second.name == snd && g_sound->soundExists(i->second.id)) {
|
||||
add_sound = false;
|
||||
}else{
|
||||
g_sound->stopSound(i->second.id);
|
||||
}
|
||||
}
|
||||
if (add_sound) {
|
||||
v3f pf = intToFloat(p+blockpos_nodes,BS);
|
||||
MapBlockSound bsnd;
|
||||
bsnd.id = g_sound->playSoundAt(snd,true,pf, true);
|
||||
bsnd.name = snd;
|
||||
if (bsnd.id > 0)
|
||||
(*data->m_sounds)[p] = bsnd;
|
||||
}
|
||||
}else if (i != data->m_sounds->end()) {
|
||||
g_sound->stopSound(i->second.id);
|
||||
data->m_sounds->erase(i);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Add torches to mesh
|
||||
*/
|
||||
|
|
|
@ -2078,6 +2078,7 @@ void content_mapnode_init(bool repeat)
|
|||
f->setAllTextureTypes(MATERIAL_ALPHA_VERTEX);
|
||||
f->post_effect_color = video::SColor(64, 100, 100, 200);
|
||||
#endif
|
||||
f->sound_ambient = "env-water";
|
||||
f->suffocation_per_second = 2;
|
||||
|
||||
i = CONTENT_WATERSOURCE;
|
||||
|
@ -2197,6 +2198,7 @@ void content_mapnode_init(bool repeat)
|
|||
f->liquid_alternative_source = CONTENT_LAVASOURCE;
|
||||
f->liquid_viscosity = LAVA_VISC;
|
||||
f->damage_per_second = 4*2;
|
||||
f->sound_ambient = "env-lava";
|
||||
#ifndef SERVER
|
||||
f->post_effect_color = video::SColor(192, 255, 64, 0);
|
||||
#endif
|
||||
|
|
|
@ -955,6 +955,7 @@ void content_mapnode_special(bool repeat)
|
|||
f->diggable = false;
|
||||
f->buildable_to = true;
|
||||
f->damage_per_second = 8;
|
||||
f->sound_ambient = "env-fire";
|
||||
#ifndef SERVER
|
||||
f->post_effect_color = video::SColor(192, 255, 64, 0);
|
||||
#endif
|
||||
|
|
|
@ -219,6 +219,7 @@ void content_mob_init()
|
|||
f->punch_action = MPA_PICKUP;
|
||||
f->dropped_item = std::string("CraftItem2 ")+itos(CONTENT_CRAFTITEM_RAT)+" 1";
|
||||
f->motion = MM_WANDER;
|
||||
f->moves_silently = true;
|
||||
f->spawn_on = CONTENT_STONE;
|
||||
f->spawn_in = CONTENT_AIR;
|
||||
f->spawn_max_height = -10;
|
||||
|
|
|
@ -29,6 +29,9 @@
|
|||
#include "main.h"
|
||||
#include "light.h"
|
||||
#include <sstream>
|
||||
#ifndef SERVER
|
||||
#include "sound.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
MapBlock
|
||||
|
@ -65,11 +68,15 @@ MapBlock::~MapBlock()
|
|||
{
|
||||
JMutexAutoLock lock(mesh_mutex);
|
||||
|
||||
if(mesh)
|
||||
{
|
||||
if (mesh) {
|
||||
delete mesh;
|
||||
mesh = NULL;
|
||||
}
|
||||
if (g_sound) {
|
||||
for (std::map<v3s16,MapBlockSound>::iterator i = m_sounds.begin(); i != m_sounds.end(); i++) {
|
||||
g_sound->stopSound(i->second.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -126,6 +133,7 @@ void MapBlock::updateMesh(u32 daynight_ratio, Environment *env, v3s16 camera_off
|
|||
MeshMakeData data;
|
||||
data.m_env = env;
|
||||
data.fill(daynight_ratio, this);
|
||||
data.m_sounds = &m_sounds;
|
||||
|
||||
MapBlockMesh *mesh_new = new MapBlockMesh(&data, camera_offset);
|
||||
|
||||
|
|
|
@ -584,6 +584,8 @@ public:
|
|||
#ifndef SERVER // Only on client
|
||||
MapBlockMesh *mesh;
|
||||
JMutex mesh_mutex;
|
||||
|
||||
std::map<v3s16,MapBlockSound> m_sounds;
|
||||
#endif
|
||||
|
||||
NodeMetadataList m_node_metadata;
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "profiler.h"
|
||||
#include "mesh.h"
|
||||
#include "base64.h"
|
||||
#include "sound.h"
|
||||
|
||||
void MeshMakeData::fill(u32 daynight_ratio, MapBlock *block)
|
||||
{
|
||||
|
|
|
@ -120,6 +120,12 @@ u8 getSmoothLight(v3s16 p, v3s16 corner, VoxelManipulator &vmanip, u32 daynight_
|
|||
class MapBlock;
|
||||
class Environment;
|
||||
|
||||
struct MapBlockSound
|
||||
{
|
||||
int id;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
struct MeshMakeData
|
||||
{
|
||||
u32 m_daynight_ratio;
|
||||
|
@ -128,6 +134,8 @@ struct MeshMakeData
|
|||
v3s16 m_blockpos;
|
||||
Environment *m_env;
|
||||
|
||||
std::map<v3s16,MapBlockSound> *m_sounds;
|
||||
|
||||
/*
|
||||
Copy central data directly from block, and other data from
|
||||
parent of block.
|
||||
|
|
|
@ -402,6 +402,8 @@ struct ContentFeatures
|
|||
std::string sound_dig;
|
||||
// Sound played when the node is placed
|
||||
std::string sound_place;
|
||||
// Sound played by the node always
|
||||
std::string sound_ambient;
|
||||
|
||||
// If the content is liquid, this is the flowing version of the liquid.
|
||||
// If content is liquid, this is the same content.
|
||||
|
@ -500,6 +502,7 @@ struct ContentFeatures
|
|||
sound_step = "";
|
||||
sound_dig = "";
|
||||
sound_place = "";
|
||||
sound_ambient = "";
|
||||
liquid_alternative_flowing = CONTENT_IGNORE;
|
||||
liquid_alternative_source = CONTENT_IGNORE;
|
||||
liquid_viscosity = 0;
|
||||
|
|
|
@ -35,6 +35,8 @@ ISoundManager *g_sound = NULL;
|
|||
|
||||
void init_sounds(ISoundManager *sound)
|
||||
{
|
||||
// sounds must be mono sounds, stereo will not work right!
|
||||
// exceptions: background music
|
||||
// walking
|
||||
// CMT_DIRT
|
||||
sound->loadSound("dirt-step-left","step_dirt.1.ogg");
|
||||
|
@ -95,12 +97,12 @@ void init_sounds(ISoundManager *sound)
|
|||
sound->loadSound("open-chest","open_chest.ogg");
|
||||
|
||||
// environment and node sounds
|
||||
// these must be mono sounds, stereo will not work right!
|
||||
sound->loadSound("env-piston","env_piston.ogg");
|
||||
sound->loadSound("env-dooropen","env_dooropen.ogg");
|
||||
sound->loadSound("env-doorclose","env_doorclose.ogg");
|
||||
sound->loadSound("env-fire","env_fire.ogg");
|
||||
sound->loadSound("env-lava","env_lava.ogg");
|
||||
sound->loadSound("env-lava","env_lava.ogg",0.2);
|
||||
sound->loadSound("env-water","env_water.ogg",0.2);
|
||||
sound->loadSound("env-steam","env_steam.ogg");
|
||||
sound->loadSound("env-tnt","env_tnt.ogg");
|
||||
sound->loadSound("env-teleport","env_teleport.ogg");
|
||||
|
|
|
@ -48,7 +48,7 @@ public:
|
|||
// playSound functions return -1 on failure, otherwise a handle to the
|
||||
// sound. If name=="", call should be ignored without error.
|
||||
virtual int playSound(const std::string &name, bool loop) = 0;
|
||||
virtual int playSoundAt(const std::string &name, bool loop, v3f pos, float gain=1.0) = 0;
|
||||
virtual int playSoundAt(const std::string &name, bool loop, v3f pos, float gain=1.0, bool queue=false) = 0;
|
||||
virtual void stopSound(int sound) = 0;
|
||||
virtual bool soundExists(int sound) = 0;
|
||||
|
||||
|
@ -69,7 +69,7 @@ public:
|
|||
void setListenerGain(float gain) {}
|
||||
|
||||
int playSound(const std::string &name, bool loop) {return 0;}
|
||||
int playSoundAt(const std::string &name, bool loop, v3f pos, float gain) {return 0;}
|
||||
int playSoundAt(const std::string &name, bool loop, v3f pos, float gain, bool queue) {return 0;}
|
||||
void stopSound(int sound) {}
|
||||
bool soundExists(int sound) {return false;}
|
||||
|
||||
|
|
|
@ -177,9 +177,14 @@ SoundBuffer* loadOggFile(const std::string &filepath)
|
|||
|
||||
struct PlayingSound
|
||||
{
|
||||
SoundBuffer *buf;
|
||||
ALuint source_id;
|
||||
bool loop;
|
||||
bool should_delete;
|
||||
bool has_position;
|
||||
v3f pos;
|
||||
bool disabled;
|
||||
float gain;
|
||||
};
|
||||
|
||||
class OpenALSoundManager: public ISoundManager
|
||||
|
@ -195,6 +200,7 @@ private:
|
|||
std::map<int, PlayingSound*> m_sounds_playing;
|
||||
std::map<std::string, int> m_indexes;
|
||||
v3f m_listener_pos;
|
||||
JMutex m_mutex;
|
||||
public:
|
||||
OpenALSoundManager():
|
||||
m_device(NULL),
|
||||
|
@ -208,6 +214,8 @@ public:
|
|||
|
||||
infostream<<"Audio: Initializing..."<<std::endl;
|
||||
|
||||
m_mutex.Init();
|
||||
|
||||
m_device = alcOpenDevice(NULL);
|
||||
if (!m_device) {
|
||||
infostream<<"Audio: No audio device available, audio system "
|
||||
|
@ -267,6 +275,7 @@ public:
|
|||
~OpenALSoundManager()
|
||||
{
|
||||
infostream<<"Audio: Deinitializing..."<<std::endl;
|
||||
g_sound = NULL;
|
||||
// KABOOM!
|
||||
// TODO: Clear SoundBuffers
|
||||
alcMakeContextCurrent(NULL);
|
||||
|
@ -329,14 +338,18 @@ public:
|
|||
alSource3f(sound->source_id, AL_POSITION, 0, 0, 0);
|
||||
alSource3f(sound->source_id, AL_VELOCITY, 0, 0, 0);
|
||||
alSourcei(sound->source_id, AL_LOOPING, loop ? AL_TRUE : AL_FALSE);
|
||||
float volume = MYMAX(0.0, buf->gain);
|
||||
alSourcef(sound->source_id, AL_GAIN, volume);
|
||||
sound->gain = 1.0;
|
||||
alSourcef(sound->source_id, AL_GAIN, buf->gain);
|
||||
alSourcePlay(sound->source_id);
|
||||
sound->should_delete = false;
|
||||
sound->loop = loop;
|
||||
sound->has_position = false;
|
||||
sound->disabled = false;
|
||||
sound->buf = buf;
|
||||
return sound;
|
||||
}
|
||||
|
||||
PlayingSound* createPlayingSoundAt(SoundBuffer *buf, bool loop, v3f pos, float gain)
|
||||
PlayingSound* createPlayingSoundAt(SoundBuffer *buf, bool loop, v3f pos, float gain, bool queue)
|
||||
{
|
||||
infostream<<"OpenALSoundManager: Creating positional playing sound"
|
||||
<<std::endl;
|
||||
|
@ -345,18 +358,29 @@ public:
|
|||
errorstream<<"Attempting to play non-mono sound as positional sound"<<std::endl;
|
||||
PlayingSound *sound = new PlayingSound;
|
||||
assert(sound);
|
||||
float distance = m_listener_pos.getDistanceFrom(pos);
|
||||
if (!queue && (!loop || distance < 240.0)) {
|
||||
alGenSources(1, &sound->source_id);
|
||||
alSourcei(sound->source_id, AL_BUFFER, buf->buffer_id);
|
||||
alSourcei(sound->source_id, AL_SOURCE_RELATIVE, false);
|
||||
alSource3f(sound->source_id, AL_POSITION, pos.X, pos.Y, pos.Z);
|
||||
alSource3f(sound->source_id, AL_VELOCITY, 0, 0, 0);
|
||||
//alSourcef(sound->source_id, AL_ROLLOFF_FACTOR, 0.7);
|
||||
alSourcef(sound->source_id, AL_REFERENCE_DISTANCE, 30.0);
|
||||
alSourcei(sound->source_id, AL_LOOPING, loop ? AL_TRUE : AL_FALSE);
|
||||
float volume = MYMAX(0.0, buf->gain*gain);
|
||||
alSourcef(sound->source_id, AL_GAIN, volume);
|
||||
float t_gain = MYMAX(0.0, buf->gain*gain);
|
||||
alSourcef(sound->source_id, AL_GAIN, t_gain);
|
||||
alSourcePlay(sound->source_id);
|
||||
sound->disabled = false;
|
||||
}else{
|
||||
sound->source_id = 0;
|
||||
sound->disabled = true;
|
||||
}
|
||||
sound->gain = gain;
|
||||
sound->should_delete = false;
|
||||
sound->loop = loop;
|
||||
sound->has_position = true;
|
||||
sound->pos = pos;
|
||||
sound->buf = buf;
|
||||
return sound;
|
||||
}
|
||||
|
||||
|
@ -366,19 +390,27 @@ public:
|
|||
PlayingSound *sound = createPlayingSound(buf, loop);
|
||||
if (!sound)
|
||||
return -1;
|
||||
int id = m_next_id++;
|
||||
int id = -1;
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
id = m_next_id++;
|
||||
m_sounds_playing[id] = sound;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
int playSoundRawAt(SoundBuffer *buf, bool loop, v3f pos, float gain)
|
||||
int playSoundRawAt(SoundBuffer *buf, bool loop, v3f pos, float gain, bool queue)
|
||||
{
|
||||
assert(buf);
|
||||
PlayingSound *sound = createPlayingSoundAt(buf, loop, pos, gain);
|
||||
PlayingSound *sound = createPlayingSoundAt(buf, loop, pos, gain, queue);
|
||||
if (!sound)
|
||||
return -1;
|
||||
int id = m_next_id++;
|
||||
int id = -1;
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
id = m_next_id++;
|
||||
m_sounds_playing[id] = sound;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
|
@ -391,24 +423,53 @@ public:
|
|||
m_music_last_id = 0;
|
||||
if (i == m_sounds_playing.end())
|
||||
return;
|
||||
|
||||
PlayingSound *sound = i->second;
|
||||
|
||||
alSourceStop(sound->source_id);
|
||||
alDeleteSources(1, &sound->source_id);
|
||||
|
||||
delete sound;
|
||||
|
||||
m_sounds_playing.erase(id);
|
||||
|
||||
}
|
||||
|
||||
// Remove stopped sounds
|
||||
void maintain(float dtime)
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
verbosestream<<"OpenALSoundManager::maintain(): "
|
||||
<<m_sounds_playing.size()<<" playing sounds, "
|
||||
<<m_buffers.size()<<" sound names loaded"<<std::endl;
|
||||
std::set<int> del_list;
|
||||
bool did_start = false;
|
||||
for (std::map<int, PlayingSound*>::iterator i = m_sounds_playing.begin(); i != m_sounds_playing.end(); i++) {
|
||||
int id = i->first;
|
||||
PlayingSound *sound = i->second;
|
||||
if (sound->has_position && sound->loop && !sound->should_delete) {
|
||||
float distance = m_listener_pos.getDistanceFrom(sound->pos);
|
||||
if (distance > 320.0 && !sound->disabled && !did_start) {
|
||||
alSourceStop(sound->source_id);
|
||||
alDeleteSources(1, &sound->source_id);
|
||||
sound->disabled = true;
|
||||
sound->source_id = 0;
|
||||
}else if (distance < 240.0 && sound->disabled) {
|
||||
did_start = true;
|
||||
alGenSources(1, &sound->source_id);
|
||||
alSourcei(sound->source_id, AL_BUFFER, sound->buf->buffer_id);
|
||||
alSourcei(sound->source_id, AL_SOURCE_RELATIVE, false);
|
||||
alSource3f(sound->source_id, AL_POSITION, sound->pos.X, sound->pos.Y, sound->pos.Z);
|
||||
alSource3f(sound->source_id, AL_VELOCITY, 0, 0, 0);
|
||||
alSourcef(sound->source_id, AL_REFERENCE_DISTANCE, 30.0);
|
||||
alSourcei(sound->source_id, AL_LOOPING, AL_TRUE);
|
||||
float t_gain = MYMAX(0.0, sound->buf->gain*sound->gain);
|
||||
alSourcef(sound->source_id, AL_GAIN, t_gain);
|
||||
alSourcePlay(sound->source_id);
|
||||
sound->disabled = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (sound->should_delete) {
|
||||
del_list.insert(id);
|
||||
}else{ // If not playing, remove it
|
||||
|
@ -490,7 +551,7 @@ public:
|
|||
}
|
||||
return playSoundRaw(buf, loop);
|
||||
}
|
||||
int playSoundAt(const std::string &name, bool loop, v3f pos, float gain)
|
||||
int playSoundAt(const std::string &name, bool loop, v3f pos, float gain, bool queue=false)
|
||||
{
|
||||
if (name == "")
|
||||
return 0;
|
||||
|
@ -500,10 +561,11 @@ public:
|
|||
<<std::endl;
|
||||
return -1;
|
||||
}
|
||||
return playSoundRawAt(buf, loop, pos, gain);
|
||||
return playSoundRawAt(buf, loop, pos, gain, queue);
|
||||
}
|
||||
void stopSound(int id)
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
std::map<int, PlayingSound*>::iterator i = m_sounds_playing.find(id);
|
||||
if (id == m_music_id)
|
||||
m_music_id = 0;
|
||||
|
@ -516,6 +578,7 @@ public:
|
|||
}
|
||||
bool soundExists(int sound)
|
||||
{
|
||||
JMutexAutoLock lock(m_mutex);
|
||||
return (m_sounds_playing.count(sound) != 0);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue