forked from oerkki/voxelands
sound pt2
This commit is contained in:
parent
81cf0e0719
commit
3099caf133
|
@ -16,9 +16,11 @@ endif(GETTEXT_FOUND)
|
||||||
|
|
||||||
# user visible option to enable/disable audio
|
# user visible option to enable/disable audio
|
||||||
OPTION(ENABLE_AUDIO "Enable audio" ON)
|
OPTION(ENABLE_AUDIO "Enable audio" ON)
|
||||||
|
OPTION(ENABLE_MUMBLE "Enable Mumble Positional Audio" ON)
|
||||||
|
|
||||||
## this is only set to 1 if audio is enabled _and_ available
|
## this is only set to 1 if audio is enabled _and_ available
|
||||||
set(USE_AUDIO 0)
|
set(USE_AUDIO 0)
|
||||||
|
set(USE_MUMBLE 0)
|
||||||
set(SOUND_PROBLEM 0)
|
set(SOUND_PROBLEM 0)
|
||||||
|
|
||||||
if(ENABLE_AUDIO AND BUILD_CLIENT)
|
if(ENABLE_AUDIO AND BUILD_CLIENT)
|
||||||
|
@ -39,6 +41,14 @@ if(ENABLE_AUDIO AND BUILD_CLIENT)
|
||||||
set(USE_AUDIO 1)
|
set(USE_AUDIO 1)
|
||||||
message(STATUS "Sound enabled")
|
message(STATUS "Sound enabled")
|
||||||
endif()
|
endif()
|
||||||
|
if(ENABLE_MUMBLE AND USE_AUDIO)
|
||||||
|
if(WIN32)
|
||||||
|
set(USE_MUMBLE 1)
|
||||||
|
else()
|
||||||
|
find_library(MUMBLE_LIBS rt)
|
||||||
|
set(USE_MUMBLE 1)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
endif(ENABLE_AUDIO AND BUILD_CLIENT)
|
endif(ENABLE_AUDIO AND BUILD_CLIENT)
|
||||||
|
|
||||||
if(SOUND_PROBLEM)
|
if(SOUND_PROBLEM)
|
||||||
|
@ -46,7 +56,11 @@ if(SOUND_PROBLEM)
|
||||||
"To continue, either fill in the required paths or disable sound. (-DENABLE_AUDIO=0)")
|
"To continue, either fill in the required paths or disable sound. (-DENABLE_AUDIO=0)")
|
||||||
endif()
|
endif()
|
||||||
if(USE_AUDIO)
|
if(USE_AUDIO)
|
||||||
set(audio_SRCS sound.c sound_ogg.c sound_wav.c)
|
if(USE_MUMBLE)
|
||||||
|
set(audio_SRCS sound.c sound_ogg.c sound_wav.c sound_util.cpp sound_mumble.c)
|
||||||
|
else()
|
||||||
|
set(audio_SRCS sound.c sound_ogg.c sound_wav.c sound_util.cpp)
|
||||||
|
endif()
|
||||||
set(AUDIO_INCLUDE_DIRS
|
set(AUDIO_INCLUDE_DIRS
|
||||||
${OPENAL_INCLUDE_DIR}
|
${OPENAL_INCLUDE_DIR}
|
||||||
${VORBIS_INCLUDE_DIR}
|
${VORBIS_INCLUDE_DIR}
|
||||||
|
@ -321,6 +335,7 @@ if(BUILD_CLIENT)
|
||||||
${SQLITE3_LIBRARY}
|
${SQLITE3_LIBRARY}
|
||||||
${PLATFORM_LIBS}
|
${PLATFORM_LIBS}
|
||||||
${CLIENT_PLATFORM_LIBS}
|
${CLIENT_PLATFORM_LIBS}
|
||||||
|
${MUMBLE_LIBS}
|
||||||
)
|
)
|
||||||
if(USE_FREETYPE)
|
if(USE_FREETYPE)
|
||||||
if(FREETYPE_PKGCONFIG_FOUND)
|
if(FREETYPE_PKGCONFIG_FOUND)
|
||||||
|
|
|
@ -1632,7 +1632,7 @@ void Client::useItem()
|
||||||
if ((w&CONTENT_CRAFTITEM_MASK) == CONTENT_CRAFTITEM_MASK)
|
if ((w&CONTENT_CRAFTITEM_MASK) == CONTENT_CRAFTITEM_MASK)
|
||||||
snd = content_craftitem_features(w)->sound_use;
|
snd = content_craftitem_features(w)->sound_use;
|
||||||
if (snd != "")
|
if (snd != "")
|
||||||
sound_play_effect(snd.c_str(),1.0,NULL);
|
sound_play_effect((char*)snd.c_str(),1.0,0,NULL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -2287,7 +2287,7 @@ float Client::getRTT(void)
|
||||||
// foot: 0 = left, 1 = right
|
// foot: 0 = left, 1 = right
|
||||||
void Client::playStepSound(int foot)
|
void Client::playStepSound(int foot)
|
||||||
{
|
{
|
||||||
//sound_playStep(&m_env.getMap(),m_env.getLocalPlayer()->getPosition(),foot);
|
sound_play_step(&m_env.getMap(),m_env.getLocalPlayer()->getPosition(),foot,1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::playDigSound(content_t c)
|
void Client::playDigSound(content_t c)
|
||||||
|
@ -2300,7 +2300,7 @@ void Client::playDigSound(content_t c)
|
||||||
if (c == CONTENT_IGNORE)
|
if (c == CONTENT_IGNORE)
|
||||||
c = CONTENT_AIR;
|
c = CONTENT_AIR;
|
||||||
|
|
||||||
//sound_playDig(c,m_env.getLocalPlayer()->getPosition());
|
sound_play_dig(c,m_env.getLocalPlayer()->getPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::playPlaceSound(content_t c)
|
void Client::playPlaceSound(content_t c)
|
||||||
|
@ -2310,27 +2310,25 @@ void Client::playPlaceSound(content_t c)
|
||||||
|
|
||||||
ContentFeatures *f = &content_features(c);
|
ContentFeatures *f = &content_features(c);
|
||||||
if (f->sound_place != "") {
|
if (f->sound_place != "") {
|
||||||
sound_play_effect((char*)f->sound_place.c_str(),1.0,NULL);
|
sound_play_effect((char*)f->sound_place.c_str(),1.0,0,NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (f->type) {
|
switch (f->type) {
|
||||||
case CMT_LIQUID:
|
case CMT_LIQUID:
|
||||||
sound_play_effect("liquid-place",1.0,NULL);
|
sound_play_effect("liquid-place",1.0,0,NULL);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sound_play_effect("place",1.0,NULL);
|
sound_play_effect("place",1.0,0,NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::playSound(std::string &name, bool loop)
|
void Client::playSound(std::string &name, bool loop)
|
||||||
{
|
{
|
||||||
/* TODO: looping */
|
sound_play_effect((char*)name.c_str(),1.0,loop,NULL);
|
||||||
sound_play_effect((char*)name.c_str(),1.0,NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::playSoundAt(std::string &name, v3f pos, bool loop)
|
void Client::playSoundAt(std::string &name, v3f pos, bool loop)
|
||||||
{
|
{
|
||||||
v3_t p = {pos.X,pos.Y,pos.Z};
|
v3_t p = {pos.X,pos.Y,pos.Z};
|
||||||
/* TODO: looping */
|
sound_play_effect((char*)name.c_str(),1.0,loop,&p);
|
||||||
sound_play_effect((char*)name.c_str(),1.0,&p);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Filled in by the build system
|
/* Filled in by the build system */
|
||||||
|
|
||||||
#ifndef CMAKE_CONFIG_H
|
#ifndef CMAKE_CONFIG_H
|
||||||
#define CMAKE_CONFIG_H
|
#define CMAKE_CONFIG_H
|
||||||
|
@ -7,6 +7,7 @@
|
||||||
#define INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@"
|
#define INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@"
|
||||||
#define VERSION_STRING "@VERSION_STRING@"
|
#define VERSION_STRING "@VERSION_STRING@"
|
||||||
#define USE_AUDIO @USE_AUDIO@
|
#define USE_AUDIO @USE_AUDIO@
|
||||||
|
#define USE_MUMBLE @USE_MUMBLE@
|
||||||
#define USE_FREETYPE @USE_FREETYPE@
|
#define USE_FREETYPE @USE_FREETYPE@
|
||||||
#define USE_GETTEXT @USE_GETTEXT@
|
#define USE_GETTEXT @USE_GETTEXT@
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
|
|
13
src/common.h
13
src/common.h
|
@ -27,6 +27,17 @@ extern "C" {
|
||||||
#undef _DEFAULT_SOURCE
|
#undef _DEFAULT_SOURCE
|
||||||
#endif
|
#endif
|
||||||
#define _DEFAULT_SOURCE
|
#define _DEFAULT_SOURCE
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
#define WIN32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -35,6 +46,8 @@ extern "C" {
|
||||||
#include "array.h"
|
#include "array.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#ifndef _HAVE_V3_TYPE
|
#ifndef _HAVE_V3_TYPE
|
||||||
#define _HAVE_V3_TYPE
|
#define _HAVE_V3_TYPE
|
||||||
typedef struct v3_s {
|
typedef struct v3_s {
|
||||||
|
|
38
src/config.h
38
src/config.h
|
@ -7,29 +7,27 @@
|
||||||
#define CONFIG_H
|
#define CONFIG_H
|
||||||
|
|
||||||
#ifdef USE_CMAKE_CONFIG_H
|
#ifdef USE_CMAKE_CONFIG_H
|
||||||
#include "cmake_config.h"
|
|
||||||
|
#include "cmake_config.h"
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define PROJECT_NAME "voxelands"
|
|
||||||
|
|
||||||
//#define INSTALL_PREFIX ""
|
#define PROJECT_NAME "voxelands"
|
||||||
#define VERSION_STRING "unknown"
|
|
||||||
#ifdef NDEBUG
|
#define VERSION_STRING "unknown"
|
||||||
#define BUILD_TYPE "Release"
|
#ifdef NDEBUG
|
||||||
#else
|
#define BUILD_TYPE "Release"
|
||||||
#define BUILD_TYPE "Debug"
|
#else
|
||||||
#endif
|
#define BUILD_TYPE "Debug"
|
||||||
#ifdef RUN_IN_PLACE
|
#endif
|
||||||
#define RUN_IN_PLACE_BOOLSTRING "1"
|
#if USE_GETTEXT
|
||||||
#else
|
#define USE_GETTEXT_BOOLSTRING "1"
|
||||||
#define RUN_IN_PLACE_BOOLSTRING "0"
|
#else
|
||||||
#endif
|
#define USE_GETTEXT_BOOLSTRING "0"
|
||||||
#if USE_GETTEXT
|
#endif
|
||||||
#define USE_GETTEXT_BOOLSTRING "1"
|
|
||||||
#else
|
#define BUILD_INFO "NON-CMAKE RUN_IN_PLACE=" RUN_IN_PLACE_BOOLSTRING " USE_GETTEXT=" USE_GETTEXT_BOOLSTRING " BUILD_TYPE=" BUILD_TYPE
|
||||||
#define USE_GETTEXT_BOOLSTRING "0"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define BUILD_INFO "NON-CMAKE RUN_IN_PLACE=" RUN_IN_PLACE_BOOLSTRING " USE_GETTEXT=" USE_GETTEXT_BOOLSTRING " BUILD_TYPE=" BUILD_TYPE
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,10 @@ void config_default_init()
|
||||||
config_set_default("client.sound.volume","50",sound_master_setter);
|
config_set_default("client.sound.volume","50",sound_master_setter);
|
||||||
config_set_default("client.sound.volume.effects","50",sound_effects_setter);
|
config_set_default("client.sound.volume.effects","50",sound_effects_setter);
|
||||||
config_set_default("client.sound.volume.music","50",sound_music_setter);
|
config_set_default("client.sound.volume.music","50",sound_music_setter);
|
||||||
|
config_set_default("client.sound.mumble","true",NULL);
|
||||||
|
#if USE_MUMBLE == 0
|
||||||
|
config_set_default("client.name",NULL,sound_mumble_set_ident);
|
||||||
|
#endif
|
||||||
|
|
||||||
config_set_default("client.graphics.mesh.lod","3",NULL);
|
config_set_default("client.graphics.mesh.lod","3",NULL);
|
||||||
config_set_default("client.graphics.texture.animations","true",NULL);
|
config_set_default("client.graphics.texture.animations","true",NULL);
|
||||||
|
|
|
@ -272,7 +272,7 @@ void MobCAO::step(float dtime, ClientEnvironment *env)
|
||||||
/* roughly sort of when a step sound should probably be heard, maybe */
|
/* roughly sort of when a step sound should probably be heard, maybe */
|
||||||
if (m_last_step > 0.5) {
|
if (m_last_step > 0.5) {
|
||||||
m_last_step -= 0.5;
|
m_last_step -= 0.5;
|
||||||
//sound_playStep(&env->getMap(),m_position,m_next_foot, 0.3);
|
sound_play_step(&env->getMap(),m_position,m_next_foot, 0.3);
|
||||||
m_next_foot = !m_next_foot;
|
m_next_foot = !m_next_foot;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1503,7 +1503,7 @@ void the_game(
|
||||||
std::string gender = f.next(":");
|
std::string gender = f.next(":");
|
||||||
std::string snd("player-hurt-");
|
std::string snd("player-hurt-");
|
||||||
snd += gender;
|
snd += gender;
|
||||||
sound_play_effect((char*)snd.c_str(),1.0,NULL);
|
sound_play_effect((char*)snd.c_str(),1.0,0,NULL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}else if (event.type == CE_PLAYER_FORCE_MOVE) {
|
}else if (event.type == CE_PLAYER_FORCE_MOVE) {
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <IGUIListBox.h>
|
#include <IGUIListBox.h>
|
||||||
#include <IGUIFont.h>
|
#include <IGUIFont.h>
|
||||||
#include <IGUIScrollBar.h>
|
#include <IGUIScrollBar.h>
|
||||||
|
#include "intlGUIEditBox.h"
|
||||||
#include "gui_colours.h"
|
#include "gui_colours.h"
|
||||||
#include "http.h"
|
#include "http.h"
|
||||||
|
|
||||||
|
|
|
@ -1103,7 +1103,7 @@ int main(int argc, char *argv[])
|
||||||
infostream<<"Created main menu"<<std::endl;
|
infostream<<"Created main menu"<<std::endl;
|
||||||
|
|
||||||
#if USE_AUDIO == 1
|
#if USE_AUDIO == 1
|
||||||
sound_play_music("bg-mainmenu",1.0);
|
sound_play_music("bg-mainmenu",1.0,1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
while (device->run() && kill == false) {
|
while (device->run() && kill == false) {
|
||||||
|
@ -1208,7 +1208,7 @@ int main(int argc, char *argv[])
|
||||||
menu->allowFocusRemoval(true);
|
menu->allowFocusRemoval(true);
|
||||||
|
|
||||||
#if USE_AUDIO == 1
|
#if USE_AUDIO == 1
|
||||||
sound_play_music("bg-charcreator",1.0);
|
sound_play_music("bg-charcreator",1.0,1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
while (device->run() && kill == false) {
|
while (device->run() && kill == false) {
|
||||||
|
@ -1253,6 +1253,9 @@ int main(int argc, char *argv[])
|
||||||
password,
|
password,
|
||||||
error_message
|
error_message
|
||||||
);
|
);
|
||||||
|
#if USE_AUDIO == 1
|
||||||
|
sound_stop_effects(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
} //try
|
} //try
|
||||||
catch(con::PeerNotFoundException &e)
|
catch(con::PeerNotFoundException &e)
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
#include "mapblock.h"
|
#include "mapblock.h"
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
// For g_settings
|
// For g_settings
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
|
@ -25,11 +25,13 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#include "mapblock_mesh.h"
|
#include "mapblock_mesh.h"
|
||||||
#include "light.h"
|
#include "light.h"
|
||||||
#include "mapblock.h"
|
#include "mapblock.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "main.h" // For g_settings and g_texturesource
|
#include "main.h" // For g_texturesource
|
||||||
#include "content_mapblock.h"
|
#include "content_mapblock.h"
|
||||||
#include "content_nodemeta.h"
|
#include "content_nodemeta.h"
|
||||||
#include "profiler.h"
|
#include "profiler.h"
|
||||||
|
@ -536,10 +538,10 @@ void MapBlockMesh::generate(MeshMakeData *data, v3s16 camera_offset, JMutex *mut
|
||||||
if (snd != "") {
|
if (snd != "") {
|
||||||
bool add_sound = true;
|
bool add_sound = true;
|
||||||
if (i != data->m_sounds->end()) {
|
if (i != data->m_sounds->end()) {
|
||||||
if (i->second.name == snd && g_sound->soundExists(i->second.id)) {
|
if (i->second.name == snd && sound_exists(i->second.id)) {
|
||||||
add_sound = false;
|
add_sound = false;
|
||||||
}else{
|
}else{
|
||||||
g_sound->stopSound(i->second.id);
|
sound_stop_single(i->second.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (add_sound && content_features(n).liquid_type != LIQUID_NONE) {
|
if (add_sound && content_features(n).liquid_type != LIQUID_NONE) {
|
||||||
|
@ -567,14 +569,15 @@ void MapBlockMesh::generate(MeshMakeData *data, v3s16 camera_offset, JMutex *mut
|
||||||
}
|
}
|
||||||
if (add_sound) {
|
if (add_sound) {
|
||||||
v3f pf = intToFloat(p+data->m_blockpos_nodes,BS);
|
v3f pf = intToFloat(p+data->m_blockpos_nodes,BS);
|
||||||
|
v3_t vp = {pf.X,pf.Y,pf.Z};
|
||||||
MapBlockSound bsnd;
|
MapBlockSound bsnd;
|
||||||
bsnd.id = g_sound->playSoundAt(snd,true,pf, true);
|
bsnd.id = sound_play_effect((char*)snd.c_str(),1.0,1,&vp);
|
||||||
bsnd.name = snd;
|
bsnd.name = snd;
|
||||||
if (bsnd.id > 0)
|
if (bsnd.id > 0)
|
||||||
(*data->m_sounds)[p] = bsnd;
|
(*data->m_sounds)[p] = bsnd;
|
||||||
}
|
}
|
||||||
}else if (i != data->m_sounds->end()) {
|
}else if (i != data->m_sounds->end()) {
|
||||||
g_sound->stopSound(i->second.id);
|
sound_stop_single(i->second.id);
|
||||||
data->m_sounds->erase(i);
|
data->m_sounds->erase(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -760,12 +760,12 @@ void RemotePlayer::move(f32 dtime, Map &map, f32 pos_max_d)
|
||||||
int frame = m_node->getFrameNr();
|
int frame = m_node->getFrameNr();
|
||||||
/* roughly sort of when a step sound should probably be heard, maybe */
|
/* roughly sort of when a step sound should probably be heard, maybe */
|
||||||
if (frame == 218 || frame == 186 || frame == 209 || frame == 177) {
|
if (frame == 218 || frame == 186 || frame == 209 || frame == 177) {
|
||||||
//sound_playStep(&map,m_showpos,m_next_foot);
|
sound_play_step(&map,m_showpos,m_next_foot,1.0);
|
||||||
m_next_foot = !m_next_foot;
|
m_next_foot = !m_next_foot;
|
||||||
}
|
}
|
||||||
/* roughly sort of when a dig sound should probably be heard, maybe */
|
/* roughly sort of when a dig sound should probably be heard, maybe */
|
||||||
if (frame == 214 || frame == 205 || frame == 193) {
|
if (frame == 214 || frame == 205 || frame == 193) {
|
||||||
//sound_playDig(m_pointed,m_showpos);
|
sound_play_dig(m_pointed,m_showpos);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_anim_id == PLAYERANIM_DIE) {
|
if (m_anim_id == PLAYERANIM_DIE) {
|
||||||
|
@ -1233,8 +1233,7 @@ void LocalPlayer::applyControl(float dtime)
|
||||||
std::string snd("low-energy-");
|
std::string snd("low-energy-");
|
||||||
snd += gender;
|
snd += gender;
|
||||||
|
|
||||||
/* TODO: looping */
|
m_low_energy_effect = sound_play_effect((char*)snd.c_str(),1.0,1,NULL);
|
||||||
m_low_energy_effect = sound_play_effect(snd.c_str(),1.0,NULL);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}else if (m_energy > 9.8) {
|
}else if (m_energy > 9.8) {
|
||||||
|
|
45
src/sound.c
45
src/sound.c
|
@ -87,6 +87,11 @@ int sound_init()
|
||||||
alDistanceModel(AL_EXPONENT_DISTANCE);
|
alDistanceModel(AL_EXPONENT_DISTANCE);
|
||||||
alListenerf(AL_GAIN, 1.0);
|
alListenerf(AL_GAIN, 1.0);
|
||||||
|
|
||||||
|
#if USE_MUMBLE == 1
|
||||||
|
if (config_get_bool("client.sound.mumble"))
|
||||||
|
sound_mumble_init();
|
||||||
|
#endif
|
||||||
|
|
||||||
sound_data.init = 1;
|
sound_data.init = 1;
|
||||||
|
|
||||||
/* sounds must be mono sounds, stereo will not work right!
|
/* sounds must be mono sounds, stereo will not work right!
|
||||||
|
@ -263,7 +268,7 @@ void sound_step(float dtime, v3_t *pos, v3_t *at, v3_t *up)
|
||||||
sound_process(dtime);
|
sound_process(dtime);
|
||||||
|
|
||||||
if (pos) {
|
if (pos) {
|
||||||
alListenerfv(AL_POSITION, (float*)pos);
|
alListener3f(AL_POSITION, pos->x,pos->y,pos->z);
|
||||||
}else{
|
}else{
|
||||||
alListener3f(AL_POSITION, 0.0,0.0,0.0);
|
alListener3f(AL_POSITION, 0.0,0.0,0.0);
|
||||||
}
|
}
|
||||||
|
@ -277,12 +282,17 @@ void sound_step(float dtime, v3_t *pos, v3_t *at, v3_t *up)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (up) {
|
if (up) {
|
||||||
orientation[3] = up->x;
|
orientation[3] = -up->x;
|
||||||
orientation[4] = up->y;
|
orientation[4] = -up->y;
|
||||||
orientation[5] = up->z;
|
orientation[5] = -up->z;
|
||||||
}
|
}
|
||||||
|
|
||||||
alListenerfv(AL_ORIENTATION, orientation);
|
alListenerfv(AL_ORIENTATION, orientation);
|
||||||
|
|
||||||
|
#if USE_MUMBLE == 1
|
||||||
|
if (pos && at && up)
|
||||||
|
sound_mumble_step(dtime,pos,at,up);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get/set sound effect volume */
|
/* get/set sound effect volume */
|
||||||
|
@ -458,7 +468,7 @@ void sound_free_music(char* token)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* play sound effect */
|
/* play sound effect */
|
||||||
uint32_t sound_play_effect(char* token, float volume, v3_t *pos)
|
uint32_t sound_play_effect(char* token, float volume, uint8_t loop, v3_t *pos)
|
||||||
{
|
{
|
||||||
sound_instance_t *i;
|
sound_instance_t *i;
|
||||||
sound_t *e = sound_data.effects.sounds;
|
sound_t *e = sound_data.effects.sounds;
|
||||||
|
@ -494,7 +504,11 @@ uint32_t sound_play_effect(char* token, float volume, v3_t *pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
alSource3f(i->id, AL_VELOCITY, 0, 0, 0);
|
alSource3f(i->id, AL_VELOCITY, 0, 0, 0);
|
||||||
alSourcei(i->id, AL_LOOPING, AL_FALSE);
|
if (loop) {
|
||||||
|
alSourcei(i->id, AL_LOOPING, AL_TRUE);
|
||||||
|
}else{
|
||||||
|
alSourcei(i->id, AL_LOOPING, AL_FALSE);
|
||||||
|
}
|
||||||
alSourcef(i->id, AL_GAIN, sound_data.effects.volume*sound_data.volume*volume);
|
alSourcef(i->id, AL_GAIN, sound_data.effects.volume*sound_data.volume*volume);
|
||||||
alSourcePlay(i->id);
|
alSourcePlay(i->id);
|
||||||
|
|
||||||
|
@ -510,7 +524,7 @@ uint32_t sound_play_effect(char* token, float volume, v3_t *pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* play music */
|
/* play music */
|
||||||
uint32_t sound_play_music(char* token, float volume)
|
uint32_t sound_play_music(char* token, float volume, uint8_t loop)
|
||||||
{
|
{
|
||||||
sound_t *e = sound_data.music.sounds;
|
sound_t *e = sound_data.music.sounds;
|
||||||
if (!sound_data.init || !e)
|
if (!sound_data.init || !e)
|
||||||
|
@ -543,7 +557,11 @@ uint32_t sound_play_music(char* token, float volume)
|
||||||
alSourcei(sound_data.music.playing->id, AL_SOURCE_RELATIVE, AL_TRUE);
|
alSourcei(sound_data.music.playing->id, AL_SOURCE_RELATIVE, AL_TRUE);
|
||||||
alSource3f(sound_data.music.playing->id, AL_POSITION, 0, 0, 0);
|
alSource3f(sound_data.music.playing->id, AL_POSITION, 0, 0, 0);
|
||||||
alSource3f(sound_data.music.playing->id, AL_VELOCITY, 0, 0, 0);
|
alSource3f(sound_data.music.playing->id, AL_VELOCITY, 0, 0, 0);
|
||||||
alSourcei(sound_data.music.playing->id, AL_LOOPING, AL_TRUE);
|
if (loop) {
|
||||||
|
alSourcei(sound_data.music.playing->id, AL_LOOPING, AL_TRUE);
|
||||||
|
}else{
|
||||||
|
alSourcei(sound_data.music.playing->id, AL_LOOPING, AL_FALSE);
|
||||||
|
}
|
||||||
alSourcef(sound_data.music.playing->id, AL_GAIN, sound_data.music.volume*sound_data.volume*volume);
|
alSourcef(sound_data.music.playing->id, AL_GAIN, sound_data.music.volume*sound_data.volume*volume);
|
||||||
alSourcePlay(sound_data.music.playing->id);
|
alSourcePlay(sound_data.music.playing->id);
|
||||||
|
|
||||||
|
@ -600,6 +618,17 @@ void sound_stop_single(uint32_t id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sound_exists(uint32_t id)
|
||||||
|
{
|
||||||
|
sound_instance_t *i = sound_data.effects.playing;
|
||||||
|
while (i) {
|
||||||
|
if (i->id == id)
|
||||||
|
return 1;
|
||||||
|
i = i->next;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* stop all sounds, optionally fading out in fade seconds */
|
/* stop all sounds, optionally fading out in fade seconds */
|
||||||
void sound_stop(int fade)
|
void sound_stop(int fade)
|
||||||
{
|
{
|
||||||
|
|
238
src/sound.cpp
238
src/sound.cpp
|
@ -1,238 +0,0 @@
|
||||||
/************************************************************************
|
|
||||||
* Minetest-c55
|
|
||||||
* Copyright (C) 2012 celeron55, Perttu Ahola <celeron55@gmail.com>
|
|
||||||
*
|
|
||||||
* sound.cpp
|
|
||||||
* voxelands - 3d voxel world sandbox game
|
|
||||||
* Copyright (C) Lisa 'darkrose' Milne 2014 <lisa@ltmnet.com>
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
* See the GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
|
||||||
*
|
|
||||||
* License updated from GPLv2 or later to GPLv3 or later by Lisa Milne
|
|
||||||
* for Voxelands.
|
|
||||||
************************************************************************/
|
|
||||||
|
|
||||||
#include "sound.h"
|
|
||||||
#include "map.h"
|
|
||||||
#include "mapnode.h"
|
|
||||||
#include "content_mapnode.h"
|
|
||||||
#include "content_mob.h"
|
|
||||||
|
|
||||||
// Global DummySoundManager singleton
|
|
||||||
DummySoundManager dummySoundManager;
|
|
||||||
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",0.3);
|
|
||||||
sound->loadSound("dirt-step-right","step_dirt.2.ogg",0.3);
|
|
||||||
// CMT_STONE
|
|
||||||
sound->loadSound("stone-step-left","step_stone.1.ogg");
|
|
||||||
sound->loadSound("stone-step-right","step_stone.2.ogg");
|
|
||||||
sound->loadSound("stone-step-left","step_stone.3.ogg");
|
|
||||||
sound->loadSound("stone-step-right","step_stone.4.ogg");
|
|
||||||
// CMT_PLANT
|
|
||||||
sound->loadSound("plant-step-left","step_plant.1.ogg",0.3);
|
|
||||||
sound->loadSound("plant-step-right","step_plant.2.ogg",0.3);
|
|
||||||
// CMT_LIQUID
|
|
||||||
sound->loadSound("liquid-step-left","step_liquid.1.ogg",0.5);
|
|
||||||
sound->loadSound("liquid-step-right","step_liquid.2.ogg",0.5);
|
|
||||||
// CMT_WOOD
|
|
||||||
sound->loadSound("wood-step-left","step_wood.1.ogg");
|
|
||||||
sound->loadSound("wood-step-right","step_wood.2.ogg");
|
|
||||||
sound->loadSound("wood-step-left","step_wood.3.ogg");
|
|
||||||
sound->loadSound("wood-step-right","step_wood.4.ogg");
|
|
||||||
// CMT_GLASS
|
|
||||||
sound->loadSound("glass-step-left","step_glass.1.ogg",0.3);
|
|
||||||
sound->loadSound("glass-step-right","step_glass.1.ogg",0.3);
|
|
||||||
// special for grass
|
|
||||||
sound->loadSound("grass-step-left","step_grass.1.ogg");
|
|
||||||
sound->loadSound("grass-step-right","step_grass.2.ogg");
|
|
||||||
|
|
||||||
// digging
|
|
||||||
// CMT_DIRT
|
|
||||||
sound->loadSound("dirt-dig","dig_dirt.1.ogg");
|
|
||||||
// CMT_STONE
|
|
||||||
sound->loadSound("stone-dig","dig_stone.1.ogg");
|
|
||||||
// CMT_PLANT
|
|
||||||
sound->loadSound("plant-dig","dig_plant.1.ogg");
|
|
||||||
// CMT_LIQUID
|
|
||||||
sound->loadSound("liquid-dig","dig_liquid.1.ogg");
|
|
||||||
// CMT_WOOD
|
|
||||||
sound->loadSound("wood-dig","dig_wood.1.ogg");
|
|
||||||
// CMT_GLASS
|
|
||||||
sound->loadSound("glass-dig","dig_glass.1.ogg");
|
|
||||||
// mobs
|
|
||||||
sound->loadSound("mob-dig","dig_mob.ogg");
|
|
||||||
// miss
|
|
||||||
sound->loadSound("miss-dig","dig_miss.ogg");
|
|
||||||
|
|
||||||
// placing
|
|
||||||
sound->loadSound("place","place_node.1.ogg");
|
|
||||||
sound->loadSound("place","place_node.2.ogg");
|
|
||||||
sound->loadSound("place","place_node.3.ogg");
|
|
||||||
// CMT_DIRT
|
|
||||||
// CMT_STONE
|
|
||||||
// CMT_PLANT
|
|
||||||
// CMT_LIQUID
|
|
||||||
sound->loadSound("liquid-place","place_liquid.1.ogg");
|
|
||||||
// CMT_WOOD
|
|
||||||
// CMT_GLASS
|
|
||||||
|
|
||||||
// open formspec
|
|
||||||
sound->loadSound("open-menu","open_menu.ogg");
|
|
||||||
sound->loadSound("open-book","open_book.ogg");
|
|
||||||
sound->loadSound("open-chest","open_chest.ogg");
|
|
||||||
|
|
||||||
// environment and node sounds
|
|
||||||
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",0.5);
|
|
||||||
sound->loadSound("env-water","env_water.ogg",0.5);
|
|
||||||
sound->loadSound("env-steam","env_steam.ogg");
|
|
||||||
sound->loadSound("env-tnt","env_tnt.ogg");
|
|
||||||
sound->loadSound("env-teleport","env_teleport.ogg");
|
|
||||||
|
|
||||||
// mobs
|
|
||||||
sound->loadSound("mob-oerkki-spawn","mob_oerkki_spawn.ogg");
|
|
||||||
sound->loadSound("mob-wolf-hit","mob_wolf_hit.ogg");
|
|
||||||
sound->loadSound("mob-wolf-spawn","mob_wolf_spawn.ogg");
|
|
||||||
sound->loadSound("mob-sheep-env","mob_sheep_env.ogg");
|
|
||||||
sound->loadSound("mob-ducksheep-env","mob_ducksheep_env.ogg");
|
|
||||||
sound->loadSound("mob-deer-env","mob_deer_env.ogg");
|
|
||||||
|
|
||||||
// special
|
|
||||||
sound->loadSound("wield","wield_item.ogg");
|
|
||||||
sound->loadSound("low-energy-F","low_energy_F.ogg");
|
|
||||||
sound->loadSound("low-energy-M","low_energy_M.ogg");
|
|
||||||
sound->loadSound("player-hurt-F","player_hurt_F.ogg");
|
|
||||||
sound->loadSound("player-hurt-M","player_hurt_M.ogg");
|
|
||||||
|
|
||||||
// use
|
|
||||||
sound->loadSound("use-eat","use_eat.ogg");
|
|
||||||
sound->loadSound("use-drink","use_drink.ogg");
|
|
||||||
|
|
||||||
// menu backgrounds
|
|
||||||
sound->loadSound("bg-mainmenu","bg_mainmenu.ogg");
|
|
||||||
sound->loadSound("bg-charcreator","bg_charcreator.ogg");
|
|
||||||
}
|
|
||||||
|
|
||||||
void sound_playStep(Map *map, v3f pos, int foot, float gain)
|
|
||||||
{
|
|
||||||
if (!g_sound)
|
|
||||||
return;
|
|
||||||
|
|
||||||
v3s16 p = floatToInt(pos,BS);
|
|
||||||
MapNode n = map->getNodeNoEx(p);
|
|
||||||
ContentFeatures *f = &content_features(n);
|
|
||||||
if (f->type == CMT_AIR) {
|
|
||||||
p.Y--;
|
|
||||||
n = map->getNodeNoEx(p);
|
|
||||||
f = &content_features(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string snd("");
|
|
||||||
|
|
||||||
if (f->sound_step != "") {
|
|
||||||
snd = f->sound_step;
|
|
||||||
}else{
|
|
||||||
switch (f->type) {
|
|
||||||
case CMT_PLANT:
|
|
||||||
snd = "plant-step";
|
|
||||||
break;
|
|
||||||
case CMT_DIRT:
|
|
||||||
snd = "dirt-step";
|
|
||||||
break;
|
|
||||||
case CMT_STONE:
|
|
||||||
snd = "stone-step";
|
|
||||||
break;
|
|
||||||
case CMT_LIQUID:
|
|
||||||
snd = "liquid-step";
|
|
||||||
break;
|
|
||||||
case CMT_TREE:
|
|
||||||
case CMT_WOOD:
|
|
||||||
snd = "wood-step";
|
|
||||||
break;
|
|
||||||
case CMT_GLASS:
|
|
||||||
snd = "glass-step";
|
|
||||||
break;
|
|
||||||
default:;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (snd == "")
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (foot == 0) {
|
|
||||||
snd += "-left";
|
|
||||||
}else{
|
|
||||||
snd += "-right";
|
|
||||||
}
|
|
||||||
|
|
||||||
g_sound->playSoundAt(snd,false,pos,gain);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sound_playDig(content_t c, v3f pos)
|
|
||||||
{
|
|
||||||
if (!g_sound)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (c == CONTENT_IGNORE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ContentFeatures *f = &content_features(c);
|
|
||||||
if (f->sound_dig != "") {
|
|
||||||
g_sound->playSoundAt(f->sound_dig,false,pos);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch (f->type) {
|
|
||||||
case CMT_PLANT:
|
|
||||||
g_sound->playSoundAt("plant-dig",false,pos);
|
|
||||||
break;
|
|
||||||
case CMT_DIRT:
|
|
||||||
g_sound->playSoundAt("dirt-dig",false,pos);
|
|
||||||
break;
|
|
||||||
case CMT_STONE:
|
|
||||||
g_sound->playSoundAt("stone-dig",false,pos);
|
|
||||||
break;
|
|
||||||
case CMT_LIQUID:
|
|
||||||
g_sound->playSoundAt("liquid-dig",false,pos);
|
|
||||||
break;
|
|
||||||
case CMT_TREE:
|
|
||||||
case CMT_WOOD:
|
|
||||||
g_sound->playSoundAt("wood-dig",false,pos);
|
|
||||||
break;
|
|
||||||
case CMT_GLASS:
|
|
||||||
g_sound->playSoundAt("glass-dig",false,pos);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
g_sound->playSoundAt("miss-dig",false,pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef SERVER
|
|
||||||
|
|
||||||
ISoundManager *createSoundManager()
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
16
src/sound.h
16
src/sound.h
|
@ -40,11 +40,12 @@ int sound_load_effect(char* file, char* token);
|
||||||
int sound_load_music(char* file, char* token);
|
int sound_load_music(char* file, char* token);
|
||||||
void sound_free_effect(char* token);
|
void sound_free_effect(char* token);
|
||||||
void sound_free_music(char* token);
|
void sound_free_music(char* token);
|
||||||
uint32_t sound_play_effect(char* token, float volume, v3_t *pos);
|
uint32_t sound_play_effect(char* token, float volume, uint8_t loop, v3_t *pos);
|
||||||
uint32_t sound_play_music(char* token, float volume);
|
uint32_t sound_play_music(char* token, float volume, uint8_t loop);
|
||||||
void sound_stop_effects(int fade);
|
void sound_stop_effects(int fade);
|
||||||
void sound_stop_music(int fade);
|
void sound_stop_music(int fade);
|
||||||
void sound_stop_single(uint32_t id);
|
void sound_stop_single(uint32_t id);
|
||||||
|
int sound_exists(uint32_t id);
|
||||||
void sound_stop(int fade);
|
void sound_stop(int fade);
|
||||||
int sound_master_setter(char* value);
|
int sound_master_setter(char* value);
|
||||||
int sound_effects_setter(char* value);
|
int sound_effects_setter(char* value);
|
||||||
|
@ -64,10 +65,21 @@ int sound_load_ogg(file_t *f, sound_t *e);
|
||||||
/* defined in sound_wav.c */
|
/* defined in sound_wav.c */
|
||||||
int sound_is_wav(file_t *f);
|
int sound_is_wav(file_t *f);
|
||||||
int sound_load_wav(file_t *f, sound_t *e);
|
int sound_load_wav(file_t *f, sound_t *e);
|
||||||
|
|
||||||
|
/* defined in sound_mumble.c */
|
||||||
|
void sound_mumble_init(void);
|
||||||
|
void sound_mumble_step(float dtime, v3_t *pos, v3_t *at, v3_t *up);
|
||||||
#endif
|
#endif
|
||||||
|
int sound_mumble_set_ident(char* id);
|
||||||
|
void sound_mumble_set_context(char* ctx, int len);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
#include "map.h"
|
||||||
|
|
||||||
|
/* defined in sound_util.cpp, currently bridging functions */
|
||||||
|
void sound_play_step(Map *map, v3f pos, int foot, float gain);
|
||||||
|
void sound_play_dig(content_t c, v3f pos);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,184 @@
|
||||||
|
/************************************************************************
|
||||||
|
* sound_mumble.c
|
||||||
|
* voxelands - 3d voxel world sandbox game
|
||||||
|
* Copyright (C) Lisa 'darkrose' Milne 2017 <lisa@ltmnet.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#define _VL_SOUND_EXPOSE_INTERNAL
|
||||||
|
#include "sound.h"
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct linkedmem_s {
|
||||||
|
#ifdef WIN32
|
||||||
|
UINT32 uiVersion;
|
||||||
|
DWORD uiTick;
|
||||||
|
#else
|
||||||
|
uint32_t uiVersion;
|
||||||
|
uint32_t uiTick;
|
||||||
|
#endif
|
||||||
|
float fAvatarPosition[3];
|
||||||
|
float fAvatarFront[3];
|
||||||
|
float fAvatarTop[3];
|
||||||
|
wchar_t name[256];
|
||||||
|
float fCameraPosition[3];
|
||||||
|
float fCameraFront[3];
|
||||||
|
float fCameraTop[3];
|
||||||
|
wchar_t identity[256];
|
||||||
|
#ifdef WIN32
|
||||||
|
UINT32 context_len;
|
||||||
|
#else
|
||||||
|
uint32_t context_len;
|
||||||
|
#endif
|
||||||
|
unsigned char context[256];
|
||||||
|
wchar_t description[2048];
|
||||||
|
} linkedmem_t;
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
float dtime_cumulative;
|
||||||
|
linkedmem_t *link;
|
||||||
|
} mumble_data = {
|
||||||
|
0.0,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
void sound_mumble_init()
|
||||||
|
{
|
||||||
|
#ifdef WIN32
|
||||||
|
HANDLE hMapObject = OpenFileMappingW(FILE_MAP_ALL_ACCESS, FALSE, L"MumbleLink");
|
||||||
|
if (hMapObject == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mumble_data.link = (linkedmem_t*)MapViewOfFile(hMapObject, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(linkedmem_t));
|
||||||
|
if (!mumble_data.link)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CloseHandle(hMapObject);
|
||||||
|
hMapObject = NULL;
|
||||||
|
#else
|
||||||
|
char memname[256];
|
||||||
|
int shmfd = -1;
|
||||||
|
|
||||||
|
snprintf(memname, 256, "/MumbleLink.%d", getuid());
|
||||||
|
|
||||||
|
shmfd = shm_open(memname, O_RDWR, S_IRUSR | S_IWUSR);
|
||||||
|
if (shmfd < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mumble_data.link = (linkedmem_t*)(mmap(NULL, sizeof(linkedmem_t), PROT_READ | PROT_WRITE, MAP_SHARED, shmfd,0));
|
||||||
|
if (mumble_data.link == (void*)(-1)) {
|
||||||
|
mumble_data.link = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
sound_mumble_set_ident("singleplayer");
|
||||||
|
sound_mumble_set_context(NULL,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sound_mumble_set_ident(char* id)
|
||||||
|
{
|
||||||
|
wchar_t ident[256];
|
||||||
|
int wl;
|
||||||
|
int l;
|
||||||
|
if (!mumble_data.link || !id)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
l = strlen(id);
|
||||||
|
if (l>255)
|
||||||
|
l = 255;
|
||||||
|
|
||||||
|
wl = mbstowcs(ident, id, l);
|
||||||
|
if (wl < 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
ident[l] = 0;
|
||||||
|
|
||||||
|
wcsncpy(mumble_data.link->identity, ident, 256);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sound_mumble_set_context(char* ctx, int len)
|
||||||
|
{
|
||||||
|
if (!mumble_data.link)
|
||||||
|
return;
|
||||||
|
/* Context should be equal for players which should be able to
|
||||||
|
* hear each other positional and differ for those who shouldn't
|
||||||
|
* (e.g. it could contain the server+port and team) */
|
||||||
|
if (!ctx || len < 1) {
|
||||||
|
memcpy(mumble_data.link->context, "VoxelandsPlayer", 15);
|
||||||
|
mumble_data.link->context_len = 15;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memcpy(mumble_data.link->context, ctx, len);
|
||||||
|
mumble_data.link->context_len = len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sound_mumble_step(float dtime, v3_t *pos, v3_t *at, v3_t *up)
|
||||||
|
{
|
||||||
|
if (!mumble_data.link)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mumble_data.dtime_cumulative += dtime;
|
||||||
|
|
||||||
|
if (mumble_data.link->uiVersion != 2) {
|
||||||
|
wcsncpy(mumble_data.link->name, L"TestLink", 256);
|
||||||
|
wcsncpy(mumble_data.link->description, L"TestLink is a test of the Link plugin.", 2048);
|
||||||
|
mumble_data.link->uiVersion = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
mumble_data.link->uiTick++;
|
||||||
|
|
||||||
|
/* Position of the avatar */
|
||||||
|
mumble_data.link->fAvatarPosition[0] = pos->x;
|
||||||
|
mumble_data.link->fAvatarPosition[1] = pos->y;
|
||||||
|
mumble_data.link->fAvatarPosition[2] = pos->z;
|
||||||
|
|
||||||
|
/* Unit vector pointing out of the avatar's eyes aka "At"-vector. */
|
||||||
|
mumble_data.link->fAvatarFront[0] = at->x;
|
||||||
|
mumble_data.link->fAvatarFront[1] = at->y;
|
||||||
|
mumble_data.link->fAvatarFront[2] = at->z;
|
||||||
|
|
||||||
|
/* Unit vector pointing out of the top of the avatar's head aka "Up"-vector. */
|
||||||
|
mumble_data.link->fAvatarTop[0] = -up->x;
|
||||||
|
mumble_data.link->fAvatarTop[1] = -up->y;
|
||||||
|
mumble_data.link->fAvatarTop[2] = -up->z;
|
||||||
|
|
||||||
|
/* Same as avatar but for the camera. */
|
||||||
|
mumble_data.link->fCameraPosition[0] = pos->x;
|
||||||
|
mumble_data.link->fCameraPosition[1] = pos->y;
|
||||||
|
mumble_data.link->fCameraPosition[2] = pos->z;
|
||||||
|
|
||||||
|
mumble_data.link->fCameraFront[0] = at->x;
|
||||||
|
mumble_data.link->fCameraFront[1] = at->y;
|
||||||
|
mumble_data.link->fCameraFront[2] = at->z;
|
||||||
|
|
||||||
|
mumble_data.link->fCameraTop[0] = -up->x;
|
||||||
|
mumble_data.link->fCameraTop[1] = -up->y;
|
||||||
|
mumble_data.link->fCameraTop[2] = -up->z;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -1,615 +0,0 @@
|
||||||
/************************************************************************
|
|
||||||
* Minetest-c55
|
|
||||||
* Copyright (C) 2012 celeron55, Perttu Ahola <celeron55@gmail.com>
|
|
||||||
* OpenAL support based on work by:
|
|
||||||
* Copyright (C) 2011 Sebastian 'Bahamada' Rühl
|
|
||||||
* Copyright (C) 2011 Cyriaque 'Cisoun' Skrapits <cysoun@gmail.com>
|
|
||||||
* Copyright (C) 2011 Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
|
|
||||||
*
|
|
||||||
* sound_openal.cpp
|
|
||||||
* voxelands - 3d voxel world sandbox game
|
|
||||||
* Copyright (C) Lisa 'darkrose' Milne 2014 <lisa@ltmnet.com>
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
* See the GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
|
||||||
*
|
|
||||||
* License updated from GPLv2 or later to GPLv3 or later by Lisa Milne
|
|
||||||
* for Voxelands.
|
|
||||||
************************************************************************/
|
|
||||||
|
|
||||||
#ifndef SERVER
|
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
#include "sound_openal.h"
|
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#include <al.h>
|
|
||||||
#include <alc.h>
|
|
||||||
#include <alext.h>
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
#include <OpenAL/al.h>
|
|
||||||
#include <OpenAL/alc.h>
|
|
||||||
#else
|
|
||||||
#include <AL/al.h>
|
|
||||||
#include <AL/alc.h>
|
|
||||||
#include <AL/alext.h>
|
|
||||||
#endif
|
|
||||||
#include <vorbis/vorbisfile.h>
|
|
||||||
#include "log.h"
|
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
|
||||||
#include "utility.h" // myrand()
|
|
||||||
#include "path.h"
|
|
||||||
#include "main.h"
|
|
||||||
|
|
||||||
#define BUFFER_SIZE 30000
|
|
||||||
|
|
||||||
static const char *alcErrorString(ALCenum err)
|
|
||||||
{
|
|
||||||
switch (err) {
|
|
||||||
case ALC_NO_ERROR:
|
|
||||||
return "no error";
|
|
||||||
case ALC_INVALID_DEVICE:
|
|
||||||
return "invalid device";
|
|
||||||
case ALC_INVALID_CONTEXT:
|
|
||||||
return "invalid context";
|
|
||||||
case ALC_INVALID_ENUM:
|
|
||||||
return "invalid enum";
|
|
||||||
case ALC_INVALID_VALUE:
|
|
||||||
return "invalid value";
|
|
||||||
case ALC_OUT_OF_MEMORY:
|
|
||||||
return "out of memory";
|
|
||||||
default:
|
|
||||||
return "<unknown OpenAL error>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *alErrorString(ALenum err)
|
|
||||||
{
|
|
||||||
switch (err) {
|
|
||||||
case AL_NO_ERROR:
|
|
||||||
return "no error";
|
|
||||||
case AL_INVALID_NAME:
|
|
||||||
return "invalid name";
|
|
||||||
case AL_INVALID_ENUM:
|
|
||||||
return "invalid enum";
|
|
||||||
case AL_INVALID_VALUE:
|
|
||||||
return "invalid value";
|
|
||||||
case AL_INVALID_OPERATION:
|
|
||||||
return "invalid operation";
|
|
||||||
case AL_OUT_OF_MEMORY:
|
|
||||||
return "out of memory";
|
|
||||||
default:
|
|
||||||
return "<unknown OpenAL error>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void f3_set(ALfloat *f3, v3f v)
|
|
||||||
{
|
|
||||||
f3[0] = v.X;
|
|
||||||
f3[1] = v.Y;
|
|
||||||
f3[2] = v.Z;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SoundBuffer
|
|
||||||
{
|
|
||||||
ALenum format;
|
|
||||||
ALsizei freq;
|
|
||||||
ALuint buffer_id;
|
|
||||||
std::vector<char> buffer;
|
|
||||||
float gain;
|
|
||||||
};
|
|
||||||
|
|
||||||
SoundBuffer* loadOggFile(const std::string &filepath)
|
|
||||||
{
|
|
||||||
int endian = 0; // 0 for Little-Endian, 1 for Big-Endian
|
|
||||||
int bitStream;
|
|
||||||
long bytes;
|
|
||||||
char array[BUFFER_SIZE]; // Local fixed size array
|
|
||||||
vorbis_info *pInfo;
|
|
||||||
OggVorbis_File oggFile;
|
|
||||||
|
|
||||||
// Try opening the given file
|
|
||||||
if (ov_fopen((char*)filepath.c_str(), &oggFile) != 0) {
|
|
||||||
infostream<<"Audio: Error opening "<<filepath<<" for decoding"<<std::endl;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
SoundBuffer *snd = new SoundBuffer;
|
|
||||||
|
|
||||||
// Get some information about the OGG file
|
|
||||||
pInfo = ov_info(&oggFile, -1);
|
|
||||||
|
|
||||||
// Check the number of channels... always use 16-bit samples
|
|
||||||
if (pInfo->channels == 1) {
|
|
||||||
snd->format = AL_FORMAT_MONO16;
|
|
||||||
}else{
|
|
||||||
snd->format = AL_FORMAT_STEREO16;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The frequency of the sampling rate
|
|
||||||
snd->freq = pInfo->rate;
|
|
||||||
|
|
||||||
// Keep reading until all is read
|
|
||||||
do {
|
|
||||||
// Read up to a buffer's worth of decoded sound data
|
|
||||||
bytes = ov_read(&oggFile, array, BUFFER_SIZE, endian, 2, 1, &bitStream);
|
|
||||||
|
|
||||||
if (bytes < 0) {
|
|
||||||
ov_clear(&oggFile);
|
|
||||||
infostream<<"Audio: Error decoding "<<filepath<<std::endl;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append to end of buffer
|
|
||||||
snd->buffer.insert(snd->buffer.end(), array, array + bytes);
|
|
||||||
} while (bytes > 0);
|
|
||||||
|
|
||||||
alGenBuffers(1, &snd->buffer_id);
|
|
||||||
alBufferData(snd->buffer_id, snd->format,
|
|
||||||
&(snd->buffer[0]), snd->buffer.size(),
|
|
||||||
snd->freq);
|
|
||||||
|
|
||||||
ALenum error = alGetError();
|
|
||||||
|
|
||||||
if (error != AL_NO_ERROR) {
|
|
||||||
infostream<<"Audio: OpenAL error: "<<alErrorString(error)
|
|
||||||
<<"preparing sound buffer"<<std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
infostream<<"Audio file "<<filepath<<" loaded"<<std::endl;
|
|
||||||
|
|
||||||
// Clean up!
|
|
||||||
ov_clear(&oggFile);
|
|
||||||
|
|
||||||
return snd;
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
ALCdevice *m_device;
|
|
||||||
ALCcontext *m_context;
|
|
||||||
bool m_can_vorbis;
|
|
||||||
int m_next_id;
|
|
||||||
int m_music_id;
|
|
||||||
int m_music_last_id;
|
|
||||||
std::map<std::string, std::vector<SoundBuffer*> > m_buffers;
|
|
||||||
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),
|
|
||||||
m_context(NULL),
|
|
||||||
m_can_vorbis(false),
|
|
||||||
m_next_id(1),
|
|
||||||
m_music_id(0),
|
|
||||||
m_music_last_id(0)
|
|
||||||
{
|
|
||||||
ALCenum error = ALC_NO_ERROR;
|
|
||||||
|
|
||||||
infostream<<"Audio: Initializing..."<<std::endl;
|
|
||||||
|
|
||||||
m_mutex.Init();
|
|
||||||
|
|
||||||
m_device = alcOpenDevice(NULL);
|
|
||||||
if (!m_device) {
|
|
||||||
infostream<<"Audio: No audio device available, audio system "
|
|
||||||
<<"not initialized"<<std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (alcIsExtensionPresent(m_device, "EXT_vorbis")) {
|
|
||||||
infostream<<"Audio: Vorbis extension present"<<std::endl;
|
|
||||||
m_can_vorbis = true;
|
|
||||||
}else{
|
|
||||||
infostream<<"Audio: Vorbis extension NOT present"<<std::endl;
|
|
||||||
m_can_vorbis = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_context = alcCreateContext(m_device, NULL);
|
|
||||||
if (!m_context) {
|
|
||||||
error = alcGetError(m_device);
|
|
||||||
infostream<<"Audio: Unable to initialize audio context, "
|
|
||||||
<<"aborting audio initialization ("<<alcErrorString(error)
|
|
||||||
<<")"<<std::endl;
|
|
||||||
alcCloseDevice(m_device);
|
|
||||||
m_device = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
!alcMakeContextCurrent(m_context)
|
|
||||||
|| (error = alcGetError(m_device) != ALC_NO_ERROR)
|
|
||||||
) {
|
|
||||||
infostream<<"Audio: Error setting audio context, aborting audio "
|
|
||||||
<<"initialization ("<<alcErrorString(error)<<")"<<std::endl;
|
|
||||||
alcDestroyContext(m_context);
|
|
||||||
m_context = NULL;
|
|
||||||
alcCloseDevice(m_device);
|
|
||||||
m_device = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
alDistanceModel(AL_EXPONENT_DISTANCE);
|
|
||||||
|
|
||||||
{
|
|
||||||
float volume = config_get_float("client.sound.volume");
|
|
||||||
if (volume < 1.0)
|
|
||||||
return;
|
|
||||||
if (volume > 100.0)
|
|
||||||
volume = 100.0;
|
|
||||||
volume /= 100.0;
|
|
||||||
alListenerf(AL_GAIN, volume);
|
|
||||||
}
|
|
||||||
|
|
||||||
infostream<<"Audio: Initialized: OpenAL "<<alGetString(AL_VERSION)
|
|
||||||
<<", using "<<alcGetString(m_device, ALC_DEVICE_SPECIFIER)
|
|
||||||
<<std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
~OpenALSoundManager()
|
|
||||||
{
|
|
||||||
infostream<<"Audio: Deinitializing..."<<std::endl;
|
|
||||||
g_sound = NULL;
|
|
||||||
// KABOOM!
|
|
||||||
// TODO: Clear SoundBuffers
|
|
||||||
alcMakeContextCurrent(NULL);
|
|
||||||
alcDestroyContext(m_context);
|
|
||||||
m_context = NULL;
|
|
||||||
alcCloseDevice(m_device);
|
|
||||||
m_device = NULL;
|
|
||||||
|
|
||||||
for (std::map<std::string, std::vector<SoundBuffer*> >::iterator i = m_buffers.begin();
|
|
||||||
i != m_buffers.end(); i++) {
|
|
||||||
for (std::vector<SoundBuffer*>::iterator iter = (*i).second.begin();
|
|
||||||
iter != (*i).second.end(); iter++) {
|
|
||||||
delete *iter;
|
|
||||||
}
|
|
||||||
(*i).second.clear();
|
|
||||||
}
|
|
||||||
m_buffers.clear();
|
|
||||||
infostream<<"Audio: Deinitialized."<<std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void addBuffer(const std::string &name, SoundBuffer *buf)
|
|
||||||
{
|
|
||||||
std::map<std::string, std::vector<SoundBuffer*> >::iterator i =
|
|
||||||
m_buffers.find(name);
|
|
||||||
if (i != m_buffers.end()) {
|
|
||||||
i->second.push_back(buf);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::vector<SoundBuffer*> bufs;
|
|
||||||
bufs.push_back(buf);
|
|
||||||
m_buffers[name] = bufs;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SoundBuffer* getBuffer(const std::string &name)
|
|
||||||
{
|
|
||||||
std::map<std::string, std::vector<SoundBuffer*> >::iterator i =
|
|
||||||
m_buffers.find(name);
|
|
||||||
if (i == m_buffers.end())
|
|
||||||
return NULL;
|
|
||||||
std::vector<SoundBuffer*> &bufs = i->second;
|
|
||||||
if (bufs.size() == 1)
|
|
||||||
return bufs[0];
|
|
||||||
int j = myrand_range(0,bufs.size()-1);
|
|
||||||
return bufs[j];
|
|
||||||
}
|
|
||||||
|
|
||||||
PlayingSound* createPlayingSound(SoundBuffer *buf, bool loop)
|
|
||||||
{
|
|
||||||
assert(buf);
|
|
||||||
PlayingSound *sound = new PlayingSound;
|
|
||||||
assert(sound);
|
|
||||||
alGenSources(1, &sound->source_id);
|
|
||||||
alSourcei(sound->source_id, AL_BUFFER, buf->buffer_id);
|
|
||||||
alSourcei(sound->source_id, AL_SOURCE_RELATIVE, true);
|
|
||||||
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);
|
|
||||||
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, bool queue)
|
|
||||||
{
|
|
||||||
assert(buf);
|
|
||||||
if (buf->format != AL_FORMAT_MONO16)
|
|
||||||
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 < 160.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_REFERENCE_DISTANCE, 30.0);
|
|
||||||
alSourcei(sound->source_id, AL_LOOPING, loop ? AL_TRUE : AL_FALSE);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
int playSoundRaw(SoundBuffer *buf, bool loop)
|
|
||||||
{
|
|
||||||
assert(buf);
|
|
||||||
PlayingSound *sound = createPlayingSound(buf, loop);
|
|
||||||
if (!sound)
|
|
||||||
return -1;
|
|
||||||
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, bool queue)
|
|
||||||
{
|
|
||||||
assert(buf);
|
|
||||||
PlayingSound *sound = createPlayingSoundAt(buf, loop, pos, gain, queue);
|
|
||||||
if (!sound)
|
|
||||||
return -1;
|
|
||||||
int id = -1;
|
|
||||||
{
|
|
||||||
JMutexAutoLock lock(m_mutex);
|
|
||||||
id = m_next_id++;
|
|
||||||
m_sounds_playing[id] = sound;
|
|
||||||
}
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
void deleteSound(int id)
|
|
||||||
{
|
|
||||||
std::map<int, PlayingSound*>::iterator i = m_sounds_playing.find(id);
|
|
||||||
if (id == m_music_id)
|
|
||||||
m_music_id = 0;
|
|
||||||
if (id == m_music_last_id)
|
|
||||||
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);
|
|
||||||
std::set<int> del_list;
|
|
||||||
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) {
|
|
||||||
alDeleteSources(1, &sound->source_id);
|
|
||||||
sound->disabled = true;
|
|
||||||
sound->source_id = 0;
|
|
||||||
}else if (distance < 160.0 && sound->disabled) {
|
|
||||||
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
|
|
||||||
ALint state;
|
|
||||||
alGetSourcei(sound->source_id, AL_SOURCE_STATE, &state);
|
|
||||||
if (state != AL_PLAYING) {
|
|
||||||
del_list.insert(id);
|
|
||||||
if (id == m_music_last_id)
|
|
||||||
m_music_last_id = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (id == m_music_last_id) {
|
|
||||||
ALfloat volume;
|
|
||||||
alSourcei(sound->source_id, AL_LOOPING, AL_FALSE);
|
|
||||||
alGetSourcef(sound->source_id, AL_GAIN, &volume);
|
|
||||||
if (dtime > 0.05)
|
|
||||||
dtime = 0.05;
|
|
||||||
while (volume > 1.) {
|
|
||||||
volume /= 10.;
|
|
||||||
}
|
|
||||||
volume -= dtime;
|
|
||||||
if (volume < 0.01) {
|
|
||||||
volume = 0.0;
|
|
||||||
m_music_last_id = 0;
|
|
||||||
sound->should_delete = true;
|
|
||||||
}
|
|
||||||
alSourcef(sound->source_id, AL_GAIN, volume);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (del_list.size() == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (std::set<int>::iterator i = del_list.begin(); i != del_list.end(); i++) {
|
|
||||||
int id = *i;
|
|
||||||
deleteSound(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool loadSound(const std::string &name, const std::string &filepath, float gain)
|
|
||||||
{
|
|
||||||
char buff[1024];
|
|
||||||
if (!path_get((char*)"sound",const_cast<char*>(filepath.c_str()),1,buff,1024))
|
|
||||||
return false;
|
|
||||||
SoundBuffer *buf = loadOggFile(buff);
|
|
||||||
if (buf == NULL)
|
|
||||||
return false;
|
|
||||||
buf->gain = gain;
|
|
||||||
addBuffer(name, buf);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateListener(v3f pos, v3f vel, v3f at, v3f up)
|
|
||||||
{
|
|
||||||
m_listener_pos = pos;
|
|
||||||
alListener3f(AL_POSITION, pos.X, pos.Y, pos.Z);
|
|
||||||
alListener3f(AL_VELOCITY, vel.X, vel.Y, vel.Z);
|
|
||||||
ALfloat f[6];
|
|
||||||
f3_set(f, at);
|
|
||||||
f3_set(f+3, -up);
|
|
||||||
alListenerfv(AL_ORIENTATION, f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setListenerGain(float gain)
|
|
||||||
{
|
|
||||||
alListenerf(AL_GAIN, gain);
|
|
||||||
}
|
|
||||||
|
|
||||||
int playSound(const std::string &name, bool loop)
|
|
||||||
{
|
|
||||||
if (name == "")
|
|
||||||
return 0;
|
|
||||||
SoundBuffer *buf = getBuffer(name);
|
|
||||||
if (!buf) {
|
|
||||||
infostream<<"OpenALSoundManager: \""<<name<<"\" not found."
|
|
||||||
<<std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return playSoundRaw(buf, loop);
|
|
||||||
}
|
|
||||||
int playSoundAt(const std::string &name, bool loop, v3f pos, float gain, bool queue=false)
|
|
||||||
{
|
|
||||||
if (name == "")
|
|
||||||
return 0;
|
|
||||||
SoundBuffer *buf = getBuffer(name);
|
|
||||||
if (!buf) {
|
|
||||||
infostream<<"OpenALSoundManager: \""<<name<<"\" not found."
|
|
||||||
<<std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
if (id == m_music_last_id)
|
|
||||||
m_music_last_id = 0;
|
|
||||||
if (i == m_sounds_playing.end())
|
|
||||||
return;
|
|
||||||
PlayingSound *sound = i->second;
|
|
||||||
sound->should_delete = true;
|
|
||||||
}
|
|
||||||
bool soundExists(int sound)
|
|
||||||
{
|
|
||||||
JMutexAutoLock lock(m_mutex);
|
|
||||||
return (m_sounds_playing.count(sound) != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool playMusic(const std::string &name, bool loop)
|
|
||||||
{
|
|
||||||
stopMusic();
|
|
||||||
|
|
||||||
m_music_id = playSound(name,loop);
|
|
||||||
if (m_music_id > 0)
|
|
||||||
return true;
|
|
||||||
m_music_id = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void stopMusic()
|
|
||||||
{
|
|
||||||
if (m_music_id != 0) {
|
|
||||||
if (m_music_last_id != 0)
|
|
||||||
stopSound(m_music_last_id);
|
|
||||||
m_music_last_id = m_music_id;
|
|
||||||
}
|
|
||||||
m_music_id = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateSoundPosition(int id, v3f pos)
|
|
||||||
{
|
|
||||||
std::map<int, PlayingSound*>::iterator i =
|
|
||||||
m_sounds_playing.find(id);
|
|
||||||
if (i == m_sounds_playing.end())
|
|
||||||
return;
|
|
||||||
PlayingSound *sound = i->second;
|
|
||||||
|
|
||||||
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_REFERENCE_DISTANCE, 30.0);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ISoundManager *createSoundManager()
|
|
||||||
{
|
|
||||||
ISoundManager *sound = new OpenALSoundManager();
|
|
||||||
g_sound = sound;
|
|
||||||
init_sounds(sound);
|
|
||||||
return sound;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,34 +0,0 @@
|
||||||
/************************************************************************
|
|
||||||
* Minetest-c55
|
|
||||||
* Copyright (C) 20102celeron55, Perttu Ahola <celeron55@gmail.com>
|
|
||||||
*
|
|
||||||
* sound_openal.h
|
|
||||||
* voxelands - 3d voxel world sandbox game
|
|
||||||
* Copyright (C) Lisa 'darkrose' Milne 2014 <lisa@ltmnet.com>
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
* See the GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
|
||||||
*
|
|
||||||
* License updated from GPLv2 or later to GPLv3 or later by Lisa Milne
|
|
||||||
* for Voxelands.
|
|
||||||
************************************************************************/
|
|
||||||
|
|
||||||
#ifndef SOUND_OPENAL_HEADER
|
|
||||||
#define SOUND_OPENAL_HEADER
|
|
||||||
|
|
||||||
#include "sound.h"
|
|
||||||
|
|
||||||
ISoundManager *createOpenALSoundManager();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -0,0 +1,121 @@
|
||||||
|
/************************************************************************
|
||||||
|
* sound_util.c
|
||||||
|
* voxelands - 3d voxel world sandbox game
|
||||||
|
* Copyright (C) Lisa 'darkrose' Milne 2017 <lisa@ltmnet.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "sound.h"
|
||||||
|
|
||||||
|
void sound_play_step(Map *map, v3f pos, int foot, float gain)
|
||||||
|
{
|
||||||
|
v3_t vp;
|
||||||
|
v3s16 p = floatToInt(pos,BS);
|
||||||
|
MapNode n = map->getNodeNoEx(p);
|
||||||
|
ContentFeatures *f = &content_features(n);
|
||||||
|
if (f->type == CMT_AIR) {
|
||||||
|
p.Y--;
|
||||||
|
n = map->getNodeNoEx(p);
|
||||||
|
f = &content_features(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string snd("");
|
||||||
|
|
||||||
|
if (f->sound_step != "") {
|
||||||
|
snd = f->sound_step;
|
||||||
|
}else{
|
||||||
|
switch (f->type) {
|
||||||
|
case CMT_PLANT:
|
||||||
|
snd = "plant-step";
|
||||||
|
break;
|
||||||
|
case CMT_DIRT:
|
||||||
|
snd = "dirt-step";
|
||||||
|
break;
|
||||||
|
case CMT_STONE:
|
||||||
|
snd = "stone-step";
|
||||||
|
break;
|
||||||
|
case CMT_LIQUID:
|
||||||
|
snd = "liquid-step";
|
||||||
|
break;
|
||||||
|
case CMT_TREE:
|
||||||
|
case CMT_WOOD:
|
||||||
|
snd = "wood-step";
|
||||||
|
break;
|
||||||
|
case CMT_GLASS:
|
||||||
|
snd = "glass-step";
|
||||||
|
break;
|
||||||
|
default:;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (snd == "")
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (foot == 0) {
|
||||||
|
snd += "-left";
|
||||||
|
}else{
|
||||||
|
snd += "-right";
|
||||||
|
}
|
||||||
|
|
||||||
|
vp.x = pos.X;
|
||||||
|
vp.y = pos.Y;
|
||||||
|
vp.z = pos.Z;
|
||||||
|
|
||||||
|
sound_play_effect((char*)snd.c_str(),1.0,0,&vp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sound_play_dig(content_t c, v3f pos)
|
||||||
|
{
|
||||||
|
v3_t vp;
|
||||||
|
ContentFeatures *f;
|
||||||
|
|
||||||
|
if (c == CONTENT_IGNORE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
vp.x = pos.X;
|
||||||
|
vp.y = pos.Y;
|
||||||
|
vp.z = pos.Z;
|
||||||
|
|
||||||
|
f = &content_features(c);
|
||||||
|
|
||||||
|
if (f->sound_dig != "") {
|
||||||
|
sound_play_effect((char*)f->sound_dig.c_str(),1.0,0,&vp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (f->type) {
|
||||||
|
case CMT_PLANT:
|
||||||
|
sound_play_effect("plant-dig",1.0,0,&vp);
|
||||||
|
break;
|
||||||
|
case CMT_DIRT:
|
||||||
|
sound_play_effect("dirt-dig",1.0,0,&vp);
|
||||||
|
break;
|
||||||
|
case CMT_STONE:
|
||||||
|
sound_play_effect("stone-dig",1.0,0,&vp);
|
||||||
|
break;
|
||||||
|
case CMT_LIQUID:
|
||||||
|
sound_play_effect("liquid-dig",1.0,0,&vp);
|
||||||
|
break;
|
||||||
|
case CMT_TREE:
|
||||||
|
case CMT_WOOD:
|
||||||
|
sound_play_effect("wood-dig",1.0,0,&vp);
|
||||||
|
break;
|
||||||
|
case CMT_GLASS:
|
||||||
|
sound_play_effect("glass-dig",1.0,0,&vp);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sound_play_effect("miss-dig",1.0,0,&vp);
|
||||||
|
}
|
||||||
|
}
|
|
@ -39,6 +39,7 @@
|
||||||
#include "mineral.h" // For texture atlas making
|
#include "mineral.h" // For texture atlas making
|
||||||
#include "path.h"
|
#include "path.h"
|
||||||
#include "base64.h"
|
#include "base64.h"
|
||||||
|
#include "xCGUITTFont.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TextureSource
|
TextureSource
|
||||||
|
@ -1794,7 +1795,8 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
|
||||||
gui::IGUIFont *std_font = skin->getFont();
|
gui::IGUIFont *std_font = skin->getFont();
|
||||||
static gui::IGUIFont *tex_font = NULL;
|
static gui::IGUIFont *tex_font = NULL;
|
||||||
#if USE_FREETYPE
|
#if USE_FREETYPE
|
||||||
tex_font = gui::CGUITTFont::createTTFont(guienv, getPath("font","unifont.ttf",false).c_str(),10);
|
if (path_get("font","unifont.ttf",1,buff,1024))
|
||||||
|
tex_font = gui::CGUITTFont::createTTFont(guienv, buff,10);
|
||||||
#else
|
#else
|
||||||
if (path_get((char*)"texture",(char*)"fontlucida.png",1,buff,1024))
|
if (path_get((char*)"texture",(char*)"fontlucida.png",1,buff,1024))
|
||||||
tex_font = guienv->getFont(buff);
|
tex_font = guienv->getFont(buff);
|
||||||
|
|
Loading…
Reference in New Issue