The Battle for Wesnoth  1.17.0-dev
lua_audio.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2017 - 2021
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #include "lua_audio.hpp"
16 
17 #include "log.hpp"
18 #include "lua/lua.h"
19 #include "lua/lauxlib.h"
20 #include "scripting/lua_common.hpp"
21 #include "scripting/push_check.hpp"
22 #include "sound.hpp"
23 #include "sound_music_track.hpp"
24 #include "preferences/general.hpp"
25 #include "resources.hpp"
26 #include "soundsource.hpp"
27 #include <set>
28 
29 static lg::log_domain log_audio("audio");
30 #define DBG_AUDIO LOG_STREAM(debug, log_audio)
31 #define LOG_AUDIO LOG_STREAM(info, log_audio)
32 #define ERR_AUDIO LOG_STREAM(err, log_audio)
33 
34 static const char* Track = "music track";
35 static const char* Source = "sound source";
36 
38  std::shared_ptr<sound::music_track> track;
39 public:
40  explicit lua_music_track(int i) : track(sound::get_track(i)) {}
41  explicit lua_music_track(std::shared_ptr<sound::music_track> new_track) : track(new_track) {}
42  bool valid() const {
43  return track && track->valid();
44  }
46  return *track;
47  }
48  const sound::music_track& operator*() const {
49  return *track;
50  }
51  std::shared_ptr<sound::music_track> operator->() {
52  return track;
53  }
54  std::shared_ptr<const sound::music_track> operator->() const {
55  return track;
56  }
57 };
58 
60  lua_music_track* trk = new(L) lua_music_track(i);
62  return trk;
63 }
64 
65 static lua_music_track* push_track(lua_State* L, std::shared_ptr<sound::music_track> new_track) {
66  lua_music_track* trk = new(L) lua_music_track(new_track);
68  return trk;
69 }
70 
72  return static_cast<lua_music_track*>(luaL_checkudata(L, i, Track));
73 }
74 
77 public:
78  explicit lua_sound_source(const soundsource::sourcespec& spec) : spec(spec) {}
81  return spec;
82  }
84  return spec;
85  }
87  return &spec;
88  }
90  return &spec;
91  }
92 };
93 
95  lua_sound_source* src = new(L) lua_sound_source(spec);
97  return *src;
98 }
99 
101  return *static_cast<lua_sound_source*>(luaL_checkudata(L, i, Source));
102 }
103 
104 /**
105  * Destroys a lua_music_track object before it is collected (__gc metamethod).
106  */
108 {
109  lua_music_track* u = get_track(L, 1);
110  u->lua_music_track::~lua_music_track();
111  return 0;
112 }
113 
114 static int impl_music_get(lua_State* L) {
115  if(lua_isnumber(L, 2)) {
116  push_track(L, lua_tointeger(L, 2) - 1);
117  return 1;
118  }
119  const char* m = luaL_checkstring(L, 2);
120 
121  if(strcmp(m, "current") == 0) {
123  return 1;
124  }
125 
126  if(strcmp(m, "previous") == 0) {
128  return 1;
129  }
130 
131  if(strcmp(m, "current_i") == 0) {
132  auto current_index = sound::get_current_track_index();
133  if(current_index) {
134  lua_pushinteger(L, *current_index + 1);
135  } else {
136  lua_pushnil(L);
137  }
138  return 1;
139  }
140  if(strcmp(m, "all") == 0) {
141  config playlist;
143  const auto& range = playlist.child_range("music");
144  std::vector<config> tracks(range.begin(), range.end());
145  lua_push(L, tracks);
146  return 1;
147  }
148  // This calculation reverses the one used in [volume] to get back the relative volume level.
149  // (Which is the same calculation that's duplicated in impl_music_set.)
151  return luaW_getmetafield(L, 1, m);
152 }
153 
154 static int impl_music_set(lua_State* L) {
155  if(lua_isnumber(L, 2)) {
156  unsigned int i = lua_tointeger(L, 2) - 1;
157  config cfg;
158  if(lua_isnil(L, 3)) {
159  if(i < sound::get_num_tracks()) {
161  }
162  } else if(luaW_toconfig(L, 3, cfg)) {
163  // Don't clear the playlist
164  cfg["append"] = true;
165  // Don't allow play_once=yes
166  if(cfg["play_once"]) {
167  return luaL_argerror(L, 3, "For play_once, use wesnoth.music_list.play instead");
168  }
169  if(i >= sound::get_num_tracks()) {
171  } else {
172  // Remove the track at that index and add the new one in its place
173  // It's a little inefficient though...
175  sound::play_music_config(cfg, false, i);
176  }
177  } else {
178  lua_music_track& track = *get_track(L, 3);
179  if(i < sound::get_num_tracks()) {
180  sound::set_track(i, track.operator->());
181  } else {
182  track->write(cfg, true);
184  }
185  }
186  return 0;
187  }
188  const char* m = luaL_checkstring(L, 2);
190  modify_int_attrib_check_range("current_i", sound::play_track(value - 1), 1, static_cast<int>(sound::get_num_tracks()));
191  return 0;
192 }
193 
194 static int impl_music_len(lua_State* L) {
196  return 1;
197 }
198 
199 static int intf_music_play(lua_State* L) {
201  return 0;
202 }
203 
205  std::size_t n = sound::get_num_tracks();
206  if(n > 0) {
208  }
209  return 0;
210 }
211 
212 static int intf_music_add(lua_State* L) {
213  int index = -1;
214  if(lua_isinteger(L, 1)) {
215  index = lua_tointeger(L, 1);
216  lua_remove(L, 1);
217  }
218  config cfg = config {
219  "name", luaL_checkstring(L, 1),
220  "append", true,
221  };
222  bool found_ms_before = false, found_ms_after = false, found_imm = false;
223  for(int i = 2; i <= lua_gettop(L); i++) {
224  if(lua_isboolean(L, i)) {
225  if(found_imm) {
226  return luaL_argerror(L, i, "only one boolean argument may be passed");
227  } else {
228  cfg["immediate"] = luaW_toboolean(L, i);
229  }
230  } else if(lua_isnumber(L, i)) {
231  if(found_ms_after) {
232  return luaL_argerror(L, i, "only two integer arguments may be passed");
233  } else if(found_ms_before) {
234  cfg["ms_after"] = lua_tointeger(L, i);
235  found_ms_after = true;
236  } else {
237  cfg["ms_before"] = lua_tointeger(L, i);
238  found_ms_before = true;
239  }
240  } else {
241  return luaL_argerror(L, i, "unrecognized argument");
242  }
243  }
244  sound::play_music_config(cfg, false, index);
245  return 0;
246 }
247 
250  return 0;
251 }
252 
253 static int intf_music_remove(lua_State* L) {
254  // Use a non-standard comparator to ensure iteration in descending order
255  std::set<int, std::greater<int>> to_remove;
256  for(int i = 1; i <= lua_gettop(L); i++) {
257  to_remove.insert(luaL_checkinteger(L, i));
258  }
259  for(int i : to_remove) {
261  }
262  return 0;
263 }
264 
267  return 0;
268 }
269 
270 static int impl_track_get(lua_State* L) {
272  if(track == nullptr) {
273  return luaL_error(L, "Error: Attempted to access an invalid music track.\n");
274  }
275  const char* m = luaL_checkstring(L, 2);
276  return_bool_attrib("valid", track->valid());
277  if(!track->valid()) {
278  return luaL_error(L, "Tried to access member of track that is no longer valid.");
279  }
280  return_bool_attrib("append", (*track)->append());
281  return_bool_attrib("shuffle", (*track)->shuffle());
282  return_bool_attrib("immediate", (*track)->immediate());
283  return_bool_attrib("once", (*track)->play_once());
284  return_int_attrib("ms_before", (*track)->ms_before());
285  return_int_attrib("ms_after", (*track)->ms_after());
286  return_string_attrib("name", (*track)->id());
287  return_string_attrib("title", (*track)->title());
288 
289  return_cfg_attrib("__cfg",
290  cfg["append"]=(*track)->append();
291  cfg["shuffle"]=(*track)->shuffle();
292  cfg["immediate"]=(*track)->immediate();
293  cfg["once"]=(*track)->play_once();
294  cfg["ms_before"]=(*track)->ms_before();
295  cfg["ms_after"]=(*track)->ms_after();
296  cfg["name"]=(*track)->id();
297  cfg["title"]=(*track)->title());
298 
299  return luaW_getmetafield(L, 1, m);
300 }
301 
302 static int impl_track_set(lua_State* L) {
304  if(track == nullptr || !track->valid()) {
305  return luaL_error(L, "Error: Attempted to access an invalid music track.\n");
306  }
307  const char* m = luaL_checkstring(L, 2);
308  modify_bool_attrib("shuffle", (*track)->set_shuffle(value));
309  modify_bool_attrib("once", (*track)->set_play_once(value));
310  modify_int_attrib("ms_before", (*track)->set_ms_before(value));
311  modify_int_attrib("ms_after", (*track)->set_ms_after(value));
312  modify_string_attrib("title", (*track)->set_title(value));
313  return 0;
314 }
315 
316 static int impl_track_eq(lua_State* L) {
317  lua_music_track* a = get_track(L, 1);
318  lua_music_track* b = get_track(L, 2);
319  if(!a || !b) {
320  // This implies that one argument is not a music track, though I suspect this is dead code...?
321  // Does Lua ever call this if the arguments are not of the same type?
322  lua_pushboolean(L, false);
323  return 1;
324  }
325  if(!a->valid() && !b->valid()) {
326  lua_pushboolean(L, true);
327  return 1;
328  }
329  if(a->valid() && b->valid()) {
330  lua_music_track& lhs = *a;
331  lua_music_track& rhs = *b;
332  lua_pushboolean(L, lhs->id() == rhs->id() && lhs->shuffle() == rhs->shuffle() && lhs->play_once() == rhs->play_once() && lhs->ms_before() == rhs->ms_before() && lhs->ms_after() == rhs->ms_after());
333  return 1;
334  }
335  lua_pushboolean(L, false);
336  return 1;
337 }
338 
339 /**
340  * Get an existing sound source
341  * Key: The sound source ID
342  */
343 static int impl_sndsrc_get(lua_State* L) {
345  return 0;
346  }
347  std::string id = luaL_checkstring(L, 2);
349  return 0;
350  }
352  return 1;
353 }
354 
355 /**
356  * Adds or removes a sound source by its ID
357  * Key: sound source ID
358  * Value: Table containing keyword arguments, existing sound source userdata, or nil to delete
359  */
360 static int impl_sndsrc_set(lua_State* L) {
362  return 0;
363  }
364  std::string id = luaL_checkstring(L, 2);
365  config cfg;
366  if(lua_isnil(L, 3)) {
368  } else if(luaW_toconfig(L, 3, cfg)) {
369  cfg["id"] = id;
370  soundsource::sourcespec spec(cfg);
373  } else {
374  auto& src = get_source(L, 3);
377  }
378  return 0;
379 }
381 {
382  lua_sound_source& u = get_source(L, 1);
383  u.lua_sound_source::~lua_sound_source();
384  return 0;
385 }
386 
387 static int impl_source_get(lua_State* L) {
388  lua_sound_source& src = get_source(L, 1);
389  const char* m = luaL_checkstring(L, 2);
390  return_string_attrib("id", src->id());
392  return_int_attrib("delay", src->minimum_delay());
393  return_int_attrib("chance", src->chance());
394  return_int_attrib("loop", src->loops());
395  return_int_attrib("range", src->full_range());
396  return_int_attrib("fade_range", src->fade_range());
397  return_bool_attrib("check_fogged", src->check_fogged());
398  return_bool_attrib("check_shrouded", src->check_shrouded());
399  return_cfg_attrib("__cfg", src->write(cfg));
400 
401  if(strcmp(m, "locations") == 0) {
402  const auto& locs = src->get_locations();
403  lua_createtable(L, locs.size(), 0);
404  for(const auto& loc : locs) {
405  luaW_pushlocation(L, loc);
406  lua_rawseti(L, -1, lua_rawlen(L, -2) + 1);
407  }
408  }
409 
410  return luaW_getmetafield(L, 1, m);
411 }
412 
413 static int impl_source_set(lua_State* L) {
414  lua_sound_source& src = get_source(L, 1);
415  const char* m = luaL_checkstring(L, 2);
416  modify_int_attrib("delay", src->set_minimum_delay(value));
417  modify_int_attrib("chance", src->set_chance(value));
418  modify_int_attrib("loop", src->set_loops(value));
419  modify_int_attrib("range", src->set_full_range(value));
420  modify_int_attrib("fade_range", src->set_fade_range(value));
421  modify_bool_attrib("check_fogged", src->set_check_fogged(value));
422  modify_bool_attrib("check_shrouded", src->set_check_shrouded(value));
423 
424  if(strcmp(m, "sounds") == 0) {
425  std::string files;
426  if(lua_istable(L, 3)) {
427  files = utils::join(lua_check<std::vector<std::string>>(L, 3));
428  } else {
429  files = luaL_checkstring(L, 3);
430  }
431  src->set_files(files);
432  }
433 
434  if(strcmp(m, "locations") == 0) {
435  std::vector<map_location> locs;
436  locs.resize(1);
437  if(luaW_tolocation(L, 3, locs[0])) {
438 
439  } else {
440  locs.clear();
441  for(lua_pushnil(L); lua_next(L, 3); lua_pop(L, 1)) {
442  locs.push_back(luaW_checklocation(L, -1));
443  }
444  }
445  src->set_locations(locs);
446  }
447 
448  // Now apply the change
451  return 0;
452 }
453 
454 static int impl_source_eq(lua_State* L) {
455  lua_sound_source& a = get_source(L, 1);
456  lua_sound_source& b = get_source(L, 2);
457  if(a->id() != b->id()) {
458  lua_pushboolean(L, false);
459  return 1;
460  }
461  lua_pushboolean(L,
462  a->files() == b->files() &&
463  a->minimum_delay() == b->minimum_delay() &&
464  a->chance() == b->chance() &&
465  a->loops() == b->loops() &&
466  a->full_range() == b->full_range() &&
467  a->fade_range() == b->fade_range() &&
468  a->check_fogged() == b->check_fogged() &&
469  a->check_shrouded() == b->check_shrouded() &&
470  std::set<map_location>(a->get_locations().begin(), a->get_locations().end()) == std::set<map_location>(b->get_locations().begin(), b->get_locations().end())
471  );
472  return 1;
473 }
474 
475 /**
476  * Gets the current sound volume
477  * - Return: Current volume
478  */
479 static int impl_audio_get(lua_State* L)
480 {
481  std::string m = luaL_checkstring(L, 2);
482  if(m != "volume") return 0;
483  int vol = preferences::sound_volume();
484  lua_pushnumber(L, sound::get_sound_volume() * 100.0 / vol);
485  return 1;
486 }
487 
488 /**
489  * Sets the current sound volume
490  * - Arg: New volume to set
491  */
492 static int impl_audio_set(lua_State* L)
493 {
494  std::string m = luaL_checkstring(L, 2);
495  if(m != "volume") {
496  lua_rawset(L, 1);
497  return 0;
498  }
499  int vol = preferences::sound_volume();
500  float rel = lua_tonumber(L, 2);
501  if(rel < 0.0f || rel > 100.0f) {
502  return luaL_argerror(L, 1, "volume must be in range 0..100");
503  }
504  vol = static_cast<int>(rel*vol / 100.0f);
506  return 0;
507 }
508 
509 namespace lua_audio {
510  std::string register_table(lua_State* L) {
511  // Metatable to enable the volume attribute
512  luaW_getglobal(L, "wesnoth", "audio");
513  lua_createtable(L, 0, 2);
514  static luaL_Reg vol_callbacks[] {
515  { "__index", impl_audio_get },
516  { "__newindex", impl_audio_set },
517  { nullptr, nullptr },
518  };
519  luaL_setfuncs(L, vol_callbacks, 0);
520  lua_setmetatable(L, -2);
521 
522  // The music playlist metatable
523  lua_newuserdatauv(L, 0, 0);
524  lua_createtable(L, 0, 10);
525  static luaL_Reg pl_callbacks[] {
526  { "__index", impl_music_get },
527  { "__newindex", impl_music_set },
528  { "__len", impl_music_len },
529  { "play", intf_music_play },
530  { "add", intf_music_add },
531  { "clear", intf_music_clear },
532  { "remove", intf_music_remove },
533  { "next", intf_music_next },
534  { "force_refresh", intf_music_commit },
535  { nullptr, nullptr },
536  };
537  luaL_setfuncs(L, pl_callbacks, 0);
538  lua_pushstring(L, "music playlist");
539  lua_setfield(L, -2, "__metatable");
540  lua_setmetatable(L, -2);
541  lua_setfield(L, -2, "music_list");
542 
543  // The sound source map metatable
544  lua_newuserdatauv(L, 0, 0);
545  lua_createtable(L, 0, 3);
546  static luaL_Reg slm_callbacks[] {
547  { "__index", impl_sndsrc_get },
548  { "__newindex", impl_sndsrc_set },
549  { nullptr, nullptr },
550  };
551  luaL_setfuncs(L, slm_callbacks, 0);
552  lua_pushstring(L, "sound source map");
553  lua_setfield(L, -2, "__metatable");
554  lua_setmetatable(L, -2);
555  lua_setfield(L, -2, "sources");
556  lua_pop(L, 1);
557 
558  // The music track metatable
560  static luaL_Reg track_callbacks[] {
561  {"__gc", impl_track_collect},
562  { "__index", impl_track_get },
563  { "__newindex", impl_track_set },
564  { "__eq", impl_track_eq },
565  { nullptr, nullptr },
566  };
567  luaL_setfuncs(L, track_callbacks, 0);
568  lua_pushstring(L, Track);
569  lua_setfield(L, -2, "__metatable");
570  lua_pop(L, 1);
571 
572  // The sound source metatable
574  static luaL_Reg source_callbacks[] {
575  {"__gc", impl_source_collect},
576  { "__index", impl_source_get },
577  { "__newindex", impl_source_set },
578  { "__eq", impl_source_eq },
579  { nullptr, nullptr },
580  };
581  luaL_setfuncs(L, source_callbacks, 0);
583  lua_setfield(L, -2, "__metatable");
584 
585  return "Adding music playlist table...\n";
586  }
587 }
void empty_playlist()
Definition: sound.cpp:612
std::decay_t< T > lua_check(lua_State *L, int n)
Definition: push_check.hpp:371
#define modify_bool_attrib(name, accessor)
Definition: lua_common.hpp:404
void write(config &cfg) const
Serializes information into cfg as a new (appended) child of key "sound_source".
LUALIB_API void * luaL_checkudata(lua_State *L, int ud, const char *tname)
Definition: lauxlib.cpp:345
unsigned int get_num_tracks()
Definition: sound.cpp:221
LUA_API void lua_createtable(lua_State *L, int narray, int nrec)
Definition: lapi.cpp:728
static int impl_source_eq(lua_State *L)
Definition: lua_audio.cpp:454
static int impl_sndsrc_set(lua_State *L)
Adds or removes a sound source by its ID Key: sound source ID Value: Table containing keyword argumen...
Definition: lua_audio.cpp:360
sound::music_track & operator*()
Definition: lua_audio.cpp:45
std::string join(const T &v, const std::string &s=",")
Generates a new string joining container items in a list.
std::shared_ptr< music_track > get_current_track()
Definition: sound.cpp:208
LUA_API void lua_pushboolean(lua_State *L, int b)
Definition: lapi.cpp:581
static int impl_audio_get(lua_State *L)
Gets the current sound volume.
Definition: lua_audio.cpp:479
static int intf_music_commit(lua_State *)
Definition: lua_audio.cpp:265
bool contains(const pane::item &item, const std::string &tag, const text_box &text_box)
A filter testing whether a search string is used in a text.
Definition: filter.hpp:64
static lua_music_track * get_track(lua_State *L, int i)
Definition: lua_audio.cpp:71
#define a
static lg::log_domain log_audio("audio")
LUA_API void lua_rawseti(lua_State *L, int idx, lua_Integer n)
Definition: lapi.cpp:889
LUA_API int lua_gettop(lua_State *L)
Definition: lapi.cpp:168
child_itors child_range(config_key_type key)
Definition: config.cpp:344
static lua_sound_source & push_source(lua_State *L, const soundsource::sourcespec &spec)
Definition: lua_audio.cpp:94
void remove_track(unsigned int i)
Definition: sound.cpp:246
#define lua_remove(L, idx)
Definition: lua.h:391
std::shared_ptr< sound::music_track > track
Definition: lua_audio.cpp:38
#define return_string_attrib(name, accessor)
Definition: lua_common.hpp:256
#define lua_tointeger(L, i)
Definition: lua.h:362
static int impl_sndsrc_get(lua_State *L)
Get an existing sound source Key: The sound source ID.
Definition: lua_audio.cpp:343
static int impl_source_collect(lua_State *L)
Definition: lua_audio.cpp:380
std::shared_ptr< music_track > get_previous_music_track()
Definition: sound.cpp:212
void set_fade_range(int value)
static int impl_track_collect(lua_State *L)
Destroys a lua_music_track object before it is collected (__gc metamethod).
Definition: lua_audio.cpp:107
#define lua_tonumber(L, i)
Definition: lua.h:361
void remove(const std::string &id)
Definition: soundsource.cpp:66
Audio output for sound and music.
Definition: sound.cpp:41
void play_music_once(const std::string &file)
Definition: sound.cpp:603
#define return_vector_string_attrib(name, accessor)
Definition: lua_common.hpp:319
LUALIB_API void luaL_setmetatable(lua_State *L, const char *tname)
Definition: lauxlib.cpp:324
void lua_push(lua_State *L, const T &val)
Definition: push_check.hpp:385
void set_minimum_delay(int value)
void write_music_play_list(config &snapshot)
Definition: sound.cpp:852
map_location luaW_checklocation(lua_State *L, int index)
Converts an optional table or pair of integers to a map location object.
Definition: lua_common.cpp:775
soundsource::sourcespec * operator->()
Definition: lua_audio.cpp:86
#define modify_float_attrib_check_range(name, accessor, allowed_min, allowed_max)
Definition: lua_common.hpp:392
const std::vector< map_location > & get_locations() const
static int intf_music_play(lua_State *L)
Definition: lua_audio.cpp:199
#define lua_pop(L, n)
Definition: lua.h:364
const std::string & id() const
static int impl_music_set(lua_State *L)
Definition: lua_audio.cpp:154
#define b
bool valid() const
Definition: lua_audio.cpp:42
static int impl_music_len(lua_State *L)
Definition: lua_audio.cpp:194
static const char * Track
Definition: lua_audio.cpp:34
static int intf_music_add(lua_State *L)
Definition: lua_audio.cpp:212
static int intf_music_next(lua_State *)
Definition: lua_audio.cpp:204
LUALIB_API int luaL_argerror(lua_State *L, int arg, const char *extramsg)
Definition: lauxlib.cpp:175
#define modify_string_attrib(name, accessor)
Definition: lua_common.hpp:347
#define return_int_attrib(name, accessor)
Definition: lua_common.hpp:267
bool luaW_getglobal(lua_State *L, const std::vector< std::string > &path)
Pushes the value found by following the variadic names (char *), if the value is not nil...
Definition: lua_common.cpp:953
bool luaW_toboolean(lua_State *L, int n)
Definition: lua_common.cpp:972
static lua_music_track * push_track(lua_State *L, int i)
Definition: lua_audio.cpp:59
void set_full_range(int value)
bool check_shrouded() const
LUA_API void * lua_newuserdatauv(lua_State *L, size_t size, int nuvalue)
Definition: lapi.cpp:1311
std::shared_ptr< sound::music_track > operator->()
Definition: lua_audio.cpp:51
static int impl_track_eq(lua_State *L)
Definition: lua_audio.cpp:316
#define modify_int_attrib_check_range(name, accessor, allowed_min, allowed_max)
Definition: lua_common.hpp:369
static int impl_source_set(lua_State *L)
Definition: lua_audio.cpp:413
static int impl_audio_set(lua_State *L)
Sets the current sound volume.
Definition: lua_audio.cpp:492
LUA_API int lua_setmetatable(lua_State *L, int objindex)
Definition: lapi.cpp:901
const std::string & files() const
void set_loops(int value)
static const char * Source
Definition: lua_audio.cpp:35
int get_sound_volume()
Definition: sound.cpp:1079
void set_sound_volume(int vol)
Definition: sound.cpp:1088
LUA_API void lua_pushnil(lua_State *L)
Definition: lapi.cpp:473
LUA_API void lua_pushnumber(lua_State *L, lua_Number n)
Definition: lapi.cpp:481
void set_music_volume(int vol)
Definition: sound.cpp:1068
void set_check_shrouded(bool value)
#define lua_isboolean(L, n)
Definition: lua.h:376
bool luaW_toconfig(lua_State *L, int index, config &cfg)
Converts an optional table or vconfig to a config object.
Definition: lua_common.cpp:824
#define return_cfg_attrib(name, accessor)
Definition: lua_common.hpp:297
LUALIB_API int luaL_newmetatable(lua_State *L, const char *tname)
Definition: lauxlib.cpp:311
Sound source info class.
std::string id
Text to match against addon_info.tags()
Definition: manager.cpp:215
#define lua_isnil(L, n)
Definition: lua.h:375
std::size_t i
Definition: function.cpp:967
soundsource::manager * soundsources
Definition: resources.cpp:28
LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int arg)
Definition: lauxlib.cpp:442
LUA_API void lua_rawset(lua_State *L, int idx)
Definition: lapi.cpp:877
void add(const sourcespec &source)
Definition: soundsource.cpp:51
lua_music_track(std::shared_ptr< sound::music_track > new_track)
Definition: lua_audio.cpp:41
Internal representation of music tracks.
static int intf_music_remove(lua_State *L)
Definition: lua_audio.cpp:253
std::string register_table(lua_State *L)
Definition: lua_audio.cpp:510
static int impl_track_get(lua_State *L)
Definition: lua_audio.cpp:270
std::size_t index(const std::string &str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
Definition: unicode.cpp:72
LUA_API int lua_isinteger(lua_State *L, int idx)
Definition: lapi.cpp:279
LUA_API int lua_isnumber(lua_State *L, int idx)
Definition: lapi.cpp:285
int get_music_volume()
Definition: sound.cpp:1059
void set_files(const std::string &f)
LUALIB_API int luaL_error(lua_State *L, const char *fmt,...)
Definition: lauxlib.cpp:234
static int impl_music_get(lua_State *L)
Definition: lua_audio.cpp:114
void set_chance(int value)
const soundsource::sourcespec * operator->() const
Definition: lua_audio.cpp:89
LUA_API lua_Unsigned lua_rawlen(lua_State *L, int idx)
Definition: lapi.cpp:402
#define return_bool_attrib(name, accessor)
Definition: lua_common.hpp:287
int sound_volume()
Definition: general.cpp:580
bool luaW_getmetafield(lua_State *L, int idx, const char *key)
Like luaL_getmetafield, but returns false if key is an empty string or begins with two underscores...
Definition: lua_common.cpp:516
#define f
#define lua_istable(L, n)
Definition: lua.h:373
std::vector< std::string > split(const config_attribute_value &val)
void play_music_config(const config &music_node, bool allow_interrupt_current_track, int i)
Definition: sound.cpp:705
static int impl_source_get(lua_State *L)
Definition: lua_audio.cpp:387
std::optional< unsigned int > get_current_track_index()
Definition: sound.cpp:201
void luaW_pushlocation(lua_State *L, const map_location &ml)
Converts a map location object to a Lua table pushed at the top of the stack.
Definition: lua_common.cpp:715
#define return_float_attrib(name, accessor)
Definition: lua_common.hpp:277
const soundsource::sourcespec & operator*() const
Definition: lua_audio.cpp:83
Standard logging facilities (interface).
lua_sound_source(const soundsource::sourcespec &spec)
Definition: lua_audio.cpp:78
std::shared_ptr< const sound::music_track > operator->() const
Definition: lua_audio.cpp:54
soundsource::sourcespec spec
Definition: lua_audio.cpp:76
void commit_music_changes()
Definition: sound.cpp:823
void set_track(unsigned int i, const std::shared_ptr< music_track > &to)
Definition: sound.cpp:239
static int intf_music_clear(lua_State *)
Definition: lua_audio.cpp:248
LUALIB_API void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup)
Definition: lauxlib.cpp:904
const sound::music_track & operator*() const
Definition: lua_audio.cpp:48
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:61
void play_track(unsigned int i)
Definition: sound.cpp:629
void set_check_fogged(bool value)
static int impl_track_set(lua_State *L)
Definition: lua_audio.cpp:302
static map_location::DIRECTION n
LUA_API void lua_pushinteger(lua_State *L, lua_Integer n)
Definition: lapi.cpp:489
LUA_API const char * lua_pushstring(lua_State *L, const char *s)
Definition: lapi.cpp:514
LUA_API void lua_setfield(lua_State *L, int idx, const char *k)
Definition: lapi.cpp:837
LUA_API int lua_next(lua_State *L, int idx)
Definition: lapi.cpp:1220
soundsource::sourcespec & operator*()
Definition: lua_audio.cpp:80
lua_music_track(int i)
Definition: lua_audio.cpp:40
bool luaW_tolocation(lua_State *L, int index, map_location &loc)
Converts an optional table or pair of integers to a map location object.
Definition: lua_common.cpp:726
int music_volume()
Definition: general.cpp:565
#define modify_int_attrib(name, accessor)
Definition: lua_common.hpp:358
static lua_sound_source & get_source(lua_State *L, int i)
Definition: lua_audio.cpp:100
void set_locations(const std::vector< map_location > &locs)
#define luaL_checkstring(L, n)
Definition: lauxlib.h:138