way better controller handling
authorhgn <hgodden00@gmail.com>
Thu, 27 Apr 2023 19:31:18 +0000 (20:31 +0100)
committerhgn <hgodden00@gmail.com>
Thu, 27 Apr 2023 19:31:18 +0000 (20:31 +0100)
vg.h
vg_audio.h
vg_build_utils_shader.h
vg_input.h
vg_io.h
vg_lines.h
vg_loader.h
vg_platform.h
vg_tex.h

diff --git a/vg.h b/vg.h
index d98828e3bd380b2f9d041436e2dc29045110487f..2eb8e7a4e7bd2a7c39110e60980a7a6cf1dfa291 100644 (file)
--- a/vg.h
+++ b/vg.h
@@ -200,6 +200,8 @@ struct vg
       k_quality_profile_low = 1,
    }
    quality_profile;
+
+   float loader_ring;
 }
 VG_STATIC vg = { .time_rate = 1.0 };
 
@@ -332,12 +334,14 @@ VG_STATIC void _vg_process_events(void)
          vg.mouse_wheel[0] += event.wheel.preciseX;
          vg.mouse_wheel[1] += event.wheel.preciseY;
       }
+      else if( event.type == SDL_CONTROLLERDEVICEADDED ||
+               event.type == SDL_CONTROLLERDEVICEREMOVED )
+      {
+         vg_input_device_event( &event );
+      }
       else if( event.type == SDL_CONTROLLERAXISMOTION ||
                event.type == SDL_CONTROLLERBUTTONDOWN ||
-               event.type == SDL_CONTROLLERBUTTONUP ||
-               event.type == SDL_CONTROLLERDEVICEADDED ||
-               event.type == SDL_CONTROLLERDEVICEREMOVED
-               )
+               event.type == SDL_CONTROLLERBUTTONUP )
       {
          vg_input_controller_event( &event );
       }
@@ -374,7 +378,7 @@ VG_STATIC void _vg_process_events(void)
    vg.mouse_pos[1] += vg.mouse_delta[1];
 
    /* Update input */
-   vg_update_inputs();
+   vg_process_inputs();
 }
 
 VG_STATIC void _vg_gameloop_update(void)
@@ -546,11 +550,10 @@ VG_STATIC int vg_framefilter( double dt )
 
 VG_STATIC int _vg_crashscreen(void)
 {
-   if( vg.window_should_close )
-      return 1;
-
+#if 0
    if( vg_getkey( SDLK_ESCAPE ) )
       return 1;
+#endif
 
    glBindFramebuffer( GL_FRAMEBUFFER, 0 );
    glEnable(GL_BLEND);
@@ -594,20 +597,20 @@ VG_STATIC void _vg_gameloop(void)
 
       enum engine_status status = _vg_engine_status();
 
+      vg.time_delta = vg.time_frame_delta * vg.time_rate;
+      vg.time += vg.time_delta;
+
+      vg_run_async_checked();
+      _vg_process_events();
+
+      if( vg.window_should_close )
+         break;
+         
       if( status == k_engine_status_crashed ){
          if( _vg_crashscreen() )
             break;
       }
       else{
-         vg.time_delta = vg.time_frame_delta * vg.time_rate;
-         vg.time += vg.time_delta;
-
-         vg_run_async_checked();
-         _vg_process_events();
-
-         if( vg.window_should_close )
-            break;
-         
          if( status == k_engine_status_running ){
             _vg_gameloop_update();
             _vg_gameloop_render();
@@ -617,6 +620,11 @@ VG_STATIC void _vg_gameloop(void)
          }
       }
 
+      if( vg.loader_ring > 0.01f ){
+         vg.loader_ring -= vg.time_frame_delta * 0.5f;
+         _vg_loader_render_ring( vg.loader_ring );
+      }
+
       vg.time_frame_delta = 0.0;
       vg.time_spinning = 0;
    }
index 34bc9ee4bac5fdbb558a8012fc5385b6f1042620..0e76efd3e4959b8808807a4ee69daa53b97f0046 100644 (file)
@@ -303,8 +303,6 @@ VG_STATIC void vg_audio_init(void)
          "  Channels: 2\n"
          "  Format: s16 or f32\n" );
    }
-
-   vg_success( "Ready\n" );
 }
 
 VG_STATIC void vg_audio_free(void)
@@ -336,7 +334,7 @@ static void audio_channel_init( audio_channel *ch, audio_clip *clip, u32 flags )
    if( (ch->source->flags & AUDIO_FLAG_FORMAT) == k_audio_format_bird )
       strcpy( ch->name, "[array]" );
    else
-      strncpy( ch->name, clip->path, 31 );
+      vg_strncpy( clip->path, ch->name, 32, k_strncpy_always_add_null );
 
    ch->allocated = 1;
 
index 1c81c41822dd0532a4273c14bebdae3d97a3ea54..72afd4e862de9449cbed2401a019ae58d9220b66 100644 (file)
@@ -45,13 +45,15 @@ static void parse_uniform_name( char *start, struct uniform *uf )
       if( start[i] == ';' )
       {
          start[i] = '\0';
-         strncpy( uf->name, start, sizeof(uf->name) );
+         vg_strncpy( start, uf->name, sizeof(uf->name), 
+                     k_strncpy_always_add_null );
       }
 
       if( start[i] == '[' )
       {
          start[i] = '\0';
-         strncpy( uf->name, start, sizeof(uf->name) );
+         vg_strncpy( start, uf->name, sizeof(uf->name),
+                     k_strncpy_always_add_null );
          uf->array = 1;
       }
       
@@ -61,7 +63,8 @@ static void parse_uniform_name( char *start, struct uniform *uf )
 
          if( !type_set )
          {
-            strncpy( uf->type, start, sizeof(uf->type) );
+            vg_strncpy( start, uf->type, sizeof(uf->type),
+                        k_strncpy_always_add_null );
             type_set = 1;
          }
          start = start+i+1;
index 02c271a1ca85b0b88f829cbc8a33264ad57855c6..17f3f167aa23869262f5379819db5cc9afbffefe 100644 (file)
@@ -5,6 +5,8 @@
 #include "common.h"
 #include "vg/vg_loader.h"
 
+#define VG_MAX_CONTROLLERS 4
+
 VG_STATIC inline float vg_get_axis( const char *axis );
 VG_STATIC inline int vg_get_button( const char *button );
 
@@ -67,15 +69,35 @@ struct
    struct input_binding named_inputs[ 32 ];
    u32                  named_input_count;
 
-   const char          *controller_name;
-   SDL_GameController  *controller_handle; /* null if unplugged */
-   SDL_JoystickID       controller_joystick_id;
-   int                  controller_should_use_trackpad_look;
+   struct vg_controller{
+      SDL_GameController *handle; /* handle for controller. NULL if unused */
+      SDL_JoystickID instance_id; /* uid used in events */
+
+      enum evg_controller_type{
+         k_vg_controller_type_standard,
+         k_vg_controller_type_trackpads
+      }
+      type;
 
-   float                controller_axises[ SDL_CONTROLLER_AXIS_MAX ];
-   int                  controller_buttons[ SDL_CONTROLLER_BUTTON_MAX ];
+      float axises[ SDL_CONTROLLER_AXIS_MAX ];
+      int   buttons[ SDL_CONTROLLER_BUTTON_MAX ];
+   }
+   controllers[4];
+
+   int active_controller_index; /* most recent controller (by button press)
+                                   will be -1 if no controllers active */
+
+   /* what the user is currently using. the keyboard and controller are still
+    * active simultaneously, but this reflects what the UI should show */
+   enum userinput_method{
+      k_userinput_method_xbox,
+      k_userinput_method_playstation,
+      k_userinput_method_steamgeneric,
+      k_userinput_method_kbm
+   }
+   input_method;
 }
-VG_STATIC vg_input;
+static vg_input;
 
 VG_STATIC void vg_create_unnamed_input( struct input_binding *bind,
                                         enum input_type type )
@@ -438,6 +460,11 @@ VG_STATIC void vg_input_update( u32 num, struct input_binding *binds )
       return;
    }
 
+   struct vg_controller *acontroller = NULL;
+
+   if( vg_input.active_controller_index != -1 )
+      acontroller = &vg_input.controllers[vg_input.active_controller_index];
+
    for( i32 i=0; i<num; i++ ){
       struct input_binding *bind = &binds[i];
 
@@ -445,17 +472,14 @@ VG_STATIC void vg_input_update( u32 num, struct input_binding *binds )
          bind->button.prev = bind->button.value;
          bind->button.value = 0;
 
-         if( bind->button.gamepad_id != -1 )
-            bind->button.value |= 
-               vg_input.controller_buttons[ bind->button.gamepad_id ];
+         if( acontroller && (bind->button.gamepad_id != -1) )
+            bind->button.value |= acontroller->buttons[bind->button.gamepad_id];
 
-         if( bind->button.keyboard_id != -1 ){
+         if( bind->button.keyboard_id != -1 )
             bind->button.value |= vg_getkey( bind->button.keyboard_id );
-         }
 
          if( bind->button.mouse_id != -1 ){
-            if( SDL_GetMouseState(NULL, NULL) & 
-                                    SDL_BUTTON( bind->button.mouse_id ) )
+            if(SDL_GetMouseState(NULL,NULL) & SDL_BUTTON(bind->button.mouse_id))
                bind->button.value |= 1;
          }
       }
@@ -471,9 +495,8 @@ VG_STATIC void vg_input_update( u32 num, struct input_binding *binds )
             if( vg_getkey( bind->axis.keyboard_negative ) )
                keyboard_value -= 1.0f;
 
-         if( bind->axis.gamepad_axis != -1 ){
-            gamepad_value = 
-               vg_input.controller_axises[ bind->axis.gamepad_axis ];
+         if( acontroller && (bind->axis.gamepad_axis != -1) ){
+            gamepad_value = acontroller->axises[ bind->axis.gamepad_axis ];
 
             if( bind->axis.gamepad_inverted )
                gamepad_value *= -1.0f;
@@ -496,61 +519,188 @@ VG_STATIC void vg_input_update( u32 num, struct input_binding *binds )
             if( vg_getkey( bind->axis.keyboard_positive ))
                value = 1.0f;
          
-         if( bind->axis.gamepad_axis != -1 )
-            value = vg_maxf( value, 
-                  vg_input.controller_axises[bind->axis.gamepad_axis] );
+         if( acontroller && (bind->axis.gamepad_axis != -1) ){
+            float value1 = acontroller->axises[bind->axis.gamepad_axis];
+            value = vg_maxf( value, value1 );
+         }
 
          bind->axis.value = value;
       }
    }
 }
 
-VG_STATIC void vg_input_controller_event( SDL_Event *ev )
+/*
+ * takes SDL device index, and tries to open that on any free channel
+ */
+VG_STATIC void vg_open_gamecontroller( Sint32 index )
 {
-   if( ev->type == SDL_CONTROLLERAXISMOTION ){
-      if( ev->caxis.which == vg_input.controller_joystick_id ){
-         vg_input.controller_axises[ ev->caxis.axis ] = 
-            (float)ev->caxis.value / 32767.0f;
+   struct vg_controller *controller = NULL;
+   int vg_id = 0;
+   const char *name = SDL_GameControllerNameForIndex( index );
+   SDL_JoystickID instance_id = SDL_JoystickGetDeviceInstanceID( index );
+
+   if( instance_id == -1 ){
+      vg_error( ". Invalid device index (vg_open_gamecontroller)\n" );
+      return;
+   }
+
+   for( int j=0; j<VG_MAX_CONTROLLERS; j++ ){
+      struct vg_controller *esta = &vg_input.controllers[j];
+
+      if( esta->handle ){
+         if( esta->instance_id == instance_id ){
+            vg_warn( " . SDL_JoystickID[%d] is already in open at index #%d\n", 
+                     esta->instance_id, j );
+            return;
+         }
+      }
+      else{
+         if( !controller ){
+            controller = &vg_input.controllers[j];
+            vg_id = j;
+         }
       }
    }
-   else if( ev->type == SDL_CONTROLLERBUTTONDOWN ){
-      if( ev->cbutton.which == vg_input.controller_joystick_id )
-         vg_input.controller_buttons[ ev->cbutton.button ] = 1;
+
+   if( controller ){
+      controller->handle = SDL_GameControllerOpen( index );
+      controller->instance_id = instance_id;
+
+      if( controller->handle ){
+         vg_success( 
+               " . opened SDL_JoystickID[%d] as controller '%s' at index #%d\n",
+               instance_id, name, vg_id );
+
+         controller->axises[ SDL_CONTROLLER_AXIS_TRIGGERLEFT ] = -1.0f;
+         controller->axises[ SDL_CONTROLLER_AXIS_TRIGGERRIGHT ] = -1.0f;
+      }
+      else{
+         vg_error( ". Failed to attach game controller '%s'. Reason: %s\n",
+               name, SDL_GetError() );
+      }
    }
-   else if( ev->type == SDL_CONTROLLERBUTTONUP ){
-      if( ev->cbutton.which == vg_input.controller_joystick_id )
-         vg_input.controller_buttons[ ev->cbutton.button ] = 0;
+   else{
+      vg_error( ". Too many controllers open! ignoring '%s'\n", name );
+                
    }
 }
 
-VG_STATIC void vg_try_attach_controller(void)
+VG_STATIC void vg_input_device_event( SDL_Event *ev )
 {
-   int joy_count = SDL_NumJoysticks();
-   for( int i=0; i<joy_count; i++ ) {
-      if( SDL_IsGameController(i) ) {
-         vg_input.controller_handle = SDL_GameControllerOpen(i);
-         vg_input.controller_joystick_id = i;
-         vg_success( "Attached game controller with joystick ID %d\n", i );
-         return;
+   if( ev->type == SDL_CONTROLLERDEVICEADDED ){
+      int is_controller = SDL_IsGameController( ev->cdevice.which );
+      const char *name = SDL_JoystickNameForIndex( ev->cdevice.which );
+
+      Sint32 index = ev->cdevice.which;
+      SDL_JoystickID instance_id = SDL_JoystickGetDeviceInstanceID( index );
+      vg_info( "SDL_CONTROLLERDEVICEADDED | device index: %d, name: '%s'\n", 
+                  index, name );
+
+      if( is_controller ){
+         vg_open_gamecontroller( index );
+      }
+   }
+   else if( ev->type == SDL_CONTROLLERDEVICEREMOVED ){
+      vg_info( "SDL_CONTROLLERDEVICEREMOVED | instance_id: %d\n", 
+                  ev->cdevice.which );
+
+      for( int i=0; i<VG_MAX_CONTROLLERS; i++ ){
+         struct vg_controller *controller = &vg_input.controllers[i];
+
+         if( controller->handle ){
+            if( controller->instance_id == ev->cdevice.which ){
+               vg_info( " . closing controller at index #%d\n", i );
+               SDL_GameControllerClose( controller->handle );
+               controller->handle = NULL;
+               controller->instance_id = -1;
+
+               if( vg_input.active_controller_index == i ){
+                  vg_input.active_controller_index = -1;
+                  vg_info( " . active controller is now keyboard and mouse\n" );
+               }
+               break;
+            }
+         }
       }
    }
 }
 
-VG_STATIC void vg_update_inputs(void)
+VG_STATIC void vg_input_controller_event( SDL_Event *ev )
 {
-   vg_input.sdl_keys = SDL_GetKeyboardState(NULL);
+   if( ev->type == SDL_CONTROLLERAXISMOTION ){
+      for( int i=0; i<VG_MAX_CONTROLLERS; i++ ){
+         struct vg_controller *esta = &vg_input.controllers[i];
+
+         if( ev->caxis.which == esta->instance_id ){
+            float value = (float)ev->caxis.value / 32767.0f;
+            esta->axises[ ev->caxis.axis ] = value;
+            break;
+         }
+      }
+   }
+   else if( ev->type == SDL_CONTROLLERBUTTONDOWN ){
+      struct vg_controller *active = NULL;
+
+      if( vg_input.active_controller_index != -1 )
+         active = &vg_input.controllers[vg_input.active_controller_index];
+
+      if( !active || (ev->cbutton.which != active->instance_id) ){
+         active = NULL;
+         vg_input.active_controller_index = -1;
+
+         for( int i=0; i<VG_MAX_CONTROLLERS; i++ ){
+            if( vg_input.controllers[i].instance_id == ev->cbutton.which ){
+               active = &vg_input.controllers[i];
+               vg_input.active_controller_index = i;
+               break;
+            }
+         }
+         
+         if( active ){
+            vg_info( "Switching active controller index to #%d\n", 
+                       vg_input.active_controller_index );
+         }
+         else{
+            vg_error( "Input out of range (SDL_JoystickID#%d)\n", 
+                       ev->cbutton.which );
+         }
+      }
 
-   if( vg_input.controller_handle ){
-      if( !SDL_GameControllerGetAttached( vg_input.controller_handle ) ){
-         SDL_GameControllerClose( vg_input.controller_handle );
-         vg_input.controller_handle = NULL;
+      if( active )
+         active->buttons[ ev->cbutton.button ] = 1;
+   }
+   else if( ev->type == SDL_CONTROLLERBUTTONUP ){
+      for( int i=0; i<VG_MAX_CONTROLLERS; i++ ){
+         struct vg_controller *esta = &vg_input.controllers[i];
+
+         if( ev->cbutton.which == esta->instance_id ){
+            esta->buttons[ ev->cbutton.button ] = 0;
+            break;
+         }
       }
    }
+}
+
+VG_STATIC void vg_process_inputs(void)
+{
+   int count;
+   vg_input.sdl_keys = SDL_GetKeyboardState( &count );
+
+   if( vg_input.input_method != k_userinput_method_kbm ){
+      /* check for giving keyboard priority */
+      for( int i=0; i<count; i++ ){
+         if( vg_input.sdl_keys[i] ){
+            vg_input.input_method = k_userinput_method_kbm;
+            break;
+         }
+      }
 
-   if( !vg_input.controller_handle ){
-      vg_input.controller_axises[ SDL_CONTROLLER_AXIS_TRIGGERLEFT ] = -1.0f;
-      vg_input.controller_axises[ SDL_CONTROLLER_AXIS_TRIGGERRIGHT ] = -1.0f;
-      vg_try_attach_controller();
+      /* check for giving mouse priority */
+      if( SDL_GetMouseState(NULL,NULL) & 
+            (SDL_BUTTON(SDL_BUTTON_LEFT)|SDL_BUTTON(SDL_BUTTON_RIGHT)) )
+      {
+         vg_input.input_method = k_userinput_method_kbm;
+      }
    }
 
    /* update all inputs */
@@ -570,21 +720,21 @@ VG_STATIC void async_vg_input_init( void *payload, u32 size )
    vg_console_reg_cmd( "bind", vg_rebind_input_cmd, vg_rebind_input_cmd_poll );
 
    VG_VAR_F32( controller_deadzone, flags=VG_VAR_PERSISTENT );
-   vg_info( "Checking for controller\n" );
+
+   vg_info( "Checking for controllers\n" );
    SDL_GameControllerAddMappingsFromFile( "gamecontrollerdb.txt" );
    
    int joy_count = SDL_NumJoysticks();
-   for( int i=0; i<joy_count; i++ ) 
-   {
-      vg_info( "joystick %d: %s [gamecontroller: %d]\n", 
-            i, SDL_JoystickNameForIndex( i ),
-            SDL_IsGameController(i) );
-   }
+   for( int i=0; i<joy_count; i++ ) {
+      const char *name = SDL_JoystickNameForIndex( i );
+      int is_controller = SDL_IsGameController(i);
 
-   vg_try_attach_controller();
+      vg_info( "%d: %s [controller: %d]\n", i, name, is_controller );
 
-   vg_input.controller_axises[ SDL_CONTROLLER_AXIS_TRIGGERLEFT ] = -1.0f;
-   vg_input.controller_axises[ SDL_CONTROLLER_AXIS_TRIGGERRIGHT ] = -1.0f;
+      if( is_controller ){
+         vg_open_gamecontroller( i );
+      }
+   }
 }
 
 VG_STATIC void vg_input_init(void)
@@ -594,9 +744,13 @@ VG_STATIC void vg_input_init(void)
 
 VG_STATIC void vg_input_free(void)
 {
-   if( vg_input.controller_handle ){
-      SDL_GameControllerClose( vg_input.controller_handle );
-      vg_input.controller_handle = NULL;
+   for( int i=0; i<VG_MAX_CONTROLLERS; i++ ){
+      struct vg_controller *controller = &vg_input.controllers[i];
+
+      if( controller->handle ){
+         SDL_GameControllerClose( controller->handle );
+         controller->handle = NULL;
+      }
    }
 }
 
diff --git a/vg_io.h b/vg_io.h
index 779b8726c09db9e81d45063422518bde1f3bbe92..93525446094aa6a9ee3dac9ff9e0fad914b4673f 100644 (file)
--- a/vg_io.h
+++ b/vg_io.h
 #include <stdio.h>
 #include <errno.h>
 
+#define _TINYDIR_MALLOC(_size) vg_linear_alloc( vg_mem.scratch, _size )
+#define _TINYDIR_FREE(_size) 
+
+#include "submodules/tinydir/tinydir.h"
+
 /*
  * File I/O
  */
 
 VG_STATIC void vg_file_print_invalid( FILE *fp )
 {
-   if( feof( fp )) 
-   {
+   if( feof( fp )) {
       vg_error( "mdl_open: header too short\n" );
    }
-   else
-   {
+   else{
       if( ferror( fp ))
          vg_error( "mdl_open: %s\n", strerror(errno) );
       else
@@ -71,8 +74,7 @@ VG_STATIC void *vg_file_read( void *lin_alloc, const char *path, u32 *size )
       
       return buffer;
        }
-       else
-       {
+       else{
       vg_error( "vg_disk_open_read: %s\n", strerror(errno) );
                return NULL;
        }
@@ -96,17 +98,14 @@ VG_STATIC char *vg_file_read_text( void *lin_alloc, const char *path, u32 *sz )
 }
 
 
-VG_STATIC int vg_asset_write( const char *path, void *data, i64 size )
-{
+VG_STATIC int vg_asset_write( const char *path, void *data, i64 size ){
        FILE *f = fopen( path, "wb" );
-       if( f )
-       {
+       if( f ){
                fwrite( data, size, 1, f );
                fclose( f );
                return 1;
        }
-       else
-       {
+       else{
                return 0;
        }
 }
index 58818f25510f683103c0296f112cf0bfff4ef648..4a77502f07ca3e83a433eedba5542c458ed36a69 100644 (file)
@@ -106,8 +106,6 @@ VG_STATIC void async_vg_lines_init( void *payload, u32 payload_size )
    glEnableVertexAttribArray( 1 );
    
    VG_CHECK_GL_ERR();
-   vg_success( "done\n" );
-
    vg_lines.allow_input = 1;
 }
 
index f62763d5ca63445115a206cb3fc5d296efefbac0..f6f3a26f8b1758a6d8ab1d0b25d71b0b45f51632 100644 (file)
@@ -20,44 +20,7 @@ static struct vg_shader _shader_loader =
    .name = "[vg] loader",
    .link = NULL,
 
-   /* This is the old background shader */
-#if 0
-   .vs = 
-   {
-      .orig_file = NULL,
-      .static_src = ""
-      "layout (location=0) in vec2 a_co;"
-      "out vec2 aUv;"
-      "void main()"
-      "{"
-         "gl_Position = vec4(a_co*2.0-1.0,0.0,1.0);"
-         "aUv = a_co;"
-      "}"
-   },
-   .fs = 
-   {
-      .orig_file = NULL,
-      .static_src = 
-      
-      "out vec4 FragColor;"
-      "uniform float uTime;"
-      "in vec2 aUv;"
-      
-      "void main()"
-      "{"
-         "float dither=fract(dot(vec2(171.0,231.0),gl_FragCoord.xy)/71.0)-0.5;"
-         "float grad = 1.0-(aUv.y*0.5+0.5)*0.5;"
-         "float fmt1 = step( 0.5, grad+dither );"
-
-         "vec3 col = 0.5+0.5*sin( uTime + aUv.xyx + vec3(0.0,2.0,4.0) );"
-
-         "FragColor = vec4(vec3(0.5,0.5,0.5)*grad*fmt1,1.0);"
-      "}"
-   }
-#else
-
    /* This is the new foreground shader */
-
    .vs = 
    {
       .orig_file = NULL,
@@ -78,6 +41,7 @@ static struct vg_shader _shader_loader =
       "out vec4 FragColor;"
       "uniform float uTime;"
       "uniform float uRatio;"
+      "uniform float uOpacity;"
       "in vec2 aUv;"
 
       "float eval_zero( vec2 uv )"
@@ -107,11 +71,9 @@ static struct vg_shader _shader_loader =
          "float dither=fract(dot(vec2(171.0,231.0),gl_FragCoord.xy)/71.0)-0.5;"
          "float fmt1 = step( 0.5, zero*zero + dither )*0.8+0.2;"
 
-         "FragColor = vec4(vec3(fmt1),0.8);"
+         "FragColor = vec4(vec3(fmt1),uOpacity);"
       "}"
    }
-
-#endif
 };
 
 static struct vg_loader
@@ -162,8 +124,6 @@ VG_STATIC void _vg_loader_free(void)
       vg_info( " -> %p\n", step->fn_free );
       step->fn_free();
    }
-
-   vg_info( "done\n" );
 }
 
 VG_STATIC void _vg_render_log(void)
@@ -199,23 +159,8 @@ VG_STATIC void _vg_render_log(void)
    ui_draw( NULL );
 }
 
-VG_STATIC void _vg_loader_render(void)
+VG_STATIC void _vg_loader_render_ring( float opacity )
 {
-   glViewport( 0,0, vg.window_x, vg.window_y );
-   glBindFramebuffer( GL_FRAMEBUFFER, 0 );
-   glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
-   glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
-
-#if 0
-   glUseProgram( _shader_loader.id );
-       glUniform1f( glGetUniformLocation( _shader_loader.id, "uTime" ), vg.time );
-   glBindVertexArray( vg_loader.vao );
-   glDrawArrays( GL_TRIANGLES, 0, 6 );
-#endif
-
-   _vg_render_log();
-
-#if 1
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glBlendEquation(GL_FUNC_ADD);
@@ -224,9 +169,20 @@ VG_STATIC void _vg_loader_render(void)
        glUniform1f( glGetUniformLocation( _shader_loader.id, "uTime" ), vg.time );
    float ratio = (float)vg.window_x / (float)vg.window_y;
    glUniform1f( glGetUniformLocation( _shader_loader.id, "uRatio"), ratio );
+   glUniform1f( glGetUniformLocation( _shader_loader.id, "uOpacity"), opacity );
    glBindVertexArray( vg_loader.vao );
    glDrawArrays( GL_TRIANGLES, 0, 6 );
-#endif
+}
+
+VG_STATIC void _vg_loader_render(void)
+{
+   glViewport( 0,0, vg.window_x, vg.window_y );
+   glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+   glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
+   glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
+
+   _vg_render_log();
+   vg.loader_ring = 0.8f;
 }
 
 
index 210192d60e7164fbf6e15ed72940bb74da6b62c6..52c26c0933fc67ecabb60b6bb2e5a772b6d50257 100644 (file)
@@ -39,17 +39,35 @@ struct vg_achievement
 #define vg_list_size( A ) (sizeof(A)/sizeof(A[0]))
 #define VG_MUST_USE_RESULT __attribute__((warn_unused_result))
 
-VG_STATIC void vg_strncpy( const char *src, char *dst, u32 len )
+enum strncpy_behaviour{
+   k_strncpy_always_add_null = 0,
+   k_strncpy_allow_cutoff = 1
+};
+
+VG_STATIC void vg_strncpy( const char *src, char *dst, u32 len,
+                           enum strncpy_behaviour behaviour )
 {
-   for( u32 i=0; i<len; i++ )
-   {
+   for( u32 i=0; i<len; i++ ){
       dst[i] = src[i];
 
       if( !src[i] )
          break;
+
+      if( (behaviour == k_strncpy_always_add_null) && (i == len-1) )
+         dst[i] = '\0';
    }
 }
 
+VG_STATIC u32 vg_strdjb2( const char *str )
+{
+   u32 hash = 5381, c;
+
+   while( (c = *str++) )
+      hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
+
+   return hash;
+}
+
 #include <stdio.h>
 #include <dirent.h>
 #include <string.h>
index e857aa85858c436558aa69d9887808661b9db6c9..ef7f0e99bfb55db0350a3dbf0589d1bb3150bb32 100644 (file)
--- a/vg_tex.h
+++ b/vg_tex.h
@@ -19,9 +19,9 @@ struct vg_sprite
 
 static u8 const_vg_tex2d_err[] =
 {
+   0x00, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0xff,
-   0xff, 0x00, 0x00, 0x00,
-   0xff, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0x00, 0xff
 };