sound pt2

master
darkrose 2017-06-22 18:28:24 +10:00
parent 81cf0e0719
commit 3099caf133
21 changed files with 441 additions and 943 deletions

View File

@ -16,9 +16,11 @@ endif(GETTEXT_FOUND)
# user visible option to enable/disable audio
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
set(USE_AUDIO 0)
set(USE_MUMBLE 0)
set(SOUND_PROBLEM 0)
if(ENABLE_AUDIO AND BUILD_CLIENT)
@ -39,6 +41,14 @@ if(ENABLE_AUDIO AND BUILD_CLIENT)
set(USE_AUDIO 1)
message(STATUS "Sound enabled")
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)
if(SOUND_PROBLEM)
@ -46,7 +56,11 @@ if(SOUND_PROBLEM)
"To continue, either fill in the required paths or disable sound. (-DENABLE_AUDIO=0)")
endif()
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
${OPENAL_INCLUDE_DIR}
${VORBIS_INCLUDE_DIR}
@ -321,6 +335,7 @@ if(BUILD_CLIENT)
${SQLITE3_LIBRARY}
${PLATFORM_LIBS}
${CLIENT_PLATFORM_LIBS}
${MUMBLE_LIBS}
)
if(USE_FREETYPE)
if(FREETYPE_PKGCONFIG_FOUND)

View File

@ -1632,7 +1632,7 @@ void Client::useItem()
if ((w&CONTENT_CRAFTITEM_MASK) == CONTENT_CRAFTITEM_MASK)
snd = content_craftitem_features(w)->sound_use;
if (snd != "")
sound_play_effect(snd.c_str(),1.0,NULL);
sound_play_effect((char*)snd.c_str(),1.0,0,NULL);
}
#endif
}
@ -2287,7 +2287,7 @@ float Client::getRTT(void)
// foot: 0 = left, 1 = right
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)
@ -2300,7 +2300,7 @@ void Client::playDigSound(content_t c)
if (c == CONTENT_IGNORE)
c = CONTENT_AIR;
//sound_playDig(c,m_env.getLocalPlayer()->getPosition());
sound_play_dig(c,m_env.getLocalPlayer()->getPosition());
}
void Client::playPlaceSound(content_t c)
@ -2310,27 +2310,25 @@ void Client::playPlaceSound(content_t c)
ContentFeatures *f = &content_features(c);
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;
}
switch (f->type) {
case CMT_LIQUID:
sound_play_effect("liquid-place",1.0,NULL);
sound_play_effect("liquid-place",1.0,0,NULL);
break;
default:
sound_play_effect("place",1.0,NULL);
sound_play_effect("place",1.0,0,NULL);
}
}
void Client::playSound(std::string &name, bool loop)
{
/* TODO: looping */
sound_play_effect((char*)name.c_str(),1.0,NULL);
sound_play_effect((char*)name.c_str(),1.0,loop,NULL);
}
void Client::playSoundAt(std::string &name, v3f pos, bool loop)
{
v3_t p = {pos.X,pos.Y,pos.Z};
/* TODO: looping */
sound_play_effect((char*)name.c_str(),1.0,&p);
sound_play_effect((char*)name.c_str(),1.0,loop,&p);
}

View File

@ -1,4 +1,4 @@
// Filled in by the build system
/* Filled in by the build system */
#ifndef CMAKE_CONFIG_H
#define CMAKE_CONFIG_H
@ -7,6 +7,7 @@
#define INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@"
#define VERSION_STRING "@VERSION_STRING@"
#define USE_AUDIO @USE_AUDIO@
#define USE_MUMBLE @USE_MUMBLE@
#define USE_FREETYPE @USE_FREETYPE@
#define USE_GETTEXT @USE_GETTEXT@
#ifdef NDEBUG

View File

@ -27,6 +27,17 @@ extern "C" {
#undef _DEFAULT_SOURCE
#endif
#define _DEFAULT_SOURCE
#else
#ifdef _WIN32
#ifndef WIN32
#define WIN32
#endif
#include <windows.h>
#endif
#endif
#include <stdlib.h>
@ -35,6 +46,8 @@ extern "C" {
#include "array.h"
#include "file.h"
#include "config.h"
#ifndef _HAVE_V3_TYPE
#define _HAVE_V3_TYPE
typedef struct v3_s {

View File

@ -7,29 +7,27 @@
#define CONFIG_H
#ifdef USE_CMAKE_CONFIG_H
#include "cmake_config.h"
#include "cmake_config.h"
#else
#define PROJECT_NAME "voxelands"
//#define INSTALL_PREFIX ""
#define VERSION_STRING "unknown"
#ifdef NDEBUG
#define BUILD_TYPE "Release"
#else
#define BUILD_TYPE "Debug"
#endif
#ifdef RUN_IN_PLACE
#define RUN_IN_PLACE_BOOLSTRING "1"
#else
#define RUN_IN_PLACE_BOOLSTRING "0"
#endif
#if USE_GETTEXT
#define USE_GETTEXT_BOOLSTRING "1"
#else
#define USE_GETTEXT_BOOLSTRING "0"
#endif
#define PROJECT_NAME "voxelands"
#define VERSION_STRING "unknown"
#ifdef NDEBUG
#define BUILD_TYPE "Release"
#else
#define BUILD_TYPE "Debug"
#endif
#if USE_GETTEXT
#define USE_GETTEXT_BOOLSTRING "1"
#else
#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
#define BUILD_INFO "NON-CMAKE RUN_IN_PLACE=" RUN_IN_PLACE_BOOLSTRING " USE_GETTEXT=" USE_GETTEXT_BOOLSTRING " BUILD_TYPE=" BUILD_TYPE
#endif
#endif

View File

@ -59,6 +59,10 @@ void config_default_init()
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.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.texture.animations","true",NULL);

View File

@ -272,7 +272,7 @@ void MobCAO::step(float dtime, ClientEnvironment *env)
/* roughly sort of when a step sound should probably be heard, maybe */
if (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;
}
}

View File

@ -1503,7 +1503,7 @@ void the_game(
std::string gender = f.next(":");
std::string snd("player-hurt-");
snd += gender;
sound_play_effect((char*)snd.c_str(),1.0,NULL);
sound_play_effect((char*)snd.c_str(),1.0,0,NULL);
}
#endif
}else if (event.type == CE_PLAYER_FORCE_MOVE) {

View File

@ -32,6 +32,7 @@
#include <IGUIListBox.h>
#include <IGUIFont.h>
#include <IGUIScrollBar.h>
#include "intlGUIEditBox.h"
#include "gui_colours.h"
#include "http.h"

View File

@ -1103,7 +1103,7 @@ int main(int argc, char *argv[])
infostream<<"Created main menu"<<std::endl;
#if USE_AUDIO == 1
sound_play_music("bg-mainmenu",1.0);
sound_play_music("bg-mainmenu",1.0,1);
#endif
while (device->run() && kill == false) {
@ -1208,7 +1208,7 @@ int main(int argc, char *argv[])
menu->allowFocusRemoval(true);
#if USE_AUDIO == 1
sound_play_music("bg-charcreator",1.0);
sound_play_music("bg-charcreator",1.0,1);
#endif
while (device->run() && kill == false) {
@ -1253,6 +1253,9 @@ int main(int argc, char *argv[])
password,
error_message
);
#if USE_AUDIO == 1
sound_stop_effects(0);
#endif
} //try
catch(con::PeerNotFoundException &e)

View File

@ -24,6 +24,8 @@
************************************************************************/
#include "mapblock.h"
#include "config.h"
#include "map.h"
// For g_settings
#include "main.h"

View File

@ -25,11 +25,13 @@
#include "common.h"
#include "config.h"
#include "mapblock_mesh.h"
#include "light.h"
#include "mapblock.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_nodemeta.h"
#include "profiler.h"
@ -536,10 +538,10 @@ void MapBlockMesh::generate(MeshMakeData *data, v3s16 camera_offset, JMutex *mut
if (snd != "") {
bool add_sound = true;
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;
}else{
g_sound->stopSound(i->second.id);
sound_stop_single(i->second.id);
}
}
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) {
v3f pf = intToFloat(p+data->m_blockpos_nodes,BS);
v3_t vp = {pf.X,pf.Y,pf.Z};
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;
if (bsnd.id > 0)
(*data->m_sounds)[p] = bsnd;
}
}else if (i != data->m_sounds->end()) {
g_sound->stopSound(i->second.id);
sound_stop_single(i->second.id);
data->m_sounds->erase(i);
}
}

View File

@ -760,12 +760,12 @@ void RemotePlayer::move(f32 dtime, Map &map, f32 pos_max_d)
int frame = m_node->getFrameNr();
/* roughly sort of when a step sound should probably be heard, maybe */
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;
}
/* roughly sort of when a dig sound should probably be heard, maybe */
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) {
@ -1233,8 +1233,7 @@ void LocalPlayer::applyControl(float dtime)
std::string snd("low-energy-");
snd += gender;
/* TODO: looping */
m_low_energy_effect = sound_play_effect(snd.c_str(),1.0,NULL);
m_low_energy_effect = sound_play_effect((char*)snd.c_str(),1.0,1,NULL);
}
#endif
}else if (m_energy > 9.8) {

View File

@ -87,6 +87,11 @@ int sound_init()
alDistanceModel(AL_EXPONENT_DISTANCE);
alListenerf(AL_GAIN, 1.0);
#if USE_MUMBLE == 1
if (config_get_bool("client.sound.mumble"))
sound_mumble_init();
#endif
sound_data.init = 1;
/* 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);
if (pos) {
alListenerfv(AL_POSITION, (float*)pos);
alListener3f(AL_POSITION, pos->x,pos->y,pos->z);
}else{
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) {
orientation[3] = up->x;
orientation[4] = up->y;
orientation[5] = up->z;
orientation[3] = -up->x;
orientation[4] = -up->y;
orientation[5] = -up->z;
}
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 */
@ -458,7 +468,7 @@ void sound_free_music(char* token)
}
/* 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_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);
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);
alSourcePlay(i->id);
@ -510,7 +524,7 @@ uint32_t sound_play_effect(char* token, float volume, v3_t *pos)
}
/* 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;
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);
alSource3f(sound_data.music.playing->id, AL_POSITION, 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);
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 */
void sound_stop(int fade)
{

View File

@ -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

View File

@ -40,11 +40,12 @@ int sound_load_effect(char* file, char* token);
int sound_load_music(char* file, char* token);
void sound_free_effect(char* token);
void sound_free_music(char* token);
uint32_t sound_play_effect(char* token, float volume, v3_t *pos);
uint32_t sound_play_music(char* token, float volume);
uint32_t sound_play_effect(char* token, float volume, uint8_t loop, v3_t *pos);
uint32_t sound_play_music(char* token, float volume, uint8_t loop);
void sound_stop_effects(int fade);
void sound_stop_music(int fade);
void sound_stop_single(uint32_t id);
int sound_exists(uint32_t id);
void sound_stop(int fade);
int sound_master_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 */
int sound_is_wav(file_t *f);
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
int sound_mumble_set_ident(char* id);
void sound_mumble_set_context(char* ctx, int len);
#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

184
src/sound_mumble.c Normal file
View File

@ -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;
}

View File

@ -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

View File

@ -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

121
src/sound_util.cpp Normal file
View File

@ -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);
}
}

View File

@ -39,6 +39,7 @@
#include "mineral.h" // For texture atlas making
#include "path.h"
#include "base64.h"
#include "xCGUITTFont.h"
/*
TextureSource
@ -1794,7 +1795,8 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
gui::IGUIFont *std_font = skin->getFont();
static gui::IGUIFont *tex_font = NULL;
#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
if (path_get((char*)"texture",(char*)"fontlucida.png",1,buff,1024))
tex_font = guienv->getFont(buff);