now thats a lot of damage!
[vg.git] / src / vg / vg.h
index 299c9b0112d1e5a83510e7d32d4c3b3fe6df3868..08c18b34c7c59eb455fbbd88b747e41ee54c2279 100644 (file)
@@ -1,9 +1,27 @@
 /* Copyright (C) 2021-2022 Harry Godden (hgn) - All Rights Reserved */
 
+/*
+ * Memory model:
+ *    [global (.data)] [temp-stack] [system-stack] [game-heap]
+ *
+ *    1. Program starts: .data memory is loaded
+ *    2. System initialization: 
+ *       2a. the large heap buffer is allocated
+ *       2b. each engine system is initialized in order, using some of the 
+ *           system stack
+ *       2c. game systems are also put into here
+ */
+
+
 #ifndef VG_HEADER_H
 #define VG_HEADER_H
 
 #include "vg_platform.h"
+#include "vg_mem.h"
+
+#ifndef _WIN32
+#include <execinfo.h>
+#endif
 
 
 #if defined(VG_SERVER) || defined(VG_TOOLS)
@@ -35,10 +53,6 @@ void vg_register_exit( void( *funcptr )(void), const char *name );
 #include "vg_steam.h"
 #endif
 
-#ifndef VG_NON_CLIENT
-#include "vg_gldiag.h"
-#endif
-
 #ifndef VG_NON_CLIENT
 
 struct vg
@@ -103,7 +117,7 @@ struct vg
    const char       *gamepad_name;
    int                               gamepad_id;
 }
-static vg = { .time_rate = 1.0 };
+VG_STATIC vg = { .time_rate = 1.0 };
 
 struct vg_thread_info
 {
@@ -129,9 +143,9 @@ static VG_THREAD_LOCAL struct vg_thread_info vg_thread_info;
   #define VG_SYNC_LOG(...)
 #endif
 
-static void vg_fatal_exit_loop( const char *error );
+VG_STATIC void vg_fatal_exit_loop( const char *error );
 
-static void vg_ensure_engine_running(void)
+VG_STATIC void vg_ensure_engine_running(void)
 {
    /* Check if the engine is no longer running */
    vg_mutex_lock( &vg.mux_engine_status );
@@ -156,7 +170,7 @@ static void vg_ensure_engine_running(void)
  * Sync execution so that the OpenGL context is switched onto this thread.
  * Anything after this call will be in a valid context.
  */
-static void vg_acquire_thread_sync(void)
+VG_STATIC void vg_acquire_thread_sync(void)
 {
    /* We dont want to do anything if this is the main thread */
    if( vg_thread_info.purpose == k_thread_purpose_main )
@@ -193,7 +207,7 @@ static void vg_acquire_thread_sync(void)
  * Signify that we are done with the OpenGL context in this thread.
  * Anything after this call will be in an undefined context.
  */
-static void vg_release_thread_sync(void)
+VG_STATIC void vg_release_thread_sync(void)
 {
    if( vg_thread_info.purpose == k_thread_purpose_main )
       return;
@@ -211,7 +225,7 @@ static void vg_release_thread_sync(void)
    }
 }
 
-static void vg_run_synced_content(void)
+VG_STATIC void vg_run_synced_content(void)
 {
    assert( vg_thread_info.purpose == k_thread_purpose_main );
 
@@ -243,7 +257,7 @@ static void vg_run_synced_content(void)
    vg_mutex_unlock( &vg.mux_context );
 }
 
-static void vg_opengl_sync_init(void)
+VG_STATIC void vg_opengl_sync_init(void)
 {
    vg_semaphore_init( &vg.sem_allow_exec, 0 );
    vg_semaphore_init( &vg.sem_exec_finished, 0 );
@@ -256,7 +270,7 @@ static void vg_opengl_sync_init(void)
    vg_thread_info.gl_context_level = 1;
 }
 
-static void vg_checkgl( const char *src_info );
+VG_STATIC void vg_checkgl( const char *src_info );
 #define VG_STRINGIT( X ) #X
 #define VG_CHECK_GL_ERR() vg_checkgl( __FILE__ ":L" VG_STRINGIT(__LINE__) )
 
@@ -268,27 +282,26 @@ static void vg_checkgl( const char *src_info );
 #include "vg_input.h"
 #include "vg_ui.h"
 #include "vg_lines.h"
-#include "vg_debug.h"
 #include "vg_loader.h"
 #include "vg_opt.h"
 
 /* Diagnostic */
-static struct vg_profile vg_prof_update = {.name="update()"},
-                         vg_prof_render = {.name="render()"};
+VG_STATIC struct vg_profile vg_prof_update = {.name="update()"},
+                            vg_prof_render = {.name="render()"};
 
 #define VG_GAMELOOP
-static void vg_register(void) VG_GAMELOOP;
-static void vg_start(void) VG_GAMELOOP;
+VG_STATIC void vg_register(void) VG_GAMELOOP;
+VG_STATIC void vg_start(void) VG_GAMELOOP;
 
-static void vg_update(int loaded) VG_GAMELOOP;
-static void vg_update_fixed(int loaded) VG_GAMELOOP;
-static void vg_update_post(int loaded) VG_GAMELOOP;
+VG_STATIC void vg_update(int loaded) VG_GAMELOOP;
+VG_STATIC void vg_update_fixed(int loaded) VG_GAMELOOP;
+VG_STATIC void vg_update_post(int loaded) VG_GAMELOOP;
 
-static void vg_framebuffer_resize(int w, int h) VG_GAMELOOP;
-static void vg_render(void) VG_GAMELOOP;
-static void vg_ui(void) VG_GAMELOOP;
+VG_STATIC void vg_framebuffer_resize(int w, int h) VG_GAMELOOP;
+VG_STATIC void vg_render(void) VG_GAMELOOP;
+VG_STATIC void vg_ui(void) VG_GAMELOOP;
 
-static void vg_checkgl( const char *src_info )
+VG_STATIC void vg_checkgl( const char *src_info )
 {
    int fail = 0;
 
@@ -329,39 +342,31 @@ void vg_framebuffer_resize_callback( GLFWwindow *ptrW, int w, int h )
    vg_framebuffer_resize(w,h);
 }
 
-static int vg_bake_shaders(void)
+VG_STATIC void vg_bake_shaders(void)
 {
    vg_acquire_thread_sync();
 
+#if 0
    vg_function_push( (struct vg_cmd)
    {
       .name = "shaders",
       .function = vg_shaders_live_recompile
    });
+#endif
 
-   if( !vg_shaders_recompile() )
-   {
-      vg_shaders_free(NULL);
-      vg_release_thread_sync();
-      return 0;
-   }
-   else
-   {
-      vg_release_thread_sync();
-      vg_loader_highwater( NULL, vg_shaders_free, NULL );
-      return 1;
-   }
+   vg_shaders_compile();
+   vg_release_thread_sync();
 }
 
-void vg_preload(void);
-void vg_load(void);
-static void vg_load_full(void)
+VG_STATIC void vg_preload(void);
+VG_STATIC void vg_load(void);
+VG_STATIC void vg_load_full(void)
 {
    vg_preload();
 
    /* internal */
    vg_loader_highwater( vg_gamepad_init, NULL, NULL );
-   vg_loader_highwater( vg_lines_init, vg_lines_free, NULL );
+   vg_loader_highwater( vg_lines_init, NULL, NULL );
    vg_loader_highwater( vg_audio_init, vg_audio_free, NULL );
    vg_loader_highwater( vg_profiler_init, NULL, NULL );
 
@@ -373,7 +378,7 @@ static void vg_load_full(void)
    vg_release_thread_sync();
 }
 
-static void vg_enter( int argc, char *argv[], const char *window_name )
+VG_STATIC void vg_enter( int argc, char *argv[], const char *window_name )
 {
    char *arg;
    while( vg_argp( argc, argv ) )
@@ -401,7 +406,7 @@ static void vg_enter( int argc, char *argv[], const char *window_name )
    glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 );
    glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 3 );
    glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
-   glfwWindowHint( GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE );
+   //glfwWindowHint( GLFW_OPENGL_DEBUG_CONTEXT, GL_FALSE );
    glfwWindowHint( GLFW_CONTEXT_RELEASE_BEHAVIOR, GLFW_RELEASE_BEHAVIOR_FLUSH );
    
    glfwWindowHint( GLFW_RESIZABLE, GLFW_FALSE );
@@ -468,9 +473,7 @@ static void vg_enter( int argc, char *argv[], const char *window_name )
    
    glfwSetCharCallback( vg.window, console_proc_wchar );
    glfwSetKeyCallback( vg.window, console_proc_key );
-#if 0
-   glfwSetInputMode(vg_window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
-#endif
+   glfwSetInputMode( vg.window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN );
 
    if( !gladLoadGLLoader((GLADloadproc)glfwGetProcAddress) ) 
    {
@@ -481,13 +484,11 @@ static void vg_enter( int argc, char *argv[], const char *window_name )
 
    const unsigned char* glver = glGetString( GL_VERSION );
    vg_success( "Load setup complete, OpenGL version: %s\n", glver );
-   vg_run_gfx_diagnostics();
-
-   if( !ui_default_init() )
-      goto il_exit_ui;
 
-   if( !vg_loader_init() )
-      goto il_exit_loader;
+   /* init systems 
+    * -----------------------------------------------------------------------*/
+   ui_init_context();
+   vg_loader_init();
 
    vg_mutex_init( &vg.mux_engine_status );
    vg.engine_status = k_engine_status_running;
@@ -516,11 +517,6 @@ static void vg_enter( int argc, char *argv[], const char *window_name )
       
       if( vg.is_loaded )
       {
-#if 0
-         glClearColor( 0.0f,sinf(vg.time*20.0)*0.5f+0.5f,0.0f,1.0f );
-         glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
-#endif
-         
          if( !loaded )
          {
             vg_start();
@@ -580,9 +576,9 @@ static void vg_enter( int argc, char *argv[], const char *window_name )
          /* ui */
          vg.engine_stage = k_engine_stage_ui;
          {
-            ui_begin( &ui_global_ctx, vg.window_x, vg.window_y );
-            ui_set_mouse( &ui_global_ctx, vg.mouse[0], vg.mouse[1], 
-                  vg_get_button_state( "primary" ) );
+            ui_begin( vg.window_x, vg.window_y );
+            ui_set_mouse( vg.mouse[0], vg.mouse[1], 
+                           vg_get_button_state( "primary" ) );
             
             vg_profile_drawn( 
                   (struct vg_profile *[]){&vg_prof_update,&vg_prof_render}, 2,
@@ -606,15 +602,15 @@ static void vg_enter( int argc, char *argv[], const char *window_name )
                      vg.fixed_iterations, 
                      (vg.accumulator/VG_TIMESTEP_FIXED)*100.0f );
 
-               ui_text( &ui_global_ctx, (ui_rect){258, 4+24+12,0,0},perf, 1,0);
+               ui_text( (ui_rect){258, 4+24+12,0,0},perf, 1,0);
             }
 
             audio_debug_ui( vg.pv );
             vg_ui();
             vg_console_draw();
             
-            ui_resolve( &ui_global_ctx );
-            ui_draw( &ui_global_ctx, NULL );
+            ui_resolve();
+            ui_draw( NULL );
          }
       }
 
@@ -632,10 +628,7 @@ static void vg_enter( int argc, char *argv[], const char *window_name )
 
    vg_loader_free();
 
-il_exit_loader:
-   ui_default_free();
-
-il_exit_ui:
+   vg_success( "If you see this it means everything went.. \"well\".....\n" );
    glfwTerminate();
 }
 
@@ -643,13 +636,41 @@ il_exit_ui:
  * Immediately transfer away from calling thread into a safe loop, signal for 
  * others to shutdown, then free everything once the user closes the window.
  *
- * FIXME(bug): glfwWindowShouldClose() never returns 1 in windows via wine, only
+ * FIXME(bug): glfwWindowShouldClose() never returns 1 in windows via wine, ONLY
  *             when calling the program from outside its normal directory.
- *
- *             A workaround is placed to skip the error loop on windows builds
  */
-static void vg_fatal_exit_loop( const char *error )
+VG_STATIC void vg_fatal_exit_loop( const char *error )
 {
+   /* 
+    *    https://www.gnu.org/software/libc/manual/html_node/Backtraces.html
+    *    thanks gnu <3
+    *
+    *    TODO: this on windows?
+    */
+
+#ifndef _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 error: %s\n", error );
    assert( vg_semaphore_trywait( &vg.sem_fatal ) );
 
@@ -700,7 +721,6 @@ static void vg_fatal_exit_loop( const char *error )
       }
       vg_audio_free(NULL);
 
-#ifndef _WIN32
       while(1)
       {
          if( glfwWindowShouldClose( vg.window ) )
@@ -725,12 +745,9 @@ static void vg_fatal_exit_loop( const char *error )
 
          glfwSwapBuffers( vg.window );
       }
-#endif
 
       /* Can now shutdown and EXIT */
       vg_loader_free();
-      ui_default_free();
-
       glfwTerminate();
       exit(0);
    }
@@ -738,7 +755,7 @@ static void vg_fatal_exit_loop( const char *error )
 
 #else
 
-static void vg_fatal_exit_loop( const char *error )
+VG_STATIC void vg_fatal_exit_loop( const char *error )
 {
    vg_error( "Fatal error: %s\n", error );
    exit(0);