+struct vg_console
+{
+ struct vg_convar
+ {
+ void *data;
+ const char *name;
+
+ enum vg_convar_dtype
+ {
+ k_convar_dtype_i32,
+ k_convar_dtype_u32,
+ k_convar_dtype_f32
+ }
+ data_type;
+ }
+ *convars;
+
+ char lines[16][512];
+ u32 current, len;
+}
+vg_console;
+
+static void vg_convar_push( struct vg_convar cv )
+{
+ arrpush( vg_console.convars, cv );
+}
+
+static void vg_console_draw( void )
+{
+ int ptr = vg_console.current - vg_console.len;
+ if( ptr <= 0 )
+ ptr += vg_list_size( vg_console.lines );
+ ptr --;
+
+ ui_global_ctx.cursor[0] = 0;
+ ui_global_ctx.cursor[1] = 0;
+ ui_global_ctx.cursor[3] = vg_console.len*8;
+ ui_fill_x( &ui_global_ctx );
+
+ ui_new_node( &ui_global_ctx );
+ {
+ ui_fill_rect( &ui_global_ctx, ui_global_ctx.cursor, 0x77333333 );
+
+ ui_global_ctx.cursor[3] = 8;
+ ui_align_bottom( &ui_global_ctx );
+
+ for( int i = 0; i < vg_console.len; i ++ )
+ {
+ ui_text( &ui_global_ctx, vg_console.lines[ptr], 1, 0 );
+ ui_global_ctx.cursor[1] -= 8;
+
+ ptr --;
+ if( ptr < 0 )
+ ptr = vg_list_size( vg_console.lines )-1;
+ }
+ }
+ ui_end_down( &ui_global_ctx );
+}
+
+void vg_console_println( const char *str )
+{
+ if( vg_console.len < vg_list_size( vg_console.lines ) )
+ vg_console.len ++;
+
+ strcpy( vg_console.lines[ vg_console.current ++ ], str );
+
+ if( vg_console.current >= vg_list_size( vg_console.lines ) )
+ vg_console.current = 0;
+}
+
+static void vg_console_init(void)
+{
+ vg_log_callback = vg_console_println;
+}
+
+static void vg_console_free(void)
+{
+ arrfree( vg_console.convars );
+}