naev 0.10.4
music.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
11#include "physfsrwops.h"
12#include "SDL.h"
13
14#include "naev.h"
17#include "music.h"
18
19#include "conf.h"
20#include "log.h"
21#include "ndata.h"
22#include "nlua.h"
23#include "nlua_audio.h"
24#include "nlua_tk.h"
25#include "nlua_var.h"
26#include "nluadef.h"
27#include "nstring.h"
28#include "sound.h"
29
30#define MUSIC_SUFFIX ".ogg"
33static double music_vol = 0.;
34static double music_vol_lin = 0.;
35
36/*
37 * Handle if music should run Lua script. Must be locked to ensure same
38 * behaviour always.
39 */
40static int music_runchoose = 0;
42/*
43 * global music lua
44 */
45static nlua_env music_env = LUA_NOREF;
46static int music_lua_update = LUA_NOREF;
47static int music_lua_choose = LUA_NOREF;
48static int music_lua_play = LUA_NOREF;
49static int music_lua_stop = LUA_NOREF;
50static int music_lua_pause = LUA_NOREF;
51static int music_lua_resume = LUA_NOREF;
52static int music_lua_info = LUA_NOREF;
53static int music_lua_volume = LUA_NOREF;
54
55/* functions */
56static int music_runLua( const char *situation );
57
58/*
59 * prototypes
60 */
61/* music stuff */
62static int music_find (void);
63/* Lua stuff */
64static int music_luaInit (void);
65static void music_luaQuit (void);
66
70void music_update( double dt )
71{
73 return;
74
75 /* Run the choose function in Lua. */
76 lua_rawgeti( naevL, LUA_REGISTRYINDEX, music_lua_update );
77 lua_pushnumber( naevL, dt );
78 if (nlua_pcall(music_env, 1, 0)) { /* error has occurred */
79 WARN(_("Error while running music function '%s': %s"), "update", lua_tostring(naevL,-1));
80 lua_pop(naevL,1);
81 }
82}
83
90static int music_runLua( const char *situation )
91{
93 return 0;
94
95 /* Run the choose function in Lua. */
96 lua_rawgeti( naevL, LUA_REGISTRYINDEX, music_lua_choose );
97 if (situation != NULL)
98 lua_pushstring( naevL, situation );
99 else
100 lua_pushnil( naevL );
101 if (nlua_pcall(music_env, 1, 0)) { /* error has occurred */
102 WARN(_("Error while running music function '%s': %s"), "choose", lua_tostring(naevL,-1));
103 lua_pop(naevL,1);
104 return -1;
105 }
106
107 return 0;
108}
109
115int music_init (void)
116{
117 if (music_disabled)
118 return 0;
119
120 /* Load the music. */
121 if (music_find() < 0)
122 return -1;
123
124 /* Start up Lua. */
125 if (music_luaInit() < 0)
126 return -1;
127
128 /* Set the volume. */
129 if ((conf.music > 1.) || (conf.music < 0.))
130 WARN(_("Music has invalid value, clamping to [0:1]."));
131 music_volume( conf.music );
132
133 return 0;
134}
135
139void music_exit (void)
140{
141 if (music_disabled)
142 return;
143
144 /* Clean up Lua. */
146}
147
153static int music_find (void)
154{
155 char** files;
156 int suflen;
157 int nmusic;
158
159 if (music_disabled)
160 return 0;
161
162 /* get the file list */
163 files = PHYSFS_enumerateFiles( MUSIC_PATH );
164
165 /* load the profiles */
166 nmusic = 0;
167 suflen = strlen(MUSIC_SUFFIX);
168 for (size_t i=0; files[i]!=NULL; i++) {
169 int flen = strlen(files[i]);
170 if ((flen > suflen) &&
171 strncmp( &files[i][flen - suflen], MUSIC_SUFFIX, suflen)==0) {
172
173 /* grow the selection size */
174 nmusic++;
175 }
176 }
177
178 DEBUG( n_("Loaded %d Song", "Loaded %d Songs", nmusic ), nmusic );
179
180 /* More clean up. */
181 PHYSFS_freeList(files);
182
183 return 0;
184}
185
192int music_volume( double vol )
193{
194 if (music_disabled)
195 return 0;
196
197 music_vol_lin = vol;
198 if (vol > 0.)
199 music_vol = 1. / pow(2., (1.-vol) * 8. );
200 else
201 music_vol = 0.;
202
203 /* Run the choose function in Lua. */
204 lua_rawgeti( naevL, LUA_REGISTRYINDEX, music_lua_volume );
205 lua_pushnumber( naevL, music_vol );
206 if (nlua_pcall(music_env, 1, 0)) { /* error has occurred */
207 WARN(_("Error while running music function '%s': %s"), "volume", lua_tostring(naevL,-1));
208 lua_pop(naevL,1);
209 return -1;
210 }
211 return 0;
212}
213
219double music_getVolume (void)
220{
221 return music_vol_lin;
222}
223
230{
231 return music_vol;
232}
233
237int music_play( const char *filename )
238{
239 if (music_disabled) return 0;
240
241 /* Run the play function in Lua. */
242 lua_rawgeti( naevL, LUA_REGISTRYINDEX, music_lua_play );
243 if (filename != NULL)
244 lua_pushstring( naevL, filename );
245 else
246 lua_pushnil( naevL );
247 if (nlua_pcall(music_env, 1, 0)) { /* error has occurred */
248 WARN(_("Error while running music function '%s': %s"), "play", lua_tostring(naevL,-1));
249 lua_pop(naevL,1);
250 return -1;
251 }
252 return 0;
253}
254
261int music_stop( int disable )
262{
263 if (music_disabled) return 0;
264
265 /* Run the stop function in Lua. */
266 lua_rawgeti( naevL, LUA_REGISTRYINDEX, music_lua_stop );
267 lua_pushboolean( naevL, disable );
268 if (nlua_pcall(music_env, 1, 0)) { /* error has occurred */
269 WARN(_("Error while running music function '%s': %s"), "stop", lua_tostring(naevL,-1));
270 lua_pop(naevL,1);
271 return -1;
272 }
273 return 0;
274}
275
279int music_pause( int disable )
280{
281 if (music_disabled) return 0;
282
283 /* Run the pause function in Lua. */
284 lua_rawgeti( naevL, LUA_REGISTRYINDEX, music_lua_pause );
285 lua_pushboolean( naevL, disable );
286 if (nlua_pcall(music_env, 1, 0)) { /* error has occurred */
287 WARN(_("Error while running music function '%s': %s"), "pause", lua_tostring(naevL,-1));
288 lua_pop(naevL,1);
289 return -1;
290 }
291 return 0;
292}
293
297int music_resume (void)
298{
299 if (music_disabled) return 0;
300
301 /* Run the resume function in Lua. */
302 lua_rawgeti( naevL, LUA_REGISTRYINDEX, music_lua_resume );
303 if (nlua_pcall(music_env, 0, 0)) { /* error has occurred */
304 WARN(_("Error while running music function '%s': %s"), "resume", lua_tostring(naevL,-1));
305 lua_pop(naevL,1);
306 return -1;
307 }
308 return 0;
309}
310
311static MusicInfo_t minfo;
316{
317 if (minfo.name) {
318 free( minfo.name );
319 minfo.name = NULL;
320 }
321
322 /* Run the info function in Lua. */
323 lua_rawgeti( naevL, LUA_REGISTRYINDEX, music_lua_info );
324 if (nlua_pcall(music_env, 0, 3)) { /* error has occurred */
325 WARN(_("Error while running music function '%s': %s"), "info", lua_tostring(naevL,-1));
326 lua_pop(naevL,1);
327 return NULL;
328 }
329
330 minfo.playing = lua_toboolean(naevL,-3);
331 minfo.name = strdup(luaL_optstring(naevL,-2,""));
332 minfo.pos = luaL_optnumber(naevL,-1,-1);
333
334 lua_pop(naevL,3);
335
336 return &minfo;
337}
338
339/*
340 * music Lua stuff
341 */
347static int music_luaInit (void)
348{
349 char *buf;
350 size_t bufsize;
351
352 if (music_disabled)
353 return 0;
354
355 if (music_env != LUA_NOREF)
357
358 /* Reset the environment. */
359 music_env = nlua_newEnv();
362
363 /* load the actual Lua music code */
364 buf = ndata_read( MUSIC_LUA_PATH, &bufsize );
365 if (nlua_dobufenv(music_env, buf, bufsize, MUSIC_LUA_PATH) != 0) {
366 ERR(_("Error loading music file: %s\n"
367 "%s\n"
368 "Most likely Lua file has improper syntax, please check"),
369 MUSIC_LUA_PATH, lua_tostring(naevL,-1) );
370 return -1;
371 }
372 free(buf);
373
374 /* Set up comfort functions. */
375 music_lua_choose = nlua_refenvtype( music_env, "choose", LUA_TFUNCTION );
376 music_lua_update = nlua_refenvtype( music_env, "update", LUA_TFUNCTION );
377 music_lua_play = nlua_refenvtype( music_env, "play", LUA_TFUNCTION );
378 music_lua_stop = nlua_refenvtype( music_env, "stop", LUA_TFUNCTION );
379 music_lua_pause = nlua_refenvtype( music_env, "pause", LUA_TFUNCTION );
380 music_lua_resume = nlua_refenvtype( music_env, "resume", LUA_TFUNCTION );
381 music_lua_info = nlua_refenvtype( music_env, "info", LUA_TFUNCTION );
382 music_lua_volume = nlua_refenvtype( music_env, "volume", LUA_TFUNCTION );
383
384 return 0;
385}
386
390static void music_luaQuit (void)
391{
392 if (music_disabled)
393 return;
394
395 nlua_freeEnv(music_env);
396 music_env = LUA_NOREF;
397 music_lua_choose = LUA_NOREF;
398 music_lua_update = LUA_NOREF;
399 music_lua_play = LUA_NOREF;
400 music_lua_stop = LUA_NOREF;
401 music_lua_pause = LUA_NOREF;
402 music_lua_resume = LUA_NOREF;
403 music_lua_info = LUA_NOREF;
404 music_lua_volume = LUA_NOREF;
405}
406
413int music_choose( const char* situation )
414{
416 return 0;
417
418 if (music_runLua( situation ))
419 return -1;
420
421 return 0;
422}
423
427void music_rechoose (void)
428{
429 if (music_disabled)
430 return;
431
432 /* Lock so it doesn't run in between an update. */
433 music_runchoose = 1;
434}
MusicInfo_t * music_info(void)
Gets information about the current music state.
Definition: music.c:315
static int music_runchoose
Definition: music.c:40
static int music_find(void)
Internal music loading routines.
Definition: music.c:153
int music_play(const char *filename)
Plays the loaded music.
Definition: music.c:237
int music_disabled
Definition: music.c:32
int music_pause(int disable)
Pauses the music.
Definition: music.c:279
double music_getVolumeLog(void)
Gets the current music volume (logarithmic).
Definition: music.c:229
double music_getVolume(void)
Gets the current music volume (linear).
Definition: music.c:219
int music_choose(const char *situation)
Actually runs the music stuff, based on situation.
Definition: music.c:413
int music_volume(double vol)
Sets the music volume from a linear value.
Definition: music.c:192
int music_stop(int disable)
Stops the loaded music.
Definition: music.c:261
static void music_luaQuit(void)
Quits the music Lua control system.
Definition: music.c:390
#define MUSIC_SUFFIX
Definition: music.c:30
void music_rechoose(void)
Attempts to rechoose the music.
Definition: music.c:427
static int music_luaInit(void)
Initialize the music Lua control system.
Definition: music.c:347
void music_exit(void)
Exits the music subsystem.
Definition: music.c:139
static nlua_env music_env
Definition: music.c:45
void music_update(double dt)
Updates the music.
Definition: music.c:70
int music_init(void)
Initializes the music subsystem.
Definition: music.c:115
static int music_runLua(const char *situation)
Runs the Lua music choose function.
Definition: music.c:90
int music_resume(void)
Resumes the music.
Definition: music.c:297
Header file with generic functions and naev-specifics.
void * ndata_read(const char *path, size_t *filesize)
Reads a file from the ndata (will be NUL terminated).
Definition: ndata.c:154
static char buf[NEWS_MAX_LENGTH]
Definition: news.c:45
int nlua_loadStandard(nlua_env env)
Loads the standard Naev Lua API.
Definition: nlua.c:760
int nlua_refenvtype(nlua_env env, const char *name, int type)
Gets the reference of a global in a lua environment if it matches a type.
Definition: nlua.c:873
int nlua_loadTk(nlua_env env)
Loads the Toolkit Lua library.
Definition: nlua_tk.c:90
int sound_disabled
Definition: sound.c:133
double music
Definition: conf.h:109