naev 0.12.6
nlua_spfx.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
10#include <lauxlib.h>
12
13#include "nlua_spfx.h"
14
15#include "array.h"
16#include "camera.h"
17#include "debris.h"
18#include "nlua_audio.h"
19#include "nlua_colour.h"
20#include "nlua_vec2.h"
21#include "nluadef.h"
22#include "nopenal.h"
23#include "ntracing.h"
24#include "opengl.h"
25#include "player.h"
26#include "sound.h"
27
28#define SPFX_GLOBAL ( 1 << 1 )
29#define SPFX_RELATIVE ( 1 << 2 )
30#define SPFX_MOVING ( 1 << 3 )
31#define SPFX_AUDIO ( 1 << 4 )
32#define SPFX_CLEANUP ( 1 << 5 )
33
40typedef struct LuaSpfxData_s {
41 int id;
42 unsigned int flags;
43 double ttl;
46 double radius;
47 int data;
51 int update;
52 int remove;
54 /* We ideally would want the Lua SPFX to run in their own environment, in
55 * case any global voodoo is being done or the likes. However, this seems to
56 * crash, so we're just going to use pcall and not save the environment for
57 * now. Lua SPFX "shouldn't" be using globals anyways... */
58 // nlua_env env; /**< Lua environment. */
60
64static LuaSpfxData_t *lua_spfx = NULL;
65static LuaSpfxData_t *lua_spfx_queue = NULL;
66static int lua_spfx_idgen = 0;
67static int lua_spfx_lock = 0;
68
69/* Spfx methods. */
70static int spfxL_gc( lua_State *L );
71static int spfxL_eq( lua_State *L );
72static int spfxL_getAll( lua_State *L );
73static int spfxL_new( lua_State *L );
74static int spfxL_rm( lua_State *L );
75static int spfxL_pos( lua_State *L );
76static int spfxL_vel( lua_State *L );
77static int spfxL_setPos( lua_State *L );
78static int spfxL_setVel( lua_State *L );
79static int spfxL_sfx( lua_State *L );
80static int spfxL_data( lua_State *L );
81static int spfxL_debris( lua_State *L );
82static int spfxL_nebulaColour( lua_State *L );
83
84static const luaL_Reg spfxL_methods[] = {
85 { "__gc", spfxL_gc },
86 { "__eq", spfxL_eq },
87 { "getAll", spfxL_getAll },
88 { "new", spfxL_new },
89 { "rm", spfxL_rm },
90 { "pos", spfxL_pos },
91 { "vel", spfxL_vel },
92 { "setPos", spfxL_setPos },
93 { "setVel", spfxL_setVel },
94 { "sfx", spfxL_sfx },
95 { "data", spfxL_data },
96 { "debris", spfxL_debris },
97 { "nebulaColour", spfxL_nebulaColour },
98 { 0, 0 } };
99
100static int spfx_cmp( const void *p1, const void *p2 )
101{
102 const LuaSpfxData_t *s1 = p1;
103 const LuaSpfxData_t *s2 = p2;
104 return s1->id - s2->id;
105}
106
113int nlua_loadSpfx( nlua_env env )
114{
115 nlua_register( env, SPFX_METATABLE, spfxL_methods, 1 );
116 return 0;
117}
118
126LuaSpfx_t *lua_tospfx( lua_State *L, int ind )
127{
128 return (LuaSpfx_t *)lua_touserdata( L, ind );
129}
130
137LuaSpfx_t *luaL_checkspfx( lua_State *L, int ind )
138{
139 if ( lua_isspfx( L, ind ) )
140 return lua_tospfx( L, ind );
141 luaL_typerror( L, ind, SPFX_METATABLE );
142 return NULL;
143}
144static LuaSpfxData_t *luaL_checkspfxdataNoWarn( lua_State *L, int ind )
145{
146 const LuaSpfx_t *ls = luaL_checkspfx( L, ind );
147 const LuaSpfxData_t key = { .id = *ls };
148 LuaSpfxData_t *f = bsearch( &key, lua_spfx, array_size( lua_spfx ),
149 sizeof( LuaSpfxData_t ), spfx_cmp );
150 if ( f == NULL ) {
151 f = bsearch( &key, lua_spfx_queue, array_size( lua_spfx_queue ),
152 sizeof( LuaSpfxData_t ), spfx_cmp );
153 }
154 return f;
155}
156static LuaSpfxData_t *luaL_checkspfxdata( lua_State *L, int ind )
157{
158 LuaSpfxData_t *f = luaL_checkspfxdataNoWarn( L, ind );
159 if ( f == NULL )
160 NLUA_ERROR( L, _( "Spfx does not exist." ) );
161 return f;
162}
170LuaSpfx_t *lua_pushspfx( lua_State *L, LuaSpfx_t spfx )
171{
172 LuaSpfx_t *la = (LuaSpfx_t *)lua_newuserdata( L, sizeof( LuaSpfx_t ) );
173 *la = spfx;
174 luaL_getmetatable( L, SPFX_METATABLE );
175 lua_setmetatable( L, -2 );
176 return la;
177}
178
185int lua_isspfx( lua_State *L, int ind )
186{
187 int ret;
188
189 if ( lua_getmetatable( L, ind ) == 0 )
190 return 0;
191 lua_getfield( L, LUA_REGISTRYINDEX, SPFX_METATABLE );
192
193 ret = 0;
194 if ( lua_rawequal( L, -1, -2 ) ) /* does it have the correct mt? */
195 ret = 1;
196
197 lua_pop( L, 2 ); /* remove both metatables */
198 return ret;
199}
200
206static void spfx_cleanup( LuaSpfxData_t *ls )
207{
208 /* Unreference stuff so it can get gc'd. */
209 nlua_unref( naevL, ls->data );
210 nlua_unref( naevL, ls->render_bg );
211 nlua_unref( naevL, ls->render_mg );
212 nlua_unref( naevL, ls->render_fg );
213 nlua_unref( naevL, ls->update );
214 nlua_unref( naevL, ls->remove );
215
216 /* Make sure stuff doesn't get run. */
217 ls->data = LUA_NOREF;
218 ls->render_bg = LUA_NOREF;
219 ls->render_mg = LUA_NOREF;
220 ls->render_fg = LUA_NOREF;
221 ls->update = LUA_NOREF;
222 ls->remove = LUA_NOREF;
223
224 /* Clean up audio. */
225 ls->sfx.nocleanup = 0; /* Have to disable so it gets cleaned. */
226 audio_cleanup( &ls->sfx );
227
228 /* Set as cleaned up. */
229 ls->id = -1;
230}
231
244static int spfxL_gc( lua_State *L )
245{
246 LuaSpfx_t *ls = luaL_checkspfx( L, 1 );
247 (void)ls;
248 return 0;
249}
250
259static int spfxL_eq( lua_State *L )
260{
261 const LuaSpfx_t *s1, *s2;
262 s1 = luaL_checkspfx( L, 1 );
263 s2 = luaL_checkspfx( L, 2 );
264 lua_pushboolean( L, ( memcmp( s1, s2, sizeof( LuaSpfx_t ) ) == 0 ) );
265 return 1;
266}
267
274static int spfxL_getAll( lua_State *L )
275{
276 int n = 1;
277 lua_newtable( L );
278 for ( int i = 0; i < array_size( lua_spfx ); i++ ) {
279 const LuaSpfxData_t *ls = &lua_spfx[i];
280
281 if ( ls->flags & ( SPFX_GLOBAL | SPFX_CLEANUP ) )
282 continue;
283
284 lua_pushspfx( L, ls->id );
285 lua_rawseti( L, -2, n++ );
286 }
287 return 1;
288}
289
319static int spfxL_new( lua_State *L )
320{
321 LuaSpfxData_t ls;
322
323 memset( &ls, 0, sizeof( LuaSpfxData_t ) );
324
325 ls.id = ++lua_spfx_idgen;
326 ls.ttl = luaL_checknumber( L, 1 );
327 ls.update = LUA_NOREF;
328 ls.render_bg = LUA_NOREF;
329 ls.render_mg = LUA_NOREF;
330 ls.render_fg = LUA_NOREF;
331 ls.remove = LUA_NOREF;
332#if 0
333 nlua_pushenv( L, __NLUA_CURENV );
334#if DEBUGGING
335 if (__NLUA_CURENV == LUA_NOREF)
336 WARN(_("Trying to create Lua SPFX from no environment!"));
337#endif /* DEBUGGING */
338 ls.env = luaL_ref( naevL, LUA_REGISTRYINDEX );
339#endif
340
341 /* Functions. */
342 if ( !lua_isnoneornil( L, 2 ) )
343 ls.update = nlua_ref( L, 2 );
344 if ( !lua_isnoneornil( L, 3 ) )
345 ls.render_bg = nlua_ref( L, 3 );
346 if ( !lua_isnoneornil( L, 4 ) )
347 ls.render_mg = nlua_ref( L, 4 );
348 if ( !lua_isnoneornil( L, 5 ) )
349 ls.render_fg = nlua_ref( L, 5 );
350
351 /* Position information. */
352 if ( !lua_isnoneornil( L, 6 ) ) {
353 if ( lua_isboolean( L, 6 ) ) {
354 ls.flags |= SPFX_RELATIVE;
355 if ( !lua_toboolean( L, 6 ) )
356 ls.flags |= SPFX_GLOBAL;
357 } else
358 ls.pos = *luaL_checkvector( L, 6 );
359 } else
361 if ( !lua_isnoneornil( L, 7 ) ) {
362 ls.vel = *luaL_checkvector( L, 7 );
363 ls.flags |= SPFX_MOVING;
364 }
365
366 /* Special effect. */
367 if ( !lua_isnoneornil( L, 8 ) ) {
368 const LuaAudio_t *la = luaL_checkaudio( L, 8 );
369
370 if ( !sound_disabled ) {
371 ls.flags |= SPFX_AUDIO;
372 audio_clone( &ls.sfx, la );
373 ls.sfx.nocleanup = 1;
374
375 /* Set up parameters. */
376 if ( !ls.sfx.ok ) {
377 soundLock();
378 alSourcei( ls.sfx.source, AL_LOOPING, AL_FALSE );
379 alSourcef( ls.sfx.source, AL_REFERENCE_DISTANCE,
380 SOUND_REFERENCE_DISTANCE );
381 alSourcef( ls.sfx.source, AL_MAX_DISTANCE, SOUND_MAX_DISTANCE );
382 if ( ls.flags & SPFX_RELATIVE ) {
383 alSourcei( ls.sfx.source, AL_SOURCE_RELATIVE, AL_TRUE );
384 if ( ls.flags & SPFX_GLOBAL )
385 alSourcef( ls.sfx.source, AL_PITCH, 1. );
386 else
387 alSourcef( ls.sfx.source, AL_PITCH,
388 player_dt_default() * player.speed );
389 } else {
390 ALfloat alf[3];
391 alSourcei( ls.sfx.source, AL_SOURCE_RELATIVE, AL_FALSE );
392 alSourcef( ls.sfx.source, AL_PITCH,
393 player_dt_default() * player.speed );
394 alf[0] = ls.pos.x;
395 alf[1] = ls.pos.y;
396 alf[2] = 0.;
397 alSourcefv( ls.sfx.source, AL_POSITION, alf );
398 alf[0] = ls.vel.x;
399 alf[1] = ls.vel.y;
400 alf[2] = 0.;
401 alSourcefv( ls.sfx.source, AL_VELOCITY, alf );
402
403 /* Set the global filter. */
404 if ( al_info.efx == AL_TRUE )
405 alSource3i( ls.sfx.source, AL_AUXILIARY_SEND_FILTER,
406 sound_efx_directSlot, 0, AL_FILTER_NULL );
407 }
408 alSourcePlay( ls.sfx.source );
409 al_checkErr();
410 soundUnlock();
411 }
412 }
413 }
414
415 /* Store radius. */
416 ls.radius = luaL_optnumber( L, 9, -1. );
417
418 /* Finally remove function if applicable. */
419 if ( !lua_isnoneornil( L, 10 ) )
420 ls.remove = nlua_ref( L, 10 );
421
422 /* Set up new data. */
423 lua_newtable( L );
424 ls.data = luaL_ref( L, LUA_REGISTRYINDEX ); /* Pops result. */
425
426 /* Add to Lua and stack, depending on if locked or not. */
427 if ( lua_spfx_lock ) {
428 if ( lua_spfx_queue == NULL )
429 lua_spfx_queue = array_create( LuaSpfxData_t );
430 array_push_back( &lua_spfx_queue, ls );
431 } else {
432 if ( lua_spfx == NULL )
435 }
436
437 lua_pushspfx( L, ls.id );
438 return 1;
439}
440
447static int spfxL_rm( lua_State *L )
448{
449 LuaSpfxData_t *ls = luaL_checkspfxdataNoWarn( L, 1 );
450 if ( ls != NULL ) {
451 if ( ls->remove != LUA_NOREF ) {
452 lua_rawgeti( naevL, LUA_REGISTRYINDEX, ls->remove );
453 lua_pushspfx( naevL, ls->id );
454 if ( lua_pcall( naevL, 1, 0, 0 ) != 0 ) {
455 // if ( nlua_pcall( ls->env, 1, 0 ) != 0 ) {
456 NLUA_WARN( L, _( "Spfx failed to run 'remove':\n%s" ),
457 lua_tostring( naevL, -1 ) );
458 lua_pop( naevL, 1 );
459 }
460 }
461
462 ls->flags &= SPFX_CLEANUP;
463 ls->ttl = -1.;
464 // luaL_unref( L, LUA_REGISTRYINDEX, ls->env );
465 }
466 return 0;
467}
468
476static int spfxL_pos( lua_State *L )
477{
478 const LuaSpfxData_t *ls = luaL_checkspfxdata( L, 1 );
479 lua_pushvector( L, ls->pos );
480 return 1;
481}
482
490static int spfxL_vel( lua_State *L )
491{
492 const LuaSpfxData_t *ls = luaL_checkspfxdata( L, 1 );
493 lua_pushvector( L, ls->vel );
494 return 1;
495}
496
504static int spfxL_setPos( lua_State *L )
505{
506 LuaSpfxData_t *ls = luaL_checkspfxdata( L, 1 );
507 const vec2 *v = luaL_checkvector( L, 2 );
508 ls->pos = *v;
509 return 0;
510}
511
519static int spfxL_setVel( lua_State *L )
520{
521 LuaSpfxData_t *ls = luaL_checkspfxdata( L, 1 );
522 const vec2 *v = luaL_checkvector( L, 2 );
523 ls->vel = *v;
524 return 0;
525}
526
534static int spfxL_sfx( lua_State *L )
535{
536 const LuaSpfxData_t *ls = luaL_checkspfxdata( L, 1 );
537 lua_pushaudio( L, ls->sfx );
538 return 1;
539}
540
550static int spfxL_data( lua_State *L )
551{
552 LuaSpfxData_t *ls = luaL_checkspfxdata( L, 1 );
553 lua_rawgeti( L, LUA_REGISTRYINDEX, ls->data );
554 return 1;
555}
556
560void spfxL_setSpeed( double s )
561{
562 if ( sound_disabled )
563 return;
564
565 soundLock();
566 for ( int i = 0; i < array_size( lua_spfx ); i++ ) {
567 LuaSpfxData_t *ls = &lua_spfx[i];
568
569 if ( !( ls->flags & SPFX_AUDIO ) )
570 continue;
571
572 if ( ls->flags & ( SPFX_GLOBAL | SPFX_CLEANUP ) )
573 continue;
574
575 /* Sound is not valid. */
576 if ( ls->sfx.ok )
577 continue;
578
579 alSourcef( ls->sfx.source, AL_PITCH, s );
580 }
581 al_checkErr();
582 soundUnlock();
583}
584
590void spfxL_setSpeedVolume( double v )
591{
592 if ( sound_disabled )
593 return;
594
595 soundLock();
596 for ( int i = 0; i < array_size( lua_spfx ); i++ ) {
597 LuaSpfxData_t *ls = &lua_spfx[i];
598
599 if ( !( ls->flags & SPFX_AUDIO ) )
600 continue;
601
602 if ( ls->flags & ( SPFX_GLOBAL | SPFX_CLEANUP ) )
603 continue;
604
605 /* Sound is not valid. */
606 if ( ls->sfx.ok )
607 continue;
608
609 alSourcef( ls->sfx.source, AL_GAIN, ls->sfx.volume * v );
610 }
611 al_checkErr();
612 soundUnlock();
613}
614
615static void spfx_lock( void )
616{
617 lua_spfx_lock = 1;
618}
619
620static void spfx_unlock( void )
621{
622 lua_spfx_lock = 0;
623
624 if ( lua_spfx_queue == NULL )
625 return;
626
627 for ( int i = 0; i < array_size( lua_spfx_queue ); i++ )
628 array_push_back( &lua_spfx, lua_spfx_queue[i] );
629 array_erase( &lua_spfx_queue, array_begin( lua_spfx_queue ),
630 array_end( lua_spfx_queue ) );
631}
632
636void spfxL_clear( void )
637{
638 for ( int i = 0; i < array_size( lua_spfx ); i++ )
639 spfx_cleanup( &lua_spfx[i] );
641 for ( int i = 0; i < array_size( lua_spfx_queue ); i++ )
642 spfx_cleanup( &lua_spfx_queue[i] );
643 array_erase( &lua_spfx_queue, array_begin( lua_spfx_queue ),
644 array_end( lua_spfx_queue ) );
645}
646
647void spfxL_exit( void )
648{
649 spfxL_clear();
651 lua_spfx = NULL;
652 array_free( lua_spfx_queue );
653 lua_spfx_queue = NULL;
654}
655
661void spfxL_update( double dt )
662{
663 NTracingZone( _ctx, 1 );
664 NTracingPlotI( "Lua spfx", array_size( lua_spfx ) );
665
666 spfx_lock();
667 for ( int i = array_size( lua_spfx ) - 1; i >= 0; i-- ) {
668 LuaSpfxData_t *ls = &lua_spfx[i];
669
670 /* Count down. */
671 ls->ttl -= dt;
672 if ( ( ls->ttl <= 0. ) || ( ls->flags & SPFX_CLEANUP ) ) {
673 spfx_cleanup( ls );
674 array_erase( &lua_spfx, &lua_spfx[i], &lua_spfx[i + 1] );
675 continue;
676 }
677
678 /* Normal update. */
679 if ( ls->flags & SPFX_MOVING ) {
680 ls->pos.x += ls->vel.x * dt;
681 ls->pos.y += ls->vel.y * dt;
682
683 /* Check sound. */
684 if ( ( ls->flags & SPFX_AUDIO ) && !( ls->flags & SPFX_RELATIVE ) &&
685 !ls->sfx.ok ) {
686 soundLock();
687 ALfloat alf[3];
688 alf[0] = ls->pos.x;
689 alf[1] = ls->pos.y;
690 alf[2] = 0.;
691 alSourcefv( ls->sfx.source, AL_POSITION, alf );
692 al_checkErr();
693 soundUnlock();
694 }
695 }
696
697 /* Update if necessary. */
698 if ( ls->update == LUA_NOREF )
699 continue;
700
701 /* Run update. */
702 lua_rawgeti( naevL, LUA_REGISTRYINDEX, ls->update );
703 lua_pushspfx( naevL, ls->id );
704 lua_pushnumber( naevL, dt );
705 if ( lua_pcall( naevL, 2, 0, 0 ) != 0 ) {
706 // if ( nlua_pcall( ls->env, 2, 0 ) != 0 ) {
707 WARN( _( "Spfx failed to run 'update':\n%s" ),
708 lua_tostring( naevL, -1 ) );
709 lua_pop( naevL, 1 );
710 }
711 }
712 spfx_unlock();
713
714 NTracingZoneEnd( _ctx );
715}
716
717static void spfxL_renderLayer( int func, const char *funcname, double dt )
718{
719 double z = cam_getZoom();
720 spfx_lock();
721 for ( int i = 0; i < array_size( lua_spfx ); i++ ) {
722 vec2 pos;
723 LuaSpfxData_t *ls = &lua_spfx[i];
724 double r = ls->radius;
725 int funcref;
726
727 switch ( func ) {
728 case 0:
729 funcref = ls->render_bg;
730 break;
731 case 1:
732 funcref = ls->render_mg;
733 break;
734 case 2:
735 funcref = ls->render_fg;
736 break;
737 default:
738 WARN( _( "Unknown render layer '%d'!" ), func );
739 return;
740 }
741
742 /* Skip no rendering. */
743 if ( ( funcref == LUA_NOREF ) || ( ls->flags & SPFX_CLEANUP ) )
744 continue;
745
746 /* Convert coordinates. */
747 gl_gameToScreenCoords( &pos.x, &pos.y, ls->pos.x, ls->pos.y );
748
749 /* If radius is defined see if in screen. */
750 if ( ( r > 0. ) &&
751 ( ( pos.x < -r ) || ( pos.y < -r ) || ( pos.x > SCREEN_W + r ) ||
752 ( pos.y > SCREEN_H + r ) ) )
753 continue;
754
755 /* Invert y axis. */
756 pos.y = SCREEN_H - pos.y;
757
758 /* Render. */
759 lua_rawgeti( naevL, LUA_REGISTRYINDEX, funcref );
760 lua_pushspfx( naevL, ls->id );
761 lua_pushnumber( naevL, pos.x );
762 lua_pushnumber( naevL, pos.y );
763 lua_pushnumber( naevL, z );
764 lua_pushnumber( naevL, dt );
765 if ( lua_pcall( naevL, 5, 0, 0 ) != 0 ) {
766 // if ( nlua_pcall( ls->env, 5, 0 ) != 0 ) {
767 WARN( _( "Spfx failed to run '%s':\n%s" ), funcname,
768 lua_tostring( naevL, -1 ) );
769 lua_pop( naevL, 1 );
770 }
771 }
772 spfx_unlock();
773}
774
778void spfxL_renderbg( double dt )
779{
780 NTracingZone( _ctx, 1 );
781 spfxL_renderLayer( 0, "renderbg", dt );
782 NTracingZoneEnd( _ctx );
783}
784
788void spfxL_rendermg( double dt )
789{
790 NTracingZone( _ctx, 1 );
791 spfxL_renderLayer( 1, "rendermg", dt );
792 NTracingZoneEnd( _ctx );
793}
794
798void spfxL_renderfg( double dt )
799{
800 NTracingZone( _ctx, 1 );
801 spfxL_renderLayer( 2, "rendermg", dt );
802 NTracingZoneEnd( _ctx );
803}
804
814static int spfxL_debris( lua_State *L )
815{
816 double mass = luaL_checknumber( L, 1 );
817 double radius = luaL_checknumber( L, 2 );
818 const vec2 *p = luaL_checkvector( L, 3 );
819 const vec2 *v = luaL_checkvector( L, 4 );
820 debris_add( mass, radius, p->x, p->y, v->x, v->y );
821 return 0;
822}
823
833static int spfxL_nebulaColour( lua_State *L )
834{
835 if ( lua_iscolour( L, 1 ) ) {
836 const glColour *c = lua_tocolour( L, 1 );
837 spfx_setNebulaColour( c->r, c->g, c->b );
838 } else {
839 double r = luaL_checknumber( L, 1 );
840 double g = luaL_checknumber( L, 2 );
841 double b = luaL_checknumber( L, 3 );
842 spfx_setNebulaColour( r, g, b );
843 }
844 return 0;
845}
Provides macros to work with dynamic arrays.
#define array_free(ptr_array)
Frees memory allocated and sets array to NULL.
Definition array.h:170
#define array_end(array)
Returns a pointer to the end of the reserved memory space.
Definition array.h:214
#define array_erase(ptr_array, first, last)
Erases elements in interval [first, last).
Definition array.h:148
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
Definition array.h:179
#define array_push_back(ptr_array, element)
Adds a new element at the end of the array.
Definition array.h:134
#define array_begin(array)
Returns a pointer to the beginning of the reserved memory space.
Definition array.h:206
#define array_create(basic_type)
Creates a new dynamic array of ‘basic_type’.
Definition array.h:93
double cam_getZoom(void)
Gets the camera zoom.
Definition camera.c:101
void debris_add(double mass, double r, double px, double py, double vx, double vy)
Creates a cloud of debris.
Definition debris.c:80
void nlua_unref(lua_State *L, int idx)
Removes a reference set with nlua_ref.
Definition nlua.c:1088
int nlua_ref(lua_State *L, int idx)
Creates a new reference to a Lua structure at a position.
Definition nlua.c:1079
nlua_env __NLUA_CURENV
Definition nlua.c:55
lua_State * naevL
Definition nlua.c:54
LuaAudio_t * lua_pushaudio(lua_State *L, LuaAudio_t audio)
Pushes a audio on the stack.
Definition nlua_audio.c:310
LuaAudio_t * luaL_checkaudio(lua_State *L, int ind)
Gets audio at index or raises error if there is no audio at index.
Definition nlua_audio.c:296
int lua_iscolour(lua_State *L, int ind)
Checks to see if ind is a colour.
glColour * lua_tocolour(lua_State *L, int ind)
Lua bindings to interact with colours.
Definition nlua_colour.c:87
#define SPFX_MOVING
Definition nlua_spfx.c:30
static int spfxL_new(lua_State *L)
Creates a new special effect.
Definition nlua_spfx.c:319
static int spfxL_vel(lua_State *L)
Gets the velocity of a spfx.
Definition nlua_spfx.c:490
static int spfxL_sfx(lua_State *L)
Gets the sound effect of a spfx.
Definition nlua_spfx.c:534
static int spfxL_setVel(lua_State *L)
Sets the velocity of a spfx.
Definition nlua_spfx.c:519
int lua_isspfx(lua_State *L, int ind)
Checks to see if ind is a spfx.
Definition nlua_spfx.c:185
void spfxL_setSpeedVolume(double v)
Sets the speed volume due to autonav and the likes.
Definition nlua_spfx.c:590
static const luaL_Reg spfxL_methods[]
Definition nlua_spfx.c:84
static int spfxL_nebulaColour(lua_State *L)
Sets the nebula colour.
Definition nlua_spfx.c:833
void spfxL_renderbg(double dt)
Renders the Lua SPFX on the background.
Definition nlua_spfx.c:778
static int spfxL_setPos(lua_State *L)
Sets the position of a spfx.
Definition nlua_spfx.c:504
#define SPFX_GLOBAL
Definition nlua_spfx.c:28
static int spfxL_pos(lua_State *L)
Gets the position of a spfx.
Definition nlua_spfx.c:476
void spfxL_rendermg(double dt)
Renders the Lua SPFX in the midground.
Definition nlua_spfx.c:788
static int spfxL_eq(lua_State *L)
Compares two spfxs to see if they are the same.
Definition nlua_spfx.c:259
void spfxL_renderfg(double dt)
Renders the Lua SPFX in the foreground.
Definition nlua_spfx.c:798
void spfxL_clear(void)
Clears the Lua spfx.
Definition nlua_spfx.c:636
static void spfx_cleanup(LuaSpfxData_t *ls)
Cleans up a special effect.
Definition nlua_spfx.c:206
static int spfxL_data(lua_State *L)
Gets the data table of a spfx.
Definition nlua_spfx.c:550
static int spfxL_rm(lua_State *L)
Removes a special effect.
Definition nlua_spfx.c:447
static LuaSpfxData_t * lua_spfx
List of special effects being handled.
Definition nlua_spfx.c:64
void spfxL_update(double dt)
Updates the spfx.
Definition nlua_spfx.c:661
#define SPFX_RELATIVE
Definition nlua_spfx.c:29
#define SPFX_CLEANUP
Definition nlua_spfx.c:32
LuaSpfx_t * luaL_checkspfx(lua_State *L, int ind)
Gets spfx at index or raises error if there is no spfx at index.
Definition nlua_spfx.c:137
static int spfxL_debris(lua_State *L)
Creates a cloud of debris.
Definition nlua_spfx.c:814
static int spfxL_getAll(lua_State *L)
Gets all the active spfx.
Definition nlua_spfx.c:274
int nlua_loadSpfx(nlua_env env)
Loads the spfx library.
Definition nlua_spfx.c:113
LuaSpfx_t * lua_pushspfx(lua_State *L, LuaSpfx_t spfx)
Pushes a spfx on the stack.
Definition nlua_spfx.c:170
#define SPFX_AUDIO
Definition nlua_spfx.c:31
void spfxL_setSpeed(double s)
Sets the speed of the playing spfx sounds.
Definition nlua_spfx.c:560
LuaSpfx_t * lua_tospfx(lua_State *L, int ind)
Gets spfx at index.
Definition nlua_spfx.c:126
static int spfxL_gc(lua_State *L)
Lua bindings to interact with spfx.
Definition nlua_spfx.c:244
vec2 * luaL_checkvector(lua_State *L, int ind)
Gets vector at index making sure type is valid.
Definition nlua_vec2.c:130
vec2 * lua_pushvector(lua_State *L, vec2 vec)
Pushes a vector on the stack.
Definition nlua_vec2.c:145
void gl_gameToScreenCoords(double *nx, double *ny, double bx, double by)
Converts in-game coordinates to screen coordinates.
double player_dt_default(void)
Returns the player's total default time delta based on time dilation stuff.
Definition player.c:2001
Player_t player
Definition player.c:77
static const double c[]
Definition rng.c:256
int sound_disabled
Definition sound.c:130
ALuint sound_efx_directSlot
Definition sound.c:192
alInfo_t al_info
Definition sound.c:176
void spfx_setNebulaColour(double r, double g, double b)
Sets the nebula colour where applicable.
Definition spfx.c:1002
int nocleanup
Definition nlua_audio.h:31
double volume
Definition nlua_audio.h:34
ALuint source
Definition nlua_audio.h:32
Handles the special effects Lua-side.
Definition nlua_spfx.c:40
LuaAudio_t sfx
Definition nlua_spfx.c:53
double radius
Definition nlua_spfx.c:46
unsigned int flags
Definition nlua_spfx.c:42
Represents a 2d vector.
Definition vec2.h:45
double y
Definition vec2.h:47
double x
Definition vec2.h:46