engine_stage;
/* graphics */
+#if 0
m4x4f pv;
+#endif
enum quality_profile
{
k_quality_profile_high = 0,
ui_text( (ui_rect){258, 4+24+12,0,0},perf, 1,0);
}
+ /* FIXME */
+#if 0
audio_debug_ui( vg.pv );
+#endif
vg_ui();
_vg_console_draw();
_vg_gameloop_update();
_vg_gameloop_render();
+ audio_push_console_vol();
SDL_GL_SwapWindow( vg.window );
_vg_run_synced();
SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK,
SDL_GL_CONTEXT_PROFILE_CORE );
- SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 1 );
+ SDL_GL_SetAttribute( SDL_GL_CONTEXT_RELEASE_BEHAVIOR,
+ SDL_GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH );
+
SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 );
SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 );
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 );
SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 8 );
+ SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 0 );
- if( vg.samples > 1 )
- {
- SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 1 );
- SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, vg.samples );
- }
-
- SDL_GL_SetAttribute( SDL_GL_CONTEXT_RELEASE_BEHAVIOR,
- SDL_GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH );
-
/*
* Get monitor information
*/
glBlendEquation(GL_FUNC_ADD);
glClearColor( 0.15f + sinf(vg.time_real)*0.1f, 0.0f, 0.0f,1.0f );
- glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
+ glClear( GL_COLOR_BUFFER_BIT );
glViewport( 0,0, vg.window_x, vg.window_y );
_vg_render_log();
#include "vg/vg_profiler.h"
#include <sys/time.h>
+#include <math.h>
#ifdef __GNUC__
#ifndef __clang__
v3f listener_pos,
listener_ears;
+
+ float volume,
+ volume_target,
+ volume_target_internal,
+ volume_console;
}
-vg_audio;
+vg_audio = { .volume_console = 1.0f };
static struct vg_profile
_vg_prof_audio_decode = {.mode = k_profile_mode_accum,
.persistent = 1
});
+ vg_convar_push( (struct vg_convar){
+ .name = "volume",
+ .data = &vg_audio.volume_console,
+ .data_type = k_convar_dtype_f32,
+ .opt_f32 = { .min=0.0f, .max=2.0f, .clamp=1 },
+ .persistent = 1
+ });
+
/* allocate memory */
/* 32mb fixed */
{
/* Process incoming sound queue */
audio_lock();
+
+ vg_audio.volume_target_internal = vg_audio.volume_target;
int wr = 0;
for( int i=0; i<vg_audio.queue_len; i++ )
/*
* Get effective volume and pan from this entity
*/
-VG_STATIC void audio_entity_spacialize( audio_entity *ent, float *vol, float *pan )
+VG_STATIC void audio_entity_spacialize( audio_entity *ent,
+ float *vol, float *pan )
{
if( ent->info.vol < 0.01f )
{
return;
}
+ if( !vg_validf(vg_audio.listener_pos[0]) ||
+ !vg_validf(vg_audio.listener_pos[1]) ||
+ !vg_validf(vg_audio.listener_pos[2]) ||
+ !vg_validf(ent->info.world_position[0]) ||
+ !vg_validf(ent->info.world_position[1]) ||
+ !vg_validf(ent->info.world_position[2]) )
+ {
+ vg_error( "NaN listener/world position (%s)\n", ent->name );
+ *vol = 0.0f;
+ *pan = 0.0f;
+ return;
+ }
+
v3f delta;
v3_sub( ent->info.world_position, vg_audio.listener_pos, delta );
for( u32 j=0; j<frame_count; j++ )
{
- float frame_vol = vol;
-
+ float frame_vol = vol * vg_audio.volume;
if( ent->fadeout )
{
/* Force this system to be removed now */
for( int i=0; i<frame_count*2; i ++ )
pOut32F[i] = 0.0f;
+ float start_vol = vg_audio.volume;
+
/* Mix all sounds */
for( int i=0; i<SFX_MAX_SYSTEMS; i ++ )
{
struct active_audio_player *aap = &vg_audio.active_players[i];
+ vg_audio.volume = start_vol;
if( aap->active )
- {
audio_entity_mix( i, pOut32F, frame_count );
- }
}
+ float vol_diff = vg_audio.volume_target_internal - vg_audio.volume,
+ vol_rate = 1.0f / (44100.0f*0.25f),
+ vol_chg = frame_count * vol_rate;
+
+ if( vol_chg > fabsf( vol_diff ) )
+ vg_audio.volume = vg_audio.volume_target_internal;
+ else
+ vg_audio.volume += vg_signf( vol_diff ) * vol_chg;
+
/* redistribute */
audio_system_cleanup();
audio_lock();
+
vg_profile_increment( &_vg_prof_audio_decode );
vg_profile_increment( &_vg_prof_audio_mix );
VG_STATIC void audio_player_set_vol( audio_player *sys, float vol )
{
audio_require_lock();
+
+ if( !vg_validf(vol) )
+ {
+ vg_warn( "NaN volume (%s)\n", sys->name );
+ vol = 0.0f;
+ }
+
+ if( (vol < 0.0f) || (vol > 100.0f) )
+ {
+ vg_warn( "Invalid volume (%s: %f)\n", sys->name, vol );
+ vol = 0.0f;
+ }
+
sys->info.vol = vol;
}
return sys->info.flags;
}
+VG_STATIC void audio_set_master_vol( float vol )
+{
+ audio_require_lock();
+ vg_audio.volume_target = vol;
+}
+
+VG_STATIC void audio_push_console_vol(void)
+{
+ audio_lock();
+ audio_set_master_vol( vg_audio.volume_console );
+ audio_unlock();
+}
/*
* Debugging
wpos[3] = 1.0f;
m4x4_mulv( mtx_pv, wpos, wpos );
- if( wpos[3] < 0.0f )
+ if( wpos[3] <= 0.0f )
goto projected_behind;
v2_muls( wpos, (1.0f/wpos[3]) * 0.5f, wpos );
#define VG_PIf 3.14159265358979323846264338327950288f
#define VG_TAUf 6.28318530717958647692528676655900576f
+static u32 vg_ftu32( float a )
+{
+ u32 *ptr = (u32 *)(&a);
+ return *ptr;
+}
+
+static int vg_isinff( float a )
+{
+ return ((vg_ftu32(a)) & 0x7FFFFFFFU) == 0x7F800000U;
+}
+
+static int vg_isnanf( float a )
+{
+ return !vg_isinff(a) && ((vg_ftu32(a)) & 0x7F800000U) == 0x7F800000U;
+}
+
+static int vg_validf( float a )
+{
+ return ((vg_ftu32(a)) & 0x7F800000U) != 0x7F800000U;
+}
+
static inline float vg_minf( float a, float b )
{
return a < b? a: b;
static inline void v3_div( v3f a, v3f b, v3f d )
{
- d[0] = a[0]/b[0]; d[1] = a[1]/b[1]; d[2] = a[2]/b[2];
+ d[0] = b[0]!=0.0f? a[0]/b[0]: INFINITY;
+ d[1] = b[1]!=0.0f? a[1]/b[1]: INFINITY;
+ d[2] = b[2]!=0.0f? a[2]/b[2]: INFINITY;
}
static inline void v3_muls( v3f a, float s, v3f d )
d[0] = a[0]*s; d[1] = a[1]*s; d[2] = a[2]*s;
}
+static inline void v3_fill( v3f a, float v )
+{
+ a[0] = v;
+ a[1] = v;
+ a[2] = v;
+}
+
static inline void v3_divs( v3f a, float s, v3f d )
{
- d[0] = a[0]/s; d[1] = a[1]/s; d[2] = a[2]/s;
+ if( s == 0.0f )
+ v3_fill( d, INFINITY );
+ else
+ {
+ d[0] = a[0]/s;
+ d[1] = a[1]/s;
+ d[2] = a[2]/s;
+ }
}
static inline void v3_muladds( v3f a, v3f b, float s, v3f d )
return vg_maxf( vg_maxf( a[0], a[1] ), a[2] );
}
-static inline void v3_fill( v3f a, float v )
-{
- a[0] = v;
- a[1] = v;
- a[2] = v;
-}
-
static inline void v3_floor( v3f a, v3f b )
{
b[0] = floorf( a[0] );
static inline float v4_dot( v4f a, v4f b )
{
- return a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*a[3];
+ return a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3];
}
static inline float v4_length( v4f a )
v3_sub( box[0], co, v0 );
v3_sub( box[1], co, v1 );
+
v3_div( v0, dir, v0 );
v3_div( v1, dir, v1 );
{ 0.0f, 0.0f, 0.0f, 0.0f }}
static void m4x4_projection( m4x4f m, float angle,
- float ratio, float fnear, float ffar )
+ float ratio, float fnear, float ffar )
{
float scale = tanf( angle * 0.5f * VG_PIf / 180.0f ) * fnear,
r = ratio * scale,
t = scale,
b = -t;
- m[0][0] = 2.0f * fnear / (r - l);
- m[0][1] = 0.0f;
- m[0][2] = 0.0f;
- m[0][3] = 0.0f;
- m[1][0] = 0.0f;
- m[1][1] = 2.0f * fnear / (t - b);
- m[1][2] = 0.0f;
- m[1][3] = 0.0f;
- m[2][0] = (r + l) / (r - l);
- m[2][1] = (t + b) / (t - b);
- m[2][2] = -(ffar + fnear) / (ffar - fnear);
- m[2][3] = -1.0f;
- m[3][0] = 0.0f;
- m[3][1] = 0.0f;
- m[3][2] = -2.0f * ffar * fnear / (ffar - fnear);
+ m[0][0] = 2.0f * fnear / (r - l);
+ m[0][1] = 0.0f;
+ m[0][2] = 0.0f;
+ m[0][3] = 0.0f;
+
+ m[1][0] = 0.0f;
+ m[1][1] = 2.0f * fnear / (t - b);
+ m[1][2] = 0.0f;
+ m[1][3] = 0.0f;
+
+ m[2][0] = (r + l) / (r - l);
+ m[2][1] = (t + b) / (t - b);
+ m[2][2] = -(ffar + fnear) / (ffar - fnear);
+ m[2][3] = -1.0f;
+
+ m[3][0] = 0.0f;
+ m[3][1] = 0.0f;
+ m[3][2] = -2.0f * ffar * fnear / (ffar - fnear);
m[3][3] = 0.0f;
}