18#include "nlua_audio.h"
19#include "nlua_colour.h"
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 )
40typedef struct LuaSpfxData_s {
66static int lua_spfx_idgen = 0;
67static int lua_spfx_lock = 0;
100static int spfx_cmp(
const void *p1,
const void *p2 )
104 return s1->
id - s2->
id;
128 return (LuaSpfx_t *)lua_touserdata( L, ind );
141 luaL_typerror( L, ind, SPFX_METATABLE );
144static LuaSpfxData_t *luaL_checkspfxdataNoWarn( lua_State *L,
int ind )
151 f = bsearch( &key, lua_spfx_queue,
array_size( lua_spfx_queue ),
156static LuaSpfxData_t *luaL_checkspfxdata( lua_State *L,
int ind )
160 NLUA_ERROR( L, _(
"Spfx does not exist." ) );
172 LuaSpfx_t *la = (LuaSpfx_t *)lua_newuserdata( L,
sizeof( LuaSpfx_t ) );
174 luaL_getmetatable( L, SPFX_METATABLE );
175 lua_setmetatable( L, -2 );
189 if ( lua_getmetatable( L, ind ) == 0 )
191 lua_getfield( L, LUA_REGISTRYINDEX, SPFX_METATABLE );
194 if ( lua_rawequal( L, -1, -2 ) )
217 ls->
data = LUA_NOREF;
226 audio_cleanup( &ls->
sfx );
261 const LuaSpfx_t *s1, *s2;
264 lua_pushboolean( L, ( memcmp( s1, s2,
sizeof( LuaSpfx_t ) ) == 0 ) );
285 lua_rawseti( L, -2, n++ );
325 ls.
id = ++lua_spfx_idgen;
326 ls.
ttl = luaL_checknumber( L, 1 );
336 WARN(_(
"Trying to create Lua SPFX from no environment!"));
338 ls.env = luaL_ref(
naevL, LUA_REGISTRYINDEX );
342 if ( !lua_isnoneornil( L, 2 ) )
344 if ( !lua_isnoneornil( L, 3 ) )
346 if ( !lua_isnoneornil( L, 4 ) )
348 if ( !lua_isnoneornil( L, 5 ) )
352 if ( !lua_isnoneornil( L, 6 ) ) {
353 if ( lua_isboolean( L, 6 ) ) {
355 if ( !lua_toboolean( L, 6 ) )
361 if ( !lua_isnoneornil( L, 7 ) ) {
367 if ( !lua_isnoneornil( L, 8 ) ) {
372 audio_clone( &ls.
sfx, la );
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 );
383 alSourcei( ls.
sfx.
source, AL_SOURCE_RELATIVE, AL_TRUE );
385 alSourcef( ls.
sfx.
source, AL_PITCH, 1. );
391 alSourcei( ls.
sfx.
source, AL_SOURCE_RELATIVE, AL_FALSE );
397 alSourcefv( ls.
sfx.
source, AL_POSITION, alf );
401 alSourcefv( ls.
sfx.
source, AL_VELOCITY, alf );
405 alSource3i( ls.
sfx.
source, AL_AUXILIARY_SEND_FILTER,
416 ls.
radius = luaL_optnumber( L, 9, -1. );
419 if ( !lua_isnoneornil( L, 10 ) )
424 ls.
data = luaL_ref( L, LUA_REGISTRYINDEX );
427 if ( lua_spfx_lock ) {
428 if ( lua_spfx_queue == NULL )
451 if ( ls->
remove != LUA_NOREF ) {
452 lua_rawgeti(
naevL, LUA_REGISTRYINDEX, ls->
remove );
454 if ( lua_pcall(
naevL, 1, 0, 0 ) != 0 ) {
456 NLUA_WARN( L, _(
"Spfx failed to run 'remove':\n%s" ),
457 lua_tostring(
naevL, -1 ) );
553 lua_rawgeti( L, LUA_REGISTRYINDEX, ls->
data );
579 alSourcef( ls->
sfx.
source, AL_PITCH, s );
615static void spfx_lock(
void )
620static void spfx_unlock(
void )
624 if ( lua_spfx_queue == NULL )
627 for (
int i = 0; i <
array_size( lua_spfx_queue ); i++ )
641 for (
int i = 0; i <
array_size( lua_spfx_queue ); i++ )
647void spfxL_exit(
void )
653 lua_spfx_queue = NULL;
663 NTracingZone( _ctx, 1 );
691 alSourcefv( ls->
sfx.
source, AL_POSITION, alf );
698 if ( ls->
update == LUA_NOREF )
702 lua_rawgeti(
naevL, LUA_REGISTRYINDEX, ls->
update );
704 lua_pushnumber(
naevL, dt );
705 if ( lua_pcall(
naevL, 2, 0, 0 ) != 0 ) {
707 WARN( _(
"Spfx failed to run 'update':\n%s" ),
708 lua_tostring(
naevL, -1 ) );
714 NTracingZoneEnd( _ctx );
717static void spfxL_renderLayer(
int func,
const char *funcname,
double dt )
738 WARN( _(
"Unknown render layer '%d'!" ), func );
751 ( ( pos.
x < -r ) || ( pos.
y < -r ) || ( pos.
x > SCREEN_W + r ) ||
752 ( pos.
y > SCREEN_H + r ) ) )
756 pos.
y = SCREEN_H - pos.
y;
759 lua_rawgeti(
naevL, LUA_REGISTRYINDEX, funcref );
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 ) {
767 WARN( _(
"Spfx failed to run '%s':\n%s" ), funcname,
768 lua_tostring(
naevL, -1 ) );
780 NTracingZone( _ctx, 1 );
781 spfxL_renderLayer( 0,
"renderbg", dt );
782 NTracingZoneEnd( _ctx );
790 NTracingZone( _ctx, 1 );
791 spfxL_renderLayer( 1,
"rendermg", dt );
792 NTracingZoneEnd( _ctx );
800 NTracingZone( _ctx, 1 );
801 spfxL_renderLayer( 2,
"rendermg", dt );
802 NTracingZoneEnd( _ctx );
816 double mass = luaL_checknumber( L, 1 );
817 double radius = luaL_checknumber( L, 2 );
820 debris_add( mass, radius, p->x, p->y, v->x, v->y );
839 double r = luaL_checknumber( L, 1 );
840 double g = luaL_checknumber( L, 2 );
841 double b = luaL_checknumber( L, 3 );
Provides macros to work with dynamic arrays.
#define array_free(ptr_array)
Frees memory allocated and sets array to NULL.
#define array_end(array)
Returns a pointer to the end of the reserved memory space.
#define array_erase(ptr_array, first, last)
Erases elements in interval [first, last).
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
#define array_push_back(ptr_array, element)
Adds a new element at the end of the array.
#define array_begin(array)
Returns a pointer to the beginning of the reserved memory space.
#define array_create(basic_type)
Creates a new dynamic array of ‘basic_type’.
double cam_getZoom(void)
Gets the camera zoom.
void debris_add(double mass, double r, double px, double py, double vx, double vy)
Creates a cloud of debris.
void nlua_unref(lua_State *L, int idx)
Removes a reference set with nlua_ref.
int nlua_ref(lua_State *L, int idx)
Creates a new reference to a Lua structure at a position.
LuaAudio_t * lua_pushaudio(lua_State *L, LuaAudio_t audio)
Pushes a audio on the stack.
LuaAudio_t * luaL_checkaudio(lua_State *L, int ind)
Gets audio at index or raises error if there is no audio at index.
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.
static int spfxL_new(lua_State *L)
Creates a new special effect.
static int spfxL_vel(lua_State *L)
Gets the velocity of a spfx.
static int spfxL_sfx(lua_State *L)
Gets the sound effect of a spfx.
static int spfxL_setVel(lua_State *L)
Sets the velocity of a spfx.
int lua_isspfx(lua_State *L, int ind)
Checks to see if ind is a spfx.
void spfxL_setSpeedVolume(double v)
Sets the speed volume due to autonav and the likes.
static const luaL_Reg spfxL_methods[]
static int spfxL_nebulaColour(lua_State *L)
Sets the nebula colour.
void spfxL_renderbg(double dt)
Renders the Lua SPFX on the background.
static int spfxL_setPos(lua_State *L)
Sets the position of a spfx.
static int spfxL_pos(lua_State *L)
Gets the position of a spfx.
void spfxL_rendermg(double dt)
Renders the Lua SPFX in the midground.
static int spfxL_eq(lua_State *L)
Compares two spfxs to see if they are the same.
void spfxL_renderfg(double dt)
Renders the Lua SPFX in the foreground.
void spfxL_clear(void)
Clears the Lua spfx.
static void spfx_cleanup(LuaSpfxData_t *ls)
Cleans up a special effect.
static int spfxL_data(lua_State *L)
Gets the data table of a spfx.
static int spfxL_rm(lua_State *L)
Removes a special effect.
static LuaSpfxData_t * lua_spfx
List of special effects being handled.
void spfxL_update(double dt)
Updates the spfx.
LuaSpfx_t * luaL_checkspfx(lua_State *L, int ind)
Gets spfx at index or raises error if there is no spfx at index.
static int spfxL_debris(lua_State *L)
Creates a cloud of debris.
static int spfxL_getAll(lua_State *L)
Gets all the active spfx.
int nlua_loadSpfx(nlua_env env)
Loads the spfx library.
LuaSpfx_t * lua_pushspfx(lua_State *L, LuaSpfx_t spfx)
Pushes a spfx on the stack.
void spfxL_setSpeed(double s)
Sets the speed of the playing spfx sounds.
LuaSpfx_t * lua_tospfx(lua_State *L, int ind)
Gets spfx at index.
static int spfxL_gc(lua_State *L)
Lua bindings to interact with spfx.
vec2 * luaL_checkvector(lua_State *L, int ind)
Gets vector at index making sure type is valid.
vec2 * lua_pushvector(lua_State *L, vec2 vec)
Pushes a vector on the stack.
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.
ALuint sound_efx_directSlot
void spfx_setNebulaColour(double r, double g, double b)
Sets the nebula colour where applicable.
Handles the special effects Lua-side.