revision 2
authorhgn <hgodden00@gmail.com>
Fri, 23 Feb 2024 03:33:37 +0000 (03:33 +0000)
committerhgn <hgodden00@gmail.com>
Fri, 23 Feb 2024 03:33:37 +0000 (03:33 +0000)
16 files changed:
vg_build.h
vg_build_utils_shader.h
vg_bvh.h
vg_engine.c
vg_imgui.c
vg_lines.c
vg_lines.h
vg_loader.c
vg_rigidbody_view.c
vg_shader.c
vg_shader.h
vg_steam_networking.h
vg_steam_remote_storage.h
vg_steam_ugc.h
vg_string.c
vg_string.h

index 9e5d9a7dcab17db3bead2b3a63c5834db6cd3b71..b582d0f9f727e9171af3877ee990208444b3c3fe 100644 (file)
@@ -433,7 +433,7 @@ struct vg_engine_config
 {
    bool use_3d, legacy_support_vg_msg1, log_source_info, steam_api,
         custom_game_settings,
-        release_mode;
+        release_mode, custom_shaders;
    i32 fixed_update_hz;
 }
 vg_engine_default_config = {
@@ -443,7 +443,8 @@ vg_engine_default_config = {
    .log_source_info = 1,
    .steam_api = 0,
    .custom_game_settings = 0,
-   .release_mode = 0
+   .release_mode = 0,
+   .custom_shaders = 0
 };
 
 void vg_add_engine( struct vg_project *proj, struct vg_engine_config *config )
@@ -463,6 +464,8 @@ void vg_add_engine( struct vg_project *proj, struct vg_engine_config *config )
       vg_strcat( &config_string, "-DVG_GAME_SETTINGS \\\n" );
    if( config->custom_game_settings )
       vg_strcat( &config_string, "-DVG_RELEASE \\\n" );
+   if( config->custom_shaders )
+      vg_strcat( &config_string, "-DVG_CUSTOM_SHADERS \\\n" );
 
    vg_strcat( &config_string, "\\\n" );
 
index 5747cf9729e25722a6f0193bcd32f52934c91549..cb4cc4b8894ef5f488f1e0430a4007ea470b9458 100644 (file)
@@ -18,6 +18,12 @@ struct
          uniform_uid;
    char  shader_dir[ 256 ];
    char  current_shader_name[ 128 ];
+
+   vg_str code_register,
+          code_link,
+          code_function_body;
+
+   bool init;
 }
 static vg_shaderbuild;
 
@@ -71,7 +77,7 @@ static void parse_uniform_name( char *start, struct uniform *uf )
              uf->name );
 }
 
-static int compile_subshader( FILE *header, char *name )
+static int compile_subshader( vg_str *str, char *name )
 {
    char error[256];
    char *full = stb_include_file( name, "", vg_shaderbuild.shader_dir, error );
@@ -83,7 +89,7 @@ static int compile_subshader( FILE *header, char *name )
    }
    else
    {
-      fprintf( header, "{\n"
+      vg_strcatf( str, "{\n"
                        ".orig_file = \"%s\",\n" 
                        ".static_src = \n",
                        name );
@@ -95,8 +101,8 @@ static int compile_subshader( FILE *header, char *name )
          if( c == '\n' || c == '\0' )
          {
             *cur = '\0';
-            fputs( "\"", header );
-            fputs( start, header );
+            vg_strcatf( str, "\"" );
+            vg_strcatf( str, start );
 
             if( !strncmp(start,"uniform",7) )
             {
@@ -110,76 +116,104 @@ static int compile_subshader( FILE *header, char *name )
 
             if( c == '\0' )
             {
-               fputs( "\"", header );
+               vg_strcatf( str, "\"" );
                break;
             }
 
-            fputs( "\\n\"\n", header );
+            vg_strcatf( str, "\\n\"\n" );
             start = cur+1;
          }
          cur ++;
       }
 
-      fputs( "},", header );
+      vg_strcatf( str, "}," );
    }
 
    free( full );
    return 1;
 }
 
+void vg_build_shader_impl( char *path )
+{
+   FILE *fp = fopen( path, "w" );
+   fputs( vg_shaderbuild.code_function_body.buffer, fp );
+   fputs( "\n\n", fp );
+
+   fputs( "void vg_auto_shader_link(void)\n{\n", fp );
+   fputs( vg_shaderbuild.code_link.buffer, fp );
+   fputs( "}\n\n", fp );
+
+   fputs( "void vg_auto_shader_register(void)\n{\n", fp );
+   fputs( vg_shaderbuild.code_register.buffer, fp );
+   fputs( "}\n\n", fp );
+
+   fclose( fp );
+}
+
 int vg_build_shader( char *src_vert, /* path/to/vert.vs    */
                      char *src_frag, /* path/to/frag.fs    */
                      char *src_geo,  /* unused currently   */
                      char *dst_h,    /* folder where .h go */
                      char *name      /* shader name        */ )
 {
-   char path[260];
+   if( !vg_shaderbuild.init )
+   {
+      vg_strnull( &vg_shaderbuild.code_link, NULL, -1 );
+      vg_strnull( &vg_shaderbuild.code_register, NULL, -1 );
+      vg_strnull( &vg_shaderbuild.code_function_body, NULL, -1 );
+      vg_shaderbuild.init = 1;
+   }
+
+   vg_str *c_link = &vg_shaderbuild.code_link,
+          *c_reg  = &vg_shaderbuild.code_register,
+          *c_body = &vg_shaderbuild.code_function_body;
+
+   char path_header[260];
    
    strcpy( vg_shaderbuild.current_shader_name, name );
-
-   strcpy( path, dst_h );
-   strcat( path, "/" );
-   strcat( path, name );
-   strcat( path, ".h" );
+   strcpy( path_header, dst_h );
+   strcat( path_header, "/" );
+   strcat( path_header, name );
+   strcat( path_header, ".h" );
 
    vg_low( "Compiling shader called '%s'\r", name );
 
-   FILE *header = fopen( path, "w" );
+   FILE *header = fopen( path_header, "w" );
    if( !header )
    {
-      fprintf(stderr, "Could not open '%s'\n", path );
+      fprintf(stderr, "Could not open '%s'\n", path_header );
       return 0;
    }
    
-   fprintf( header, "#ifndef SHADER_%s_H\n"
-                    "#define SHADER_%s_H\n", name, name );
-   fprintf( header, "static void shader_%s_link(void);\n", name );
-   fprintf( header, "static void shader_%s_register(void);\n", name );
-   fprintf( header, "static struct vg_shader _shader_%s = {\n"
-                    "   .name = \"%s\",\n"
-                    "   .link = shader_%s_link,\n"
-                    "   .vs = \n", name, name, name );
+   fprintf( header, "#pragma once\n" );
+   fprintf( header, "#include \"vg/vg_engine.h\"\n" );
+   vg_strcatf( c_body, "#include \"%s\"\n", path_header );
+   fprintf( header, "extern struct vg_shader _shader_%s;\n", name );
+   vg_strcatf( c_body, "struct vg_shader _shader_%s = {\n"
+                       "   .name = \"%s\",\n"
+                       "   .vs = \n", name, name, name );
 
    vg_shaderbuild.uniform_count = 0;
-   if( !compile_subshader(header,src_vert) )
+   if( !compile_subshader( c_body, src_vert ) )
    {
       fclose( header );
       return 0;
    }
 
-   fprintf( header, "\n   .fs = \n" );
-   if( !compile_subshader(header,src_frag) )
+   vg_strcatf( c_body, "\n   .fs = \n" );
+   if( !compile_subshader( c_body, src_frag ) )
    {
       fclose( header );
       return 0;
    }
 
-   fprintf( header, "\n};\n\n" );
+   vg_strcatf( c_body, "\n};\n\n" );
    
    for( int i=0; i<vg_shaderbuild.uniform_count; i++ )
    {
       struct uniform *uf = &vg_shaderbuild.uniform_buffer[i];
-      fprintf( header, "static GLuint %s;\n", uf->uniform_code_id );
+      fprintf( header, "extern GLuint %s;\n", uf->uniform_code_id );
+      vg_strcatf( c_body, "GLuint %s;\n", uf->uniform_code_id );
    }
 
    struct type_info
@@ -190,19 +224,17 @@ int vg_build_shader( char *src_vert, /* path/to/vert.vs    */
    }
    types[] =
    {
-      { "float", "float f", "glUniform1f(%s,f);" },
+      { "float", "f32 f", "glUniform1f(%s,f);" },
       { "bool", "int b", "glUniform1i(%s,b);" },
-
       { "vec2", "v2f v", "glUniform2fv(%s,1,v);" },
       { "vec3", "v3f v", "glUniform3fv(%s,1,v);" },
       { "vec4", "v4f v", "glUniform4fv(%s,1,v);" },
-
       { "sampler2D", "int i", "glUniform1i(%s,i);" },
       { "samplerCube", "int i", "glUniform1i(%s,i);" },
-      { "mat2", "m2x2f m", "glUniformMatrix2fv(%s,1,GL_FALSE,(float*)m);" },
-      { "mat4x3", "m4x3f m", "glUniformMatrix4x3fv(%s,1,GL_FALSE,(float*)m);" },
-      { "mat3", "m3x3f m", "glUniformMatrix3fv(%s,1,GL_FALSE,(float*)m);" },
-      { "mat4", "m4x4f m", "glUniformMatrix4fv(%s,1,GL_FALSE,(float*)m);" },
+      { "mat2", "m2x2f m", "glUniformMatrix2fv(%s,1,GL_FALSE,(f32*)m);" },
+      { "mat4x3", "m4x3f m", "glUniformMatrix4x3fv(%s,1,GL_FALSE,(f32*)m);" },
+      { "mat3", "m3x3f m", "glUniformMatrix3fv(%s,1,GL_FALSE,(f32*)m);" },
+      { "mat4", "m4x4f m", "glUniformMatrix4fv(%s,1,GL_FALSE,(f32*)m);" },
    };
 
    for( int i=0; i<vg_shaderbuild.uniform_count; i++ )
@@ -217,8 +249,8 @@ int vg_build_shader( char *src_vert, /* path/to/vert.vs    */
 
          if( !strcmp( inf->glsl_type, uf->type ) )
          {
-            fprintf( header, "static void shader_%s_%s(%s){\n", 
-                              name, uf->name, inf->args );
+            fprintf( header, "static inline void shader_%s_%s(%s)\n{\n", 
+                     name, uf->name, inf->args );
             fprintf( header, "   " );
             fprintf( header, inf->gl_call_pattern, uf->uniform_code_id );
             fprintf( header, "\n}\n" );
@@ -226,33 +258,21 @@ int vg_build_shader( char *src_vert, /* path/to/vert.vs    */
       }
    }
 
-   fprintf( header,
-         "static void shader_%s_register(void){\n"
-         "   vg_shader_register( &_shader_%s );\n"
-         "}\n",
-            name,name );
-
-   fprintf( header,
-         "static void shader_%s_use(void){ glUseProgram(_shader_%s.id); }\n",
-            name, name );
-
-   fprintf( header,
-         "static void shader_%s_link(void){\n",
-            name );
+   vg_strcatf( c_reg, "   vg_shader_register( &_shader_%s );\n", name );
+   fprintf( header,    "static inline void shader_%s_use(void);\n", name );
+   fprintf( header, "static inline void shader_%s_use(void)\n{\n", name );
+   fprintf( header, "   glUseProgram(_shader_%s.id);\n}\n", name );
 
    for( int i=0; i<vg_shaderbuild.uniform_count; i++ )
    {
       struct uniform *uf = &vg_shaderbuild.uniform_buffer[i];
-      fprintf( header
+      vg_strcatf( c_link
          "   _uniform_%s_%s = "
             "glGetUniformLocation( _shader_%s.id, \"%s\" );\n",
          name, uf->name,
          name, uf->name );
    }
 
-   fprintf( header, "}\n" );
-   fprintf( header, "#endif /* SHADER_%s_H */\n", name );
    fclose( header );
-
    return 1;
 }
index 37b100aa7c689394e1c834161162dfbe746a071d..1adb3d8cbdebbd1c432365d3bae60706ff380e0e 100644 (file)
--- a/vg_bvh.h
+++ b/vg_bvh.h
@@ -1,4 +1,5 @@
 #pragma once
+#include "vg_platform.h"
 #include "vg_mem.h"
 #include "vg_m.h"
 #include "vg_lines.h"
index 0d8c01575ecb2fa9641948fbcf5984d587da4659..268594f915f7df4b6b51b038a61ac5ae8e8435ce 100644 (file)
@@ -105,6 +105,10 @@ void async_internal_complete( void *payload, u32 size )
    SDL_AtomicUnlock( &vg.sl_status );
 }
 
+#ifdef VG_CUSTOM_SHADERS
+void vg_auto_shader_register(void); /* created from codegen */
+#endif
+
 static void _vg_load_full( void *data )
 {
    vg_preload();
@@ -121,6 +125,9 @@ static void _vg_load_full( void *data )
    vg_loader_step( vg_profiler_init, NULL );
 
    /* client */
+#ifdef VG_CUSTOM_SHADERS
+   vg_auto_shader_register();
+#endif
    vg_load();
 
    vg_async_call( async_internal_complete, NULL, 0 );
@@ -1190,3 +1197,7 @@ int AmdPowerXpressRequestHighPerformance = 1;
 #include "vg_rigidbody.c"
 #include "vg_rigidbody_view.c"
 #include "vg_shader.c"
+
+#ifdef VG_CUSTOM_SHADERS
+ #include "shaders/impl.c"
+#endif
index 25104044dfa25b6604009d95112b5c1089ba7084..21936cca44b9315aca8e2516027cda3b6fa6346c 100644 (file)
@@ -89,7 +89,6 @@ struct vg_imgui vg_ui = {
 
 static struct vg_shader _shader_ui ={
    .name = "[vg] ui - transparent",
-   .link = NULL,
    .vs = {
       .orig_file = NULL,
       .static_src = 
@@ -159,7 +158,6 @@ static struct vg_shader _shader_ui ={
 
 static struct vg_shader _shader_ui_image = {
    .name = "[vg] ui_image",
-   .link = NULL,
    .vs = 
    {
       .orig_file = NULL,
@@ -204,7 +202,6 @@ static struct vg_shader _shader_ui_image = {
 
 static struct vg_shader _shader_ui_hsv = {
    .name = "[vg] ui_hsv",
-   .link = NULL,
    .vs = {
       .orig_file = NULL,
       .static_src = 
index 27694fccacc30444536752811f1f33baf314aafa..63154820972c2e7f0aa62e04c3fdb9ebf1e4657f 100644 (file)
@@ -14,7 +14,6 @@ struct vg_lines vg_lines;
 
 static struct vg_shader _shader_lines = {
    .name = "[vg] lines",
-   .link = NULL,
    .vs = {
       .orig_file = NULL,
       .static_src = 
index dbb37c5ba5d408c97f78fcfbac984fe06b29ad82..3730b6b00f1e467ea0cd4d61cfd5f7b7a2be2199 100644 (file)
@@ -2,6 +2,7 @@
 
 #pragma once
 #include "vg_platform.h"
+#include "vg_engine.h"
 
 typedef v3f line_co;
 
index 86c7417c2f9112a3d0b37b88f85143e7562224dc..55ab081a2808b9910638109d513a44670aec9e4d 100644 (file)
@@ -1,12 +1,13 @@
+#include "vg_engine.h"
 #include "vg_loader.h"
 #include "vg_shader.h"
+#include "vg_async.h"
 
 struct vg_loader vg_loader;
 
 static struct vg_shader _shader_loader = 
 {
    .name = "[vg] loader",
-   .link = NULL,
 
    /* This is the new foreground shader */
    .vs = 
index b14df65e11765266952907e14b1cd5df5d2e5bd4..962148f13396e31787d2ac83f0f006fb5bc9b797 100644 (file)
@@ -8,7 +8,6 @@
 static struct vg_shader _shader_rigidbody = 
 {
    .name = "[vg] rigidbody",
-   .link = NULL,
    .vs = {
       .orig_file = NULL,
       .static_src = 
index 4b41c2e697cbc5ca19297a81cde52718fc3419a3..c12495c9dc93cf1909b3c45bcdb46390d3975ffe 100644 (file)
@@ -138,8 +138,6 @@ int vg_shader_compile( struct vg_shader *shader )
    
    shader->id = program;
        shader->compiled = 1;
-   if( shader->link ) 
-      shader->link();
        return 1;
 }
 
@@ -152,6 +150,10 @@ static void vg_free_shader( struct vg_shader *shader )
    }
 }
 
+#ifdef VG_CUSTOM_SHADERS
+void vg_auto_shader_link(void);
+#endif 
+
 void vg_shaders_compile(void)
 {
        vg_info( "Compiling shaders\n" );
@@ -162,6 +164,10 @@ void vg_shaders_compile(void)
                if( !vg_shader_compile( shader ) )
          vg_fatal_error( "Failed to compile shader" );
        }
+
+#ifdef VG_CUSTOM_SHADERS
+   vg_auto_shader_link();
+#endif
 }
 
 int vg_shaders_live_recompile(int argc, const char *argv[])
index 059ed8ef2cc0aa228674d659c3dc9f2f3ba58385..5e2ad3522bac3e4927b9e9b3db63f24feaca2601 100644 (file)
@@ -15,8 +15,6 @@ struct vg_shaders
                     *static_src;
       }
       vs, fs;
-
-      void (*link)(void);
       int compiled;
    }
    * shaders[48];
index da933f73e8f5bfba275f69fb7ca4d1c07b02ecf1..5abb7b651afed22dbe9f38437ff1438e0617282d 100644 (file)
@@ -181,7 +181,7 @@ typedef enum ESteamNetworkingAvailability ESteamNetworkingAvailability;
 
 /* Handle used to identify a connection to a remote host. */
 typedef u32 HSteamNetConnection;
-HSteamNetConnection const k_HSteamNetConnection_Invalid = 0;
+static HSteamNetConnection const k_HSteamNetConnection_Invalid = 0;
 
 /* 
  * Handle used to identify a "listen socket".  Unlike traditional
@@ -189,7 +189,7 @@ HSteamNetConnection const k_HSteamNetConnection_Invalid = 0;
  * different abstractions.
  */
 typedef u32 HSteamListenSocket;
-HSteamListenSocket const k_HSteamListenSocket_Invalid = 0;
+static HSteamListenSocket const k_HSteamListenSocket_Invalid = 0;
 
 typedef u32 SteamNetworkingPOPID;
 typedef i64 SteamNetworkingMicroseconds;
@@ -391,7 +391,7 @@ typedef struct SteamNetConnectionInfo_t SteamNetConnectionInfo_t;
  * connections at once efficiently.
  */
 typedef u32 HSteamNetPollGroup;
-HSteamNetPollGroup const k_HSteamNetPollGroup_Invalid = 0;
+static HSteamNetPollGroup const k_HSteamNetPollGroup_Invalid = 0;
 
 ISteamNetworkingSockets 
 *SteamAPI_SteamGameServerNetworkingSockets_SteamAPI_v012(void);
@@ -424,7 +424,7 @@ ISteamNetworkingSockets *SteamAPI_SteamNetworkingSockets_SteamAPI()
  * Migration note: This is not exactly the same as k_EP2PSendUnreliable!  You
  * probably want k_ESteamNetworkingSendType_UnreliableNoNagle
  */
-const int k_nSteamNetworkingSend_Unreliable = 0;
+static const int k_nSteamNetworkingSend_Unreliable = 0;
 
 /* 
  * Disable Nagle's algorithm.
@@ -445,7 +445,7 @@ const int k_nSteamNetworkingSend_Unreliable = 0;
  * server simulation tick to a particular client), and you use this flag to
  * flush all messages.
  */
-const int k_nSteamNetworkingSend_NoNagle = 1;
+static const int k_nSteamNetworkingSend_NoNagle = 1;
 
 /* 
  * Send a message unreliably, bypassing Nagle's algorithm for this message and 
@@ -455,7 +455,7 @@ const int k_nSteamNetworkingSend_NoNagle = 1;
  * ISteamNetworkingMessages::FlushMessagesToUser. (But using this flag is more 
  * efficient since you only make one API call.)
  */
-const int k_nSteamNetworkingSend_UnreliableNoNagle = 
+static const int k_nSteamNetworkingSend_UnreliableNoNagle = 
             k_nSteamNetworkingSend_Unreliable | 
             k_nSteamNetworkingSend_NoNagle;
 /*
@@ -464,7 +464,7 @@ const int k_nSteamNetworkingSend_UnreliableNoNagle =
  * This is only applicable for unreliable messages. Using this flag on reliable 
  * messages is invalid.
  */
-const int k_nSteamNetworkingSend_NoDelay = 4;
+static const int k_nSteamNetworkingSend_NoDelay = 4;
 
 /* 
  * Send an unreliable message, but if it cannot be sent relatively quickly, just
@@ -482,7 +482,7 @@ const int k_nSteamNetworkingSend_NoDelay = 4;
  *
  * If a message is dropped for these reasons, k_EResultIgnored will be returned.
  */
-const int k_nSteamNetworkingSend_UnreliableNoDelay = 
+static const int k_nSteamNetworkingSend_UnreliableNoDelay = 
             k_nSteamNetworkingSend_Unreliable |
             k_nSteamNetworkingSend_NoDelay | 
             k_nSteamNetworkingSend_NoNagle;
@@ -501,14 +501,14 @@ const int k_nSteamNetworkingSend_UnreliableNoDelay =
  * Migration note: This is NOT the same as k_EP2PSendReliable, it's more like 
  * k_EP2PSendReliableWithBuffering
  */
-const int k_nSteamNetworkingSend_Reliable = 8;
+static const int k_nSteamNetworkingSend_Reliable = 8;
 
 /* 
  * Send a message reliably, but bypass Nagle's algorithm.
  *
  * Migration note: This is equivalent to k_EP2PSendReliable
  */
-const int k_nSteamNetworkingSend_ReliableNoNagle = 
+static const int k_nSteamNetworkingSend_ReliableNoNagle = 
             k_nSteamNetworkingSend_Reliable | 
             k_nSteamNetworkingSend_NoNagle;
 
index 24aaf3b16b37220bfce3a81795ef4c71fcba5395..c7980e2f3d480162c0a7d5c203716cab9c0148ee 100644 (file)
@@ -1,7 +1,7 @@
 #pragma once
 #include "vg_steam.h"
 
-const u32 k_unMaxCloudFileChunkSize = 100 * 1024 * 1024;
+static const u32 k_unMaxCloudFileChunkSize = 100 * 1024 * 1024;
 
 #if defined( VALVE_CALLBACK_PACK_SMALL )
 #pragma pack( push, 4 )
@@ -22,14 +22,14 @@ typedef void ISteamRemoteStorage;
 typedef u64 UGCHandle_t;
 typedef u64 PublishedFileUpdateHandle_t;
 typedef u64 PublishedFileId_t;
-const PublishedFileId_t k_PublishedFileIdInvalid = 0;
-const UGCHandle_t k_UGCHandleInvalid = 0xffffffffffffffffull;
-const PublishedFileUpdateHandle_t 
+static const PublishedFileId_t k_PublishedFileIdInvalid = 0;
+static const UGCHandle_t k_UGCHandleInvalid = 0xffffffffffffffffull;
+static const PublishedFileUpdateHandle_t 
 k_PublishedFileUpdateHandleInvalid = 0xffffffffffffffffull;
 
 /* Handle for writing to Steam Cloud */
 typedef u64 UGCFileWriteStreamHandle_t;
-const UGCFileWriteStreamHandle_t 
+static const UGCFileWriteStreamHandle_t 
 k_UGCFileStreamHandleInvalid = 0xffffffffffffffffull;
 
 enum{ k_cchPublishedDocumentTitleMax = 128 + 1 };
index 48594b28ca6bf4e09668daa2db1e2e993df30d64..d8c2776aa80812725ec3f301b8f07131042f295c 100644 (file)
@@ -13,8 +13,8 @@ typedef void ISteamUGC;
 typedef u64 UGCQueryHandle_t;
 typedef u64 UGCUpdateHandle_t;
 
-const UGCQueryHandle_t k_UGCQueryHandleInvalid = 0xffffffffffffffffull;
-const UGCUpdateHandle_t k_UGCUpdateHandleInvalid = 0xffffffffffffffffull;
+static const UGCQueryHandle_t k_UGCQueryHandleInvalid = 0xffffffffffffffffull;
+static const UGCUpdateHandle_t k_UGCUpdateHandleInvalid = 0xffffffffffffffffull;
 
 /* Matching UGC types for queries */
 typedef enum EUGCMatchingUGCType EUGCMatchingUGCType;
@@ -196,8 +196,8 @@ enum EItemPreviewType{
    k_EItemPreviewType_ReservedMax = 255,
 };
 
-const u32 kNumUGCResultsPerPage = 50;
-const u32 k_cchDeveloperMetadataMax = 5000;
+static const u32 kNumUGCResultsPerPage = 50;
+static const u32 k_cchDeveloperMetadataMax = 5000;
 
 /* Details for a single published file/UGC */
 typedef struct SteamUGCDetails_t SteamUGCDetails_t;
index 1a38479e139243635011b0c272a6af081c6d6b80..1261f5b9479e79ea77b6989772bbcfaa42501194 100644 (file)
@@ -1,6 +1,8 @@
 #include "vg_string.h"
 #include "vg_platform.h"
 #include <string.h>
+#include <stdarg.h>
+#include <stdio.h>
 
 i32 vg_str_storage( vg_str *str )
 {
@@ -185,6 +187,21 @@ u32 vg_strncpy( const char *src, char *dst, u32 len,
    return 0;
 }
 
+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 );
+   vg_strcat( str, buffer );
+}
+
+void vg_strcatf( vg_str *str, const char *fmt, ... )
+{
+   va_list args;
+   va_start( args, fmt );
+   _vg_strcatf_va( str, fmt, args );
+   va_end( args );
+}
+
 u32 vg_strdjb2( const char *str )
 {
    u32 hash = 5381, c;
index 62d5abc14a38d40818b1a93bcec244d4f3111f68..01caf7d24b146d2c02bf1ed4a5ee652188fa8d87 100644 (file)
@@ -34,6 +34,7 @@ void vg_strfree( vg_str *str );
  * Append null terminated string to vg_str 
  */
 void vg_strcat( vg_str *str, const char *append );
+void vg_strcatf( vg_str *str, const char *fmt, ... );
 
 /* 
  * Append character to vg_str