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
|
||||
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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
13
src/common.h
13
src/common.h
|
@ -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 {
|
||||
|
|
38
src/config.h
38
src/config.h
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <IGUIListBox.h>
|
||||
#include <IGUIFont.h>
|
||||
#include <IGUIScrollBar.h>
|
||||
#include "intlGUIEditBox.h"
|
||||
#include "gui_colours.h"
|
||||
#include "http.h"
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
************************************************************************/
|
||||
|
||||
#include "mapblock.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "map.h"
|
||||
// For g_settings
|
||||
#include "main.h"
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
41
src/sound.c
41
src/sound.c
|
@ -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);
|
||||
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);
|
||||
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)
|
||||
{
|
||||
|
|
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);
|
||||
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
|
||||
|
|
|
@ -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 "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);
|
||||
|
|
Loading…
Reference in New Issue