{
vg_info( "SDL_INIT\n" );
- if( SDL_Init( SDL_INIT_VIDEO ) != 0 )
- {
+ if( SDL_Init( SDL_INIT_VIDEO ) != 0 ){
vg_error( "SDL_Init failed: %s\n", SDL_GetError() );
exit(0);
}
*/
vg_info( "Getting display count\n" );
int display_count = 0, display_index = 0, mode_index = 0;
- if( (display_count = SDL_GetNumVideoDisplays()) < 1 )
- {
+ if( (display_count = SDL_GetNumVideoDisplays()) < 1 ){
vg_error( "SDL_GetNumVideoDisplays returned: %i\n", display_count );
exit(0);
}
SDL_Quit();
}
-/*
- * Immediately transfer away from calling thread into a safe loop, signal for
- * others to shutdown, then free everything once the user closes the window.
- *
- * FIXME(bug): glfwWindowShouldClose() never returns 1 in windows via wine, ONLY
- * when calling the program from outside its normal directory.
- */
-VG_STATIC void vg_fatal_exit_loop( const char *error )
+void vg_print_backtrace(void)
{
- /*
- * https://www.gnu.org/software/libc/manual/html_node/Backtraces.html
- * thanks gnu <3
- *
- * TODO: this on windows?
- */
-
#ifndef _WIN32
void *array[20];
free( strings );
#endif
+}
+
+/*
+ * Immediately transfer away from calling thread into a safe loop, signal for
+ * others to shutdown, then free everything once the user closes the window.
+ *
+ * FIXME(bug): glfwWindowShouldClose() never returns 1 in windows via wine, ONLY
+ * when calling the program from outside its normal directory.
+ */
+VG_STATIC void vg_fatal_exit_loop( const char *error )
+{
+ /*
+ * https://www.gnu.org/software/libc/manual/html_node/Backtraces.html
+ * thanks gnu <3
+ *
+ * TODO: this on windows?
+ */
+ vg_print_backtrace();
vg_error( "Fatal error: %s\n", error );
SDL_AtomicLock( &vg.sl_context );
/* synchro */
int sync_locked;
- SDL_mutex *mux_checker,
- *mux_sync;
+ SDL_SpinLock sl_checker,
+ sl_sync;
struct audio_lfo{
u32 time, time_startframe;
}
channels[ AUDIO_CHANNELS ];
- /* System queue, and access from thread 0 */
int debug_ui, debug_ui_3d;
- v3f listener_pos,
- listener_ears,
- listener_velocity;
+ v3f internal_listener_pos,
+ internal_listener_ears,
+ internal_listener_velocity,
- float volume,
- volume_target,
- volume_target_internal,
- volume_console;
+ external_listener_pos,
+ external_listener_ears,
+ external_lister_velocity;
+
+ float internal_global_volume,
+ external_global_volume;
}
-vg_audio = { .volume_console = 1.0f };
+vg_audio = { .external_global_volume = 1.0f };
#include "vg/vg_audio_dsp.h"
VG_STATIC int audio_lock_checker_load(void)
{
int value;
- SDL_LockMutex( vg_audio.mux_checker );
+ SDL_AtomicLock( &vg_audio.sl_checker );
value = vg_audio.sync_locked;
- SDL_UnlockMutex( vg_audio.mux_checker );
+ SDL_AtomicUnlock( &vg_audio.sl_checker );
return value;
}
VG_STATIC void audio_lock_checker_store( int value )
{
- SDL_LockMutex( vg_audio.mux_checker );
+ SDL_AtomicLock( &vg_audio.sl_checker );
vg_audio.sync_locked = value;
- SDL_UnlockMutex( vg_audio.mux_checker );
+ SDL_AtomicUnlock( &vg_audio.sl_checker );
}
VG_STATIC void audio_require_lock(void)
VG_STATIC void audio_lock(void)
{
- SDL_LockMutex( vg_audio.mux_sync );
+ SDL_AtomicLock( &vg_audio.sl_sync );
audio_lock_checker_store(1);
}
VG_STATIC void audio_unlock(void)
{
audio_lock_checker_store(0);
- SDL_UnlockMutex( vg_audio.mux_sync );
+ SDL_AtomicUnlock( &vg_audio.sl_sync );
}
VG_STATIC void audio_mixer_callback( void *user, u8 *stream, int frame_count );
VG_STATIC void vg_audio_init(void)
{
- vg_audio.mux_checker = SDL_CreateMutex();
- vg_audio.mux_sync = SDL_CreateMutex();
-
/* TODO: Move here? */
vg_var_push( (struct vg_var){
.name = "debug_audio",
vg_var_push( (struct vg_var){
.name = "volume",
- .data = &vg_audio.volume_console,
+ .data = &vg_audio.external_global_volume,
.data_type = k_var_dtype_f32,
.opt_f32 = { .min=0.0f, .max=2.0f, .clamp=1 },
.persistent = 1
ch->editble_state_write_mask = 0x00;
}
+static void audio_channel_group( audio_channel *ch, u32 group )
+{
+ ch->group = group;
+ ch->colour = ((group * 29986577) & 0x00ffffff) | 0xff000000;
+}
+
static audio_channel *audio_get_first_idle_channel(void)
{
for( int i=0; i<AUDIO_CHANNELS; i++ ){
static audio_channel *audio_get_group_idle_channel( u32 group, u32 max_count )
{
u32 count = 0;
- audio_channel *dest;
+ audio_channel *dest = NULL;
for( int i=0; i<AUDIO_CHANNELS; i++ ){
audio_channel *ch = &vg_audio.channels[i];
static void audio_channel_mix( audio_channel *ch, float *buffer )
{
- float framevol_l = 1.0f,
- framevol_r = 1.0f;
+ float framevol_l = vg_audio.internal_global_volume,
+ framevol_r = vg_audio.internal_global_volume;
float frame_samplerate = ch->_.sampling_rate;
if( ch->flags & AUDIO_FLAG_SPACIAL_3D ){
v3f delta;
- v3_sub( ch->_.spacial_falloff, vg_audio.listener_pos, delta );
+ v3_sub( ch->_.spacial_falloff, vg_audio.internal_listener_pos, delta );
float dist = v3_length( delta ),
vol = vg_maxf( 0.0f, 1.0f - ch->_.spacial_falloff[3]*dist );
}
else{
v3_muls( delta, 1.0f/dist, delta );
- float pan = v3_dot( vg_audio.listener_ears, delta );
+ float pan = v3_dot( vg_audio.internal_listener_ears, delta );
vol = powf( vol, 5.0f );
framevol_l *= (vol * 0.5f) * (1.0f - pan);
framevol_r *= (vol * 0.5f) * (1.0f + pan);
- const float vs = 323.0f;
- float doppler = (vs+v3_dot(delta,vg_audio.listener_velocity))/vs;
- doppler = vg_clampf( doppler, 0.6f, 1.4f );
-
- if( fabsf(doppler-1.0f) > 0.01f )
- frame_samplerate *= doppler;
+ if( !(ch->source->flags & AUDIO_FLAG_NO_DOPPLER) ){
+ const float vs = 323.0f;
+
+ float dv = v3_dot(delta,vg_audio.internal_listener_velocity);
+ float doppler = (vs+dv)/vs;
+ doppler = vg_clampf( doppler, 0.6f, 1.4f );
+
+ if( fabsf(doppler-1.0f) > 0.01f )
+ frame_samplerate *= doppler;
+ }
}
if( !vg_validf( framevol_l ) ) vg_fatal_exit_loop( "NaN left channel" );
const float volume_target = ch->_.volume_target;
for( u32 j=0; j<AUDIO_MIX_FRAME_SIZE; j++ ){
- /*
- * there is some REALLY weird behaviour with minss,
- * i cannot begin to guess what the cause is, but the bahaviour when
- * the second argument is not 1.0 would seemingly tripple or up to
- * eight times this routine.
- *
- * the times it would happen are when moving from empty space into areas
- * with geometry. in the bvh for skate rift.
- *
- * it should be completely unrelated to this, but somehow -- it is
- * effecting the speed of minss. and severely at that too.
- **/
-
volume_movement += 1.0f;
float movement_t = volume_movement * inv_volume_rate;
- movement_t = vg_minf( volume_movement, 1.0f );
+ movement_t = vg_minf( movement_t, 1.0f );
volume = vg_lerpf( volume_start, volume_target, movement_t );
float vol_norm = volume * volume;
* Copy data and move edit flags to commit flags
* ------------------------------------------------------------- */
audio_lock();
+
+ v3_copy( vg_audio.external_listener_pos, vg_audio.internal_listener_pos );
+ v3_copy( vg_audio.external_listener_ears, vg_audio.internal_listener_ears );
+ v3_copy( vg_audio.external_lister_velocity,
+ vg_audio.internal_listener_velocity );
+ vg_audio.internal_global_volume = vg_audio.external_global_volume;
+
for( int i=0; i<AUDIO_CHANNELS; i++ ){
audio_channel *ch = &vg_audio.channels[i];
v2_add( wpos, (v2f){ 0.5f, 0.5f }, wpos );
ui_rect wr;
- wr[0] = wpos[0] * vg.window_x;
- wr[1] = (1.0f-wpos[1]) * vg.window_y;
+ wr[0] = vg_clampf(wpos[0] * vg.window_x, -32000.0f,32000.0f);
+ wr[1] = vg_clampf((1.0f-wpos[1]) * vg.window_y,-32000.0f,32000.0f);
wr[2] = 100;
wr[3] = 17;
{
u32 total = 0;
- for( int i=0; i<bird->settings.pattern_length; i ++ )
- {
+ for( int i=0; i<bird->settings.pattern_length; i ++ ){
struct synth_bird_signature *sig = &bird->settings.pattern[i];
u32 l = sig->length * (float)BIRD_SAMPLE_RATE,
VG_STATIC void *vg_file_read( void *lin_alloc, const char *path, u32 *size )
{
FILE *f = fopen( path, "rb" );
- if( f )
- {
+ if( f ){
void *buffer = vg_linear_alloc( lin_alloc, 0 );
u64 current = 0;
/* read in chunks */
- for( u32 i=0; 1; i++ )
- {
+ for( u32 i=0; 1; i++ ){
buffer = vg_linear_extend( lin_alloc, buffer, VG_FILE_IO_CHUNK_SIZE );
u64 l = fread( buffer + current, 1, VG_FILE_IO_CHUNK_SIZE, f );
current += l;
- if( l != VG_FILE_IO_CHUNK_SIZE )
- {
- if( feof( f ) )
- {
+ if( l != VG_FILE_IO_CHUNK_SIZE ){
+ if( feof( f ) ){
break;
}
- else
- {
- if( ferror( f ) )
- {
+ else{
+ if( ferror( f ) ){
fclose(f);
vg_fatal_exit_loop( "read error" );
}
- else
- {
+ else{
fclose(f);
vg_fatal_exit_loop( "unknown error codition" );
}
}
}
- buffer = vg_linear_resize( lin_alloc, buffer, current );
+ buffer = vg_linear_resize( lin_alloc, buffer, vg_align8(current) );
fclose( f );
*size = (u32)current;
vg_uictx.cursor[3] = fh;
ui_fill_x();
- for( int i=0; i<lines_to_draw; i ++ )
- {
+ for( int i=0; i<lines_to_draw; i ++ ){
ptr --;
if( ptr < 0 )
char *dest = vg_log.buffer[ vg_log.buffer_line_current ++ ];
- for( int i=0; i<vg_list_size( vg_log.buffer[0] ); i++ )
- {
- if( !str[i] || ( i == vg_list_size(vg_log.buffer[0])-1 ) )
- {
+ for( int i=0; i<vg_list_size( vg_log.buffer[0] ); i++ ){
+ if( !str[i] || ( i == vg_list_size(vg_log.buffer[0])-1 ) ){
dest[i] = '\0';
break;
}
char buffer[ 4096 ];
int i, j;
- for( i=0; i<vg_list_size( buffer ); i ++ )
- {
+ for( i=0; i<vg_list_size( buffer ); i ++ ){
if( prefix[i] )
buffer[i] = prefix[i];
else
#include <stdlib.h>
#include <malloc.h>
+void vg_print_backtrace(void);
+
#define VG_MAX_ALLOCATIONS 128
#define VG_FUZZ_ALLOCATIONS
__attribute__((warn_unused_result))
VG_STATIC void *vg_linear_alloc( void *buffer, u32 size )
{
- if( size % 8 )
- {
+ if( size % 8 ){
vg_error( "alloc(%u) is not 8 byte aligned\n", size );
+ vg_print_backtrace();
size = vg_align8( size );
}
+ if( ((u64)buffer) % 8 ){
+ vg_error( "buffer: %p\n", buffer );
+ vg_fatal_exit_loop( "unaligned buffer" );
+ }
vg_linear_allocator *alloc = vg_linear_header( buffer );
- if( (alloc->cur + size) > alloc->size )
- {
+ if( (alloc->cur + size) > alloc->size ){
vg_error( "%u + %u > %u\n", alloc->cur, size, alloc->size );
vg_fatal_exit_loop( "linear allocator overflow" );
}
void *data;
- if( vg_mem.use_libc_malloc && (alloc->flags & VG_MEMORY_SYSTEM) )
- {
+ if( vg_mem.use_libc_malloc && (alloc->flags & VG_MEMORY_SYSTEM) ){
data = malloc( size );
vg_allocation_meta *meta = &alloc->alloc_table[ alloc->allocation_count ];
meta->type = k_allocation_type_block;
meta->data = data;
}
- else
- {
+ else{
data = buffer + alloc->cur;
}
+ u8 *bytes = data;
+ for( u32 i=0; i<size; i++ ){
+ bytes[i] = 0xae;
+ }
+
alloc->allocation_count ++;
alloc->last_alloc = data;
alloc->last_alloc_size = size;
alloc->cur += size;
+ if( ((u64)data) % 8 ){
+ vg_fatal_exit_loop( "unaligned" );
+ }
+
return data;
}
-
/* resize latest block of memory from linear */
__attribute__((warn_unused_result))
VG_STATIC void *vg_linear_resize( void *buffer, void *data, u32 newsize )
{
vg_linear_allocator *alloc = vg_linear_header( buffer );
+ if( newsize % 8 ){
+ vg_error( "alloc(%u) is not 8 byte aligned\n", newsize );
+ vg_print_backtrace();
+ newsize = vg_align8( newsize );
+ }
+
if( alloc->last_alloc != data )
vg_fatal_exit_loop( "This block has been fixed!" );
alloc->cur += newsize;
alloc->last_alloc_size = newsize;
- if( vg_mem.use_libc_malloc && (alloc->flags & VG_MEMORY_SYSTEM) )
- {
+ if( vg_mem.use_libc_malloc && (alloc->flags & VG_MEMORY_SYSTEM) ){
data = realloc( data, newsize );
if( !data )
vg_fatal_exit_loop( "realloc failed" );
alloc->last_alloc = data;
return data;
}
- else
- {
+ else{
return data;
}
}
if( alloc->last_alloc != data )
vg_fatal_exit_loop( "This block has been fixed!" );
- if( vg_mem.use_libc_malloc && (alloc->flags & VG_MEMORY_SYSTEM) )
- {
+ if( vg_mem.use_libc_malloc && (alloc->flags & VG_MEMORY_SYSTEM) ){
vg_allocation_meta *meta = &alloc->alloc_table[alloc->allocation_count-1];
if( meta->type == k_allocation_type_linear )
vg_fatal_exit_loop( "Cannot free a linear allocator in this conext" );
vg_linear_allocator *alloc = vg_linear_header( buffer );
/* libc mode we recursively free any allocations made */
- if( vg_mem.use_libc_malloc && (alloc->flags & VG_MEMORY_SYSTEM) )
- {
- for( u32 i=0; i<alloc->allocation_count; i++ )
- {
+ if( vg_mem.use_libc_malloc && (alloc->flags & VG_MEMORY_SYSTEM) ){
+ for( u32 i=0; i<alloc->allocation_count; i++ ){
vg_allocation_meta *meta = &alloc->alloc_table[i];
- if( meta->type == k_allocation_type_block )
- {
+ if( meta->type == k_allocation_type_block ){
free( meta->data );
}
- else
- {
+ else{
vg_linear_clear( meta->data );
vg_linear_allocator *sub = vg_linear_header( meta->data );
u32 block_size = size + sizeof(vg_linear_allocator);
/* Creating it inside an existing one */
- if( lin_alloc )
- {
+ if( lin_alloc ){
vg_linear_allocator *alloc = vg_linear_header( lin_alloc );
if( alloc->cur + block_size > alloc->size )
vg_fatal_exit_loop( "Cannot declare realtime allocator inside systems"
" allocator" );
- if( vg_mem.use_libc_malloc )
- {
+ if( vg_mem.use_libc_malloc ){
vg_allocation_meta *meta =
&alloc->alloc_table[ alloc->allocation_count ];
meta->data = header+1;
meta->type = k_allocation_type_linear;
}
- else
- {
+ else{
header = lin_alloc + alloc->cur;
}
header->size = size;
header->flags = flags;
- if( vg_mem.use_libc_malloc && (flags & VG_MEMORY_SYSTEM) )
- {
+ if( vg_mem.use_libc_malloc && (flags & VG_MEMORY_SYSTEM) ){
u32 table_size = sizeof(vg_allocation_meta)*VG_MAX_ALLOCATIONS;
header->alloc_table = malloc( table_size );
}
u32 pixels = 0, total = 256*256, data = 0;
u8 image[256*256];
- while( pixels < total )
- {
- for( int b = 31; b >= 0; b-- )
- {
- image[ pixels ++ ] = (compressed[data] & (0x1 << b))? 0xff: 0x00;
+ while( pixels < total ){
+ for( int b = 31; b >= 0; b-- ){
+ image[ pixels ++ ] = (compressed[data] & (0x1u << b))? 0xffu: 0x00u;
- if( pixels >= total )
- {
+ if( pixels >= total ){
total = 0;
break;
}
text_cursor[2] = 8*scale;
text_cursor[3] = 14*scale;
- while( (c = *(_c ++)) )
- {
- if( c == '\n' )
- {
+ while( (c = *(_c ++)) ){
+ if( c == '\n' ){
text_cursor[1] += 14*scale;
text_cursor[0] = pos[0] + ui_text_line_offset( _c, scale, align );
continue;
}
- else if( c >= 33 )
- {
+ else if( c >= 33 ){
u8 glyph_base[2];
u8 glyph_index = c;
glyph_base[0] = glyph_index & 0xf;
glyph_base[1]+8
});
}
- else if( c == '\x1B' )
- {
+ else if( c == '\x1B' ){
_c ++;
u16 colour_id = 0;
- for( int i = 0; i < 3; i ++ )
- {
- if( _c[i] )
- {
- if( _c[i] == 'm' )
- {
+ for( int i = 0; i < 3; i ++ ){
+ if( _c[i] ){
+ if( _c[i] == 'm' ){
_c = _c + i + 1;
- switch( colour_id )
- {
+ switch( colour_id ){
case '0': current_colour = 0x00ffffff; break;
case '3'|'1'<<8: current_colour = 0x00201fee; break;
case '3'|'2'<<8: current_colour = 0x0037e420; break;
colour_id |= _c[i] << (i*8);
}
- else
- {
+ else{
_c = _c +i;
break;
}
continue;
}
- else if( c == '\t' )
- {
+ else if( c == '\t' ){
text_cursor[0] += UI_GLYPH_SPACING_X*scale*4;
continue;
}