+ 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_audio_init, vg_audio_free, NULL );
+
+ /* client */
+ vg_load();
+
+ vg_acquire_thread_sync();
+ vg.is_loaded = 1;
+ vg_release_thread_sync();
+}
+
+static void vg_enter( int argc, char *argv[], const char *window_name )
+{
+ char *arg;
+ while( vg_argp( argc, argv ) )
+ {
+ if( (arg = vg_opt_arg( 'w' )) )
+ {
+ vg_window_x = atoi( arg );
+ }
+
+ if( (arg = vg_opt_arg( 'h' )) )
+ {
+ vg_window_y = atoi( arg );
+ }
+
+ if( (arg = vg_long_opt_arg( "samples" )) )
+ {
+ vg_samples = VG_MAX( 0, VG_MIN( 8, atoi( arg ) ) );
+ }
+ }
+
+ vg_log_init();
+ vg_console_init();
+
+ glfwInit();
+ 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_CONTEXT_RELEASE_BEHAVIOR, GLFW_RELEASE_BEHAVIOR_FLUSH );
+
+ glfwWindowHint( GLFW_RESIZABLE, GLFW_FALSE );
+ glfwWindowHint( GLFW_DOUBLEBUFFER, GLFW_TRUE );
+
+ glfwWindowHint( GLFW_SAMPLES, vg_samples );
+
+ GLFWmonitor *monitor_primary = glfwGetPrimaryMonitor();
+
+ const GLFWvidmode *mode = glfwGetVideoMode( monitor_primary );
+ glfwWindowHint( GLFW_RED_BITS, mode->redBits );
+ glfwWindowHint( GLFW_GREEN_BITS, mode->greenBits );
+ glfwWindowHint( GLFW_BLUE_BITS, mode->blueBits );
+
+ /* TODO? */
+ glfwWindowHint( GLFW_REFRESH_RATE, 60 );
+
+ if( !vg_window_x )
+ vg_window_x = mode->width;
+
+ if( !vg_window_y )
+ vg_window_y = mode->height;
+
+
+ if( (vg.window = glfwCreateWindow( vg_window_x, vg_window_y,
+ window_name, monitor_primary, NULL)) )
+ {
+ glfwGetFramebufferSize( vg.window, &vg_window_x, &vg_window_y );
+ vg_success( "Window created (%dx%d)\n", vg_window_x, vg_window_y );
+ }
+ else
+ {
+ vg_error( "GLFW Failed to initialize\n" );
+ return;
+ }
+
+ /* We need 3.1.2 for correct VSync on windows */
+ {
+ int vmaj, vmin, vrev;
+ glfwGetVersion( &vmaj, &vmin, &vrev );
+
+ if( vmaj < 3 ||
+ (vmaj == 3 && vmin < 1) ||
+ (vmaj == 3 && vmin == 1 && vrev < 2 ) )
+ {
+ vg_error( "GLFW out of date (%d.%d.%d); (3.1.2 is required)\n",
+ vmaj, vmin, vrev );
+
+ glfwTerminate();
+ return;
+ }
+
+ vg_success( "GLFW Version %d.%d.%d\n", vmaj, vmin, vrev );
+ }
+
+ glfwMakeContextCurrent( vg.window );
+ glfwSwapInterval( 1 );
+
+ glfwSetWindowSizeLimits( vg.window, 800, 600, GLFW_DONT_CARE,GLFW_DONT_CARE);
+ glfwSetFramebufferSizeCallback( vg.window, vg_framebuffer_resize_callback );
+
+ glfwSetCursorPosCallback( vg.window, vg_mouse_callback );
+ glfwSetScrollCallback( vg.window, vg_scroll_callback );
+
+ glfwSetCharCallback( vg.window, console_proc_wchar );
+ glfwSetKeyCallback( vg.window, console_proc_key );
+#if 0
+ glfwSetInputMode(vg_window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);