thingies
authorhgn <hgodden00@gmail.com>
Sun, 5 Oct 2025 19:05:54 +0000 (19:05 +0000)
committerhgn <hgodden00@gmail.com>
Sun, 5 Oct 2025 19:05:54 +0000 (19:05 +0000)
14 files changed:
async.kv [new file with mode: 0644]
bootstrap.sh
foundation.kv
include/common_api.h
include/opengl.h
shaders/blit.vs
source/engine/console.c
source/engine/main.c
source/engine/shader.c
source/engine/ui.c
source/foundation/logging.c
source/foundation/options.c
source/terminal/main.c [deleted file]
source/tools/metacompiler.c

diff --git a/async.kv b/async.kv
new file mode 100644 (file)
index 0000000..51f5f87
--- /dev/null
+++ b/async.kv
@@ -0,0 +1,7 @@
+add source/foundation/async.c
+
+hook
+{
+   event START
+   function _async_init
+}
index 86c6f1aa33567cbf86bae0a9cf461ac253a47f7e..94383467cf9cfe3ea3c60842d92f37d27458cf2c 100755 (executable)
@@ -2,7 +2,6 @@ mkdir -p bin/vg.metacompiler-linux-x86_64-zig-cc/ &&
 taskset -c 0-1 zig cc -I. -I./include/ -fsanitize=address -lasan -Wall -Wno-unused-function -O0 -ggdb \
    -std=c11 -D_DEFAULT_SOURCE \
    -include "common_api.h" \
-   source/terminal/main.c \
    source/foundation/options.c \
    source/foundation/logging.c \
    source/foundation/allocator_heap.c \
index fb1c376617b2dc6f7e5e70321a3d293265e71087..20a0e3c951e7794029280bae362df81a286c9757 100644 (file)
@@ -1,7 +1,24 @@
 include include/
 include source/
+
+event
+{
+   name OPTIONS
+   prototype "void"
+}
+event
+{
+   name START
+   prototype "void"
+}
+
 add source/foundation/options.c
 add source/foundation/logging.c
+{
+   hook OPTIONS
+   function _log_options
+}
+
 add source/foundation/allocator_heap.c
 add source/foundation/allocator_stack.c
 add source/foundation/allocator_pool.c
@@ -12,7 +29,6 @@ add source/foundation/string.c
 add source/foundation/keyvalues.c
 add source/foundation/buffer_operations.c
 add source/foundation/temporary.c
-add source/foundation/async.c
 
 {
    if linux
@@ -33,11 +49,79 @@ add source/foundation/async.c
 
 {
    if game_engine
-   add source/engine/main.c
-   add source/engine/ui.c
+   {
+      add source/engine/main.c
+      hook
+      {
+         event OPTIONS
+         function _engine_options
+      }
+   }
+
+   {
+      add source/engine/ui.c
+      hook
+      {
+         event START
+         function _engine_ui_init
+      }
+   }
+
+   {
+      add source/engine/input.c
+      hook
+      {
+         event START
+         function _input_init
+      }
+      ccmd
+      {
+         name bind
+         function _input_bind_ccmd
+         description "Bind device input to a button, action or axis"
+
+         parameter
+         {
+            description "Device input alias"
+         }
+
+         parameter
+         {
+            description "button,action,axis name"
+         }
+      }
+      ccmd
+      {
+         name unbind
+         description "Unbind all bindings that match"
+         function _input_unbind_ccmd
+
+         parameter
+         {
+            description "binding"
+         }
+      }
+   }
+
+   {
+      add source/console_core.c
+      hook
+      {
+         event START
+         function _console_init
+      }
+   }
+
+   {
+      add source/engine/console.c
+      hook
+      {
+         event START
+         function _engine_console_init
+      }
+   }
+
    add source/engine/shader.c
-   add source/engine/console.c
-   add source/console_core.c
    input_layer
    {
       name console
@@ -49,10 +133,12 @@ add source/foundation/async.c
       layer_mask console
    }
 
+   append async.kv
    thread
    {
       name main
       queue_size_m 40
+      flag MAIN
    }
    thread
    {
@@ -72,34 +158,6 @@ add source/foundation/async.c
    append graphics.kv
    append glfw3.kv
 
-   add source/engine/input.c
-   ccmd
-   {
-      name bind
-      function _input_bind_ccmd
-      description "Bind device input to a button, action or axis"
-
-      parameter
-      {
-         description "Device input alias"
-      }
-
-      parameter
-      {
-         description "button,action,axis name"
-      }
-   }
-   ccmd
-   {
-      name unbind
-      description "Unbind all bindings that match"
-      function _input_unbind_ccmd
-
-      parameter
-      {
-         description "binding"
-      }
-   }
 
    ccmd
    {
@@ -222,11 +280,16 @@ add source/foundation/async.c
       {
          type vertex
          add shaders/blit.vs
-         
+
          uniform
          {
-            type sampler2D
-            alias uTexMain
+            type vec2
+            alias uInverseRatio
+         }
+         uniform
+         {
+            type int
+            alias uFlip
          }
       }
 
@@ -234,6 +297,12 @@ add source/foundation/async.c
       {
          type fragment
          add shaders/blit_tex.fs
+         
+         uniform
+         {
+            type sampler2D
+            alias uTexMain
+         }
       }
    }
 
@@ -245,12 +314,6 @@ add source/foundation/async.c
       cheat 1
       description "This is just a test variable!"
    }
-
-   event
-   {
-      name ENGINE_INIT
-      prototype "void"
-   }
    event
    {
       name ENGINE_FIXED_UPDATE
@@ -271,4 +334,10 @@ add source/foundation/async.c
       name ENGINE_UI
       prototype "void"
    }
+
+   hook
+   {
+      event START
+      function "_shaders_compile"
+   }
 }
index 2c3c7b72c39babcf39bd37a8a0f4599d9f575f96..985bba41e1a7901c97ab572cf05a2e12453b66eb 100644 (file)
@@ -3,6 +3,13 @@
 #define API
 #define IMPL
 
+#define VG_PRE_MAIN \
+   _exit_init(); \
+   _log_init(); \
+   _options_init( argc, argv ); \
+   EVENT_CALL( OPTIONS ); \
+   _options_check_end(); 
+
 /* Types
  * ------------------------------------------------------------------------------------------------------------------ */
 typedef unsigned        char u8;
@@ -297,8 +304,7 @@ enum string_parse_result string_parse_string( struct stream *string, u32 *out_st
 struct stream *_log_event( u32 type, const c8 *code_location );
 void _log_init(void);
 void _log_end_event(void);
-void _log_set_journal_path( const c8 *path );
-void _log_add_listener( void (*fn)(const c8 *line, u32 length, u32 type), u32 filter );
+void _log_add_listener( void (*fn)(const c8 *line, u32 length, u32 type), u32 filter, bool accept_vt_codes );
 
 /* Keyvalues
  * ------------------------------------------------------------------------------------------------------------------ */
index c30219b3f7ac329ee34197123c220028bd897f2b..b04c4972718348e46165a358d080141f323a07c1 100644 (file)
@@ -1,5 +1,7 @@
 #include "vg/dep/glad.4.3/glad/glad.h"
+#include "generated/shaders.h"
 
-API GLuint compile_opengl_subshader( GLint type, const c8 *src, bool critical, const c8 *debug_path );
+API GLuint compile_opengl_subshader( GLint type, const c8 *sources[], u32 source_count, bool critical, const c8 *debug_path );
 API bool link_opengl_program( GLuint program, bool critical );
-API GLuint compile_opengl_shader( const c8 *vs, const c8 *fs );
+
+void _shader_bind( enum shader_id id );
index 06ffba6ba1e2383f0abe19e3093ac6a473f5917c..e19a10f0d40e39c44023e402e006dec930dfef11 100644 (file)
@@ -1,10 +1,12 @@
 layout (location=0) in vec2 a_co;
 out vec2 aUv;
 
-uniform vec2 uInverseRatio;
-
 void main()
 {
    gl_Position = vec4(a_co*2.0-1.0,0.0,1.0);
-   aUv = a_co * uInverseRatio;
+
+   if( uFlip == 1 )
+      aUv = vec2(a_co.x,1.0-a_co.y) * uInverseRatio;
+   else
+      aUv = a_co * uInverseRatio;
 }
index 0920b695eb9043e36d96b7bd5ae3569869191e8c..005ff54b5d3c136932f674b3a40e03a5f57e8db5 100644 (file)
@@ -64,7 +64,7 @@ again:;
 
 void _engine_console_init(void)
 {
-   _log_add_listener( _log_listener, ($info | $ok | $warning | $error | $fatal | $shell) );
+   _log_add_listener( _log_listener, ($info | $ok | $warning | $error | $fatal | $shell), 0 );
    queue_init( &_console.input_history, _heap_allocate( BYTES_KB(2) ), BYTES_KB(2) );
    queue_init( &_console.log_history, _heap_allocate( BYTES_KB(4) ), BYTES_KB(4) );
 }
index 8f4d93878daaeb38624b36166d27456b80370ec3..20fc9feba6b28daf451259a3e2f6dd82486f14f1 100644 (file)
@@ -38,24 +38,19 @@ void _character_callback( GLFWwindow *window, u32 codepoint )
    _engine_ui_input_character( codepoint );
 }
 
-i32 main( i32 argc, const c8 *argv[] )
+void _engine_options(void)
 {
-   _exit_init();
-   _log_init();
-   _options_init( argc, argv );
-
    const c8 *arg;
    if( _option_long( "high-performance", "Turn graphics to lowest quality" ) )
       _engine.quality = k_quality_profile_low;
 
-   if( (arg = _option_long_argument( "log", "Log output to text file (without console colours)" )) )
-      _log_set_journal_path( arg );
-
    //if( vg_long_opt( "no-steam", "Disable Steam integration (Good idea for pirating)" ) )
    //   _steam_api.disabled = 1;
-   
-   EVENT_CALL( ENGINE_INIT );
-   _options_check_end();
+}
+
+i32 main( i32 argc, const c8 *argv[] )
+{
+   VG_PRE_MAIN;
 
    ASSERT_CRITICAL( glfwInit() );
 
@@ -79,10 +74,7 @@ i32 main( i32 argc, const c8 *argv[] )
    f64 next_frame_time = 0.0, fixed_time = 0.0, fixed_accumulator = 0.0;
 
    /* ------------- */
-   _engine_ui_init();
-   _input_init();
-   _console_init();
-   _engine_console_init();
+   EVENT_CALL( START );
 
 L_new_frame:;
    f64 now = glfwGetTime();
index 2d2b3b2fbbee25d0393e863dc923639b72255126..8183d3d30ae86968a96e77c00df2f7c2e83eddd6 100644 (file)
@@ -1,9 +1,6 @@
 #include "opengl.h"
-#include "generated/shaders.h"
 
-GLuint _uniform_locations[ k_shader_uniform_count ];
-
-GLuint compile_opengl_subshader( GLint type, const c8 *src, bool critical, const c8 *debug_path )
+GLuint compile_opengl_subshader( GLint type, const c8 *sources[], u32 source_count, bool critical, const c8 *name )
 {
        GLuint shader = glCreateShader( type );
    if( shader == 0 )
@@ -12,7 +9,7 @@ GLuint compile_opengl_subshader( GLint type, const c8 *src, bool critical, const
       _fatal_exit();
    }
 
-       glShaderSource( shader, 2, (const char*[2]){ "#version 330 core\n", src }, NULL );
+       glShaderSource( shader, source_count, sources, NULL );
        glCompileShader( shader );
 
        GLint status;
@@ -30,7 +27,7 @@ GLuint compile_opengl_subshader( GLint type, const c8 *src, bool critical, const
       else if( type == GL_FRAGMENT_SHADER ) type_str = "GL_FRAGMENT_SHADER";
       if( critical ) 
       {
-         $log( $fatal, {"subshader compile error\n"}, {debug_path}, {": "}, {type_str}, {info} );
+         $log( $fatal, {"subshader compile error\n"}, {name}, {": "}, {type_str}, {info} );
          _fatal_exit();
       }
       return 0;
@@ -57,6 +54,7 @@ bool link_opengl_program( GLuint program, bool critical )
        }
 }
 
+#if 0
 GLuint compile_opengl_shader( const c8 *vs, const c8 *fs )
 {
    GLuint vert = compile_opengl_subshader( GL_VERTEX_SHADER, vs, 1, NULL ),
@@ -69,6 +67,10 @@ GLuint compile_opengl_shader( const c8 *vs, const c8 *fs )
        glDeleteShader( frag );
    return program;
 }
+#endif
+
+GLuint _shader_programs[ k_shader_count ];
+GLuint _uniform_locations[ k_shader_uniform_count ];
 
 struct shader
 {
@@ -93,3 +95,46 @@ struct shader
 };
 
 #include "generated/shaders.c"
+
+void _shaders_compile(void)
+{
+   for( u32 i=0; i<k_shader_count; i ++ )
+   {
+      struct shader *shader = &_shader_definitions[ i ];
+      GLuint new_program = glCreateProgram();
+      GLuint sub_programs[3];
+
+      for( u32 j=0; j<shader->subshader_count; j ++ )
+      {
+         struct subshader *subshader = &shader->subshaders[j];
+
+         const c8 *sources[32] = { "#version 330 core\n", NULL };
+         u32 source_count = 1;
+         sources[ source_count ++ ] = subshader->source_uniforms;
+         sources[ source_count ++ ] = subshader->source_static;
+
+         ASSERT_CRITICAL( subshader->type != k_subshader_geometry );
+         sub_programs[j] = compile_opengl_subshader( 
+               (subshader->type == k_subshader_vertex? GL_VERTEX_SHADER: GL_FRAGMENT_SHADER), 
+               sources, source_count, 1, shader->name );
+         glAttachShader( new_program, sub_programs[j] );
+      }
+
+      link_opengl_program( new_program, 1 );
+      _shader_programs[i] = new_program;
+
+      for( u32 j=0; j<shader->subshader_count; j ++ )
+         glDeleteShader( sub_programs[j] );
+
+      for( u32 j=0; j<shader->uniform_count; j ++ )
+      {
+         u32 index = shader->uniform_start+j;
+         _uniform_locations[ index ] = glGetUniformLocation( new_program, _uniform_aliases[ index ] );
+      }
+   }
+}
+
+void _shader_bind( enum shader_id id )
+{
+   glUseProgram( _shader_programs[ id ] );
+}
index 970cf84af5403da43eadfb23dd0f30d0cfd2b954..931cb280ca406a09e16b9c282b9c92c8e63f12bb 100644 (file)
@@ -10,7 +10,6 @@ struct graphics_target _ui_surface =
 };
 
 GLuint _ui_surface_texture;
-GLuint _ui_blit_shader;
 GLuint quad_vao, quad_vbo;
 
 void _engine_ui_init(void)
@@ -40,27 +39,6 @@ void _engine_ui_init(void)
    glBindVertexArray( quad_vao );
    glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, sizeof(f32)*2, (void*)0 );
    glEnableVertexAttribArray( 0 );
-
-   const c8 *blit_vs = 
-"layout (location=0) in vec2 a_co;\n"
-"out vec2 aUv;\n"
-"uniform vec2 uInverseRatio;\n"
-"void main()\n"
-"{\n"
-"   gl_Position = vec4(a_co*2.0-1.0,0.0,1.0);\n"
-"   aUv = vec2(a_co.x,1.0-a_co.y) * uInverseRatio;\n"
-"}\n";
-
-   const c8 *blit_fs = 
-"out vec4 FragColor;\n"
-"uniform sampler2D uTexMain;\n"
-"in vec2 aUv;\n"
-"void main()\n"
-"{\n"
-"   FragColor = texture( uTexMain, aUv );\n"
-"}\n";
-
-  _ui_blit_shader = compile_opengl_shader( blit_vs, blit_fs );
 }
 
 void _engine_ui_pre_render(void)
@@ -119,9 +97,10 @@ void _engine_ui_post_render(void)
    glBindTexture( GL_TEXTURE_2D, _ui_surface_texture );
    glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 1920, 1080, GL_BGRA, GL_UNSIGNED_BYTE, _ui_surface.buffer );
 
-   glUseProgram( _ui_blit_shader );
-   glUniform1i( glGetUniformLocation( _ui_blit_shader, "uTexMain" ), 0 );
-   glUniform2f( glGetUniformLocation( _ui_blit_shader, "uInverseRatio" ), (f64)_engine.w/1920.0, (f64)_engine.h/1080.0 );
+   _shader_bind( k_shader_blit );
+   _shader_blit_uTexMain( 0 );
+   _shader_blit_uFlip( 1 );
+   _shader_blit_uInverseRatio( (f32[2]){ (f64)_engine.w/1920.0, (f64)_engine.h/1080.0 } );
    glBindVertexArray( quad_vao );
    glDrawArrays( GL_TRIANGLES, 0, 6 );
 }
index a90917dfed99e29063787b2485f7c60f578842d1..8fa4617804c00b21820a423a36ae6d49185ed23a 100644 (file)
 static struct stream _log_stream;
 static struct stream _stdout_stream;
 static struct stream _journal_stream;
-static mtx_t _lock;
-static bool _writing_event;
+
+#define OUTPUT_LINE_LENGTH 120
+#define VT_MAX_LENGTH      10
 
 struct
 {
-   c8 line[ 121 ];
-   u32 line_length;
+   bool writing_event;
+   mtx_t lock;
+
+   c8 line[ OUTPUT_LINE_LENGTH + VT_MAX_LENGTH + 2 /* \n\0 */ ];
+   u32 line_length, line_length_visual, vt_filter;
 
-   bool wait;
    u32 current_type;
 
    struct log_line_callback
    {
       u32 filter;
+      bool accept_vt_codes;
       void( *fn )( const c8 *line, u32 length, u32 type );
    }
    callbacks[ 8 ];
    u32 callback_count;
 }
-_listeners;
+_log;
 
-void _log_add_listener( void (*fn)(const c8 *line, u32 length, u32 type), u32 filter )
+void _log_add_listener( void (*fn)(const c8 *line, u32 length, u32 type), u32 filter, bool accept_vt_codes )
 {
-   ASSERT_CRITICAL( _listeners.callback_count < ARRAY_COUNT( _listeners.callbacks ) );
-   struct log_line_callback *cb = &_listeners.callbacks[ _listeners.callback_count ++ ];
+   ASSERT_CRITICAL( _log.callback_count < ARRAY_COUNT( _log.callbacks ) );
+   struct log_line_callback *cb = &_log.callbacks[ _log.callback_count ++ ];
    cb->fn = fn;
    cb->filter = filter;
+   cb->accept_vt_codes = accept_vt_codes;
 }
 
 static u32 _log_stream_passthrough( struct stream *stream, const void *buffer, u32 length )
 {
-   // TODO: Allow colour codes into the line buffer, but those dont count towards line length.
-   //       the AFTERWARDS, filter out the codes and send those to the listeners.
    for( u32 i=0; i<length; i ++ )
    {
       u8 c = ((u8 *)buffer)[i];
-      if( _listeners.wait )
+
+      _log.line[ _log.line_length ++ ] = c;
+
+      if( _log.vt_filter )
       {
          if( c == 'm' )
-            _listeners.wait = 0;
+            _log.vt_filter = 0;
+         else
+         {
+            _log.vt_filter ++;
+            ASSERT_CRITICAL( _log.vt_filter <= VT_MAX_LENGTH );
+         }
+         continue;
       }
-      else
+      else if( c == 0x1B )
       {
-         if( c == 0x1B )
-            _listeners.wait = 1;
-         else
+         _log.vt_filter ++;
+         continue;
+      }
+
+      _log.line_length_visual ++;
+
+      bool wrap = (_log.line_length == (ARRAY_COUNT( _log.line )-VT_MAX_LENGTH-2));
+      if( wrap )
+         _log.line[ _log.line_length ++ ] = '\n';
+
+      if( c == '\n' )
+         wrap = 1;
+
+      if( wrap )
+      {
+         _log.line[ _log.line_length ] = 0;
+
+         /* With VT codes */
+         stream_write( &_stdout_stream, _log.line, _log.line_length );
+         for( u32 j=0; j<_log.callback_count; j ++ )
          {
-            bool nl = ( c == '\n' );
-            _listeners.line[ _listeners.line_length ++ ] = c;
+            struct log_line_callback *cb = &_log.callbacks[j];
+            if( (cb->filter & _log.current_type) && cb->accept_vt_codes )
+               cb->fn( _log.line, _log.line_length, _log.current_type );
+         }
 
-            bool wrap = (_listeners.line_length == (ARRAY_COUNT( _listeners.line )-1));
-            if( wrap || nl )
+         /* Take out VT codes */
+         u32 vt_filter;
+         u32 k = 0;
+         for( u32 j=0; j<_log.line_length; j ++ )
+         {
+            u8 c = _log.line[ j ];
+            if( vt_filter )
             {
-               _listeners.line[ _listeners.line_length ] = 0;
-
-               if( _journal_stream.flags & k_stream_write )
-                  stream_write( &_journal_stream, _listeners.line, _listeners.line_length );
-
-               for( u32 j=0; j<_listeners.callback_count; j ++ )
-               {
-                  struct log_line_callback *cb = &_listeners.callbacks[j];
-                  if( cb->filter & _listeners.current_type )
-                     cb->fn( _listeners.line, _listeners.line_length, _listeners.current_type );
-               }
-               stream_write( &_stdout_stream, _listeners.line, _listeners.line_length );
-               _listeners.line_length = 0;
+               if( c == 'm' ) vt_filter = 0;
+               else           vt_filter ++;
+               continue;
             }
-
-            if( _writing_event && (nl||wrap) )
+            else
             {
-               while( _listeners.line_length < 33 )
-                  _listeners.line[ _listeners.line_length ++ ] = ' ';
-               _listeners.line[ _listeners.line_length ++ ] = '.';
+               if( c == 0x1B ) vt_filter ++;
+               else            _log.line[ k ++ ] = c;
             }
          }
+         _log.line_length = k;
+         _log.line[ k ] = 0;
+
+         if( _journal_stream.flags & k_stream_write )
+            stream_write( &_journal_stream, _log.line, _log.line_length );
+         for( u32 j=0; j<_log.callback_count; j ++ )
+         {
+            struct log_line_callback *cb = &_log.callbacks[j];
+            if( (cb->filter & _log.current_type) && !cb->accept_vt_codes )
+               cb->fn( _log.line, _log.line_length, _log.current_type );
+         }
+
+         _log.line_length = 0;
+         _log.line_length_visual = 0;
+      }
+
+      if( _log.writing_event && wrap )
+      {
+         while( _log.line_length < 33 )
+            _log.line[ _log.line_length ++ ] = ' ';
+         _log.line[ _log.line_length ++ ] = '.';
+         _log.line_length_visual = _log.line_length;
       }
    }
 
@@ -87,34 +133,26 @@ static u32 _log_stream_passthrough( struct stream *stream, const void *buffer, u
    return length;
 }
 
-void _log_set_journal_path( const c8 *path )
-{
-   _journal_stream.posix_stream = fopen( path, "wb" );
-   ASSERT_CRITICAL( _journal_stream.posix_stream );
-   _journal_stream.offset = 0;
-   _journal_stream.buffer_length = 0;
-   _journal_stream.flags = k_stream_posix | k_stream_write;
-}
-
 struct stream *_log_event( u32 type, const c8 *code_location )
 {
-   ASSERT_CRITICAL( mtx_lock( &_lock ) == thrd_success );
-   _listeners.current_type = type;
+   ASSERT_CRITICAL( mtx_lock( &_log.lock ) == thrd_success );
+   _log.current_type = type;
 
    struct stream *output = &_log_stream;
    string_append( output, KBLK, 0 );
 
-   u32 line_start = output->offset;
-
-   i32 s = buffer_last_index( code_location, '/', 0 );
-   if( s != -1 )
+   if( type != $raw ) 
    {
-      string_append( output, "...", 0 );
-      code_location += s+1;
+      i32 s = buffer_last_index( code_location, '/', 0 );
+      if( s != -1 )
+      {
+         string_append( output, "...", 0 );
+         code_location += s+1;
+      }
+      string_append( output, code_location, 0 );
+      while( _log.line_length_visual < 30 ) string_append_c8( output, ' ' );
    }
-   string_append( output, code_location, 0 );
 
-   while( (output->offset-line_start) < 30 ) string_append_c8( output, ' ' );
         if( type == $error )   string_append( output, KRED "ERR|", 0 );
    else if( type == $warning ) string_append( output, KYEL "WRN|", 0 );
    else if( type == $ok )      string_append( output, KGRN "OK |", 0 );
@@ -124,23 +162,21 @@ struct stream *_log_event( u32 type, const c8 *code_location )
    else if( type == $shell )   string_append( output, KBLU "SHL|", 0 );
    string_append( output, KNRM, 0 );
 
-   _writing_event = 1;
+   _log.writing_event = 1;
    return output;
 }
 
 void _log_end_event(void)
 {
-   _writing_event = 0;
-
+   _log.writing_event = 0;
    struct stream *output = &_log_stream;
    string_append( output, "\n", 0 );
-
-   ASSERT_CRITICAL( mtx_unlock( &_lock ) == thrd_success );
+   ASSERT_CRITICAL( mtx_unlock( &_log.lock ) == thrd_success );
 }
 
 void _log_init(void)
 {
-   ASSERT_CRITICAL( mtx_init( &_lock, mtx_plain ) == thrd_success );
+   ASSERT_CRITICAL( mtx_init( &_log.lock, mtx_plain ) == thrd_success );
    _stdout_stream.posix_stream = stdout;
    _stdout_stream.offset = 0;
    _stdout_stream.buffer_length = 0;
@@ -150,3 +186,16 @@ void _log_init(void)
    _log_stream.offset = 0;
    _log_stream.write_procedure = _log_stream_passthrough;
 }
+
+void _log_options(void)
+{
+   const c8 *arg;
+   if( (arg = _option_long_argument( "log", "Log output to text file (without console colours)" )) )
+   {
+      _journal_stream.posix_stream = fopen( arg, "wb" );
+      ASSERT_CRITICAL( _journal_stream.posix_stream );
+      _journal_stream.offset = 0;
+      _journal_stream.buffer_length = 0;
+      _journal_stream.flags = k_stream_posix | k_stream_write;
+   }
+}
index c3eeedcb16e61313ae08139c6c06621d70b0b282..556d2a0e5fe3b2153a18dfa0a5d8fef1c404d0dd 100644 (file)
@@ -107,7 +107,7 @@ void _options_check_end(void)
          struct option *option = &_options.options[i];
          const c8 *desc = option->desc? option->desc: "";
 
-         struct stream *log = _log_event( $raw, NULL );
+         struct stream *log = _log_event( $raw, $line );
 
          u32 base_offset = log->offset;
          if( option->type == k_option_type_flag || option->type == k_option_type_option )
@@ -124,10 +124,9 @@ void _options_check_end(void)
                $v_string( log, {"=<value>"} );
          }
 
-         while( log->offset < base_offset + 60 )
+         while( log->offset < base_offset + 40 )
             string_append_c8( log, ' ' );
          string_append( log, desc, 0 );
-         string_append_c8( log, '\n' );
          _log_end_event();
       }
       _normal_exit();
@@ -141,7 +140,7 @@ void _options_check_end(void)
       {
          if( argument->type == k_argument_singles )
          {
-            for( u32 j=0; j<32; j ++ )
+            for( u32 j=0; j<31; j ++ )
             {
                if( !(argument->used & (0x1<<j)) )
                {
diff --git a/source/terminal/main.c b/source/terminal/main.c
deleted file mode 100644 (file)
index aef4a11..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-i32 _terminal_init(void);
-i32 _terminal_main(void);
-
-i32 main( i32 argc, const c8 *argv[] )
-{
-   _exit_init();
-   _log_init();
-   _options_init( argc, argv );
-   _terminal_init();
-   _options_check_end();
-   return _terminal_main();
-}
index 680c6807e700bfd5edd6db544b9ce9e287a61a46..d8a1c3b7bc63108a6e5ec2847bae65898cce29e0 100644 (file)
@@ -153,20 +153,20 @@ void _parse_kv_block( struct keyvalues *kvs, u32 block, struct block_context con
             }
             type_list[] =
             {
-               { "int",          "i32 b",    "glUniform1i",            "b" },
-               { "vec2",         "v2f v",    "glUniform2fv",           "1,v" },
-               { "vec3",         "v3f v",    "glUniform3fv",           "1,v" },
-               { "vec4",         "v4f v",    "glUniform4fv",           "1,v" },
-               { "bool",         "i32 b",    "glUniform1i",            "b" },
-               { "mat2",         "m2x2f m",  "glUniformMatrix2fv",     "1,GL_FALSE,(f32*)m" },
-               { "mat3",         "m3x3f m",  "glUniformMatrix3fv",     "1,GL_FALSE,(f32*)m" },
-               { "mat4",         "m4x4f m",  "glUniformMatrix4fv",     "1,GL_FALSE,(f32*)m" },
-               { "float",        "f32 f",    "glUniform1f",            "f" },
-               { "mat4x3",       "m4x3f m",  "glUniformMatrix4x3fv",   "1,GL_FALSE,(f32*)m" },
-               { "sampler2D",    "i32 i",    "glUniform1i",            "i" },
-               { "usampler3D",   "i32 i",    "glUniform1i",            "i" },
-               { "samplerCube",  "i32 i",    "glUniform1i",            "i" },
-               { "samplerBuffer","i32 i",    "glUniform1i",            "i" },
+               { "int",          "i32 b",        "glUniform1i",            "b" },
+               { "vec2",         "f32 v[2]",     "glUniform2fv",           "1,v" },
+               { "vec3",         "f32 v[3]",     "glUniform3fv",           "1,v" },
+               { "vec4",         "f32 v[4]",     "glUniform4fv",           "1,v" },
+               { "bool",         "i32 b",        "glUniform1i",            "b" },
+               { "mat2",         "f32 m[2][2]",  "glUniformMatrix2fv",     "1,GL_FALSE,(f32*)m" },
+               { "mat3",         "f32 m[3][3]",  "glUniformMatrix3fv",     "1,GL_FALSE,(f32*)m" },
+               { "mat4",         "f32 m[4][4]",  "glUniformMatrix4fv",     "1,GL_FALSE,(f32*)m" },
+               { "float",        "f32 f",        "glUniform1f",            "f" },
+               { "mat4x3",       "f32 m[4][3]",  "glUniformMatrix4x3fv",   "1,GL_FALSE,(f32*)m" },
+               { "sampler2D",    "i32 i",        "glUniform1i",            "i" },
+               { "usampler3D",   "i32 i",        "glUniform1i",            "i" },
+               { "samplerCube",  "i32 i",        "glUniform1i",            "i" },
+               { "samplerBuffer","i32 i",        "glUniform1i",            "i" },
             },
             *trans = NULL;
 
@@ -183,10 +183,10 @@ void _parse_kv_block( struct keyvalues *kvs, u32 block, struct block_context con
             $v_string( &_shaders.uniform_enum, {"   k_shader_"}, {string_get(&shader->name)}, {"_"}, {alias}, {",\n"} );
             $v_string( &_shaders.uniform_aliases, {"   [k_shader_"}, {string_get(&shader->name)}, {"_"}, {alias}, {"] = \""},
                   {alias},{"\",\n"} );
-            $v_string( &subshader->uniform_source, {"uniform "}, {type}, {" "}, {alias}, {"\\n"} );
+            $v_string( &subshader->uniform_source, {"uniform "}, {type}, {" "}, {alias}, {";\\n"} );
 
-            $v_string( &_shaders.uniform_func_protos, {"void _shader"}, {string_get(&shader->name)}, {"_"}, {alias}, {"( "},{trans->args},{" );\n"} );
-            $v_string( &_shaders.uniform_funcs, {"void _shader"}, {string_get(&shader->name)}, {"_"}, {alias}, {"( "},{trans->args},{" )"},
+            $v_string( &_shaders.uniform_func_protos, {"void _shader_"}, {string_get(&shader->name)}, {"_"}, {alias}, {"( "},{trans->args},{" );\n"} );
+            $v_string( &_shaders.uniform_funcs, {"void _shader_"}, {string_get(&shader->name)}, {"_"}, {alias}, {"( "},{trans->args},{" )"},
                      {"{ "},{trans->call},{"( _uniform_locations["}, 
                         {"k_shader_"}, {string_get(&shader->name)}, {"_"}, {alias},
                      {"], "},{trans->end},{" ); }\n"});
@@ -552,7 +552,7 @@ const c8 *platform_names[] =
 u64 processors = 4;
 const c8 *target_file_path = NULL;
 
-i32 _terminal_init(void)
+void _metacompiler_options(void)
 {
    const c8 *arg;
    if( _option_long( "tsan", "Build using thread sanitizer" ) )
@@ -589,12 +589,18 @@ i32 _terminal_init(void)
    
    target_file_path = _option();
    ASSERT_CRITICAL( target_file_path );
-
-   return 0;
 }
 
-i32 _terminal_main(void)
+void (*_event_OPTIONS_subscribers[])( void ) = 
+{
+   _metacompiler_options,
+   NULL
+};
+
+i32 main( i32 argc, const c8 *argv[] )
 {
+   VG_PRE_MAIN;
+
    buffer_copy( "project", 0, _metacompiler.project_name, sizeof(_metacompiler.project_name) );
 
    u32 options = k_stream_null_terminate;