diff --git a/changelog b/changelog index c8043f02349..09443b804c2 100644 --- a/changelog +++ b/changelog @@ -30,10 +30,12 @@ Version 1.13.7+dev: * wesnoth.music_list.add appends a track to the playlist (as [music]append=yes) * wesnoth.music_list.clear clears the current playlist * wesnoth.music_list.force_refresh forces any pending playlist changes to be immediately applied + * wesnoth.music_list.volume attribute gets/sets the current music volume, as [volume]music= * Each track has modifiable shuffle, once, ms_before, ms_after attributes and read-only append, immediate, name, title attributes. They are also comparable with == or ~= * wesnoth.set_music is now deprecated, in favour of the above new API + * New wesnoth.sound_volume function gets/sets the current sound volume, as [volume]sound= * Multiplayer: * Fixed statistics being lost when reloading an MP game. * Performance: @@ -62,6 +64,7 @@ Version 1.13.7+dev: * New [change_theme] tag to change the theme mid-scenario * New [zoom] tag allows changing the zoom level from an event * [kill]animate=yes now plays victory animations if applicable + * Fix [volume] not accepting 100% as the new volume. Version 1.13.7: * AI: diff --git a/data/lua/wml-tags.lua b/data/lua/wml-tags.lua index 0961694de8c..14f2388ee3f 100644 --- a/data/lua/wml-tags.lua +++ b/data/lua/wml-tags.lua @@ -286,6 +286,17 @@ function wml_actions.music(cfg) end end +function wml_actions.volume(cfg) + if cfg.music then + local rel = tonumber(cfg.music) or 100.0 + wesnoth.music_list.volume = rel + end + if cfg.sound then + local rel = tonumber(cfg.sound) or 100.0 + wesnoth.sound_volume(rel) + end +end + -- This is mainly for use in unit test macros, but maybe it can be useful elsewhere too function wml_actions.test_condition(cfg) local logger = cfg.logger or "warning" diff --git a/src/game_events/action_wml.cpp b/src/game_events/action_wml.cpp index 73733f56207..a2b599e5eaa 100644 --- a/src/game_events/action_wml.cpp +++ b/src/game_events/action_wml.cpp @@ -929,34 +929,6 @@ WML_HANDLER_FUNCTION(unit,, cfg) } -WML_HANDLER_FUNCTION(volume,, cfg) -{ - - int vol; - float rel; - std::string music = cfg["music"]; - std::string sound = cfg["sound"]; - - if(!music.empty()) { - vol = preferences::music_volume(); - rel = atof(music.c_str()); - if (rel >= 0.0f && rel < 100.0f) { - vol = static_cast(rel*vol/100.0f); - } - sound::set_music_volume(vol); - } - - if(!sound.empty()) { - vol = preferences::sound_volume(); - rel = atof(sound.c_str()); - if (rel >= 0.0f && rel < 100.0f) { - vol = static_cast(rel*vol/100.0f); - } - sound::set_sound_volume(vol); - } - -} - WML_HANDLER_FUNCTION(on_undo, event_info, cfg) { if(cfg["delayed_variable_substitution"].to_bool(false)) { diff --git a/src/scripting/game_lua_kernel.cpp b/src/scripting/game_lua_kernel.cpp index 38a203b336c..ec2f63826b7 100644 --- a/src/scripting/game_lua_kernel.cpp +++ b/src/scripting/game_lua_kernel.cpp @@ -2538,6 +2538,26 @@ int game_lua_kernel::intf_play_sound(lua_State *L) return 0; } +/** + * Gets/sets the current sound volume + * - Arg 1: (optional) New volume to set + * - Return: Original volume + */ +static int intf_sound_volume(lua_State* L) +{ + int vol = preferences::sound_volume(); + lua_pushnumber(L, sound::get_sound_volume() * 100.0f / vol); + if(lua_isnumber(L, 1)) { + float rel = lua_tonumber(L, 1); + if(rel < 0.0f || rel > 100.0f) { + return luaL_argerror(L, 1, "volume must be in range 0..100"); + } + vol = static_cast(rel*vol / 100.0f); + sound::set_sound_volume(vol); + } + return 1; +} + /** * Scrolls to given tile. * - Arg 1: location. @@ -3943,6 +3963,7 @@ game_lua_kernel::game_lua_kernel(game_state & gs, play_controller & pc, reports { "modify_ai", &intf_modify_ai_old }, { "remove_modifications", &intf_remove_modifications }, { "set_music", &intf_set_music }, + { "sound_volume", &intf_sound_volume }, { "transform_unit", &intf_transform_unit }, { "unit_defense", &intf_unit_defense }, { "unit_movement_cost", &intf_unit_movement_cost }, diff --git a/src/scripting/lua_audio.cpp b/src/scripting/lua_audio.cpp index 40c26fe15a5..5015af80158 100644 --- a/src/scripting/lua_audio.cpp +++ b/src/scripting/lua_audio.cpp @@ -19,6 +19,7 @@ See the COPYING file for more details. #include "sound.hpp" #include "sound_music_track.hpp" #include "config_assign.hpp" +#include "preferences.hpp" static const char* Track = "music track"; @@ -71,6 +72,9 @@ static int impl_music_get(lua_State* L) { } return 1; } + // This calculation reverses the one used in [volume] to get back the relative volume level. + // (Which is the same calculation that's duplicated in impl_music_set.) + return_float_attrib("volume", sound::get_music_volume() * 100.0f / preferences::music_volume()); return luaW_getmetafield(L, 1, m); } @@ -80,6 +84,8 @@ static int impl_music_set(lua_State* L) { sound::set_track(lua_tointeger(L, 2), *track); return 0; } + const char* m = luaL_checkstring(L, 2); + modify_float_attrib_check_range("volume", sound::set_music_volume(value * preferences::music_volume() / 100.0f), 0.0, 100.0); // TODO: Set "current" and "current_i" return 0; } diff --git a/src/sound.cpp b/src/sound.cpp index 030f5d4b255..bd3d9b0199f 100644 --- a/src/sound.cpp +++ b/src/sound.cpp @@ -896,6 +896,14 @@ void play_UI_sound(const std::string& files) } } +int get_music_volume() +{ + if(mix_ok) { + return Mix_VolumeMusic(-1); + } + return 0; +} + void set_music_volume(int vol) { if(mix_ok && vol >= 0) { @@ -906,6 +914,15 @@ void set_music_volume(int vol) } } +int get_sound_volume() +{ + if(mix_ok) { + // Since set_sound_volume sets all main channels to the same, just return the volume of any main channel + return Mix_Volume(source_channel_start, -1); + } + return 0; +} + void set_sound_volume(int vol) { if(mix_ok && vol >= 0) { diff --git a/src/sound.hpp b/src/sound.hpp index a89f62de9f3..e2aad87e38a 100644 --- a/src/sound.hpp +++ b/src/sound.hpp @@ -96,6 +96,8 @@ public: // Save music playlist for snapshot void write_music_play_list(config& snapshot); +int get_music_volume(); +int get_sound_volume(); void set_music_volume(int vol); void set_sound_volume(int vol); void set_bell_volume(int vol);