naev 0.11.5
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 music_find();
122
123 /* Start up Lua. */
124 if (music_luaInit() < 0)
125 return -1;
126
127 /* Set the volume. */
128 if ((conf.music > 1.) || (conf.music < 0.))
129 WARN(_("Music has invalid value, clamping to [0:1]."));
130 music_volume( conf.music );
131
132 return 0;
133}
134
138void music_exit (void)
139{
140 if (music_disabled)
141 return;
142
143 /* Clean up Lua. */
145}
146
152static int music_find (void)
153{
154 char** files;
155 int suflen;
156 int nmusic;
157
158 if (music_disabled)
159 return 0;
160
161 /* get the file list */
162 files = PHYSFS_enumerateFiles( MUSIC_PATH );
163
164 /* load the profiles */
165 nmusic = 0;
166 suflen = strlen(MUSIC_SUFFIX);
167 for (size_t i=0; files[i]!=NULL; i++) {
168 int flen = strlen(files[i]);
169 if ((flen > suflen) &&
170 strncmp( &files[i][flen - suflen], MUSIC_SUFFIX, suflen)==0) {
171
172 /* grow the selection size */
173 nmusic++;
174 }
175 }
176
177 DEBUG( n_("Loaded %d Song", "Loaded %d Songs", nmusic ), nmusic );
178
179 /* More clean up. */
180 PHYSFS_freeList(files);
181
182 return 0;
183}
184
191int music_volume( double vol )
192{
193 if (music_disabled)
194 return 0;
195
196 music_vol_lin = vol;
197 if (vol > 0.)
198 music_vol = 1. / pow(2., (1.-vol) * 8. );
199 else
200 music_vol = 0.;
201
202 /* Run the choose function in Lua. */
203 lua_rawgeti( naevL, LUA_REGISTRYINDEX, music_lua_volume );
204 lua_pushnumber( naevL, music_vol );
205 if (nlua_pcall(music_env, 1, 0)) { /* error has occurred */
206 WARN(_("Error while running music function '%s': %s"), "volume", lua_tostring(naevL,-1));
207 lua_pop(naevL,1);
208 return -1;
209 }
210 return 0;
211}
212
218double music_getVolume (void)
219{
220 return music_vol_lin;
221}
222
229{
230 return music_vol;
231}
232
236int music_play( const char *filename )
237{
238 if (music_disabled) return 0;
239
240 /* Run the play function in Lua. */
241 lua_rawgeti( naevL, LUA_REGISTRYINDEX, music_lua_play );
242 if (filename != NULL)
243 lua_pushstring( naevL, filename );
244 else
245 lua_pushnil( naevL );
246 if (nlua_pcall(music_env, 1, 0)) { /* error has occurred */
247 WARN(_("Error while running music function '%s': %s"), "play", lua_tostring(naevL,-1));
248 lua_pop(naevL,1);
249 return -1;
250 }
251 return 0;
252}
253
260int music_stop( int disable )
261{
262 if (music_disabled) return 0;
263
264 /* Run the stop function in Lua. */
265 lua_rawgeti( naevL, LUA_REGISTRYINDEX, music_lua_stop );
266 lua_pushboolean( naevL, disable );
267 if (nlua_pcall(music_env, 1, 0)) { /* error has occurred */
268 WARN(_("Error while running music function '%s': %s"), "stop", lua_tostring(naevL,-1));
269 lua_pop(naevL,1);
270 return -1;
271 }
272 return 0;
273}
274
278int music_pause( int disable )
279{
280 if (music_disabled) return 0;
281
282 /* Run the pause function in Lua. */
283 lua_rawgeti( naevL, LUA_REGISTRYINDEX, music_lua_pause );
284 lua_pushboolean( naevL, disable );
285 if (nlua_pcall(music_env, 1, 0)) { /* error has occurred */
286 WARN(_("Error while running music function '%s': %s"), "pause", lua_tostring(naevL,-1));
287 lua_pop(naevL,1);
288 return -1;
289 }
290 return 0;
291}
292
296int music_resume (void)
297{
298 if (music_disabled) return 0;
299
300 /* Run the resume function in Lua. */
301 lua_rawgeti( naevL, LUA_REGISTRYINDEX, music_lua_resume );
302 if (nlua_pcall(music_env, 0, 0)) { /* error has occurred */
303 WARN(_("Error while running music function '%s': %s"), "resume", lua_tostring(naevL,-1));
304 lua_pop(naevL,1);
305 return -1;
306 }
307 return 0;
308}
309
310static MusicInfo_t minfo;
315{
316 if (minfo.name) {
317 free( minfo.name );
318 minfo.name = NULL;
319 }
320
321 /* Run the info function in Lua. */
322 lua_rawgeti( naevL, LUA_REGISTRYINDEX, music_lua_info );
323 if (nlua_pcall(music_env, 0, 3)) { /* error has occurred */
324 WARN(_("Error while running music function '%s': %s"), "info", lua_tostring(naevL,-1));
325 lua_pop(naevL,1);
326 return NULL;
327 }
328
329 minfo.playing = lua_toboolean(naevL,-3);
330 minfo.name = strdup(luaL_optstring(naevL,-2,""));
331 minfo.pos = luaL_optnumber(naevL,-1,-1);
332
333 lua_pop(naevL,3);
334
335 return &minfo;
336}
337
338/*
339 * music Lua stuff
340 */
346static int music_luaInit (void)
347{
348 char *buf;
349 size_t bufsize;
350
351 if (music_disabled)
352 return 0;
353
354 if (music_env != LUA_NOREF)
356
357 /* Reset the environment. */
358 music_env = nlua_newEnv();
361
362 /* load the actual Lua music code */
363 buf = ndata_read( MUSIC_LUA_PATH, &bufsize );
364 if (nlua_dobufenv(music_env, buf, bufsize, MUSIC_LUA_PATH) != 0) {
365 ERR(_("Error loading music file: %s\n"
366 "%s\n"
367 "Most likely Lua file has improper syntax, please check"),
368 MUSIC_LUA_PATH, lua_tostring(naevL,-1) );
369 return -1;
370 }
371 free(buf);
372
373 /* Set up comfort functions. */
374 music_lua_choose = nlua_refenvtype( music_env, "choose", LUA_TFUNCTION );
375 music_lua_update = nlua_refenvtype( music_env, "update", LUA_TFUNCTION );
376 music_lua_play = nlua_refenvtype( music_env, "play", LUA_TFUNCTION );
377 music_lua_stop = nlua_refenvtype( music_env, "stop", LUA_TFUNCTION );
378 music_lua_pause = nlua_refenvtype( music_env, "pause", LUA_TFUNCTION );
379 music_lua_resume = nlua_refenvtype( music_env, "resume", LUA_TFUNCTION );
380 music_lua_info = nlua_refenvtype( music_env, "info", LUA_TFUNCTION );
381 music_lua_volume = nlua_refenvtype( music_env, "volume", LUA_TFUNCTION );
382
383 return 0;
384}
385
389static void music_luaQuit (void)
390{
391 if (music_disabled)
392 return;
393
394 nlua_freeEnv(music_env);
395 music_env = LUA_NOREF;
396 music_lua_choose = LUA_NOREF;
397 music_lua_update = LUA_NOREF;
398 music_lua_play = LUA_NOREF;
399 music_lua_stop = LUA_NOREF;
400 music_lua_pause = LUA_NOREF;
401 music_lua_resume = LUA_NOREF;
402 music_lua_info = LUA_NOREF;
403 music_lua_volume = LUA_NOREF;
404}
405
412int music_choose( const char* situation )
413{
415 return 0;
416
417 if (music_runLua( situation ))
418 return -1;
419
420 return 0;
421}
422
426void music_rechoose (void)
427{
428 if (music_disabled)
429 return;
430
431 /* Lock so it doesn't run in between an update. */
432 music_runchoose = 1;
433}
MusicInfo_t * music_info(void)
Gets information about the current music state.
Definition music.c:314
static int music_runchoose
Definition music.c:40
static int music_find(void)
Internal music loading routines.
Definition music.c:152
int music_play(const char *filename)
Plays the loaded music.
Definition music.c:236
int music_disabled
Definition music.c:32
int music_pause(int disable)
Pauses the music.
Definition music.c:278
double music_getVolumeLog(void)
Gets the current music volume (logarithmic).
Definition music.c:228
double music_getVolume(void)
Gets the current music volume (linear).
Definition music.c:218
int music_choose(const char *situation)
Actually runs the music stuff, based on situation.
Definition music.c:412
int music_volume(double vol)
Sets the music volume from a linear value.
Definition music.c:191
int music_stop(int disable)
Stops the loaded music.
Definition music.c:260
static void music_luaQuit(void)
Quits the music Lua control system.
Definition music.c:389
#define MUSIC_SUFFIX
Definition music.c:30
void music_rechoose(void)
Attempts to rechoose the music.
Definition music.c:426
static int music_luaInit(void)
Initialize the music Lua control system.
Definition music.c:346
void music_exit(void)
Exits the music subsystem.
Definition music.c:138
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:296
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
int nlua_loadStandard(nlua_env env)
Loads the standard Naev Lua API.
Definition nlua.c:798
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:920
int nlua_loadTk(nlua_env env)
Loads the Toolkit Lua library.
Definition nlua_tk.c:93
int sound_disabled
Definition sound.c:133
double music
Definition conf.h:108