adjust fatal errors
authorhgn <hgodden00@gmail.com>
Fri, 6 Sep 2024 02:02:08 +0000 (03:02 +0100)
committerhgn <hgodden00@gmail.com>
Fri, 6 Sep 2024 02:02:08 +0000 (03:02 +0100)
38 files changed:
vg_async.c
vg_audio.c
vg_audio_dsp.c
vg_build.h
vg_build_utils_shader.h
vg_bvh.c
vg_console.c
vg_engine.c
vg_engine.h
vg_framebuffer.c
vg_input.c
vg_io.c
vg_io.h
vg_lines.c
vg_loader.c
vg_loader.h
vg_log.c
vg_log.h
vg_mem.c
vg_mem.h
vg_mem_pool.c
vg_msg.c
vg_opengl.c [new file with mode: 0644]
vg_opengl.h
vg_platform.h
vg_profiler.c
vg_rigidbody.c
vg_rigidbody_collision.c
vg_rigidbody_view.c
vg_shader.c
vg_shader.h
vg_steam.c
vg_string.c
vg_tex.c
vg_tool.c
vg_tool.h
vg_ui/imgui.c
vg_ui/imgui_impl_opengl.c

index 7916282cb6e588369132197ffa2b9f2616fe90f6..9a3da53d1a77931ba7357921f753311096543df7 100644 (file)
@@ -18,16 +18,19 @@ vg_async_item *vg_async_alloc( u32 size )
        remaining        = vg_linear_remaining( vg_async.buffer ),
        capacity         = vg_linear_get_capacity( vg_async.buffer );
 
-   if( total_allocation > capacity ){
+   if( total_allocation > capacity )
+   {
       SDL_AtomicUnlock( &vg_async.sl_index );
-      vg_error( "Requested: %umb. Buffer size: %umb\n",
+      vg_fatal_condition();
+      vg_info( "async alloc invalid size\n" );
+      vg_info( "Requested: %umb. Buffer size: %umb\n",
                   (total_allocation/1024)/1024,
                   (capacity/1024)/1024 );
-
-      vg_fatal_error( "async alloc invalid size\n" );
+      vg_fatal_exit();
    }
 
-   if( total_allocation > remaining ){
+   if( total_allocation > remaining )
+   {
       SDL_AtomicUnlock( &vg_async.sl_index );
       SDL_SemWait( vg_async.sem_wait_for_flush );
       SDL_AtomicLock( &vg_async.sl_index );
@@ -65,14 +68,14 @@ vg_async_item *vg_async_alloc( u32 size )
  */
 void vg_async_stall(void)
 {
-   vg_assert_thread(k_thread_purpose_loader);
+   VG_ASSERT( vg_thread_purpose() == k_thread_purpose_loader );
    SDL_SemWait( vg_async.sem_wait_for_flush );
 }
 
 void vg_async_dispatch( vg_async_item *item, 
                         void (*runner)( void *payload, u32 size ) )
 {
-   vg_assert_thread(k_thread_purpose_loader);
+   VG_ASSERT( vg_thread_purpose() == k_thread_purpose_loader );
    if( SDL_SemValue(vg_async.sem_wait_for_flush) )
       SDL_SemWait(vg_async.sem_wait_for_flush);
 
@@ -84,7 +87,7 @@ void vg_async_dispatch( vg_async_item *item,
 void vg_async_call( void (*runner)( void *payload, u32 size ), 
                     void *payload, u32 size )
 {
-   vg_assert_thread(k_thread_purpose_loader);
+   VG_ASSERT( vg_thread_purpose() == k_thread_purpose_loader );
    vg_async_item *call = vg_async_alloc(0);
    call->payload = payload;
    call->size = size;
index 99b43822ba69e915bc71ff814214137f5892fd88..e7bc7e59a76a69cf2bacfc6f559cd7350b4cbfcc 100644 (file)
@@ -631,22 +631,22 @@ static void audio_channel_mix( audio_channel *ch, float *buffer )
 
       if( !vg_validf( framevol_l ) || 
           !vg_validf( framevol_r ) ||
-          !vg_validf( frame_samplerate ) ){
-         vg_fatal_error( "Invalid sampling conditions.\n"
-                         "This crash is to protect your ears.\n"
-                         "  channel: %p (%s)\n"
-                         "  sample_rate: %f\n"
-                         "  volume: L%f R%f\n"
-                         "  listener: %.2f %.2f %.2f [%.2f %.2f %.2f]\n",
-                         ch, ch->name, frame_samplerate, 
-                         framevol_l, framevol_r,
-                         vg_audio.internal_listener_pos[0],
-                         vg_audio.internal_listener_pos[1],
-                         vg_audio.internal_listener_pos[2],
-                         vg_audio.internal_listener_ears[0],
-                         vg_audio.internal_listener_ears[1],
-                         vg_audio.internal_listener_ears[2]
-                         );
+          !vg_validf( frame_samplerate ) )
+      {
+         vg_fatal_condition();
+         vg_info( "Invalid sampling conditions.\n"
+                  "This crash is to protect your ears.\n" );
+         vg_info( "  channel: %p (%s)\n", ch, ch->name );
+         vg_info( "  sample_rate: %f\n", frame_samplerate );
+         vg_info( "  volume: L%f R%f\n", framevol_l, framevol_r );
+         vg_info( "  listener: %.2f %.2f %.2f [%.2f %.2f %.2f]\n",
+                  vg_audio.internal_listener_pos[0],
+                  vg_audio.internal_listener_pos[1],
+                  vg_audio.internal_listener_pos[2],
+                  vg_audio.internal_listener_ears[0],
+                  vg_audio.internal_listener_ears[1],
+                  vg_audio.internal_listener_ears[2] );
+         vg_fatal_exit();
       }
    }
 
@@ -983,9 +983,11 @@ void audio_clip_load( audio_clip *clip, void *lin_alloc )
     *       NULL when we get the clip
     */
 
-   if( format == k_audio_format_vorbis ){
-      if( !clip->path ){
-         vg_fatal_error( "No path specified, embeded vorbis unsupported" );
+   if( format == k_audio_format_vorbis )
+   {
+      if( !clip->path )
+      {
+         vg_error( "No path specified, embeded vorbis unsupported\n" );
       }
 
       audio_lock();
@@ -993,17 +995,22 @@ void audio_clip_load( audio_clip *clip, void *lin_alloc )
       audio_unlock();
 
       if( !clip->data )
-         vg_fatal_error( "Audio failed to load" );
+      {
+         vg_error( "Audio failed to load\n" );
+      }
 
       float mb = (float)(clip->size) / (1024.0f*1024.0f);
       vg_info( "Loaded audio clip '%s' (%.1fmb)\n", clip->path, mb );
    }
-   else if( format == k_audio_format_stereo ){
-      vg_fatal_error( "Unsupported format (Stereo uncompressed)" );
+   else if( format == k_audio_format_stereo )
+   {
+      vg_error( "Unsupported format (Stereo uncompressed)\n" );
    }
-   else if( format == k_audio_format_bird ){
-      if( !clip->data ){
-         vg_fatal_error( "No data, external birdsynth unsupported" );
+   else if( format == k_audio_format_bird )
+   {
+      if( !clip->data )
+      {
+         vg_error( "No data, external birdsynth unsupported\n" );
       }
 
       u32 total_size  = clip->size + sizeof(struct synth_bird);
@@ -1011,7 +1018,9 @@ void audio_clip_load( audio_clip *clip, void *lin_alloc )
           total_size  = vg_align8( total_size );
 
       if( total_size > AUDIO_DECODE_SIZE )
-         vg_fatal_error( "Bird coding too long\n" );
+      {
+         vg_error( "Bird coding too long, and exceeds maximum decode size\n" );
+      }
 
       struct synth_bird *bird = vg_linear_alloc( lin_alloc, total_size );
       memcpy( &bird->settings, clip->data, clip->size );
@@ -1021,9 +1030,11 @@ void audio_clip_load( audio_clip *clip, void *lin_alloc )
 
       vg_info( "Loaded bird synthesis pattern (%u bytes)\n", total_size );
    }
-   else{
-      if( !clip->path ){
-         vg_fatal_error( "No path specified, embeded mono unsupported" );
+   else
+   {
+      if( !clip->path )
+      {
+         vg_error( "No path specified, embeded mono unsupported\n" );
       }
 
       vg_linear_clear( vg_mem.scratch );
@@ -1040,10 +1051,13 @@ void audio_clip_load( audio_clip *clip, void *lin_alloc )
       stb_vorbis *decoder = stb_vorbis_open_memory( 
                             filedata, fsize, &err, &alloc );
 
-      if( !decoder ){
-         vg_error( "stb_vorbis_open_memory failed on '%s' (%d)\n", 
+      if( !decoder )
+      {
+         vg_fatal_condition();
+         vg_info( "Vorbis decode error\n" );
+         vg_info( "stb_vorbis_open_memory failed on '%s' (%d)\n", 
                      clip->path, err );
-         vg_fatal_error( "Vorbis decode error" );
+         vg_fatal_exit();
       }
 
       /* only mono is supported in uncompressed */
@@ -1059,13 +1073,9 @@ void audio_clip_load( audio_clip *clip, void *lin_alloc )
                               decoder, clip->data, length_samples );
 
       if( read_samples != length_samples )
-         vg_fatal_error( "Decode error" );
-
-#if 0
-      float mb = (float)(data_size) / (1024.0f*1024.0f);
-      vg_info( "Loaded audio clip '%s' (%.1fmb) %u samples\n", clip->path, mb,
-               length_samples );
-#endif
+      {
+         vg_error( "Decode error, read_samples did not match length_samples\n" );
+      }
    }
 }
 
@@ -1081,6 +1091,7 @@ static void audio_require_clip_loaded( audio_clip *clip )
       return;
 
    audio_unlock();
+
    vg_fatal_error( "Must load audio clip before playing! \n" );
 }
 
index 3714e32e2b5dac58b5895f2476f2ff1e7fe3a899..e362b3e4fb763705ed37cf60f385a58b62b23e8a 100644 (file)
@@ -9,7 +9,10 @@ float *dsp_allocate( u32 samples )
    samples = vg_align4( samples );
 
    if( vg_dsp.allocations + samples > (1024*1024)/4 )
-      vg_fatal_error( "too much dsp" );
+   {
+      vg_fatal_error( "Ran out of memory in the DSP buffer\n"
+                      "  Request was %u samples\n", samples );
+   }
 
    float *buf = &vg_dsp.buffer[ vg_dsp.allocations ];
    vg_dsp.allocations += samples;
index 5fce6f06127bfe2a364fa601656764455cf54f01..9a1d861ab45f12c05ccc57c7809d86eb5cdf7529 100644 (file)
@@ -224,14 +224,26 @@ vg_compiler_run( struct vg_project *project,
 {
    /* check for problems in configuration */
    if( env->libc != k_libc_version_native )
+   {
       if( env->compiler != k_compiler_zigcc )
-         vg_fatal_error( 
+      {
+         vg_fatal_condition();
+         vg_info(
                "Cannot specify libc version using the '%s' compiler.\n",
                compiler_names[ env->compiler ] );
+         vg_fatal_exit();
+      }
+   }
 
    if( env->compiler == k_compiler_clang )
+   {
       if( env->platform != k_platform_linux )
-         vg_fatal_error( "Cannot compile for '%s' using the '%s' compiler;" );
+      {
+         vg_fatal_condition();
+         vg_info( "Cannot compile for '%s' using the '%s' compiler;" );
+         vg_fatal_exit();
+      }
+   }
 
    vg_str cmd = {0};
    vg_strcat( &cmd, "ccache " );
@@ -509,7 +521,12 @@ vg_make_app( struct vg_project *proj,
                               appname, k_obj_type_exe );
    }
    else
-      vg_fatal_error( "Programming error" );
+   {
+      vg_fatal_condition();
+      vg_info( "No compile procedure set for platform '%s'\n", 
+            platform_names[env->platform] );
+      vg_fatal_exit();
+   }
 
    return (struct compile_result){};
 }
index 0bbb81631af3e442adf9c6a4d90352f6f44c9a68..235c67c04f6f156b8a9d3f87800a184c35692642 100644 (file)
@@ -187,11 +187,7 @@ int vg_build_shader( char *src_vert, /* path/to/vert.vs    */
 
    FILE *header = fopen( path_header, "w" );
    if( !header )
-   {
-      fprintf(stderr, "Could not open '%s'\n", path_header );
-      vg_fatal_error( "IO error" );
-      return 0;
-   }
+      vg_fatal_error( "Could not open '%s'\n", path_header );
    
    fprintf( header, "#pragma once\n" );
    fprintf( header, "#include \"vg/vg_engine.h\"\n" );
@@ -206,7 +202,6 @@ int vg_build_shader( char *src_vert, /* path/to/vert.vs    */
    {
       fclose( header );
       vg_fatal_error( "Failed to assemble vertex source code" );
-      return 0;
    }
 
    vg_strcatf( c_body, "\n   .fs = \n" );
@@ -214,7 +209,6 @@ int vg_build_shader( char *src_vert, /* path/to/vert.vs    */
    {
       fclose( header );
       vg_fatal_error( "Failed to assemble fragment source code" );
-      return 0;
    }
 
    vg_strcatf( c_body, "\n};\n\n" );
@@ -254,7 +248,7 @@ int vg_build_shader( char *src_vert, /* path/to/vert.vs    */
       if( uf->array ) 
          continue;
 
-      for( int j=0; j<vg_list_size(types); j ++ )
+      for( int j=0; j<VG_ARRAY_LEN(types); j ++ )
       {
          struct type_info *inf = &types[j];
 
index bf1ffc47bf2f5ad9ae6cf03051f16edf23381efa..b33b0315569b3b0e93d33edba7bf26884e353915 100644 (file)
--- a/vg_bvh.c
+++ b/vg_bvh.c
@@ -234,7 +234,7 @@ i32 bh_next( bh_tree *bh, bh_iter *it, i32 *em )
          }
       }
       else{
-         if( it->depth+1 >= vg_list_size(it->stack) ){
+         if( it->depth+1 >= VG_ARRAY_LEN(it->stack) ){
             vg_error( "Maximum stack reached!\n" );
             return 0;
          }
index 0f7387d04396fe1f1e1daaffd5c5af387eea1875..00d8e5f3d4d38f0aa42f653e8180507e16983b3d 100644 (file)
@@ -10,11 +10,8 @@ struct vg_console vg_console;
 void vg_console_reg_var( const char *alias, void *ptr, enum vg_var_dtype type, 
                          u32 flags )
 {
-   if( vg_thread_purpose() == k_thread_purpose_main ) 
-      vg_fatal_error( "FIXME: Cannot register VAR from main thread" );
-
-   if( vg_console.var_count > vg_list_size(vg_console.vars) )
-      vg_fatal_error( "Too many vars registered" );
+   VG_ASSERT( vg_thread_purpose() != k_thread_purpose_main );
+   VG_ASSERT( vg_console.var_count < VG_ARRAY_LEN(vg_console.vars) );
 
    vg_var *var = &vg_console.vars[ vg_console.var_count ++ ];
    var->name = alias;
@@ -29,11 +26,8 @@ void vg_console_reg_cmd( const char *alias,
                          int (*function)(int argc, const char *argv[]),
                          void (*poll_suggest)(int argc, const char *argv[]) )
 {
-   if( vg_thread_purpose() == k_thread_purpose_main ) 
-      vg_fatal_error( "FIXME: Cannot register CMD from main thread" );
-
-   if( vg_console.function_count > vg_list_size(vg_console.functions) )
-      vg_fatal_error( "Too many functions registered" );
+   VG_ASSERT( vg_thread_purpose() != k_thread_purpose_main );
+   VG_ASSERT( vg_console.function_count < VG_ARRAY_LEN(vg_console.functions) );
 
    vg_cmd *cmd = &vg_console.functions[ vg_console.function_count ++ ];
 
@@ -345,10 +339,10 @@ void console_suggest_score_text( const char *str, const char *input,
          best_pos = j;
    
    /* insert if good score */
-   if( best_pos < vg_list_size( vg_console.suggestions ) )
+   if( best_pos < VG_ARRAY_LEN( vg_console.suggestions ) )
    {
       int start = VG_MIN( vg_console.suggestion_count, 
-                          vg_list_size( vg_console.suggestions )-1 );
+                          VG_ARRAY_LEN( vg_console.suggestions )-1 );
       for( int j=start; j>best_pos; j -- )
          vg_console.suggestions[j] = vg_console.suggestions[j-1];
 
@@ -357,7 +351,7 @@ void console_suggest_score_text( const char *str, const char *input,
       vg_console.suggestions[ best_pos ].lev_score = score;
 
       if( vg_console.suggestion_count < 
-            vg_list_size( vg_console.suggestions ) )
+            VG_ARRAY_LEN( vg_console.suggestions ) )
          vg_console.suggestion_count ++;
    }
 }
@@ -452,7 +446,7 @@ static void _console_fetch_suggestion( ui_context *ctx )
    {
       strncpy( target,
             vg_console.suggestions[ vg_console.suggestion_select ].str,
-            vg_list_size( vg_console.input )-1 );
+            VG_ARRAY_LEN( vg_console.input )-1 );
 
       _ui_textbox_move_cursor( ctx,
                                &ctx->textbox.cursor_user,
@@ -515,7 +509,7 @@ static void console_history_get( char* buf, int entry_num )
        
    int offset = VG_MIN( entry_num, vg_console.history_count -1 ),
        pick = (vg_console.history_last - offset) % 
-               vg_list_size( vg_console.history );
+               VG_ARRAY_LEN( vg_console.history );
        strcpy( buf, vg_console.history[ pick ] );
 }
 
@@ -532,7 +526,7 @@ static void _vg_console_on_up( ui_context *ctx, char *buf, u32 len )
           vg_console.history_pos+1, 
           VG_MIN
           ( 
-            vg_list_size( vg_console.history ), 
+            VG_ARRAY_LEN( vg_console.history ), 
             vg_console.history_count - 1 
           )
         )
@@ -542,7 +536,7 @@ static void _vg_console_on_up( ui_context *ctx, char *buf, u32 len )
       _ui_textbox_move_cursor( ctx,
                                &ctx->textbox.cursor_user,
                                &ctx->textbox.cursor_pos,
-                               vg_list_size(vg_console.input)-1, 1 );
+                               VG_ARRAY_LEN(vg_console.input)-1, 1 );
    }
 }
 
@@ -556,7 +550,7 @@ static void _vg_console_on_down( ui_context *ctx, char *buf, u32 len )
       _ui_textbox_move_cursor( ctx, 
                                &ctx->textbox.cursor_user,
                                &ctx->textbox.cursor_pos,
-                               vg_list_size(vg_console.input)-1, 1 );
+                               VG_ARRAY_LEN(vg_console.input)-1, 1 );
    }
 }
 
@@ -573,9 +567,9 @@ static void _vg_console_on_enter( ui_context *ctx, char *buf, u32 len )
                   vg_console.history[ vg_console.history_last ]) )
       {
          vg_console.history_last = ( vg_console.history_last + 1) % 
-                                    vg_list_size(vg_console.history );
+                                    VG_ARRAY_LEN(vg_console.history );
          vg_console.history_count = 
-            VG_MIN( vg_list_size( vg_console.history ), 
+            VG_MIN( VG_ARRAY_LEN( vg_console.history ), 
                   vg_console.history_count + 1 );
          strcpy( vg_console.history[ vg_console.history_last ], 
                  vg_console.input );
@@ -673,7 +667,7 @@ void vg_console_draw( ui_context *ctx )
    {
       ptr --;
 
-      if( ptr < 0 ) ptr = vg_list_size( vg_log.log )-1;
+      if( ptr < 0 ) ptr = VG_ARRAY_LEN( vg_log.log )-1;
       
       ui_text( ctx, rect_line, vg_log.log[ptr], 1, k_ui_align_left, 0 );
       rect_line[1] -= fh;
@@ -691,7 +685,7 @@ void vg_console_draw( ui_context *ctx )
       .enter = _vg_console_on_enter,
    };
    ui_textbox( ctx, rect_input, NULL, 
-               vg_console.input, vg_list_size(vg_console.input), 1,
+               vg_console.input, VG_ARRAY_LEN(vg_console.input), 1,
                UI_TEXTBOX_AUTOFOCUS, &callbacks );
 
    /* 
index ddcda8f9f32a09ead6a9810112237a74efe0ac42..2470b49423c28048184c79aeff268b363c7d8c1c 100644 (file)
@@ -12,42 +12,34 @@ struct vg_engine vg =
 #include "vg/vg_ui/imgui_impl_opengl.c"
 #include "vg/vg_default_font.gc"
 
-#define TEMP_STATUS_LOCK      SDL_AtomicLock
-#define TEMP_STATUS_UNLOCK    SDL_AtomicUnlock
-#define TEMP_SEM_POST(X)      SDL_SemPost( X )
-#define TEMP_SEM_WAIT(X)      SDL_SemWait( X )
-#define TEMP_SEM_GET(X)       SDL_SemValue( X )
-
 enum engine_status _vg_engine_status(void)
 {
-   TEMP_STATUS_LOCK( &vg.sl_status );
+   SDL_AtomicLock( &vg.sl_status );
    enum engine_status status = vg.engine_status;
-   TEMP_STATUS_UNLOCK( &vg.sl_status );
+   SDL_AtomicUnlock( &vg.sl_status );
 
    return status;
 }
 
 enum vg_thread_purpose vg_thread_purpose(void)
 {
-   TEMP_STATUS_LOCK( &vg.sl_status );
-   if( vg.thread_id_main == SDL_GetThreadID(NULL) )
+   SDL_AtomicLock( &vg.sl_status );
+
+   SDL_threadID id = SDL_GetThreadID(NULL);
+   if( vg.thread_id_main == id )
    {
-      TEMP_STATUS_UNLOCK( &vg.sl_status );
+      SDL_AtomicUnlock( &vg.sl_status );
       return k_thread_purpose_main;
    }
-   else
+   else if( vg.thread_id_loader == id )
    {
-      TEMP_STATUS_UNLOCK( &vg.sl_status );
+      SDL_AtomicUnlock( &vg.sl_status );
       return k_thread_purpose_loader;
    }
-}
-
-static void vg_assert_thread( enum vg_thread_purpose required )
-{
-   enum vg_thread_purpose purpose = vg_thread_purpose();
-
-   if( purpose != required ){
-      vg_fatal_error( "thread_purpose must be %u not %u\n", required, purpose );
+   else
+   {
+      SDL_AtomicUnlock( &vg.sl_status );
+      return k_thread_purpose_nothing;
    }
 }
 
@@ -77,20 +69,6 @@ static struct vg_profile vg_prof_update = {.name="update()"},
                          vg_prof_render = {.name="render()"},
                          vg_prof_swap   = {.name="swap"};
 
-void vg_checkgl( const char *src_info )
-{
-   int fail = 0;
-
-   GLenum err;
-   while( (err = glGetError()) != GL_NO_ERROR ){
-      vg_error( "(%s) OpenGL Error: #%d\n", src_info, err );
-      fail = 1;
-   }
-
-   if( fail )
-      vg_fatal_error( "OpenGL Error" );
-}
-
 static void async_vg_bake_shaders( void *payload, u32 size )
 {
    vg_shaders_compile();
@@ -106,11 +84,11 @@ void async_internal_complete( void *payload, u32 size )
 {
    vg_success( "Internal async setup complete\n" );
 
-   TEMP_STATUS_LOCK( &vg.sl_status );
+   SDL_AtomicLock( &vg.sl_status );
 
    if( vg.engine_status == k_engine_status_crashed )
    {
-      TEMP_STATUS_UNLOCK( &vg.sl_status );
+      SDL_AtomicUnlock( &vg.sl_status );
       return;
    }
    else
@@ -118,9 +96,7 @@ void async_internal_complete( void *payload, u32 size )
       vg.engine_status = k_engine_status_running;
    }
 
-   TEMP_STATUS_UNLOCK( &vg.sl_status );
-
-   vg.client_has_control = 1;
+   SDL_AtomicUnlock( &vg.sl_status );
 }
 
 #ifdef VG_CUSTOM_SHADERS
@@ -455,13 +431,8 @@ static int vg_framefilter( double dt ){
    return 0;
 }
 
-static int _vg_crashscreen(void)
+static void _vg_crashscreen(void)
 {
-#if 0
-   if( vg_getkey( SDLK_ESCAPE ) )
-      return 1;
-#endif
-
    glBindFramebuffer( GL_FRAMEBUFFER, 0 );
    glEnable(GL_BLEND);
    glDisable(GL_DEPTH_TEST);
@@ -472,11 +443,22 @@ static int _vg_crashscreen(void)
    glClear( GL_COLOR_BUFFER_BIT );
    glViewport( 0,0, vg.window_x, vg.window_y );
 
-#if 0
-   _vg_render_log();
-#endif
+   ui_prerender( &vg_ui.ctx );
+   vg_ui_set_screen( vg.window_x, vg.window_y );
+   ui_update_mouse( &vg_ui.ctx, 
+      (ui_px[2]){ vg.mouse_pos[0], vg.mouse_pos[1] }, vg.mouse_state );
 
-   return 0;
+   vg_framebuffer_ui( &vg_ui.ctx );
+
+   vg_console.enabled = 1;
+   ui_ignore_input_frames( &vg_ui.ctx, 10 );
+   vg_gui( &vg_ui.ctx );
+   ui_ignore_input_frames( &vg_ui.ctx, 0 );
+   ui_capture_mouse( &vg_ui.ctx, 1 );
+   vg_console_draw( &vg_ui.ctx );
+
+   ui_postrender( &vg_ui.ctx, vg.time_frame_delta );
+   vg_ui_post_update();
 }
 
 static void _vg_gameloop(void)
@@ -521,8 +503,7 @@ static void _vg_gameloop(void)
          
       if( status == k_engine_status_crashed )
       {
-         if( _vg_crashscreen() )
-            break;
+         _vg_crashscreen();
       }
       else
       {
@@ -726,16 +707,16 @@ static void _vg_terminate(void)
    /* Shutdown */
    vg_console_write_persistent();
 
-   TEMP_STATUS_LOCK( &vg.sl_status );
+   SDL_AtomicLock( &vg.sl_status );
    vg.engine_status = k_engine_status_none;
-   TEMP_STATUS_UNLOCK( &vg.sl_status );
+   SDL_AtomicUnlock( &vg.sl_status );
 
-   vg_loader_free();
-
-   vg_success( "If you see this it means everything went.. \"well\".....\n" );
+   vg_loader_atexit();
 
    SDL_GL_DeleteContext( vg.gl_context );
    SDL_Quit();
+
+   vg_success( "The program has terminated 'correctly'\n" );
    exit(0);
 }
 
@@ -778,28 +759,45 @@ void vg_enter( int argc, char *argv[], const char *window_name )
    
    /* Opengl-required systems */
    vg_ui_init();
-   vg_loader_init();
 
    vg.engine_status = k_engine_status_load_internal;
+   vg_loader_step( vg_loader_init, vg_loader_free );
 
    _vg_opengl_sync_init();
-    vg_loader_start( _vg_load_full, NULL );
+    vg_loader_start( _vg_load_full, NULL );  
    _vg_gameloop();
    _vg_terminate();
 }
 
-void vg_fatal_error( const char *fmt, ... )
+#ifndef _WIN32
+ #include <execinfo.h>
+#endif
+
+void vg_fatal_exit(void)
 {
-   va_list args;
-   va_start( args, fmt );
-   _vg_logx_va( stderr, NULL, "fatal", KRED, fmt, args );
-   va_end( args );
+   /* append backtrace */
+#if !defined(_WIN32)
+   void *array[20];
+   char **strings;
+   int size, i;
+
+   size = backtrace( array, 20 );
+   strings = backtrace_symbols( array, size );
+
+   if( strings != NULL )
+   {
+      vg_info( "\n\n---------------- gnu backtrace -------------\n" );
 
-   vg_print_backtrace();
+      for( int i=0; i<size; i++ )
+         vg_info( "%s\n", strings[i] );
+   }
+
+   free( strings );
+#endif
 
-   TEMP_STATUS_LOCK( &vg.sl_status );
+   SDL_AtomicLock( &vg.sl_status );
    vg.engine_status = k_engine_status_crashed;
-   TEMP_STATUS_UNLOCK( &vg.sl_status );
+   SDL_AtomicUnlock( &vg.sl_status );
 
    if( vg_thread_purpose() == k_thread_purpose_loader )
    {
@@ -807,11 +805,23 @@ void vg_fatal_error( const char *fmt, ... )
    }
    else
    {
-      vg_error( "There is no jump to the error runner thing yet! bai bai\n" );
+      /* TODO: This should also be able to go to the crash screen? */
       _vg_terminate();
    }
 }
 
+void vg_fatal_error( const char *fmt, ... )
+{
+   vg_fatal_condition();
+
+   va_list args;
+   va_start( args, fmt );
+   _vg_logx_va( stderr, NULL, "fatal", KRED, fmt, args );
+   va_end( args );
+
+   vg_fatal_exit();
+}
+
 /* 
  * settings menu
  * ---------------------------------------------------------------------------
@@ -1121,7 +1131,7 @@ static void vg_settings_audio_apply(void)
       if( vg_settings.audio_devices.new_value == -1 ){ }
       else if( vg_settings.audio_devices.new_value == -2 )
       {
-         vg_fatal_error( "Programming error\n" );
+         vg_fatal_exit();
       }
       else 
       {
@@ -1269,7 +1279,7 @@ static void vg_settings_gui( ui_context *ctx )
    };
 
    static i32 page = 0;
-   ui_tabs( ctx, panel, panel, opts, vg_list_size(opts), &page );
+   ui_tabs( ctx, panel, panel, opts, VG_ARRAY_LEN(opts), &page );
 
    if( page == 0 )
    {
@@ -1292,10 +1302,9 @@ static int cmd_vg_settings_toggle( int argc, const char *argv[] )
 
 /*
  * Graphic cards will check these to force it to use the GPU.
- *   TODO: explicit declexport. since -flto strips these symbols in release.
  */
-u32 NvOptimusEnablement = 0x00000001;
-int AmdPowerXpressRequestHighPerformance = 1;
+__attribute__((used)) u32 NvOptimusEnablement = 0x00000001;
+__attribute__((used)) int AmdPowerXpressRequestHighPerformance = 1;
 
 #include "vg_async.c"
 #include "vg_audio.c"
@@ -1326,6 +1335,7 @@ int AmdPowerXpressRequestHighPerformance = 1;
 #include "vg_shader.c"
 #include "vg_framebuffer.c"
 #include "vg_render.c"
+#include "vg_opengl.c"
 
 #ifdef VG_CUSTOM_SHADERS
  #include "shaders/impl.c"
index 54c595bbe163944ec2ba6613b92acf2b4d7a0d5b..c17938e61910500a47efd4337cc889a3ca84346e 100644 (file)
@@ -78,6 +78,7 @@
 #include "vg_mem.h"
 #include "vg_m.h"
 #include "vg_font.h"
+#include "vg_string.h"
 #include "vg_ui/imgui.h"
 
 #include <setjmp.h>
@@ -125,13 +126,6 @@ struct vg_engine
    SDL_GLContext  gl_context;
    SDL_sem        *sem_loader; /* allows only one loader at a time */
 
-   bool  client_has_control;  /* [T0] If 0: VG will display a loader screen
-                                      If 1: The game is responsible for 
-                                             drawing everything.
-                                 This can be set back to 0 after vg_load is 
-                                 complete to blinder the client
-                                 Not recommended! */
-
    SDL_threadID  thread_id_main,
                  thread_id_loader;
 
index 8a70b61239fa8a229a344538b4496f7ff2654e11..253c3a59599b7bb55c305a28b37712bcdaf37bf1 100644 (file)
@@ -74,8 +74,10 @@ void vg_framebuffer_bind_texture( vg_framebuffer *fb, int attachment, int slot )
    if( (at->purpose != k_framebuffer_attachment_type_texture) &&
        (at->purpose != k_framebuffer_attachment_type_texture_depth) )
    {
-      vg_fatal_error( "illegal operation: bind non-texture framebuffer"
-                          " attachment to texture slot" );
+      vg_fatal_condition();
+      vg_info( "illegal operation: bind non-texture framebuffer"
+               " attachment to texture slot" );
+      vg_fatal_exit();
    }
 
    glActiveTexture( GL_TEXTURE0 + slot );
@@ -99,7 +101,7 @@ static const char *render_fb_attachment_str( GLenum e )
       FB_FORMAT_STR(GL_DEPTH_STENCIL_ATTACHMENT)
    };
 
-   for( int i=0; i<vg_list_size(formats); i++ )
+   for( int i=0; i<VG_ARRAY_LEN(formats); i++ )
       if( formats[i].e == e )
          return formats[i].str;
 
@@ -195,7 +197,7 @@ static const char *render_fb_format_str( GLenum format )
       FB_FORMAT_STR(GL_RGBA32UI)
    };
 
-   for( int i=0; i<vg_list_size(formats); i++ )
+   for( int i=0; i<VG_ARRAY_LEN(formats); i++ )
       if( formats[i].e == format )
          return formats[i].str;
 
@@ -232,10 +234,14 @@ vg_framebuffer *vg_framebuffer_allocate( void *alloc,
 
    if( track )
    {
-      if( _vg_framebuffer.count != vg_list_size(_vg_framebuffer.list) )
+      if( _vg_framebuffer.count != VG_ARRAY_LEN(_vg_framebuffer.list) )
          _vg_framebuffer.list[ _vg_framebuffer.count ++ ] = fb;
       else
-         vg_fatal_error( "Framebuffer list is full" );
+      {
+         vg_fatal_condition();
+         vg_info( "Framebuffer list is full, and tried to allocate another.\n");
+         vg_fatal_exit();
+      }
    }
 
    fb->attachments = vg_linear_alloc( alloc, 
@@ -311,17 +317,17 @@ static void async_framebuffer_create( void *payload, u32 size )
    }
    else
    {
+      vg_fatal_condition();
       if( result == GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT )
-         vg_error( "  status: Incomplete attachment" );
+         vg_info( "  status: Incomplete attachment" );
       else if( result == GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT )
-         vg_error( "  status: Missing attachment" );
+         vg_info( "  status: Missing attachment" );
       else if( result == GL_FRAMEBUFFER_UNSUPPORTED )
-         vg_error( "  status: Unsupported framebuffer format" );
+         vg_info( "  status: Unsupported framebuffer format" );
       else
-         vg_error( "  status: Generic Error" );
-
+         vg_info( "  status: Generic Error" );
       vg_info( "}\n" );
-      vg_fatal_error( "Incomplete framebuffer (see logs)" );
+      vg_fatal_exit();
    }
 }
 
index d4e51bc6b77ca3c3c974a4cf9fa7e9156ac2a6c0..ee0df5fd49ba84623c85afc1d5e08b26d4ccbfd8 100644 (file)
@@ -394,7 +394,7 @@ next_code:;
    else if( op == vg_gui_visible )
       pc ++;
    else 
-      vg_fatal_error( "unknown op\n" );
+      vg_fatal_error( "unknown op (%u)\n", op );
 
    goto next_code;
 }
@@ -406,10 +406,10 @@ const char *controller_button_str( SDL_GameControllerButton button )
 {
    static const char *controller_glyphs[ SDL_CONTROLLER_BUTTON_MAX ][2] = {
                                              /* xbox/generic  playstation */
-      [ SDL_CONTROLLER_BUTTON_A ]            = { KGRN "\x06\x02\x85",KBLU "\x06\x02\x82" },
-      [ SDL_CONTROLLER_BUTTON_B ]            = { KRED "\x06\x02\x86",KRED "\x06\x02\x81" },
-      [ SDL_CONTROLLER_BUTTON_X ]            = { KBLU "\x06\x02\x83",KMAG "\x06\x02\x7f" },
-      [ SDL_CONTROLLER_BUTTON_Y ]            = { KYEL "\x06\x02\x84",KGRN "\x06\x02\x80" },
+      [ SDL_CONTROLLER_BUTTON_A ] = { KGRN "\x06\x02\x85",KBLU "\x06\x02\x82" },
+      [ SDL_CONTROLLER_BUTTON_B ] = { KRED "\x06\x02\x86",KRED "\x06\x02\x81" },
+      [ SDL_CONTROLLER_BUTTON_X ] = { KBLU "\x06\x02\x83",KMAG "\x06\x02\x7f" },
+      [ SDL_CONTROLLER_BUTTON_Y ] = { KYEL "\x06\x02\x84",KGRN "\x06\x02\x80" },
       [ SDL_CONTROLLER_BUTTON_LEFTSTICK ]    = { "\x87","\x87" },
       [ SDL_CONTROLLER_BUTTON_RIGHTSTICK ]   = { "\x8b","\x8b" },
       [ SDL_CONTROLLER_BUTTON_LEFTSHOULDER ] = { "\x91","\x91" },
diff --git a/vg_io.c b/vg_io.c
index 76e8ca3a0d0e9c8955d8cda95363fcaf50dda64f..b100992649075236e4f99ef8548a21fd9548c3a0 100644 (file)
--- a/vg_io.c
+++ b/vg_io.c
@@ -108,17 +108,16 @@ void vg_dir_close( vg_dir *dir )
    dir->index = 0;
 }
 
-void vg_file_print_invalid( FILE *fp )
+void vg_file_error_info( FILE *fp )
 {
-   if( feof( fp )) {
+   if( feof( fp )) 
+   {
       vg_error( "mdl_open: header too short\n" );
    }
-   else{
-      if( ferror( fp ))
-         vg_error( "mdl_open: %s\n", strerror(errno) );
-      else
-         vg_error( "mdl_open: unkown failure\n" );
-
+   else
+   {
+      if( ferror( fp )) vg_info( "fopen: %s\n", strerror(errno) );
+      else              vg_info( "fopen: unkown failure\n" );
    }
 }
 
@@ -128,13 +127,15 @@ void vg_file_print_invalid( FILE *fp )
 void *vg_file_read( void *lin_alloc, const char *path, u32 *size )
 {
        FILE *f = fopen( path, "rb" );
-       if( f ){
+       if( f )
+   {
       void *buffer = lin_alloc? vg_linear_alloc( lin_alloc, 0 ):
                                 NULL;
       u64 current = 0;
 
       /* read in chunks */
-      for( u32 i=0; 1; i++ ){
+      for( u32 i=0; 1; i++ )
+      {
          if( lin_alloc )
             buffer = vg_linear_extend( lin_alloc,buffer,VG_FILE_IO_CHUNK_SIZE );
          else 
@@ -143,18 +144,27 @@ void *vg_file_read( void *lin_alloc, const char *path, u32 *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_error( "read error" );
+                  vg_fatal_condition();
+                  vg_info( "Read error\n" );
+                  vg_fatal_exit();
                }
-               else{
+               else
+               {
                   fclose(f);
-                  vg_fatal_error( "unknown error codition" );
+                  vg_fatal_condition();
+                  vg_info( "Unknown error condition\n" );
+                  vg_fatal_exit();
                }
             }
          }
diff --git a/vg_io.h b/vg_io.h
index fefb6bfa1af487c141896a1f1723790f2c69cfaa..0991f0eb69dca24112b7083a524bd5ab60833e93 100644 (file)
--- a/vg_io.h
+++ b/vg_io.h
@@ -35,7 +35,6 @@ int vg_dirskip( vg_dir *dir );
 int vg_dir_next_entry( vg_dir *dir );
 enum vg_entry_type vg_dir_entry_type( vg_dir *dir );
 void vg_dir_close( vg_dir *dir );
-void vg_file_print_invalid( FILE *fp );
 
 /*
  * File I/O
@@ -50,3 +49,4 @@ char *vg_file_read_text( void *lin_alloc, const char *path, u32 *sz );
 int vg_asset_write( const char *path, void *data, i64 size );
 int vg_file_copy( const char *src, const char *dst, void *lin_alloc );
 const char *vg_path_filename( const char *path );
+void vg_file_error_info( FILE *fp );
index 63154820972c2e7f0aa62e04c3fdb9ebf1e4657f..94f8b687b1f81523e76226db64f189d325ec7e32 100644 (file)
@@ -57,7 +57,6 @@ static void async_vg_lines_init( void *payload, u32 payload_size )
    
    glBufferData( GL_ARRAY_BUFFER, VG_LINES_BUFFER_SIZE, NULL, GL_DYNAMIC_DRAW );
    glBindVertexArray( vg_lines.vao );
-   VG_CHECK_GL_ERR();
 
    /* Pointers */
    glVertexAttribPointer( 
@@ -79,8 +78,6 @@ static void async_vg_lines_init( void *payload, u32 payload_size )
       (void*)(offsetof( struct vg_lines_vert, colour ))
    );
    glEnableVertexAttribArray( 1 );
-   
-   VG_CHECK_GL_ERR();
 }
 
 void vg_lines_init(void)
@@ -187,7 +184,7 @@ void vg_line_boxf( boxf box, u32 colour )
                        {4,5},{5,7},{7,6},{6,4},
                        {4,0},{5,1},{6,2},{7,3}};
 
-   vg_line_mesh( verts, indices, vg_list_size(indices), colour );
+   vg_line_mesh( verts, indices, VG_ARRAY_LEN(indices), colour );
 }
 
 void vg_line_boxf_transformed( m4x3f m, boxf box, u32 colour )
@@ -205,7 +202,7 @@ void vg_line_boxf_transformed( m4x3f m, boxf box, u32 colour )
                        {4,5},{5,7},{7,6},{6,4},
                        {4,0},{5,1},{6,2},{7,3}};
 
-   vg_line_mesh( verts, indices, vg_list_size(indices), colour );
+   vg_line_mesh( verts, indices, VG_ARRAY_LEN(indices), colour );
 }
 
 void vg_line_cross(v3f pos,u32 colour, float scale)
index 4859f75cd43fad01d53f43f1ebb75c024fb3a2a8..f16d2c40387534e1eae4349276ce9114edbfd86e 100644 (file)
@@ -78,18 +78,18 @@ void vg_loader_init(void)
    glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, sizeof(float)*2, (void*)0 );
    glEnableVertexAttribArray( 0 );
 
-   VG_CHECK_GL_ERR();
-
-   if( !vg_shader_compile( &_shader_loader ) )
-      vg_fatal_error( "failed to compile shader" );
+   vg_compile_shader( &_shader_loader );
 }
 
-static void vg_loader_free(void)
+void vg_loader_free(void)
 {
-   vg_info( "vg_loader_free\n" );
    glDeleteVertexArrays( 1, &vg_loader.vao );
    glDeleteBuffers( 1, &vg_loader.vbo );
+}
 
+void vg_loader_atexit(void)
+{
+   vg_info( "Shutdown steps\n" );
    for( int i=0; i<vg_loader.step_count; i++ )
    {
       struct loader_free_step *step = 
@@ -137,11 +137,10 @@ static int _vg_loader_thread( void *pfn )
    }
 
    /* Run client loader */
-   //vg_info( "Starting client loader thread @%p\n", pfn );
    void (*call_func)(void *data) = pfn;
    call_func( vg.thread_data );
 
-   TEMP_SEM_POST( vg.sem_loader );
+   SDL_SemPost( vg.sem_loader );
    vg.thread_id_loader = 0;
 
    return 0;
@@ -149,7 +148,7 @@ static int _vg_loader_thread( void *pfn )
 
 int vg_loader_availible(void)
 {
-   if( TEMP_SEM_GET( vg.sem_loader ) )
+   if( SDL_SemValue( vg.sem_loader ) )
    {
       if( !(vg_async.start) )
          return 1;
@@ -160,7 +159,7 @@ int vg_loader_availible(void)
 
 void vg_loader_start( void(*pfn)(void *data), void *data )
 {
-   TEMP_SEM_WAIT( vg.sem_loader );
+   SDL_SemWait( vg.sem_loader );
 
    vg.thread_data = data;
    SDL_CreateThread( _vg_loader_thread, "vg: loader", pfn );
@@ -170,8 +169,8 @@ void vg_loader_start( void(*pfn)(void *data), void *data )
  * Schedule something to be ran now, freed later. Checks in with engine status
  */
 void _vg_loader_step( void( *fn_load )(void), void( *fn_free )(void),
-                      const char *alias ){
-   
+                      const char *alias )
+{
    u64 t0 = SDL_GetPerformanceCounter();
    vg.time_hp_last = vg.time_hp;
 
@@ -182,15 +181,22 @@ void _vg_loader_step( void( *fn_load )(void), void( *fn_free )(void),
    double dt = (double)udt / (double)SDL_GetPerformanceFrequency();
    vg_info( "ltime [%p] %s: %fs\n", fn_load, alias, dt );
 
-   if( fn_free ){
+   if( fn_free )
+   {
       struct loader_free_step step;
       step.fn_free = fn_free;
 
-      if( vg_loader.step_count == vg_list_size(vg_loader.step_buffer) )
-         vg_fatal_error( "Too many free steps" );
-
+      VG_ASSERT( vg_loader.step_count < VG_ARRAY_LEN(vg_loader.step_buffer) );
       vg_loader.step_buffer[ vg_loader.step_count ++ ] = step;
    }
 
-   /* TODO: There was a quit checker here, re-add this? */
+   SDL_AtomicLock( &vg.sl_status );
+   enum engine_status status = vg.engine_status;
+   SDL_AtomicUnlock( &vg.sl_status );
+
+   if( status != k_engine_status_load_internal )
+   {
+      vg_info( "Joining loader thread.\n" );
+      longjmp( vg.env_loader_exit, 1 );
+   }
 }
index b69b287267a18de62cacaddcab2db1b98e279dc4..c5ce205041f393d6ca3343a451eb8ef783f612f4 100644 (file)
@@ -32,7 +32,8 @@ void _vg_loader_step( void( *fn_load )(void), void( *fn_free )(void),
 int vg_loader_availible(void);
 void vg_loader_render(void);
 void vg_loader_render_ring( f32 opacity );
-static void vg_loader_free(void);
+void vg_loader_free(void);
+void vg_loader_atexit(void);
 void vg_loader_init(void);
 
 #define vg_loader_step( FN, FN_FREE )\
index 6b38c1570027b7f6c3486753403ce567bdc8c57b..2168444b22b01336012a1a9347f82eafa37f853c 100644 (file)
--- a/vg_log.c
+++ b/vg_log.c
@@ -5,21 +5,17 @@
 #include "vg_log.h"
 #include "vg_string.h"
 
-#ifndef _WIN32
- #include <execinfo.h>
-#endif
-
 struct vg_log vg_log;
 
 static void _vg_log_append_line( const char *str )
 {
-   if( vg_log.log_line_count < vg_list_size( vg_log.log ) )
+   if( vg_log.log_line_count < VG_ARRAY_LEN( vg_log.log ) )
       vg_log.log_line_count ++;
 
    char *dest = vg_log.log[ vg_log.log_line_current ++ ];
-   vg_strncpy( str, dest, vg_list_size(vg_log.log[0]), k_strncpy_allow_cutoff );
+   vg_strncpy( str, dest, VG_ARRAY_LEN(vg_log.log[0]), k_strncpy_allow_cutoff );
    
-   if( vg_log.log_line_current >= vg_list_size( vg_log.log ) )
+   if( vg_log.log_line_current >= VG_ARRAY_LEN( vg_log.log ) )
       vg_log.log_line_current = 0;
 }
 
@@ -40,12 +36,12 @@ void _vg_logx_va( FILE *file,
 
        char buffer[4096];
 
-   vsnprintf( buffer, vg_list_size(buffer), fmt, args );
+   vsnprintf( buffer, VG_ARRAY_LEN(buffer), fmt, args );
 
    const char *line = buffer;
    char logline[96];
 
-   for( u32 i=0; i<vg_list_size(buffer); i++ ){
+   for( u32 i=0; i<VG_ARRAY_LEN(buffer); i++ ){
       char c = buffer[i];
 
       if( c == '\0' || c == '\n' ){
@@ -70,7 +66,7 @@ void _vg_logx_va( FILE *file,
             };
 
             const char *colour = thread_colours[
-               (vg_thread_purpose() % vg_list_size( thread_colours ))];
+               (vg_thread_purpose() % VG_ARRAY_LEN( thread_colours ))];
 
             fprintf( file, "%s[%u]"KNRM"%.32s", 
                      colour, vg_thread_purpose(), line_location );
@@ -112,27 +108,7 @@ void vg_logx( FILE *file,
    va_end( args );
 }
 
-void vg_print_backtrace(void)
+void vg_fatal_condition(void)
 {
-#if !defined(_WIN32)
-   void *array[20];
-   char **strings;
-   int size, i;
-
-   size = backtrace( array, 20 );
-   strings = backtrace_symbols( array, size );
-
-   if( strings != NULL )
-   {
-      vg_error( "---------------- gnu backtrace -------------\n" );
-
-      for( int i=0; i<size; i++ )
-         vg_info( "%s\n", strings[i] );
-
-      vg_error( "---------------- gnu backtrace -------------\n" );
-   }
-
-   free( strings );
-
-#endif
+   vg_error( "--------- Fatal condition entered --------- \n" );
 }
index bb7411b7e261a9f104252ef3eea7993b29e5d0a3..89b86dc186e1976ba6e6e64877811adaae5b4191 100644 (file)
--- a/vg_log.h
+++ b/vg_log.h
@@ -63,6 +63,3 @@ void _vg_logx_va( FILE *file,
                   const char *location, const char *prefix,
                   const char *colour,
                   const char *fmt, va_list args );
-
-void vg_print_backtrace(void);
-
index 863b2a5177345f15c0f28be7fa37039250694184..1b55b09b7e78bd225779b6c292f72451e7ac27fb 100644 (file)
--- a/vg_mem.c
+++ b/vg_mem.c
@@ -38,29 +38,33 @@ void *_vg_linear_alloc( void *buffer, u32 size, const char *constr_name )
       size = vg_align8( size );
 
    if( ((u64)buffer) % 8 )
-      vg_fatal_error( "unaligned buffer (%p)", buffer );
+      vg_fatal_error( "Tried allocating to an unaligned buffer (%p)", buffer );
 
    vg_linear_allocator *alloc = vg_linear_header( buffer );
 
    if( (alloc->cur + size) > alloc->size )
-   {
       vg_fatal_error( "linear allocator overflow (%u + %u > %u)\n", 
-                        alloc->cur, size, alloc->size );
-   }
+                      alloc->cur, size, alloc->size );
 
    if( alloc->flags & VG_MEMORY_SYSTEM )
    {
       if( (alloc->allocation_count + 1) > VG_MAX_ALLOCATIONS )
       {
-         vg_error( "Alloc (%p) allocation count is at the limit of"
-                   " %u allocations.\n", alloc, VG_MAX_ALLOCATIONS );
-         vg_fatal_error( "Max linear allocations reached" );
+         vg_fatal_condition();
+         vg_info( "Linear allocators marked as 'SYSTEMS', have a hard limit of "
+                  "%u allocations.\n\n"
+                  "The limit was exceeded by the following request:\n",
+                  VG_MAX_ALLOCATIONS );
+         vg_info( "  Name: %s\n", constr_name );
+         vg_info( "  Size: %u bytes\n", size );
+         vg_fatal_exit();
       }
    }
 
    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 ];
@@ -69,24 +73,21 @@ void *_vg_linear_alloc( void *buffer, u32 size, const char *constr_name )
       meta->size = size;
       meta->name = constr_name;
    }
-   else{
+   else
       data = buffer + alloc->cur;
-   }
 
    u8 *bytes = data;
-   for( u32 i=0; i<size; i++ ){
+   for( u32 i=0; i<size; i++ )
       bytes[i] = 0xfe;
-   }
 
    alloc->allocation_count ++;
    alloc->last_alloc = data;
    alloc->last_alloc_size = size;
    alloc->cur += size;
 
-   if( ((u64)data) % 8 ){
-      vg_fatal_error( "unaligned" );
-   }
-
+   if( ((u64)data) % 8 )
+      vg_fatal_error( "Resultant allocation was unaligned, most likely memory "
+                      "corruption or programmer error\n" );
    return data;
 }
 
@@ -100,28 +101,29 @@ void *vg_linear_resize( void *buffer, void *data, u32 newsize )
       newsize = vg_align8( newsize );
 
    if( alloc->last_alloc != data )
-      vg_fatal_error( "This block has been fixed!" );
+      vg_fatal_error( "Tried to resize allocation in linear allocator which "
+                      "has allocated other things after this block.\n" );
 
    if( (alloc->cur - alloc->last_alloc_size + newsize) > alloc->size )
-      vg_fatal_error( "Cannot resize, overflow" );
+      vg_fatal_error( "Tried to resize allocation to new size which would "
+                      "overflow the allocator\n" );
 
    alloc->cur -= alloc->last_alloc_size;
    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_error( "realloc failed" );
+         vg_fatal_error( "We are libc mode, and realloc failed" );
 
       alloc->alloc_table[ alloc->allocation_count-1 ].data = data;
       alloc->alloc_table[ alloc->allocation_count-1 ].size = newsize;
       alloc->last_alloc = data;
       return data;
    }
-   else{
-      return data;
-   }
+   else return data;
 }
 
 /* its possible to delete just the last item */
@@ -129,12 +131,12 @@ void vg_linear_del( void *buffer, void *data )
 {
    vg_linear_allocator *alloc = vg_linear_header( buffer );
 
-   if( alloc->last_alloc != data ){
-      vg_fatal_error( "This block has been fixed! Last alloc: %p, this: %p\n",
-                      alloc->last_alloc, data );
-   }
+   if( alloc->last_alloc != data )
+      vg_fatal_error( "This block has been fixed and cannot be deleted.\n"
+                      "Last alloc: %p, this: %p\n", alloc->last_alloc, data );
 
-   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_error( "Cannot free a linear allocator in this conext" );
@@ -229,25 +231,27 @@ void vg_linear_clear( void *buffer )
 void *_vg_create_linear_allocator( void *lin_alloc, u32 size, 
                                    u16 flags, const char *constr_name)
 {
-   if( sizeof( vg_linear_allocator ) != 32 ) 
-      vg_fatal_error( "Programming error" );
+   VG_ASSERT( sizeof( vg_linear_allocator ) == 32 );
 
    vg_linear_allocator *header;
    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_error( "Out of memory" );
+         vg_fatal_error( "Out of memory (%u + %u > %u)\n", 
+                         alloc->cur, block_size, alloc->size );
 
       if( alloc->allocation_count + 1 > VG_MAX_ALLOCATIONS )
-         vg_fatal_error( "Max allocations in linear allocator" );
+         vg_fatal_error( "Exceeded max allocations in linear allocator (%u)\n", 
+                         VG_MAX_ALLOCATIONS );
 
       if( (flags && VG_MEMORY_SYSTEM) && (alloc->flags & VG_MEMORY_REALTIME) )
-         vg_fatal_error( "Cannot declare realtime allocator inside systems"
-                             " allocator" );
+         vg_fatal_error( "Cannot declare realtime allocator inside systems "
+                         "allocator");
 
       if( vg_mem.use_libc_malloc ){
          vg_allocation_meta *meta = 
@@ -263,9 +267,7 @@ void *_vg_create_linear_allocator( void *lin_alloc, u32 size,
          meta->size = size;
          meta->name = constr_name;
       }
-      else{
-         header = lin_alloc + alloc->cur;
-      }
+      else header = lin_alloc + alloc->cur;
       
       alloc->cur += block_size;
       alloc->last_alloc = header;
@@ -286,12 +288,12 @@ void *_vg_create_linear_allocator( void *lin_alloc, u32 size,
    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 );
    }
-   else
-      header->alloc_table = NULL;
+   else header->alloc_table = NULL;
 
    return header+1;
 }
index 94042a971e8cd94464ddfcde75fc85a47c0bdf85..6fde883b7643e7c91ad5b58a35ee63e35679082f 100644 (file)
--- a/vg_mem.h
+++ b/vg_mem.h
@@ -1,6 +1,6 @@
 #pragma once
 
-#define VG_MAX_ALLOCATIONS 256
+#define VG_MAX_ALLOCATIONS 128
 
 typedef struct vg_linear_allocator vg_linear_allocator;
 typedef struct vg_allocation_meta vg_allocation_meta;
index 1fe3302fd960bb1349f6981cbc5310f619204955..0a830a2658d02749ef91740bdcaa02bb5df08662 100644 (file)
@@ -69,12 +69,11 @@ void vg_pool_watch( vg_pool *pool, u16 id )
 {
    vg_pool_node *node = vg_pool_nodeptr( pool, id );
 
-   if( !node->ref_count ){
+   if( !node->ref_count )
       vg_pool_unlink( pool, id );
-   }
 
    if( node->ref_count == 0xffff )
-      vg_fatal_error( "pool watch missmatch (limit is 128)\n" );
+      vg_fatal_error( "Pool watch missmatch (limit is 128)\n" );
 
    node->ref_count ++;
 }
@@ -88,7 +87,8 @@ void vg_pool_unwatch( vg_pool *pool, u16 id )
       vg_fatal_error( "pool unwatch missmatch (no watchers)\n" );
 
    node->ref_count --;
-   if( !node->ref_count ){
+   if( !node->ref_count )
+   {
       vg_pool_node *head = vg_pool_nodeptr( pool, pool->head ),
                    *tail = vg_pool_nodeptr( pool, pool->tail );
       
index 16ce1d87e2a0a894fdf27bf729ad01b3271325ba..facd66b1b9d9b8d5d7cef8d0dde162824e7907d5 100644 (file)
--- a/vg_msg.c
+++ b/vg_msg.c
@@ -119,7 +119,7 @@ u32 vg_msg_cmd_bytecount( u8 code )
 
 u8 vg_msg_count_bits( u32 count )
 {
-   if( count > 16 ) vg_fatal_error( "Too large\n" );
+   VG_ASSERT( count <= 16 );
    return ((count-1)<<2);
 }
 
diff --git a/vg_opengl.c b/vg_opengl.c
new file mode 100644 (file)
index 0000000..8e4e55a
--- /dev/null
@@ -0,0 +1,38 @@
+#include "vg/vg_opengl.h"
+
+static const char *gl_error_names[] =
+{
+   "GL_INVALID_ENUM",
+   "GL_INVALID_VALUE",
+   "GL_INVALID_OPERATION",
+   "GL_STACK_OVERFLOW",
+   "GL_STACK_UNDERFLOW",
+   "GL_OUT_OF_MEMORY",
+   "GL_INVALID_FRAMEBUFFER_OPERATION"
+};
+
+void vg_opengl_log_errors(void)
+{
+   u32 err_count = 0;
+   GLenum err;
+   while( (err = glGetError()) != GL_NO_ERROR )
+   {
+      if( !err_count )
+         vg_info( "OpenGL error buffer:\n" );
+
+      u32 err_i = err - 0x0500;
+      if( err_i < VG_ARRAY_LEN(gl_error_names) )
+      {
+         vg_info( " %u %s\n", err, gl_error_names[ err_i ] );
+      }
+      else
+      {
+         vg_info( "%u (unknown code)\n", err );
+      }
+
+      err_count ++;
+   }
+   
+   if( !err_count )
+      vg_info( "OpenGL error buffer is empty.\n" );
+}
index 3656719262d7e8f5541d475b400ffc5e7bdd3ebe..a59c1f0c810dbda8e1bedd8daee5a5e38f309b4c 100644 (file)
@@ -1 +1,3 @@
 #include "dep/glad/glad.h"
+
+void vg_opengl_log_errors(void);
index b846b06a4056356e8b0825f6621c3a337303a10b..e9bf50b4e9e606845f0c87085eee59c7aab59863 100644 (file)
@@ -28,15 +28,16 @@ typedef v3f                 m4x3f[4];
 typedef v4f       m4x4f[4];
 typedef v3f                    boxf[2];
 
-/* anything compiled against VG shall implement this function somewhere. */
+/* anything compiled against VG shall implement vg_fatal_exit() somewhere. */
+void vg_fatal_condition(void);
+void vg_fatal_exit(void);
 void vg_fatal_error( const char *fmt, ... );
 
 #define VG_ASSERT( ITEM, ... ) \
-   if( !( ITEM ) ) { \
-      vg_fatal_error( "Assertion failed: " VG_LOG_MCSTR(ITEM) "\n" \
-                      VG_LOG_WHERE ); \
-   }
+ if( !( ITEM ) ) { \
+   vg_fatal_error( "Assertion failed: " VG_LOG_MCSTR(ITEM) "\n" VG_LOG_WHERE );\
+ }
 
 #define VG_MIN( A, B ) ((A)<(B)?(A):(B))
 #define VG_MAX( A, B ) ((A)>(B)?(A):(B))
-#define vg_list_size( A ) (sizeof(A)/sizeof(A[0]))
+#define VG_ARRAY_LEN( A ) (sizeof(A)/sizeof(A[0]))
index 79e072367687c4f65135395541dd0577521db559..47857430856c0fc95e66cc4c7ce2c80a93680dfd 100644 (file)
@@ -52,7 +52,7 @@ void vg_profile_drawn( ui_context *ctx, struct vg_profile **profiles, u32 count,
 
    ui_fill( ctx, panel, 0xa0000000 );
 
-   if( count > 8 ) vg_fatal_error( "Too many profiles\n" );
+   VG_ASSERT( count <= 8 );
 
    f64 avgs[8];
    u32 colours[8];
index bcfebc5ba55c3dff32eae87592d83611997599bf..322f42a97dc37a3266a1fd4492806d06d0c1b65b 100644 (file)
@@ -89,11 +89,11 @@ void rb_extrapolate( rigidbody *rb, v3f co, v4f q )
 
 void rb_iter( rigidbody *rb )
 {
-   if( !vg_validf( rb->v[0] ) ||
-       !vg_validf( rb->v[1] ) ||
-       !vg_validf( rb->v[2] ) )
+   if( !vg_validf(rb->v[0]) || !vg_validf(rb->v[1]) || !vg_validf(rb->v[2]) )
    {
-      vg_fatal_error( "NaN velocity" );
+      vg_fatal_error( 
+            "Aborting the program because velocity has invalid value in one "
+            "or more components: %f %f %f\n", rb->v[0],rb->v[1],rb->v[2] );
    }
 
    v3f gravity = { 0.0f, -9.8f, 0.0f };
index 1c1d0583fe4092619f3824462c2f043a881da390..2989a46e026c75fc2e8b024511117a13bd6ec3e7 100644 (file)
@@ -495,7 +495,7 @@ int rb_capsule__triangle( m4x3f mtxA, rb_capsule *c, v3f tri[3], rb_ct *buf )
 
 int rb_global_has_space( void )
 {
-   if( rb_contact_count + 16 > vg_list_size(rb_contact_buffer) )
+   if( rb_contact_count + 16 > VG_ARRAY_LEN(rb_contact_buffer) )
       return 0;
 
    return 1;
index 962148f13396e31787d2ac83f0f006fb5bc9b797..f16f3c66e8d460fa1161e288db259b6b3bd58ca9 100644 (file)
@@ -134,8 +134,6 @@ static void async_vg_rb_view_init( void *payload, u32 payload_size )
    glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, 
                           stride, (void *)offsetof(rb_view_vert, n) );
    glEnableVertexAttribArray( 1 );
-
-   VG_CHECK_GL_ERR();
 }
 
 void vg_rb_view_init(void)
index b17c64a4d5cac2177dda0e4989f9aa0aed57eb6a..ace5c175744462682f84750ef9056da861119ba2 100644 (file)
@@ -21,13 +21,21 @@ struct vg_shaders
 }
 static vg_shaders;
 
-static GLuint vg_shader_subshader( const char *src, GLint gliShaderType )
+/* 
+ * Compile OpenGL subshader from GLSL source. Type is subshader type.
+ * If critical is set to 1, the program will fatal exit on compile failure.
+ */
+static GLuint vg_compile_opengl_subshader( GLint type,
+                                           const char *src, bool critical )
 {
-       GLint shader = glCreateShader( gliShaderType );
+       GLuint shader = glCreateShader( type );
 
-   if( shader == GL_NONE )
+   if( shader == 0 )
    {
-      vg_error( "Could not 'glCreateShader()'\n" );
+      vg_fatal_condition();
+      vg_info( "glCreateShader returned 0.\n" );
+      vg_opengl_log_errors();
+      vg_fatal_exit();
       return 0;
    }
 
@@ -37,113 +45,139 @@ static GLuint vg_shader_subshader( const char *src, GLint gliShaderType )
        GLint status;
        glGetShaderiv( shader, GL_COMPILE_STATUS, &status );
 
-       if( status != GL_TRUE )
-       {
+   if( status == GL_TRUE )
+   {
+      return shader;
+   }
+   else
+   {
+      if( critical ) vg_fatal_condition();
+
       GLchar info[1024];
       GLsizei len;
+      glGetShaderInfoLog( shader, sizeof(info), &len, info );
 
-               glGetShaderInfoLog( shader, sizeof(info), &len, info );
-               vg_error( "Error info:\n%s\n", info );
-               return 0;
-       }
+      const char *type_str = "?";
+
+           if( type == GL_VERTEX_SHADER )   type_str = "GL_VERTEX_SHADER";
+      else if( type == GL_FRAGMENT_SHADER ) type_str = "GL_FRAGMENT_SHADER";
+
+      vg_info( "%s subshader compile error:\n\n%s\n", type_str, info );
 
-       return shader;
+      if( critical ) vg_fatal_exit();
+      return 0;
+   }
 }
 
-int vg_shader_compile( struct vg_shader *shader )
+/*
+ * Final compilation by linking, if critical is 1, a fatal exit will occur on
+ * link failure
+ */
+static int vg_link_opengl_program( GLuint program, bool critical )
 {
-       GLuint program, vert, frag;
-
-   /* If we are compiling this again, we obviously need to try to take the src
-    * from the disk instead.
-    *
-    * Only do this if we have filenames set on the shader, so engine shaders 
-    * dont have to do it (text.. etc).
-    */
-
-   int use_source_files = 0;
-   if( shader->compiled ){
-      if( shader->vs.orig_file && shader->fs.orig_file ){
-         use_source_files = 1;
-      }
-      else {
-         vg_warn( "No source files for shader '%s'\n", shader->name );
-         return 1;
-      }
-   }
+       glLinkProgram( program );
+               
+       GLint success;
+       glGetProgramiv( program, GL_LINK_STATUS, &success );
 
-       vg_info( "Compile shader '%s'\n", shader->name );
-
-   if( use_source_files ){
-      char error[260];
-      char path[260];
-
-      strcpy( path, "../../" );
-      strcat( path, shader->vs.orig_file );
-      char *vertex_src = stb_include_file( path, "", "../../shaders", error );
-
-      strcpy( path, "../../" );
-      strcat( path, shader->fs.orig_file );
-      char *fragment_src = stb_include_file( path, "", "../../shaders", error );
-   
-      if( !vertex_src || !fragment_src ){
-         const char *errstr = "Could not find shader source files (%s)\n";
-         if( shader->compiled ){
-            vg_warn( errstr, shader->vs.orig_file );
-            free( vertex_src );
-            free( fragment_src );
-            return 1;
-         }
-         else{
-            vg_error( errstr, shader->vs.orig_file );
-            free( vertex_src );
-            free( fragment_src );
-            return 0;
-         }
-      }
-
-      vert = vg_shader_subshader( vertex_src,   GL_VERTEX_SHADER );
-      frag = vg_shader_subshader( fragment_src, GL_FRAGMENT_SHADER );
-
-      free( vertex_src );
-      free( fragment_src );
-   }
-   else{
-      vert = vg_shader_subshader( shader->vs.static_src, GL_VERTEX_SHADER );
-      frag = vg_shader_subshader( shader->fs.static_src, GL_FRAGMENT_SHADER );
-   }
-       
-       if( !vert || !frag )
+       if( success ) return 1;
+   else
+       {
+      if( critical ) vg_fatal_condition();
+
+      char info[ 512 ];
+               glGetProgramInfoLog( program, sizeof(info), NULL, info );
+      vg_info( "Shader program link error:\n\n%s\n", info );
+
+      if( critical ) vg_fatal_exit();
                return 0;
-       
-       program = glCreateProgram();
+       }
+}
+
+/*
+ * Compile vg_shader from static source code. Will fatal exit if there is a 
+ * compile error 
+ */
+void vg_compile_shader( struct vg_shader *shader )
+{
+   VG_ASSERT( shader->compiled == 0 );
+
+   const char *vs = shader->vs.static_src,
+              *fs = shader->fs.static_src;
+
+   GLuint vert = vg_compile_opengl_subshader( GL_VERTEX_SHADER, vs, 1 ),
+          frag = vg_compile_opengl_subshader( GL_FRAGMENT_SHADER, fs, 1 ),
+              program = glCreateProgram();
                
        glAttachShader( program, vert );
        glAttachShader( program, frag );
-       glLinkProgram( program );
+
+   vg_link_opengl_program( program, 1 );
        
        glDeleteShader( vert );
        glDeleteShader( frag );
-               
-       /* Check for link errors */
-       char infoLog[ 512 ];
-       int success_link = 1;
-       
-       glGetProgramiv( program, GL_LINK_STATUS, &success_link );
-       if( !success_link )
-       {
-               glGetProgramInfoLog( program, 512, NULL, infoLog );
-               vg_error( "Link failed: %s\n", infoLog );
-               glDeleteProgram( program );
-               return 0;
-       }
-       
-   if( shader->compiled )
-      glDeleteProgram( shader->id );
-   
+
    shader->id = program;
-       shader->compiled = 1;
-       return 1;
+   shader->compiled = 1;
+}
+
+/*
+ * Recompile vg_shader from its original source files. This won't work in the
+ * shipped version of the engine.
+ */
+void vg_recompile_shader( struct vg_shader *shader )
+{
+   VG_ASSERT( shader->compiled == 1 );
+
+   char error[260];
+   char path[260];
+
+   strcpy( path, "../../" );
+   strcat( path, shader->vs.orig_file );
+   char *vs = stb_include_file( path, "", "../../shaders", error );
+
+   strcpy( path, "../../" );
+   strcat( path, shader->fs.orig_file );
+   char *fs = stb_include_file( path, "", "../../shaders", error );
+
+   if( !vs || !fs )
+   {
+      vg_warn( "Could not recompile shader due to missing source files:\n" );
+
+      if( !vs ) vg_info( "  Vertex: %s\n", shader->vs.orig_file );
+      if( !fs ) vg_info( "  Fragment: %s\n", shader->fs.orig_file );
+      free( vs );
+      free( fs );
+      return;
+   }
+
+   GLuint vert = vg_compile_opengl_subshader( GL_VERTEX_SHADER, vs, 0 ),
+          frag = vg_compile_opengl_subshader( GL_FRAGMENT_SHADER, fs, 0 );
+
+   free( vs );
+   free( fs );
+
+   if( !vert || !frag ) return;
+
+   GLuint program = glCreateProgram();
+
+       glAttachShader( program, vert );
+       glAttachShader( program, frag );
+
+   if( vg_link_opengl_program( program, 0 ) )
+   {
+      /* replace existing */
+      glDeleteProgram( shader->id );
+      shader->id = program;
+   }
+   else
+   {
+      /* womp womp */
+      glDeleteProgram( program );
+   }
+       
+       glDeleteShader( vert );
+       glDeleteShader( frag );
 }
 
 void vg_free_shader( struct vg_shader *shader )
@@ -151,6 +185,7 @@ void vg_free_shader( struct vg_shader *shader )
    if( shader->compiled )
    {
       glDeleteProgram( shader->id );
+      shader->id = 0;
       shader->compiled = 0;
    }
 }
@@ -163,25 +198,21 @@ void vg_shaders_compile(void)
 {
        vg_info( "Compiling shaders\n" );
 
-       for( int i=0; i<vg_shaders.count; i ++ ){
-               vg_shader *shader = vg_shaders.shaders[i];
-
-               if( !vg_shader_compile( shader ) )
-         vg_fatal_error( "Failed to compile shader" );
-       }
+       for( int i=0; i<vg_shaders.count; i ++ )
+               vg_compile_shader( vg_shaders.shaders[i] );
 
 #ifdef VG_CUSTOM_SHADERS
    vg_auto_shader_link();
 #endif
 }
 
-int vg_shaders_live_recompile(int argc, const char *argv[])
+int vg_shaders_live_recompile( int argc, const char *argv[] )
 {
    vg_info( "Recompiling shaders\n" );
    for( int i=0; i<vg_shaders.count; i ++ )
    {
       struct vg_shader *shader = vg_shaders.shaders[i];
-      vg_shader_compile( shader );
+      vg_compile_shader( shader );
    }
 
    return 0;
@@ -189,10 +220,9 @@ int vg_shaders_live_recompile(int argc, const char *argv[])
 
 void vg_shader_register( struct vg_shader *shader )
 {
-   if( vg_shaders.count == vg_list_size(vg_shaders.shaders) )
-      vg_fatal_error( "Too many shaders" );
+   VG_ASSERT( vg_shaders.count < VG_ARRAY_LEN(vg_shaders.shaders) );
 
    shader->compiled = 0;
-   shader->id = 0;         /* TODO: make this an error shader */
+   shader->id = 0; /* TODO: make this an error shader */
    vg_shaders.shaders[ vg_shaders.count ++ ] = shader;
 }
index 1ea106c84fdbc6a2a8342f89aa063a79e4198a4d..9fff67ddc6f692ed65d06cf56643fbc07d960a72 100644 (file)
@@ -18,5 +18,6 @@ struct vg_shader
 void vg_shaders_compile(void);
 int vg_shaders_live_recompile(int argc, const char *argv[]);
 void vg_shader_register( struct vg_shader *shader );
-int vg_shader_compile( struct vg_shader *shader );
+void vg_compile_shader( struct vg_shader *shader );
+void vg_recompile_shader( struct vg_shader *shader );
 void vg_free_shader( struct vg_shader *shader );
index a021cb17455ed983fa86d2ac822910e7877ed6f5..3c51338a230184ea24e6ab33214fb8322ef68807 100644 (file)
@@ -6,7 +6,8 @@ struct vg_steam vg_steam;
 
 vg_steam_async_call *vg_alloc_async_steam_api_call(void)
 {
-   if( vg_steam.call_count == vg_list_size(vg_steam.calls) ){
+   if( vg_steam.call_count == VG_ARRAY_LEN(vg_steam.calls) )
+   {
       vg_fatal_error( "Maximum concurrent API calls exceeded (%u)\n",
                       vg_steam.call_count );
    }
@@ -17,7 +18,7 @@ vg_steam_async_call *vg_alloc_async_steam_api_call(void)
 void steam_register_callback( u32 id, void (*p_handler)( CallbackMsg_t *msg ) )
 {
    if( vg_steam.callback_handler_count == 
-       vg_list_size(vg_steam.callback_handlers) )
+       VG_ARRAY_LEN(vg_steam.callback_handlers) )
    {
       vg_fatal_error( "Too many steam callback handlers registered (%u)\n", 
                       vg_steam.callback_handler_count );
index 61df5fe7b2bd1f0460e5dbda98a06c0bceb328bb..34b98f7eee21af2747f165efd8d9ddc14620eb50 100644 (file)
@@ -24,7 +24,7 @@ i32 vg_str_storage( vg_str *str )
  */
 void vg_strnull( vg_str *str, char *buffer, i32 len )
 {
-   if( len == -1 ) vg_fatal_error( "waaaa" );
+   VG_ASSERT( len >= 0 );
 
    str->buffer = buffer;
    if( buffer )
@@ -204,7 +204,10 @@ u32 vg_strncpy( const char *src, char *dst, u32 len,
          }
          else if( behaviour == k_strncpy_overflow_fatal )
          {
-            vg_fatal_error( "Strncpy dest exceeded buffer length\n" );
+            vg_fatal_condition();
+            vg_info( "vg_strncpy to buffer with maximum length '%u' exceeded"
+                     " the end of the buffer.\n", len );
+            vg_fatal_exit();
          }
       }
    }
@@ -215,7 +218,7 @@ u32 vg_strncpy( const char *src, char *dst, u32 len,
 static void _vg_strcatf_va( vg_str *str, const char *fmt, va_list args )
 {
        char buffer[4096];
-   vsnprintf( buffer, vg_list_size(buffer), fmt, args );
+   vsnprintf( buffer, VG_ARRAY_LEN(buffer), fmt, args );
    vg_strcat( str, buffer );
 }
 
index 8791dd8830b1d163197b05069e40b51ddad1d1cc..17db5f2a0c99436f093c1ce05d944b83aeea90eb 100644 (file)
--- a/vg_tex.c
+++ b/vg_tex.c
@@ -83,9 +83,7 @@ struct texture_load_info{
 
 static void async_vg_tex2d_upload( void *payload, u32 size )
 {
-   if( vg_thread_purpose() != k_thread_purpose_main ){
-      vg_fatal_error( "Catastrophic programming error.\n" );
-   }
+   VG_ASSERT( vg_thread_purpose() == k_thread_purpose_main );
 
    struct texture_load_info *info = payload;
 
@@ -277,7 +275,7 @@ void vg_tex2d_load_qoi_async( const u8 *bytes, u32 size,
 void vg_tex2d_load_qoi_async_file( const char *path, u32 flags, GLuint *dest )
 {
    if( vg_thread_purpose() != k_thread_purpose_loader )
-      vg_fatal_error( "wrong thread\n" );
+      vg_fatal_error( "Called aync texture load from wrong thread (main)\n" );
 
    vg_linear_clear( vg_mem.scratch );
 
index 8ac0832f874191bd848537c750b16b972bced9b9..ce45fa30f7a250c0b625fb7eb8796bba57d75c3e 100644 (file)
--- a/vg_tool.c
+++ b/vg_tool.c
@@ -9,11 +9,19 @@
 #include "vg_mem_queue.c"
 #include "vg_io.c"
 
+void vg_fatal_exit(void)
+{
+   exit(1);
+}
+
 void vg_fatal_error( const char *fmt, ... )
 {
+   vg_fatal_condition();
+
    va_list args;
    va_start( args, fmt );
    _vg_logx_va( stderr, NULL, "fatal", KRED, fmt, args );
    va_end( args );
-   exit(1);
+
+   vg_fatal_exit();
 }
index aa7a8502ebf86b715b1296598f84640515442c19..04493705a537dd8b9298eddb18b0a7a7328f9f3b 100644 (file)
--- a/vg_tool.h
+++ b/vg_tool.h
@@ -1,3 +1,2 @@
 #pragma once
 #include "vg_log.h"
-void vg_fatal_error( const char *fmt, ... );
index 30ccef2f474100112ed7d122e765520948efa06f..0b63730312aba77122b04076c249ec8294308f67 100644 (file)
@@ -59,7 +59,7 @@ ui_vert *ui_fill_rect( ui_context *ctx, ui_rect rect, u32 colour, ui_px uv[4] )
        u16 start = ctx->cur_vert;
    u32 mesh[] = { 0,2,1, 0,3,2 };
 
-   for( u32 i=0; i<vg_list_size(mesh); i++ )
+   for( u32 i=0; i<VG_ARRAY_LEN(mesh); i++ )
       indices[i] = start+mesh[i];
 
        ctx->cur_indice += 6;
@@ -115,7 +115,7 @@ void ui_outline( ui_context *ctx,
       mask = UI_TOP|UI_LEFT|UI_BOTTOM|UI_RIGHT;
 
    u32 c = 0;
-   for( u32 i=0; i<vg_list_size(mesh)/6; i++ )
+   for( u32 i=0; i<VG_ARRAY_LEN(mesh)/6; i++ )
    {
       if( (0x1<<i) & mask )
       {
@@ -1932,7 +1932,7 @@ void ui_dev_colourview( ui_context *ctx )
 {
    ui_rect window = {ctx->area[0]-256,0,256,ctx->area[1]}, swatch;
 
-   const char *names[vg_list_size(ctx->scheme)] = {
+   const char *names[VG_ARRAY_LEN(ctx->scheme)] = {
       [k_ui_bg] = "k_ui_bg",   "k_ui_bg+1", "k_ui_bg+2", "k_ui_bg+3",
                   "k_ui_bg+4", "k_ui_bg+5", "k_ui_bg+6", "k_ui_bg+7",
 
@@ -1947,7 +1947,7 @@ void ui_dev_colourview( ui_context *ctx )
    ui_rect col[2];
    ui_split_ratio( window, k_ui_axis_v, 0.5f, 0, col[0], col[1] );
 
-   for( int i=0; i<vg_list_size(ctx->scheme); i++ )
+   for( int i=0; i<VG_ARRAY_LEN(ctx->scheme); i++ )
    {
       int which = (i/8)%2;
 
index 236789dd91241900ffb0d9f25856a25bba650bac..9c4dc32d14cfa429c64ceb99c9d9e68b9c984d42 100644 (file)
@@ -331,7 +331,11 @@ void ui_impl_render_batch( ui_context *ctx, ui_batch *batch,
       glUniform1f( glGetUniformLocation(_shader_ui_hsv.id,"uHue"), inf->hue );
    }
    else
-      vg_fatal_error( "Invalid UI shader (%d)\n", shader );
+   {
+      vg_fatal_condition();
+      vg_info( "Invalid UI shader (%d)\n", shader );
+      vg_fatal_exit();
+   }
 
        glDrawElements( GL_TRIANGLES, batch->indice_count, GL_UNSIGNED_SHORT, 
                    (void *)((size_t)batch->indice_offset) );
@@ -411,7 +415,7 @@ void vg_ui_handle_sdl_key( ui_context *ctx, SDL_Keysym ev )
    if( ev.mod & KMOD_ALT )
       mod |= KMOD_ALT;
 
-   for( int i=0; i<vg_list_size( mappings ); i++ )
+   for( int i=0; i<VG_ARRAY_LEN( mappings ); i++ )
    {
       struct textbox_mapping *mapping = &mappings[i];
 
@@ -441,12 +445,9 @@ bool _wrap_sdl_hasclipboard_text(void)
 
 void vg_ui_init(void)
 {
-   if( !vg_shader_compile( &_shader_ui ) ||
-       !vg_shader_compile( &_shader_ui_hsv ) ||
-       !vg_shader_compile( &_shader_ui_image ) )
-   {
-      vg_fatal_error( "" );
-   }
+   vg_compile_shader( &_shader_ui );
+   vg_compile_shader( &_shader_ui_hsv );
+   vg_compile_shader( &_shader_ui_image );
 
    u32 verts = 30000, indices = 20000;
    ui_init( &vg_ui.ctx, 
@@ -538,7 +539,6 @@ void vg_ui_init(void)
    glTexImage2D( GL_TEXTURE_2D, 0, GL_R8, sheet->w, sheet->h, 0, 
                  GL_RED, GL_UNSIGNED_BYTE, image );
 
-   VG_CHECK_GL_ERR();
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );