A few more improvements to the music API

- Handle all plausible cases of assigning into the playlist
- Allow changing the current track to an existing one on the playlist
- Allow getting playlist as a real array instead of an array-like proxy
  (Could be useful for storing it to a WML variable, for example)
This commit is contained in:
Celtic Minstrel 2017-04-29 00:01:40 -04:00
parent c04456dec1
commit a694201c02
4 changed files with 53 additions and 10 deletions

View file

@ -26,9 +26,12 @@ Version 1.13.7+dev:
* #wesnoth.music_list counts the number of tracks on the playlist
* wesnoth.music_list.current returns mutable information about the currently-playing track
* wesnoth.music_list.current_i returns the index of the current track on the list
It is writeable, allowing you to switch to any track on the list. This respects fade values.
* wesnoth.music_list.all returns a copy of the playlist that can be stored in a variable.
* wesnoth.music_list.play plays a specific track (as [music]play_once=yes)
* 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.next fades out the current track and moves to a new track on the 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

View file

@ -16,6 +16,7 @@ See the COPYING file for more details.
#include "lua/lua.h"
#include "lua/lauxlib.h"
#include "scripting/lua_common.hpp"
#include "scripting/push_check.hpp"
#include "sound.hpp"
#include "sound_music_track.hpp"
#include "config_assign.hpp"
@ -74,6 +75,14 @@ static int impl_music_get(lua_State* L) {
}
return 1;
}
if(strcmp(m, "all") == 0) {
config playlist;
sound::write_music_play_list(playlist);
const auto& range = playlist.child_range("music");
std::vector<config> tracks(range.begin(), range.end());
lua_push(L, tracks);
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());
@ -82,28 +91,39 @@ static int impl_music_get(lua_State* L) {
static int impl_music_set(lua_State* L) {
if(lua_isnumber(L, 2)) {
int i = lua_tointeger(L, 2) - 1;
unsigned int i = lua_tointeger(L, 2) - 1;
config cfg;
if(lua_isnil(L, 3)) {
sound::remove_track(i);
if(i < sound::get_num_tracks()) {
sound::remove_track(i);
}
} else if(luaW_toconfig(L, 3, cfg)) {
// Don't allow play_once=yes
if(cfg["play_once"]) {
return luaL_argerror(L, 3, "For play_once, use wesnoth.music_list.play instead");
}
// Remove the track at that index and add the new one in its place
// It's a little inefficient though...
sound::remove_track(i);
sound::play_music_config(cfg, i);
if(i < sound::get_num_tracks()) {
sound::play_music_config(cfg);
} else {
// Remove the track at that index and add the new one in its place
// It's a little inefficient though...
sound::remove_track(i);
sound::play_music_config(cfg, i);
}
} else {
music_track& track = *get_track(L, 3);
sound::set_track(i, track.operator->());
if(i < sound::get_num_tracks()) {
sound::set_track(i, track.operator->());
} else {
track->write(cfg, true);
sound::play_music_config(cfg);
}
}
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"
modify_int_attrib_check_range("current_i", sound::play_track(value - 1), 1, static_cast<int>(sound::get_num_tracks()));
return 0;
}
@ -117,6 +137,14 @@ static int intf_music_play(lua_State* L) {
return 0;
}
static int intf_music_next(lua_State* L) {
size_t n = sound::get_num_tracks();
if(n > 0) {
sound::play_track(n);
}
return 0;
}
static int intf_music_add(lua_State* L) {
int i = -1;
if(lua_isinteger(L, 1)) {
@ -239,6 +267,7 @@ namespace lua_audio {
{ "add", intf_music_add },
{ "clear", intf_music_clear },
{ "remove", intf_music_remove },
{ "next", intf_music_next },
{ "force_refresh", intf_music_commit },
{ nullptr, nullptr },
};

View file

@ -288,9 +288,9 @@ static std::shared_ptr<sound::music_track> choose_track()
current_track_index = track;
}
//LOG_AUDIO << "Next track will be " << current_track_list[track].file_path() << "\n";
DBG_AUDIO << "Next track will be " << current_track_list[current_track_index]->file_path() << "\n";
played_before.push_back( current_track_list[current_track_index]->file_path() );
return current_track_list[current_track_index++];
return current_track_list[current_track_index];
}
static std::string pick_one(const std::string &files)
@ -524,6 +524,16 @@ void play_music()
fadingout_time = current_track->ms_after();
}
void play_track(unsigned int i) {
if(i >= current_track_list.size()) {
current_track = choose_track();
} else {
current_track_index = i;
current_track = current_track_list[i];
}
play_music();
}
static void play_new_music()
{
music_start_time = 0; //reset status: no start time

View file

@ -106,6 +106,7 @@ void set_UI_volume(int vol);
unsigned int get_current_track();
unsigned int get_num_tracks();
void remove_track(unsigned int i);
void play_track(unsigned int i);
}