+++ /dev/null
-clang -fsanitize=address -O0 -I. -DVG_BUILD src/texsheet.c -o /tmp/tmpsr && /tmp/tmpsr $@
+++ /dev/null
-./vg/bin/fontcomp vg/src/fonts/vg_font_thin.png vg/vg_pxfont_thin.h
+++ /dev/null
-#include "vg/vg_build.h"
-#include "vg/vg_build_utils_shader.h"
-
-void s_lab_physics(void){
- vg_info( "running script: s_lab_physics(void)\n" );
-
- struct vg_project project;
- struct vg_env env = vg_test_env;
-
- vg_project_init( &project, &vg_test_env, "labs" );
- vg_project_new_target( &project, "physics", k_obj_type_exe );
- vg_add_engine( &project, NULL );
- vg_add_source( &project, "physics.c" );
- vg_compile_project( &project );
- vg_success( "Completed 1/1\n" );
-}
-
-int main( int argc, char *argv[] ){
- char *arg;
- while( vg_argp( argc, argv ) ){
- if( vg_long_opt( "physics" ) )
- s_lab_physics();
-
- if( vg_opt('r') )
- vg_test_env.optimization = 3;
- }
-
- vg_success( "All scripts ran successfully\n" );
-}
+++ /dev/null
-clang -fsanitize=address -O0 -I./vg build.c vg/vg_tool.c -o /tmp/tmpsr && /tmp/tmpsr $@
+++ /dev/null
-#include "vg/vg_engine.h"
-#include "vg/vg_opt.h"
-#include "vg/vg_audio.h"
-#include "vg/vg_camera.h"
-#include "vg/vg_rigidbody.h"
-#include "vg/vg_rigidbody_collision.h"
-#include "vg/vg_rigidbody_view.h"
-#include "vg/vg_profiler.h"
-#include "vg/vg_bvh.h"
-#include "vg/vg_input.h"
-
-#define SHAPE_MAX 256
-static rigidbody shapes[SHAPE_MAX];
-static rb_capsule shapes_inf[SHAPE_MAX];
-static v4f shapes_colour[SHAPE_MAX];
-static boxf shapes_bbx[SHAPE_MAX];
-
-static boxf floor_box = {{-6.999,-2.001,-6.999},{6.999,-0.999,6.999}};
-
-static rigidbody racket;
-
-static f32 k_iterations = 8.0f,
- k_view_x = 0.0f,
- k_view_y = 0.2f,
- k_view_z = 10.0f,
- k_shapes = 32.0f,
- k_racket_d = 8.0f;
-
-static rb_capsule racket_ca = { .h = 4.3f, .r = 0.6f },
- racket_cb = { .h = 5.5f, .r = 0.9f };
-static m4x3f racket_a_mdl, racket_b_mdl;
-static m3x3f racket_I;
-
-static v3f k_racket_init_w;
-static i32 k_demo = 0;
-static i32 k_gyro = 0;
-static i32 k_prof_normalize = 0;
-static i32 k_bbx = 1;
-static i32 k_spacial = 0;
-
-static struct vg_profile prof_refit = { .name = "Refit" },
- prof_broad = { .name = "Broad phase",
- .mode = k_profile_mode_accum },
- prof_narrow = { .name = "Narrow phase",
- .mode = k_profile_mode_accum },
- prof_solve = { .name = "Solver" };
-
-static void shape_bvh_expand_bound( void *user, boxf bound, u32 item_index ){
- box_concat( bound, shapes_bbx[item_index] );
-}
-
-static f32 shape_bvh_centroid( void *user, u32 item_index, int axis ){
- f32 x = shapes_bbx[item_index][0][axis] + shapes_bbx[item_index][1][axis];
- return x*0.5f;
-}
-
-static void shape_bvh_closest( void *user, u32 item_index,
- v3f point, v3f closest ){
- closest_point_aabb( point, shapes_bbx[item_index], closest );
-}
-
-static void shape_bvh_swap( void *user, u32 ia, u32 ib ){
- rigidbody temp = shapes[ib];
- shapes[ib] = shapes[ia];
- shapes[ia] = temp;
-
- rb_capsule cb = shapes_inf[ib];
- shapes_inf[ib] = shapes_inf[ia];
- shapes_inf[ia] = cb;
-
- v4f colourb;
- v4_copy( shapes_colour[ib], colourb );
- v4_copy( shapes_colour[ia], shapes_colour[ib] );
- v4_copy( colourb, shapes_colour[ia] );
-
- boxf boxb;
- box_copy( shapes_bbx[ib], boxb );
- box_copy( shapes_bbx[ia], shapes_bbx[ib] );
- box_copy( boxb, shapes_bbx[ia] );
-}
-
-static bh_system shape_bvh = {
- .expand_bound = shape_bvh_expand_bound,
- .item_centroid = shape_bvh_centroid,
- .item_closest = shape_bvh_closest,
- .item_swap = shape_bvh_swap
-};
-
-static bh_tree *shape_bvh_tree = NULL;
-
-int main( int argc, char *argv[] ){
- vg_mem.use_libc_malloc = 0;
- vg_set_mem_quota( 80*1024*1024 );
- vg_enter( argc, argv, "Voyager Game Engine" );
- return 0;
-}
-
-void vg_launch_opt(void){
- const char *arg;
-}
-
-void vg_preload(void)
-{
- vg_audio.dsp_enabled = 0;
-}
-
-static void init_random(void)
-{
- for( u32 i=0; i<(u32)k_shapes; i ++ ){
- f32 h = vg_randf64( &vg.rand ) * 2.0f + 1.3f,
- r = vg_randf64( &vg.rand ) * 0.5f + 0.125f,
- pv = vg_capsule_volume( r, h ),
- k_density = 8.0f,
- pm = pv * k_density;
-
- shapes_inf[i].r = r;
- shapes_inf[i].h = h;
-
- m3x3f pI;
- vg_capsule_inertia( r, h, pm, pI );
- m3x3_inv( pI, shapes[i].iI );
- shapes[i].inv_mass = 1.0f / pm;
-
- v3f dir;
- vg_rand_dir( &vg.rand, dir );
- q_axis_angle( shapes[i].q, dir, vg_randf64(&vg.rand)*VG_TAUf );
- vg_rand_sphere( &vg.rand, shapes[i].co );
- v3_muladds( (v3f){0,4,0}, shapes[i].co, 4.0f, shapes[i].co );
- v3_zero( shapes[i].v );
- v3_zero( shapes[i].w );
- shapes_colour[i][0] = vg_randf64(&vg.rand);
- shapes_colour[i][1] = vg_randf64(&vg.rand);
- shapes_colour[i][2] = vg_randf64(&vg.rand);
- shapes_colour[i][3] = 1.0f;
- rb_update_matrices( &shapes[i] );
- }
-}
-
-static void init_racket(void){
- f32 ma = vg_capsule_volume( racket_ca.r, racket_ca.h ) * k_racket_d,
- mb = vg_capsule_volume( racket_cb.r, racket_cb.h ) * k_racket_d,
- mt = ma+mb;
- m3x3f aI, bI;
-
- /* tensor for A */
- vg_capsule_inertia( racket_ca.r, racket_ca.h, ma, aI );
- m4x3_identity( racket_a_mdl );
- racket_a_mdl[3][1] = -racket_ca.h*0.5f*(mb/mt);
- vg_translate_inertia( aI, ma, racket_a_mdl[3] );
-
- /* tensor for B */
- vg_capsule_inertia( racket_cb.r, racket_cb.h, mb, bI );
-
- v4f q;
- q_axis_angle( q, (v4f){1,0,0}, VG_TAUf*0.25f );
-
- m4x3_identity( racket_b_mdl );
- q_m3x3( q, racket_b_mdl );
- vg_rotate_inertia( bI, racket_b_mdl );
- racket_b_mdl[3][1] = racket_ca.h*0.5f*(ma/mt);
- vg_translate_inertia( bI, mb, racket_b_mdl[3] );
-
- m3x3_add( aI, bI, racket_I );
- m3x3_inv( racket_I, racket.iI );
- racket.inv_mass = 1.0f/(mb+ma);
-}
-
-static void reset_racket(void){
- q_identity( racket.q );
- v3_zero( racket.co );
- v3_copy( k_racket_init_w, racket.w );
- v3_zero( racket.v );
- rb_update_matrices( &racket );
-}
-
-void vg_load(void)
-{
- vg_bake_shaders();
- init_random();
- shape_bvh_tree = bh_create( NULL, &shape_bvh, NULL, SHAPE_MAX, 1 );
- init_racket();
- reset_racket();
-}
-
-void vg_pre_update(void)
-{
- vg_console.cheats = 1;
- vg_lines.render = 1;
-}
-
-static void demo0_refit(void){
- if( k_spacial == 0 ) return;
-
- for( u32 i=0; i<(u32)k_shapes; i ++ ){
- f32 h = shapes_inf[i].h,
- r = shapes_inf[i].r;
-
- rigidbody *rb = &shapes[i];
-
- v3f p0, p1;
- v3_muladds( rb->to_world[3], rb->to_world[1], -h*0.5f+r, p0 );
- v3_muladds( rb->to_world[3], rb->to_world[1], h*0.5f-r, p1 );
-
- v3f *bbx = shapes_bbx[i];
- v3_minv( p0, p1, bbx[0] );
- v3_maxv( p0, p1, bbx[1] );
- v3_muladds( bbx[0], (v3f){-1,-1,-1}, r, bbx[0] );
- v3_muladds( bbx[1], (v3f){ 1, 1, 1}, r, bbx[1] );
- }
-
- if( k_spacial == 1 ) return;
-
- if( k_spacial == 2 )
- bh_rebuild( shape_bvh_tree, (u32)k_shapes );
-}
-
-static void demo0(void){
- vg_profile_begin( &prof_refit );
- demo0_refit();
- vg_profile_end( &prof_refit );
-
- static rigidbody _null,
- _mover;
- rb_solver_reset();
-
- f32 t = vg.time * 0.1f * VG_TAUf;
- v3f sphere_pos = { sinf(t)*2.0f, -1, cosf(t)*2.0f };
- _mover.v[0] = (sinf(t+vg.time_fixed_delta)-sinf(t))*2.0f;
- _mover.v[2] = (cosf(t+vg.time_fixed_delta)-cosf(t))*2.0f;
-
- for( u32 i=0; i<(u32)k_shapes; i ++ ){
- rigidbody *rbi = &shapes[i];
- rb_capsule *infi = &shapes_inf[i];
- v3f *bbxi = shapes_bbx[i];
-
- if( rb_global_has_space() ){
- rb_ct *buf = rb_global_buffer();
- m4x3f mtx;
- m4x3_identity( mtx );
- u32 l = rb_capsule__box( rbi->to_world, infi,
- mtx, mtx, floor_box, buf );
-
- for( u32 k=0; k<l; k ++ ){
- buf[k].rba = rbi;
- buf[k].rbb = &_null;
- }
-
- rb_contact_count += l;
- }
- else break;
-
- if( rb_global_has_space() ){
- rb_ct *buf = rb_global_buffer();
- u32 l = rb_capsule__sphere( rbi->to_world, infi, sphere_pos, 1, buf );
-
- for( u32 k=0; k<l; k ++ ){
- buf[k].rba = rbi;
- buf[k].rbb = &_mover;
- }
-
- rb_contact_count += l;
- }
-
- if( k_spacial == 2 ){
- bh_iter it;
- bh_iter_init_box( 0, &it, bbxi );
- i32 idx;
-
- while(1){
- vg_profile_begin( &prof_broad );
- if( !bh_next( shape_bvh_tree, &it, &idx ) ){
- vg_profile_end( &prof_broad );
- break;
- }
- vg_profile_end( &prof_broad );
-
- if( idx <= i ) continue;
-
- vg_profile_begin( &prof_narrow );
-
- rigidbody *rbj = &shapes[idx];
- v3f *bbxj = shapes_bbx[idx];
- rb_capsule *infj = &shapes_inf[idx];
-
- if( rb_global_has_space() ){
- rb_ct *buf = rb_global_buffer();
- u32 l = rb_capsule__capsule( rbi->to_world, infi,
- rbj->to_world, infj, buf );
-
- for( u32 k=0; k<l; k ++ ){
- buf[k].rba = rbi;
- buf[k].rbb = rbj;
- }
-
- rb_contact_count += l;
- }
-
- vg_profile_end( &prof_narrow );
- }
- }
- else {
- if( i == ((u32)k_shapes)-1 ){
- break;
- }
- for( u32 j=i+1; j<(u32)k_shapes; j ++ ){
- rigidbody *rbj = &shapes[j];
- v3f *bbxj = shapes_bbx[j];
- rb_capsule *infj = &shapes_inf[j];
-
- if( k_spacial == 1 ){
- vg_profile_begin( &prof_broad );
- if( !box_overlap( bbxi, bbxj ) ){
- vg_profile_end( &prof_broad );
- continue;
- }
- }
-
- vg_profile_begin( &prof_narrow );
- if( rb_global_has_space() ){
- rb_ct *buf = rb_global_buffer();
- u32 l = rb_capsule__capsule( rbi->to_world, infi,
- rbj->to_world, infj, buf );
-
- for( u32 k=0; k<l; k ++ ){
- buf[k].rba = rbi;
- buf[k].rbb = rbj;
- }
-
- rb_contact_count += l;
- }
- vg_profile_end( &prof_narrow );
- }
- }
- }
-
- vg_profile_increment( &prof_broad );
- vg_profile_increment( &prof_narrow );
-
- vg_profile_begin( &prof_solve );
- rb_presolve_contacts( rb_contact_buffer,
- vg.time_fixed_delta, rb_contact_count );
- for( u32 i=0; i<(u32)k_iterations; i ++ )
- rb_solve_contacts( rb_contact_buffer, rb_contact_count );
-
- for( u32 i=0; i<(u32)k_shapes; i ++ ){
- rigidbody *rbi = &shapes[i];
- if( k_gyro ){
- m3x3f I;
- m3x3_inv( rbi->iI, I );
- rb_solve_gyroscopic( rbi, I, vg.time_fixed_delta );
- }
- rb_iter( rbi );
- rb_update_matrices( rbi );
- }
- vg_profile_end( &prof_solve );
-}
-
-static void demo1(void){
- vg_profile_begin( &prof_refit );
- vg_profile_end( &prof_refit );
-
- vg_profile_increment( &prof_broad );
- vg_profile_increment( &prof_narrow );
-
- vg_profile_begin( &prof_solve );
-
- v3_muladds( racket.v, (v3f){0,9.8f,0}, vg.time_fixed_delta, racket.v );
- if( k_gyro ) rb_solve_gyroscopic( &racket, racket_I, vg.time_fixed_delta );
- rb_iter( &racket );
- rb_update_matrices( &racket );
-
- vg_profile_end( &prof_solve );
-}
-
-void vg_fixed_update(void)
-{
- if( k_demo == 0 ) demo0();
- else if( k_demo == 1 ) demo1();
-}
-
-void vg_post_update(void)
-{
- if( vg_getkey( SDLK_8 ) )
- init_random();
-}
-
-void vg_framebuffer_resize( int w, int h )
-{
-}
-
-static void draw_origin_axis(void){
- vg_line( (v3f){ 0.0f, 0.0f, 0.0f }, (v3f){ 1.0f, 0.0f, 0.0f }, 0xffff0000 );
- vg_line( (v3f){ 0.0f, 0.0f, 0.0f }, (v3f){ 0.0f, 1.0f, 0.0f }, 0xff00ff00 );
- vg_line( (v3f){ 0.0f, 0.0f, 0.0f }, (v3f){ 0.0f, 0.0f, 1.0f }, 0xff0000ff );
-}
-
-static void render0(void){
- f32 t = vg.time * 0.1f * VG_TAUf;
- m4x3f mdl;
- m4x3_identity( mdl );
- vg_rb_view_box( mdl, floor_box, (v4f){0.8f,0.8f,0.8f,1} );
-
- mdl[3][0] = sinf(t)*2.0f;
- mdl[3][1] = -1;
- mdl[3][2] = cosf(t)*2.0f;
- vg_rb_view_sphere( mdl, 1, (v4f){0,1,0,1} );
-
- for( u32 i=0; i<(u32)k_shapes; i ++ ){
- rigidbody *rbi = &shapes[i];
- rb_capsule *infi = &shapes_inf[i];
- f32 *coli = shapes_colour[i];
-
- v4f q;
- v3f co;
- rb_extrapolate( rbi, co, q );
- q_m3x3( q, mdl );
- v3_copy( co, mdl[3] );
- vg_rb_view_capsule( mdl, infi->r, infi->h, coli );
- }
-
- if( k_spacial && k_bbx ){
- for( u32 i=0; i<(u32)k_shapes; i ++ ){
- vg_line_boxf( shapes_bbx[i], VG__RED );
- }
-
- if( k_spacial == 2 ){
- bh_debug_trace( shape_bvh_tree, 0, (v3f){0,0,0}, VG__GREEN );
- }
- }
-}
-
-static void render1(void){
- m4x3f mdl, mmdl;
- v4f q;
- rb_extrapolate( &racket, mdl[3], q );
- q_m3x3( q, mdl );
-
- m4x3_mul( mdl, racket_a_mdl, mmdl );
- vg_rb_view_capsule( mmdl, racket_ca.r, racket_ca.h, (v4f){1,0,0,1} );
-
- m4x3_mul( mdl, racket_b_mdl, mmdl );
- vg_rb_view_capsule( mmdl, racket_cb.r, racket_cb.h, (v4f){0,1,0,1} );
-}
-
-void vg_render(void)
-{
- glBindFramebuffer( GL_FRAMEBUFFER, 0 );
- glViewport( 0,0, vg.window_x, vg.window_y );
- glEnable( GL_DEPTH_TEST );
- glDisable( GL_BLEND );
-
- glClearColor( 0.05f, 0.05f, 0.05f, 1.0f );
- glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
-
- vg_camera cam = {
- .angles = { -k_view_x, k_view_y, 0 },
- .nearz = 0.01f,
- .farz = 500.0f,
- .fov = 90.0f,
- .pos = { sinf(k_view_x)*k_view_z*cosf(k_view_y),
- sinf(k_view_y)*k_view_z,
- cosf(k_view_x)*k_view_z*cosf(k_view_y) },
- };
-
- vg_camera_update_transform( &cam );
- vg_camera_update_view( &cam );
- vg_camera_update_projection( &cam );
- vg_camera_finalize( &cam );
- m4x4_copy( cam.mtx.pv, vg.pv );
-
- vg_rb_view_bind();
- if( k_demo == 0 ) render0();
- else if( k_demo == 1 ) render1();
-
- draw_origin_axis();
- vg_lines_drawall();
-
- glDisable(GL_DEPTH_TEST);
-}
-
-struct ui_enum_opt spacial_mode_ui_enum[] = {
- { 0, "None" },
- { 1, "BBX" },
- { 2, "BVH - Full rebuild" },
- { 3, "BVH - Temporal fitting" }
-};
-
-static void gui0( ui_rect panel ){
- ui_slider( panel, "Shapes", 2, vg_list_size(shapes), &k_shapes, "%.0f" );
-
- if( ui_button( panel, "randomize" ) == k_ui_button_click ){
- init_random();
- }
-}
-
-static void gui1( ui_rect panel ){
- ui_rect l, r;
- ui_standard_widget( panel, l, 1 );
- ui_split_ratio( l, k_ui_axis_v, 0.5f, 4, l, r );
- ui_slider( l, "aH", 1.0f, 10.0f, &racket_ca.h, "%.1f" );
- ui_slider( r, "aR", 0.1f, 10.0f, &racket_ca.r, "%.1f" );
-
- ui_standard_widget( panel, l, 1 );
- ui_split_ratio( l, k_ui_axis_v, 0.5f, 4, l, r );
- ui_slider( l, "bH", 1.0f, 10.0f, &racket_cb.h, "%.1f" );
- ui_slider( r, "bR", 0.1f, 10.0f, &racket_cb.r, "%.1f" );
-
- for( u32 i=0; i<3; i ++ ){
- ui_rect v0,v1,v2;
- ui_standard_widget( panel, v0, 1 );
- ui_split_ratio( v0, k_ui_axis_v, 2.0f/3.0f, 4, v0, v2 );
- ui_split_ratio( v0, k_ui_axis_v, 1.0f/2.0f, 4, v0, v1 );
-
- char buf[16];
- snprintf( buf, sizeof(buf), "%.3f", racket_I[i][0] );
- ui_text( v0, buf, 1, k_ui_align_middle_center, 0 );
- snprintf( buf, sizeof(buf), "%.3f", racket_I[i][1] );
- ui_text( v1, buf, 1, k_ui_align_middle_center, 0 );
- snprintf( buf, sizeof(buf), "%.3f", racket_I[i][2] );
- ui_text( v2, buf, 1, k_ui_align_middle_center, 0 );
- }
-
- init_racket();
-
- ui_info( panel, "init conditions" );
- ui_rect v0,v1,v2;
- ui_standard_widget( panel, v0, 1 );
- ui_split_ratio( v0, k_ui_axis_v, 2.0f/3.0f, 4, v0, v2 );
- ui_split_ratio( v0, k_ui_axis_v, 1.0f/2.0f, 4, v0, v1 );
- ui_slider( v0, "X", 0.01f, 30.0f, k_racket_init_w+0, "%.1f" );
- ui_slider( v1, "Y", 0.01f, 30.0f, k_racket_init_w+1, "%.1f" );
- ui_slider( v2, "Z", 0.01f, 30.0f, k_racket_init_w+2, "%.1f" );
-
- if( ui_button( panel, "init" ) == k_ui_button_click ){
- reset_racket();
- }
-}
-
-void vg_gui(void)
-{
- vg_ui.wants_mouse = 1;
- ui_rect panel = { vg.window_x-300, 0, 300, vg.window_y };
- ui_rect_pad( panel, (ui_px[2]){ 8, 8 } );
-
- ui_rect box;
- ui_split( panel, k_ui_axis_h, VG_PROFILE_SAMPLE_COUNT*2 +4, 8, box, panel );
- vg_profile_drawn( (struct vg_profile *[]){ &prof_refit,
- &prof_broad,
- &prof_narrow,
- &prof_solve }, 4,
- vg.time_fixed_delta*1000.0, box, 0, k_prof_normalize );
-
- ui_split( panel, k_ui_axis_h, 14*2+8, 4, box, panel );
- ui_checkbox( panel, "Normalize", &k_prof_normalize );
-
- ui_slider( panel, "Iterations", 1.0f, 20.0f, &k_iterations, "%.0f" );
- ui_enum( panel, "Spacial Type", spacial_mode_ui_enum,
- vg_list_size(spacial_mode_ui_enum), &k_spacial );
-
- static f32 rate = 60.0f;
- ui_slider( panel, "Fixed timestep", 10, 200, &rate, "%.1f" );
- vg.time_fixed_delta = 1.0f/rate;
-
- ui_checkbox( panel, "Show BBX", &k_bbx );
- ui_checkbox( panel, "Gyroscopic Term", &k_gyro );
-
- ui_tabs( panel, panel,
- (const char *[]){ "collision", "racket" }, 2, &k_demo );
-
- if( k_demo == 0 ) gui0( panel );
- else if( k_demo == 1 ) gui1( panel );
-
- ui_rect viewport = { 0,0, vg.window_x-300, vg.window_y };
-
- if( ui_inside_rect( viewport, vg_ui.mouse ) && ui_clicking(UI_MOUSE_LEFT) ){
- k_view_x += -((f32)vg.mouse_delta[0] / (f32)vg.window_x) * VG_TAUf,
- k_view_y += ((f32)vg.mouse_delta[1] / (f32)vg.window_y) * VG_PIf;
- }
-}
+++ /dev/null
-..
\ No newline at end of file
+++ /dev/null
-
-#ifdef _WIN32
-
-__declspec( dllexport ) DWORD NvOptimusEnablement = 0x00000001;
-__declspec( dllexport ) int AmdPowerXpressRequestHighPerformance = 1;
-#else
-__attribute__((used)) unsigned int NvOptimusEnablement = 0x00000001;
-__attribute__((used)) int AmdPowerXpressRequestHighPerformance = 1;
-#endif
+++ /dev/null
-name program
-append foundation.kv
-add source/tools/metacompiler.c
+++ /dev/null
-synth_bird__warbling_vireo:
-BAAAAAAABAAAAAAAGAAAAAAAFAAAAAAAIAAAAAAAHAAAAAAANAAAAAAAMAAAAAAAILFMNGKDDJLJEBLDAAAAAAAAMAAAAAAAILOBFAODNMMMMMNDAAAAKHFEAAAAIMCEAAAAIMCEAAAAAAAAAAAAAIPDAAAAAAPDNMMMMEODAAAAAAODMDAAAAAAAAAAIEDENMMMMMNDNMMMMENDAAAEDIFEAAAAKPDMAAAIENEEAAAAAAAAAAAAAIPDAAAAAAPDNMMMMEODAAAAAAODMDAAAAAAAAAAAMCENMMMMMNDAAAAAAAAAAAAGBFEAAAAGJEMAAAAKHEEAAAIENEEAAAAAIPDAAAAAAPDNMMMMEODAAAAAAODMDAAAAAAAAAAAMCEPICMFHNDKAHNDCNDAAAMBEFEAAAAIEDEAAAAACBMAAAIJIEMAAAAAIPDAAAAAAPDNMMMMEODAAAAAAODMDAAAAAAAAAAELCEILOBFAODJCMFPINDAAAMPIFEAAAAKPEMAAAAAAAAAAAICKEEAAAAAIPDAAAAAAPDNMMMMEODAAAAAAODMDAAAAAAAAAAACBENMMMMENDAAAAAAAAAAAMICFEAAAAGJDMAAAAPCEEAAAAIEEEAAAAAIPDAAAAAAPDNMMMMEODAAAAAAODMDAAAAAAAAAAACBEMOBFILNDJCMFPINDAAAABGFEAAAAGJDMAAAAAAAAAAAAAAAAAAAAAIPDAAAAAAPDNMMMMEODAAAAAAODMDAAAAAAAAAAAKBENMMMMENDJCMFPINDAAAAGJFEAAAALJEEAAAAGJDEAAAAAAAAAAAAAIPDAAAAAAPDNMMMMEODAAAAAAODMDAAAAAAAAAAAKBEKAHNDKNDKAHNDKMDAAAMICFEAAAAIEEMAAAAGBDEAAAAKHEEAAAAAIPDAAAAAAPDNMMMMEODAAAAAAODMDAAAAAAAAAAACDEPICMFPNDKAHNDKNDAAAMICFEAAAAIEEMAAAAGBDEAAAAKHEEAAAAAIPDAAAAAAPDNMMMMEODAAAAAAODMDAAAAAAAAAAACDENMMMMMNDKAHNDCNDAAAOEMFEAAAAIMCMAAAAIEFMAAAAKHEEAAAAAIPDAAAAAAPDNMMMMEODAAAAAAODMDAAAAAAAAAAIMCEKAHNDCODNMMMMMNDAAACFIFEAAAAIEDMAAAAGJDEAAAIJIEEAAAAAIPDAAAAAAPDNMMMMEODAAAAAAODMDAAAAAAAAAAAKBE
-
-synth_bird__pied_monarch:
-BAAAAAAABAAAAAAAGAAAAAAAFAAAAAAAIAAAAAAAHAAAAAAANAAAAAAAMAAAAAAAILFMNGKDDJLJEBLDAAAAAAAAMAAAAAAAMOBFIDODILOBFAODAAAIJAFEAAAAPCEEAAAAGJDMAAAAAAAAKJJJJBPDNMMMMENDAAAAAAAAAAAAAAAAMDAAAAAAAAAAAAAALHEBOCODPICMFPNDAAAIJAFEAAAAPCEEAAAAGJDMAAAAAAAANMMMMEPDNMMMMENDAAAAAAAAAAAAAAAAMDAAAAAAAAAAAAAAKAHNDCODOKHEBONDAAAIJAFEAAAAPCEEAAAAGJDMAAAAAAAAGGGGGGPDNMMMMENDAAAAAAAAAAAAAAAAMDAAAAAAAAAAAAAAJCMFPAODMOBFILNDAAAIJAFEAAAAPCEEAAAAGJDMAAAAAAAAAAAAAIPDNMMMMENDAAAAAAAAAAAAAAAAMDAAAAAAAAAAAAAAPICMFPNDJCMFPINDAAAIJAFEAAAAPCEEAAAAGJDMAAAAAAAAAAAAAIPDNMMMMENDAAAAAAAAAAAAAAAAMDAAAAAAAAAAAAAAOKHEBONDPICMFHNDAAAIJAFEAAAAPCEEAAAAGJDMAAAAAAAAAAAAAIPDNMMMMENDAAAAAAAAAAAAAAAAMDAAAAAAAAAAAAAANMMMMMNDNMMMMENDAAAIJAFEAAAAPCEEAAAAGJDMAAAAAAAAAAAAAIPDNMMMMENDAAAAAAAAAAAAAAAAMDAAAAAAAAAAAAAANMMMMMNDNMMMMENDAAAIJAFEAAAAPCEEAAAAGJDMAAAAAAAAAAAAAIPDNMMMMENDAAAAAAAAAAAAAAAAMDAAAAAAAAAAAAAANMMMMMNDNMMMMENDAAAIJAFEAAAAPCEEAAAAGJDMAAAAAAAAAAAAAIPDNMMMMENDAAAAAAAAAAAAAAAAMDAAAAAAAAAAAAAANMMMMMNDNMMMMENDAAAIJAFEAAAAPCEEAAAAGJDMAAAAAAAAAAAAAIPDNMMMMENDAAAAAAAAAAAAAAAAMDAAAAAAAAAAAAAANMMMMMNDNMMMMENDAAAIJAFEAAAAPCEEAAAAGJDMAAAAAAAAAAAAAIPDNMMMMENDAAAAAAAAAAAAAAAAMDAAAAAAAAAAAAAANMMMMMNDNMMMMMNDAAAIJAFEAAAAPCEEAAAAGJDMAAAAAAAAAAAAAIPDNMMMMENDAAAAAAAAAAAAAAAAMDAAAAAAAAAAAAAA
-
-synth_bird__bridled_honeyeater:
-BAAAAAAABAAAAAAAGAAAAAAAFAAAAAAAIAAAAAAAHAAAAAAANAAAAAAAMAAAAAAAILFMNGKDDJLJEBLDAAAAAAAAKAAAAAAANMMMMMNDNMMMMMNDAAAAKPEEAAAAKHEMAAAAGBEEAAAAAAAAAAAAAIPDAAAAAAAAAAAAAAAAAAAAAAAAOBAAAAAAAAAAAHCENMMMMMNDNMMMMMNDAAAAKHFEAAAAAAAAAAAAIEDMAAAAIEDMNMMMMEPDAAAAAIODAAAAAIODAAAAAIODOBAAAAAAAAAAAHCEPICMFHNDKAHNDCMDAAAAKHFEAAAAAAAAAAAAPCEMAAAAIEEMGGGGGGPDNMMMMMNDAAAAAAAAAAAAAAAAMDAAAAAAAAAAAKBEJCMFPINDKAHNDCMDAAAOGHFEAAAAAAAAAAAAPCEMAAAAIEEMGGGGGGPDNMMMMMNDAAAAAAAAAAAAAAAAMDAAAAAAAAAAAKBEKAHNDKNDKAHNDCMDAAAMDHFEAAAAAAAAAAAAPCEMAAAAIEEMGGGGGGPDNMMMMMNDAAAAAAAAAAAAAAAAMDAAAAAAAAAAAKBEMOBFILNDKAHNDCMDAAAKAHFEAAAAAAAAAAAAPCEMAAAAIEEMGGGGGGPDNMMMMMNDAAAAAAAAAAAAAAAAMDAAAAAAAAAAAKBENMMMMMNDKAHNDKMDAAAINGFEAAAAAAAAAAAAPCEMAAAAIEEMGGGGGGPDNMMMMEODNMMMMMNDAAAAAAAAMDAAAAAAAAAAAKBEOKHEBONDNMMMMENDAAAGKGFEAAAAAAAAAAAAPCEMAAAAIEEMGGGGGGPDNMMMMMODNMMMMEODAAAAAAAAMDAAAAAAAAAAAKBEPICMFPNDNMMMMEODAAAEHGFEAAAAAAAAAAAAPCEMAAAAIEEMKJJJJJODNMMMMMNDAAAAAAAAAAAAAAAAMDAAAAAAAAAAAKBENMMMMMNDNMMMMMNDAAAICCFEAAAICKEEAAAAGBEEAAAAAAAAMOBFIHPDPICMFPMDAAAAAAAAAAAAAAAAMDAAAAAAAAAAAKBE
-
-synth_bird__cricket:
-BAAAAAAABAAAAAAAGAAAAAAAFAAAAAAAIAAAAAAAHAAAAAAANAAAAAAAMAAAAAAAILFMNGKDDJLJEBLDAAAAAAAAKAAAAAAANMMMMMNDKJJJJBODAAAEMJFEAAAAAAAAAAAAAAAAAAAAIMCEAAAAAIODAAAAAIODAAAAAIODAAAAAIODICAAAAAAAAAAIEDEOKHEBONDJCMFPAODAAAEMJFEAAAAAAAAAAAAAAAAAAAAIMCEAAAAAIODAAAAAIODAAAAAIODAAAAAIODICAAAAAAAAAAIEDEILOBFAODKJJJJBODAAAEMJFEAAAAAAAAAAAAAAAAAAAAIMCEAAAAAIODAAAAAIODAAAAAIODAAAAAIODICAAAAAAAAAAIEDEMOBFILNDKAHNDCODAAAEMJFEAAAAAAAAAAAAAAAAAAAAIMCEAAAAAIODAAAAAIODAAAAAIODAAAAAIODICAAAAAAAAAAIEDENMMMMMNDPICMFPNDAAAEMJFEAAAAAAAAAAAAAAAAAAAAIMCEAAAAAIODAAAAAIODAAAAAIODAAAAAIODICAAAAAAAAAAIEDENMMMMMNDKJJJJBODAAAEMJFEAAAAAAAAAAAAAAAAAAAAIMCEAAAAAIODAAAAAIODAAAAAIODAAAAAIODICAAAAAAAAAAIEDEOKHEBONDJCMFPAODAAAEMJFEAAAAAAAAAAAAAAAAAAAAIMCEAAAAAIODAAAAAIODAAAAAIODAAAAAIODICAAAAAAAAAAIEDEILOBFAODKJJJJBODAAAEMJFEAAAAAAAAAAAAAAAAAAAAIMCEAAAAAIODAAAAAIODAAAAAIODAAAAAIODICAAAAAAAAAAIEDEMOBFILNDKAHNDCODAAAEMJFEAAAAAAAAAAAAAAAAAAAAIMCEAAAAAIODAAAAAIODAAAAAIODAAAAAIODICAAAAAAAAAAIEDENMMMMMNDPICMFPNDAAAEMJFEAAAAAAAAAAAAAAAAAAAAIMCEAAAAAIODAAAAAIODAAAAAIODAAAAAIODICAAAAAAAAAAIEDE
-
-synth_bird__gray_shrikethrush:
-BAAAAAAABAAAAAAAGAAAAAAAFAAAAAAAIAAAAAAAHAAAAAAANAAAAAAAMAAAAAAAILFMNGKDDJLJEBLDAAAAAAAABAAAAAAAILOBFAODNMMMMMNDAAAICCFEAAAAIEDMAAAAIMCMAAAAIEDEGGGGGGPDNMMMMMNDNMMMMENDPGCBDIKDMDAAAAAAAAAAACBE
-
-synth_bird__boobook:
-BAAAAAAABAAAAAAAGAAAAAAAFAAAAAAAIAAAAAAAHAAAAAAANAAAAAAAMAAAAAAAILFMNGKDDJLJEBLDAAAAAAAACAAAAAAAKJJJJJODJCMFPAODAAAAPCEEAAAAAAAAAAAAIMCMAAAAIMCEGGGGGGPDJCMFPAODAAAAAAAANMMMMEODOBAAAAAAAAAAAJBEKJJJJJODKJJJJJPDAAAINBEEAAAAAAAAAAAAIMCMAAAAIMCEGGGGGGPDAAAAAAAAKJJJJJODAAAAAAAAOBAAAAAAAAAAAJBE
-
-synth_bird__shrike_tit:
-BAAAAAAABAAAAAAAGAAAAAAAFAAAAAAAIAAAAAAAHAAAAAAANAAAAAAAMAAAAAAAILFMNGKDDJLJEBLDAAAAAAAABAAAAAAAKJJJJBPDDDDDDLPDAAAMPAFEAAAAGJDMAAAAIMCMAAAAIMCEAAAAAIPDJCMFPAODAAAAAAAANMMMMMNDMDAAAAAAAAAAAKAE
-
+++ /dev/null
-#include "stdint.h"
-#include "stdio.h"
-#include "stdlib.h"
-#include "math.h"
-
-#define SYNTH_BIRD_STDLIB
-#include "vg_audio_synth_bird.h"
-#include "vg_m.h"
-
-#define WRAP1S( X ) (X)%44100
-
-/*
- * clang birds.c -lm -o birds && ./birds | aplay -f cd /dev/stdin
- *
- * Performance measurements: (generate 30seconds audio)
- *
- * DSP SINE_ACCURATE -O3 x Realtime
- *
- * on yes 0.182s 164x
- * on no 0.134s 223x
- * off yes 0.113s 265x
- * off no 0.074s 405x
- *
- */
-
-static void vg_dsp_init( void );
-static void vg_dsp_process( float *stereo_in, float *stereo_out );
-
-static void write_profile( FILE *fp, struct synth_bird_settings *settings,
- struct synth_bird_signature *pattern,
- u32 pattern_count, const char *name )
-{
- struct synth_bird *bird =
- synth_bird_create( settings, pattern, pattern_count );
-
- u32 size = synth_bird_save_size( bird );
- char save[ size*2 ];
- synth_bird_save( bird, save );
-
- fprintf( fp, "%s:\n%.*s\n\n", name, size*2, save );
-}
-
-#define _PROFILE( FP, SETTINGS, ARRAY ) \
- write_profile( FP, SETTINGS, ARRAY, sizeof(ARRAY)/sizeof(ARRAY[0]), \
- #ARRAY )
-
-static void export_all_profiles(void)
-{
- FILE *fp = fopen( "bird_profiles.txt", "w" );
-
- struct synth_bird_settings *settings = &synth_bird__default_settings;
-
- _PROFILE( fp, settings, synth_bird__warbling_vireo );
- _PROFILE( fp, settings, synth_bird__pied_monarch );
- _PROFILE( fp, settings, synth_bird__bridled_honeyeater );
- _PROFILE( fp, settings, synth_bird__cricket );
- _PROFILE( fp, settings, synth_bird__gray_shrikethrush );
- _PROFILE( fp, settings, synth_bird__boobook );
- _PROFILE( fp, settings, synth_bird__shrike_tit );
-
- fclose( fp );
-}
-
-int main( int argc, char *argv[] )
-{
- vg_dsp_init();
-
- export_all_profiles();
-
- struct synth_bird *warbling_vireo =
- synth_bird_create( &synth_bird__default_settings,
- synth_bird__warbling_vireo,
- sizeof(synth_bird__warbling_vireo)/
- sizeof(struct synth_bird_signature) );
-
- for(;;){
- float stereo[2] = { 0.0f, 0.0f };
-
- float b[2];
-
- synth_bird_generate_samples( warbling_vireo, b, 1 );
- stereo[0] += b[0];
- stereo[1] += b[1];
-
-#if 0
- vg_dsp_process( stereo, stereo );
-#endif
-
- int16_t l = stereo[0] * 14000.0f,
- r = stereo[1] * 14000.0f;
-
- fwrite( &l, 2,1, stdout );
- fwrite( &r, 2,1, stdout );
- }
-}
-
-
-static float dsp_buffer[(1024*1024)/4];
-static int dsp_allocations = 0;
-
-struct dsp_delay
-{
- int length, cur;
- float *buffer;
-};
-
-struct dsp_lpf
-{
- float exponent;
- float *buffer;
-};
-
-struct dsp_schroeder
-{
- struct dsp_delay M;
- float gain;
-};
-
-static float *dsp_allocate( int l )
-{
- float *buf = &dsp_buffer[ dsp_allocations ];
- dsp_allocations += l;
- return buf;
-}
-
-static inline void dsp_read_delay( struct dsp_delay *delay, float *s )
-{
- int index = delay->cur+1;
- if( index >= delay->length ) index = 0;
- *s = delay->buffer[ index ];
-}
-
-static inline void dsp_write_delay( struct dsp_delay *delay, float *s )
-{
- int index = delay->cur;
- delay->buffer[ index ] = *s;
- delay->cur ++;
- if( delay->cur >= delay->length ) delay->cur = 0;
-}
-
-static void dsp_init_delay( struct dsp_delay *delay, float length )
-{
- delay->length = 44100.0f * length;
- delay->cur = 0;
- delay->buffer = dsp_allocate( delay->length );
-
- for( int i=0; i<delay->length; i++ )
- delay->buffer[i] = 0.0f;
-}
-
-static void dsp_update_lpf( struct dsp_lpf *lpf, float freq )
-{
- lpf->exponent = 1.0f-expf( -(1.0f/44100.0f) *2.0f*3.1415926535897f*freq );
-}
-
-static void dsp_init_lpf( struct dsp_lpf *lpf, float freq )
-{
- lpf->buffer = dsp_allocate( 4 );
- lpf->buffer[0] = 0.0f;
- dsp_update_lpf( lpf, freq );
-}
-
-static inline void dsp_write_lpf( struct dsp_lpf *lpf, float *s )
-{
- float diff = *s - lpf->buffer[0];
- lpf->buffer[0] += diff * lpf->exponent;
-}
-
-static inline void dsp_read_lpf( struct dsp_lpf *lpf, float *s )
-{
- *s = lpf->buffer[0];
-}
-
-static void dsp_init_schroeder( struct dsp_schroeder *sch, float length,
- float gain )
-{
- dsp_init_delay( &sch->M, length );
- sch->gain = gain;
-}
-
-static inline void dsp_process_schroeder( struct dsp_schroeder *sch,
- float *input, float *output )
-{
- float dry = *input;
-
- float delay_output;
- dsp_read_delay( &sch->M, &delay_output );
-
- float feedback_attenuated = delay_output * sch->gain,
- input_feedback_sum = dry + feedback_attenuated;
-
- dsp_write_delay( &sch->M, &input_feedback_sum );
-
- *output = delay_output - input_feedback_sum*sch->gain;
-}
-
-/* temporary global design */
-static struct dsp_lpf __lpf_mud_free,
- __hpf_mud_free;
-
-static struct dsp_delay __echos[8];
-static struct dsp_lpf __echos_lpf[8];
-static struct dsp_schroeder __diffusion_chain[8];
-
-static void vg_dsp_init( void )
-{
- /* temporary global design */
-
- dsp_init_lpf( &__lpf_mud_free, 125.0f );
- dsp_init_lpf( &__hpf_mud_free, 500.0f );
-
- float sizes[] =
- { 2.0f, 4.0f, 8.0f, 16.0f, 32.0f, 64.0f, 128.0f, 256.0f };
-
- float reflection_variance = 0.04f;
-
- for( int i=0; i<8; i++ )
- {
- float reflection_time = ((sizes[i])/343.0f) * 1000.0f;
-
- float var = 1.0f + vg_randf64_range(-1.0,1.0) * reflection_variance,
- total = reflection_time * var;
-
- dsp_init_delay( &__echos[i], total / 1000.0f );
-
- float freq = vg_lerpf( 800.0f, 350.0f, sizes[i] / 256.0f );
- dsp_init_lpf( &__echos_lpf[i], freq );
- }
-
- float diffusions[] = { 187.0f, 159.0f, 143.0f, 121.0f,
- 79.0f, 57.0f, 27.0f, 11.0f };
-
- for( int i=0; i<8; i++ )
- {
- dsp_init_schroeder( __diffusion_chain+i, diffusions[i]/1000.0f, 0.7f );
- }
-}
-
-static void vg_dsp_process( float *stereo_in, float *stereo_out )
-{
- float in_total = (stereo_in[0]+stereo_in[1])*0.5f;
- float recieved = 0.0f;
-
- float echo_tunings[] = { 0.05f, 0.05f, 0.1f, 0.1f,
- 0.1f, 0.1f, 0.2f, 0.3f };
-
- for( int i=0; i<8; i++ )
- {
- float echo;
- dsp_read_delay( __echos+i, &echo );
- dsp_write_lpf( __echos_lpf+i, &echo );
- dsp_read_lpf( __echos_lpf+i, &echo );
-
- recieved += echo * echo_tunings[i]*0.9;
- }
-
- float diffused = recieved;
-
- for( int i=0; i<8; i++ )
- {
- dsp_process_schroeder( __diffusion_chain+i, &diffused, &diffused );
- }
-
- float total = in_total + (diffused*0.5f + recieved*0.5f);
-
- dsp_write_lpf( &__hpf_mud_free, &total );
- dsp_read_lpf( &__hpf_mud_free, &total );
-
- float low_mud;
- dsp_write_lpf( &__lpf_mud_free, &total );
- dsp_read_lpf( &__lpf_mud_free, &low_mud );
-
- total -= low_mud;
-
- for( int i=0; i<8; i++ )
- dsp_write_delay( __echos+i, &total );
-
- stereo_out[0] = stereo_in[0]*0.5f;
- stereo_out[1] = stereo_in[1]*0.5f;
- stereo_out[0] += diffused*0.8f+recieved*0.9f;
- stereo_out[1] += diffused*0.8f+recieved*0.9f;
-}
-
+++ /dev/null
-// Copyright (C) 2021 Harry Godden (hgn) - All Rights Reserved
-
-#define VG_TOOLS
-#include "vg/vg.h"
-
-#define STB_IMAGE_IMPLEMENTATION
-#include "stb/stb_image.h"
-
-// Super basic model compiler
-int main( int argc, char *argv[] )
-{
- if( argc < 3 )
- {
- vg_error( "Need input/output files\n" );
- return 0;
- }
-
- FILE *output;
-
- int x,y,n;
- unsigned char *data = stbi_load( argv[1], &x, &y, &n, 4 );
-
- if( data )
- {
- output = fopen( argv[2], "w" );
- if( !output )
- {
- vg_error( "couldn't open output for writing\n" );
- free(data);
- return 0;
- }
-
- fprintf( output, "/* Font buffer generated from source file: '%s' */\n", argv[1] );
-
- u32 pixel_max = x*y;
- u32 pixel = 0, chars = 0;
- while(pixel_max)
- {
- u32 buff = 0;
- for( int b = 31; b >= 0; b-- )
- {
- buff |= data[pixel*4]>128?0x1<<b:0;
- pixel++;
-
- if( pixel >= pixel_max )
- {
- pixel_max = 0;
- break;
- }
- }
-
- fprintf( output, "%#x,", buff );
- if( (++chars) % 8 == 0 )
- fprintf( output, "\n" );
- }
-
- free(data);
- fclose(output);
-
- vg_success( "Font compiled successfully\n" );
- }
- else
- {
- vg_error( "Couldn't open source file\n" );
- return 0;
- }
-}
+++ /dev/null
-i32 main( i32 argc, const c8 *argv[] )
-{
- return 0;
-}
+++ /dev/null
-// Copyright (C) 2021-2023 Harry Godden (hgn) - All Rights Reserved
-
-#define VG_TOOLS
-#include "vg/vg.h"
-#include "vg/vg_msg.h"
-
-#define CHUNK_SIZE 4096
-
-int main( int argc, char *argv[] ){
- assert(argc);
-
- if( argc < 2 ){
- vg_error( "Usage: %s <file>\n", argv[0] );
- return 0;
- }
-
- for( int i=0; i<argc-1; i++ ){
- FILE *f = fopen( argv[i+1], "rb" );
- if( !f ){
- vg_error( "vg_disk_open_read: %s\n", strerror(errno) );
- }
-
- void *buffer = NULL;
- u64 current = 0;
-
- /* read in chunks */
- for( u32 i=0; 1; i++ ){
- buffer = realloc( buffer, current + CHUNK_SIZE );
- u64 l = fread( buffer + current, 1, CHUNK_SIZE, f );
- current += l;
-
- if( l != CHUNK_SIZE ){
- if( feof( f ) ){
- break;
- }
- else{
- if( ferror( f ) ){
- fclose(f);
- vg_fatal_error( "read error" );
- }
- else{
- fclose(f);
- vg_fatal_error( "unknown error codition" );
- }
- }
- }
- }
-
- fclose( f );
-
- printf( "%s (%u bytes):", argv[i+1], (u32)current );
-
- vg_msg msg;
- vg_msg_init( &msg, buffer, current );
- vg_msg_print( &msg, current );
-
- free( buffer );
- }
-}
+++ /dev/null
-/*
-
-Command line tool to convert between png <> qoi format
-
-Requires "stb_image.h" and "stb_image_write.h"
-Compile with:
- gcc qoiconv.c -std=c99 -O3 -o qoiconv
-
-Dominic Szablewski - https://phoboslab.org
-
-
--- LICENSE: The MIT License(MIT)
-
-Copyright(c) 2021 Dominic Szablewski
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files(the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies
-of the Software, and to permit persons to whom the Software is furnished to do
-so, subject to the following conditions :
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-*/
-
-
-#define STB_IMAGE_IMPLEMENTATION
-#define STBI_ONLY_PNG
-#define STBI_NO_LINEAR
-#include "stb/stb_image.h"
-
-//#define STB_IMAGE_WRITE_IMPLEMENTATION
-//#include "stb_image_write.h"
-
-#define QOI_IMPLEMENTATION
-#include "phoboslab/qoi.h"
-
-
-#define STR_ENDS_WITH(S, E) (strcmp(S + strlen(S) - (sizeof(E)-1), E) == 0)
-
-int main(int argc, char **argv) {
- if (argc < 3) {
- printf("Usage: qoiconv <infile> <outfile>\n");
- printf("Examples:\n");
- printf(" qoiconv input.png output.qoi\n");
- printf(" qoiconv input.qoi output.png\n");
- exit(1);
- }
-
- stbi_set_flip_vertically_on_load(1);
-
- void *pixels = NULL;
- int w, h, channels;
- if (STR_ENDS_WITH(argv[1], ".png")) {
- pixels = (void *)stbi_load(argv[1], &w, &h, &channels, 4);
- }
- else if (STR_ENDS_WITH(argv[1], ".qoi")) {
- qoi_desc desc;
- pixels = qoi_read(argv[1], &desc, 0);
- channels = desc.channels;
- w = desc.width;
- h = desc.height;
- }
-
- if (pixels == NULL) {
- printf("Couldn't load/decode %s\n", argv[1]);
- exit(1);
- }
-
- int encoded = 0;
- if (STR_ENDS_WITH(argv[2], ".png")) {
- //encoded = stbi_write_png(argv[2], w, h, channels, pixels, 0);
- }
- else if (STR_ENDS_WITH(argv[2], ".qoi")) {
- encoded = qoi_write(argv[2], pixels, &(qoi_desc){
- .width = w,
- .height = h,
- .channels = 4,
- .colorspace = QOI_SRGB
- });
- }
-
- if (!encoded) {
- printf("Couldn't write/encode %s\n", argv[2]);
- exit(1);
- }
-
- free(pixels);
- return 0;
-}
+++ /dev/null
-#define STB_INCLUDE_IMPLEMENTATION
-#define STB_INCLUDE_LINE_GLSL
-#include "../dep/stb/stb_include.h"
-#define VG_TOOLS
-#include "vg/vg.h"
-
-struct uniform
-{
- char name[30];
- char type[20];
-
- int array;
-}
-uniform_buffer[100];
-static int uniform_count;
-
-static int compile_subshader( FILE *header, char *name )
-{
- char error[256];
- char *full = stb_include_file( name, "", ".", error );
-
- if( !full )
- {
- fprintf( stderr, "stb_include_file error:\n%s\n", error );
- return 0;
- }
- else
- {
- /* VG */
-
- fprintf( header, "{\n"
- ".orig_file = \"../../shaders/%s\",\n"
- ".static_src = \n", name );
-
- char *cur = full, *start = full;
- while( 1 )
- {
- char c = *cur;
- if( c == '\n' || c == '\0' )
- {
- *cur = '\0';
- fputs( "\"", header );
- fputs( start, header );
-
- if( !strncmp(start,"uniform",7) )
- {
- start += 8;
- struct uniform *uf = &uniform_buffer[ uniform_count ++ ];
- uf->array = 0;
- for( int i=0;; i++ )
- {
- if( start[i] == '\0' )
- break;
-
- if( start[i] == ';' )
- {
- start[i] = '\0';
- strncpy( uf->name, start, sizeof(uf->name) );
- }
-
- if( start[i] == '[' )
- {
- start[i] = '\0';
- strncpy( uf->name, start, sizeof(uf->name) );
- uf->array = 1;
- }
-
- if( start[i] == ' ' )
- {
- start[i] = '\0';
- strncpy( uf->type, start, sizeof(uf->type) );
- start = start+i+1;
- i=0;
- }
- }
- }
-
- if( c == '\0' )
- {
- fputs( "\"", header );
- break;
- }
-
- fputs( "\\n\"\n", header );
- start = cur+1;
- }
- cur ++;
- }
-
- fputs( "},", header );
- }
-
- free( full );
- return 1;
-}
-
-int main( int argc, char *argv[] )
-{
- if( argc < 2 || (argc-1)%3 != 0 )
- {
- fprintf( stderr, "invalid\n" );
- return 0;
- }
-
- char path[260];
- int shader_count = (argc-1)/3;
- for( int i=0; i<shader_count; i++ )
- {
- char **args = &argv[1+i*3];
- strcpy( path, args[0] );
- strcat( path, ".h" );
-
- printf( "Compiling shader called '%s'\n", args[0] );
-
- FILE *header = fopen( path, "w" );
- if( !header )
- {
- fprintf(stderr, "Could not open '%s'\n", path );
- continue;
- }
-
- fprintf( header, "#ifndef SHADER_%s_H\n"
- "#define SHADER_%s_H\n", args[0], args[0] );
- fprintf( header, "static void shader_%s_link(void);\n", args[0] );
- fprintf( header, "static void shader_%s_register(void);\n", args[0] );
- fprintf( header, "static struct vg_shader _shader_%s = {\n"
- " .name = \"%s\",\n"
- " .link = shader_%s_link,\n"
- " .vs = \n", args[0], args[0], args[0] );
-
- uniform_count = 0;
- if( !compile_subshader(header,args[1]) )
- {
- fclose( header );
- continue;
- }
-
- fprintf( header, "\n .fs = \n" );
- if( !compile_subshader(header,args[2]) )
- {
- fclose( header );
- continue;
- }
-
- fprintf( header, "\n};\n\n" );
-
- for( int i=0; i<uniform_count; i++ )
- {
- struct uniform *uf = &uniform_buffer[i];
- fprintf( header, "static GLuint _uniform_%s_%s;\n", args[0], uf->name);
- }
-
- for( int i=0; i<uniform_count; i++ )
- {
- struct uniform *uf = &uniform_buffer[i];
- if( uf->array ) continue;
-
- if( !strcmp(uf->type,"vec2") )
- {
- fprintf( header, "static void shader_%s_%s(v2f v){\n"
- " glUniform2fv( _uniform_%s_%s, 1, v );\n"
- "}\n", args[0], uf->name, args[0], uf->name );
- }
- if( !strcmp(uf->type,"vec3") )
- {
- fprintf( header, "static void shader_%s_%s(v3f v){\n"
- " glUniform3fv( _uniform_%s_%s, 1, v );\n"
- "}\n", args[0], uf->name, args[0], uf->name );
- }
- if( !strcmp(uf->type,"vec4") )
- {
- fprintf( header, "static void shader_%s_%s(v4f v){\n"
- " glUniform4fv( _uniform_%s_%s, 1, v );\n"
- "}\n", args[0], uf->name, args[0], uf->name );
- }
- if( !strcmp(uf->type,"sampler2D") )
- {
- fprintf( header, "static void shader_%s_%s(int i){\n"
- " glUniform1i( _uniform_%s_%s, i );\n"
- "}\n", args[0], uf->name, args[0], uf->name );
- }
- if( !strcmp(uf->type,"float") )
- {
- fprintf( header, "static void shader_%s_%s(float f){\n"
- " glUniform1f( _uniform_%s_%s, f );\n"
- "}\n", args[0], uf->name, args[0], uf->name );
- }
- if( !strcmp(uf->type,"mat4x3") )
- {
- fprintf( header,
- "static void shader_%s_%s(m4x3f m){\n"
- " glUniformMatrix4x3fv"
- "( _uniform_%s_%s, 1, GL_FALSE, (float *)m );\n"
- "}\n", args[0], uf->name, args[0], uf->name );
- }
- if( !strcmp(uf->type,"mat3") )
- {
- fprintf( header,
- "static void shader_%s_%s(m3x3f m){\n"
- " glUniformMatrix3fv"
- "( _uniform_%s_%s, 1, GL_FALSE, (float *)m );\n"
- "}\n", args[0], uf->name, args[0], uf->name );
- }
- if( !strcmp(uf->type,"mat4") )
- {
- fprintf( header,
- "static void shader_%s_%s(m4x4f m){\n"
- " glUniformMatrix4fv"
- "( _uniform_%s_%s, 1, GL_FALSE, (float *)m );\n"
- "}\n", args[0], uf->name, args[0], uf->name );
- }
- }
-
- fprintf( header,
- "static void shader_%s_register(void){\n"
- " vg_shader_register( &_shader_%s );\n"
- "}\n",
- args[0],args[0] );
-
- fprintf( header,
- "static void shader_%s_use(void){ glUseProgram(_shader_%s.id); }\n",
- args[0], args[0] );
-
- fprintf( header,
- "static void shader_%s_link(void){\n",
- args[0] );
-
- for( int i=0; i<uniform_count; i++ )
- {
- struct uniform *uf = &uniform_buffer[i];
- fprintf( header,
- " _uniform_%s_%s = "
- "glGetUniformLocation( _shader_%s.id, \"%s\" );\n",
- args[0], uf->name,
- args[0], uf->name );
- }
-
- fprintf( header, "}\n" );
- fprintf( header, "#endif /* SHADER_%s_H */\n", args[0] );
- fclose( header );
- }
-}
+++ /dev/null
-// Copyright (C) 2021 Harry Godden (hgn) - All Rights Reserved
-
-#include "vg/vg.h"
-
-int main( int argc, char *argv[] )
-{
- vg_init( argc, argv, "Voyager Game Engine" );
-}
-
-void vg_register(void){}
-void vg_start(void){}
-void vg_update(void){}
-
-void vg_render(void)
-{
- glViewport( 0,0, vg_window_x, vg_window_y );
-
- glDisable( GL_DEPTH_TEST );
- glClearColor( 0.1f, 0.1f, 0.2f, 1.0f );
- glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
-
- // Rest of drawing code...
-}
-
-void vg_ui(void)
-{
- gui_text(
- (ui_px [2]){ vg_window_x / 2, vg_window_y / 2 },
- "Voyager Game Engine", 2, k_text_align_center
- );
-
- gui_text(
- (ui_px [2]){ vg_window_x / 2, vg_window_y / 2 + 30 },
- "Template project file", 1, k_text_align_center
- );
-}
-void vg_free(void){}
+++ /dev/null
-vg_src="main.c"
-vg_target="game"
+++ /dev/null
-// Copyright (C) 2021 Harry Godden (hgn) - All Rights Reserved
-#define VG_CONFIG
-
-static struct button_binding vg_button_binds[] =
-{
- { .name = "primary", .bind = GLFW_MOUSE_BUTTON_LEFT },
- { .name = "secondary", .bind = GLFW_MOUSE_BUTTON_RIGHT }
-};
-
-static struct axis_binding vg_axis_binds[] =
-{
- { .name = "horizontal", .axis = GLFW_GAMEPAD_AXIS_LEFT_X },
- { .name = "vertical", .axis = GLFW_GAMEPAD_AXIS_LEFT_Y }
-};
-
-static struct vg_achievement vg_achievements[] =
-{
-};
+++ /dev/null
-// Copyright (C) 2021 Harry Godden (hgn) - All Rights Reserved
-
-#ifdef VG_BUILD
-
-#include "vg.h"
-#include "vg_platform.h"
-#include "vg_log.h"
-#include "vg_opt.h"
-#include "vg_build.h"
-
-u32 optimize_test_compile = 0;
-
-/*
- * Scripts
- * -------------------------------------------------------------------------- */
-
-void s_build(void){
- vg_info( "running script: s_build(void)\n" );
-
- vg_build.optimization = optimize_test_compile;
- vg_build.fresh = 0;
- vg_build.platform = k_platform_linux;
- vg_build.arch = k_architecture_x86_64;
- vg_build.compiler = k_compiler_clang;
- vg_build.libc = k_libc_version_native;
-
- vg_build_new( "texsheet" );
- vg_add_source( "src/texsheet.c" );
- vg_compile( "texsheet" );
-
- vg_success( "Completed 1/1\n" );
-}
-
-int main( int argc, char *argv[] ){
- char *arg;
- while( vg_argp( argc, argv ) ){
- if( vg_long_opt( "native" ) )
- s_build();
-
- if( vg_opt('r') )
- optimize_test_compile = 3;
- }
-
- if( vg_build.warnings )
- vg_warn( "Finished with %u warnings\n", vg_build.warnings );
- else
- vg_success( "All scripts ran successfully\n" );
-}
-
-#else
-
-#define VG_TOOLS
-#include "vg.h"
-
-#define STB_IMAGE_IMPLEMENTATION
-#include "submodules/stb/stb_image.h"
-
-#define QOI_IMPLEMENTATION
-#include "submodules/qoi/qoi.h"
-
-struct image_src
-{
- int x,y,ch;
-
- u8 *data;
-};
-
-int image_sort( const void* a, const void* b)
-{
- struct image_src *p_a = (struct image_src *)a;
- struct image_src *p_b = (struct image_src *)b;
-
- if( p_a->x == p_b->x )
- return 0;
- else if ( p_a->x < p_b->x )
- return 1;
- else
- return -1;
-}
-
-int main( int argc, const char *argv[] )
-{
- struct image_src *source_images = malloc( sizeof( struct image_src ) * argc );
-
- u32 num_images = 0;
-
- if( argc < 4 )
- {
- vg_info( "Usage: %s \\\n[output_image output_header name images...]\n",
- argv[0] );
- return 0;
- }
-
- // Open header handle
- // ------------------
- FILE *fp = fopen( argv[2], "w" );
- if( !fp )
- {
- vg_error( "Could not open file for writing\n" );
- return 0;
- }
-
- fprintf( fp, "enum %s_index\n{\n", argv[3] );
-
- // Load images
- // -----------
- stbi_set_flip_vertically_on_load(1);
-
- for( int i = 4; i < argc; i ++ )
- {
- struct image_src *src = &source_images[ num_images ];
- src->data = (u8 *)stbi_load( argv[i], &src->x, &src->y, &src->ch, 4 );
-
- char name[ 256 ];
- int j = 0; int ext = 0;
- for( ; j < vg_list_size( name )-1; j ++ )
- {
- if( argv[i][j] )
- {
- name[j] = argv[i][j];
-
- if( name[j] == '.' )
- ext = j;
-
- if( name[j] == '.' || name[j] == '-' )
- name[j] = '_';
- }
- else
- break;
- }
-
- if( ext )
- name[ext] = 0x00;
- else
- name[j] = 0x00;
-
- fprintf( fp, "\tk_sprite_%s,\n", name );
-
- if( src->data )
- {
- if( src->x != src->y )
- {
- vg_error( "Non-square images are currently not supported ('%s')\n", argv[i] );
- free( src->data );
- }
- else
- num_images ++;
- }
- else
- vg_error( "Could not decode '%s'\n", argv[i] );
- }
-
- fprintf( fp, "};\n\n" );
-
- // Sort by size
- // ------------
- qsort( source_images, num_images, sizeof(struct image_src), image_sort );
-
- // Process images
- // --------------
- fprintf( fp, "static struct vg_sprite %s[] = \n{\n", argv[3] );
-
- u8 *dest = (u8 *)malloc( 1024*1024*4 );
-
- for( int i = 0; i < 1024*1024; i ++ )
- {
- dest[ i*4 + 0 ] = 0;
- dest[ i*4 + 1 ] = 0;
- dest[ i*4 + 2 ] = 0;
- dest[ i*4 + 3 ] = 0;
- }
-
- struct region
- {
- v2i p0;
- v2i p1;
- }
- region_stack[ 32 ] =
- {
- {
- .p0 = { 0, 0 },
- .p1 = { 1024, 1024 }
- }
- };
- int stack_h = 0;
-
- for( int i = 0; i < num_images; i ++ )
- {
- struct image_src *psrc = &source_images[ i ];
-
- // Region checks
- while( 1 )
- {
- struct region *pregion = ®ion_stack[ stack_h ];
-
- if( (pregion->p0[ 0 ] + psrc->x <= pregion->p1[0]) && (pregion->p0[ 1 ] + psrc->y <= pregion->p1[1]) )
- {
- // Passed, add image and create subdivisions
- fprintf( fp, "\t{{ %f, %f, %f, %f }}",
- (float)pregion->p0[0] / 1024.0f,
- (float)pregion->p0[1] / 1024.0f,
- (float)psrc->x / 1024.0f,
- (float)psrc->y / 1024.0f
- );
-
- if( i != num_images-1 )
- fputs( ",\n", fp );
- else
- fputc( '\n', fp );
-
- // Write image
- for( int y = 0; y < psrc->y; y ++ )
- {
- int px = pregion->p0[0];
- int py = pregion->p0[1] + y;
-
- memcpy( &dest[ (py*1024+px) * 4 ], &psrc->data[ y*psrc->x*4 ], psrc->x*4 );
- }
-
- // Subdivisions
- stack_h ++;
- struct region *new_region = ®ion_stack[ stack_h ];
-
- new_region->p0[0] = pregion->p0[0] + psrc->x;
- new_region->p0[1] = pregion->p0[1];
- new_region->p1[0] = pregion->p1[0];
- new_region->p1[1] = pregion->p0[1] + psrc->y;
-
- pregion->p0[ 1 ] += psrc->y;
- break;
- }
- else
- {
- // Failed, loop up to next region if can
- if( stack_h == 0 )
- {
- vg_error( "Could not fit image %d. Pack failed\n", i );
-
- goto IL_END_ERR;
- }
- else
- stack_h --;
- }
- }
- }
-
-IL_END_ERR:
- fprintf( fp, "};" );
- fclose( fp );
-
- // Write output
- // ------------
- qoi_write( argv[1], dest, &(qoi_desc){
- .width = 1024,
- .height = 1024,
- .channels = 4,
- .colorspace = QOI_SRGB
- });
-
- // Free
- // ----
- for( int i = 0; i < num_images; i ++ )
- free( source_images[ i ].data );
- free( dest );
- free( source_images );
-
- vg_success( "Processed %u images\n", num_images );
-
-}
-
-#endif
+++ /dev/null
-#!/bin/bash
-# Copyright (C) 2021-2022 Harry Godden (hgn) - All Rights Reserved
-#
-# Standard tool scripts
-#
-mkdir $_folder/tools -p
-
-_link="-lm"
-
-tool_shader(){
- _src="vg/src/shader.c"
- _dst="tools/shader"
- compile_x
-}
-
-tool_fontcomp(){
- _src="vg/src/fontcomp.c"
- _dst="tools/fontcomp"
- compile_x
-}
-
-tool_qoiconv(){
- _src="vg/src/qoiconv.c"
- _dst="tools/qoiconv"
- compile_x
-}
-
-#tool_texsheet(){
-# _src="vg/src/texsheet.c"
-# _dst="tools/texsheet"
-# compile_x
-#}
-
-tool_shader
-tool_fontcomp
-tool_qoiconv
-#tool_texsheet
+++ /dev/null
-#ifndef VG_STORE_H
-#define VG_STORE_H
-
-#include "vg_stdint.h"
-#include "vg_io.h"
-
-/*
- * Anderson tree implementation with extensions:
- * parents are kept track of
- * duplicates are allowed
- * data is never allocated or destroyed here
- *
- * TODO: seperate offset,stride,base into 'generic array', seperate pool
- */
-
-typedef struct aatree aatree;
-typedef struct aatree_node aatree_node;
-typedef struct aatree_pool_node aatree_pool_node;
-
-typedef u32 aatree_ptr;
-#define AATREE_PTR_NIL 0xffffffff
-
-struct aatree
-{
- u32 offset, stride; /* distance between elements */
- void *base;
-
- int (*p_cmp)( void *a, void *b );
-};
-
-#pragma pack(push,1)
-struct aatree_node
-{
- aatree_ptr left, right, parent;
- u32 level, count;
-};
-
-struct aatree_pool_node
-{
- aatree_ptr next_free;
-};
-#pragma pack(pop)
-
-/* api
- * ===========================================================================*/
-
-/* return a pointer to the start of the data referenced by t */
-static void *aatree_get_data( aatree *tree, aatree_ptr t );
-
-/* link node x into the tree with root t */
-static aatree_ptr aatree_insert( aatree *tree, aatree_ptr t, aatree_ptr x );
-
-/* delete node x from tree, does not free memory */
-static aatree_ptr aatree_del( aatree *tree, aatree_ptr x );
-
-/* get pointer to element in tree with index k */
-static aatree_ptr aatree_kth( aatree *tree, aatree_ptr t, u32 k );
-
-/* get pointer to the element above x */
-static aatree_ptr aatree_next( aatree *tree, aatree_ptr x );
-
-/* get pointer by value, returns NIL if not found.
- *
- * if duplicates values are present then the result is undefined, but it will be
- * AN node with that value, just maybe not the first lexicographically
- */
-static aatree_ptr aatree_find( aatree *tree, aatree_ptr t, void *value );
-
-/* implementation
- * ===========================================================================*/
-
-static void *aatree_get_data( aatree *tree, aatree_ptr t )
-{
- return (u8 *)tree->base + tree->stride*t;
-}
-
-static u8 *aatree_node_base( aatree *tree, aatree_ptr t )
-{
- return (u8 *)tree->base + tree->stride*t + tree->offset;
-}
-
-static aatree_pool_node *aatree_get_pool_node( aatree *tree, aatree_ptr t )
-{
- return (aatree_pool_node *)aatree_node_base( tree, t );
-}
-
-static aatree_node *aatree_get_node( aatree *tree, aatree_ptr t )
-{
- return (aatree_node *)aatree_node_base( tree, t );
-}
-
-static void aatree_recount( aatree *tree, aatree_ptr n )
-{
- aatree_node *pnode = aatree_get_node( tree, n );
- pnode->count = 1;
-
- if( pnode->left != AATREE_PTR_NIL )
- pnode->count += aatree_get_node( tree, pnode->left )->count;
-
- if( pnode->right != AATREE_PTR_NIL )
- pnode->count += aatree_get_node( tree, pnode->right )->count;
-}
-
-/* . .
- * | |
- * L <- T L -> T
- * / \ \ -> / / \
- * A B R A B R
- */
-static aatree_ptr aatree_skew( aatree *tree, u32 t )
-{
- if( t == AATREE_PTR_NIL ) return t;
-
- aatree_node *ptnode = aatree_get_node( tree, t );
- if( ptnode->left == AATREE_PTR_NIL ) return t;
-
- aatree_node *plnode = aatree_get_node( tree, ptnode->left );
- if( plnode->level == ptnode->level )
- {
- aatree_ptr l = ptnode->left;
- ptnode->left = plnode->right;
- plnode->right = t;
-
- aatree_recount( tree, t );
- aatree_recount( tree, l );
-
- plnode->parent = ptnode->parent;
- ptnode->parent = l;
- if( ptnode->left != AATREE_PTR_NIL )
- aatree_get_node( tree, ptnode->left )->parent = t;
-
- return l;
- }
-
- return t;
-}
-
-/* . .
- * | |
- * T -> R -> X -> R
- * / / / \
- * A B T X
- * / \
- * A B
- */
-static aatree_ptr aatree_split( aatree *tree, aatree_ptr t )
-{
- if( t == AATREE_PTR_NIL ) return t;
-
- aatree_node *ptnode = aatree_get_node( tree, t );
- if( ptnode->right == AATREE_PTR_NIL ) return t;
-
- aatree_node *prnode = aatree_get_node( tree, ptnode->right );
- if( prnode->right == AATREE_PTR_NIL ) return t;
-
- aatree_node *prrnode = aatree_get_node( tree, prnode->right );
- if( ptnode->level == prrnode->level )
- {
- aatree_ptr r = ptnode->right;
- ptnode->right = prnode->left;
- prnode->left = t;
- prnode->level ++;
-
- aatree_recount( tree, t );
- aatree_recount( tree, r );
-
- prnode->parent = ptnode->parent;
- ptnode->parent = r;
- if( ptnode->right != AATREE_PTR_NIL )
- aatree_get_node( tree, ptnode->right )->parent = t;
-
- return r;
- }
-
- return t;
-}
-
-static aatree_ptr aatree_insert( aatree *tree, aatree_ptr t, aatree_ptr x )
-{
- aatree_node *pxnode = aatree_get_node( tree, x );
-
- if( t == AATREE_PTR_NIL )
- {
- pxnode->left = AATREE_PTR_NIL;
- pxnode->right = AATREE_PTR_NIL;
- pxnode->parent = AATREE_PTR_NIL;
- pxnode->level = 0;
- pxnode->count = 1;
- return x;
- }
-
- aatree_node *ptnode = aatree_get_node( tree, t );
- int cmp_result = tree->p_cmp( aatree_get_data( tree, t ),
- aatree_get_data( tree, x ) );
-
- ptnode->count ++;
-
- if( cmp_result <= 0 )
- {
- ptnode->left = aatree_insert( tree, ptnode->left, x );
- //aatree_node *plnode = aatree_get_node( tree, ptnode->left );
- //plnode->parent = t;
- }
- else
- {
- ptnode->right = aatree_insert( tree, ptnode->right, x );
- //aatree_node *prnode = aatree_get_node( tree, ptnode->right );
- //prnode->parent = t;
- }
-
- t = aatree_skew( tree, t );
- t = aatree_split( tree, t );
- return t;
-}
-
-static void aatree_link_down( aatree *tree, aatree_ptr p, aatree_ptr *pl,
- aatree_ptr l )
-{
- *pl = l;
-
- if( *pl != AATREE_PTR_NIL )
- aatree_get_node( tree, *pl )->parent = p;
-}
-
-static aatree_ptr aatree_copy_links( aatree *tree, aatree_ptr root,
- aatree_ptr src, aatree_ptr dst )
-{
- aatree_node *pdst = aatree_get_node( tree, dst ),
- *psrc = aatree_get_node( tree, src );
-
- pdst->count = psrc->count;
- pdst->level = psrc->level;
- pdst->parent = psrc->parent;
-
- aatree_link_down( tree, dst, &pdst->left, psrc->left );
- aatree_link_down( tree, dst, &pdst->right, psrc->right );
-
- if( pdst->parent != AATREE_PTR_NIL )
- {
- aatree_node *parent = aatree_get_node( tree, pdst->parent );
-
- if( parent->left == src )
- parent->left = dst;
- else if( parent->right == src )
- parent->right = dst;
- }
- else
- return dst;
-
- return root;
-}
-
-static aatree_ptr aatree_del( aatree *tree, aatree_ptr x )
-{
- aatree_ptr it = x,
- up[32];
-
- int count = 1, dir = 0;
-
- /* TODO: maybe be a better way to do this, without counting back up */
- for( aatree_node *s = aatree_get_node( tree, x );
- s->parent != AATREE_PTR_NIL;
- count ++ )
- s = aatree_get_node( tree, s->parent );
-
- int top=0;
- while(1)
- {
- int index = count - (++top);
-
- up[ index ] = it;
- aatree_node *itnode = aatree_get_node( tree, it );
- if( itnode->parent == AATREE_PTR_NIL )
- break;
- else
- it = itnode->parent;
- }
-
- aatree_ptr _ptrswap_src = AATREE_PTR_NIL,
- _ptrswap_dst = AATREE_PTR_NIL;
-
- aatree_node *pxnode = aatree_get_node( tree, x );
- aatree_ptr root = up[ count-1 ];
- if( pxnode->left == AATREE_PTR_NIL || pxnode->right == AATREE_PTR_NIL )
- {
- if( --top != 0 )
- {
- aatree_node *pnode = aatree_get_node( tree, up[top-1] ),
- *parent = aatree_get_node( tree, pxnode->parent );
-
- aatree_ptr next = pxnode->left == AATREE_PTR_NIL?
- pxnode->right:
- pxnode->left;
-
- if( parent->left == x ) pnode->left = next;
- else pnode->right = next;
-
- if( next != AATREE_PTR_NIL )
- {
- aatree_node *pnext = aatree_get_node( tree, next );
- pnext->parent = up[top-1];
- }
- }
- else
- {
- if( pxnode->right != AATREE_PTR_NIL ) root = pxnode->right;
- else if( pxnode->left != AATREE_PTR_NIL ) root = pxnode->left;
- else return AATREE_PTR_NIL;
-
- aatree_node *newroot = aatree_get_node( tree, root );
- newroot->parent = AATREE_PTR_NIL;
- }
- }
- else
- {
- aatree_ptr heir = pxnode->right,
- prev = x;
-
- aatree_node *pheir = aatree_get_node( tree, heir );
-
- while( pheir->left != AATREE_PTR_NIL )
- {
- up[top++] = prev = heir;
- heir = pheir->left;
- pheir = aatree_get_node( tree, heir );
- }
-
- _ptrswap_dst = heir;
- _ptrswap_src = x;
-
- aatree_node *pprev = aatree_get_node( tree, prev );
-
- if( prev == x )
- aatree_link_down( tree, prev, &pprev->right, pheir->right );
- else
- aatree_link_down( tree, prev, &pprev->left, pheir->right );
- }
-
- /* Tail */
- while( --top >= 0 )
- {
- if( top != 0 )
- {
- aatree_node *above = aatree_get_node( tree, up[top-1] );
- dir = above->right == up[top];
- }
-
- aatree_recount( tree, up[top] );
- aatree_node *pntop = aatree_get_node( tree, up[top] );
-
- if( !(pntop->left == AATREE_PTR_NIL || pntop->right == AATREE_PTR_NIL) )
- {
- aatree_node *pnl = aatree_get_node( tree, pntop->left ),
- *pnr = aatree_get_node( tree, pntop->right );
-
- if( pnl->level < pntop->level-1 || pnr->level < pntop->level-1 )
- {
- if( pnr->level > --pntop->level )
- pnr->level = pntop->level;
-
- up[top] = aatree_skew( tree, up[top] );
-
- aatree_node *ut = aatree_get_node( tree, up[top] );
- ut->right = aatree_skew( tree, ut->right );
-
- aatree_node *utr = aatree_get_node( tree, ut->right );
- utr->right = aatree_skew( tree, utr->right );
-
- up[top] = aatree_split( tree, up[top] );
- ut = aatree_get_node( tree, up[top] );
-
- ut->right = aatree_split( tree, ut->right );
- }
- }
-
- if( top != 0 )
- {
- aatree_node *ut1 = aatree_get_node( tree, up[top-1] );
-
- if( dir == 1 )
- aatree_link_down( tree, up[top-1], &ut1->right, up[top] );
- else
- aatree_link_down( tree, up[top-1], &ut1->left, up[top] );
- }
- else
- {
- root = up[top];
- aatree_get_node( tree, root )->parent = AATREE_PTR_NIL;
- }
- }
-
- /* This is our extension to the original non-recursive delete, so no data
- * has to be moved */
- if( _ptrswap_dst != AATREE_PTR_NIL )
- root = aatree_copy_links( tree, root, _ptrswap_src, _ptrswap_dst );
-
- return root;
-}
-
-static aatree_ptr aatree_kth( aatree *tree, aatree_ptr t, u32 k )
-{
- u32 i = 0;
-
- while( t != AATREE_PTR_NIL )
- {
- aatree_node *ptnode = aatree_get_node( tree, t );
-
- u32 j = i;
- if( ptnode->left != AATREE_PTR_NIL )
- j += aatree_get_node( tree, ptnode->left )->count;
-
- if( j < k )
- {
- i = j+1;
- t = ptnode->right;
- }
- else
- {
- if( j > k )
- {
- t = ptnode->left;
- }
- else
- {
- return t;
- }
- }
- }
-
- return AATREE_PTR_NIL;
-}
-
-static aatree_ptr aatree_next( aatree *tree, aatree_ptr x )
-{
- /* if can go left, go left then all the way right,
- * else go up, if it was right link accept
- */
-
- aatree_node *pnode = aatree_get_node( tree, x );
- if( pnode->right != AATREE_PTR_NIL )
- {
- aatree_ptr next = pnode->right;
-
- while(1)
- {
- aatree_node *pnext = aatree_get_node( tree, next );
-
- if( pnext->left != AATREE_PTR_NIL )
- next = pnext->left;
- else
- return next;
- }
- }
- else
- {
- aatree_ptr next = x;
-
- while(1)
- {
- aatree_node *pnode = aatree_get_node( tree, next );
-
- if( pnode->parent == AATREE_PTR_NIL )
- return AATREE_PTR_NIL;
-
- aatree_node *pabove = aatree_get_node( tree, pnode->parent );
- if( pabove->left == next )
- return pnode->parent;
- else
- next = pnode->parent;
- }
- }
-}
-
-static aatree_ptr aatree_find( aatree *tree, aatree_ptr t, void *value )
-{
- while( t != AATREE_PTR_NIL )
- {
- int cmp_result = tree->p_cmp( aatree_get_data( tree, t ), value );
-
- if( cmp_result == 0 )
- return t;
- else
- {
- aatree_node *ptnode = aatree_get_node( tree, t );
-
- if( cmp_result < 0 )
- t = ptnode->left;
- else
- t = ptnode->right;
- }
- }
- return t;
-}
-
-/*
- * Debugging stuff, everything below is scaffholding and will be removed
- * =============================================================================
- */
-
-static int aatree_verify_split( aatree *tree, aatree_ptr t )
-{
- if( t == AATREE_PTR_NIL ) return 1;
-
- aatree_node *ptnode = aatree_get_node( tree, t );
- if( ptnode->right == AATREE_PTR_NIL ) return 1;
-
- aatree_node *prnode = aatree_get_node( tree, ptnode->right );
- if( prnode->right == AATREE_PTR_NIL ) return 1;
-
- aatree_node *prrnode = aatree_get_node( tree, prnode->right );
- if( ptnode->level == prrnode->level )
- return 0;
-
- return 1;
-}
-
-static int aatree_verify_skew( aatree *tree, aatree_ptr t )
-{
- if( t == AATREE_PTR_NIL ) return 1;
-
- aatree_node *ptnode = aatree_get_node( tree, t );
- if( ptnode->left == AATREE_PTR_NIL ) return 1;
-
- aatree_node *plnode = aatree_get_node( tree, ptnode->left );
- if( plnode->level == ptnode->level )
- return 0;
-
- return 1;
-}
-
-static int aatree_verify( aatree *tree, aatree_ptr t )
-{
- aatree_node *ptnode = aatree_get_node( tree, t );
- if( ptnode->parent != AATREE_PTR_NIL )
- {
- aatree_node *parent = aatree_get_node( tree, ptnode->parent );
- if( !(parent->left == t || parent->right == t) )
- return 0;
- }
-
- if( ptnode->left != AATREE_PTR_NIL )
- if( aatree_get_node( tree, ptnode->left )->parent != t )
- return 0;
- if( ptnode->right != AATREE_PTR_NIL )
- if( aatree_get_node( tree, ptnode->right )->parent != t )
- return 0;
-
- return aatree_verify_skew( tree, t ) &&
- aatree_verify_split( tree, t );
-}
-
-
-static void aatree_show_r( aatree *tree, aatree_ptr t, int lvl,
- void(*p_show)(void *data) )
-{
- if( t != AATREE_PTR_NIL )
- {
- aatree_node *ptnode = aatree_get_node( tree, t );
- aatree_show_r( tree, ptnode->left, lvl+1, p_show );
-
- void *data = aatree_get_data( tree, t );
-
- for( int i=0; i<lvl; i++ )
- {
- vg_log( " " );
- }
- p_show( data );
- vg_log( " (%d) \n", t );
-
- aatree_show_r( tree, ptnode->right, lvl+1, p_show );
- }
-}
-
-static void aatree_show( aatree *tree, aatree_ptr t, void(*p_show)(void *data))
-{
- if( t != AATREE_PTR_NIL )
- {
- aatree_node *ptnode = aatree_get_node( tree, t );
- aatree_show( tree, ptnode->left, p_show );
- void *data = aatree_get_data( tree, t );
-
- for( int i=0; i<ptnode->level; i++ )
- {
- vg_log( " " );
- }
- p_show( data );
- vg_log( " (%d) \n", t );
-
- aatree_show( tree, ptnode->right, p_show );
- }
-}
-
-static void aatree_show_counts( aatree *tree, aatree_ptr t, int lvl, int *ln,
- int *err,
- void(*p_show)(void *data), int show )
-{
- if( lvl > 20 )
- return;
- if( t == AATREE_PTR_NIL ) return;
-
- aatree_node *ptnode = aatree_get_node( tree, t );
- void *data = aatree_get_data( tree, t );
-
- aatree_show_counts( tree, ptnode->left, lvl+1, ln, err, p_show, show );
-
- if( show ) vg_log( "%03d| ", *ln );
- *ln = *ln +1;
-
- if( show )
- for( int i=0; i<lvl; i++ )
- printf( " " );
-
- if( show )
- {
- p_show( data );
-
- if( ptnode->left != AATREE_PTR_NIL && ptnode->right != AATREE_PTR_NIL )
- printf( "|" );
- if( ptnode->left != AATREE_PTR_NIL && ptnode->right == AATREE_PTR_NIL )
- printf( "/" );
- if( ptnode->left == AATREE_PTR_NIL && ptnode->right != AATREE_PTR_NIL )
- printf( "\\" );
-
- printf( " (%d, %d, parent: %d. V: %d, level: %d) \n", t,
- ptnode->count, ptnode->parent,
- aatree_verify( tree, t ), ptnode->level);
- }
-
- if( !aatree_verify( tree, t ) )
- {
- if( show )
- vg_log( "error\n" );
- *err = 1;
- }
-
- aatree_show_counts( tree, ptnode->right, lvl+1, ln, err, p_show, show );
-}
-
-/*
- * Pool allocator utility which can be placed in a union with regular aa nodes.
- */
-
-static aatree_ptr aatree_init_pool( aatree *info, u32 item_count )
-{
- for( aatree_ptr i=0; i<item_count; i++ )
- {
- aatree_pool_node *pn = aatree_get_pool_node( info, i );
-
- if( i==item_count-1 )
- pn->next_free = AATREE_PTR_NIL;
- else
- pn->next_free = i+1;
- }
-
- return 0;
-}
-
-static aatree_ptr aatree_pool_alloc( aatree *info, aatree_ptr *head )
-{
- if( *head == AATREE_PTR_NIL )
- {
- vg_error( "No nodes free in pool allocator!\n" );
- return AATREE_PTR_NIL;
- }
- else
- {
- aatree_ptr gap = *head;
- *head = aatree_get_pool_node( info, *head )->next_free;
- return gap;
- }
-}
-
-static void aatree_pool_free( aatree *info, aatree_ptr node, aatree_ptr *head )
-{
- aatree_pool_node *pn = aatree_get_pool_node( info, node );
- pn->next_free = *head;
- *head = node;
-}
-
-#endif /* VG_STORE_H */
+++ /dev/null
-#include <windows.h>
-#include <windowsx.h>
-#include <wingdi.h>
-#include <commctrl.h>
-#include <wininet.h>
-#include <time.h>
-#include <processthreadsapi.h>
-
-#include "vg_opt.h"
-#include "vg_platform.h"
-#include "vg_string.h"
-#include "vg_io.h"
-
-#include "vg_tool.c"
-
-char *report_text = NULL;
-u32 report_length = 0;
-
-HWND window = NULL,
- send_button = NULL,
- select_button = NULL,
- close_button = NULL,
- textbox = NULL;
-
-int sent_report = 0;
-
-WNDPROC defWndProc = NULL;
-
-LRESULT OnWindowClose( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
-{
- PostQuitMessage(0);
- return CallWindowProc(defWndProc, hwnd, message, wParam, lParam);
-}
-
-#define HTTPBOUND "99667vg.mtzero.boundary88337"
-
-void send_report(void)
-{
- HINTERNET hSession = InternetOpen(
- "Mozilla/5.0", // User-Agent
- INTERNET_OPEN_TYPE_PRECONFIG,
- NULL,
- NULL,
- 0);
-
- if( hSession == NULL )
- {
- MessageBox( window, "Call failed.",
- "InternetOpen (wininet)", MB_OK|MB_ICONERROR);
- goto e4;
- }
-
- HINTERNET hConnect = InternetConnect(
- hSession,
- "skaterift.com", // HOST
- INTERNET_DEFAULT_HTTPS_PORT,
- "",
- "",
- INTERNET_SERVICE_HTTP,
- 0,
- 0);
-
- if( hConnect == NULL )
- {
- MessageBox( window, "Call failed.",
- "InternetConnect (wininet)", MB_OK|MB_ICONERROR);
- goto e3;
- }
-
- HINTERNET hHttpFile = HttpOpenRequest(
- hConnect,
- "POST", // METHOD
- "/vgreport/index.php", // URI
- NULL,
- NULL,
- NULL,
- INTERNET_FLAG_SECURE|INTERNET_FLAG_RELOAD,
- 0);
- if( hHttpFile == NULL )
- {
- MessageBox( window, "Call failed.",
- "HttpOpenRequest (wininet)", MB_OK|MB_ICONERROR);
- goto e2;
- }
-
- HttpAddRequestHeaders( hHttpFile, "Content-Type: multipart/form-data; boundary=" HTTPBOUND "\r\nConnection: close\r\n",
- -1, HTTP_ADDREQ_FLAG_ADD );
- vg_str content;
- vg_strnull( &content, NULL, 0 );
- vg_strcat( &content, "--" HTTPBOUND "\r\nContent-Disposition: form-data; name=\"uploaded_file\"\r\n" );
- vg_strcat( &content, "Content-Type: text/plain\r\n\r\n" );
- vg_strcat( &content, report_text );
- vg_strcat( &content, "\r\n\r\n--" HTTPBOUND "--\r\n" );
-
- while( !HttpSendRequest(hHttpFile, NULL, 0, content.buffer, content.i) )
- {
- DWORD option = InternetErrorDlg(
- window,
- hHttpFile,
- ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED,
- FLAGS_ERROR_UI_FILTER_FOR_ERRORS |
- FLAGS_ERROR_UI_FLAGS_GENERATE_DATA |
- FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS,
- NULL);
-
- if( option == ERROR_CANCELLED )
- goto e1;
- }
-
- {
- DWORD dwFileSize = 4096;
- char* buffer[dwFileSize + 1];
-
- while(1)
- {
- DWORD dwBytesRead;
- BOOL bRead;
-
- bRead = InternetReadFile(
- hHttpFile,
- buffer,
- dwFileSize + 1,
- &dwBytesRead);
-
- if( dwBytesRead == 0 )
- break;
-
- if( !bRead )
- {
- MessageBox( window, "Report may or may not have been sent",
- "Error reading response", MB_OK|MB_ICONERROR);
- goto e1;
- }
- else
- buffer[dwBytesRead] = 0;
- }
-
- sent_report = 1;
- MessageBox( window, "Thank you, a developer will take a look and try to fix this bug.", "Report Sent!", MB_OK );
- }
-
-e1:InternetCloseHandle(hHttpFile);
-e2:InternetCloseHandle(hConnect);
-e3:InternetCloseHandle(hSession);
-e4:return;
-}
-
-LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
-{
- if (message == WM_CLOSE && hwnd == window) return OnWindowClose(hwnd, message, wParam, lParam);
- if( message == WM_COMMAND && HIWORD(wParam) == BN_CLICKED && (HWND)lParam == close_button )
- {
- exit(0);
- }
- if( message == WM_COMMAND && HIWORD(wParam) == BN_CLICKED && (HWND)lParam == send_button )
- {
- if( sent_report )
- {
- if( MessageBox( window,
- "The more times you send it the faster the bug gets fixed!",
- "Mail this report?", MB_YESNO|MB_APPLMODAL ) == IDYES )
- {
- MessageBox( window, "Thank you, a developer will take a look and try to fix this bug.", "Report Sent!", MB_OK );
- }
- }
- else
- {
- if( MessageBox( window,
- "Clicking yes confirms sending this error log straight to the developers (which we would much appreciate)",
- "Mail this report?", MB_YESNO|MB_APPLMODAL ) == IDYES )
- {
- send_report();
- }
- }
- }
- if( message == WM_COMMAND && HIWORD(wParam) == BN_CLICKED && (HWND)lParam == select_button )
- {
- SetFocus( textbox );
- Edit_SetSel( textbox, 0, 100000 );
- }
- return CallWindowProc(defWndProc, hwnd, message, wParam, lParam);
-}
-
-
-int main( int argc, const char *argv[] )
-{
- if( argc < 3 )
- {
- MessageBox( NULL, "Required parameters: PID and Crash path.",
- "Usage error", MB_OK|MB_ICONERROR );
- return -1;
-
- }
- vg_log_init();
-
- DWORD pid = (DWORD)strtoul( argv[1], NULL, 16 );
- HANDLE hGameProcess = OpenProcess( PROCESS_QUERY_INFORMATION, 0, pid );
- if( hGameProcess == NULL )
- goto we_crashed;
-
- while(1)
- {
- sleep(2);
- DWORD exit_code;
- if( GetExitCodeProcess( hGameProcess, &exit_code ) )
- {
- if( exit_code == STATUS_PENDING )
- continue;
- else if( exit_code == 0 )
- return 0;
- else
- goto we_crashed;
- }
- }
-
-we_crashed:
- report_text = vg_file_read( NULL, argv[2], &report_length, 1 );
- if( !report_text )
- {
- MessageBox( NULL, "Can't even open the crash text file. Something has gone seriously wrong! Contact a developer.",
- "Total epic failure!", MB_OK|MB_ICONERROR );
- return -1;
- }
-
- int x = 10;
- int y = 10;
- int w = 800;
- int h = 600;
- int sh = 32;
- int p = 8;
-
- RECT rect;
- rect.left = x;
- rect.top = y;
- rect.right = x + w;
- rect.bottom = y + h;
-
- UINT style = WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_MAXIMIZEBOX;
- AdjustWindowRectEx( &rect, style, 0, 0 );
-
- window = CreateWindowEx( 0, WC_DIALOG, "VG Error report", style,
- rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top,
- NULL, NULL, NULL, NULL );
-
- CreateWindowEx( 0, WC_STATIC, "Very sorry, VG Game engine has crashed. This is probably the fault of a developer!\n"
- "\n"
- "Here is some information about the crash. Optionally you can submit "
- "this log anonymously, straight to Mt.Zero Software."
- " This will help get the bug fixed for future players!",
- WS_CHILD | WS_VISIBLE, p, p, w-p*2, 80, window, NULL, NULL, NULL );
-
- textbox = CreateWindowEx( WS_EX_CLIENTEDGE, WC_EDIT, "textBox",
- WS_CHILD | WS_VSCROLL | WS_VISIBLE | ES_MULTILINE | ES_WANTRETURN | ES_READONLY,
- p, p+80+p, 800-p*2, 600-(p*2+sh+80+p), window, NULL, NULL, NULL );
-
- send_button = CreateWindowEx( 0, WC_BUTTON, "Send to Mt.Zero developers",
- WS_CHILD | WS_VISIBLE,
- 800-(200+p), 600-(p*2+sh)+p, 200, sh, window, NULL, NULL, NULL );
- close_button = CreateWindowEx( 0, WC_BUTTON, "Close",
- WS_CHILD | WS_VISIBLE,
- 800-(200+p)-(100+p), 600-(p*2+sh)+p, 100, sh, window, NULL, NULL, NULL );
- select_button = CreateWindowEx( 0, WC_BUTTON, "Select all",
- WS_CHILD | WS_VISIBLE,
- p, 600-(p*2+sh)+p, 100, sh, window, NULL, NULL, NULL );
-
- Edit_SetText( textbox, report_text );
- Edit_SetSel( textbox, 0, 0 );
-
- HFONT font = CreateFont( 16, 0, 0, 0, FW_NORMAL, 0, 0, 0, 0, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Consolas");
- SendMessage( textbox, WM_SETFONT, (WPARAM)font, 1 );
-
- defWndProc = (WNDPROC)SetWindowLongPtr(window, GWLP_WNDPROC, (LONG_PTR)WndProc);
-
- ShowWindow(window, SW_SHOW);
-
- MSG message = { 0 };
- while( GetMessage(&message, NULL, 0, 0) )
- DispatchMessage(&message);
- return (int)message.wParam;
-}
+++ /dev/null
-name program
-append foundation.kv
-append build/test.kv
+++ /dev/null
-#include "vg/vg.hconf"
-
-#define VG_IMPLEMENTATION
-#include "vg/vg.hconf"
-#undef VG_IMPLEMENTATION
+++ /dev/null
-#define VG_THIRDPARTY
-#include "vg/vg.hconf"
+++ /dev/null
-hc vg_build.h
-hc vg_build_utils_shader.h
-hc vg_m.h
-
-u32arr vg_pxfont.h
-u32arr vg_pxfont_thin.h
-
-vg_platform.h ??
-
-# vg_vorbis.h
-# vg_image.h
-# vg_depencies.c
-
-# vg_async.h
-# vg_async.c
-# vg_audio_dsp.h
-# vg_audio_dsp.c
-# vg_audio.h
-# vg_audio.c
-# vg_audio_synth_bird.h
-# vg_audio_synth_bird.c
-# vg_binstr.h
-# vg_binstr.c
-# vg_bvh.h
-# vg_bvh.c
-# vg_camera.h
-# vg_camera.c
-# vg_engine.c
-# vg_engine.h
-# vg_log.h
-# vg_log.c
-# vg_tex.c
-# vg_tex.h
-# vg_console.h
-# vg_console.c
-# vg_loader.h
-# vg_loader.c
-# vg_imgui.h
-# vg_imgui.c
-# vg_input.h
-# vg_input.c
-# vg_io.h
-# vg_io.c
-
-# vg_lines.h
-# vg_lines.c
-
-vg_mem.h
-vg_mem.c
-vg_mem_pool.h
-vg_mem_pool.c
-vg_mem_queue.h
-vg_mem_queue.c
-vg_msg.h
-vg_msg.c
-vg_opt.h
-vg_opt.c
-vg_perlin.h
-vg_perlin.c
-vg_string.h
-vg_string.c
-vg_profiler.h
-vg_profiler.c
-vg_rigidbody_collision.h
-vg_rigidbody_collision.c
-vg_rigidbody_constraints.h
-vg_rigidbody_constraints.c
-vg_rigidbody.h
-vg_rigidbody.c
-vg_rigidbody_view.h
-vg_rigidbody_view.c
-vg_shader.h
-vg_shader.c
-
-vg_steam.h
-vg_steam_auth.h
-vg_steam_friends.h
-vg_steam_http.h
-vg_steam_networking.h
-vg_steam_remote_storage.h
-vg_steam_ugc.h
-vg_steam_user_stats.h
-vg_steam_utils.h
-
-vg_tool.c
-vg_tool.h
+++ /dev/null
-/* Dependence (Standard)
- * ------------------------------------------------------------------------------------------------------------------ */
-
-#if !defined( VG_THIRDPARTY )
-# if defined(_WIN32)
-# include <windows.h>
-# include <dbghelp.h>
-# include <fileapi.h>
-# include <shlobj.h>
-# else
-# include <execinfo.h>
-# include <dirent.h>
-# include <sys/stat.h>
-# endif
-# include <fcntl.h>
-# include <unistd.h>
-
-# include <stdlib.h>
-# include <stdint.h> /* remove */
-# include <stdalign.h>
-# include <stdio.h> /* remove? eventually? */
-# include <stddef.h> /* remove? */
-# include <stdarg.h> /* remove */
-# include <string.h> /* remove? eventually? */
-# include <malloc.h>
-# include <time.h>
-# include <errno.h>
-# include <math.h>
-
-# if defined( VG_MULTITHREAD )
-# if !defined( VG_ENGINE )
-# include <pthread.h>
-# include <semaphore.h>
-# endif
-# endif
-#endif
-
-/* Dependence (Third party)
- * ------------------------------------------------------------------------------------------------------------------ */
-
-#if defined( VG_THIRDPARTY )
-# include "vg/submodules/anyascii/impl/c/anyascii.c"
-#else
-# include "vg/submodules/anyascii/impl/c/anyascii.h"
-#endif
-
-#if defined( VG_ENGINE ) || defined( VG_BUILD_TOOLS )
-# if defined( VG_THIRDPARTY )
-# define STB_IMAGE_IMPLEMENTATION
-# define STB_IMAGE_WRITE_IMPLEMENTATION
-# endif
-# define STBI_NO_THREAD_LOCALS
-# include "vg/submodules/stb/stb_image.h"
-# include "vg/submodules/stb/stb_image_write.h"
-#endif
-
-#if defined( VG_BUILD_TOOLS ) || defined( VG_ENGINE )
-# if defined( VG_THIRDPARTY )
-# define STB_INCLUDE_IMPLEMENTATION
-# endif
-# define STB_INCLUDE_LINE_GLSL
-# include "vg/submodules/stb/stb_include.h"
-#endif
-
-#if defined( VG_ENGINE )
-# define STB_VORBIS_MAX_CHANNELS 2
-# if defined( VG_THIRDPARTY )
-# undef STB_VORBIS_HEADER_ONLY
-# include "vg/submodules/stb/stb_vorbis.c"
-# include "vg/vg_vorbis.c"
-# undef L
-# undef R
-# undef C
-# else
-# define STB_VORBIS_HEADER_ONLY
-# include "vg/submodules/stb/stb_vorbis.c"
-# include "vg/vg_vorbis.h"
-# endif
-# define SDL_MAIN_HANDLED
-# include "vg/dep/sdl2-devel/include/SDL.h"
-# if defined( VG_THIRDPARTY )
-# include "vg/submodules/rax/rax.c"
-# else
-# include "vg/submodules/rax/rax.h"
-# endif
-# if defined( VG_THIRDPARTY )
-# include "vg/dep/glad/glad.c"
-# else
-# include "vg/dep/glad/glad.h"
-# endif
-#endif
-
-
-/* Tier 0
- * ------------------------------------------------------------------------------------------------------------------ */
-#if !defined( VG_THIRDPARTY )
-# include "vg/vg_platform.h"
-# include "vg/vg_mutex.h"
-# include "vg/vg_log.h"
-# include "vg/vg_mem.h"
-# include "vg/vg_mem_pool.h"
-# include "vg/vg_mem_queue.h"
-# include "vg/vg_string.h"
-
-/* Tier 1
- * ------------------------------------------------------------------------------------------------------------------ */
-# include "vg/vg_io.h"
-# include "vg/vg_kv.h"
-# if defined( VG_MSG_LEGACY ) || defined( VG_MSG_TO_KVS )
-# include "vg/vg_msg.h"
-# endif
-# if defined( VG_MULTITHREAD )
-# include "vg/vg_async2.h"
-# endif
-# if defined( VG_CONSOLE )
-# include "vg/vg_console.h"
-# endif
-# include "vg/vg_opt.h"
-# include "vg/vg_binstr.h"
-
-/* Maths
- * ------------------------------------------------------------------------------------------------------------------ */
-# if defined( VG_MATH )
-# include "vg/vg_m.h"
-# include "vg/vg_perlin.h"
-# endif
-
-/* Database
- * ------------------------------------------------------------------------------------------------------------------ */
-# if defined( VG_DB )
-# include "vg/vg_db.h"
-# endif
-
-/* Build tools
- * ------------------------------------------------------------------------------------------------------------------ */
-# if defined( VG_BUILD_TOOLS )
-# include "vg/vg_font.h"
-# include "vg/vg_build_font.h"
-# include "vg/vg_build.h"
-# include "vg/vg_build_utils_shader.h"
-# if !defined( VG_IMPLEMENTATION )
-# include "vg/vg_tex.h"
-# endif
-# endif
-
-/* Game Engine
- * ------------------------------------------------------------------------------------------------------------------ */
-# if defined( VG_ENGINE )
-# include "vg/vg_window.h"
-# include "vg/vg_shader.h"
-# include "src.generated/vg.shaders.h"
-# include "vg/vg_tex.h"
-# endif
-
-# if defined( VG_ENGINE ) || defined( VG_IMGUI )
-# include "vg/vg_font.h"
-# include "vg/vg_ui/imgui.h"
-# endif
-
-# if defined( VG_ENGINE )
-# include "vg/vg_ui/imgui_impl_opengl.h"
-# include "vg/vg_ui/filebrowser.h"
-# include "vg/vg_ui/console.h"
-# include "vg/vg_magi.h"
-# include "vg/vg_settings.h"
-
-# include "vg/vg_framebuffer.h"
-# include "vg/vg_camera.h"
-# include "vg/vg_loader.h"
-# include "vg/vg_render.h"
-
-# include "vg/vg_audio.h"
-# include "vg/vg_audio_dsp.h"
-# include "vg/vg_audio_synth_bird.h"
-
-# include "vg/vg_bvh.h"
-# include "vg/vg_rigidbody.h"
-# include "vg/vg_rigidbody_collision.h"
-# include "vg/vg_rigidbody_constraints.h"
-# include "vg/vg_rigidbody_view.h"
-
-# include "vg/vg_input.h"
-
-# include "vg/vg_profiler.h"
-# include "vg/vg_lines.h"
-# include "vg/vg_mem_view.h"
-
-# include "vg/vg_steam2.h"
-# include "vg/vg_engine.h"
-# if defined( VG_IMPLEMENTATION )
-# include "vg/laptop_gpu.c"
-# endif
-# endif
-#endif
+++ /dev/null
-struct _vg_async
-{
- i16 group_counts[ 16 ];
- vg_mutex count_lock;
-}
-_vg_async;
-
-struct vg_async_task
-{
- const c8 *alloc_debug_info;
- vg_async_fn fn;
- u32 buffer_size;
- u16 groups, unused0;
-
- union
- {
- u64 _force_8byte_align[];
- u8 buffer[];
- };
-};
-
-VG_API void _vg_async_init( void )
-{
- VG_ASSERT( VG_MUTEX_INIT( _vg_async.count_lock ) );
-}
-
-static void _vg_async_group_increment( u16 groups, i16 dir )
-{
- if( !groups )
- return;
-
- VG_MUTEX_LOCK( _vg_async.count_lock );
- for( u16 i=0; i<16; i ++ )
- {
- if( (groups >> i) & 0x1 )
- {
- _vg_async.group_counts[i] += dir;
-
- VG_ASSERT( _vg_async.group_counts[i] >= 0 );
- VG_ASSERT( _vg_async.group_counts[i] <= 2048 );
-
- vg_warn( "The task count for group %d has %s to %d\n",
- i, dir>0? "increased": "decreased", _vg_async.group_counts[i] );
- }
- }
- VG_MUTEX_UNLOCK( _vg_async.count_lock );
-}
-
-VG_API i16 _vg_async_group_count( u16 group )
-{
- VG_ASSERT( group );
- u32 index = __builtin_ctz( (u32)group );
-
- VG_MUTEX_LOCK( _vg_async.count_lock );
- i16 count = _vg_async.group_counts[ index ];
- VG_MUTEX_UNLOCK( _vg_async.count_lock );
-
- return count;
-}
-
-bool vg_init_async_queue( vg_async_queue *queue )
-{
- if( !VG_MUTEX_INIT( queue->lock ) )
- goto e0;
-
- if( !VG_MUTEX_INIT( queue->data_lock ) )
- goto e1;
-
- if( !VG_SEMAPHORE_INIT( queue->blocking_signal, 0 ) )
- goto e2;
-
- if( !VG_SEMAPHORE_INIT( queue->work_semaphore, 0 ) )
- goto e3;
-
- queue->queue.buffer = malloc( queue->buffer_size );
- queue->queue.size = queue->buffer_size;
- if( !queue->queue.buffer )
- goto e2;
-
- return 1;
-e3: VG_SEMAPHORE_FREE( queue->blocking_signal );
-e2: VG_MUTEX_FREE( queue->data_lock );
-e1: VG_MUTEX_FREE( queue->lock );
-e0: return 0;
-}
-
-void vg_free_async_queue( vg_async_queue *queue )
-{
- VG_MUTEX_FREE( queue->data_lock );
- VG_MUTEX_FREE( queue->lock );
- VG_SEMAPHORE_FREE( queue->work_semaphore );
- VG_SEMAPHORE_FREE( queue->blocking_signal );
-}
-
-bool vg_async_checksize( vg_async_queue *queue, u32 bytes )
-{
- u32 total_size = sizeof(vg_async_task) + bytes;
- return total_size <= queue->queue.size;
-}
-
-VG_TIER_1 vg_async_task *vg_create_task( vg_async_queue *queue, u32 buffer_size, u32 async_flags, const c8 *debug_info )
-{
- vg_queue *ring = &queue->queue;
- u32 total_size = sizeof(vg_async_task) + buffer_size;
- VG_ASSERT( total_size <= queue->queue.size );
- VG_MUTEX_LOCK( queue->data_lock );
- if( queue->allocating_task )
- {
- vg_fatal_error( "Overlapping async allocations. \n"
- " Previous allocation began at: %s\n"
- " Overlapping call at: %s\n", queue->allocating_task->alloc_debug_info, debug_info );
- }
- VG_MUTEX_LOCK( queue->lock );
-
- vg_async_task *task = vg_queue_alloc( ring, total_size );
- while( (async_flags & (VG_ASYNC_CRIT|VG_ASYNC_BLOCKING)) && !task )
- {
- VG_MUTEX_UNLOCK( queue->lock );
-
- if( async_flags & VG_ASYNC_CRIT )
- vg_fatal_error( "Too much tasks (critical)\n" );
-
- VG_SEMAPHORE_WAIT( queue->blocking_signal );
- VG_MUTEX_LOCK( queue->lock );
- task = vg_queue_alloc( ring, total_size );
- }
-
- if( task )
- {
- queue->allocating_task = task;
- task->alloc_debug_info = debug_info;
- task->fn = NULL;
- task->buffer_size = buffer_size;
- task->groups = _vg_async_context_get_groups();
- _vg_async_group_increment( task->groups, +1 );
- VG_MUTEX_UNLOCK( queue->lock );
- return task;
- }
- else
- {
- VG_MUTEX_UNLOCK( queue->lock );
- return NULL;
- }
-}
-
-void *vg_task_buffer( vg_async_queue *queue, vg_async_task *task )
-{
- VG_ASSERT( task );
- VG_ASSERT( queue->allocating_task == task );
- return task->buffer;
-}
-
-void vg_task_send( vg_async_queue *queue, vg_async_task *task, vg_async_fn fn )
-{
- VG_ASSERT( task );
- VG_ASSERT( queue->allocating_task == task );
-
- if( fn ) task->fn = fn;
- else _vg_async_group_increment( task->groups, -1 );
- queue->allocating_task = NULL;
-
- VG_MUTEX_UNLOCK( queue->data_lock );
- VG_SEMAPHORE_POST( queue->work_semaphore );
-}
-
-bool vg_async_has_work( vg_async_queue *queue )
-{
- return VG_SEMAPHORE_VALUE( queue->work_semaphore ) > 0? 1: 0;
-}
-
-bool vg_async_process_next_task( vg_async_queue *queue )
-{
- VG_SEMAPHORE_WAIT( queue->work_semaphore );
- VG_MUTEX_LOCK( queue->lock );
- if( queue->quit == k_async_quit_immediate )
- {
- VG_MUTEX_UNLOCK( queue->lock );
- return 0;
- }
- else if( queue->quit == k_async_quit_when_empty )
- {
- if( queue->queue.allocation_count == 0 )
- {
- VG_MUTEX_UNLOCK( queue->lock );
- return 0;
- }
- }
- vg_async_task *task = vg_queue_tail_data( &queue->queue );
- VG_MUTEX_UNLOCK( queue->lock );
-
- if( task )
- {
- /* task can be NULL if it was cancelled (so this is a NOP). Makes code easier if we do this instead of
- * reverting the queue to cancel. */
- if( task->fn )
- {
- vg_async_info info =
- {
- .buffer_size = task->buffer_size,
- };
-
- _vg_async_context_push_groups( task->groups, 0 );
- task->fn( (void *)task->buffer, &info );
- _vg_async_context_pop_groups();
- _vg_async_group_increment( task->groups, -1 );
- }
-
- VG_MUTEX_LOCK( queue->lock );
- vg_queue_pop( &queue->queue );
- VG_MUTEX_UNLOCK( queue->lock );
- }
-
- if( VG_SEMAPHORE_VALUE( queue->blocking_signal ) <= 0 )
- VG_SEMAPHORE_POST( queue->blocking_signal );
-
- return 1;
-}
-
-void vg_async_queue_end( vg_async_queue *queue, enum async_quit quit )
-{
- VG_MUTEX_LOCK( queue->lock );
- queue->quit = quit;
- VG_MUTEX_UNLOCK( queue->lock );
- VG_SEMAPHORE_POST( queue->work_semaphore );
-}
+++ /dev/null
-/* VG Async 2
- * Type: Library
- * Depends on: vg_platform, vg_mem, vg_mutex
- */
-
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_async2.c"
-#else
-
-typedef struct vg_async_queue vg_async_queue;
-typedef struct vg_async_task vg_async_task;
-typedef struct vg_async_data vg_async_data;
-typedef struct vg_async_info vg_async_info;
-
-typedef void (*vg_async_fn)( void *user, vg_async_info *info );
-
-struct vg_async_info
-{
- u32 buffer_size;
-};
-
-struct vg_async_queue
-{
- u32 buffer_size;
- u32 requested_bytes;
-
- vg_semaphore blocking_signal;
- vg_semaphore work_semaphore;
- vg_mutex lock;
- vg_mutex data_lock;
- vg_queue queue;
- vg_async_task *allocating_task;
-
- enum async_quit
- {
- k_async_no_quit,
- k_async_quit_immediate,
- k_async_quit_when_empty
- }
- quit;
-};
-
-VG_API void _vg_async_init( void );
-
-VG_API u32 _vg_async_push_grouping( u32 group_ids );
-VG_API void _vg_async_pop_grouping(void);
-VG_API i16 _vg_async_group_count( u16 group );
-
-bool vg_init_async_queue( vg_async_queue *queue );
-void vg_free_async_queue( vg_async_queue *queue );
-
-#define VG_ASYNC_CANCEL 0
-#define VG_ASYNC_OK 1
-
-/* If task would exceed queue capacity, crash the program */
-#define VG_ASYNC_CRIT 0x4
-
-/* If task currently would exceeed queue capacity, block until there is space */
-#define VG_ASYNC_BLOCKING 0x2
-
-/* If queue is full, immediately return and don't conduct task */
-#define VG_ASYNC_NONBLOCK 0x1
-
-/* Any asynchronous flag. NOTE: if you try to create a task that exceeds the queue capacity, regardless of which
- * strategy you chose, the program will crash. */
-#define VG_ASYNC (VG_ASYNC_CRIT|VG_ASYNC_BLOCKING|VG_ASYNC_NONBLOCK)
-
-/* Used for clarity in other functions that you DONT wan't it to run asynchronously */
-#define VG_SYNC 0x0
-
-#define VG_ASYNC_GROUP_OPENGL 0x1
-#define VG_ASYNC_GROUP_INIT 0x2
-#define VG_ASYNC_GROUP_RESERVED2 0x4
-#define VG_ASYNC_GROUP_RESERVED3 0x8
-#define VG_ASYNC_GROUP_RESERVED4 0x10
-#define VG_ASYNC_GROUP_RESERVED5 0x20
-#define VG_ASYNC_GROUP_RESERVED6 0x40
-#define VG_ASYNC_GROUP_RESERVED7 0x80
-
-#define VG_ASYNC_GROUP_CLIENT0 0x100
-#define VG_ASYNC_GROUP_CLIENT1 0x200
-#define VG_ASYNC_GROUP_CLIENT2 0x400
-#define VG_ASYNC_GROUP_CLIENT3 0x800
-#define VG_ASYNC_GROUP_CLIENT4 0x1000
-#define VG_ASYNC_GROUP_CLIENT5 0x2000
-#define VG_ASYNC_GROUP_CLIENT6 0x4000
-#define VG_ASYNC_GROUP_CLIENT7 0x8000
-
-VG_TIER_1 vg_async_task *vg_create_task( vg_async_queue *queue, u32 buffer_size, u32 async_flags, const c8 *debug_info );
-void *vg_task_buffer( vg_async_queue *queue, vg_async_task *task );
-void vg_task_send( vg_async_queue *queue, vg_async_task *task, vg_async_fn fn );
-
-void vg_async_queue_end( vg_async_queue *queue, enum async_quit quit );
-
-bool vg_async_has_work( vg_async_queue *queue );
-bool vg_async_process_next_task( vg_async_queue *queue );
-bool vg_async_checksize( vg_async_queue *queue, u32 bytes );
-
-#endif
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_audio.c"
-#else
-#define AUDIO_FRAME_SIZE 512
-#define AUDIO_MIX_FRAME_SIZE 256
-
-#define AUDIO_CHANNELS 32
-#define AUDIO_LFOS 8
-#define AUDIO_FILTERS 16
-#define AUDIO_FLAG_LOOP 0x1
-#define AUDIO_FLAG_NO_DOPPLER 0x2
-#define AUDIO_FLAG_SPACIAL_3D 0x4
-#define AUDIO_FLAG_AUTO_START 0x8
-#define AUDIO_FLAG_NO_DSP 0x10
-#define AUDIO_FLAG_WORLD 0x20
-#define AUDIO_FLAG_FORMAT 0x1E00
-#define AUDIO_FLAG_RELINQUISHED 0x2000
-#define AUDIO_FLAG_CUTSCENE 0x4000
-
-enum audio_format
-{
- k_audio_format_mono = 0x000u,
- k_audio_format_stereo = 0x200u,
- k_audio_format_vorbis = 0x400u,
- k_audio_format_none0 = 0x600u,
- k_audio_format_none1 = 0x800u,
- k_audio_format_none2 = 0xA00u,
- k_audio_format_none3 = 0xC00u,
- k_audio_format_none4 = 0xE00u,
-
- k_audio_format_bird = 0x1000u,
- k_audio_format_gen = 0x1200u,
- k_audio_format_none6 = 0x1400u,
- k_audio_format_none7 = 0x1600u,
- k_audio_format_none8 = 0x1800u,
- k_audio_format_none9 = 0x1A00u,
- k_audio_format_none10 = 0x1C00u,
- k_audio_format_none11 = 0x1E00u,
-};
-
-#define AUDIO_DECODE_SIZE (1024*256) /* 256 kb decoding buffers */
-
-#define AUDIO_VOLUME_100 500000000
-#define AUDIO_PAN_RIGHT_100 500000000
-#define AUDIO_PAN_LEFT_100 -500000000
-
-typedef struct audio_clip audio_clip;
-typedef struct audio_channel audio_channel;
-typedef struct audio_lfo audio_lfo;
-typedef u16 audio_channel_id;
-typedef u16 audio_channel_group; /* TODO: Create a generation system for this */
-
-enum channel_stage
-{
- k_channel_stage_none = 0,
- k_channel_stage_allocation,
- k_channel_stage_active,
- k_channel_stage_orphan
-};
-
-enum channel_activity
-{
- k_channel_activity_wake,
- k_channel_activity_playing,
- k_channel_activity_paused,
- k_channel_activity_end,
- k_channel_activity_error
-};
-
-struct audio_clip
-{
- union
- {
- const char *path;
- void *generative_function;
-
- u64 __serialized_pointer_width0;
- };
-
- u32 flags;
- u32 size;
-
- union
- {
- void *any_data;
- u64 __serialized_pointer_width1;
- };
-};
-
-struct audio_lfo
-{
- enum channel_stage stage;
-
- struct audio_lfo_controls
- {
- u32 period_in_samples;
- enum lfo_wave_type
- {
- k_lfo_triangle,
- k_lfo_square,
- k_lfo_saw,
- k_lfo_polynomial_bipolar
- }
- wave_type;
-
- f32 polynomial_coefficient, sqrt_polynomial_coefficient;
- u32 flags;
- }
- controls;
-
- struct audio_lfo_state
- {
- u32 time, last_period_in_samples, frame_reference_count, time_at_frame_start;
- struct audio_lfo_controls *controls;
- }
- state;
-};
-
-#define LFO_FLAG_PERIOD_CHANGED 0x1
-
-struct audio_channel
-{
- enum channel_stage stage;
-
- char ui_name[32];
- u32 ui_colour;
- i32 ui_volume, ui_pan;
- f32 ui_spacial_volume, ui_spacial_pan;
-
- enum channel_activity ui_activity;
- u16 group;
-
- audio_clip *clip;
-
- /* the controls structure is copied into the stack of the mixer function so it can work without locking. */
- struct audio_channel_controls
- {
- u32 flags;
-
- i32 volume_target, volume_slew_rate_per_sample;
- i32 pan_target, pan_slew_rate_per_sample;
- f32 sampling_rate_multiplier;
-
- audio_channel_id lfo_id;
- f32 lfo_attenuation_amount; /* multiply volume by (1 + value) */
-
- v4f spacial_falloff; /* xyz, range */
- bool pause;
- }
- controls;
-
- /* the channel state can be accessed when channel stage is in allocation, or by the mixer thread post allocation. */
- struct audio_channel_state
- {
- enum channel_activity activity;
-
- u32 cursor;
- i32 volume, pan,
- spacial_volume, spacial_pan;
- bool spacial_warm;
-
- union
- {
- struct synth_bird *bird;
- stb_vorbis *vorbis;
- }
- decoder_handle;
-
- u32 loaded_clip_length;
- }
- state;
-};
-
-struct vg_audio
-{
- SDL_AudioDeviceID sdl_output_device;
- vg_str device_choice; /* buffer is null? use default from OS */
-
- void *decoding_buffer;
-
- SDL_mutex *mutex;
- u32 samples_written_last_audio_frame;
-
- audio_lfo lfos[ AUDIO_LFOS ];
- audio_channel channels[ AUDIO_CHANNELS ];
- stb_vorbis_alloc vorbis_decoders[ AUDIO_CHANNELS ];
-
- bool inspector_open;
-
- struct audio_master_controls
- {
- v3f listener_position,
- listener_right_ear_direction,
- listener_velocity;
-
- bool dsp_enabled;
- i32 volume_target;
- }
- controls;
-
- struct audio_master_state
- {
- i32 volume, volume_at_frame_start;
- }
- state;
-
- f32 master_volume_ui;
- i32 dsp_enabled_ui;
-
- bool working;
-
- u32 profiler;
-}
-extern _vg_audio;
-
-VG_API void _vg_audio_register(void);
-VG_API void _vg_audio_init(void);
-
-void vg_audio_device_init(void);
-void vg_audio_begin(void);
-
-VG_TIER_2 bool vg_audio_clip_load( audio_clip *clip, vg_stack_allocator *stack );
-VG_TIER_2 u32 vg_audio_clip_loadn( audio_clip *arr, u32 count, vg_stack_allocator *stack );
-
-void vg_audio_lock(void);
-void vg_audio_unlock(void);
-void vg_audio_preupdate(void);
-
-/* channel API */
-audio_channel_id vg_audio_get_first_idle_channel(void);
-void vg_audio_set_channel_clip( audio_channel_id id, audio_clip *clip );
-void vg_audio_set_channel_group( audio_channel_id id, u16 group );
-u32 vg_audio_count_channels_in_group( u16 group );
-audio_channel_id vg_audio_get_first_active_channel_in_group( u16 group );
-void vg_audio_sidechain_lfo_to_channel( audio_channel_id id, audio_channel_id lfo_id, f32 amount );
-void vg_audio_set_channel_spacial_falloff( audio_channel_id id, v3f co, f32 range );
-void vg_audio_set_channel_volume( audio_channel_id id, f64 volume, bool instant );
-void vg_audio_set_channel_volume_slew_duration( audio_channel_id id, f64 length_seconds );
-void vg_audio_set_channel_pan( audio_channel_id id, f64 pan, bool instant );
-void vg_audio_set_channel_pan_slew_duration( audio_channel_id id, f64 length_seconds );
-void vg_audio_set_channel_sampling_rate( audio_channel_id id, f32 rate );
-void vg_audio_start_channel( audio_channel_id id );
-void vg_audio_add_channel_flags( audio_channel_id id, u32 flags );
-
-audio_channel_id vg_audio_get_first_idle_lfo(void);
-void vg_audio_set_lfo_polynomial_bipolar( audio_channel_id lfo_id, f32 coefficient );
-void vg_audio_set_lfo_frequency( audio_channel_id lfo_id, f32 freq );
-void vg_audio_start_lfo( audio_channel_id lfo_id );
-
-/* high level functions */
-void vg_audio_sync_ui_master_controls(void);
-audio_channel_id vg_audio_crossfade( audio_channel_id id, audio_clip *new_clip, f32 transition_seconds );
-void vg_audio_oneshot_3d( audio_clip *clip, v3f co, f32 range, f32 volume, u16 group, u32 flags );
-void vg_audio_oneshot( audio_clip *clip, f32 volume, f32 pan, u16 group, u32 flags );
-void vg_audio_set_channel_pause( audio_channel_id id, bool pause );
-
-/* half measures... Don't expect these functions to stay. */
-void vg_audio_fadeout_flagged_audio( u32 flag, f32 length );
-bool vg_audio_flagged_stopped( u32 flag );
-bool vg_audio_is_channel_using_clip( audio_channel_id id, audio_clip *clip );
-void vg_audio_set_flagged_pause( u32 flag, bool pause );
-#endif
+++ /dev/null
-struct vg_dsp vg_dsp;
-
-float *dsp_allocate( u32 samples )
-{
- samples = vg_align4( samples );
-
- if( vg_dsp.allocations + samples > (1024*1024)/4 )
- {
- vg_fatal_error( "Ran out of memory in the DSP buffer\n"
- " Request was %u samples\n", samples );
- }
-
- float *buf = &vg_dsp.buffer[ vg_dsp.allocations ];
- vg_dsp.allocations += samples;
-
- return buf;
-}
-
-
-/*
- * filters
- * ----------------------------------------------
- */
-
-f32 dsp_biquad_process( struct dsp_biquad *bq, f32 xn ){
- f32 yn = + bq->a0*xn + bq->a1*bq->xnz1 + bq->a2*bq->xnz2
- - bq->b1*bq->ynz1 - bq->b2*bq->ynz2;
- bq->xnz2 = bq->xnz1;
- bq->xnz1 = xn;
- bq->ynz2 = bq->ynz1;
- bq->ynz1 = yn;
- return yn + bq->offset;
-}
-
-void dsp_init_biquad_butterworth_lpf( struct dsp_biquad *bq, f32 fc ){
- f32 c = 1.0f/tanf(VG_PIf*fc / 44100.0f);
- bq->a0 = 1.0f / (1.0f + sqrtf(2.0f)*c + powf(c, 2.0f) );
- bq->a1 = 2.0f * bq->a0;
- bq->a2 = bq->a0;
- bq->b1 = 2.0f * bq->a0*(1.0f - powf(c, 2.0f));
- bq->b2 = bq->a0 * (1.0f - sqrtf(2.0f)*c + powf(c, 2.0f) );
-}
-
-void dsp_read_delay( struct dsp_delay *delay, float *s, u32 t ){
- u32 index = delay->cur+t;
-
- if( index >= delay->length )
- index -= delay->length;
-
- *s = delay->buffer[ index ];
-}
-
-void dsp_write_delay( struct dsp_delay *delay, float *s )
-{
- u32 index = delay->cur;
- delay->buffer[ index ] = *s;
-
- delay->cur ++;
-
- if( delay->cur >= delay->length )
- delay->cur = 0;
-}
-
-void dsp_init_delay( struct dsp_delay *delay, float length )
-{
- delay->length = 44100.0f * length;
- delay->cur = 0;
- delay->buffer = dsp_allocate( delay->length );
-
- for( int i=0; i<delay->length; i++ )
- delay->buffer[i] = 0.0f;
-}
-
-void dsp_update_lpf( struct dsp_lpf *lpf, float freq )
-{
- lpf->exponent = 1.0f-expf( -(1.0f/44100.0f) * 2.0f * VG_PIf * freq );
-}
-
-void dsp_init_lpf( struct dsp_lpf *lpf, float freq )
-{
- lpf->buffer = dsp_allocate( 4 );
- lpf->buffer[0] = 0.0f;
- dsp_update_lpf( lpf, freq );
-}
-
-void dsp_write_lpf( struct dsp_lpf *lpf, float *s )
-{
- float diff = *s - lpf->buffer[0];
- lpf->buffer[0] += diff * lpf->exponent;
-}
-
-void dsp_read_lpf( struct dsp_lpf *lpf, float *s )
-{
- *s = lpf->buffer[0];
-}
-
-void dsp_init_schroeder( struct dsp_schroeder *sch, float length, float gain )
-{
- dsp_init_delay( &sch->M, length );
- sch->gain = gain;
-}
-
-void dsp_process_schroeder( struct dsp_schroeder *sch,
- float *input, float *output )
-{
- float dry = *input;
-
- float delay_output;
- dsp_read_delay( &sch->M, &delay_output, 1 );
-
- float feedback_attenuated = delay_output * sch->gain,
- input_feedback_sum = dry + feedback_attenuated;
-
- dsp_write_delay( &sch->M, &input_feedback_sum );
-
- *output = delay_output - input_feedback_sum*sch->gain;
-}
-
-/* temporary global design */
-static struct dsp_lpf __lpf_mud_free;
-static struct dsp_delay __echos[8];
-
-#ifdef VG_ECHO_LPF_BUTTERWORTH
-static struct dsp_biquad __echos_lpf[8];
-#else
-static struct dsp_lpf __echos_lpf[8];
-#endif
-static struct dsp_schroeder __diffusion_chain[8];
-
-VG_API void _vg_dsp_init(void)
-{
- vg_rand_seed( &vg_dsp.rand, 461 );
- vg_dsp.buffer = vg_stack_allocate( NULL, VG_MB(1), 8, "Audio DSP Buffer" );
-
- /* temporary global design */
- dsp_init_lpf( &__lpf_mud_free, 125.0f );
-
- float sizes[] =
- { 2.0f, 4.0f, 8.0f, 16.0f, 32.0f, 64.0f, 128.0f, 256.0f };
-
- float variance = 0.1f;
-
- for( int i=0; i<8; i++ ){
- float reflection_time = ((sizes[i])/343.0f) * 1000.0f;
-
- float var = 1.0f + (vg_randf64(&vg_dsp.rand)*2.0f - 1.0f) * variance,
- total = reflection_time * var;
-
- dsp_init_delay( &__echos[i], total / 1000.0f );
-
- float freq = vg_lerpf( 800.0f, 350.0f, sizes[i] / 256.0f );
-
-#ifdef VG_ECHO_LPF_BUTTERWORTH
- dsp_init_biquad_butterworth_lpf( &__echos_lpf[i], freq );
-#else
- dsp_init_lpf( &__echos_lpf[i], freq );
-#endif
- }
-
- float diffusions[] = { 187.0f, 159.0f, 143.0f, 121.0f,
- 79.0f, 57.0f, 27.0f, 11.0f };
-
- for( int i=0; i<8; i++ ){
- dsp_init_schroeder( __diffusion_chain+i, diffusions[i]/1000.0f, 0.7f );
- }
-}
-
-void vg_dsp_process( float *stereo_in, float *stereo_out )
-{
- float in_total = (stereo_in[0]+stereo_in[1])*0.5f;
- float recieved = 0.0f;
-
- for( int i=0; i<8; i++ ){
- f32 echo;
- dsp_read_delay( __echos+i, &echo, 1 );
-
-#ifdef VG_ECHO_LPF_BUTTERWORTH
- echo = dsp_biquad_process( __echos_lpf+i, echo );
-#else
- dsp_write_lpf( __echos_lpf+i, &echo );
- dsp_read_lpf( __echos_lpf+i, &echo );
-#endif
-
- recieved += echo * vg_dsp.echo_tunings[i]*0.98;
- }
-
- float diffused = recieved;
-
- for( int i=0; i<8; i++ ){
- dsp_process_schroeder( __diffusion_chain+i, &diffused, &diffused );
- }
-
- float diffuse_mix = vg_dsp.reverb_wet_mix;
- diffuse_mix = vg_lerpf( recieved, diffused, diffuse_mix );
- float total = in_total + diffuse_mix;
-
- float low_mud;
- dsp_write_lpf( &__lpf_mud_free, &total );
- dsp_read_lpf( &__lpf_mud_free, &low_mud );
-
- total -= low_mud;
-
- for( int i=0; i<8; i++ )
- dsp_write_delay( __echos+i, &total );
-
- stereo_out[0] = stereo_in[0]*vg_dsp.reverb_dry_mix;
- stereo_out[1] = stereo_in[1]*vg_dsp.reverb_dry_mix;
- stereo_out[0] += diffuse_mix*2.0f*vg_dsp.reverb_wet_mix;
- stereo_out[1] += diffuse_mix*2.0f*vg_dsp.reverb_wet_mix;
-}
-
-void dsp_update_tunings(void)
-{
- float sizes[] =
- { 2.0f, 4.0f, 8.0f, 16.0f, 32.0f, 64.0f, 128.0f, 256.0f };
- float volumes[] =
- { 0.2f, 0.3f, 0.5f, 0.7f, 0.8f, 0.9f, 1.0f, 1.0f };
-
- float avg_distance = 0.0f;
-
- for( int i=0; i<8; i++ )
- vg_dsp.echo_tunings[i] = 0.5f;
-
- for( int j=0; j<14; j++ ){
- float d = vg_dsp.echo_distances[j];
-
- for( int i=0; i<7; i++ ){
- if( d < sizes[i+1] ){
- float range = sizes[i+1]-sizes[i];
- float t = vg_clampf( (d - sizes[i])/range, 0.0f, 1.0f );
-
- vg_dsp.echo_tunings[i ] += 1.0f-t;
- vg_dsp.echo_tunings[i+1] += t;
-
- break;
- }
- }
-
- avg_distance += d;
- }
- avg_distance /= 14.0f;
-
-
- vg_dsp.reverb_wet_mix =1.0f-vg_clampf((avg_distance-30.0f)/200.0f,0.0f,1.0f);
- vg_dsp.reverb_dry_mix =1.0f-vg_dsp.reverb_wet_mix*0.4f;
-
- float total = 0.0f;
- for( int i=0; i<8; i++ )
- total += vg_dsp.echo_tunings[i];
-
- if( total > 0.0f ){
- float inverse = 1.0f/total;
-
- for( int i=0;i<8; i++ ){
- vg_dsp.echo_tunings[i] *= inverse;
- }
- }
-
- for( int i=0; i<8; i++ ){
- float freq = vg_lerpf( 200.0f, 500.0f, vg_dsp.echo_tunings[i] );
-
-#ifdef VG_ECHO_LPF_BUTTERWORTH
- dsp_init_biquad_butterworth_lpf( &__echos_lpf[i], freq );
-#else
- dsp_update_lpf( &__echos_lpf[i], freq );
-#endif
- }
-
- for( int i=0;i<8; i++ ){
- vg_dsp.echo_tunings[i] *= volumes[i];
- }
-}
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_audio_dsp.c"
-#else
-
-//#define VG_ECHO_LPF_BUTTERWORTH
-
-struct vg_dsp
-{
- float *buffer;
- u32 allocations;
-
- float echo_distances[14],
- echo_tunings[8],
- reverb_wet_mix,
- reverb_dry_mix;
-
- vg_rand rand;
-}
-extern vg_dsp;
-
-struct dsp_delay
-{
- u32 length, cur;
- float *buffer;
-};
-
-struct dsp_lpf
-{
- float exponent;
- float *buffer;
-};
-
-struct dsp_schroeder
-{
- struct dsp_delay M;
- float gain;
-};
-
-struct dsp_biquad
-{
- f32 a0, a1, a2, b1, b2, c0, d0,
- xnz1, xnz2, ynz1, ynz2, offset;
-};
-
-VG_API void _vg_dsp_init(void);
-void dsp_update_tunings(void);
-void vg_dsp_process( float *stereo_in, float *stereo_out );
-
-f32 dsp_biquad_process( struct dsp_biquad *bq, f32 xn );
-void dsp_init_biquad_butterworth_lpf( struct dsp_biquad *bq, f32 fc );
-void dsp_read_delay( struct dsp_delay *delay, float *s, u32 t );
-void dsp_write_delay( struct dsp_delay *delay, float *s );
-void dsp_init_delay( struct dsp_delay *delay, float length );
-void dsp_update_lpf( struct dsp_lpf *lpf, float freq );
-void dsp_init_lpf( struct dsp_lpf *lpf, float freq );
-void dsp_write_lpf( struct dsp_lpf *lpf, float *s );
-void dsp_read_lpf( struct dsp_lpf *lpf, float *s );
-void dsp_init_schroeder( struct dsp_schroeder *sch, float length, float gain );
-void dsp_process_schroeder( struct dsp_schroeder *sch, float *input, float *output );
-
-#endif
+++ /dev/null
-#define DEFAULT_VOL 1.0f,0.5f,0.2f,0.125f
-#define DEFAULT_TONES { {1,1}, {6,5}, {8,7}, {13,12} }
-#define DEFAULT_RISE 0.00090702947f
-#define DEFAULT_FALL 0.00226757369f
-
-static struct synth_bird_settings synth_bird__default_settings =
-{
- .tones = DEFAULT_TONES,
- .type = k_bird_lfo_sine_approx,
- .adsr_rise = DEFAULT_RISE,
- .adsr_fall = DEFAULT_FALL
-};
-
-static struct synth_bird_signature synth_bird__warbling_vireo[] =
-{
- /* timing fundemental volumes lfo hz,depth */
- {0.13,0.10, 4000,100,100,0, DEFAULT_VOL, 60,200 },
- {0.10,0.05, 4200,-500,1700,0, DEFAULT_VOL, 60,96 },
- {0.10,0.00, 2400,-1200,1000,1700, DEFAULT_VOL, 60,96 },
- {0.06,0.04, 3100,200,-10,-1100, DEFAULT_VOL, 60,90 },
- {0.13,0.07, 4600,-2000,0,1300, DEFAULT_VOL, 60,10 },
- {0.05,0.00, 2700,-300,700,800, DEFAULT_VOL, 60,10 },
- {0.09,0.07, 3600,-300,0,0, DEFAULT_VOL, 60,20 },
- {0.05,0.07, 4800,1240,300,0, DEFAULT_VOL, 60,20 },
- {0.08,0.02, 2700,-800,150,1000, DEFAULT_VOL, 60,160 },
- {0.12,0.08, 2700,-800,150,1000, DEFAULT_VOL, 60,160 },
- {0.10,0.04, 6300,-100,-3200,1000, DEFAULT_VOL, 60,100 },
- {0.16,0.10, 4260,-200,300,1100, DEFAULT_VOL, 60,20 }
-};
-
-static struct synth_bird_signature synth_bird__pied_monarch[] =
-{
- /* timing fundemental volumes lfo hz,depth */
- {0.18,0.13, 2200,700,-300,0, 0.6,0.05,0,0, 60,0 },
- {0.17,0.12, 2200,700,-300,0, 0.8,0.05,0,0, 60,0 },
- {0.16,0.11, 2200,700,-300,0, 0.9,0.05,0,0, 60,0 },
- {0.14,0.09, 2200,700,-300,0, 1.0,0.05,0,0, 60,0 },
- {0.12,0.07, 2200,700,-300,0, 1.0,0.05,0,0, 60,0 },
- {0.11,0.06, 2200,700,-300,0, 1.0,0.05,0,0, 60,0 },
- {0.10,0.05, 2200,700,-300,0, 1.0,0.05,0,0, 60,0 },
- {0.10,0.05, 2200,700,-300,0, 1.0,0.05,0,0, 60,0 },
- {0.10,0.05, 2200,700,-300,0, 1.0,0.05,0,0, 60,0 },
- {0.10,0.05, 2200,700,-300,0, 1.0,0.05,0,0, 60,0 },
- {0.10,0.05, 2200,700,-300,0, 1.0,0.05,0,0, 60,0 },
- {0.10,0.10, 2200,700,-300,0, 1.0,0.05,0,0, 60,0 }
-};
-
-static struct synth_bird_signature synth_bird__bridled_honeyeater[] =
-{
- /* timing fundemental volumes lfo hz,depth */
- {0.10,0.10, 2000,-1000,600,0, 1.00,0.00,0.00,0.00, 30,60},
- {0.10,0.10, 4000,0,-200,-200, 0.80,0.25,0.25,0.25, 30,60},
- {0.06,0.01, 4000,0,-700,-800, 0.90,0.10,0.00,0.00, 60,20},
- {0.07,0.01, 3950,0,-700,-800, 0.90,0.10,0.00,0.00, 60,20},
- {0.08,0.01, 3900,0,-700,-800, 0.90,0.10,0.00,0.00, 60,20},
- {0.09,0.01, 3850,0,-700,-800, 0.90,0.10,0.00,0.00, 60,20},
- {0.10,0.02, 3800,0,-700,-800, 0.90,0.20,0.10,0.00, 60,20},
- {0.11,0.05, 3750,0,-700,-800, 0.90,0.40,0.20,0.00, 60,20},
- {0.12,0.20, 3700,0,-700,-800, 0.30,0.10,0.00,0.00, 60,20},
- {0.10,0.10, 2600,1300,600,0, 0.97,0.03,0.00,0.00, 60,20},
-};
-
-static struct synth_bird_signature synth_bird__cricket[] =
-{
- /* timing fundemental volumes lfo hz, depth */
- {0.10,0.15, 5000,0,0,100, 0.25,0.25,0.25,0.25, 40,200},
- {0.11,0.14, 5000,0,0,100, 0.25,0.25,0.25,0.25, 40,200},
- {0.13,0.15, 5000,0,0,100, 0.25,0.25,0.25,0.25, 40,200},
- {0.09,0.16, 5000,0,0,100, 0.25,0.25,0.25,0.25, 40,200},
- {0.10,0.12, 5000,0,0,100, 0.25,0.25,0.25,0.25, 40,200},
- {0.10,0.15, 5000,0,0,100, 0.25,0.25,0.25,0.25, 40,200},
- {0.11,0.14, 5000,0,0,100, 0.25,0.25,0.25,0.25, 40,200},
- {0.13,0.15, 5000,0,0,100, 0.25,0.25,0.25,0.25, 40,200},
- {0.09,0.16, 5000,0,0,100, 0.25,0.25,0.25,0.25, 40,200},
- {0.10,0.12, 5000,0,0,100, 0.25,0.25,0.25,0.25, 40,200}
-};
-
-static struct synth_bird_signature synth_bird__gray_shrikethrush[] =
-{
- /* timing fundemental volumes lfo hz, depth */
- { 0.13,0.1, 2600,-200,-100,200, 0.9,0.1,0.05,0.001, 60,10 }
-};
-
-static struct synth_bird_signature synth_bird__boobook[] =
-{
- /* timing fundemental volumes lfo hz, depth */
- {0.3,0.14, 700,0,-100,100, 0.9,0.14,0.0,0.2, 30,18},
- {0.3,1.20, 630,0,-100,100, 0.9,0.00,0.3,0.0, 30,18}
-};
-
-static struct synth_bird_signature synth_bird__shrike_tit[] =
-{
- /* timing fundemental volumes lfo hz, depth */
- {0.6,1.4, 2300,-300,-100,100, 1.0,0.14,0.0,0.1, 60,5 }
-};
-
-/* sine functions over the range [0, 44100] : [-pi, pi].
- * Not accurate! */
-
-static float sine_1second_1( int o )
-{
- float s = (o<(BIRD_SAMPLE_RATE/2))?-1.0f:1.0f;
- float t = ((float)o*(1.0f/(float)(BIRD_SAMPLE_RATE/2)))-1.0f - s*0.5f;
- float t2 = t*t;
- float t4 = t2*t2;
- return s*(5.0f*t2-4.0f*t4-1.0f);
-}
-
-static void sine_1second_4( int o[4], float v[4] )
-{
- float s[4],t[4],t2[4],t4[4];
- s[0] = (o[0]<(BIRD_SAMPLE_RATE/2))?-1.0f:1.0f;
- s[1] = (o[1]<(BIRD_SAMPLE_RATE/2))?-1.0f:1.0f;
- s[2] = (o[2]<(BIRD_SAMPLE_RATE/2))?-1.0f:1.0f;
- s[3] = (o[3]<(BIRD_SAMPLE_RATE/2))?-1.0f:1.0f;
-
- t[0] = ((float)o[0]*(1.0f/(float)(BIRD_SAMPLE_RATE/2)))-1.0f - s[0]*0.5f;
- t[1] = ((float)o[1]*(1.0f/(float)(BIRD_SAMPLE_RATE/2)))-1.0f - s[1]*0.5f;
- t[2] = ((float)o[2]*(1.0f/(float)(BIRD_SAMPLE_RATE/2)))-1.0f - s[2]*0.5f;
- t[3] = ((float)o[3]*(1.0f/(float)(BIRD_SAMPLE_RATE/2)))-1.0f - s[3]*0.5f;
-
- t2[0] = t[0]*t[0];
- t2[1] = t[1]*t[1];
- t2[2] = t[2]*t[2];
- t2[3] = t[3]*t[3];
-
- t4[0] = t2[0]*t2[0];
- t4[1] = t2[1]*t2[1];
- t4[2] = t2[2]*t2[2];
- t4[3] = t2[3]*t2[3];
-
- v[0] = s[0]*(5.0f*t2[0]-4.0f*t4[0]-1.0f);
- v[1] = s[1]*(5.0f*t2[1]-4.0f*t4[1]-1.0f);
- v[2] = s[2]*(5.0f*t2[2]-4.0f*t4[2]-1.0f);
- v[3] = s[3]*(5.0f*t2[3]-4.0f*t4[3]-1.0f);
-}
-
-static float saw_1second_1( int o )
-{
- float t = ((float)o*(1.0f/(float)(BIRD_SAMPLE_RATE/2)))-1.0f,
- tt = t*t,
- ttt = tt*t;
-
- return -2.5f*ttt+2.5f*t;
-}
-
-u32 synth_bird_get_length_in_samples( struct synth_bird *bird )
-{
- u32 total = 0;
-
- for( int i=0; i<bird->settings->pattern_length; i ++ )
- {
- struct synth_bird_signature *sig = &bird->settings->pattern[i];
- u32 l = sig->length * (float)BIRD_SAMPLE_RATE,
- p = sig->pause * (float)BIRD_SAMPLE_RATE;
-
- total += l+p;
- }
-
- return total;
-}
-
-void synth_bird_reset( struct synth_bird *bird )
-{
- bird->rt.osc_main[0] = 0;
- bird->rt.osc_main[1] = 0;
- bird->rt.osc_main[2] = 0;
- bird->rt.osc_main[3] = 0;
- bird->rt.osc_lfo = 0;
-
- bird->rt.volume[0] = 0.0f;
- bird->rt.volume[1] = 0.0f;
- bird->rt.volume[2] = 0.0f;
- bird->rt.volume[3] = 0.0f;
-
- bird->rt.fundamental = 0.0f;
- bird->rt.x = 0;
- bird->rt.length = bird->settings->pattern[0].length * (float)BIRD_SAMPLE_RATE;
- bird->rt.gate = 1;
- bird->rt.adsr = 0;
- bird->rt.frame = 0;
- bird->rt.lfo_hz = 0;
- bird->rt.fm_depth = 0.0f;
-
- bird->rt.adsr_rise = bird->settings->adsr_rise * (float)BIRD_SAMPLE_RATE;
- bird->rt.adsr_fall = bird->settings->adsr_fall * (float)BIRD_SAMPLE_RATE;
-}
-
-static u32 synth_bird_save_size( struct synth_bird *bird )
-{
- return sizeof(struct synth_bird_signature) * bird->settings->pattern_length +
- sizeof(struct synth_bird_settings);
-}
-
-static void synth_bird_save( struct synth_bird *bird, void *txt )
-{
- void *src = &bird->settings;
- vg_bin_str( src, txt, synth_bird_save_size( bird ) );
-}
-
-#if 0
-static void synth_bird_load( struct synth_bird *bird,
- const char *txt, u32 length )
-{
- vg_str_bin( txt, &bird->settings, length );
- synth_bird_reset( bird );
-}
-
-/* expects a null terminated string */
-static u32 synth_bird_memory_requirement( u32 string_length )
-{
- return (string_length/2) +
- sizeof(struct synth_bird) - sizeof(struct synth_bird_settings);
-}
-#endif
-
-#ifdef SYNTH_BIRD_STDLIB
-#include "stdlib.h"
-#include "string.h"
-
-static struct synth_bird *synth_bird_create(
- struct synth_bird_settings *settings,
- struct synth_bird_signature *pattern,
- u32 pattern_length )
-{
- u32 pattern_size = sizeof( struct synth_bird_signature ) * pattern_length;
- u32 total_size = sizeof( struct synth_bird ) + pattern_size;
- struct synth_bird *bird = malloc( total_size );
-
- bird->settings = *settings;
-
- memcpy( bird->settings->pattern, pattern, pattern_size );
- bird->settings->pattern_length = pattern_length;
-
- synth_bird_reset( bird );
- return bird;
-}
-
-#endif
-
-static void synth_bird_think( struct synth_bird *bird )
-{
- struct synth_bird_signature *sig = &bird->settings->pattern[ bird->rt.frame ];
-
- bird->rt.x ++;
- if( bird->rt.x >= bird->rt.length )
- {
- if( bird->rt.gate && (sig->pause != 0.0f) )
- {
- bird->rt.gate = 0;
- bird->rt.length = sig->pause * (float)BIRD_SAMPLE_RATE;
- }
- else
- {
- bird->rt.frame ++;
-
- if( bird->rt.frame >= bird->settings->pattern_length )
- bird->rt.frame = 0;
-
- sig = &bird->settings->pattern[ bird->rt.frame ];
-
- bird->rt.gate = 1;
- bird->rt.length = sig->length * (float)BIRD_SAMPLE_RATE;
- }
-
- bird->rt.x = 0;
- }
-
- if( bird->rt.gate )
- {
- bird->rt.adsr += bird->rt.adsr_rise;
- if( bird->rt.adsr > BIRD_SAMPLE_RATE )
- bird->rt.adsr = BIRD_SAMPLE_RATE;
- }
- else
- {
- bird->rt.adsr -= bird->rt.adsr_fall;
- if( bird->rt.adsr < 0 )
- bird->rt.adsr = 0;
- }
-
- if( bird->rt.gate )
- {
- float l = (float)bird->rt.length,
- t = ((float)bird->rt.x * (1.0f/l))*2.0f - 1.0f,
- tt = t*t,
- ttt = tt*t;
-
- bird->rt.fundamental = sig->x0 + t*sig->x1 + tt*sig->x2 + ttt*sig->x3;
- }
-
- float vol = (float)bird->rt.adsr * (1.0f/(float)BIRD_SAMPLE_RATE);
-
- bird->rt.fm_depth = sig->fm;
- bird->rt.lfo_hz = sig->lfo_hz;
- bird->rt.volume[0] = sig->v0 * vol;
- bird->rt.volume[1] = sig->v1 * vol;
- bird->rt.volume[2] = sig->v2 * vol;
- bird->rt.volume[3] = sig->v3 * vol;
-}
-
-static inline void int_add_mod( int *a, int const b )
-{
- *a += b;
-
- if( *a > BIRD_SAMPLE_RATE )
- *a -= BIRD_SAMPLE_RATE;
-}
-
-void synth_bird_generate_samples( struct synth_bird *bird,
- float *stereo_buffer, int samples )
-{
- for( int _=0; _<samples; _++ )
- {
- synth_bird_think( bird );
-
- int_add_mod( &bird->rt.osc_lfo, bird->rt.lfo_hz );
- float fm = sine_1second_1( bird->rt.osc_lfo ) * bird->rt.fm_depth;
-
- int freq = bird->rt.fundamental + fm;
- int hz[4] =
- {
- (freq * bird->settings->tones[0][0]) / bird->settings->tones[0][1],
- (freq * bird->settings->tones[1][0]) / bird->settings->tones[1][1],
- (freq * bird->settings->tones[2][0]) / bird->settings->tones[2][1],
- (freq * bird->settings->tones[3][0]) / bird->settings->tones[3][1],
- };
-
- int_add_mod( bird->rt.osc_main + 0, hz[0] );
- int_add_mod( bird->rt.osc_main + 1, hz[1] );
- int_add_mod( bird->rt.osc_main + 2, hz[2] );
- int_add_mod( bird->rt.osc_main + 3, hz[3] );
-
- float v[4];
- sine_1second_4( bird->rt.osc_main, v );
-
- float s = v[0] * bird->rt.volume[0] +
- v[1] * bird->rt.volume[1] +
- v[2] * bird->rt.volume[2] +
- v[3] * bird->rt.volume[3] ;
-
- stereo_buffer[ _*2+0 ] = s;
- stereo_buffer[ _*2+1 ] = s;
- }
-}
-
-#ifdef SYNTH_BIRD_STDLIB
-#define KNRM "\x1B[00m"
-#define KRED "\x1B[31m"
-#define KGRN "\x1B[32m"
-#define KYEL "\x1B[33m"
-#define KBLU "\x1B[34m"
-#define KMAG "\x1B[35m"
-#define KCYN "\x1B[36m"
-#define KWHT "\x1B[37m"
-
-#define LOG_BAR0 " . |"
-#define LOG_BAR1 "-------+-------+-------+-------+"
-#define LOG_BAR2 " "
-
-static void synth_bird_log_pattern( struct synth_bird *bird )
-{
- synth_bird_reset( bird );
-
- char output[][400]= {
-KNRM "9k-" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0,
-KNRM " -" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0,
-KNRM "8k-" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0,
-KNRM " -" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0,
-KNRM "7k-" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0,
-KNRM " -" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0,
-KMAG "6k-" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0,
-KMAG " -" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0,
-KCYN "5k-" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0,
-KCYN " -" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0,
-KBLU "4k-" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0,
-KBLU " -" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0,
-KGRN "3k-" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0,
-KGRN " -" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0,
-KYEL "2k-" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0,
-KYEL " -" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0,
-KRED "1k-" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0,
-KRED " -" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0,
-KWHT " +" LOG_BAR1 LOG_BAR1 LOG_BAR1 LOG_BAR1 LOG_BAR1
-KWHT " 0.0s"LOG_BAR2"0.5s"LOG_BAR2"1.0s"LOG_BAR2"1.5s"LOG_BAR2"2.0s"LOG_BAR2
- };
-
- for( int i=0; i<190*8; i++ )
- {
- for( int j=0; j<BIRD_SAMPLE_RATE/(32*8*2); j++ )
- synth_bird_think( bird );
-
- float hz = bird->rt.fundamental / 500.0f;
- int j = hz;
-
- if( j < 0 ) j = 0;
- if( j > 18 ) j = 18;
- j = 18-j;
-
- float level = bird->rt.adsr;
- level *= (1.0f/(float)BIRD_SAMPLE_RATE);
-
- int ch = level*3.0f;
-
- if( ch )
- output[j][(i/8)+7] = " *###"[ch];
- }
-
- for( int i=0; i<20; i++ )
- {
- puts( output[i] );
- }
-}
-#endif
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_audio_synth_bird.c"
-#else
-
-#ifndef BIRD_SAMPLE_RATE
- #define BIRD_SAMPLE_RATE 44100
-#endif
-
-struct synth_bird_signature
-{
- float length, pause, /* timings in seconds */
- x0,x1,x2,x3, /* polynomial coefficients for the fundemental */
- v0,v1,v2,v3; /* volume of each oscillator */
-
- int lfo_hz; /* LFO frequency (30-60hz) */
- float fm; /* LFO modulation depth (+/- hz) */
-};
-
-struct synth_bird
-{
- struct
- {
- int osc_main[4],
- osc_lfo;
- float volume[4];
-
- float fundamental;
- int x, length, /* position/length of signature in samples */
- gate, adsr, /* adsr ranges 0->44100 */
- frame; /* current frame of the pattern */
-
- int lfo_hz;
- float fm_depth;
-
- int adsr_rise,
- adsr_fall;
- }
- rt;
-
- struct synth_bird_settings
- {
- int tones[4][2]; /* fraction of the fundemental tone
- for each oscillator */
- float adsr_rise, /* rise/fall in seconds */
- adsr_fall;
-
- enum bird_lfo_wave{
- k_bird_lfo_sine_approx,
- k_bird_lfo_bipolar_poly
- }
- type;
-
- int pattern_length;
- struct synth_bird_signature pattern[];
- }
- *settings;
-};
-
-void synth_bird_reset( struct synth_bird *bird );
-u32 synth_bird_get_length_in_samples( struct synth_bird *bird );
-void synth_bird_generate_samples( struct synth_bird *bird, float *stereo_buffer, int samples );
-
-#endif
+++ /dev/null
-void vg_str_bin( const void *txt, void *bin, int size )
-{
- const u8 *src = txt;
- u8 *dst = bin;
-
- for( u32 i=0; i<size/2; i++ ){
- dst[i] = (src[i*2+0]-VG_BINSTR_BASECHAR);
- dst[i] |= (src[i*2+1]-VG_BINSTR_BASECHAR)<<4u;
- }
-}
-
-void vg_bin_str( const void *bin, void *txt, u32 size )
-{
- u8 *dst = txt;
- const u8 *src = bin;
-
- for( u32 i=0; i<size; i++ ){
- dst[i*2+0] = VG_BINSTR_BASECHAR + ((src[i] ) & 0xf);
- dst[i*2+1] = VG_BINSTR_BASECHAR + ((src[i]>>4u) & 0xf);
- }
-}
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_binstr.c"
-#else
-
-/* dead simple.. 4 bits/character encoding */
-#define VG_BINSTR_BASECHAR 0x41
-
-void vg_str_bin( const void *txt, void *bin, int size );
-void vg_bin_str( const void *bin, void *txt, u32 size );
-
-#endif
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-/* we dont free dynamic vg_strs in this program. so, we dont care.. */
-const c8 *__asan_default_options() { return "detect_leaks=0"; }
-
-struct vg_project
-{
- vg_str uid, bin_folder;
-};
-
-struct vg_compiler_env
-{
- u32 optimization;
- bool debug_asan;
- bool thread_san;
- bool no_pdb;
-
- enum platform
- {
- k_platform_anyplatform,
- k_platform_windows,
- k_platform_linux,
- }
- platform;
-
- enum architecture
- {
- k_architecture_anyarch,
- k_architecture_i386,
- k_architecture_x86_64,
- }
- arch;
-
- enum compiler
- {
- k_compiler_blob,
- k_compiler_clang,
- k_compiler_zigcc,
- }
- compiler;
-
- enum libc_version
- {
- k_libc_version_native,
- k_libc_version_2_23,
- }
- libc;
-}
-_vg_common_env =
-{
- .optimization = 0,
- .debug_asan = 1,
- .thread_san = 0,
- .platform = k_platform_linux,
- .arch = k_architecture_x86_64,
- .compiler = k_compiler_zigcc,
- .libc = k_libc_version_2_23
-};
-
-struct vg_compiler_conf
-{
- vg_str include,
- library,
- link,
- defines;
- bool no_lto;
-};
-
-enum obj_type
-{
- k_obj_type_none,
- k_obj_type_exe,
- k_obj_type_obj,
- k_obj_type_shared,
-};
-
-/*
- * string tables
- * -------------------------------------------------------------------------- */
-
-static const c8 *platform_names[] =
-{
- [k_platform_anyplatform] = "anyplatform",
- [k_platform_windows] = "windows",
- [k_platform_linux] = "linux",
-};
-
-static const c8 *architecture_names[] =
-{
- [k_architecture_anyarch] = "anyarch",
- [k_architecture_i386] = "i386",
- [k_architecture_x86_64] = "x86_64",
-};
-
-static const c8 *compiler_names[] =
-{
- [k_compiler_blob] = "blob",
- [k_compiler_clang] = "clang",
- [k_compiler_zigcc] = "zig-cc",
-};
-
-static const c8 *libc_names[] =
-{
- [k_libc_version_native] = "",
- [k_libc_version_2_23] = ".2.23"
-};
-
-/*
- * OS & file tools
- * -------------------------------------------------------------------------- */
-
-void vg_syscall( const c8 *fmt, ... )
-{
- va_list args;
- va_start( args, fmt );
-
- char call[4096];
- vsnprintf( call, sizeof(call), fmt, args );
-
- va_end( args );
- vg_low( "%s\n", call );
- if( system(call) )
- exit(1);
-}
-
-void vg_add_blob( struct vg_project *proj, const c8 *blob, const c8 *dest )
-{
- vg_syscall( "cp %s %s/%s", blob, proj->bin_folder.buffer, dest );
-}
-
-void vg_symlink( struct vg_project *proj, const c8 *folder, const c8 *bin_name )
-{
- char dest[512];
- snprintf( dest, 512, "%s/%s", proj->bin_folder.buffer, bin_name );
- if( !access( dest, F_OK ) )
- vg_syscall( "unlink %s", dest );
- vg_syscall( "ln -srf %s %s", folder, dest );
-}
-
-void vg_tarball_project( struct vg_project *proj )
-{
- vg_syscall( "tar -chzvf dist/%s-%u.tar.gz %s/", proj->uid.buffer, time(NULL), proj->bin_folder.buffer );
-}
-
-/*
- * Project
- * -------------------------------------------------------------------------- */
-
-/* Initialize the project structure, proj,
- * IN folder/name,
- * CLEAR IF fresh
- */
-void vg_project_init( struct vg_project *proj,
- const c8 *folder,
- const c8 *name,
- struct vg_compiler_env *env,
- bool fresh )
-{
- vg_strnull( &proj->uid, NULL, 0 );
- vg_strcat( &proj->uid, name );
-
- if( env )
- {
- vg_strcat( &proj->uid, "-" );
- vg_strcat( &proj->uid, platform_names[ env->platform ] );
- vg_strcat( &proj->uid, "-" );
- vg_strcat( &proj->uid, architecture_names[ env->arch ] );
- vg_strcat( &proj->uid, "-" );
- vg_strcat( &proj->uid, compiler_names[ env->compiler ] );
- }
-
- vg_strnull( &proj->bin_folder, NULL, 0 );
- vg_strcat( &proj->bin_folder, folder );
- vg_strcat( &proj->bin_folder, "/" );
- vg_strcat( &proj->bin_folder, proj->uid.buffer );
-
- vg_info( "project_init: %s (fresh: %s)\n (%s)\n",
- name,
- fresh? "yes":"no",
- proj->bin_folder.buffer );
-
- if( fresh )
- vg_syscall( "rm -rf %s", proj->bin_folder.buffer );
- vg_syscall( "mkdir -p %s", proj->bin_folder.buffer );
-}
-
-struct compile_result
-{
- vg_str path,
- rel_path;
-};
-
-bool compiler_supports_sanitizers( enum compiler compiler )
-{
- if( compiler == k_compiler_clang ) return 1;
- if( compiler == k_compiler_zigcc ) return 1;
- return 0;
-}
-
-/* run a compiler.. return compiled object relative to project folder
- */
-struct compile_result
-vg_compiler_run( struct vg_project *project,
- struct vg_compiler_env *env,
- struct vg_compiler_conf *conf,
- const c8 *sources,
- const c8 *target_name,
- enum obj_type type )
-{
- /* check for problems in configuration */
- if( env->libc != k_libc_version_native )
- {
- if( env->compiler != k_compiler_zigcc )
- {
- vg_fatal_error( "Cannot specify libc version using the '%s' compiler.\n", compiler_names[ env->compiler ] );
- }
- }
-
- if( env->compiler == k_compiler_clang )
- {
- if( env->platform != k_platform_linux )
- {
- vg_fatal_error( "Cannot compile for '%s' using the '%s' compiler;" );
- }
- }
-
- vg_str cmd = {0};
- vg_strcat( &cmd, "ccache " );
-
- /* compiler specification */
-
- if( env->compiler == k_compiler_zigcc )
- {
- vg_strcat( &cmd, "zig cc " );
-
- if( env->platform == k_platform_windows )
- {
- if( type == k_obj_type_exe )
- {
- vg_strcat( &cmd, "-Wl,--subsystem=windows" );
-
- if( env->no_pdb )
- vg_strcat( &cmd, "-Wl,/pdb:/dev/null" );
- }
- }
-
- vg_strcat( &cmd, " -target " );
- vg_strcat( &cmd, architecture_names[env->arch] );
- vg_strcat( &cmd, "-" );
- vg_strcat( &cmd, platform_names[env->platform] );
-
- if( env->platform == k_platform_linux )
- {
- vg_strcat( &cmd, "-gnu" );
- vg_strcat( &cmd, libc_names[env->libc] );
- }
-
- vg_strcat( &cmd, " -fno-sanitize=undefined " );
- vg_strcat( &cmd, " -fkeep-static-consts -fkeep-persistent-storage-variables " );
- }
-
- else if( env->compiler == k_compiler_clang )
- vg_strcat( &cmd, "clang" );
-
- vg_strcat( &cmd, " -std=gnu99 -D_REENTRANT \\\n" );
-
- if( env->optimization )
- {
- vg_strcat( &cmd, " -O" );
- vg_strcati64( &cmd, env->optimization, 10 );
- }
- else
- {
- vg_strcat( &cmd, " -O0 -ggdb3 -fno-omit-frame-pointer " );
- vg_strcat( &cmd, "\\\n" );
- }
-
- if( compiler_supports_sanitizers(env->compiler) && env->debug_asan )
- vg_strcat( &cmd, " -lasan -rdynamic -fsanitize=address -fPIE -fstack-protector-strong " );
-
- if( compiler_supports_sanitizers(env->compiler) && env->thread_san )
- vg_strcat( &cmd, " -lasan -rdynamic -fsanitize=thread -fPIE -fstack-protector-strong " );
-
- vg_strcat( &cmd, conf->no_lto? " -fno-lto \\\n": " -flto \\\n" );
-
- /* want a lot of warnings but not useless ones */
- vg_strcat( &cmd, " -Wall -ferror-limit=5000\\\n"
- " -Wno-unused-function -Wno-unused-variable\\\n"
- " -Wno-unused-command-line-argument -Wno-unused-but-set-variable\\\n"
- );
-
- if( env->compiler != k_compiler_clang )
- vg_strcat( &cmd, " -Wno-format-truncation\\\n" );
-
- /* defines */
- vg_strcat( &cmd, " " );
- vg_strcat( &cmd, conf->defines.buffer );
- vg_strcat( &cmd, "\\\n" );
-
- /* include paths */
- vg_strcat( &cmd, " " );
- vg_strcat( &cmd, conf->include.buffer );
- vg_strcat( &cmd, "\\\n" );
-
- /* library paths */
- vg_strcat( &cmd, " " );
- vg_strcat( &cmd, conf->library.buffer );
- vg_strcat( &cmd, "\\\n" );
-
- /* sources */
- vg_strcat( &cmd, " " );
-
- if( type == k_obj_type_obj )
- vg_strcat( &cmd, "-c -fPIC " );
-
- if( type == k_obj_type_shared )
- {
- vg_strcat( &cmd, "-shared -fPIC " );
- }
-
- vg_strcat( &cmd, sources );
- vg_strcat( &cmd, "\\\n" );
-
- struct compile_result res = {0};
-
- vg_strcat( &res.rel_path, target_name );
-
- if( env->platform == k_platform_windows )
- {
- if( type == k_obj_type_exe )
- vg_strcat( &res.rel_path, ".exe" );
- else if( type == k_obj_type_shared )
- vg_strcat( &res.rel_path, ".dll" );
- else if( type == k_obj_type_obj )
- vg_strcat( &res.rel_path, ".obj" );
- }
-
- if( env->platform == k_platform_linux )
- {
- if( type == k_obj_type_shared )
- vg_strcat( &res.rel_path, ".so" );
- else if( type == k_obj_type_obj )
- vg_strcat( &res.rel_path, ".o" );
- }
-
- vg_strcat( &res.path, project->bin_folder.buffer );
- vg_strcat( &res.path, "/" );
- vg_strcat( &res.path, res.rel_path.buffer );
-
- vg_strcat( &cmd, " -o " );
- vg_strcat( &cmd, res.path.buffer );
- vg_strcat( &cmd, "\\\n" );
-
- /* link */
- vg_strcat( &cmd, " " );
- vg_strcat( &cmd, conf->link.buffer );
- vg_strcat( &cmd, "\\\n" );
-
- if( type == k_obj_type_exe )
- {
- vg_strcat( &cmd, " -Wl,-rpath=./\\\n" );
- }
-
- vg_syscall( cmd.buffer );
- return res;
-}
-
-/*
- * Standard VG includes & libraries which we use for games/graphics
- * -------------------------------------------------------------------------- */
-
-struct vg_engine_config
-{
- bool use_3d,
- legacy_support_vg_msg1,
- log_source_info,
- steam_api,
- custom_game_settings,
- multiplayer,
- release_mode;
- i32 fixed_update_hz;
-}
-vg_engine_default_config =
-{
- .use_3d = 1,
- .fixed_update_hz = 60,
- .legacy_support_vg_msg1 = 0,
- .log_source_info = 1,
- .steam_api = 0,
- .custom_game_settings = 0,
- .multiplayer = 0,
- .release_mode = 0
-};
-
-struct compile_result
-vg_make_app( struct vg_project *proj,
- struct vg_engine_config *vg_conf,
- struct vg_compiler_env *env,
- struct vg_compiler_conf *conf,
- const c8 *sources,
- const c8 *appname )
-{
- struct vg_project vg_proj;
- vg_project_init( &vg_proj, "bin", ".vg", env, 0 );
-
- /* building assets */
- vg_build_default_font();
-
- /* add config defines to compiler config */
- if( !vg_conf ) vg_conf = &vg_engine_default_config;
-
- vg_strcat( &conf->defines, vg_conf->use_3d? "-DVG_3D \\\n": "-DVG_2D \\\n" );
- vg_strcatf( &conf->defines, "-DVG_TIMESTEP_FIXED=\"(1.0/%d.0)\" \\\n", vg_conf->fixed_update_hz );
- vg_strcat( &conf->defines, "-DVG_MULTITHREAD -DVG_CONSOLE -DVG_MATH \\\n" );
-
- if( vg_conf->legacy_support_vg_msg1 )
- vg_strcat( &conf->defines, "-DVG_MSG_TO_KVS \\\n" );
-
- if( vg_conf->log_source_info )
- vg_strcat( &conf->defines, "-DVG_LOG_SOURCE_INFO \\\n" );
-
- if( vg_conf->custom_game_settings )
- vg_strcat( &conf->defines, "-DVG_GAME_SETTINGS \\\n" );
-
- if( vg_conf->multiplayer )
- vg_strcat( &conf->defines, "-DVG_MULTIPLAYER \\\n" );
-
- if( vg_conf->release_mode )
- vg_strcat( &conf->defines, "-DVG_RELEASE_MODE \\\n" );
-
- vg_strcat( &conf->defines, "-DVG_ENGINE \\\n" );
-
- vg_strcat( &conf->defines, "\\\n" );
- vg_strcat( &conf->include, "-I. -I./vg -I./vg/dep " );
-
- vg_strcat( &conf->library, "-L. -L/usr/lib" );
- vg_strcat( &conf->link, "-lm " );
-
- /* compile all the components
- * ----------------------------------------------------------------------- */
- vg_str components = {0};
- vg_strcatf( &components, "%s ", sources );
-
- struct vg_compiler_env denv = *env;
- //denv.optimization = 3;
-
- /* external dependencies */
- struct compile_result depencies = vg_compiler_run( &vg_proj, &denv, conf, "vg/unit_thirdparty.c", "vg_deps", k_obj_type_obj );
- vg_strcatf( &components, "%s ", depencies.path );
-
- /* core engine */
- struct compile_result vg = vg_compiler_run( &vg_proj, &denv, conf, "vg/unit_engine.c", "vg_engine_core", k_obj_type_obj );
- vg_strcatf( &components, "%s ", vg.path );
-
- /* steamworks */
- if( vg_conf->steam_api )
- {
- //struct compile_result steam = vg_compiler_run( &vg_proj, &denv, conf, "vg/vg_steam2.c", "vg_steam", k_obj_type_obj );
- //vg_strcatf( &components, "%s ", steam.path );
-
- if( env->platform == k_platform_linux )
- {
- vg_add_blob( proj, "vg/dep/steam/libsteam_api.so", "" );
- vg_strcat( &conf->link, "-lsteam_api " );
- }
- else if( env->platform == k_platform_windows )
- {
- vg_add_blob( proj, "vg/dep/steam/steam_api64.dll", "" );
- vg_strcat( &conf->link, "vg/dep/steam/steam_api64.dll " );
- }
-
- vg_strcat( &conf->library, "-L./vg/dep/steam " );
- }
-
- /* link */
- /* TODO: Could be /usr/lib/x86_64-linux-gnu or /usr/lib
- */
-
- if( env->platform == k_platform_linux )
- {
- vg_strcat( &conf->link, "-lSDL2 -lGL -lX11 -lXxf86vm "
- "-lXrandr -lXi -ldl -pthread " );
- return vg_compiler_run( proj, env, conf, components.buffer, appname, k_obj_type_exe );
- }
- else if( env->platform == k_platform_windows )
- {
- vg_strcat( &conf->link, "-lSDL2main -lSDL2 -lopengl32 -ldbghelp \\\n" );
- vg_strcat( &conf->link, "vg/dep/sdl/SDL2.dll " );
- vg_add_blob( proj, "vg/dep/sdl/SDL2.dll ", "" );
- vg_strcat( &conf->library, "-L./vg/dep/sdl " );
- return vg_compiler_run( proj, env, conf, components.buffer, appname, k_obj_type_exe );
- }
- else
- {
- vg_fatal_error( "No compile procedure set for platform '%s'\n", platform_names[env->platform] );
- }
-
- return (struct compile_result){};
-}
-
-void vg_add_controller_database( struct vg_project *proj )
-{
- vg_add_blob( proj, "vg/submodules/SDL_GameControllerDB/gamecontrollerdb.txt", "" );
-}
-
-void vg_build_scripts(void);
-int main( int argc, const c8 *argv[] )
-{
- _vg_log_pre_init();
- _vg_opt_init( argc, argv );
-
- if( vg_long_opt( "windows", "Build for windows" ) )
- _vg_common_env.platform = k_platform_windows;
-
- if( vg_long_opt( "tsan", "Use Thread Sanitizer instead of Adress Sanitizer" ) )
- {
- _vg_common_env.debug_asan = 0;
- _vg_common_env.thread_san = 1;
- }
-
- if( vg_opt( 'O', "Build with optimisations" ) )
- {
- _vg_common_env.optimization = 3;
- _vg_common_env.debug_asan = 0;
- _vg_common_env.thread_san = 0;
- }
-
- vg_build_scripts();
-
- if( !_vg_opt_check() )
- return 0;
-}
-
-#endif
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-void vg_build_font_face_run( vg_font_face *face, char first, char last, i16 x, i16 y )
-{
- u32 uf = *((u8 *)&first),
- ul = *((u8 *)&last);
-
- u32 count = ul - uf;
- for( u32 i=0; i<=count; i ++ )
- {
- u32 index = uf + i;
- face->map[index].x = x+(i*face->cw);
- face->map[index].y = y;
- }
-}
-
-void vg_build_write_font_face( FILE *fp, vg_font_face *face )
-{
- fprintf( fp, "vg_font_face %s = {\n", face->name );
- fprintf( fp, " .name=\"%s\",\n", face->name );
- fprintf( fp, " .cw=%hd,.ch=%hd,\n", face->cw,face->ch );
- fprintf( fp, " .sx=%hd,.sy=%hd,\n", face->sx,face->sy );
- fprintf( fp, " .baseline=%hd,\n", face->baseline );
- fprintf( fp, " .map={\n" );
-
- u32 chars = 0;
-
- for( u32 i=0; i<256; i ++ )
- {
- if( face->map[i].x || face->map[i].y )
- {
- chars += fprintf( fp, "[%u]={%hd,%hd},",
- i, face->map[i].x, face->map[i].y );
-
- if( chars > 80 )
- {
- fprintf( fp, "\n" );
- chars = 0;
- }
- }
- }
-
- fprintf( fp, "\n}};\n\n" );
-}
-
-void vg_build_font_sheet( FILE *fp, char *name, const char *source )
-{
- int x,y,n;
- unsigned char *data = stbi_load( source, &x, &y, &n, 4 );
-
- if( !data )
- {
- vg_error( "Couldn't open source file\n" );
- return;
- }
-
- fprintf( fp, "vg_font_sheet %s = {\n", name );
- fprintf( fp, " .w=%d, .h=%d,\n", x,y );
- fprintf( fp, " .bitmap={\n" );
-
- u32 pixel_max = x*y;
- u32 pixel = 0, chars = 0;
- while( pixel_max )
- {
- u32 buff = 0;
- for( int b = 31; b >= 0; b-- )
- {
- buff |= (data[pixel*4] > 128)? (0x1u<<(u32)b): 0;
- pixel++;
-
- if( pixel >= pixel_max )
- {
- pixel_max = 0;
- break;
- }
- }
-
- chars += fprintf( fp, "%#x,", buff );
- if( chars > 80 )
- {
- fprintf( fp, "\n" );
- chars = 0;
- }
- }
-
- fprintf( fp, "\n}};\n" );
- free( data );
-}
-
-void vg_build_default_font(void)
-{
- FILE *fp = fopen( "vg/vg_default_font.gc", "w" );
- vg_build_font_sheet( fp, "vg_default_font_sheet", "vg/src/fonts/vg_font_thin_3.png" );
- vg_font_face small =
- {
- .name = "vgf_default_small",
- .cw=8, .ch=14,
- .sx=8, .sy=14,
- .baseline = 4
- };
- vg_build_font_face_run( &small, '!', '/', 8, 0 );
- vg_build_font_face_run( &small, '[', '`', 128,0 );
- vg_build_font_face_run( &small, '{', '~', 176,0 );
- vg_build_font_face_run( &small, ':', '@', 208,0 );
- vg_build_font_face_run( &small, 'A', 'Z', 0, 14 );
- vg_build_font_face_run( &small, 'a', 'z', 0, 28 );
- vg_build_font_face_run( &small, '0', '9', 208,14 );
- vg_build_font_face_run( &small, 0x7f, 0xa4, 0,42 );
- vg_build_font_face_run( &small, 0xb0, 0xbf, 208,28 );
- vg_build_write_font_face( fp, &small );
-
- vg_font_face large =
- {
- .name = "vgf_default_large",
- .cw=12, .ch=21,
- .sx=12, .sy=21,
- .baseline=6,
- };
- vg_build_font_face_run( &large, '!', '/', 12, 56 );
- vg_build_font_face_run( &large, '[', '`', 192,56 );
- vg_build_font_face_run( &large, '{', '~', 264,56 );
- vg_build_font_face_run( &large, ':', '@', 312,56 );
- vg_build_font_face_run( &large, 'A', 'Z', 0, 77 );
- vg_build_font_face_run( &large, 'a', 'z', 0, 98 );
- vg_build_font_face_run( &large, '0', '9', 312,77 );
- vg_build_font_face_run( &large, 0x7f, 0xa4, 0,119 );
- vg_build_font_face_run( &large, 0xb0, 0xbe, 312,98 );
- vg_build_write_font_face( fp, &large );
-
- vg_font_face title =
- {
- .name = "vgf_default_title",
- .cw=24, .ch=42,
- .sx=20, .sy=42,
- .baseline=12,
- };
- vg_build_font_face_run( &title, '!', '/', 24, 140 );
- vg_build_font_face_run( &title, '[', '_', 384,140 );
- vg_build_font_face_run( &title, '`', '`', 0, 182 );
- vg_build_font_face_run( &title, '{', '~', 24, 182 );
- vg_build_font_face_run( &title, ':', '@', 120,182 );
- vg_build_font_face_run( &title, 'A', 'U', 0, 224 );
- vg_build_font_face_run( &title, 'V', 'Z', 0, 308 );
- vg_build_font_face_run( &title, 'a', 'u', 0, 266 );
- vg_build_font_face_run( &title, 'v', 'z', 0, 350 );
- vg_build_font_face_run( &title, '0', '9', 120,308 );
- vg_build_font_face_run( &title, 0x89, 0x8c, 409,182 );
- vg_build_font_face_run( &title, 0x8d, 0x92, 360,308 );
- vg_build_font_face_run( &title, 0x7f, 0x88, 120,350 );
- vg_build_font_face_run( &title, 0x93, 0x98, 360,350 );
- vg_build_font_face_run( &title, 0x99, 0xa4, 0,392 );
- vg_build_font_face_run( &title, 0xb0, 0xb2, 288,392 );
- vg_build_write_font_face( fp, &title );
-
- fclose( fp );
-}
-#endif
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-
-struct
-{
- vg_str c_structs,
- c_funcs,
- c_enum;
-
- struct multi_string
- {
- vg_str str;
- u32 ghost_count;
- }
- names,
- infos,
- glsl;
-
- u32 name_count, shader_count;
-
- bool init;
- char shader_dir[ 256 ];
-}
-_shadercomp;
-
-static void _shadercomp_pstr( struct multi_string *ms, vg_str *ref_place, const c8 *str, u32 length )
-{
- if( ref_place )
- {
- vg_strcatu64( ref_place, ms->str.i - ms->ghost_count, 10 );
- vg_strcat( ref_place, "," );
- }
-
- if( str )
- {
- vg_strcat_limit( &ms->str, str, length );
- vg_strcat( &ms->str, "\\0" );
- ms->ghost_count ++;
- }
-}
-
-static int compile_subshader( c8 *file, c8 *shader_name )
-{
- char error[256];
- char *full = stb_include_file( file, "", _shadercomp.shader_dir, error );
-
- if( !full )
- {
- vg_error( "stb_include_file error:\n%s\n", error );
- return 0;
- }
-
- enum
- {
- k_nothing,
- k_type,
- k_name,
- k_maybe_uniform_block
- }
- state = k_nothing;
-
- bool uniform = 0;
- u32 t_length = 0, t_start = 0;
- u32 type_index = 0;
- c8 comment = 0;
-
- // glsl types have to be ordered by string length!!!!!!!!
- const c8 *glsl_defs[][6] =
- {
- { "int", "int b", "glUniform1i(", ",b);" },
- { "vec2", "v2f v", "glUniform2fv(", ",1,v);" },
- { "vec3", "v3f v", "glUniform3fv(", ",1,v);" },
- { "vec4", "v4f v", "glUniform4fv(", ",1,v);" },
- { "bool", "int 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);",
- "m4x3f *m, u32 count", ",count,GL_FALSE,(f32*)m);"}, // 1,3 -> 4,5
- { "sampler2D", "int i", "glUniform1i(", ",i);" },
- { "usampler3D", "int i", "glUniform1i(", ",i);" },
- { "samplerCube", "int i", "glUniform1i(", ",i);" },
- { "samplerBuffer","int i", "glUniform1i(", ",i);" },
- };
-
- _shadercomp_pstr( &_shadercomp.glsl, &_shadercomp.c_structs, NULL, 0 );
- vg_strcatch( &_shadercomp.glsl.str, '"' );
- _shadercomp.glsl.ghost_count += 1;
-
- for( u32 i=0; 1; i ++ )
- {
- c8 c = full[i];
- if( !c )
- break;
-
- if( comment == '/' )
- {
- if( c == '\n' ) comment = 0;
- continue;
- }
- if( comment == '*' )
- {
- if( (c == '*') && (full[i+1] == '/') )
- {
- comment = 0;
- i ++;
- }
- continue;
- }
- if( (c == '/') && ((full[i+1] == '/') || (full[i+1] == '*')) )
- {
- comment = full[i+1];
- i ++;
- continue;
- }
-
- if( c == '\n' )
- {
- vg_strcat( &_shadercomp.glsl.str, "\\n\"\n\"" );
- _shadercomp.glsl.ghost_count += 4;
- }
- else
- vg_strcatch( &_shadercomp.glsl.str, c );
-
- if( c==' '||c=='\t'||c=='\r'||c=='\n'||c=='{'||c=='}'||c==';'||c=='[' )
- {
- if( t_length )
- {
- if( state == k_nothing )
- {
- if( !strncmp( full+t_start, "uniform", t_length ) )
- {
- state = k_type;
- }
- }
- else if( state == k_type )
- {
- // check type
- type_index = 9999;
-
- for( u32 j=0; j<VG_ARRAY_LEN(glsl_defs); j ++ )
- {
- if( !strncmp( full+t_start, glsl_defs[j][0], t_length ) )
- {
- state = k_name;
- type_index = j;
- break;
- }
- }
-
- if( type_index == 9999 )
- {
- /* TODO: Yes, this is scuffed, un-conformant parsering. But it's okay, we'll be alright. */
- if( c=='\n' )
- {
- vg_strcat( &_shadercomp.c_enum, " k_uniform_block_" );
- vg_strcat( &_shadercomp.c_enum, shader_name );
- vg_strcat( &_shadercomp.c_enum, "_" );
- vg_strcat_limit( &_shadercomp.c_enum, full+t_start, t_length );
- vg_strcat( &_shadercomp.c_enum, " = " );
- vg_strcatu64( &_shadercomp.c_enum, _shadercomp.name_count, 10 );
- vg_strcat( &_shadercomp.c_enum, ",\n" );
-
- _shadercomp.name_count ++;
- vg_strcat( &_shadercomp.names.str, "$" );
- vg_strcat_limit( &_shadercomp.names.str, full+t_start, t_length );
- vg_strcat( &_shadercomp.names.str, "\\0" );
- _shadercomp.names.ghost_count ++;
-
- }
- state = k_nothing;
- }
- }
- else if( state == k_name )
- {
- bool is_array = c == '[';
- vg_strcat( &_shadercomp.c_funcs, "static inline void shader_" );
- vg_strcat( &_shadercomp.c_funcs, shader_name );
- vg_strcat( &_shadercomp.c_funcs, "_" );
- vg_strcat_limit( &_shadercomp.c_funcs, full+t_start, t_length );
- vg_strcat( &_shadercomp.c_funcs, "(" );
- vg_strcat( &_shadercomp.c_funcs, glsl_defs[type_index][is_array? 4: 1] );
- vg_strcat( &_shadercomp.c_funcs, ") { " );
- vg_strcat( &_shadercomp.c_funcs, glsl_defs[type_index][2] );
- vg_strcat( &_shadercomp.c_funcs, "_vg_shader_names[" );
- vg_strcatu64( &_shadercomp.c_funcs, _shadercomp.name_count, 10 );
- vg_strcat( &_shadercomp.c_funcs, "] " );
- vg_strcat( &_shadercomp.c_funcs, glsl_defs[type_index][is_array? 5: 3] );
- vg_strcat( &_shadercomp.c_funcs, "}\n" );
-
- vg_strcat( &_shadercomp.c_enum, " k_uniform_" );
- vg_strcat( &_shadercomp.c_enum, shader_name );
- vg_strcat( &_shadercomp.c_enum, "_" );
- vg_strcat_limit( &_shadercomp.c_enum, full+t_start, t_length );
- vg_strcat( &_shadercomp.c_enum, " = " );
- vg_strcatu64( &_shadercomp.c_enum, _shadercomp.name_count, 10 );
- vg_strcat( &_shadercomp.c_enum, ",\n" );
-
- _shadercomp.name_count ++;
- _shadercomp_pstr( &_shadercomp.names, NULL, full+t_start, t_length );
-
- state = k_nothing;
- }
- t_length = 0;
- }
- }
- else
- {
- if( t_length )
- t_length ++;
- else
- {
- t_length = 1;
- t_start = i;
- }
- }
- }
- vg_strcat( &_shadercomp.glsl.str, "\\0\"\n" );
- _shadercomp.glsl.ghost_count += 3; //TODO these are kind of ugly, we should have a 'propper' C source builder.
-
- free( full );
- return 1;
-}
-
-
-int vg_build_shader( char *src_vert, /* path/to/vert.vs */
- char *src_frag, /* path/to/frag.fs */
- char *src_geo, /* unused currently */
- char *name /* shader name */ )
-{
- if( !_shadercomp.init )
- {
- vg_strnull( &_shadercomp.c_structs, NULL, 0 );
- vg_strnull( &_shadercomp.names.str, NULL, 0 );
- vg_strnull( &_shadercomp.infos.str, NULL, 0 );
- vg_strnull( &_shadercomp.c_funcs, NULL, 0 );
- vg_strnull( &_shadercomp.c_enum, NULL, 0 );
- vg_strnull( &_shadercomp.glsl.str, NULL, 0 );
- _shadercomp.init = 1;
- }
-
- vg_low( "Compiling shader '%s'\n", name );
-
- u32 u_start = _shadercomp.name_count,
- u_offset = _shadercomp.names.str.i - _shadercomp.names.ghost_count;
-
- /* [shader] _use() */
- vg_strcat( &_shadercomp.c_enum, " k_shader_" );
- vg_strcat( &_shadercomp.c_enum, name );
- vg_strcat( &_shadercomp.c_enum, " = " );
- vg_strcatu64( &_shadercomp.c_enum, _shadercomp.name_count, 10 );
- vg_strcat( &_shadercomp.c_enum, ",\n" );
-
- vg_strcat( &_shadercomp.c_funcs, "static inline void shader_" );
- vg_strcat( &_shadercomp.c_funcs, name );
- vg_strcat( &_shadercomp.c_funcs, "_use(void){ glUseProgram( _vg_shader_names[" );
- vg_strcatu64( &_shadercomp.c_funcs, _shadercomp.name_count, 10 );
- vg_strcat( &_shadercomp.c_funcs, "] ); }\n" );
- _shadercomp.name_count ++;
-
- /* [shader] *uniform* ( ... ) */
- vg_strcat( &_shadercomp.c_structs, "{" );
- _shadercomp_pstr( &_shadercomp.infos, &_shadercomp.c_structs, name, 0 );
-
- /* vs */
- vg_strcat( &_shadercomp.c_structs, "{" );
- if( !compile_subshader( src_vert, name ) ) {}
- _shadercomp_pstr( &_shadercomp.infos, &_shadercomp.c_structs, src_vert, 0 );
-
- /* fs */
- vg_strcat( &_shadercomp.c_structs, "},{" );
- if( !compile_subshader( src_frag, name ) ) {}
- _shadercomp_pstr( &_shadercomp.infos, &_shadercomp.c_structs, src_frag, 0 );
-
- u32 u_end = _shadercomp.name_count;
- vg_strcat( &_shadercomp.c_structs, "}," );
- vg_strcatu64( &_shadercomp.c_structs, u_start, 10 );
- vg_strcat( &_shadercomp.c_structs, "," );
- vg_strcatu64( &_shadercomp.c_structs, u_offset, 10 );
- vg_strcat( &_shadercomp.c_structs, "," );
- vg_strcatu64( &_shadercomp.c_structs, (u_end - u_start)-1, 10 );
- vg_strcat( &_shadercomp.c_structs, "},\n" );
-
- _shadercomp.shader_count ++;
- return 1;
-}
-
-static void vg_shader_set_include_dir( char *dir )
-{
- strcpy( _shadercomp.shader_dir, dir );
-}
-
-void vg_build_shader_impl(void)
-{
- vg_syscall( "mkdir -p src.generated" );
-
- const c8 *h_path = "src.generated/vg.shaders.h";
-
- FILE *fp = fopen( h_path, "w" );
- if( fp )
- {
- /* IMPLEMENTATION ----------------------------------------------------------------- */
- vg_str names_def;
- vg_strnull( &names_def, NULL, 0 );
- vg_strcat( &names_def, "GLuint _vg_shader_names[ " );
- vg_strcatu64( &names_def, _shadercomp.name_count, 10 );
- vg_strcat( &names_def, " ];\n" );
-
- vg_str shaders_def;
- vg_strnull( &shaders_def, NULL, 0 );
- vg_strcat( &shaders_def, "struct vg_shader _vg_shaders[ " );
- vg_strcatu64( &shaders_def, _shadercomp.shader_count, 10 );
- vg_strcat( &shaders_def, " ]" );
-
- fputs( "#ifdef VG_IMPLEMENTATION\n", fp );
- fputs( names_def.buffer, fp );
-
- fputs( shaders_def.buffer, fp );
- fputs( " = {", fp );
- if( _shadercomp.c_structs.buffer ) fputs( _shadercomp.c_structs.buffer, fp );
- fputs( "};\n", fp );
-
- fputs( "const c8 *_vg_shaders_uniform_names = \"", fp );
- if( _shadercomp.names.str.buffer ) fputs( _shadercomp.names.str.buffer, fp );
- fputs( "\";\n", fp );
-
- fputs( "const c8 *_vg_shaders_infos = \"", fp );
- if( _shadercomp.infos.str.buffer ) fputs( _shadercomp.infos.str.buffer, fp );
- fputs( "\";\n", fp );
-
- fputs( "const c8 *_vg_shaders_glsl = ", fp );
- if( _shadercomp.glsl.str.buffer ) fputs( _shadercomp.glsl.str.buffer, fp );
- fputs( ";\n", fp );
-
- fputs( "#else\n", fp ); /* HEADER ----------------------------------------------------------------- */
-
- fputs( "extern const c8 *_vg_shaders_uniform_names;\n", fp );
- fputs( "extern const c8 *_vg_shaders_infos;\n", fp );
- fputs( "extern const c8 *_vg_shaders_glsl;\n", fp );
- fputs( "extern ", fp );
- fputs( names_def.buffer, fp );
-
- fputs( "extern ", fp );
- fputs( shaders_def.buffer, fp );
- fputs( ";\n", fp );
-
- fputs( "enum e_shader_gl_name\n{\n", fp );
- if( _shadercomp.c_enum.buffer ) fputs( _shadercomp.c_enum.buffer, fp );
- fputs( "};\n", fp );
-
- if( _shadercomp.c_funcs.buffer ) fputs( _shadercomp.c_funcs.buffer, fp );
-
- fputs( "#endif\n", fp );
- fclose( fp );
- }
- else vg_fatal_error( "Cant open '%s'!\n", h_path );
-}
-
-#endif
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_bvh.c"
-#else
-
-typedef struct bh_node bh_node;
-typedef struct bh_tree bh_tree;
-typedef struct bh_system bh_system;
-
-typedef struct ray_hit ray_hit;
-struct ray_hit
-{
- f32 dist;
- u32 *tri;
- v3f pos, normal;
-};
-
-struct bh_tree
-{
- u32 node_count;
-
- bh_system *system;
- void *user;
- u32 max_per_leaf;
-
- struct bh_node
- {
- boxf bbx;
-
- /* if il is 0, this is a leaf */
- i32 il, count;
- union{ i32 ir, start; };
- }
- *nodes;
-};
-
-typedef void (*bh_expand_fn) ( void *user, boxf bound, u32 item_index );
-typedef f32 (*bh_centroid_fn)( void *user, u32 item_index, i32 axis );
-typedef void (*bh_closest_fn) ( void *user, u32 item_index, v3f point, v3f closest );
-typedef void (*bh_swap_fn) ( void *user, u32 ia, u32 ib );
-typedef void (*bh_debug_fn) ( void *user, u32 item_index );
-typedef void (*bh_raycast_fn) ( void *user, u32 index, v3f co, v3f dir, ray_hit *hit );
-
-struct bh_system
-{
- bh_expand_fn expand_bound;
- bh_centroid_fn item_centroid;
- bh_closest_fn item_closest;
- bh_swap_fn item_swap;
-
- /*
- * Optional:
- * item_debug - draw this item quickly usually with lines
- * cast_ray - shoot a ray against the object, if this is not set,
- * raycasts will simply return the hit on the bvh node
- */
- bh_debug_fn item_debug;
- bh_raycast_fn cast_ray;
-};
-
-VG_TIER_1 void bh_create( bh_tree *bh, bh_system *system, void *user, u32 item_count,
- u32 max_per_leaf, vg_stack_allocator *stack );
-VG_TIER_0 void bh_debug_leaf( bh_tree *bh, bh_node *node );
-
-/*
- * Trace the bh tree all the way down to the leaf nodes where pos is inside
- */
-VG_TIER_0 void bh_debug_trace( bh_tree *bh, u32 inode, v3f pos, u32 colour );
-
-typedef struct bh_iter bh_iter;
-struct bh_iter
-{
- struct
- {
- i32 id, depth;
- }
- stack[64];
-
- enum bh_query_type
- {
- k_bh_query_box,
- k_bh_query_ray,
- k_bh_query_range
- }
- query;
-
- union
- {
- struct
- {
- boxf box;
- }
- box;
-
- struct
- {
- v3f co, inv_dir;
- f32 max_dist;
- }
- ray;
-
- struct
- {
- v3f co;
- f32 dist_sqr;
- }
- range;
- };
-
- i32 depth, i;
-};
-
-VG_TIER_0 void bh_iter_init_generic( i32 root, bh_iter *it );
-VG_TIER_0 void bh_iter_init_box( i32 root, bh_iter *it, boxf box );
-VG_TIER_0 void bh_iter_init_ray( i32 root, bh_iter *it, v3f co, v3f dir, f32 max_dist );
-VG_TIER_0 void bh_iter_init_range( i32 root, bh_iter *it, v3f co, f32 range );
-VG_TIER_0 i32 bh_next( bh_tree *bh, bh_iter *it, i32 *em );
-VG_TIER_0 int bh_closest_point( bh_tree *bh, v3f pos, v3f closest, float max_dist );
-
-#endif
+++ /dev/null
-void vg_camera_lerp_angles( v3f a, v3f b, f32 t, v3f d )
-{
- d[0] = vg_alerpf( a[0], b[0], t );
- d[1] = vg_lerpf( a[1], b[1], t );
- d[2] = vg_lerpf( a[2], b[2], t );
-}
-
-/* lerp position, fov, and angles */
-void vg_camera_lerp( vg_camera *a, vg_camera *b, f32 t, vg_camera *d )
-{
- v3_lerp( a->pos, b->pos, t, d->pos );
- vg_camera_lerp_angles( a->angles, b->angles, t, d->angles );
- d->fov = vg_lerpf( a->fov, b->fov, t );
-}
-
-void vg_camera_copy( vg_camera *a, vg_camera *d )
-{
- v3_copy( a->pos, d->pos );
- v3_copy( a->angles, d->angles );
- d->fov = a->fov;
-}
-
-void vg_m4x3_transform_camera( m4x3f m, vg_camera *cam )
-{
- m4x3_mulv( m, cam->pos, cam->pos );
-
- v3f v0;
- v3_angles_vector( cam->angles, v0 );
- m3x3_mulv( m, v0, v0 );
- v3_normalize( v0 );
- v3_angles( v0, cam->angles );
-}
-
-/*
- * 1) [angles, pos] -> transform
- */
-void vg_camera_update_transform( vg_camera *cam )
-{
- v4f qyaw, qpitch, qroll, qcam;
- q_axis_angle( qyaw, (v3f){ 0.0f, 1.0f, 0.0f }, -cam->angles[0] );
- q_axis_angle( qpitch, (v3f){ 1.0f, 0.0f, 0.0f }, -cam->angles[1] );
- q_axis_angle( qroll, (v3f){ 0.0f, 0.0f, 1.0f }, -cam->angles[2] );
-
- q_mul( qyaw, qpitch, qcam );
- q_mul( qcam, qroll, qcam );
- q_m3x3( qcam, cam->transform );
- v3_copy( cam->pos, cam->transform[3] );
-}
-
-/*
- * 2) [transform] -> transform_inverse, view matrix
- */
-void vg_camera_update_view( vg_camera *cam )
-{
- m4x4_copy( cam->mtx.v, cam->mtx_prev.v );
- m4x3_invert_affine( cam->transform, cam->transform_inverse );
- m4x3_expand( cam->transform_inverse, cam->mtx.v );
-}
-
-/*
- * 3) [fov,nearz,farz] -> projection matrix
- */
-void vg_camera_update_projection( vg_camera *cam, f32 vw, f32 vh )
-{
- m4x4_copy( cam->mtx.p, cam->mtx_prev.p );
- m4x4_projection( cam->mtx.p, cam->fov, (float)vw / (float)vh, cam->nearz, cam->farz );
-}
-
-/*
- * 4) [projection matrix, view matrix] -> previous pv, new pv
- */
-void vg_camera_finalize( vg_camera *cam )
-{
- m4x4_copy( cam->mtx.pv, cam->mtx_prev.pv );
- m4x4_mul( cam->mtx.p, cam->mtx.v, cam->mtx.pv );
-}
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_camera.c"
-#else
-
-typedef struct vg_camera vg_camera;
-struct vg_camera
-{
- /* Input */
- v3f angles;
- v3f pos;
- f32 fov, nearz, farz;
-
- /* Output */
- m4x3f transform,
- transform_inverse;
-
- struct vg_camera_mtx{
- m4x4f p,
- v,
- pv;
- }
- mtx,
- mtx_prev;
-};
-
-void vg_camera_lerp_angles( v3f a, v3f b, f32 t, v3f d );
-
-/* lerp position, fov, and angles */
-void vg_camera_lerp( vg_camera *a, vg_camera *b, f32 t, vg_camera *d );
-void vg_camera_copy( vg_camera *a, vg_camera *d );
-void vg_m4x3_transform_camera( m4x3f m, vg_camera *cam );
-
-/*
- * 1) [angles, pos] -> transform
- */
-void vg_camera_update_transform( vg_camera *cam );
-
-/*
- * 2) [transform] -> transform_inverse, view matrix
- */
-void vg_camera_update_view( vg_camera *cam );
-
-/*
- * 3) [fov,nearz,farz] -> projection matrix
- */
-void vg_camera_update_projection( vg_camera *cam, f32 vw, f32 vh );
-
-/*
- * 4) [projection matrix, view matrix] -> previous pv, new pv
- */
-void vg_camera_finalize( vg_camera *cam );
-
-#endif
+++ /dev/null
-struct vg_console vg_console;
-
-void vg_console_reg_var( const char *alias, void *ptr, enum vg_var_dtype type, u32 flags )
-{
-#if defined( VG_ENGINE )
- VG_ASSERT( vg_console.registration_blocked==0 );
- VG_ASSERT( _vg_thread_has_flags( VG_THREAD_MAIN ) );
-#endif
- VG_ASSERT( vg_console.var_count < VG_ARRAY_LEN(vg_console.vars) );
-
- vg_var *var = &vg_console.vars[ vg_console.var_count ++ ];
- var->name = alias;
- var->data = ptr;
- var->data_type = type;
- var->flags = flags;
-}
-
-void vg_console_reg_cmd( const char *alias, int (*function)(int argc, const char *argv[]),
- void (*poll_suggest)(int argc, const char *argv[]) )
-{
-#if defined( VG_ENGINE )
- VG_ASSERT( vg_console.registration_blocked==0 );
- VG_ASSERT( _vg_thread_has_flags( VG_THREAD_MAIN ) );
-#endif
- VG_ASSERT( vg_console.function_count < VG_ARRAY_LEN(vg_console.functions) );
-
- vg_cmd *cmd = &vg_console.functions[ vg_console.function_count ++ ];
-
- cmd->function = function;
- cmd->poll_suggest = poll_suggest;
- cmd->name = alias;
-}
-
-static int _vg_console_list( int argc, char const *argv[] )
-{
- for( int i=0; i<vg_console.function_count; i ++ )
- {
- struct vg_cmd *cmd = &vg_console.functions[ i ];
- vg_info( "* %s\n", cmd->name );
- }
-
- for( int i=0; i<vg_console.var_count; i ++ )
- {
- struct vg_var *cv = &vg_console.vars[ i ];
- vg_info( "%s %s\n", (const char *[]){ "i32","u32","f32","str" }[cv->data_type], cv->name );
- }
-
- return 0;
-}
-
-#if defined( VG_ENGINE )
-static void vg_console_write_persistent(void)
-{
- VG_ASSERT( _vg_thread_has_flags( VG_THREAD_MAIN ) );
- FILE *fp = fopen( "cfg/auto.conf", "w" );
- if( !fp )
- {
- vg_error( "Cannot open cfg/auto.conf\n" );
- return;
- }
-
- for( int i=0; i<vg_console.var_count; i ++ )
- {
- struct vg_var *cv = &vg_console.vars[i];
-
- if( cv->flags & VG_VAR_PERSISTENT )
- {
- if( cv->data_type == k_var_dtype_i32 )
- fprintf( fp, "%s %d\n", cv->name, *(i32 *)(cv->data) );
- else if( cv->data_type == k_var_dtype_u32 )
- fprintf( fp, "%s %u\n", cv->name, *(u32 *)(cv->data) );
- else if( cv->data_type == k_var_dtype_f32 )
- fprintf( fp, "%s %.5f\n", cv->name, *(float *)(cv->data ) );
- else if( cv->data_type == k_var_dtype_str )
- {
- vg_str *str = cv->data;
- if( str->buffer && (str->i > 0) )
- fprintf( fp, "%s %s\n", cv->name, str->buffer );
- }
- }
- }
-
- fclose( fp );
-}
-#endif
-
-/*
- * splits src into tokens and fills out args as pointers to those tokens
- * returns number of tokens
- * dst must be as long as src
- */
-static int vg_console_tokenize( const char *src, char *dst, const char *args[32] )
-{
- int arg_count = 0;
- bool in_token = 0, in_string = 0;
-
- for( int i=0;; i ++ )
- {
- char c = src[i];
- dst[i] = c;
-
- if( c == '\0' )
- break;
-
- if( c == '"' )
- {
- if( in_string )
- {
- if( in_token )
- {
- dst[i] = '\0';
- in_token = 0;
- }
-
- in_string = 0;
- }
- else
- in_string = 1;
- }
- else
- {
- if( !in_string && (c == ' ' || c == '\t') )
- {
- if( in_token )
- {
- dst[i] = '\0';
- in_token = 0;
- }
- else
- dst[i] = '\0';
- }
- else
- {
- if( in_token ) {}
- else
- {
- if( arg_count == 32 )
- {
- vg_error( "Console input exceeded maximum command tokens (>32)\n" );
- break;
- }
- else
- {
- args[ arg_count ++ ] = &dst[i];
- in_token = 1;
- }
- }
- }
- }
- }
-
- return arg_count;
-}
-
-static vg_var *vg_console_match_var( const char *kw )
-{
- for( int i=0; i<vg_console.var_count; i ++ )
- {
- struct vg_var *cv = &vg_console.vars[ i ];
- if( !strcmp( cv->name, kw ) )
- {
- return cv;
- }
- }
-
- return NULL;
-}
-
-static vg_cmd *vg_console_match_cmd( const char *kw )
-{
- for( int i=0; i<vg_console.function_count; i ++ )
- {
- struct vg_cmd *cmd = &vg_console.functions[ i ];
- if( !strcmp( cmd->name, kw ) )
- {
- return cmd;
- }
- }
-
- return NULL;
-}
-
-void vg_execute_console_input( const char *cmd, bool silent, bool cheat_override )
-{
- char temp[512];
- char const *args[32];
- int arg_count = vg_console_tokenize( cmd, temp, args );
-
- if( arg_count == 0 )
- return;
-
- vg_var *cv = vg_console_match_var( args[0] );
- vg_cmd *fn = vg_console_match_cmd( args[0] );
-
- if( cv )
- {
- /* Cvar Matched, try get value */
- if( arg_count >= 2 )
- {
-#ifdef VG_ENGINE
- if( (cv->flags & VG_VAR_CHEAT) && !cheat_override )
- {
- bool cheats = vg_console.cheats;
- if( !cheats && !silent )
- {
- vg_error( "variable is cheat protected\n" );
- return;
- }
- }
-#endif
-
- if( (cv->data_type == k_var_dtype_u32) || (cv->data_type == k_var_dtype_i32) )
- {
- int *ptr = cv->data;
- *ptr = atoi( args[1] );
- }
- else if( cv->data_type == k_var_dtype_f32 )
- {
- float *ptr = cv->data;
- *ptr = atof( args[1] );
- }
- else if( cv->data_type == k_var_dtype_str )
- {
- vg_str *str = cv->data;
- vg_strfree( str );
- vg_strnull( str, NULL, 0 );
-
- for( int i=1; i<arg_count; i ++ )
- {
- vg_strcat( str, args[i] );
- if( i!=arg_count-1 )
- vg_strcatch( str, ' ' );
- }
- }
- }
- else
- {
- if( cv->data_type == k_var_dtype_i32 )
- vg_info( "= %d\n", *((int *)cv->data) );
- else if( cv->data_type == k_var_dtype_u32 )
- vg_info( "= %u\n", *((u32 *)cv->data) );
- else if( cv->data_type == k_var_dtype_f32 )
- vg_info( "= %.4f\n", *((float *)cv->data) );
- else if( cv->data_type == k_var_dtype_str )
- {
- vg_str *str = cv->data;
- vg_info( "= '%s'\n", str->buffer );
- }
- }
-
- return;
- }
- else if( fn )
- {
- fn->function( arg_count-1, args+1 );
- return;
- }
-
- if( !silent )
- vg_error( "No command/var named '%s'. Use 'list' to view all\n",args[0]);
-}
-
-static int vg_console_exec( int argc, const char *argv[] )
-{
- if( argc < 1 )
- return 0;
-
- int silent=0;
- if( argc == 2 )
- silent=1;
-
- char path[256];
- strcpy( path, "cfg/" );
- strncat( path, argv[0], 250 );
-
- FILE *fp = fopen( path, "r" );
- if( fp )
- {
- char line[256];
-
- while( fgets( line, sizeof( line ), fp ) )
- {
- line[ strcspn( line, "\r\n#" ) ] = 0x00;
- if( line[0] == 0x00 )
- continue;
-
- if( line[0] == '/' )
- if( line[1] == '/' )
- continue;
-
- vg_execute_console_input( line, silent, 0 );
- }
-
- fclose( fp );
- }
- else
- vg_error( "Could not open '%s'\n", path );
- return 0;
-}
-
-
-VG_API void _vg_console_register(void)
-{
- vg_console_reg_cmd( "list", _vg_console_list, NULL );
- vg_console_reg_cmd( "exec", vg_console_exec, NULL );
-#if defined( VG_ENGINE )
- vg_console_reg_var( "cheats", &vg_console.cheats, k_var_dtype_i32, 0 );
-#endif
-}
-
-VG_API void _vg_console_init(void)
-{
-#if defined( VG_ENGINE )
- vg_console.registration_blocked = 1;
- vg_console_exec( 2, (const char *[]){ "auto.conf", "silent" } );
- _vg_add_exit_function( vg_console_write_persistent );
-#endif
-}
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_console.c"
-#else
-
-#define VG_VAR_F32( NAME, ... ) \
- { u32 flags=0x00; __VA_ARGS__ ;\
- vg_console_reg_var( #NAME, &NAME, k_var_dtype_f32, flags ); }
-
-#define VG_VAR_I32( NAME, ... ) \
- { u32 flags=0x00; __VA_ARGS__ ;\
- vg_console_reg_var( #NAME, &NAME, k_var_dtype_i32, flags ); }
-
-#define VG_VAR_PERSISTENT 0x1
-#define VG_VAR_CHEAT 0x2
-
-typedef struct vg_var vg_var;
-typedef struct vg_cmd vg_cmd;
-
-struct vg_console
-{
- struct vg_var
- {
- void *data;
- const char *name;
- enum vg_var_dtype
- {
- k_var_dtype_i32,
- k_var_dtype_u32,
- k_var_dtype_f32,
- k_var_dtype_str
- }
- data_type;
- u32 flags;
- }
- vars[ 128 ];
-
- struct vg_cmd
- {
- int (*function)( int argc, char const *argv[] );
- void (*poll_suggest)( int argc, char const *argv[] );
- const char *name;
- }
- functions[ 32 ];
-
-#if defined( VG_ENGINE )
- struct {
- const char *str;
- int len;
-
- u32 lev_score;
- }
- suggestions[12];
- u32 suggestion_count;
- int suggestion_select,
- suggestion_pastepos,
- suggestion_maxlen;
-#endif
-
- u32 var_count, function_count;
-
-#if defined( VG_ENGINE )
- char input[96],
- input_copy[96];
- char history[32][96];
- int history_last, history_pos, history_count;
-
- i32 enabled, cheats;
- bool auto_focus;
-#endif
-
- bool registration_blocked;
-}
-extern vg_console;
-
-VG_API void _vg_console_register(void);
-VG_API void _vg_console_init(void);
-
-void vg_console_reg_var( const char *alias, void *ptr, enum vg_var_dtype type, u32 flags );
-
-void vg_console_reg_cmd( const char *alias, int (*function)(int argc, const char *argv[]),
- void (*poll_suggest)(int argc, const char *argv[]) );
-
-void vg_execute_console_input( const char *cmd, bool silent, bool cheat_override );
-
-#endif
+++ /dev/null
-static void vg_db_touch( vg_db *db, u16 cache_id );
-
-/* util
- * ------------------------------------------------------------------------------------------------------------------ */
-
-static void vg_db_abort( vg_db *db, const char *message, ... )
-{
- fclose( db->fp );
- db->fp = NULL;
- va_list args;
- va_start( args, message );
- _vg_logx_va( stderr, NULL, "vg_db fatal", KRED, message, args );
- va_end( args );
- vg_fatal_error( "Database error\n" );
-}
-
-static u32 vg_dbhash( u8 *buf, u32 len )
-{
- /* djb2 */
- u32 hash = 5381;
- for( u32 i=0; i<len; i ++ )
- hash = ((hash << 5) + hash) + (u32)buf[i]; /* hash * 33 + c */
- return hash;
-}
-
-static u64 vg_db_allocate_physical_page( vg_db *db );
-static void vg_db_sync_page( vg_db *db, u16 cache_id );
-
-/* API
- * ------------------------------------------------------------------------------------------------------------------ */
-
-static void vg_db_commit( vg_db *db, FILE *fwal )
-{
- void *temp_page = malloc( VG_PAGE_SIZE );
- u64 last_good_checkpoint = 0,
- last_good_log = 0;
-
- if( fseek( fwal, 0, SEEK_SET ) )
- {
- free( temp_page );
- vg_warn( "WAL file was empty (assuming db is atomic)\n" );
- return;
- }
-
- vg_db_wal log;
- if( !fread( &log, sizeof(log), 1, fwal ) )
- {
- free( temp_page );
- vg_warn( "No checkpoints in WAL file (assuming db is atomic)\n" );
- return;
- }
-
- if( log.type != k_wal_log_checkpoint )
- vg_db_abort( db, "First log in WAL file was not a checkpoint. Invalid WAL file?\n" );
-
- /* replay until we run off the end */
- while(1)
- {
- u64 log_pos = ftell( fwal );
-
- /* read one log */
- if( !fread( &log, sizeof(log), 1, fwal ) )
- break;
-
- if( log.type == k_wal_log_data )
- {
- if( !fseek( fwal, log.data_size, SEEK_CUR ) )
- {
- if( fread( temp_page, log.data_size, 1, fwal ) )
- {
- if( fseek( db->fp, log.db_file_offset, SEEK_SET ) )
- vg_db_abort( db, "While playing back WAL, SEEK_SET(0x%lx) failed\n", log.db_file_offset );
- if( !fwrite( temp_page, log.data_size, 1, db->fp ) )
- vg_db_abort( db, "While playing back WAL, fwrite failed (0x%lx bytes)\n", log.data_size );
- last_good_log = log_pos;
- }
- else
- {
- vg_warn( "Truncated log entry while playing back WAL (not enough redo data)\n" );
- break;
- }
- }
- else
- {
- vg_warn( "Truncated log entry while playing back WAL (didn't make it to redo data)\n" );
- break;
- }
- }
- else
- {
- last_good_log = log_pos;
- last_good_checkpoint = log_pos;
- }
- }
-
- /* Rewind until we get back to a good checkpoint (if needed) */
- if( last_good_log != last_good_checkpoint )
- vg_warn( "Rewinding...\n" );
-
- u32 writes_away = 0;
- u64 rewind_cur = last_good_log;
- while( rewind_cur != last_good_checkpoint )
- {
- writes_away ++;
- if( fseek( fwal, rewind_cur, SEEK_SET ) )
- vg_db_abort( db, "While rewinding WAL, SEEK_SET(0x%lx) failed\n", rewind_cur );
- if( !fread( &log, sizeof(log), 1, fwal ) )
- vg_db_abort( db, "While rewinding WAL, fread failed\n" );
- if( fread( temp_page, log.data_size, 1, fwal ) )
- {
- vg_info( "Offset: %lx, size: %lu\n", log.db_file_offset, log.data_size );
- if( fseek( db->fp, log.db_file_offset, SEEK_SET ) )
- vg_db_abort( db, "While rewinding WAL, SEEK_SET(0x%lx) failed\n", log.db_file_offset );
- if( !fwrite( temp_page, log.data_size, 1, db->fp ) )
- vg_db_abort( db, "While rewinding WAL, fwrite failed (0x%lx bytes)\n", log.data_size );
- rewind_cur = log.previous_log_offset;
- }
- else
- {
- vg_warn( "Truncated log entry while playing back WAL (not enough redo data)\n" );
- break;
- }
- }
-
- if( last_good_log != last_good_checkpoint )
- vg_info( "Rewinding took %u writes back..\n", writes_away );
-
- fflush( db->fp );
- free( temp_page );
-}
-
-void vg_db_open( vg_db *db, const char *path, const char *wal_path )
-{
- u32 k_ident = 0xf32b1a00;
- vg_rand_seed( &db->rand, k_ident
-#ifndef DB_PREDICTABLE
- + time(NULL)
-#else
-#warning PREDICTABLE DB MODE ( DEBUGGING ONLY )
-#endif
- );
-
- db->fp = fopen( path, "rb+" );
- db->fp_wal = NULL;
- db->wal_path = wal_path;
- db->page_data = malloc( VG_PAGE_SIZE*VG_MAX_CACHED_PAGES );
- db->cache_count = 0;
- db->lru_old = 0;
- db->lru_young = 0;
- if( db->fp )
- {
- FILE *fwal = fopen( wal_path, "rb" );
- if( fwal )
- {
- vg_db_commit( db, fwal );
- fclose( fwal );
- remove( wal_path );
- }
-
- u32 ident;
- vg_db_read( db, 0, &ident, 4 );
- if( ident != k_ident )
- vg_db_abort( db, "Ident not found in db file '%s'\n", path );
- vg_db_read( db, offsetof(vg_db_header,userdata_address), &db->userdata_address, 8 );
- }
- else
- {
- db->fp = fopen( path, "wb+" );
- if( !db->fp )
- vg_db_abort( db, "fopen(wb+) failed for '%s'\n", path );
-
- vg_db_header init = {0};
- init.ident = k_ident;
- init._end = k_ident;
- init.physical_size = VG_PAGE_SIZE;
- if( !fwrite( &init, sizeof(init), 1, db->fp ) )
- vg_db_abort( db, "fwrite header failed'\n" );
-
- /* Sit it into the cache */
- u16 cache_id = ++db->cache_count;
- vg_db_page *page = &db->page_cache[ cache_id-1 ];
- memset( page, 0, sizeof(vg_db_page) );
- u64 page_base = 0;
- u32 hash = vg_dbhash( (void *)(&page_base), sizeof(page_base) ) & (VG_PAGE_CACHE_HASH_WIDTH-1u);
- db->hash_table[ hash ] = cache_id;
- vg_db_touch( db, cache_id );
- page->virtual_id = page_base;
- page->physical_offset = page_base;
- page->unwritten = 0;
- memcpy( db->page_data, &init, sizeof(init) );
-
- db->userdata_address = vg_db_virtual_allocate( db, VG_1GB );
-
- db->unprotect0 ++;
- vg_db_write( db, offsetof(vg_db_header,userdata_address), &db->userdata_address, 8 );
- vg_db_tree_init( db, offsetof(vg_db_header,address_tree) );
- db->unprotect0 --;
-
- vg_db_checkpoint( db );
- }
-}
-
-void vg_db_close( vg_db *db )
-{
- vg_db_checkpoint( db );
- if( db->fp_wal )
- {
- fclose( db->fp_wal );
- db->fp_wal = NULL;
- }
- fclose( db->fp );
- db->fp = NULL;
-#if 0
- if( db->fp_wal )
- {
- fclose( db->fp_wal );
- remove( db->wal_path ); /* dont need anymore */
- }
-#endif
- free( db->page_data );
- db->page_data = NULL;
-}
-
-/* paging
- * ------------------------------------------------------------------------------------------------------------------ */
-
-static u64 vg_db_allocate_physical_page( vg_db *db )
-{
- u64 physical_size, address;
- vg_db_read( db, 0x0lu + offsetof(vg_db_header,physical_size), &physical_size, sizeof(physical_size) );
- address = physical_size;
- physical_size += VG_PAGE_SIZE;
- db->unprotect0 ++;
- vg_db_write( db, 0x0lu + offsetof(vg_db_header,physical_size), &physical_size, sizeof(physical_size) );
- db->unprotect0 --;
- return address;
-}
-
-static void vg_db_sync_page( vg_db *db, u16 cache_id )
-{
- vg_db_page *page = &db->page_cache[ cache_id-1 ];
- if( page->unwritten )
- {
- //vg_low( "Syncing page @0x%lx to disk\n", page->physical_offset );
- if( fseek( db->fp, page->physical_offset, SEEK_SET ) )
- vg_db_abort( db, "SEEK_SET(%lx) failed\n", page->physical_offset );
- void *page_data = db->page_data + (u64)(cache_id-1)*VG_PAGE_SIZE;
- if( !fwrite( page_data, VG_PAGE_SIZE, 1, db->fp ) )
- vg_db_abort( db, "fwrite failed\n" );
- page->unwritten = 0;
- }
-}
-
-static void vg_db_touch( vg_db *db, u16 cache_id )
-{
- vg_db_page *page = &db->page_cache[ cache_id-1 ];
- /* unlink entirely */
- if( page->lru_younger )
- db->page_cache[ page->lru_younger-1 ].lru_older = page->lru_older;
- else if( db->lru_young == cache_id )
- db->lru_young = page->lru_older;
- if( page->lru_older )
- db->page_cache[ page->lru_older-1 ].lru_younger = page->lru_younger;
- else if( db->lru_old == cache_id )
- db->lru_old = page->lru_younger;
- /* re-link */
- page->lru_younger = 0;
- page->lru_older = db->lru_young;
- if( db->lru_young )
- {
- page->lru_older = db->lru_young;
- db->page_cache[ db->lru_young-1 ].lru_younger = cache_id;
- }
- db->lru_young = cache_id;
- if( !db->lru_old )
- db->lru_old = cache_id;
-}
-
-static void *vg_db_devirtualize( vg_db *db, u64 address, bool write, u64 *out_physical_address )
-{
- u64 page_base = address & ~(VG_PAGE_SIZE-1lu),
- inner_offset = address & (VG_PAGE_SIZE-1lu);
-
- /* Check hash table for our page */
- u32 hash = vg_dbhash( (void *)(&page_base), sizeof(page_base) ) & (VG_PAGE_CACHE_HASH_WIDTH-1u);
- u16 current = db->hash_table[ hash ];
- while( current )
- {
- vg_db_page *page = &db->page_cache[ current-1 ];
- if( page->virtual_id == page_base )
- {
- page->unwritten |= write;
- vg_db_touch( db, current );
- *out_physical_address = page->physical_offset + inner_offset;
- return db->page_data + ((u64)(current-1)*VG_PAGE_SIZE + inner_offset);
- }
- else
- current = page->hash_prev;
- }
-
- /* Translate address & create page if need be */
- u64 translated_page_base = page_base;
- if( address & VG_VIRTUAL_ADDRESS_BIT )
- {
- u64 tree_address = offsetof(vg_db_header,address_tree);
- translated_page_base = vg_db_translate( db, tree_address, page_base );
- if( translated_page_base == 0 )
- {
- u64 new_page = vg_db_allocate_physical_page( db );
- db->unprotect0 ++;
- vg_db_tree_map( db, tree_address, page_base, new_page );
- db->unprotect0 --;
- translated_page_base = new_page;
- }
- }
-
- /* Allocate cache ID */
- u16 cache_id = 0;
- vg_db_page *page = NULL;
- if( db->cache_count < VG_MAX_CACHED_PAGES )
- {
- cache_id = ++db->cache_count;
- page = &db->page_cache[ cache_id-1 ];
- memset( page, 0, sizeof(vg_db_page) );
- }
- else
- {
- cache_id = db->lru_old;
- vg_db_sync_page( db, cache_id );
- page = &db->page_cache[ cache_id-1 ];
- u32 old_hash = vg_dbhash( (void *)(&page->virtual_id), sizeof(page->virtual_id) ) & (VG_PAGE_CACHE_HASH_WIDTH-1u);
- u16 current = db->hash_table[ old_hash ], before = 0;
- while( current != cache_id )
- {
- before = current;
- current = db->page_cache[ current-1 ].hash_prev;
- }
- if( before ) db->page_cache[ before-1 ].hash_prev = page->hash_prev;
- else db->hash_table[ old_hash ] = page->hash_prev;
- }
- page->hash_prev = db->hash_table[ hash ];
- db->hash_table[ hash ] = cache_id;
- vg_db_touch( db, cache_id );
- page->virtual_id = page_base;
- page->physical_offset = translated_page_base;
- page->unwritten = write;
-
- /* read entire page into memory */
- u8 *page_data = (u8 *)(db->page_data + (u64)(cache_id-1)*VG_PAGE_SIZE);
- if( fseek( db->fp, translated_page_base, SEEK_SET ) )
- vg_db_abort( db, "SEEK_SET (%lx) failed\n", translated_page_base );
-
- bool eof = 0;
- for( u32 i=0; i<VG_PAGE_SIZE; i ++ )
- {
- if( !eof )
- {
- if( !fread( page_data+i, 1, 1, db->fp ) )
- {
- if( ferror( db->fp ) )
- vg_db_abort( db, "fread page failed\n" );
- else if( feof( db->fp ) )
- eof = 1;
- else
- vg_db_abort( db, "Invalid read condition\n" );
- }
- }
-
- if( eof )
- page_data[i] = 0;
- }
-
- *out_physical_address = translated_page_base + inner_offset;
- return page_data + inner_offset;
-}
-
-void vg_db_checkpoint( vg_db *db )
-{
- if( db->fp_wal == NULL )
- return;
-
- u64 file_pos = ftell( db->fp_wal );
- vg_db_wal log = {
- .type = k_wal_log_checkpoint,
- .previous_log_offset = db->previous_wal_log,
- .db_file_offset = 0,
- .data_size = 0
- };
- if( !fwrite( &log, sizeof(log), 1, db->fp_wal ) )
- vg_db_abort( db, "fwrite failed into WAL\n" );
- db->previous_wal_log = file_pos;
-
- if( db->wal_writes > 1000 )
- {
- fflush( db->fp_wal );
- vg_db_commit( db, db->fp_wal );
- fclose( db->fp_wal );
- remove( db->wal_path );
- db->wal_writes = 0;
- db->previous_wal_log = 0;
- db->fp_wal = NULL;
- }
-}
-
-void vg_db_xch( vg_db *db, u64 base_address, void *buf, u32 length, bool write )
-{
- u64 address = base_address,
- end = base_address + (u64)length;
-
- while( address != end )
- {
- u64 byte_count = VG_PAGE_SIZE - (address & (VG_PAGE_SIZE-1lu));
- if( address + byte_count > end )
- byte_count = end - address;
-
- u64 physical_address = 0;
- void *cache_buffer = vg_db_devirtualize( db, address, write, &physical_address ),
- *user_buffer = buf + (address-base_address);
- if( write )
- {
- if( (physical_address < VG_PAGE_SIZE) && !db->unprotect0 )
- {
- vg_db_abort( db, "Tried to write to the 0 page while unprotected!\n"
- " base_address: %llu, length: %u\n", base_address, length );
- }
-
- if( db->fp_wal == NULL )
- {
- db->fp_wal = fopen( db->wal_path, "wb+" );
- if( !db->fp_wal )
- vg_db_abort( db, "Failed to open wal file '%s'\n", db->wal_path );
-
- vg_db_wal log = {
- .type = k_wal_log_checkpoint,
- .previous_log_offset = 0,
- .db_file_offset = 0,
- .data_size = 0
- };
- if( !fwrite( &log, sizeof(log), 1, db->fp_wal ) )
- vg_db_abort( db, "fwrite failed into WAL\n" );
- }
-
- u64 file_pos = ftell( db->fp_wal );
- vg_db_wal log = {
- .type = k_wal_log_data,
- .previous_log_offset = db->previous_wal_log,
- .db_file_offset = physical_address,
- .data_size = byte_count
- };
- if( !fwrite( &log, sizeof(log), 1, db->fp_wal ) )
- vg_db_abort( db, "fwrite failed into WAL\n" );
- if( !fwrite( cache_buffer, byte_count, 1, db->fp_wal ) )
- vg_db_abort( db, "fwrite failed into WAL\n" );
- if( !fwrite( user_buffer, byte_count, 1, db->fp_wal ) )
- vg_db_abort( db, "fwrite failed into WAL\n" );
-
- db->previous_wal_log = file_pos;
- db->wal_writes ++;
- memcpy( cache_buffer, user_buffer, byte_count );
- }
- else
- memcpy( user_buffer, cache_buffer, byte_count );
-
- address += byte_count;
- }
-}
-
-u64 vg_db_virtual_allocate( vg_db *db, u64 bytes )
-{
- u64 page_count = 0;
- vg_db_read( db, 0x0lu + offsetof(vg_db_header,virtual_pages), &page_count, sizeof(page_count) );
- u64 pages = (bytes + (VG_PAGE_SIZE-1lu)) >> VG_PAGE_BITS,
- addr = page_count * VG_PAGE_SIZE;
- page_count += pages;
- db->unprotect0 ++;
- vg_db_write( db,0x0lu + offsetof(vg_db_header,virtual_pages), &page_count, sizeof(page_count) );
- db->unprotect0 --;
- return VG_VIRTUAL_ADDRESS_BIT | addr;
-}
-
-/* AA search tree
- * ------------------------------------------------------------------------------------------------------------------ */
-
-static u64 vg_db_skew( vg_db *db, u64 t_offset )
-{
- if( t_offset == 0 )
- return t_offset;
- vg_db_address_node t_node;
- vg_db_read( db, t_offset, &t_node, sizeof(t_node) );
- if( t_node.left_offset == 0 )
- return t_offset;
-
- u64 l_offset = t_node.left_offset;
- vg_db_address_node l_node;
- vg_db_read( db, l_offset, &l_node, sizeof(l_node) );
- if( l_node.level == t_node.level )
- {
- t_node.left_offset = l_node.right_offset;
- l_node.right_offset = t_offset;
- vg_db_write( db, t_offset, &t_node, sizeof(t_node) );
- vg_db_write( db, l_offset, &l_node, sizeof(l_node) );
- return l_offset;
- }
- else return t_offset;
-}
-
-static u64 vg_db_split( vg_db *db, u64 t_offset )
-{
- if( t_offset == 0 )
- return t_offset;
- vg_db_address_node t_node;
- vg_db_read( db, t_offset, &t_node, sizeof(t_node) );
- if( t_node.right_offset == 0 )
- return t_offset;
-
- u64 r_offset = t_node.right_offset;
- vg_db_address_node r_node;
- vg_db_read( db, r_offset, &r_node, sizeof(r_node) );
- if( r_node.right_offset == 0 )
- return t_offset;
-
- u64 rr_node_offset = r_node.right_offset;
- vg_db_address_node rr_node;
- vg_db_read( db, rr_node_offset, &rr_node, sizeof(rr_node) );
- if( t_node.level == rr_node.level )
- {
- t_node.right_offset = r_node.left_offset;
- r_node.left_offset = t_offset;
- r_node.level ++;
- vg_db_write( db, t_offset, &t_node, sizeof(t_node) );
- vg_db_write( db, r_offset, &r_node, sizeof(r_node) );
- return r_offset;
- }
- else return t_offset;
-}
-
-static u64 vg_db_tree_insert( vg_db *db, u64 t_offset, u64 x_offset, u64 key )
-{
- if( t_offset == 0 )
- return x_offset;
- vg_db_address_node t_node;
- vg_db_read( db, t_offset, &t_node, sizeof(t_node) );
- if( t_node.key <= key )
- t_node.left_offset = vg_db_tree_insert( db, t_node.left_offset, x_offset, key );
- else
- t_node.right_offset= vg_db_tree_insert( db, t_node.right_offset,x_offset, key );
- vg_db_write( db, t_offset, &t_node, sizeof(t_node) );
- t_offset = vg_db_skew( db, t_offset );
- t_offset = vg_db_split( db, t_offset );
- return t_offset;
-}
-
-void vg_db_tree_map( vg_db *db, u64 tree_address, u64 key, u64 value )
-{
- vg_db_address_tree tree;
- vg_db_read( db, tree_address, &tree, sizeof(tree) );
-
- u64 cluster_offset = (tree.last_node_offset & ~(VG_PAGE_SIZE-1lu));
- vg_db_address_cluster cluster;
- vg_db_read( db, cluster_offset, &cluster, sizeof(vg_db_address_cluster) );
- if( cluster.count == VG_ADDRESS_NODES_PER_CLUSTER )
- {
- cluster.count = 0;
- cluster_offset = vg_db_allocate_physical_page( db );
- }
-
- u64 new_node_offset = cluster_offset + sizeof(vg_db_address_cluster) + cluster.count*sizeof(vg_db_address_node);
- cluster.count ++;
- vg_db_write( db, cluster_offset, &cluster, sizeof(vg_db_address_cluster) );
-
- vg_db_address_node new_node;
- new_node.left_offset = 0;
- new_node.right_offset = 0;
- new_node.key = key;
- new_node.value = value;
- new_node.level = 0;
- vg_db_write( db, new_node_offset, &new_node, sizeof(new_node) );
-
- tree.last_node_offset = new_node_offset;
- tree.root_node_offset = vg_db_tree_insert( db, tree.root_node_offset, new_node_offset, key );
- vg_db_write( db, tree_address, &tree, sizeof(tree) );
-}
-
-u64 vg_db_translate( vg_db *db, u64 tree_address, u64 key )
-{
- vg_db_address_tree tree;
- vg_db_read( db, tree_address, &tree, sizeof(tree) );
-
- u64 t_offset = tree.root_node_offset;
- while( t_offset )
- {
- vg_db_address_node t_node;
- vg_db_read( db, t_offset, &t_node, sizeof(t_node) );
-
- if( t_node.key == key )
- {
- return t_node.value;
- break;
- }
- else
- {
- if( t_node.key <= key )
- t_offset = t_node.left_offset;
- else
- t_offset = t_node.right_offset;
- }
- }
- return 0;
-}
-
-void vg_db_tree_init( vg_db *db, u64 tree_address )
-{
- vg_db_address_tree tree = {0};
- vg_db_read( db, tree_address, &tree, sizeof(tree) );
- if( tree.last_node_offset == 0 )
- {
- tree.root_node_offset = 0;
- tree.last_node_offset = vg_db_allocate_physical_page( db );
- vg_db_write( db, tree_address, &tree, sizeof(tree) );
- }
-}
-
-void vg_db_tree_iter_init( vg_db *db, vg_tree_iter *iter, u64 tree_addr )
-{
- iter->depth = 0;
- iter->key = 0;
- iter->value = 0;
- iter->has_next = 0;
-
- struct vg_db_address_tree tree;
- vg_db_read( db, tree_addr, &tree, sizeof(tree) );
-
- /* go to far left */
- u64 t_offset = tree.root_node_offset;
- while( t_offset )
- {
- iter->route[ iter->depth ] = t_offset;
- vg_db_address_node *t_node = &iter->route_nodes[ iter->depth ];
- vg_db_read( db, t_offset, t_node, sizeof(vg_db_address_node) );
- t_offset = t_node->left_offset;
- iter->depth ++;
- iter->has_next = 1;
- }
-}
-
-bool vg_db_tree_iter( vg_db *db, vg_tree_iter *iter )
-{
- if( iter->has_next )
- {
- vg_db_address_node *t_node = &iter->route_nodes[ iter->depth-1 ];
- iter->key = t_node->key;
- iter->value = t_node->value;
-
- /* right once, then left all way */
- if( t_node->right_offset )
- {
- u64 t_offset = t_node->right_offset;
- while( t_offset )
- {
- iter->route[ iter->depth ] = t_offset;
- vg_db_address_node *t_node = &iter->route_nodes[ iter->depth ];
- vg_db_read( db, t_offset, t_node, sizeof(vg_db_address_node) );
- t_offset = t_node->left_offset;
- iter->depth ++;
- }
- }
- else
- {
- u64 t_offset = iter->route[ iter->depth-1 ];
- while(1)
- {
- iter->depth --;
- if( iter->depth == 0 )
- {
- iter->has_next = 0;
- break;
- }
-
- if( iter->route_nodes[ iter->depth-1 ].left_offset == t_offset )
- break;
- else
- t_offset = iter->route[ iter->depth-1 ];
- }
- }
-
- return 1;
- }
- else return 0;
-}
-
-/* Randomized skiplist
- * ------------------------------------------------------------------------------------------------------------------ */
-
-void vg_db_skipper_init( vg_db *db, u64 skipper_address, u32 max_entries )
-{
- vg_db_skipper skipper;
- vg_db_read( db, skipper_address, &skipper, sizeof(skipper) );
- if( skipper.skips_array_address == 0 )
- {
- skipper.skips_array_address = vg_db_virtual_allocate( db, sizeof(vg_db_skip)*max_entries );
- skipper.sentry.height = 7;
- for( u32 i=0; i<7; i ++ )
- skipper.sentry.links[i] = 0xffff;
- vg_db_write( db, skipper_address, &skipper, sizeof(skipper) );
- }
-}
-
-bool vg_db_skipper_find( vg_db *db, vg_skipper_context *ctx, u16 *out_index, void *comparand )
-{
- vg_db_skipper skipper;
- vg_db_read( db, ctx->address, &skipper, sizeof(skipper) );
-
- i32 level = skipper.sentry.height-1;
- while( level>=0 )
- {
- u16 next = skipper.sentry.links[level];
- if( next != 0xffff )
- {
- i32 cmp = ctx->fn_compare( ctx, comparand, next );
- if( cmp == 0 )
- {
- *out_index = next;
- return 1;
- }
- else if( cmp > 0 )
- level --;
- else
- {
- u64 skip_addr = skipper.skips_array_address + (u64)next*sizeof(vg_db_skip);
- vg_db_read( db, skip_addr, &skipper.sentry, sizeof(vg_db_skip) );
- }
- }
- else level --;
- }
- return 0;
-}
-
-void vg_db_skipper_placement( vg_db *db, vg_skipper_context *ctx, u16 item_index, void *comparand )
-{
- vg_db_skipper skipper;
- vg_db_read( db, ctx->address, &skipper, sizeof(skipper) );
-
- u16 path[7];
- i32 level = skipper.sentry.height-1;
- u16 current_index = 0xffff;
-
- while( level>=0 )
- {
- path[level] = current_index;
- u16 next = skipper.sentry.links[level];
- if( next == 0xffff )
- level --;
- else
- {
- i32 cmp = ctx->fn_compare( ctx, comparand, next );
- if( cmp >= 0 )
- level --;
- else
- {
- current_index = next;
- u64 skip_addr = skipper.skips_array_address + (u64)current_index*sizeof(vg_db_skip);
- vg_db_read( db, skip_addr, &skipper.sentry, sizeof(vg_db_skip) );
- }
- }
- }
-
- vg_db_skip skip={0};
- skip.height = 1;
- while( (skip.height < 7) && (vg_randu32( &db->rand ) & 0x1) )
- skip.height ++;
- for( u32 i=0; i<7; i ++ )
- skip.links[i] = 0xffff;
- for( i32 i=skip.height-1; i>=0; -- i )
- {
- u64 prev_addr;
- if( path[i] == 0xffff ) prev_addr = ctx->address+offsetof(vg_db_skipper,sentry);
- else prev_addr = skipper.skips_array_address + (u64)path[i]*sizeof(vg_db_skip);
- vg_db_skip prev;
- vg_db_read( db, prev_addr, &prev, sizeof(prev) );
- skip.links[i] = prev.links[i];
- prev.links[i] = item_index;
- vg_db_write( db, prev_addr, &prev, sizeof(prev) );
- }
- u64 our_addr = skipper.skips_array_address + (u64)item_index*sizeof(vg_db_skip);
- vg_db_write( db, our_addr, &skip, sizeof(skip) );
-}
-
-void vg_db_skipper_unplace( vg_db *db, vg_skipper_context *ctx, u16 item_index, void *comparand )
-{
- vg_db_skipper skipper;
- vg_db_read( db, ctx->address, &skipper, sizeof(skipper) );
-
- u16 path[7];
- i32 level = skipper.sentry.height-1;
- u16 current_index = 0xffff;
-
- while( level>=0 )
- {
- path[level] = current_index;
- u16 next = skipper.sentry.links[level];
- if( (next == 0xffff) || (next == item_index) )
- level --;
- else
- {
- i32 cmp = ctx->fn_compare( ctx, comparand, next );
- if( cmp > 0 )
- level --;
- else
- {
- current_index = next;
- u64 skip_addr = skipper.skips_array_address + (u64)current_index*sizeof(vg_db_skip);
- vg_db_read( db, skip_addr, &skipper.sentry, sizeof(vg_db_skip) );
- }
- }
- }
-
- u64 our_addr = skipper.skips_array_address + (u64)item_index*sizeof(vg_db_skip);
- vg_db_skip skip;
- vg_db_read( db, our_addr, &skip, sizeof(vg_db_skip) );
- for( u32 i=0; i<skip.height; i ++ )
- {
- u64 prev_addr;
- if( path[i] == 0xffff ) prev_addr = ctx->address+offsetof(vg_db_skipper,sentry);
- else prev_addr = skipper.skips_array_address + (u64)path[i]*sizeof(vg_db_skip);
- vg_db_skip prev;
- vg_db_read( db, prev_addr, &prev, sizeof(prev) );
- prev.links[i] = skip.links[i];
- vg_db_write( db, prev_addr, &prev, sizeof(prev) );
- }
-}
-
-void vg_db_skipper_iter_start( vg_db *db, vg_skipper_context *ctx )
-{
- vg_db_skipper skipper;
- vg_db_read( db, ctx->address, &skipper, sizeof(skipper) );
- ctx->iter_array_address = skipper.skips_array_address;
- ctx->iter_index = skipper.sentry.links[0];
-}
-
-bool vg_db_skipper_iter( vg_db *db, vg_skipper_context *ctx, u16 *out_index )
-{
- u16 return_index = ctx->iter_index;
- if( ctx->iter_index == 0xffff )
- return 0;
- else
- {
- vg_db_skip skip;
- u64 skip_addr = ctx->iter_array_address + (u64)ctx->iter_index*sizeof(vg_db_skip);
- vg_db_read( db, skip_addr, &skip, sizeof(skip) );
- ctx->iter_index = skip.links[0];
- *out_index = return_index;
- return 1;
- }
-}
-
-/* Dumb table
- * ------------------------------------------------------------------------------------------------------------------ */
-
-void vg_db_table_init( vg_db *db, u64 table_address, u32 structure_size, u32 max_entries )
-{
- vg_db_table table;
- vg_db_read( db, table_address, &table, sizeof(table) );
- if( table.array_address == 0 )
- {
- table.array_address = vg_db_virtual_allocate( db, structure_size*max_entries );
- table.max_entries = max_entries;
- table.structure_size = structure_size;
- vg_db_write( db, table_address, &table, sizeof(table) );
- }
-}
-
-u16 vg_db_table_count( vg_db *db, u64 table_address )
-{
- u16 count;
- vg_db_read( db, table_address + offsetof(vg_db_table,current_entries), &count, sizeof(count) );
- return count;
-}
-
-u64 vg_db_table_get( vg_db *db, u64 table_address, u16 index )
-{
- vg_db_table table;
- vg_db_read( db, table_address, &table, sizeof(table) );
- return table.array_address + (u64)index * (u64)table.structure_size;
-}
-
-u64 vg_db_table_append( vg_db *db, u64 table_address )
-{
- vg_db_table table;
- vg_db_read( db, table_address, &table, sizeof(table) );
- if( table.current_entries < table.max_entries )
- {
- u64 address = table.array_address + (u64)table.current_entries * (u64)table.structure_size;
- table.current_entries ++;
- vg_db_write( db, table_address, &table, sizeof(table) );
- return address;
- }
- else return 0;
-}
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_db.c"
-#else
-
-#define VG_PAGE_BITS 11
-#define VG_PAGE_SIZE (0x1lu<<VG_PAGE_BITS)
-#define VG_1GB 0x40000000lu
-#define U64_MAX 0xfffffffffffffffflu
-#define VG_VIRTUAL_ADDRESS_BIT (0x1lu << 63)
-#define VG_MAX_CACHED_PAGES 4096
-#define VG_PAGE_CACHE_HASH_WIDTH 1024
-#define VG_ADDRESS_NODES_PER_CLUSTER ((VG_PAGE_SIZE-sizeof(vg_db_address_cluster)) / sizeof(struct vg_db_address_node))
-
-typedef struct vg_db vg_db;
-typedef struct vg_db_header vg_db_header;
-typedef struct vg_db_page vg_db_page;
-typedef struct vg_db_address_cluster vg_db_address_cluster;
-typedef struct vg_db_address_node vg_db_address_node;
-typedef struct vg_db_address_tree vg_db_address_tree;
-typedef struct vg_db_table vg_db_table;
-typedef struct vg_db_skip vg_db_skip;
-typedef struct vg_db_skipper vg_db_skipper;
-typedef struct vg_tree_iter vg_tree_iter;
-
-struct vg_db_address_tree
-{
- u64 root_node_offset, last_node_offset;
-};
-
-struct vg_db_address_cluster
-{
- u16 count;
- struct vg_db_address_node
- {
- u64 left_offset, right_offset;
- u64 key, value;
- u32 level;
- }
- entries[];
-};
-
-struct vg_tree_iter
-{
- u64 route[32];
- vg_db_address_node route_nodes[32];
- u32 depth;
- bool has_next;
-
- u64 key, value;
-};
-
-struct vg_db_table
-{
- u16 max_entries, current_entries;
- u32 structure_size;
- u64 array_address;
-};
-
-struct vg_db_header
-{
- u32 ident, none0, none1, none2;
- u64 virtual_pages;
- u64 physical_size;
- u64 userdata_address;
- vg_db_address_tree address_tree;
- u32 _end;
-};
-
-struct vg_db_skip
-{
- u16 links[7];
- u8 height, none0;
-};
-
-struct vg_db_skipper
-{
- vg_db_skip sentry;
- u64 skips_array_address;
-};
-
-struct vg_db_page
-{
- u64 virtual_id, physical_offset;
- u16 hash_prev, lru_older, lru_younger;
- bool unwritten;
-};
-
-struct vg_db
-{
- FILE *fp, *fp_wal;
- const char *wal_path;
- u64 previous_wal_log;
- u32 wal_writes;
-
- vg_db_page page_cache[ VG_MAX_CACHED_PAGES ];
- u16 lru_old, lru_young, cache_count;
- u16 hash_table[ VG_PAGE_CACHE_HASH_WIDTH ];
-
- void *page_data;
- u64 userdata_address;
- vg_rand rand;
- u16 unprotect0;
-};
-
-enum wal_log_type
-{
- k_wal_log_data = 0x07,
- k_wal_log_checkpoint = 0x09
-};
-
-typedef struct vg_db_wal vg_db_wal;
-struct vg_db_wal
-{
- u8 type;
- u64 previous_log_offset, db_file_offset, data_size;
-};
-
-void vg_db_checkpoint( vg_db *db );
-void vg_db_open( vg_db *db, const char *path, const char *wal_path );
-void vg_db_close( vg_db *db );
-#define vg_db_read( DB, BASE, BUF, LEN ) vg_db_xch( DB, BASE, BUF, LEN, 0 )
-#define vg_db_write( DB, BASE, BUF, LEN ) vg_db_xch( DB, BASE, BUF, LEN, 1 )
-void vg_db_xch( vg_db *db, u64 base_address, void *buf, u32 length, bool write );
-u64 vg_db_virtual_allocate( vg_db *db, u64 bytes );
-
-/* Heavy duty AA tree (append only), translates u64 keys to u64 value */
-void vg_db_tree_init( vg_db *db, u64 tree_address );
-void vg_db_tree_map( vg_db *db, u64 tree_address, u64 key, u64 value );
-u64 vg_db_translate( vg_db *db, u64 tree_address, u64 key );
-void vg_db_tree_iter_init( vg_db *db, vg_tree_iter *iter, u64 tree_addr );
-bool vg_db_tree_iter( vg_db *db, vg_tree_iter *iter );
-
-/* Dumb table - Just an array in virtual address space */
-void vg_db_table_init( vg_db *db, u64 table_address, u32 structure_size, u32 max_entries );
-u16 vg_db_table_count( vg_db *db, u64 table_address );
-u64 vg_db_table_get( vg_db *db, u64 table_address, u16 index );
-u64 vg_db_table_append( vg_db *db, u64 table_address );
-
-/* Skipper - For indexing and sorting a dumb table */
-typedef struct vg_skipper_context vg_skipper_context;
-typedef i32 (*fn_skipper_comparator)( vg_skipper_context *ctx, void *comparand, u16 item_index );
-struct vg_skipper_context
-{
- u64 address, table_address;
- fn_skipper_comparator fn_compare;
-
- /* internal */
- u64 iter_array_address;
- u16 iter_index;
-};
-
-void vg_db_skipper_init( vg_db *db, u64 skipper_address, u32 max_entries );
-bool vg_db_skipper_find( vg_db *db, vg_skipper_context *ctx, u16 *out_index, void *comparand );
-void vg_db_skipper_placement( vg_db *db, vg_skipper_context *ctx, u16 item_index, void *comparand );
-void vg_db_skipper_unplace( vg_db *db, vg_skipper_context *ctx, u16 item_index, void *comparand );
-void vg_db_skipper_iter_start( vg_db *db, vg_skipper_context *ctx );
-bool vg_db_skipper_iter( vg_db *db, vg_skipper_context *ctx, u16 *out_index );
-
-#endif
+++ /dev/null
-#include "vg_vorbis.h"
-#include "vg_image.h"
-
-#undef STB_VORBIS_HEADER_ONLY
-#include "submodules/stb/stb_vorbis.c"
-#undef L
-#undef R
-#undef C
-
-#define STB_IMAGE_WRITE_IMPLEMENTATION
-#define STB_IMAGE_IMPLEMENTATION
-#include "vg/submodules/stb/stb_image.h"
-#include "vg/submodules/stb/stb_image_write.h"
-
-/*
- * adapted from stb_vorbis.h, since the original does not handle mono->stereo
- */
-int
-stb_vorbis_get_samples_float_interleaved_stereo( stb_vorbis *f, float *buffer,
- int len )
-{
- int n = 0, c = 1;
- if( f->channels < 2 ) c = 0;
-
- while( n < len ) {
- int k = f->channel_buffer_end - f->channel_buffer_start;
-
- if( n+k >= len )
- k = len - n;
-
- for( int j=0; j < k; ++j ) {
- *buffer++ = f->channel_buffers[ 0 ][f->channel_buffer_start+j];
- *buffer++ = f->channel_buffers[ c ][f->channel_buffer_start+j];
- }
-
- n += k;
- f->channel_buffer_start += k;
-
- if( n == len )
- break;
-
- if( !stb_vorbis_get_frame_float( f, NULL, NULL ))
- break;
- }
-
- return n;
-}
-
-/*
- * ........ more wrecked code sorry!
- */
-int
-stb_vorbis_get_samples_i16_downmixed( stb_vorbis *f, i16 *buffer, int len )
-{
- int n = 0, c = 1;
- if( f->channels < 2 ) c = 0;
-
- while( n < len ) {
- int k = f->channel_buffer_end - f->channel_buffer_start;
-
- if( n+k >= len )
- k = len - n;
-
- for( int j=0; j < k; ++j ) {
- float sl = f->channel_buffers[ 0 ][f->channel_buffer_start+j],
- sr = f->channel_buffers[ c ][f->channel_buffer_start+j];
-
- *buffer++ = vg_clampf( 0.5f*(sl+sr), -1.0f, 1.0f ) * 32767.0f;
- //*buffer++ = vg_clampf( sr, -1.0f, 1.0f ) * 32767.0f;
- }
-
- n += k;
- f->channel_buffer_start += k;
-
- if( n == len )
- break;
-
- if( !stb_vorbis_get_frame_float( f, NULL, NULL ))
- break;
- }
-
- return n;
-}
+++ /dev/null
-struct vg_engine vg =
-{
- .time_rate = 1.0,
- .time_fixed_delta = VG_TIMESTEP_FIXED,
-
- .thread_tasks = { [0] = { .buffer_size = VG_MB(20) },
- [1] = { .buffer_size = VG_MB(20) } },
- .exit_tasks = { .buffer_size = VG_KB(16) },
-
- .thread_contexts =
- {
- [0] = { .log_prefix = KMAG "1" },
- [1] = { .log_prefix = KCYN "2" },
- [2] = { .log_prefix = KGRN "3" }
- }
-};
-
-VG_API bool _vg_thread_has_flags( u32 flags )
-{
- struct vg_thread_context *context = SDL_TLSGet( vg.thread_tls );
- if( context )
- return (context->flags & flags) == flags;
- else
- return 0;
-}
-
-VG_API void _vg_thread_set_flags( u32 flags )
-{
- struct vg_thread_context *context = SDL_TLSGet( vg.thread_tls );
- VG_ASSERT( context );
- context->flags |= flags;
-}
-
-VG_API const c8 *_vg_thread_prefix(void)
-{
- struct vg_thread_context *context = SDL_TLSGet( vg.thread_tls );
- if( context )
- return context->log_prefix;
- else
- return "?";
-}
-
-VG_API void _vg_terminate(void)
-{
- VG_ASSERT( _vg_thread_has_flags( VG_THREAD_MAIN ) );
- vg_low( "vg: exiting\n" );
-
- /* Shutdown */
- vg_magi_save();
- vg_async_queue_end( &vg.exit_tasks, k_async_quit_when_empty );
- while( vg_async_process_next_task( &vg.exit_tasks ) ) {}
- _vg_steam_shutdown();
- _vg_window_shutdown();
- SDL_Quit();
- exit(0);
-}
-
-static int _vg_async_thread( void *pfn )
-{
- SDL_TLSSet( vg.thread_tls, &vg.thread_contexts[1], NULL );
- _vg_thread_set_flags( VG_THREAD_ASYNC );
- while( vg_async_process_next_task( &vg.thread_tasks[1] ) ) {}
- return 0;
-}
-
-VG_API u32 _vg_start_temp_frame(void)
-{
- struct vg_thread_context *context = SDL_TLSGet( vg.thread_tls );
- VG_ASSERT( context->temp_stack_depth < VG_TEMP_STACK_MAX );
- u32 offset = context->temporary_memory.offset;
- context->temp_offsets[ context->temp_stack_depth ++ ] = offset;
- return offset;
-}
-
-VG_API void _vg_end_temp_frame( u32 whence )
-{
- struct vg_thread_context *context = SDL_TLSGet( vg.thread_tls );
- VG_ASSERT( context->temp_stack_depth );
- context->temp_stack_depth --;
- VG_ASSERT( context->temp_offsets[ context->temp_stack_depth ] == whence );
- context->temporary_memory.offset = whence;
-}
-
-VG_API vg_stack_allocator *_vg_temp_stack(void)
-{
- struct vg_thread_context *context = SDL_TLSGet( vg.thread_tls );
- return &context->temporary_memory;
-}
-
-/* group control */
-VG_API void _vg_async_context_push_groups( u16 groups, bool exclusive )
-{
- struct vg_thread_context *context = SDL_TLSGet( vg.thread_tls );
-
- context->async_group_depth ++;
- VG_ASSERT( context->async_group_depth < VG_TEMP_STACK_MAX );
-
- if( !exclusive )
- groups |= context->async_groups[ context->async_group_depth-1 ];
-
- context->async_groups[ context->async_group_depth ] = groups;
-}
-
-VG_API void _vg_async_context_pop_groups(void)
-{
- struct vg_thread_context *context = SDL_TLSGet( vg.thread_tls );
-
- VG_ASSERT( context->async_group_depth );
- context->async_group_depth --;
-}
-
-VG_API u16 _vg_async_context_get_groups(void)
-{
- struct vg_thread_context *context = SDL_TLSGet( vg.thread_tls );
- return context->async_groups[ context->async_group_depth ];
-}
-
-VG_API void *_vg_async_alloc ( u32 thread_id_target, u32 bytes )
-{
- struct vg_thread_context *context = SDL_TLSGet( vg.thread_tls );
- VG_ASSERT( context->async_task == NULL );
- VG_ASSERT( context->async_task_queue == NULL );
- VG_ASSERT( (thread_id_target==0) || (thread_id_target==1) );
- if( thread_id_target==1 ) { VG_ASSERT( !_vg_thread_has_flags( VG_THREAD_BACKGROUND ) ); }
- else { VG_ASSERT( _vg_thread_has_flags( VG_THREAD_BACKGROUND ) ); }
-
- context->async_task_queue = &vg.thread_tasks[ thread_id_target ];
- context->async_task = vg_create_task( context->async_task_queue, bytes, VG_ASYNC_BLOCKING, "engine (No info)" );
- return vg_task_buffer( context->async_task_queue, context->async_task );
-}
-
-VG_API void _vg_async_send( void *check_buffer, vg_async_fn fn )
-{
- struct vg_thread_context *context = SDL_TLSGet( vg.thread_tls );
- VG_ASSERT( context->async_task && context->async_task_queue );
- VG_ASSERT( vg_task_buffer( context->async_task_queue, context->async_task ) == check_buffer );
- vg_task_send( context->async_task_queue, context->async_task, fn );
- context->async_task = NULL;
- context->async_task_queue = NULL;
-}
-
-struct exit_task
-{
- void (*fn)(void);
-};
-static void vg_call_exit( struct exit_task *in_args, vg_async_info *async )
-{
- in_args->fn();
-}
-
-VG_API void _vg_add_exit_function( void( *fn )( void ) )
-{
- _vg_async_context_push_groups( 0, 1 );
- vg_async_task *task = vg_create_task( &vg.exit_tasks, sizeof(struct exit_task), VG_ASYNC_CRIT, "engine exit (No info)" );
- struct exit_task *out_args = vg_task_buffer( &vg.exit_tasks, task );
- out_args->fn = fn;
- vg_task_send( &vg.exit_tasks, task, (vg_async_fn)vg_call_exit );
- _vg_async_context_pop_groups();
-}
-
-#ifdef _WIN32
-#include <windows.h>
-#include <processthreadsapi.h>
-#endif
-
-#include <signal.h>
-static void sync_signal_handler( int signum )
-{
- // We want signals to be caught by debuggers if we're just in the testing builds.
-#if defined( VG_RELEASE_MODE )
- if( signum == SIGSEGV ) vg_fatal_exit( "SIGSEGV" );
-# if !defined( _WIN32 )
- if( signum == SIGBUS ) vg_fatal_exit( "SIGBUS" );
-# endif
- if( signum == SIGFPE ) vg_fatal_exit( "SIGFPE" );
- if( signum == SIGILL ) vg_fatal_exit( "SIGILL" );
- vg_fatal_exit( "UNKNOWN SIGNAL" );
-#endif
-}
-
-static int cmd_die( int argc, const char *argv[] )
-{
- if( argc )
- {
- if( !strcmp( argv[0], "segv" ) )
- {
- vg_info( "Trying to make a segfault\n" );
- u32 *nothing = (void *)3;
- vg_info( "Uhm %u\n", *nothing );
- }
- }
- else
- vg_fatal_error( "VG FATAL ASSERT ERROR" );
- return 0;
-}
-
-static void _vg_engine_register(void)
-{
- vg_console_reg_var( "vg_fps_limit", &vg.fps_limit, k_var_dtype_i32, VG_VAR_PERSISTENT );
- vg_console_reg_var( "vg_quality", &vg.quality_profile, k_var_dtype_i32, VG_VAR_PERSISTENT );
- vg_console_reg_cmd( "die", cmd_die, NULL );
-}
-
-static void _vg_engine_init(void)
-{
- vg_info(" Copyright . . . -----, ,----- ,---. .---. \n" );
- vg_info(" 2021-2025 |\\ /| | / | | | | /| \n" );
- vg_info(" | \\ / | +-- / +----- +---' | / | \n" );
- vg_info(" | \\ / | | / | | \\ | / | \n" );
- vg_info(" | \\/ | | / | | \\ | / | \n" );
- vg_info(" ' ' '--' [] '----- '----- ' ' '---' "
- "SOFTWARE\n" );
-
- /* init SDL */
- vg_info( "SDL_INIT_VIDEO\n" );
- if( SDL_Init( SDL_INIT_VIDEO ) != 0 )
- {
- vg_error( "SDL_Init failed: %s\n", SDL_GetError() );
- exit(0);
- }
-
-#ifndef VG_NO_AUDIO
- vg_info( "SDL_INIT_AUDIO\n" );
- SDL_InitSubSystem( SDL_INIT_AUDIO );
-#endif
- vg_info( "SDL_INIT_GAMECONTROLLER\n" );
- SDL_InitSubSystem( SDL_INIT_GAMECONTROLLER );
- vg.base_path = SDL_GetBasePath();
-
- if( !vg_init_async_queue( &vg.thread_tasks[0] ) )
- vg_fatal_error( "Failed to create main task queue\n" );
- if( !vg_init_async_queue( &vg.thread_tasks[1] ) )
- vg_fatal_error( "Failed to create async task queue\n" );
- if( !vg_init_async_queue( &vg.exit_tasks ) )
- vg_fatal_error( "Failed to create exit task queue\n" );
-
- for( u32 i=0; i<3; i ++ )
- vg_stack_init( &vg.thread_contexts[i].temporary_memory, NULL, VG_MB(20), "Temporary memory stack" );
-
- SDL_CreateThread( _vg_async_thread, "vg: async", NULL );
- vg.profiler = _vg_profiler_create( "vg.core", 1000.0f/60.0f );
- vg_rand_seed( &vg.rand, 461 );
-}
-
-VG_API void vg_run( int argc, const char *argv[], vg_event_callback callback_fn )
-{
- /* Pre-init
- * -------------------------------------------------------- */
- vg.thread_tls = SDL_TLSCreate();
- SDL_TLSSet( vg.thread_tls, &vg.thread_contexts[0], NULL );
- _vg_thread_set_flags( VG_THREAD_MAIN );
- _vg_log_pre_init();
-
- /* launch options
- * --------------------------------------------------------------------------------------------------- */
- _vg_opt_init( argc, argv );
- const char *arg;
- if( vg_long_opt( "high-performance", "Turn graphics to lowest quality" ) )
- vg.quality_profile = k_quality_profile_low;
-
- if( (arg = vg_long_opt_arg( "load-step-delay", "Loader step delay (ms)" )) )
- vg.load_step_delay = atoi(arg);
-
- if( (arg = vg_long_opt_arg( "log", "Log output to text file (without console colours)" )) )
- {
- vg_log.plain_output_file = fopen( arg, "w" );
- if( !vg_log.plain_output_file )
- vg_error( "Could not open '%s' for logging.\n", arg );
- }
-
- if( vg_long_opt( "no-steam", "Disable Steam integration (Good idea for pirating)" ) )
- _steam_api.disabled = 1;
-
- callback_fn( (vg_event_info[]){{ .type = k_vg_event_opts }} );
-
- if( !_vg_opt_check() )
- {
- callback_fn( (vg_event_info[]){{ .type = k_vg_event_invalid_options }} );
- exit(0);
- }
-
- /* Crash watcher
- * --------------------------------------------------------------------------------------------------- */
-#ifdef _WIN32
- DWORD pid = GetCurrentProcessId();
-
- char report_args_buf[ 512 ];
- vg_str report_args;
- vg_strnull( &report_args, report_args_buf, sizeof(report_args_buf) );
- vg_strcat( &report_args, "vgcrashreport.exe " );
- vg_strcatu64( &report_args, pid, 16 );
- vg_strcat( &report_args, " " );
- vg_strcat( &report_args, vg_log.crash_path );
-
- STARTUPINFO si={0};
- PROCESS_INFORMATION pi={0};
- si.cb = sizeof(si);
-
- if( CreateProcess( NULL, report_args_buf, NULL, NULL, 0, BELOW_NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi ) == 0 )
- vg_error( "Could not start crash reporter. Reason: %d\n", GetLastError() );
- else
- vg_success( "Crash watcher started!\n" );
-#endif
-
- // We want signals to be caught by debuggers if we're just in the testing builds.
-#if defined( VG_RELEASE_MODE )
- signal( SIGSEGV, sync_signal_handler );
-# if !defined( _WIN32 )
- signal( SIGBUS, sync_signal_handler );
-# endif
- signal( SIGFPE, sync_signal_handler );
- signal( SIGILL, sync_signal_handler );
-#endif
-
- /* Registration step
- * ----------------------------------------------- */
- _vg_console_register();
- _vg_magi_register();
- _vg_settings_register();
- _vg_engine_register();
- _vg_rigidbody_register();
- _vg_audio_register();
- _vg_framebuffer_register();
- _vg_render_register();
- _vg_input_register();
- _vg_lines_register();
- _vg_profiler_register();
- _vg_mem_view_register();
- _vg_shaders_register();
- callback_fn( (vg_event_info[]){{ .type = k_vg_event_register }} );
-
- /* Init step
- * ---------------------------------------------------- */
- _vg_async_init();
- _vg_profiler_init();
- _vg_engine_init();
- _vg_console_init();
- _vg_window_init();
- _vg_shaders_init();
- _vg_ui_init();
- _vg_loader_init();
- _vg_tex_init();
- _vg_render_init();
- _vg_input_init();
- _vg_lines_init();
- _vg_rb_view_init();
-#if !defined( VG_NO_AUDIO )
- _vg_audio_init();
-#endif
- _vg_steam_init();
- callback_fn( (vg_event_info[]){{ .type = k_vg_event_init }} );
-
- vg_magi_restore();
-
- /* Frame pre-filter & timing
- * -------------------------------------------- */
-L_new_frame:
- _vg_profiler_tick( vg.profiler );
-
- vg.time_frame_delta = 0.0;
- vg.time_spinning = 0;
-
-L_filter_frame:
- vg.time_hp = SDL_GetPerformanceCounter();
- u64 dt_hp = vg.time_hp - vg.time_hp_last;
- vg.time_hp_last = vg.time_hp;
-
- f64 dt = (f64)dt_hp / (f64)SDL_GetPerformanceFrequency();
- vg.time_frame_delta += dt;
-
- /* TODO: limit time we can spend here */
- while( vg_async_has_work( &vg.thread_tasks[0] ) )
- {
- if( vg_async_process_next_task( &vg.thread_tasks[0] ) == 0 )
- _vg_terminate();
- }
-
- if( vg.fps_limit == 0 )
- vg.fps_limit = _vg_window.monitor_refresh_rate;
- if( vg.fps_limit < 24 )
- vg.fps_limit = 24;
- if( vg.fps_limit > 300 )
- vg.fps_limit = 300;
-
- f64 min_frametime = 1.0/(f64)vg.fps_limit,
- max_frametime = 1.0/(f64)24.0;
-
- if( vg.time_frame_delta < min_frametime )
- {
- /* TODO: we can use high res nanosleep on Linux here */
- f64 sleep_ms = (min_frametime-vg.time_frame_delta) * 1000.0;
- u32 ms = (u32)floor( sleep_ms );
- if( ms )
- SDL_Delay(ms);
- else
- vg.time_spinning ++;
- goto L_filter_frame;
- }
-
- if( vg.time_frame_delta > max_frametime )
- vg.time_frame_delta = max_frametime;
-
- /* New fame starts here
- * --------------------------------------------------------------------------------------------------------------- */
-
- vg.time_real += vg.time_frame_delta;
- vg.time_delta = vg.time_frame_delta * vg.time_rate;
- vg.time += vg.time_delta;
-
- /* SDL event loop */
- v2_zero( vg.mouse_wheel );
- v2_zero( vg.mouse_delta );
- SDL_Event event;
- while( SDL_PollEvent( &event ) )
- {
- if( event.type == SDL_KEYDOWN )
- {
- if( vg_console.enabled && (vg_ui.ctx.focused_control_type != k_ui_control_modal) )
- {
- if( (event.key.keysym.sym == SDLK_ESCAPE) || (event.key.keysym.scancode == SDL_SCANCODE_GRAVE) )
- {
- vg_console.enabled = 0;
- ui_defocus_all( &vg_ui.ctx );
- }
- else if( (event.key.keysym.mod & KMOD_CTRL) && (event.key.keysym.sym == SDLK_n) )
- console_suggest_next( &vg_ui.ctx );
- else if( (event.key.keysym.mod & KMOD_CTRL ) && (event.key.keysym.sym == SDLK_p) )
- console_suggest_prev( &vg_ui.ctx );
- else
- vg_ui_handle_sdl_key( &vg_ui.ctx, event.key.keysym );
- }
- else
- {
- if( event.key.keysym.scancode == SDL_SCANCODE_GRAVE )
- {
- vg_console.auto_focus = 1;
- vg_console.enabled = 1;
- }
- else
- vg_ui_handle_sdl_key( &vg_ui.ctx, event.key.keysym );
- }
- }
- else if( event.type == SDL_MOUSEWHEEL )
- {
- vg.mouse_wheel[0] += event.wheel.preciseX;
- vg.mouse_wheel[1] += event.wheel.preciseY;
- }
- else if( (event.type == SDL_CONTROLLERDEVICEADDED) || (event.type == SDL_CONTROLLERDEVICEREMOVED) )
- vg_input_device_event( &event );
- else if( event.type == SDL_CONTROLLERAXISMOTION ||
- event.type == SDL_CONTROLLERBUTTONDOWN ||
- event.type == SDL_CONTROLLERBUTTONUP )
- {
- vg_input_controller_event( &event );
- }
- else if( event.type == SDL_MOUSEMOTION )
- {
- vg.mouse_delta[0] += event.motion.xrel;
- vg.mouse_delta[1] += event.motion.yrel;
- }
- else if( event.type == SDL_WINDOWEVENT )
- {
- if( event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED )
- {
- _vg_window_size_changed();
- callback_fn( (vg_event_info[]){{ .type = k_vg_event_framebuffer_resize,
- .framebuffer = { .w = _vg_window.w, .h = _vg_window.h } }} );
- }
- else if( event.window.event == SDL_WINDOWEVENT_CLOSE )
- _vg_terminate();
- }
- else if( event.type == SDL_TEXTINPUT )
- ui_proc_utf8( &vg_ui.ctx, event.text.text );
- }
- vg.mouse_state = SDL_GetMouseState( &vg.mouse_pos[0], &vg.mouse_pos[1] );
- _vg_window_swap();
-
- vg_audio_preupdate();
- vg_process_inputs();
- vg_steam_frame();
-
- /* Update loop
- * ----------------------------------------------------------------------------------------------------------- */
- {
- _vg_profiler_enter_block( vg.profiler, "update" );
- vg.gameloop_stage = k_gameloop_update;
- callback_fn( (vg_event_info[]){{ .type = k_vg_event_pre_update }} );
-
- /* Fixed update loop */
- vg.gameloop_stage = k_gameloop_update_fixed;
- vg.fixed_iterations = 0;
- vg_lines.enabled = vg_lines.render;
- vg.time_fixed_accumulator += vg.time_delta;
-
- while( vg.time_fixed_accumulator >= vg.time_fixed_delta )
- {
- callback_fn( (vg_event_info[]){{ .type = k_vg_event_fixed_update }} );
- vg_lines.enabled = 0;
- vg.time_fixed_accumulator -= vg.time_fixed_delta;
-
- vg.fixed_iterations ++;
- if( vg.fixed_iterations == 8 )
- break;
- }
- vg_lines.enabled = vg_lines.render;
- vg.time_fixed_extrapolate = vg.time_fixed_accumulator / vg.time_fixed_delta;
-
- vg.gameloop_stage = k_gameloop_update;
- callback_fn( (vg_event_info[]){{ .type = k_vg_event_post_update }} );
- _vg_profiler_exit_block( vg.profiler );
- }
-
- if( vg_loader.loading_count == 0 )
- {
- /* Render loop
- * ------------------------------------------------------------------------------------------------------------ */
- _vg_profiler_enter_block( vg.profiler, "render" );
- vg.gameloop_stage = k_gameloop_rendering;
- callback_fn( (vg_event_info[]){{ .type = k_vg_event_render }} );
- _vg_profiler_exit_block( vg.profiler );
-
- /* ui --------------------------------------------------- */
- vg.gameloop_stage = k_gameloop_ui;
-
- ui_prerender( &vg_ui.ctx );
- vg_ui_set_screen( _vg_window.w, _vg_window.h );
- ui_update_mouse( &vg_ui.ctx, (ui_px[2]){ vg.mouse_pos[0], vg.mouse_pos[1] }, vg.mouse_state );
-
- if( vg_console.enabled )
- ui_ignore_input_frames( &vg_ui.ctx, 10 );
- callback_fn( (vg_event_info[]){{ .type = k_vg_event_gui, .gui = { .ctx = &vg_ui.ctx } }} );
- if( vg_console.enabled )
- {
- ui_ignore_input_frames( &vg_ui.ctx, 0 );
- ui_capture_mouse( &vg_ui.ctx, 1 );
- vg_console_draw( &vg_ui.ctx );
- }
-
- _vg_settings_gui( &vg_ui.ctx );
- vg_framebuffer_ui( &vg_ui.ctx );
- _vg_magi_render( &vg_ui.ctx );
- ui_postrender( &vg_ui.ctx, vg.time_frame_delta );
- vg_ui_post_update();
- }
- else
- vg_loader_render();
-
- if( vg.loader_ring > 0.01f )
- {
- vg_loader_render_ring( vg.loader_ring );
- vg.loader_ring -= vg.time_frame_delta * 0.5f;
- }
-
- vg_audio_lock();
- vg_audio_sync_ui_master_controls();
- vg_audio_unlock();
-
- goto L_new_frame;
-}
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_engine.c"
-#else
-
-/* configuration warnings */
-#if !defined( VG_TIMESTEP_FIXED )
- #warning VG_TIMESTEP_FIXED not defined; setting to 1/60
- #define VG_TIMESTEP_FIXED (1.0/60.0)
-#endif
-
-#if !defined( VG_3D )
- #if !defined( VG_2D )
- #warning VG_3D or VG_2D not defined; defining VG_3D
- #define VG_3D
- #endif
-#endif
-
-enum vg_event
-{
- k_vg_event_opts,
- k_vg_event_register,
- k_vg_event_init,
- k_vg_event_pre_update,
- k_vg_event_fixed_update,
- k_vg_event_post_update,
- k_vg_event_render,
- k_vg_event_gui,
- k_vg_event_framebuffer_resize,
- k_vg_event_invalid_options
-};
-
-typedef struct vg_event_info vg_event_info;
-struct vg_event_info
-{
- enum vg_event type;
- union
- {
- struct
- {
- ui_context *ctx;
- }
- gui;
-
- struct
- {
- i32 w, h;
- }
- framebuffer;
- };
-};
-
-typedef void (*vg_event_callback)( vg_event_info *info );
-
-/* API */
-VG_API void vg_run( int argc, const char *argv[], vg_event_callback fn );
-
-/* Main thread */
-enum quality_profile
-{
- k_quality_profile_high = 0,
- k_quality_profile_low = 1,
- k_quality_profile_min = 2
-};
-
-#define VG_THREAD_OWNS_SDL 0x1
-#define VG_THREAD_OWNS_OPENGL 0x2
-#define VG_THREAD_OWNS_STEAM 0x4
-#define VG_THREAD_BACKGROUND 0x100
-#define VG_THREAD_MAIN (VG_THREAD_OWNS_SDL|VG_THREAD_OWNS_OPENGL|VG_THREAD_OWNS_STEAM)
-#define VG_THREAD_ASYNC (VG_THREAD_BACKGROUND)
-#define VG_THREAD_MAIN_ID 0
-#define VG_THREAD_ASYNC_ID 1
-#define VG_TEMP_STACK_MAX 8
-
-VG_API bool _vg_thread_has_flags( u32 flags );
-VG_API void _vg_thread_set_flags( u32 flags );
-VG_API const c8 *_vg_thread_prefix(void);
-
-VG_API void _vg_async_context_push_groups( u16 groups, bool exclusive );
-VG_API void _vg_async_context_pop_groups(void);
-VG_API u16 _vg_async_context_get_groups(void);
-
-VG_API void *_vg_async_alloc( u32 thread_id_target, u32 bytes );
-VG_API void _vg_async_send ( void *check_buffer, vg_async_fn fn );
-VG_API void _vg_add_exit_function( void( *fn )( void ) );
-
-VG_API u32 _vg_start_temp_frame(void);
-VG_API void _vg_end_temp_frame( u32 whence );
-VG_API vg_stack_allocator *_vg_temp_stack(void);
-
-VG_API void _vg_terminate(void);
-
-struct vg_engine
-{
- /* Engine sync */
- SDL_TLSID thread_tls;
-
- struct vg_thread_context
- {
- u32 flags;
- vg_stack_allocator temporary_memory;
-
- u32 temp_stack_depth,
- temp_offsets[ VG_TEMP_STACK_MAX ];
-
- u16 async_groups[ VG_TEMP_STACK_MAX ];
- u32 async_group_depth;
-
- vg_async_task *async_task;
- vg_async_queue *async_task_queue;
- const c8 *log_prefix;
- }
- thread_contexts[3];
-
- vg_async_queue thread_tasks[2], exit_tasks;
- const c8 *base_path;
-
- i32 mouse_pos[2], mouse_state;
- v2f mouse_delta,
- mouse_wheel;
-
- /* Runtime */
- f64 time,
- time_real,
- time_delta,
- time_rate,
- time_fixed_accumulator,
- time_fixed_extrapolate,
- time_frame_delta;
- f32 time_fixed_delta;
- u64 time_hp, time_hp_last, time_spinning;
-
- int fixed_iterations;
-
- enum vg_gameloop_stage
- {
- k_gameloop_update,
- k_gameloop_update_fixed,
- k_gameloop_rendering,
- k_gameloop_ui
- }
- gameloop_stage;
-
- /* graphics */
-#if defined( VG_3D )
- m4x4f pv;
-#else
- m3x3f pv;
-#endif
-
- i32 quality_profile;
-
- f32 loader_ring;
- GLuint tex_missing;
- vg_rand rand;
- i32 load_step_delay;
-
- i32 fps_limit;
- u32 profiler;
-}
-extern vg;
-
-struct vg_setting_enum
-{
- i32 new_value, *actual_value;
-
- struct ui_enum_opt *options;
- u32 option_count;
- const char *label;
-};
-
-struct vg_setting_ranged_i32
-{
- i32 new_value, *actual_value, min, max;
- char buf[10];
- const char *label;
-};
-
-void ui_settings_ranged_i32_init( struct vg_setting_ranged_i32 *prop );
-void ui_settings_enum_init( struct vg_setting_enum *prop );
-bool vg_settings_enum_diff( struct vg_setting_enum *prop );
-bool vg_settings_enum( ui_context *ctx, struct vg_setting_enum *prop, ui_rect rect );
-void vg_settings_ui_header( ui_context *ctx, ui_rect inout_panel, const char *name );
-bool vg_settings_apply_button( ui_context *ctx, ui_rect inout_panel, bool validated );
-enum engine_status _vg_engine_status(void);
-
-#endif
+++ /dev/null
-#if !defined( VG_IMPLEMENTATION )
-typedef struct vg_font_char vg_font_char;
-typedef struct vg_font_face vg_font_face;
-typedef struct vg_font_sheet vg_font_sheet;
-
-struct vg_font_char
-{
- i16 x, y;
-};
-
-struct vg_font_face
-{
- const char *name;
- i16 cw, ch, sx, sy, baseline;
- vg_font_char map[256];
-};
-
-struct vg_font_sheet
-{
- i16 w, h;
- u32 bitmap[];
-};
-#endif
+++ /dev/null
-struct
-{
- vg_framebuffer *list[16];
- u32 count;
-}
-static _vg_framebuffer;
-
-VG_API vg_framebuffer *_vg_framebuffer_alloc( vg_stack_allocator *stack, u32 attachment_count, bool track )
-{
- u32 size = sizeof(vg_framebuffer) + sizeof(vg_framebuffer_attachment)*attachment_count;
- vg_framebuffer *fb = vg_stack_allocate( stack, size, 8, "Framebuffer metadata" );
- vg_zero_mem( fb, size );
-
- fb->attachment_count = attachment_count;
- if( track )
- {
- if( _vg_framebuffer.count != VG_ARRAY_LEN(_vg_framebuffer.list) )
- _vg_framebuffer.list[ _vg_framebuffer.count ++ ] = fb;
- else
- vg_fatal_error( "Framebuffer list is full, and tried to allocate another.\n");
- }
- return fb;
-}
-
-VG_API void vg_framebuffer_get_res( vg_framebuffer *fb, int *x, int *y )
-{
- if( fb->resolution_div )
- {
- *x = _vg_window.w / fb->resolution_div;
- *y = _vg_window.h / fb->resolution_div;
- }
- else
- {
- *x = fb->fixed_w;
- *y = fb->fixed_h;
- }
-}
-
-VG_API void vg_framebuffer_inverse_ratio( vg_framebuffer *fb, v2f inverse )
-{
- if( fb )
- {
- int x, y;
- vg_framebuffer_get_res( fb, &x, &y );
-
- v2f render = { fb->render_w, fb->render_h },
- original = { x, y };
-
- v2_div( render, original, inverse );
- }
- else
- {
- v2_div( (v2f){1.0f,1.0f}, (v2f){ _vg_window.w, _vg_window.h }, inverse );
- }
-}
-
-VG_API void vg_framebuffer_bind( vg_framebuffer *fb, f32 scaling )
-{
- int x, y;
- vg_framebuffer_get_res( fb, &x, &y );
-
- if( scaling != 1.0f )
- {
- x = scaling*(float)x;
- y = scaling*(float)y;
-
- x = VG_MAX( 16, x );
- y = VG_MAX( 16, y );
-
- fb->render_w = x;
- fb->render_h = y;
- }
- else
- {
- fb->render_w = x;
- fb->render_h = y;
- }
-
- glBindFramebuffer( GL_FRAMEBUFFER, fb->id );
- glViewport( 0, 0, x, y );
-}
-
-VG_TIER_0 void vg_framebuffer_bind_texture( vg_framebuffer *fb, u32 attachment, u32 slot )
-{
- vg_framebuffer_attachment *at = &fb->attachments[attachment];
-
- if( (at->purpose != k_framebuffer_attachment_type_texture) &&
- (at->purpose != k_framebuffer_attachment_type_texture_depth) )
- {
- vg_fatal_error( "illegal operation: bind non-texture framebuffer attachment to texture slot" );
- }
-
- vg_tex_bind( GL_TEXTURE_2D, &fb->attachments[attachment].tex, slot );
-}
-
-/*
- * Convert OpenGL attachment ID enum to string
- */
-#define FB_FORMAT_STR( E ) { E, #E },
-static const char *render_fb_attachment_str( GLenum e )
-{
- struct { GLenum e; const char *str; }
- formats[] =
- {
- FB_FORMAT_STR(GL_COLOR_ATTACHMENT0)
- FB_FORMAT_STR(GL_COLOR_ATTACHMENT1)
- FB_FORMAT_STR(GL_COLOR_ATTACHMENT2)
- FB_FORMAT_STR(GL_COLOR_ATTACHMENT3)
- FB_FORMAT_STR(GL_COLOR_ATTACHMENT4)
- FB_FORMAT_STR(GL_DEPTH_STENCIL_ATTACHMENT)
- };
-
- for( int i=0; i<VG_ARRAY_LEN(formats); i++ )
- if( formats[i].e == e )
- return formats[i].str;
-
- return "UNDEFINED";
-}
-
-/*
- * Convert OpenGL texture format enums from TexImage2D table 1,2 &
- * RenderBufferStorage Table 1, into strings
- */
-static const char *render_fb_format_str( GLenum format )
-{
- struct { GLenum e; const char *str; }
- formats[] =
- {
- /* Table 1 */
- FB_FORMAT_STR(GL_DEPTH_COMPONENT)
- FB_FORMAT_STR(GL_DEPTH_STENCIL)
- FB_FORMAT_STR(GL_RED)
- FB_FORMAT_STR(GL_RG)
- FB_FORMAT_STR(GL_RGB)
- FB_FORMAT_STR(GL_RGBA)
-
- /* Render buffer formats */
- FB_FORMAT_STR(GL_DEPTH_COMPONENT16)
- FB_FORMAT_STR(GL_DEPTH_COMPONENT24)
- FB_FORMAT_STR(GL_DEPTH_COMPONENT32F)
- FB_FORMAT_STR(GL_DEPTH24_STENCIL8)
- FB_FORMAT_STR(GL_DEPTH32F_STENCIL8)
- FB_FORMAT_STR(GL_STENCIL_INDEX8)
-
- /* Table 2 */
- FB_FORMAT_STR(GL_R8)
- FB_FORMAT_STR(GL_R8_SNORM)
- FB_FORMAT_STR(GL_R16)
- FB_FORMAT_STR(GL_R16_SNORM)
- FB_FORMAT_STR(GL_RG8)
- FB_FORMAT_STR(GL_RG8_SNORM)
- FB_FORMAT_STR(GL_RG16)
- FB_FORMAT_STR(GL_RG16_SNORM)
- FB_FORMAT_STR(GL_R3_G3_B2)
- FB_FORMAT_STR(GL_RGB4)
- FB_FORMAT_STR(GL_RGB5)
- FB_FORMAT_STR(GL_RGB8)
- FB_FORMAT_STR(GL_RGB8_SNORM)
- FB_FORMAT_STR(GL_RGB10)
- FB_FORMAT_STR(GL_RGB12)
- FB_FORMAT_STR(GL_RGB16_SNORM)
- FB_FORMAT_STR(GL_RGBA2)
- FB_FORMAT_STR(GL_RGBA4)
- FB_FORMAT_STR(GL_RGB5_A1)
- FB_FORMAT_STR(GL_RGBA8)
- FB_FORMAT_STR(GL_RGBA8_SNORM)
- FB_FORMAT_STR(GL_RGB10_A2)
- FB_FORMAT_STR(GL_RGB10_A2UI)
- FB_FORMAT_STR(GL_RGBA12)
- FB_FORMAT_STR(GL_RGBA16)
- FB_FORMAT_STR(GL_SRGB8)
- FB_FORMAT_STR(GL_SRGB8_ALPHA8)
- FB_FORMAT_STR(GL_R16F)
- FB_FORMAT_STR(GL_RG16F)
- FB_FORMAT_STR(GL_RGB16F)
- FB_FORMAT_STR(GL_RGBA16F)
- FB_FORMAT_STR(GL_R32F)
- FB_FORMAT_STR(GL_RG32F)
- FB_FORMAT_STR(GL_RGB32F)
- FB_FORMAT_STR(GL_RGBA32F)
- FB_FORMAT_STR(GL_R11F_G11F_B10F)
- FB_FORMAT_STR(GL_RGB9_E5)
- FB_FORMAT_STR(GL_R8I)
- FB_FORMAT_STR(GL_R8UI)
- FB_FORMAT_STR(GL_R16I)
- FB_FORMAT_STR(GL_R16UI)
- FB_FORMAT_STR(GL_R32I)
- FB_FORMAT_STR(GL_R32UI)
- FB_FORMAT_STR(GL_RG8I)
- FB_FORMAT_STR(GL_RG8UI)
- FB_FORMAT_STR(GL_RG16I)
- FB_FORMAT_STR(GL_RG16UI)
- FB_FORMAT_STR(GL_RG32I)
- FB_FORMAT_STR(GL_RG32UI)
- FB_FORMAT_STR(GL_RGB8I)
- FB_FORMAT_STR(GL_RGB8UI)
- FB_FORMAT_STR(GL_RGB16I)
- FB_FORMAT_STR(GL_RGB16UI)
- FB_FORMAT_STR(GL_RGB32I)
- FB_FORMAT_STR(GL_RGB32UI)
- FB_FORMAT_STR(GL_RGBA8I)
- FB_FORMAT_STR(GL_RGBA8UI)
- FB_FORMAT_STR(GL_RGBA16I)
- FB_FORMAT_STR(GL_RGBA16UI)
- FB_FORMAT_STR(GL_RGBA32I)
- FB_FORMAT_STR(GL_RGBA32UI)
- };
-
- for( int i=0; i<VG_ARRAY_LEN(formats); i++ )
- if( formats[i].e == format )
- return formats[i].str;
-
- return "UNDEFINED";
-}
-
-/*
- * Bind and allocate texture for framebuffer attachment
- */
-static void vg_framebuffer_allocate_texture( vg_framebuffer *fb, vg_framebuffer_attachment *a )
-{
- VG_ASSERT( _vg_thread_has_flags( VG_THREAD_OWNS_OPENGL ) );
- if( a->tex.name == 0 )
- return;
-
- int rx, ry;
- vg_framebuffer_get_res( fb, &rx, &ry );
-
- if( a->purpose == k_framebuffer_attachment_type_renderbuffer )
- {
- glBindRenderbuffer( GL_RENDERBUFFER, a->tex.name );
- glRenderbufferStorage( GL_RENDERBUFFER, a->internalformat, rx, ry );
- }
- else if( a->purpose == k_framebuffer_attachment_type_texture ||
- a->purpose == k_framebuffer_attachment_type_texture_depth )
- {
- glBindTexture( GL_TEXTURE_2D, a->tex.name );
- glTexImage2D( GL_TEXTURE_2D, 0, a->internalformat, rx, ry, 0, a->format, a->type, NULL );
- }
-}
-
-VG_TIER_0 void vg_framebuffer_init( vg_framebuffer *fb )
-{
- VG_ASSERT( _vg_thread_has_flags( VG_THREAD_OWNS_OPENGL ) );
- glGenFramebuffers( 1, &fb->id );
- glBindFramebuffer( GL_FRAMEBUFFER, fb->id );
-
- int rx, ry;
- vg_framebuffer_get_res( fb, &rx, &ry );
-
- vg_info( "allocate_framebuffer( %s, %dx%d )\n", fb->display_name, rx, ry );
- vg_info( "{\n" );
-
- GLenum colour_attachments[ fb->attachment_count ];
- u32 colour_count = 0;
-
- for( u32 j=0; j<fb->attachment_count; j++ )
- {
- vg_framebuffer_attachment *attachment = &fb->attachments[j];
-
- if( attachment->purpose == k_framebuffer_attachment_type_none )
- continue;
-
- vg_info( " %s: %s\n",
- render_fb_attachment_str( attachment->attachment ),
- render_fb_format_str( attachment->internalformat ) );
-
- if( attachment->purpose == k_framebuffer_attachment_type_renderbuffer )
- {
- glGenRenderbuffers( 1, &attachment->tex.name );
- attachment->tex.flags = VG_TEX_COMPLETE|VG_TEX_FRAMEBUFFER_ATTACHMENT|VG_TEX_PRIVATE|VG_TEX_NOMIP;
-
- vg_framebuffer_allocate_texture( fb, attachment );
- glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, attachment->tex.name );
- }
- else if( attachment->purpose == k_framebuffer_attachment_type_texture ||
- attachment->purpose == k_framebuffer_attachment_type_texture_depth )
- {
- glGenTextures( 1, &attachment->tex.name );
- attachment->tex.flags = VG_TEX_COMPLETE|VG_TEX_FRAMEBUFFER_ATTACHMENT|VG_TEX_LINEAR|VG_TEX_CLAMP|VG_TEX_NOMIP;
-
- vg_framebuffer_allocate_texture( fb, attachment );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
- glFramebufferTexture2D( GL_FRAMEBUFFER, attachment->attachment, GL_TEXTURE_2D, attachment->tex.name, 0 );
-
- if( attachment->purpose == k_framebuffer_attachment_type_texture )
- colour_attachments[ colour_count ++ ] = attachment->attachment;
- }
- }
-
- glDrawBuffers( colour_count, colour_attachments );
-
- /*
- * Check result
- */
- GLenum result = glCheckFramebufferStatus( GL_FRAMEBUFFER );
- if( result == GL_FRAMEBUFFER_COMPLETE )
- {
- vg_success( " status: complete\n" );
- vg_info( "}\n" );
- }
- else
- {
- if( result == GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT )
- vg_info( " status: Incomplete attachment" );
- else if( result == GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT )
- vg_info( " status: Missing attachment" );
- else if( result == GL_FRAMEBUFFER_UNSUPPORTED )
- vg_info( " status: Unsupported framebuffer format" );
- else
- vg_info( " status: Generic Error" );
- vg_info( "}\n" );
- vg_fatal_error( "Bad framebuffer\n" );
- }
-}
-
-VG_TIER_0 void vg_framebuffer_free( vg_framebuffer *fb )
-{
- glDeleteFramebuffers( 1, &fb->id );
-
- for( u32 j=0; j<fb->attachment_count; j++ )
- {
- vg_framebuffer_attachment *attachment = &fb->attachments[j];
-
- if( attachment->purpose == k_framebuffer_attachment_type_none )
- continue;
-
- if( attachment->purpose == k_framebuffer_attachment_type_renderbuffer )
- {
- glDeleteRenderbuffers( 1, &attachment->tex.name );
- vg_zero_mem( &attachment->tex, sizeof(vg_tex) );
- }
- else if( attachment->purpose == k_framebuffer_attachment_type_texture ||
- attachment->purpose == k_framebuffer_attachment_type_texture_depth )
- {
- vg_tex_delete( &attachment->tex );
- }
- }
-}
-
-VG_API void vg_framebuffer_ui( ui_context *ctx )
-{
- ui_px w = _vg_window.w/3,
- h = _vg_window.h/3;
-
- ui_rect frame = {0,0,_vg_window.w/3,_vg_window.h/3};
-
- for( int i=0; i<_vg_framebuffer.count; i++ )
- {
- vg_framebuffer *fb = _vg_framebuffer.list[i];
-
- for( int j=0; j<fb->attachment_count; j++ )
- {
- vg_framebuffer_attachment *at = &fb->attachments[j];
-
- if( !at->debug_view )
- continue;
-
- ui_fill( ctx, frame, 0xff000000 );
- if( at->purpose == k_framebuffer_attachment_type_renderbuffer )
- {
- ui_text( ctx, frame, "<hardware texture>", 1, k_ui_align_middle_center, 0 );
- }
- else
- {
- f32 img_ratio = (f32)fb->render_w / (f32)fb->render_h,
- frame_ratio = (f32)w / (f32)h;
-
- ui_rect img = { 0,0, 0,0 };
-
- if( img_ratio >= frame_ratio )
- {
- img[2] = w;
- img[3] = w / img_ratio;
- }
- else
- {
- img[2] = h * img_ratio;
- img[3] = h;
- }
-
- ui_rect_center( frame, img );
- ui_image( ctx, img, &fb->attachments[j].tex, 0 );
- }
-
- ui_rect panel;
- rect_copy( frame, panel );
- ui_info( ctx, panel, fb->display_name );
- ui_info( ctx, panel, at->display_name );
- ui_info( ctx, panel, render_fb_attachment_str( at->attachment ) );
- ui_info( ctx, panel, render_fb_format_str( at->internalformat ) );
- ui_info( ctx, panel, render_fb_format_str( at->format ) );
-
- frame[0] += w;
-
- if( (frame[0] + w) > _vg_window.w )
- {
- frame[0] = 0;
- frame[1] += h;
- }
- }
- }
-}
-
-static void vg_framebuffer_show( vg_framebuffer *fb, vg_framebuffer_attachment *at, int operation )
-{
- at->debug_view = operation;
- vg_info( "%s %s:%s\n", (operation? "shown": "hidden" ), fb->display_name, at->display_name );
-}
-
-/*
- * arg0: command "show"/"hide"
- * arg1: framebuffer name <name>/"all"
- * arg2: subname <name>/none
- */
-static int vg_framebuffer_control( int argc, char const *argv[] )
-{
- if( argc < 2 )
- {
- vg_error( "Usage: fb \"show/hide\" <name>/\"all\" <name>/none\n" );
- return 0;
- }
-
- int modify_all = 0,
- operation = 0;
-
- if( !strcmp( argv[0], "show" ) )
- operation = 1;
- else if( !strcmp( argv[0], "hide" ) )
- operation = 0;
- else
- {
- vg_error( "Unknown framebuffer operation: '%s'\n", argv[0] );
- return 0;
- }
-
- if( !strcmp( argv[1], "all" ) )
- modify_all = 1;
-
- for( int i=0; i<_vg_framebuffer.count; i++ )
- {
- vg_framebuffer *fb = _vg_framebuffer.list[i];
-
- for( int j=0; j<fb->attachment_count; j++ )
- {
- vg_framebuffer_attachment *at = &fb->attachments[j];
-
- if( at->purpose == k_framebuffer_attachment_type_none )
- continue;
-
- if( modify_all )
- {
- vg_framebuffer_show( fb, at, operation );
- }
- else
- {
- if( !strcmp( fb->display_name, argv[1] ) )
- {
- if( argc == 2 )
- vg_framebuffer_show( fb, at, operation );
- else if( !strcmp( at->display_name, argv[2] ) )
- vg_framebuffer_show( fb, at, operation );
- }
- }
- }
- }
-
- return 0;
-}
-
-static void vg_framebuffer_poll( int argc, char const *argv[] )
-{
- const char *term = argv[argc-1];
-
- if( argc == 1 )
- {
- console_suggest_score_text( "show", term, 0 );
- console_suggest_score_text( "hide", term, 0 );
- }
- else if( argc == 2 )
- {
- console_suggest_score_text( "all", term, 0 );
-
- for( int i=0; i<_vg_framebuffer.count; i++ )
- {
- vg_framebuffer *fb = _vg_framebuffer.list[i];
- console_suggest_score_text( fb->display_name, term, 0 );
- }
- }
- else if( argc == 3 )
- {
- int modify_all = 0;
-
- if( !strcmp( argv[1], "all" ) )
- modify_all = 1;
-
- for( int i=0; i<_vg_framebuffer.count; i++ )
- {
- vg_framebuffer *fb = _vg_framebuffer.list[ i ];
-
- for( int j=0; j<fb->attachment_count; j++ )
- {
- vg_framebuffer_attachment *at = &fb->attachments[j];
-
- if( at->purpose == k_framebuffer_attachment_type_none )
- continue;
-
- if( modify_all )
- {
- console_suggest_score_text( at->display_name, term, 0 );
- }
- else if( !strcmp( fb->display_name, argv[1] ) )
- {
- console_suggest_score_text( at->display_name, term, 0 );
- }
- }
- }
- }
-}
-
-VG_API void _vg_framebuffer_register(void)
-{
- vg_console_reg_cmd( "fb", vg_framebuffer_control, vg_framebuffer_poll );
-}
-
-VG_API void vg_framebuffer_update_sizes(void)
-{
- VG_ASSERT( _vg_thread_has_flags( VG_THREAD_OWNS_OPENGL ) );
-
- for( int i=0; i<_vg_framebuffer.count; i++ )
- {
- vg_framebuffer *fb = _vg_framebuffer.list[i];
- for( int j=0; j<fb->attachment_count; j++ )
- {
- vg_framebuffer_attachment *attachment = &fb->attachments[j];
- vg_framebuffer_allocate_texture( fb, attachment );
- }
- }
-}
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_framebuffer.c"
-#else
-typedef struct vg_framebuffer vg_framebuffer;
-typedef struct vg_framebuffer_attachment vg_framebuffer_attachment;
-
-#define VG_FRAMEBUFFER_GLOBAL 1
-#define VG_FRAMEBUFFER_SPECIALIZED 0
-
-struct vg_framebuffer
-{
- const c8 *display_name;
- int resolution_div, /* If 0: Use fixed_w, fixed_h.
- If non-0: Automatically size itself to
- the window resolution divided by
- this value */
- fixed_w,
- fixed_h,
-
- render_w, /* The currently rendering resolution */
- render_h;
- GLuint id;
- u32 attachment_count;
-
- struct vg_framebuffer_attachment
- {
- const c8 *display_name;
- enum vg_framebuffer_attachment_type
- {
- k_framebuffer_attachment_type_none,
- k_framebuffer_attachment_type_texture,
- k_framebuffer_attachment_type_renderbuffer,
- k_framebuffer_attachment_type_texture_depth
- }
- purpose;
-
- enum vg_framebuffer_quality_profile
- {
- k_framebuffer_quality_all,
- k_framebuffer_quality_high_only
- }
- quality;
-
- GLenum internalformat,
- format,
- type,
- attachment;
- vg_tex tex;
-
- /* Runtime */
- int debug_view;
- }
- attachments[];
-};
-
-/*
- * Initialize framebuffer system
- */
-VG_API void _vg_framebuffer_register(void);
-VG_API vg_framebuffer *_vg_framebuffer_alloc( vg_stack_allocator *stack, u32 attachment_count, bool track );
-
-/*
- * Get the current (automatically scaled or fixed) resolution of framebuffer
- */
-VG_API void vg_framebuffer_get_res( vg_framebuffer *fb, int *x, int *y );
-
-/*
- * Get the inverse ratio to project pixel coordinates (0->1920) to UV coordinates
- *
- * NOTE: won't necesarily use the full 0->1 range, but may index a subsection
- * of the framebuffer if using variable scale rendering.
- */
-VG_API void vg_framebuffer_inverse_ratio( vg_framebuffer *fb, v2f inverse );
-
-/*
- * Bind framebuffer for drawing to
- */
-VG_API void vg_framebuffer_bind( vg_framebuffer *fb, f32 scaling );
-
-/*
- * Bind framebuffer attachment's texture
- */
-VG_TIER_0 void vg_framebuffer_bind_texture( vg_framebuffer *fb, u32 attachment, u32 slot );
-
-/*
- * Allocate graphics memory and initialize
- */
-VG_TIER_0 void vg_framebuffer_init( vg_framebuffer *fb );
-VG_TIER_0 void vg_framebuffer_free( vg_framebuffer *fb );
-
-/*
- * Draw framebuffer debugging stuff
- */
-VG_API void vg_framebuffer_ui( ui_context *ctx );
-VG_API void vg_framebuffer_update_sizes(void);
-#endif
+++ /dev/null
-#pragma once
-#include "vg/submodules/stb/stb_image_write.h"
-
-//#define STBI_ONLY_JPEG
-#define STBI_NO_THREAD_LOCALS
-#include "vg/submodules/stb/stb_image.h"
+++ /dev/null
-f32 controller_deadzone = 0.05f;
-
-struct vg_input vg_input = {
- .active_controller_index = -2
-};
-
-u8 vg_getkey( SDL_Keycode kc )
-{
- SDL_Scancode sc = SDL_GetScancodeFromKey( kc );
- return vg_input.sdl_keys[sc];
-}
-
-/*
- * takes SDL device index, and tries to open that on any free channel
- */
-static int vg_open_gamecontroller( Sint32 index )
-{
- struct vg_controller *controller = NULL;
- int vg_id = 0;
- const char *name = SDL_GameControllerNameForIndex( index );
- SDL_JoystickID instance_id = SDL_JoystickGetDeviceInstanceID( index );
-
- if( instance_id == -1 ){
- vg_error( ". Invalid device index (vg_open_gamecontroller)\n" );
- return -1;
- }
-
- for( int j=0; j<VG_MAX_CONTROLLERS; j++ ){
- struct vg_controller *esta = &vg_input.controllers[j];
-
- if( esta->handle ){
- if( esta->instance_id == instance_id ){
- vg_warn( " . SDL_JoystickID[%d] is already in open at index #%d\n",
- esta->instance_id, j );
- return -1;
- }
- }
- else{
- if( !controller ){
- controller = &vg_input.controllers[j];
- vg_id = j;
- }
- }
- }
-
- if( controller )
- {
- controller->handle = SDL_GameControllerOpen( index );
- controller->instance_id = instance_id;
-
- if( controller->handle )
- {
- vg_success(
- " . opened SDL_JoystickID[%d] as controller '%s' at index #%d\n",
- instance_id, name, vg_id );
-
- for( u32 i=0; i< SDL_CONTROLLER_BUTTON_MAX; i++ )
- controller->buttons[i] = 0;
-
- for( u32 i=0; i< SDL_CONTROLLER_AXIS_MAX; i++ )
- controller->axises[i] = 0.0f;
-
- if( vg_input.active_controller_index == -2 )
- {
- vg_input.active_controller_index = vg_id;
- vg_input.display_input_method = k_input_method_controller;
- vg_input.display_input_type = SDL_GameControllerGetType( controller->handle );
- }
-
- return vg_id;
- }
- else{
- vg_error( ". Failed to attach game controller '%s'. Reason: %s\n",
- name, SDL_GetError() );
- return -1;
- }
- }
- else{
- vg_error( ". Too many controllers open! ignoring '%s'\n", name );
- return -1;
- }
-}
-
-void vg_input_device_event( SDL_Event *ev )
-{
- if( ev->type == SDL_CONTROLLERDEVICEADDED ){
- int is_controller = SDL_IsGameController( ev->cdevice.which );
- const char *name = SDL_JoystickNameForIndex( ev->cdevice.which );
-
- Sint32 index = ev->cdevice.which;
- SDL_JoystickID instance_id = SDL_JoystickGetDeviceInstanceID( index );
- vg_info( "SDL_CONTROLLERDEVICEADDED | device index: %d, name: '%s'\n",
- index, name );
-
- if( is_controller ){
- vg_open_gamecontroller( index );
- }
- }
- else if( ev->type == SDL_CONTROLLERDEVICEREMOVED ){
- vg_info( "SDL_CONTROLLERDEVICEREMOVED | instance_id: %d\n", ev->cdevice.which );
-
- for( int i=0; i<VG_MAX_CONTROLLERS; i++ ){
- struct vg_controller *controller = &vg_input.controllers[i];
-
- if( controller->handle ){
- if( controller->instance_id == ev->cdevice.which ){
- vg_info( " . closing controller at index #%d\n", i );
- SDL_GameControllerClose( controller->handle );
- controller->handle = NULL;
- controller->instance_id = -1;
-
- if( vg_input.active_controller_index == i ){
- vg_input.active_controller_index = -1;
- vg_input.display_input_method = k_input_method_kbm;
- vg_info( "display_input: k_input_method_kbm\n" );
- }
- break;
- }
- }
- }
- }
-}
-
-static void vg_input_set_active_controller( int index, const char *why )
-{
- if( vg_input.active_controller_index != index )
- {
- vg_input.display_input_type = SDL_GameControllerGetType( vg_input.controllers[index].handle );
- vg_input.active_controller_index = index;
- vg_info( "Switching controller index to #%d. (%s)\n", index, why );
- }
-
- if( vg_input.display_input_method != k_input_method_controller )
- {
- vg_input.display_input_method = k_input_method_controller;
- vg_info( "Switching input method to controller. (%s)\n", why );
- }
-}
-
-void vg_input_controller_event( SDL_Event *ev )
-{
- if( ev->type == SDL_CONTROLLERAXISMOTION )
- {
- for( int i=0; i<VG_MAX_CONTROLLERS; i++ )
- {
- struct vg_controller *esta = &vg_input.controllers[i];
-
- if( ev->caxis.which == esta->instance_id )
- {
- float value = (float)ev->caxis.value / 32767.0f;
-
- if( ev->caxis.axis == SDL_CONTROLLER_AXIS_LEFTX ||
- ev->caxis.axis == SDL_CONTROLLER_AXIS_LEFTY ||
- ev->caxis.axis == SDL_CONTROLLER_AXIS_RIGHTX ||
- ev->caxis.axis == SDL_CONTROLLER_AXIS_RIGHTY )
- {
- float deadz = vg_clampf( controller_deadzone, 0.0f, 0.999f ),
- high = vg_maxf( 0.0f, fabsf(value) - deadz );
-
- value = vg_signf(value) * (high / (1.0f-deadz));
- if( fabsf(value) > 0.5f )
- vg_input_set_active_controller( i, "Stick pushed >|0.5|" );
- }
-
- esta->axises[ ev->caxis.axis ] = value;
- break;
- }
- }
- }
- else if( ev->type == SDL_CONTROLLERBUTTONDOWN )
- {
- for( int i=0; i<VG_MAX_CONTROLLERS; i++ )
- {
- struct vg_controller *esta = &vg_input.controllers[i];
- if( esta->instance_id == ev->cbutton.which )
- {
- vg_input_set_active_controller( i, "Button press" );
- esta->buttons[ ev->cbutton.button ] = 1;
- break;
- }
- }
- }
- else if( ev->type == SDL_CONTROLLERBUTTONUP )
- {
- for( int i=0; i<VG_MAX_CONTROLLERS; i++ )
- {
- struct vg_controller *esta = &vg_input.controllers[i];
- if( ev->cbutton.which == esta->instance_id )
- {
- esta->buttons[ ev->cbutton.button ] = 0;
- break;
- }
- }
- }
-}
-
-void vg_process_inputs(void)
-{
- int count;
- vg_input.sdl_keys = SDL_GetKeyboardState( &count );
- vg_input.sdl_mouse = SDL_GetMouseState(NULL,NULL);
-
- bool pressed_key = 0, moved_mouse = 0, clicked_mouse = 0;
- int pressed_id = -1;
-
- for( int i=0; i<count; i++ )
- {
- if( vg_input.sdl_keys[i] )
- {
- pressed_id = i;
- pressed_key = 1;
- break;
- }
- }
-
- if( vg_input.sdl_mouse & (SDL_BUTTON(SDL_BUTTON_LEFT)|SDL_BUTTON(SDL_BUTTON_RIGHT)|SDL_BUTTON(SDL_BUTTON_MIDDLE)) )
- {
- clicked_mouse = 1;
- }
-
- vg_input.hidden_mouse_travel += v2_length( vg.mouse_delta );
- if( vg_input.hidden_mouse_travel > 64.0f )
- {
- moved_mouse = 1;
- vg_input.hidden_mouse_travel = 0.0f;
- }
-
- if( vg_input.display_input_method != k_input_method_kbm )
- {
- if( pressed_key )
- {
- vg_input.display_input_method = k_input_method_kbm;
- vg_info( "display_input: k_input_method_kbm (keyboard %d)\n", pressed_id );
- }
-
- if( moved_mouse )
- {
- vg_input.display_input_method = k_input_method_kbm;
- vg_info( "display_input: k_input_method_kbm (mouse move)\n" );
- }
-
- if( clicked_mouse )
- {
- vg_input.display_input_method = k_input_method_kbm;
- vg_info( "display_input: k_input_method_kbm (mouse click)\n" );
- }
- }
- else
- vg_input.hidden_mouse_travel = 0.0f;
-}
-
-VG_API void _vg_input_register(void)
-{
- VG_VAR_F32( controller_deadzone, flags=VG_VAR_PERSISTENT );
-}
-
-static void vg_input_free(void)
-{
- for( int i=0; i<VG_MAX_CONTROLLERS; i++ )
- {
- struct vg_controller *controller = &vg_input.controllers[i];
-
- if( controller->handle )
- {
- SDL_GameControllerClose( controller->handle );
- controller->handle = NULL;
- }
- }
-}
-
-VG_API void _vg_input_init(void)
-{
- VG_ASSERT( _vg_thread_has_flags( VG_THREAD_OWNS_SDL ) );
-
- vg_info( "Checking for controllers\n" );
- SDL_GameControllerAddMappingsFromFile( "gamecontrollerdb.txt" );
-
- int joy_count = SDL_NumJoysticks();
- for( int i=0; i<joy_count; i++ )
- {
- const char *name = SDL_JoystickNameForIndex( i );
- int is_controller = SDL_IsGameController(i);
-
- vg_info( "%d: %s [controller: %d]\n", i, name, is_controller );
-
- if( is_controller )
- vg_open_gamecontroller( i );
- }
-
- _vg_add_exit_function( vg_input_free );
-}
-
-struct vg_controller *vg_active_controller(void)
-{
- if( vg_input.active_controller_index >= 0 )
- return &vg_input.controllers[vg_input.active_controller_index];
- else
- return NULL;
-}
-
-u8 vg_controller_button( SDL_GameControllerButton button )
-{
- struct vg_controller *c = vg_active_controller();
- if( c ) return c->buttons[ button ];
- else return 0;
-}
-
-f32 vg_controller_axis( SDL_GameControllerAxis axis )
-{
- struct vg_controller *c = vg_active_controller();
- if( c ) return c->axises[ axis ];
- else return 0;
-}
-
-static void vg_input_apply_to_u8( vg_input_op mode, u8 data, u8 *inout_result )
-{
- if ( mode == vg_mode_absmax ) *inout_result |= data;
- else if( mode == vg_mode_mul ) *inout_result &= data;
- else vg_fatal_error( "mode not supported for destination type (%d)", mode );
-}
-
-static void vg_input_apply_to_f32( vg_input_op mode, f32 data, f32 *inout_result )
-{
- if( mode == vg_mode_absmax )
- {
- if( fabsf(data) > fabsf(*inout_result) )
- *inout_result = data;
- }
- else if( mode == vg_mode_max ) *inout_result = vg_maxf(*inout_result,data);
- else if( mode == vg_mode_mul ) *inout_result *= (f32)data;
- else if( mode == vg_mode_sub ) *inout_result -= (f32)data;
- else if( mode == vg_mode_add ) *inout_result += (f32)data;
- else vg_fatal_error( "mode not supported for destination type (%d)", mode );
-}
-
-/*
- * Run an input program. out_result must point to memory with sufficient
- * storage respective to the size set by type.
- */
-void vg_exec_input_program( enum vg_input_type type, vg_input_op *ops, void *out_result )
-{
- u8 *out_button = NULL;
- f32 *out_joy = NULL;
-
- if( type == k_vg_input_type_button_u8 )
- {
- out_button = out_result;
- *out_button = 0;
- }
- else if( type == k_vg_input_type_axis_f32 )
- {
- out_joy = out_result;
- out_joy[0] = 0.0f;
- }
- else if( type == k_vg_input_type_joy_v2f )
- {
- out_joy = out_result;
- out_joy[0] = 0.0f;
- out_joy[1] = 0.0f;
- }
-
- /* computer state */
- vg_input_op mode = vg_mode_absmax;
- u32 pc = 0, index = 0;
-
-next_code:;
- vg_input_op op = ops[ pc ++ ];
-
- if( (op >= vg_mode_mul) && (op <= vg_mode_max) )
- mode = op;
- else if( (op == vg_keyboard) || (op == vg_mouse) || (op == vg_joy_button) ){
- u8 state = 0;
-
- if( op == vg_keyboard )
- state = vg_getkey(ops[pc ++]);
- else if( op == vg_mouse )
- state = (vg_input.sdl_mouse & SDL_BUTTON(ops[pc ++]))?1:0;
- else
- state = vg_controller_button(ops[pc ++]);
-
- if( type == k_vg_input_type_button_u8 )
- vg_input_apply_to_u8( mode, state, out_button );
- else
- vg_input_apply_to_f32( mode, (f32)state, &out_joy[index] );
- }
- else if( op == vg_joy_axis ){
- f32 state = vg_controller_axis( ops[pc ++] );
- if( type == k_vg_input_type_button_u8 )
- vg_input_apply_to_u8( mode, state>0.5f?1:0, out_button );
- else
- vg_input_apply_to_f32( mode, state, &out_joy[index] );
- }
- else if( (op == vg_joy_ls) || (op == vg_joy_rs) ){
- if( type == k_vg_input_type_joy_v2f ){
- vg_input_apply_to_f32( mode,
- vg_controller_axis( op==vg_joy_ls? SDL_CONTROLLER_AXIS_LEFTX:
- SDL_CONTROLLER_AXIS_RIGHTX),
- &out_joy[0] );
- vg_input_apply_to_f32( mode,
- vg_controller_axis( op==vg_joy_ls? SDL_CONTROLLER_AXIS_LEFTY:
- SDL_CONTROLLER_AXIS_RIGHTY),
- &out_joy[1] );
- }
- }
- else if( op == vg_index )
- index = ops[pc ++];
- else if( op == vg_end )
- return;
- else if( op == vg_normalize )
- v2_normalize( out_joy );
- else if( op == vg_gui_visible )
- pc ++;
- else
- vg_fatal_error( "unknown op (%u)\n", op );
-
- goto next_code;
-}
-
-/*
- * Get vendor specific button glyphs based on SDL button ID
- */
-const char *controller_button_str( SDL_GameControllerButton button )
-{
- static const char *controller_glyphs[ SDL_CONTROLLER_BUTTON_MAX ][2] = {
- /* xbox/generic playstation */
- [ SDL_CONTROLLER_BUTTON_A ] = { KGRN "\x06\x02\x85",KBLU "\x06\x02\x82" },
- [ SDL_CONTROLLER_BUTTON_B ] = { KRED "\x06\x02\x86",KRED "\x06\x02\x81" },
- [ SDL_CONTROLLER_BUTTON_X ] = { KBLU "\x06\x02\x83",KMAG "\x06\x02\x7f" },
- [ SDL_CONTROLLER_BUTTON_Y ] = { KYEL "\x06\x02\x84",KGRN "\x06\x02\x80" },
- [ SDL_CONTROLLER_BUTTON_LEFTSTICK ] = { "\x87","\x87" },
- [ SDL_CONTROLLER_BUTTON_RIGHTSTICK ] = { "\x8b","\x8b" },
- [ SDL_CONTROLLER_BUTTON_LEFTSHOULDER ] = { "\x91","\x91" },
- [ SDL_CONTROLLER_BUTTON_RIGHTSHOULDER ]= { "\x92","\x92" },
- [ SDL_CONTROLLER_BUTTON_DPAD_LEFT ] = { "\x93","\x93" },
- [ SDL_CONTROLLER_BUTTON_DPAD_UP ] = { "\x94","\x94" },
- [ SDL_CONTROLLER_BUTTON_DPAD_RIGHT ] = { "\x95","\x95" },
- [ SDL_CONTROLLER_BUTTON_DPAD_DOWN ] = { "\x96","\x96" },
- [ SDL_CONTROLLER_BUTTON_GUIDE ] = { "\x91","\x91" },
- };
-
- if( vg_input.display_input_type == SDL_CONTROLLER_TYPE_PS3 ||
- vg_input.display_input_type == SDL_CONTROLLER_TYPE_PS4 ||
- vg_input.display_input_type == SDL_CONTROLLER_TYPE_PS5 )
- {
- return controller_glyphs[ button ][ 1 ];
- }
- else if( vg_input.display_input_type ==
- SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO ||
- vg_input.display_input_type ==
- SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT ||
- vg_input.display_input_type ==
- SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR ||
- vg_input.display_input_type ==
- SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT )
- {
- return NULL;
- }
- else
- return controller_glyphs[ button ][ 0 ];
-}
-
-/*
- * Cat keyboard key string. special_glyphs include SR glyphs
- */
-void vg_keyboard_key_string( vg_str *str, u32 key, int special_glyphs )
-{
- if( (key >= SDLK_a) && (key <= SDLK_z) ){
- key = (key-SDLK_a)+(u32)'A';
- vg_strcatch( str, key );
- }
- else if( (key == SDLK_LSHIFT) || (key == SDLK_RSHIFT) )
- vg_strcat( str, special_glyphs? "\x9e": "shift" );
- else if( (key == SDLK_LCTRL) || (key == SDLK_RCTRL) )
- vg_strcat( str, special_glyphs? "\x9f": "ctrl" );
- else if( (key == SDLK_LALT) || (key == SDLK_RALT) )
- vg_strcat( str, special_glyphs? "\xa0": "alt" );
- else if( key == SDLK_SPACE )
- vg_strcat( str, special_glyphs? "\xa1": "space" );
- else if( (key == SDLK_RETURN) || (key == SDLK_RETURN2) )
- vg_strcat( str, special_glyphs? "\xa2": "return" );
- else if( key == SDLK_ESCAPE )
- vg_strcat( str, special_glyphs? "\xa3": "escape" );
- else if( key == SDLK_RIGHT )
- vg_strcat( str, special_glyphs? "\x95 ": "right" );
- else if( key == SDLK_LEFT )
- vg_strcat( str, special_glyphs? "\x93 ": "left" );
- else if( key == SDLK_UP )
- vg_strcat( str, special_glyphs? "\x94 ": "up" );
- else if( key == SDLK_DOWN )
- vg_strcat( str, special_glyphs? "\x96 ": "down" );
- else {
- vg_strcat( str, "keyboard key #" );
- vg_strcati64( str, key, 10 );
- }
-}
-
-/*
- * Cat mouse button string. special_glyphs include SR glyphs
- */
-void vg_mouse_button_string( vg_str *str, u32 button, int special_glyphs )
-{
- if ( button == SDL_BUTTON_LEFT )
- vg_strcat( str, special_glyphs? "\x99": "left mouse" );
- else if( button == SDL_BUTTON_RIGHT )
- vg_strcat( str, special_glyphs? "\x9a": "right mouse" );
- else if( button == SDL_BUTTON_MIDDLE )
- vg_strcat( str, special_glyphs? "\x9c": "middle mouse" );
- else{
- vg_strcat( str, "mouse button #" );
- vg_strcati64( str, button, 10 );
- }
-}
-
-/*
- * Cat string represeinting single axis
- */
-void vg_joy_axis_string( vg_str *str, SDL_GameControllerAxis axis,
- int special_glyphs )
-{
- if( axis == SDL_CONTROLLER_AXIS_TRIGGERLEFT )
- vg_strcat( str, special_glyphs?"\x8f":"left trigger" );
- else if( axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT )
- vg_strcat( str, special_glyphs?"\x90":"right trigger" );
- else if( axis == SDL_CONTROLLER_AXIS_LEFTX )
- vg_strcat( str, special_glyphs?"\x88":"left stick horizontal" );
- else if( axis == SDL_CONTROLLER_AXIS_LEFTY )
- vg_strcat( str, special_glyphs?"\x89":"left stick vertical" );
- else if( axis == SDL_CONTROLLER_AXIS_RIGHTX )
- vg_strcat( str, special_glyphs?"\x8c":"right stick horizontal" );
- else if( axis == SDL_CONTROLLER_AXIS_RIGHTY )
- vg_strcat( str, special_glyphs?"\x8d":"right stick vertical" );
- else{
- vg_strcat( str, "axis " );
- vg_strcati64( str, axis, 10 );
- }
-}
-
-/*
- * Cat string represeinting whole joystick
- */
-void vg_joy_string( vg_str *str, vg_input_op op, int special_glyphs )
-{
- if( op == vg_joy_ls )
- vg_strcat( str, special_glyphs? "\x87": "left stick" );
- else
- vg_strcat( str, special_glyphs? "\x8b": "right stick" );
-}
-
-/*
- * Convert an input program into a readable string
- */
-void vg_input_string( vg_str *str, vg_input_op *ops, int glyphs )
-{
- u32 pc = 0;
- int applicable = 0, visible = 1;
-
-next_code:;
- vg_input_op op = ops[ pc ++ ];
-
- if( (op == vg_keyboard) || (op == vg_mouse) )
- {
- if( (vg_input.display_input_method == k_input_method_kbm) && visible )
- {
- applicable = 1;
-
- if( op == vg_keyboard )
- vg_keyboard_key_string( str, ops[pc], glyphs );
- else
- vg_mouse_button_string( str, ops[pc], glyphs );
- }
- else applicable = 0;
- pc ++;
- }
- else if( (op == vg_joy_button) || (op == vg_joy_axis) )
- {
- if( (vg_input.display_input_method == k_input_method_controller) && visible )
- {
- applicable = 1;
-
- if( op == vg_joy_button )
- vg_strcat( str, controller_button_str(ops[pc]) );
- else
- vg_joy_axis_string( str, ops[pc], glyphs );
- }
- else applicable = 0;
- pc ++;
- }
- else if( (op == vg_joy_ls) || (op == vg_joy_rs) )
- {
- if( (vg_input.display_input_method == k_input_method_controller) && visible )
- {
- applicable = 1;
- vg_joy_string( str, op, glyphs );
- }
- else applicable = 0;
- }
- else if( op == vg_mode_mul ){
- if( applicable && visible )
- vg_strcat( str, " + " );
- }
- else if( op == vg_index )
- pc ++;
- else if( op == vg_gui_visible )
- visible = ops[pc++];
- else if( op == vg_end )
- return;
-
- goto next_code;
-}
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_input.c"
-#else
-
-/* Copyright (C) 2021-2024 Harry Godden (hgn) - All Rights Reserved */
-#define VG_MAX_CONTROLLERS 4
-
-extern f32 controller_deadzone;
-
-typedef u32 vg_input_op;
-typedef vg_input_op *vg_input_program;
-
-enum vg_input_type
-{
- k_vg_input_type_button_u8,
- k_vg_input_type_axis_f32,
- k_vg_input_type_joy_v2f
-};
-
-enum vg_input_op
-{
- /* data source */
- vg_keyboard,
- vg_mouse,
- vg_joy_button,
- vg_joy_axis,
- vg_joy_ls,
- vg_joy_rs,
-
- /* modes */
- vg_mode_mul,
- vg_mode_sub,
- vg_mode_add,
- vg_mode_absmax,
- vg_mode_max,
-
- /* control */
- vg_index,
- vg_end,
- vg_gui_visible,
-
- /* math */
- vg_normalize
-};
-
-struct vg_input
-{
- const u8 *sdl_keys;
- u32 sdl_mouse;
- f32 hidden_mouse_travel;
-
- struct vg_controller{
- SDL_GameController *handle; /* handle for controller. NULL if unused */
- SDL_JoystickID instance_id; /* uid used in events */
-
- float axises[ SDL_CONTROLLER_AXIS_MAX ];
- u32 buttons[ SDL_CONTROLLER_BUTTON_MAX ];
- }
- controllers[4];
-
- int active_controller_index; /* most recent controller (by button press)
- will be -1 if no controllers active */
-
- /* what the user is currently using. the keyboard and controller are still
- * active simultaneously, but this reflects what the UI should show */
- enum input_method{
- k_input_method_kbm,
- k_input_method_controller
- }
- display_input_method;
- SDL_GameControllerType display_input_type;
-}
-extern vg_input;
-
-VG_API void _vg_input_register(void);
-VG_API void _vg_input_init(void);
-
-u8 vg_getkey( SDL_Keycode kc );
-void vg_process_inputs(void);
-struct vg_controller *vg_active_controller(void);
-u8 vg_controller_button( SDL_GameControllerButton button );
-f32 vg_controller_axis( SDL_GameControllerAxis axis );
-void vg_exec_input_program( enum vg_input_type type, vg_input_op *ops, void *out_result );
-const char *controller_button_str( SDL_GameControllerButton button );
-void vg_keyboard_key_string( vg_str *str, u32 key, int special_glyphs );
-void vg_mouse_button_string( vg_str *str, u32 button, int special_glyphs );
-void vg_joy_axis_string( vg_str *str, SDL_GameControllerAxis axis, int special_glyphs );
-void vg_joy_string( vg_str *str, vg_input_op op, int special_glyphs );
-void vg_input_string( vg_str *str, vg_input_op *ops, int glyphs );
-void vg_input_device_event( SDL_Event *ev );
-void vg_input_controller_event( SDL_Event *ev );
-
-#endif
+++ /dev/null
-#include <errno.h>
-#include <string.h>
-
-const char *dir_open_result_str[] =
-{
- [k_dir_open_none] = "None",
- [k_dir_open_ok] = "OK",
- [k_dir_open_path_too_long] = "Path too long",
- [k_dir_open_invalid_path] = "Invalid path"
-};
-
-bool vg_path_exists( const char *path )
-{
-#ifdef _WIN32
- DWORD attributes = GetFileAttributes( path );
- if( attributes == INVALID_FILE_ATTRIBUTES )
- return 0;
- return 1;
-#else
- return access(path, F_OK) != -1;
-#endif
-}
-
-bool vg_make_directory( const char *path )
-{
-#ifdef _WIN32
- return CreateDirectory( path, NULL )? 1:0;
-#else
- return mkdir( path, S_IRWXU|S_IRWXG|S_IRWXO ) == 0;
-#endif
-}
-
-enum dir_open_result vg_dir_open( vg_dir *dir, const char *name )
-{
-#ifdef _WIN32
- char q_buf[4096];
- vg_str q;
- vg_strnull( &q, q_buf, 4096 );
- vg_strcat( &q, name );
-
- DWORD attributes = GetFileAttributes( q.buffer );
- if( attributes == INVALID_FILE_ATTRIBUTES )
- {
- vg_error( "Big problem: %d\n", GetLastError() );
- return k_dir_open_invalid_path;
- }
-
- if( !(attributes & FILE_ATTRIBUTE_DIRECTORY) )
- return k_dir_open_is_file;
-
- vg_strcat( &q, "/*" );
- if( !vg_strgood(&q) )
- return k_dir_open_path_too_long;
-
- vg_info( "FindFirstFile( '%s' )\n", q.buffer );
- dir->h = FindFirstFile( q.buffer, &dir->data );
- if( dir->h == INVALID_HANDLE_VALUE )
- {
- if( GetLastError() == ERROR_FILE_NOT_FOUND )
- {
- dir->index = 0;
- return k_dir_open_ok;
- }
- else
- return k_dir_open_invalid_path;
- }
-#else
- dir->h = opendir( name );
- if( !dir->h )
- {
- if( errno == ENOTDIR )
- return k_dir_open_is_file;
- else
- return k_dir_open_invalid_path;
- }
-#endif
- dir->index = 1;
- return k_dir_open_ok;
-}
-
-const char *vg_dir_entry_name( vg_dir *dir )
-{
-#ifdef _WIN32
- return dir->data.cFileName;
-#else
- return dir->data->d_name;
-#endif
-}
-
-static int vg_dirskip( vg_dir *dir )
-{
- const char *s = vg_dir_entry_name(dir);
-#ifdef _WIN32
- if( dir->data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN )
- return 1;
-#endif
- if( s[0] == '.' )
- {
- if( s[1] == '\0' )
- return 1;
- else if( s[1] == '.' )
- {
- if( s[2] == '\0' )
- return 1;
- }
- }
- return 0;
-}
-
-bool vg_dir_next_entry( vg_dir *dir )
-{
-#ifdef _WIN32
- if( dir->index == 0 )
- return 0;
-
- if( dir->index > 1 )
- {
- dir->index ++;
- if( !FindNextFile( dir->h, &dir->data ) )
- return 0;
- }
- while( vg_dirskip(dir) )
- {
- dir->index ++;
- if( !FindNextFile( dir->h, &dir->data ) )
- return 0;
- }
- if( dir->index == 1 )
- dir->index ++;
- return 1;
-#else
- while( (dir->data = readdir(dir->h)) )
- {
- dir->index ++;
- if( !vg_dirskip(dir) )
- break;
- }
- if( dir->data )
- return 1;
- else return 0;
-#endif
-}
-
-enum vg_entry_type vg_dir_entry_type( vg_dir *dir )
-{
-#ifdef _WIN32
- if( dir->data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
- return k_vg_entry_type_dir;
- else
- return k_vg_entry_type_file; /* sketchy? */
-#else
- if( dir->data->d_type == DT_DIR ) return k_vg_entry_type_dir;
- if( dir->data->d_type == DT_REG ) return k_vg_entry_type_file;
-#endif
- return k_vg_entry_type_unknown;
-}
-
-void vg_dir_close( vg_dir *dir )
-{
-#ifdef _WIN32
- if( dir->index ) FindClose( dir->h );
- dir->h = INVALID_HANDLE_VALUE;
-#else
- closedir( dir->h );
- dir->h = NULL;
- dir->data = NULL;
-#endif
- dir->index = 0;
-}
-
-VG_TIER_0 void vg_buffer_stream_open( vg_stream *stream, const void *buffer, u32 buffer_length, u32 mode )
-{
- VG_ASSERT( buffer_length );
- VG_ASSERT( buffer );
-
- stream->buffer = buffer;
- stream->byte_limit = buffer_length;
- stream->byte_count = 0;
- stream->flags = mode;
-}
-
-VG_TIER_0 bool vg_file_stream_open( vg_stream *stream, const c8 *path, u32 mode )
-{
-#if defined( VG_ENGINE )
- if( !_vg_thread_has_flags( VG_THREAD_BACKGROUND ) )
- vg_warn( "Performance: I/O file stream opened in main thread. This will cause frame stalls!\n" );
-#endif
- stream->fp = fopen( path, (mode & VG_STREAM_WRITE)? "wb": "rb" );
- stream->byte_limit = 0;
- stream->byte_count = 0;
- stream->flags = mode | VG_STREAM_FILE;
-
- if( stream->fp )
- return 1;
- else
- {
- vg_error( "Failed to open disk stream '%s'\n", path );
- return 0;
- }
-}
-
-VG_TIER_0 u32 vg_stream_usable_length( vg_stream *stream, u32 length )
-{
- if( stream->byte_limit && ((stream->byte_count + length) > stream->byte_limit) )
- length = stream->byte_limit - stream->byte_count;
- return length;
-}
-
-VG_TIER_0 u32 vg_stream_read( vg_stream *stream, void *buffer, u32 length )
-{
- VG_ASSERT( stream->flags & VG_STREAM_READ );
- u32 read_length = vg_stream_usable_length( stream, length );
-
- if( stream->flags & VG_STREAM_FILE )
- {
- u64 l = (u32)fread( buffer, 1, read_length, stream->fp );
- if( l != read_length )
- {
- if( !feof( stream->fp ) )
- {
- if( ferror( stream->fp ) )
- {
- fclose( stream->fp );
- vg_fatal_error( "Read error (%u: %s)\n", (u32)errno, strerror(errno) );
- }
- else
- {
- fclose( stream->fp );
- vg_fatal_error( "Unknown read error (fread)\n" );
- }
- }
- }
- read_length = l;
- }
- else
- {
- for( u32 i=0; i<read_length; i ++ )
- ((u8 *)buffer)[i] = ((u8 *)stream->buffer)[stream->byte_count + i];
- }
-
- for( u32 i=read_length; i<length; i ++ )
- ((u8 *)buffer)[ i ] = 0;
-
- stream->byte_count += read_length;
- return read_length;
-}
-
-VG_TIER_0 u32 vg_stream_offset( vg_stream *stream )
-{
- return stream->byte_count;
-}
-
-VG_TIER_0 void vg_stream_seek( vg_stream *stream, u32 offset )
-{
- if( stream->flags & VG_STREAM_FILE )
- {
- if( fseek( stream->fp, offset, SEEK_SET ) == -1 )
- {
- vg_fatal_error( "fseek error (%u: %s)\n", (u32)errno, strerror(errno) );
- }
- }
- stream->byte_count = offset;
-}
-
-VG_TIER_0 u32 vg_stream_write( vg_stream *stream, const void *buffer, u32 length )
-{
- VG_ASSERT( stream->flags & VG_STREAM_WRITE );
- u32 write_length = vg_stream_usable_length( stream, length );
-
- if( stream->flags & VG_STREAM_FILE )
- {
- u64 l = fwrite( buffer, 1, write_length, stream->fp );
- if( l != write_length )
- {
- if( ferror( stream->fp ) )
- {
- fclose( stream->fp );
- vg_fatal_error( "Write error (%u: %s)\n", (u32)errno, strerror(errno) );
- }
- else
- {
- fclose( stream->fp );
- vg_fatal_error( "Unknown write error (fwrite)\n" );
- }
- }
- }
- else
- {
- for( u32 i=0; i<write_length; i ++ )
- ((u8 *)stream->buffer)[stream->byte_count + i] = ((u8 *)buffer)[i];
- }
-
- stream->byte_count += write_length;
- return write_length;
-}
-
-VG_TIER_0 void vg_file_stream_close( vg_stream *stream )
-{
- VG_ASSERT( stream->flags & VG_STREAM_FILE );
- fclose( stream->fp );
- stream->fp = NULL;
-}
-
-#define VG_FILE_IO_CHUNK_SIZE VG_KB(256)
-/* read entire binary file */
-void *vg_file_read( vg_stack_allocator *stack, const char *path, u32 *size, bool text )
-{
- VG_ASSERT( stack );
-
- FILE *f = fopen( path, "rb" );
- if( f )
- {
- u8 *buffer = vg_stack_allocate( stack, 0, 8, "File data" );
- u64 current = 0;
-
- /* read in chunks */
- while(1)
- {
- vg_stack_extend_last( stack, +VG_FILE_IO_CHUNK_SIZE );
- u64 l = fread( buffer + current, 1, VG_FILE_IO_CHUNK_SIZE, f );
- current += l;
-
- if( l != VG_FILE_IO_CHUNK_SIZE )
- {
- if( feof( f ) )
- break;
- else
- {
- if( ferror( f ) )
- {
- fclose(f);
- vg_fatal_error( "Read error\n" );
- }
- else
- {
- fclose(f);
- vg_fatal_error( "Unknown error condition\n" );
- }
- }
- }
- }
-
- if( text )
- {
- vg_stack_extend_last( stack, +1 );
- buffer[ current ++ ] = '\0';
- }
- fclose( f );
-
- *size = (u32)current;
- return buffer;
- }
- else
- {
- vg_error( "vg_disk_open_read: %s (file: %s)\n", strerror(errno), path );
- return NULL;
- }
-}
-
-bool vg_asset_write( const char *path, void *data, i64 size )
-{
- FILE *f = fopen( path, "wb" );
- if( f )
- {
- fwrite( data, size, 1, f );
- fclose( f );
- return 1;
- }
- else
- return 0;
-}
-
-const char *vg_path_filename( const char *path )
-{
- const char *base = path;
- for( int i=0; i<1024; i++ )
- {
- if( path[i] == '\0' )
- break;
- if( path[i] == '/' )
- base = path+i+1;
- }
-
- return base;
-}
+++ /dev/null
-#include <dirent.h>
-#include <stdio.h>
-#include <sys/stat.h>
-
-typedef struct vg_dir vg_dir;
-
-#if defined( _WIN32 )
-struct vg_dir
-{
- HANDLE h;
- WIN32_FIND_DATA data;
- u32 index;
-};
-#else
-struct vg_dir
-{
- DIR *h;
- struct dirent *data;
- u32 index;
-};
-#endif
-
-typedef struct vg_stream vg_stream;
-struct vg_stream
-{
- u32 flags, byte_limit, byte_count;
-
- union
- {
- FILE *fp;
- const void *buffer;
- };
-};
-
-#define VG_STREAM_FILE 0x4
-#define VG_STREAM_WRITE 0x2
-#define VG_STREAM_READ 0x1
-
-VG_TIER_0 bool vg_file_stream_open( vg_stream *stream, const c8 *path, u32 mode );
-VG_TIER_0 void vg_buffer_stream_open( vg_stream *stream, const void *buffer, u32 buffer_length, u32 mode );
-VG_TIER_0 u32 vg_stream_read( vg_stream *stream, void *buffer, u32 length );
-VG_TIER_0 u32 vg_stream_write( vg_stream *stream, const void *buffer, u32 length );
-VG_TIER_0 void vg_file_stream_close( vg_stream *stream );
-VG_TIER_0 u32 vg_stream_offset( vg_stream *stream );
-VG_TIER_0 void vg_stream_seek( vg_stream *stream, u32 offset );
-
-enum vg_entry_type
-{
- k_vg_entry_type_unknown,
- k_vg_entry_type_file,
- k_vg_entry_type_dir
-};
-
-enum dir_open_result
-{
- k_dir_open_none,
- k_dir_open_ok,
- k_dir_open_path_too_long,
- k_dir_open_invalid_path,
- k_dir_open_is_file
-};
-extern const char *dir_open_result_str[];
-enum dir_open_result vg_dir_open( vg_dir *dir, const char *name );
-
-const char *vg_dir_entry_name( vg_dir *dir );
-bool vg_dir_next_entry( vg_dir *dir );
-enum vg_entry_type vg_dir_entry_type( vg_dir *dir );
-void vg_dir_close( vg_dir *dir );
-
-bool vg_path_exists( const char *path );
-bool vg_make_directory( const char *path );
-
-/*
- * File I/O
- */
-
-/* read entire binary file, if text is 1, appends a nul to the end of the buffer */
-void *vg_file_read( vg_stack_allocator *stack, const char *path, u32 *size, bool text );
-
-bool vg_asset_write( const char *path, void *data, i64 size );
-const char *vg_path_filename( const char *path );
+++ /dev/null
-static vg_kv *vg_kvs_newkv( vg_kvs *kvs )
-{
- void *kv_page;
- if( (kvs->kv_page_count == VG_KV_PAGE_COUNT) || (kvs->kv_page_offset == 0) )
- {
- u32 page_size = sizeof(vg_kv)*VG_KV_PAGE_COUNT;
- kv_page = vg_stack_allocate( kvs->stack, page_size, 64, "KV Page" );
- vg_zero_mem( kv_page, page_size );
- kvs->kv_page_offset = vg_stack_offset( kvs->stack, kv_page );
- kvs->kv_page_count = 0;
- kvs->stat_memory_pages += page_size;
- }
- else
- kv_page = vg_stack_pointer( kvs->stack, kvs->kv_page_offset );
-
- vg_kv *kv = kv_page + kvs->kv_page_count * sizeof(vg_kv);
- kvs->kv_page_count ++;
- return kv;
-}
-
-void vg_kvs_init( vg_kvs *kvs, vg_stack_allocator *stack )
-{
- vg_zero_mem( kvs, sizeof(vg_kvs) );
- kvs->stack = stack;
-
- vg_kv *root_kv = vg_kvs_newkv( kvs );
- kvs->root_offset = vg_stack_offset( kvs->stack, root_kv );
-}
-
-static u32 vg_kv_string_append( vg_kvs *kvs, const c8 *string )
-{
- if( string == NULL )
- return 0;
- char *buf = vg_stack_allocate( kvs->stack, strlen(string)+1, 1, "KV string (appended)" );
- strcpy( buf, string );
- return vg_stack_offset( kvs->stack, buf );
-}
-
-u32 vg_kv_append( vg_kvs *kvs, u32 parent_offset, const c8 *key, const c8 *value )
-{
- if( parent_offset == 0 )
- parent_offset = kvs->root_offset;
-
- vg_kv *kv = vg_kvs_newkv( kvs );
- u32 key_offset = vg_kv_string_append( kvs, key ),
- value_offset = vg_kv_string_append( kvs, value );
-
- kv->key_info = (vg_strdjb2(key) & 0xFFFFF) | (key?(strlen(key)<<20):0) | (value?(0x1<<30):0);
- kv->key_offset = key_offset;
-
- if( value )
- {
- VG_ASSERT( key );
- kv->value.offset_from_key = value_offset-key_offset;
- kv->value.length = strlen(value);
- }
-
- u32 kv_offset = vg_stack_offset( kvs->stack, kv );
- vg_kv *parent = vg_stack_pointer( kvs->stack, parent_offset );
- if( parent->first_child_offset )
- {
- u32 brother_offset = parent->first_child_offset;
- while( 1 )
- {
- vg_kv *brother = vg_stack_pointer( kvs->stack, brother_offset );
- if( brother->brother_offset )
- brother_offset = brother->brother_offset;
- else
- {
- brother->brother_offset = kv_offset;
- break;
- }
- }
- }
- else parent->first_child_offset = kv_offset;
- return kv_offset;
-}
-
-/*
- * Navigating, and read/writing the KV tree
- * --------------------------------------------------------------------------------------------------------------------
- */
-u32 vg_kv_type( vg_kvs *kvs, u32 kv_offset )
-{
- vg_kv *kv = vg_stack_pointer( kvs->stack, kv_offset );
- return (kv->key_info >> 30) & 0x3;
-}
-
-const c8 *vg_kv_key( vg_kvs *kvs, u32 kv_offset, u32 *out_length )
-{
- if( kv_offset == 0 )
- return NULL;
-
- vg_kv *kv = vg_stack_pointer( kvs->stack, kv_offset );
- u32 length = (kv->key_info >> 20) & 0x3FF;
- if( out_length )
- *out_length = length;
- return length? vg_stack_pointer( kvs->stack, kv->key_offset ): NULL;
-}
-
-const c8 *vg_kv_value( vg_kvs *kvs, u32 kv_offset, u32 *out_length )
-{
- if( kv_offset == 0 )
- return NULL;
- if( vg_kv_type( kvs, kv_offset ) == k_vg_kv_type_frame )
- return NULL;
- else
- {
- vg_kv *kv = vg_stack_pointer( kvs->stack, kv_offset );
- if( out_length )
- *out_length = kv->value.length;
- return vg_stack_pointer( kvs->stack, kv->key_offset + kv->value.offset_from_key );
- }
-}
-
-u32 vg_kv_next( vg_kvs *kvs, u32 kv_offset )
-{
- vg_kv *kv = vg_stack_pointer( kvs->stack, kv_offset );
- return kv->brother_offset;
-}
-
-u32 vg_kv_child( vg_kvs *kvs, u32 root_offset, u32 index )
-{
- if( vg_kv_type( kvs, root_offset ) == k_vg_kv_type_frame )
- {
- vg_kv *parent = vg_stack_pointer( kvs->stack, root_offset );
- u32 offset = parent->first_child_offset;
-
- for( u32 i=0; (i<index) && offset; i ++ )
- {
- vg_kv *kv = vg_stack_pointer( kvs->stack, offset );
- offset = kv->brother_offset;
- }
- return offset;
- }
- else return 0;
-}
-
-u32 vg_kv_find( vg_kvs *kvs, u32 root_offset, const c8 *key )
-{
- if( root_offset == 0 )
- root_offset = kvs->root_offset;
-
- u32 hash = vg_strdjb2( key );
- u32 child_offset = vg_kv_child( kvs, root_offset, 0 );
- while( child_offset )
- {
- vg_kv *kv = vg_stack_pointer( kvs->stack, child_offset );
- if( ((kv->key_info ^ hash) & 0xFFFFF) == 0 )
- {
- u32 key_length;
- const c8 *child_key = vg_kv_key( kvs, child_offset, &key_length );
- if( child_key )
- {
- for( u32 i=0; i<key_length; i ++ )
- if( child_key[i] != key[i] )
- goto next;
-
- return child_offset;
- }
- }
-
- next:child_offset = vg_kv_next( kvs, child_offset );
- }
- return 0;
-}
-
-bool vg_kv_read_vu32( vg_kvs *kvs, u32 root_offset, const c8 *key, u32 *default_value, u32 *out_value, u32 len )
-{
- bool good = 1;
- vg_strp s = { .buffer = vg_kv_value( kvs, vg_kv_find( kvs, root_offset, key ), NULL ) };
- for( u32 i=0; i<len; i ++ )
- {
- u64 value = 0;
- if( vg_strp_u64( &s, &value ) == k_vg_strp_ok ) out_value[ i ] = (u32)value;
- else
- {
- good = 0;
- if( default_value ) out_value[ i ] = default_value[ i ];
- else out_value[ i ] = 0;
- }
- }
- return good;
-}
-
-bool vg_kv_read_vf32( vg_kvs *kvs, u32 root_offset, const c8 *key, f32 *default_value, f32 *out_value, u32 len )
-{
- bool good = 1;
- vg_strp s = { .buffer = vg_kv_value( kvs, vg_kv_find( kvs, root_offset, key ), NULL ) };
- for( u32 i=0; i<len; i ++ )
- {
- f64 value = 0.0;
- if( vg_strp_f64( &s, &value ) == k_vg_strp_ok ) out_value[ i ] = (f32)value;
- else
- {
- good = 0;
- if( default_value ) out_value[ i ] = default_value[ i ];
- else out_value[ i ] = 0.0f;
- }
- }
- return good;
-}
-
-const c8 *vg_kv_read_string( vg_kvs *kvs, u32 root_offset, const c8 *key, const c8 *default_value )
-{
- const c8 *value = vg_kv_value( kvs, vg_kv_find( kvs, root_offset, key ), NULL );
- return value? value: default_value;
-}
-
-#define VG_KV_APPEND_TEMPLATE( FUNCTION, ... ) \
- c8 formatted[ 1024 ]; \
- vg_str value_str; \
- vg_strnull( &value_str, formatted, sizeof(formatted) ); \
- for( u32 i=0; i<len; i++ ) \
- { \
- FUNCTION ( &value_str, values[i], __VA_ARGS__ ); \
- if( i+1!=len ) \
- vg_strcatch( &value_str, ' ' ); \
- } \
- if( !vg_strgood( &value_str ) ) \
- return 0; \
- return vg_kv_append( kvs, parent_offset, key, formatted );
-
-u32 vg_kv_append_vu32( vg_kvs *kvs, u32 parent_offset, const c8 *key, u32 *values, u32 len )
-{
- VG_KV_APPEND_TEMPLATE( vg_strcatu64, 10 )
-}
-
-u32 vg_kv_append_vi32( vg_kvs *kvs, u32 parent_offset, const c8 *key, i32 *values, u32 len )
-{
- VG_KV_APPEND_TEMPLATE( vg_strcati64, 10 )
-}
-
-u32 vg_kv_append_vf32( vg_kvs *kvs, u32 parent_offset, const c8 *key, f32 *values, u32 len )
-{
- VG_KV_APPEND_TEMPLATE( vg_strcatf64, 10, 5 )
-}
-
-/*
- * Parsing from formatted stream
- * --------------------------------------------------------------------------------------------------------------------
- */
-void vg_kv_parser_init( vg_kv_parser *parser, vg_kvs *out_kvs, u32 root_offset )
-{
- VG_ASSERT( out_kvs->stack );
- VG_ASSERT( out_kvs->kv_page_count );
-
- vg_zero_mem( parser, sizeof(vg_kv_parser) );
- parser->kvs = out_kvs;
- parser->frame_stack[0].frame_offset = root_offset;
-}
-
-static void vg_kv_parser_link( vg_kv_parser *parser, u32 offset, u32 depth )
-{
- u32 parent_offset = parser->frame_stack[ depth ].frame_offset;
- vg_kv *parent = vg_stack_pointer( parser->kvs->stack, parent_offset );
- if( parent->first_child_offset == 0 )
- parent->first_child_offset = offset;
-
- u32 brother_offset = parser->frame_stack[ depth ].latest_child_offset;
- if( brother_offset )
- {
- vg_kv *brother = vg_stack_pointer( parser->kvs->stack, brother_offset );
- brother->brother_offset = offset;
- }
- parser->frame_stack[ depth ].latest_child_offset = offset;
-}
-
-void vg_kv_parse_stream( vg_kv_parser *parser, vg_stream *in_stream )
-{
- c8 c;
- while( vg_stream_read( in_stream, &c, 1 ) )
- {
- parser->stat_source_characters ++;
- if( c == '\0' )
- break;
-
- bool is_control_character = 0;
- if( parser->token0_deliminator )
- {
- if( c == parser->token0_deliminator )
- is_control_character = 1;
- }
- else
- {
- if( c==' '||c=='\t'||c=='\r'||c=='\n'||c=='{'||c=='}' )
- is_control_character = 1;
- }
-
- if( is_control_character )
- {
- if( parser->token0_length )
- {
- parser->token0_length --;
- vg_stack_extend_last( parser->kvs->stack, +1 );
- parser->token0_buffer[ parser->token0_length ] = '\0';
-
- if( parser->token1_length )
- {
- /* KV pair */
- vg_kv *kv = vg_kvs_newkv( parser->kvs );
- kv->key_info = (0xFFFFF & parser->token1_hash) |
- (0x3FF & parser->token1_length)<<20 |
- (0x1) << 30;
- kv->key_offset = parser->token1_start_offset;
- kv->value.offset_from_key = parser->token0_start_offset - parser->token1_start_offset;
- kv->value.length = parser->token0_length;
- parser->token1_length = 0;
-
- vg_kv_parser_link( parser, vg_stack_offset( parser->kvs->stack, kv ), parser->depth );
- }
- else
- {
- /* shift */
- parser->token1_start_offset = parser->token0_start_offset;
- parser->token1_length = parser->token0_length;
- parser->token1_hash = parser->token0_hash;
- }
-
- parser->token0_length = 0;
- }
-
- if( c=='{'||c=='}'||c=='\n' )
- {
- if( c == '{' )
- {
- vg_kv *kv = vg_kvs_newkv( parser->kvs );
- if( parser->token1_length )
- {
- kv->key_info = (0xFFFFF & parser->token1_hash) | (0x3FF & parser->token1_length) << 20;
- kv->key_offset = parser->token1_start_offset;
- }
- else
- kv->key_info = 5381;
-
- u32 id = vg_stack_offset( parser->kvs->stack, kv ),
- depth = parser->depth;
-
- parser->depth ++;
- parser->frame_stack[ parser->depth ].latest_child_offset = 0;
- parser->frame_stack[ parser->depth ].frame_offset = id;
- vg_kv_parser_link( parser, id, depth );
- parser->token1_length = 0;
- }
- else if( c == '}' )
- {
- if( parser->depth )
- parser->depth --;
- parser->token1_length = 0;
- }
- }
-
- parser->token0_deliminator = 0;
- }
- else
- {
- if( parser->token0_length )
- {
- vg_stack_extend_last( parser->kvs->stack, +1 );
- parser->token0_buffer[ parser->token0_length-1 ] = c;
- parser->token0_length ++;
- parser->token0_hash = ((parser->token0_hash << 5) + parser->token0_hash) + (u32)c;
- parser->stat_memory_strings ++;
- }
- else
- {
- if( c =='"' || c=='\'' )
- {
- parser->token0_buffer = vg_stack_allocate( parser->kvs->stack, 0, 1, "KV string" );
- parser->token0_start_offset = vg_stack_offset( parser->kvs->stack, parser->token0_buffer );
- parser->token0_deliminator = c;
- parser->token0_hash = 5381;
- parser->token0_length = 1;
- }
- else
- {
- parser->token0_buffer = vg_stack_allocate( parser->kvs->stack, 1, 1, "KV string" );
- parser->token0_start_offset = vg_stack_offset( parser->kvs->stack, parser->token0_buffer );
- parser->token0_buffer[0] = c;
- parser->token0_length = 2;
- parser->token0_hash = ((5381<<5)+5381) + (u32)c;
- parser->stat_memory_strings ++;
- }
- }
- }
- }
-}
-
-void vg_kv_parser_print_info( vg_kv_parser *parser )
-{
- vg_low( "KV stats\n"
- " bytes pages: %u\n"
- " bytes strings: %u\n"
- " source characters: %u. compression ratio: %.2f%%\n", parser->kvs->stat_memory_pages,
- parser->stat_memory_strings,
- parser->stat_source_characters,
- (f32)(parser->stat_memory_strings+parser->kvs->stat_memory_pages) /
- (f32)parser->stat_source_characters * 100.0f );
-}
-
-/*
- * Writing KVS to a stream (formatted)
- * --------------------------------------------------------------------------------------------------------------------
- */
-void vg_kv_write_init( vg_kv_write *w, vg_stream *stream )
-{
- vg_zero_mem( w, sizeof(vg_kv_write) );
- w->stream = stream;
-}
-
-static void vg_kv_write_indent( vg_kv_write *w )
-{
- for( u32 i=0; i<w->depth; i ++ )
- vg_stream_write( w->stream, (c8[]){ ' ' }, 1 );
-}
-
-static void vg_kv_write_string( vg_kv_write *w, const c8 *string, u32 length )
-{
- if( length == 0 )
- length = 0xffffffff;
-
- u32 i=0;
- char delim=0;
- for( ;i<length; i ++ )
- {
- char c = string[i];
- if( c == '\0' )
- break;
-
- char new_delim = 0;
- if( c == '"' )
- new_delim = '\'';
- else if( c == '\'' || c == ' ' || c == '\t' || c == '\n' )
- new_delim = '"';
-
- if( new_delim )
- {
- if( delim && (new_delim != delim) )
- {
- vg_kv_write_string( w, "VG_KV_UNWRITABLE_STRING", 0 );
- return;
- }
- else delim = new_delim;
- }
- }
-
- if( delim ) vg_stream_write( w->stream, (c8[]){ delim }, 1 );
- vg_stream_write( w->stream, string, i );
- if( delim ) vg_stream_write( w->stream, (c8[]){ delim }, 1 );
-}
-
-void vg_kv_write_block( vg_kv_write *w, const c8 *name, u32 name_length )
-{
- vg_kv_write_indent( w );
- if( name )
- {
- vg_kv_write_string( w, name, name_length );
- vg_stream_write( w->stream, (c8[]){ '\n' }, 1 );
- vg_kv_write_indent( w );
- }
-
- vg_stream_write( w->stream, (c8[]){ '{', '\n' }, 2 );
- w->depth ++;
-}
-
-void vg_kv_end_block( vg_kv_write *w )
-{
- w->depth --;
- vg_kv_write_indent( w );
- vg_stream_write( w->stream, (c8[]){ '}', '\n' }, 2 );
-}
-
-void vg_kv_write_kv( vg_kv_write *w, const c8 *key, u32 key_len, const c8 *value, u32 value_len )
-{
- vg_kv_write_indent( w );
- vg_kv_write_string( w, key, key_len );
- vg_stream_write( w->stream, (c8[]){ ' ' }, 1 );
- vg_kv_write_string( w, value, value_len );
- vg_stream_write( w->stream, (c8[]){ '\n' }, 1 );
-}
-
-void vg_kv_write_tree( vg_kv_write *w, vg_kvs *kvs, u32 root_offset )
-{
- if( root_offset == 0 )
- root_offset = kvs->root_offset;
-
- VG_ASSERT( vg_kv_type( kvs, root_offset ) == k_vg_kv_type_frame );
-
- u32 root_len;
- const c8 *root_str = vg_kv_key( kvs, root_offset, &root_len );
- vg_kv_write_block( w, root_str, root_len );
-
- u32 child_offset = vg_kv_child( kvs, root_offset, 0 );
- while( child_offset )
- {
- if( vg_kv_type( kvs, child_offset ) == k_vg_kv_type_frame )
- vg_kv_write_tree( w, kvs, child_offset );
- else
- {
- u32 key_len;
- const c8 *key_str = vg_kv_key( kvs, child_offset, &key_len );
-
- u32 value_len;
- const c8 *value_str = vg_kv_value( kvs, child_offset, &value_len );
-
- if( key_str && value_str )
- vg_kv_write_kv( w, key_str, key_len, value_str, value_len );
- }
-
- child_offset = vg_kv_next( kvs, child_offset );
- }
-
- vg_kv_end_block( w );
-}
-
-bool vg_kv_read_file( vg_kvs *kvs, const c8 *path, vg_stack_allocator *stack )
-{
- vg_stream stream;
- if( vg_file_stream_open( &stream, path, VG_STREAM_READ ) )
- {
- vg_kvs_init( kvs, stack );
- vg_kv_parser parser;
- vg_kv_parser_init( &parser, kvs, 0 );
- vg_kv_parse_stream( &parser, &stream );
- vg_file_stream_close( &stream );
- return 1;
- }
- else return 0;
-}
-
-bool vg_kv_write_file( vg_kvs *kvs, const c8 *path )
-{
- vg_stream stream;
- if( vg_file_stream_open( &stream, path, VG_STREAM_WRITE ) )
- {
- vg_kv_write writer;
- vg_kv_write_init( &writer, &stream );
- vg_kv_write_tree( &writer, kvs, 0 );
- vg_file_stream_close( &stream );
- return 1;
- }
- else return 0;
-}
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_kv.c"
-#else
-
-#define VG_KV_PAGE_COUNT 32
-#define VG_KV_APPEND_FRAME NULL
-
-/* define VG_MSG_TO_KVS to automatically convert from old vg_msg stream to plain text KVs */
-
-typedef struct vg_kv vg_kv;
-typedef struct vg_kvs vg_kvs;
-typedef struct vg_kv_parser vg_kv_parser;
-typedef struct vg_kv_write vg_kv_write;
-
-/* Initialize kvs set and set the allocator for it */
-void vg_kvs_init( vg_kvs *kvs, vg_stack_allocator *stack );
-
-/* Initialize KV parser ready to accept buffer fragments
- * out_kvs must be initialized
- */
-void vg_kv_parser_init( vg_kv_parser *parser, vg_kvs *out_kvs, u32 root_offset );
-void vg_kv_parse_stream( vg_kv_parser *parser, vg_stream *in_stream );
-void vg_kv_parser_print_info( vg_kv_parser *parser );
-
-/* returns the type of this KV.
- * 0: frame
- * 1: kv pair
- */
-enum vg_kv_type
-{
- k_vg_kv_type_frame = 0,
- k_vg_kv_type_pair = 1,
- k_vg_kv_type_unused2 = 2,
- k_vg_kv_type_unused3 = 3
-};
-u32 vg_kv_type( vg_kvs *kvs, u32 kv_offset );
-
-/* get key / values associated with KV pair or only key for a frame. */
-const c8 *vg_kv_key( vg_kvs *kvs, u32 kv_offset, u32 *out_length );
-const c8 *vg_kv_value( vg_kvs *kvs, u32 kv_offset, u32 *out_length );
-
-/* get the child KV at index, returns 0 if out of range */
-u32 vg_kv_child( vg_kvs *kvs, u32 root_offset, u32 index );
-u32 vg_kv_next( vg_kvs *kvs, u32 kv_offset );
-u32 vg_kv_find( vg_kvs *kvs, u32 root_offset, const c8 *key );
-
-bool vg_kv_read_vu32( vg_kvs *kvs, u32 root_offset, const c8 *key, u32 *default_value, u32 *out_value, u32 len );
-bool vg_kv_read_vf32( vg_kvs *kvs, u32 root_offset, const c8 *key, f32 *default_value, f32 *out_value, u32 len );
-const c8 *vg_kv_read_string( vg_kvs *kvs, u32 root_offset, const c8 *key, const c8 *default_value );
-
-/* editing kvs
- * if value is NULL, it appends a named frame
- * if key is NULL, value must also be NULL. it appends a nameless frame
- * if both key and value are set, it appends a KV pair
- * returns the new KV offset
- */
-u32 vg_kv_append( vg_kvs *kvs, u32 parent_offset, const c8 *key, const c8 *value );
-u32 vg_kv_append_vi32( vg_kvs *kvs, u32 parent_offset, const c8 *key, i32 *values, u32 len );
-u32 vg_kv_append_vu32( vg_kvs *kvs, u32 parent_offset, const c8 *key, u32 *values, u32 len );
-u32 vg_kv_append_vf32( vg_kvs *kvs, u32 parent_offset, const c8 *key, f32 *values, u32 len );
-
-/* Writing KV files. w should be initialized with depth 0, and fp to a valid C stream pointer */
-void vg_kv_write_init( vg_kv_write *w, vg_stream *stream );
-void vg_kv_write_block( vg_kv_write *w, const c8 *name, u32 name_length );
-void vg_kv_end_block( vg_kv_write *w );
-void vg_kv_write_kv( vg_kv_write *w, const c8 *key, u32 key_len, const c8 *value, u32 value_len );
-
-void vg_kv_write_tree( vg_kv_write *w, vg_kvs *kvs, u32 root_offset );
-
-/* Helpers */
-bool vg_kv_read_file( vg_kvs *kvs, const c8 *path, vg_stack_allocator *stack );
-bool vg_kv_write_file( vg_kvs *kvs, const c8 *path );
-
-struct vg_kv_parser
-{
- vg_kvs *kvs;
- u32 token0_start_offset, token0_length, token0_hash,
- token1_start_offset, token1_length, token1_hash;
-
- u32 stat_memory_strings,
- stat_source_characters;
-
- c8 token0_deliminator;
- c8 *token0_buffer;
- u32 depth;
-
- struct
- {
- u32 frame_offset, latest_child_offset;
- }
- frame_stack[64];
-};
-
-struct vg_kvs
-{
- vg_stack_allocator *stack;
- u32 root_offset;
- u32 kv_page_offset, kv_page_count;
- u32 stat_memory_pages;
-};
-
-struct vg_kv
-{
- u32 key_info; /* 20 bit hash, 10 bit key length, 2 bit type */
- u32 key_offset; /* 32 bit, indexes kvs->stack.data. same for any other _offset field */
- u32 brother_offset;
-
- union
- {
- struct
- {
- u16 offset_from_key, length;
- }
- value;
-
- u32 first_child_offset;
- };
-};
-
-struct vg_kv_write
-{
- vg_stream *stream;
- u32 depth;
-};
-
-#endif
+++ /dev/null
-struct vg_lines vg_lines;
-
-#define VG_LINES_MAX_VERTS 50000
-
-VG_API void _vg_lines_register(void)
-{
- vg_console_reg_var( "vg_lines", &vg_lines.render, k_var_dtype_i32, VG_VAR_CHEAT );
-}
-
-VG_API void _vg_lines_init(void)
-{
- VG_ASSERT( _vg_thread_has_flags( VG_THREAD_OWNS_OPENGL ) );
-
- vg_lines.vertex_buffer = vg_malloc( VG_LINES_MAX_VERTS*sizeof(struct vg_lines_vert) );
- glGenVertexArrays( 1, &vg_lines.vao );
- glGenBuffers( 1, &vg_lines.vbo );
- glBindVertexArray( vg_lines.vao );
- glBindBuffer( GL_ARRAY_BUFFER, vg_lines.vbo );
- glBufferData( GL_ARRAY_BUFFER, VG_LINES_MAX_VERTS*sizeof(struct vg_lines_vert), NULL, GL_DYNAMIC_DRAW );
- glBindVertexArray( vg_lines.vao );
-
- /* Pointers */
- glVertexAttribPointer(
- 0,
- 3,
- GL_FLOAT,
- GL_FALSE,
- sizeof( struct vg_lines_vert ),
- (void *)0
- );
- glEnableVertexAttribArray( 0 );
-
- glVertexAttribPointer(
- 1,
- 4,
- GL_UNSIGNED_BYTE,
- GL_TRUE,
- sizeof( struct vg_lines_vert ),
- (void*)(offsetof( struct vg_lines_vert, colour ))
- );
- glEnableVertexAttribArray( 1 );
-}
-
-void vg_lines_drawall( void )
-{
- shader_debug_lines_use();
- shader_debug_lines_uPv( vg.pv );
-
- glBindVertexArray( vg_lines.vao );
- glBindBuffer( GL_ARRAY_BUFFER, vg_lines.vbo );
- glBufferSubData( GL_ARRAY_BUFFER, 0, vg_lines.vertex_count*sizeof(struct vg_lines_vert), vg_lines.vertex_buffer );
-
- glEnable( GL_BLEND );
- glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
- glBlendEquation( GL_FUNC_ADD );
-
- if( vg_lines.render )
- glDrawArrays( GL_LINES, 0, vg_lines.vertex_count );
-
- glDisable( GL_BLEND );
- vg_lines.vertex_count = 0;
-}
-
-void vg_line2( line_co from, line_co to, u32 fc, u32 tc )
-{
- if( !vg_lines.enabled )
- return;
-
- if( vg_lines.vertex_count < VG_LINES_MAX_VERTS )
- {
- struct vg_lines_vert *v = &vg_lines.vertex_buffer[ vg_lines.vertex_count ];
-
- v3_copy( from, v[0].co );
- v3_copy( to, v[1].co );
-
- v[0].colour = fc;
- v[1].colour = tc;
-
- vg_lines.vertex_count += 2;
- }
-}
-
-void vg_line( line_co from, line_co to, u32 colour )
-{
- if( !vg_lines.enabled )
- return;
-
- vg_line2( from, to, colour, colour );
-}
-
-void vg_line_arrow( line_co co, line_co dir, f32 size, u32 colour )
-{
- if( !vg_lines.enabled )
- return;
-
- v3f p1, tx, ty, p2, p3;
- v3_muladds( co, dir, size, p1 );
- v3_tangent_basis( dir, tx, ty );
-
- v3_muladds( p1, dir, -size * 0.125f, p2 );
- v3_muladds( p2, ty, size * 0.125f, p3 );
- v3_muladds( p2, ty, -size * 0.125f, p2 );
-
- vg_line( co, p1, colour );
- vg_line( p1, p2, colour );
- vg_line( p1, p3, colour );
-}
-
-void vg_line_box_verts( boxf box, v3f verts[8] )
-{
- if( !vg_lines.enabled )
- return;
-
- for( u32 i=0; i<8; i++ )
- for( u32 j=0; j<3; j++ )
- verts[i][j] = i&(0x1<<j)? box[1][j]: box[0][j];
-}
-
-void vg_line_mesh( v3f verts[], u32 indices[][2], u32 indice_count,u32 colour )
-{
- if( !vg_lines.enabled )
- return;
-
- for( u32 i=0; i<indice_count; i++ )
- vg_line( verts[indices[i][0]], verts[indices[i][1]], colour );
-}
-
-void vg_line_boxf( boxf box, u32 colour )
-{
- if( !vg_lines.enabled )
- return;
-
- v3f verts[8];
- vg_line_box_verts( box, verts );
- u32 indices[][2] = {{0,1},{1,3},{3,2},{2,0},
- {4,5},{5,7},{7,6},{6,4},
- {4,0},{5,1},{6,2},{7,3}};
-
- vg_line_mesh( verts, indices, VG_ARRAY_LEN(indices), colour );
-}
-
-void vg_line_boxf_transformed( m4x3f m, boxf box, u32 colour )
-{
- if( !vg_lines.enabled )
- return;
-
- v3f verts[8];
- vg_line_box_verts( box, verts );
-
- for( u32 i=0; i<8; i++ )
- m4x3_mulv( m, verts[i], verts[i] );
-
- u32 indices[][2] = {{0,1},{1,3},{3,2},{2,0},
- {4,5},{5,7},{7,6},{6,4},
- {4,0},{5,1},{6,2},{7,3}};
-
- vg_line_mesh( verts, indices, VG_ARRAY_LEN(indices), colour );
-}
-
-void vg_line_cross(v3f pos,u32 colour, f32 scale)
-{
- if( !vg_lines.enabled )
- return;
-
- v3f p0, p1;
- v3_add( (v3f){ scale,0.0f,0.0f}, pos, p0 );
- v3_add( (v3f){-scale,0.0f,0.0f}, pos, p1 );
- vg_line( p0, p1, colour );
- v3_add( (v3f){0.0f, scale,0.0f}, pos, p0 );
- v3_add( (v3f){0.0f,-scale,0.0f}, pos, p1 );
- vg_line( p0, p1, colour );
- v3_add( (v3f){0.0f,0.0f, scale}, pos, p0 );
- v3_add( (v3f){0.0f,0.0f,-scale}, pos, p1 );
- vg_line( p0, p1, colour );
-}
-
-void vg_line_point( v3f pt, f32 size, u32 colour )
-{
- if( !vg_lines.enabled )
- return;
-
- boxf box =
- {
- { pt[0]-size, pt[1]-size, pt[2]-size },
- { pt[0]+size, pt[1]+size, pt[2]+size }
- };
-
- vg_line_boxf( box, colour );
-}
-
-
-void vg_line_sphere( m4x3f m, f32 radius, u32 colour )
-{
- if( !vg_lines.enabled )
- return;
-
- v3f ly = { 0.0f, 0.0f, radius },
- lx = { 0.0f, radius, 0.0f },
- lz = { 0.0f, 0.0f, radius };
-
- for( int i=0; i<16; i++ ){
- f32 t = ((f32)(i+1) * (1.0f/16.0f)) * VG_PIf * 2.0f,
- s = sinf(t),
- c = cosf(t);
-
- v3f py = { s*radius, 0.0f, c*radius },
- px = { s*radius, c*radius, 0.0f },
- pz = { 0.0f, s*radius, c*radius };
-
- v3f p0, p1, p2, p3, p4, p5;
- m4x3_mulv( m, py, p0 );
- m4x3_mulv( m, ly, p1 );
- m4x3_mulv( m, px, p2 );
- m4x3_mulv( m, lx, p3 );
- m4x3_mulv( m, pz, p4 );
- m4x3_mulv( m, lz, p5 );
-
- vg_line( p0, p1, colour == 0x00? 0xff00ff00: colour );
- vg_line( p2, p3, colour == 0x00? 0xff0000ff: colour );
- vg_line( p4, p5, colour == 0x00? 0xffff0000: colour );
-
- v3_copy( py, ly );
- v3_copy( px, lx );
- v3_copy( pz, lz );
- }
-}
-
-void vg_line_capsule( m4x3f m, f32 radius, f32 h, u32 colour )
-{
- if( !vg_lines.enabled )
- return;
-
- v3f ly = { 0.0f, 0.0f, radius },
- lx = { 0.0f, radius, 0.0f },
- lz = { 0.0f, 0.0f, radius };
-
- f32 s0 = sinf(0.0f)*radius,
- c0 = cosf(0.0f)*radius;
-
- v3f p0, p1, up, right, forward;
- m3x3_mulv( m, (v3f){0.0f,1.0f,0.0f}, up );
- m3x3_mulv( m, (v3f){1.0f,0.0f,0.0f}, right );
- m3x3_mulv( m, (v3f){0.0f,0.0f,-1.0f}, forward );
- v3_muladds( m[3], up, -h*0.5f+radius, p0 );
- v3_muladds( m[3], up, h*0.5f-radius, p1 );
-
- v3f a0, a1, b0, b1;
- v3_muladds( p0, right, radius, a0 );
- v3_muladds( p1, right, radius, a1 );
- v3_muladds( p0, forward, radius, b0 );
- v3_muladds( p1, forward, radius, b1 );
- vg_line( a0, a1, colour );
- vg_line( b0, b1, colour );
-
- v3_muladds( p0, right, -radius, a0 );
- v3_muladds( p1, right, -radius, a1 );
- v3_muladds( p0, forward, -radius, b0 );
- v3_muladds( p1, forward, -radius, b1 );
- vg_line( a0, a1, colour );
- vg_line( b0, b1, colour );
-
- for( int i=0; i<16; i++ )
- {
- f32 t = ((f32)(i+1) * (1.0f/16.0f)) * VG_PIf * 2.0f,
- s1 = sinf(t)*radius,
- c1 = cosf(t)*radius;
-
- v3f e0 = { s0, 0.0f, c0 },
- e1 = { s1, 0.0f, c1 },
- e2 = { s0, c0, 0.0f },
- e3 = { s1, c1, 0.0f },
- e4 = { 0.0f, c0, s0 },
- e5 = { 0.0f, c1, s1 };
-
- m3x3_mulv( m, e0, e0 );
- m3x3_mulv( m, e1, e1 );
- m3x3_mulv( m, e2, e2 );
- m3x3_mulv( m, e3, e3 );
- m3x3_mulv( m, e4, e4 );
- m3x3_mulv( m, e5, e5 );
-
- v3_add( p0, e0, a0 );
- v3_add( p0, e1, a1 );
- v3_add( p1, e0, b0 );
- v3_add( p1, e1, b1 );
-
- vg_line( a0, a1, colour );
- vg_line( b0, b1, colour );
-
- if( c0 < 0.0f )
- {
- v3_add( p0, e2, a0 );
- v3_add( p0, e3, a1 );
- v3_add( p0, e4, b0 );
- v3_add( p0, e5, b1 );
- }
- else
- {
- v3_add( p1, e2, a0 );
- v3_add( p1, e3, a1 );
- v3_add( p1, e4, b0 );
- v3_add( p1, e5, b1 );
- }
-
- vg_line( a0, a1, colour );
- vg_line( b0, b1, colour );
-
- s0 = s1;
- c0 = c1;
- }
-}
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_lines.c"
-#else
-
-typedef v3f line_co;
-
-#define VG__RED 0xff0000ff
-#define VG__GREEN 0xff00ff00
-#define VG__BLUE 0xffff0000
-#define VG__WHITE 0xffffffff
-#define VG__BLACK 0xff000000
-#define VG__CLEAR 0x00ffffff
-#define VG__PINK 0xffff00ff
-#define VG__YELOW 0xff00ffff
-#define VG__CYAN 0xffffff00
-#define VG__NONE 0x00000000
-
-struct vg_lines
-{
- u32 enabled,
- render;
-
- vg_stack_allocator vertex_stack;
- struct vg_lines_vert
- {
- v3f co;
- u32 colour;
- }
- *vertex_buffer;
- u32 vertex_count;
-
- GLuint vao, vbo;
-}
-extern vg_lines;
-
-VG_API void _vg_lines_register(void);
-VG_API void _vg_lines_init(void);
-
-void vg_line_capsule( m4x3f m, float radius, float h, u32 colour );
-void vg_line_sphere( m4x3f m, float radius, u32 colour );
-void vg_line_point( v3f pt, float size, u32 colour );
-void vg_line_boxf_transformed( m4x3f m, boxf box, u32 colour );
-void vg_line_boxf( boxf box, u32 colour );
-void vg_line_mesh( v3f verts[], u32 indices[][2], u32 indice_count,u32 colour );
-void vg_line_box_verts( boxf box, v3f verts[8] );
-void vg_line_cross(v3f pos,u32 colour, float scale);
-void vg_line_arrow( line_co co, line_co dir, float size, u32 colour );
-void vg_line( line_co from, line_co to, u32 colour );
-void vg_line2( line_co from, line_co to, u32 fc, u32 tc );
-void vg_lines_drawall( void );
-
-#endif
+++ /dev/null
-struct vg_loader vg_loader;
-
-VG_API void _vg_loader_init(void)
-{
- VG_ASSERT( _vg_thread_has_flags( VG_THREAD_OWNS_OPENGL ) );
- f32 quad[] = { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
- 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f };
-
- glGenVertexArrays( 1, &vg_loader.vao );
- glGenBuffers( 1, &vg_loader.vbo );
- glBindVertexArray( vg_loader.vao );
- glBindBuffer( GL_ARRAY_BUFFER, vg_loader.vbo );
- glBufferData( GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STATIC_DRAW );
- glBindVertexArray( vg_loader.vao );
- glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, sizeof(f32)*2, (void*)0 );
- glEnableVertexAttribArray( 0 );
-}
-
-VG_API void _vg_loader_set_user_information( const c8 *information )
-{
- VG_ASSERT( _vg_thread_has_flags( VG_THREAD_OWNS_OPENGL ) );
- vg_loader.information_for_user = information;
-}
-
-VG_API void _vg_loader_increment( i32 inc )
-{
- VG_ASSERT( _vg_thread_has_flags( VG_THREAD_OWNS_OPENGL ) );
- vg_loader.loading_count += inc;
-}
-
-VG_API bool _vg_loader_visible(void)
-{
- return vg_loader.loading_count > 0;
-}
-
-void vg_loader_render_ring( f32 opacity )
-{
- VG_ASSERT( _vg_thread_has_flags( VG_THREAD_OWNS_OPENGL ) );
- glDisable(GL_CULL_FACE);
- glDisable(GL_DEPTH_TEST);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glBlendEquation(GL_FUNC_ADD);
-
- opacity *= opacity;
-
- shader_vgloader_use();
- shader_vgloader_uInverseRatio( (v2f){1.0f,1.0f} );
- shader_vgloader_uTime( vg.time_real );
-
- f32 ratio = (f32)_vg_window.w / (f32)_vg_window.h;
- shader_vgloader_uRatio( ratio );
- shader_vgloader_uOpacity( opacity );
- glBindVertexArray( vg_loader.vao );
- glDrawArrays( GL_TRIANGLES, 0, 6 );
-
- ui_prerender( &vg_ui.ctx );
- vg_ui_set_screen( _vg_window.w, _vg_window.h );
-
-
- ui_rect test = { 0, _vg_window.h - 28*2, _vg_window.w, 28 };
- if( vg_loader.information_for_user )
- {
- vg_ui.ctx.font = &vgf_default_large;
- ui_text( &vg_ui.ctx, test, vg_loader.information_for_user,
- 1, k_ui_align_middle_center, 0 );
- vg_ui.ctx.font = &vgf_default_small;
- }
-
- ui_postrender( &vg_ui.ctx, vg.time_frame_delta );
-}
-
-void vg_loader_render(void)
-{
- VG_ASSERT( _vg_thread_has_flags( VG_THREAD_OWNS_OPENGL ) );
- glViewport( 0,0, _vg_window.w, _vg_window.h );
- glBindFramebuffer( GL_FRAMEBUFFER, 0 );
- glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
- glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
- vg.loader_ring = 1.0f;
-}
-
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_loader.c"
-#else
-
-#define VG_ENGINE_READY 0x1
-#define VG_CLIENT_READY 0x2
-#define VG_ALL_READY (VG_ENGINE_READY|VG_CLIENT_READY)
-#define VG_READYNESS_MAX 0x8000
-#define VG_CLIENT_READYNESS_MAX 0x80000000
-
-struct vg_loader
-{
- /* Shutdown steps */
- struct loader_free_step
- {
- void (*fn_free)(void);
- }
- step_buffer[16];
- u32 step_count, step_action;
-
- GLuint vao, vbo;
- const char *information_for_user;
-
- u32 loading_count;
-}
-extern vg_loader;
-
-VG_API void _vg_loader_init(void);
-
-VG_API void _vg_loader_set_user_information( const c8 *information );
-void vg_loader_render(void);
-void vg_loader_render_ring( f32 opacity );
-
-VG_API void _vg_loader_increment( i32 inc );
-VG_API bool _vg_loader_visible(void);
-
-#endif
+++ /dev/null
-struct vg_log vg_log;
-
-static void _vg_log_append_line( const char *str )
-{
- if( vg_log.log_line_count < VG_ARRAY_LEN( vg_log.log ) )
- vg_log.log_line_count ++;
-
- char *dest = vg_log.log[ vg_log.log_line_current ++ ];
- vg_strncpy( str, dest, VG_ARRAY_LEN(vg_log.log[0]), k_strncpy_allow_cutoff );
-
- if( vg_log.log_line_current >= VG_ARRAY_LEN( vg_log.log ) )
- vg_log.log_line_current = 0;
-}
-
-VG_API void _vg_log_pre_init(void)
-{
- vg_log.initialized = 1;
-
- vg_str log_path;
- vg_strnull( &log_path, vg_log.crash_path, sizeof(vg_log.crash_path) );
- vg_strcat( &log_path, "crash-" );
- vg_strcatu64( &log_path, time(NULL), 10 );
- vg_strcat( &log_path, "-trace.txt" );
-
- if( !vg_strgood( &log_path ) )
- exit(-2);
-
- VG_ASSERT( VG_MUTEX_INIT( vg_log.lock ) );
-}
-
-void _vg_logx_va( FILE *file, const char *location, const char *prefix,
- const char *colour,
- const char *fmt, va_list args )
-{
- if( vg_log.initialized == 0 )
- {
- printf( "vg_log not initialized before use. (call vg_log_init()).\n" );
- exit(-1);
- return;
- }
-
- VG_MUTEX_LOCK( vg_log.lock );
-
- char buffer[4096], line[96];
- vsnprintf( buffer, VG_ARRAY_LEN(buffer), fmt, args );
-
-#if defined( VG_ENGINE )
- if( vg_log.plain_output_file )
- {
- fputs( prefix, vg_log.plain_output_file );
- fputs( " | ", vg_log.plain_output_file );
- fputs( buffer, vg_log.plain_output_file );
- }
-#endif
-
- int line_length = snprintf( line, 90, "%s%3s" KNRM "|%s ", colour, prefix, colour );
-
- for( u32 i=0; i<VG_ARRAY_LEN(buffer); i ++ )
- {
- char c = buffer[i];
- char marker = '|';
- bool flush = 0;
-
- line[ line_length ++ ] = c;
-
- if( line_length >= 90 )
- {
- line[ line_length ++ ] = '\n';
- line[ line_length ] = '\0';
- flush = 1;
- marker = '.';
- }
-
- if( c == '\n' )
- {
- line[ line_length ] = '\0';
- flush = 1;
- }
-
- if( flush || c == '\0' )
- {
- if( location )
- {
-
-#if defined( VG_MULTITHREAD )
-# if defined( VG_ENGINE )
- fprintf( file, "%s|"KNRM"%.32s", _vg_thread_prefix(), location );
-# else
- fprintf( file, KNRM "%.32s", location );
-# endif
-#endif
- }
-
- _vg_log_append_line( line );
- fputs( line, file );
- line_length = snprintf( line, 90, "%s " KNRM "%c%s ", colour, marker, colour );
- }
-
- if( c == '\0' ) break;
- if( buffer[i+1] == '\0' ) break;
- }
-
- VG_MUTEX_UNLOCK( vg_log.lock );
-}
-
-void vg_logx( FILE *file,
- const char *location, const char *prefix,
- const char *colour,
- const char *fmt, ... )
-{
- va_list args;
- va_start( args, fmt );
- _vg_logx_va( file,
-#if defined( VG_LOG_SOURCE_INFO )
- location,
-#else
- NULL,
-#endif
- prefix, colour, fmt, args );
- va_end( args );
-}
-
-void vg_fatal_error( const char *fmt, ... )
-{
- va_list args;
- va_start( args, fmt );
- _vg_logx_va( stderr, NULL, "sos", KRED, fmt, args );
- va_end( args );
- vg_fatal_exit( "VG Assertion (check STDOUT, or the text logfile if enabled)" );
-}
-
-void vg_fatal_exit( const char *comment )
-{
-#if defined( VG_RELEASE_MODE )
- int fd = open( vg_log.crash_path, O_CREAT | O_WRONLY, 0666 );
- if( fd == -1 )
- exit(-3);
-#else
- fflush( stdout );
- int fd = STDOUT_FILENO;
-#endif
-
- char buf[ 1024 ];
- vg_str line;
- vg_strnull( &line, buf, sizeof(buf) );
-
-#if defined( _WIN32 )
- HANDLE process = GetCurrentProcess();
- HANDLE thread = GetCurrentThread();
- CONTEXT context;
- STACKFRAME64 stack;
- DWORD machine_type;
-
- RtlCaptureContext( &context );
- ZeroMemory( &stack, sizeof(STACKFRAME64) );
- machine_type = IMAGE_FILE_MACHINE_AMD64;
- stack.AddrPC.Offset = context.Rip;
- stack.AddrFrame.Offset = context.Rsp;
- stack.AddrStack.Offset = context.Rsp;
- stack.AddrPC.Mode = AddrModeFlat;
- stack.AddrFrame.Mode = AddrModeFlat;
- stack.AddrStack.Mode = AddrModeFlat;
-
- SymInitialize( process, NULL, TRUE );
- SymSetOptions( SYMOPT_LOAD_LINES | SYMOPT_UNDNAME );
-
- vg_strcat( &line, "OS: Windows\n"
- "Comment: " );
- vg_strcat( &line, comment );
- vg_strcat( &line, "\nStack trace\n"
- "-----------------------------------\n" );
- vg_str_flushfd( &line, fd );
-
- DWORD frame_number = 0;
- while( StackWalk64( machine_type, process, thread, &stack, &context, NULL, SymFunctionTableAccess64,
- SymGetModuleBase64, NULL))
- {
- if( stack.AddrPC.Offset == 0 )
- break;
-
- DWORD64 symbol_addr = stack.AddrPC.Offset;
- DWORD64 displacement = 0;
- char symbol_buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)] = {0};
- SYMBOL_INFO *symbol = (SYMBOL_INFO *)symbol_buffer;
- symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
- symbol->MaxNameLen = MAX_SYM_NAME;
-
- char function_name[ MAX_SYM_NAME ] = "Unknown";
- if( SymFromAddr( process, symbol_addr, &displacement, symbol ) )
- {
- strncpy( function_name, symbol->Name, MAX_SYM_NAME - 1 );
- function_name[ MAX_SYM_NAME - 1 ] = '\0';
- }
-
- vg_strcat( &line, " [" );
- vg_strcatu64( &line, frame_number, 10 );
- vg_strcat( &line, "] " );
- vg_strcatu64( &line, symbol_addr, 16 );
- vg_strcat( &line, " " );
- vg_strcat( &line, function_name );
- vg_strcat( &line, "\n" );
- vg_str_flushfd( &line, fd );
-
- frame_number ++;
- }
-
- SymCleanup(process);
-
-#else
- vg_strcat( &line, "OS: GNU/Linux\n"
- "Comment: " );
- vg_strcat( &line, comment );
- vg_strcat( &line, "\n\nStack trace\n"
- "-----------------------------------\n" );
- vg_str_flushfd( &line, fd );
- void *functions[20];
- int count = backtrace( functions, 20 );
- backtrace_symbols_fd( functions, count, fd );
-#endif
-
-#if defined( VG_RELEASE_MODE )
- vg_strcat( &line, "\n\nVG Console log\n"
- "-----------------------------------\n" );
-
- int ptr = vg_log.log_line_current;
- for( int i=0; i<vg_log.log_line_count; i ++ )
- {
- if( ptr >= vg_log.log_line_count )
- ptr = 0;
-
- bool vt=0;
- for( u32 j=0; j<sizeof(vg_log.log[0]); j ++ )
- {
- char c = vg_log.log[ptr][j];
- if( c == 0 )
- break;
-
- if( vt )
- {
- if( c == 'm' )
- vt = 0;
- }
- else
- {
- if( c == '\x1B' )
- vt = 1;
- else
- vg_strcatch( &line, c );
- }
- }
- vg_str_flushfd( &line, fd );
-
- ptr ++;
- }
-
- close( fd );
-#endif
-
- exit(-1);
-}
+++ /dev/null
-#define VG_LOG_MCSTR(S) VG_LOG_MCSTR2(S)
-#define VG_LOG_MCSTR2(S) #S
-#define VG_LOG_WHERE __FILE__ ":" VG_LOG_MCSTR(__LINE__)\
- " "
-
-#define vg_success( ... ) \
- vg_logx(stdout,VG_LOG_WHERE,"ok",KGRN,__VA_ARGS__)
-#define vg_info( ... ) \
- vg_logx(stdout,VG_LOG_WHERE,"inf",KNRM,__VA_ARGS__)
-#define vg_warn( ... ) \
- vg_logx(stdout,VG_LOG_WHERE,"wrn",KYEL,__VA_ARGS__ )
-#define vg_error( ... ) \
- vg_logx(stdout,VG_LOG_WHERE,"err",KRED,__VA_ARGS__)
-#define vg_low( ... ) \
- vg_logx(stdout,VG_LOG_WHERE,"log",KBLK,__VA_ARGS__)
-#define vg_logsteam( ... ) \
- vg_logx(stdout,VG_LOG_WHERE,"stm",KBLU,__VA_ARGS__)
-
-/* TODO: Virtualize these colour codes to be our own. These vt codes are uncomfy to code against + look bad if they
- * accidently leak outside of the terminal.
- *
- * Instead we can do like:
- * "Jim is [c red]a strange fellow"
- *
- * Or maybe there is a common standard?
- */
-
-#define KNRM "\x1B[0m"
-//#define KBLK "\x1B[30m"
-#define KBLK "\x1B[0m"
-#define KRED "\x1B[31m"
-#define KGRN "\x1B[32m"
-#define KYEL "\x1B[33m"
-#define KBLU "\x1B[34m"
-#define KMAG "\x1B[35m"
-#define KCYN "\x1B[36m"
-#define KWHT "\x1B[37m"
-
-struct vg_log
-{
- char crash_path[256];
- char log[64][96];
- u32 log_line_count, log_line_current;
-
- FILE *plain_output_file;
- bool initialized;
-
-#if defined( VG_MULTITHREAD )
- vg_mutex lock;
-#endif
-}
-extern vg_log;
-
-VG_API void _vg_log_pre_init(void);
-void vg_log_free(void);
-
-void vg_logx( FILE *file,
- const char *location, const char *prefix,
- const char *colour,
- const char *fmt, ... );
-
-void _vg_logx_va( FILE *file,
- const char *location, const char *prefix,
- const char *colour,
- const char *fmt, va_list args );
+++ /dev/null
-struct vg_magi _vg_magi;
-
-struct vg_magi_panel *_vg_magi_open( ui_px w, ui_px h, u32 flags )
-{
- VG_ASSERT( _vg_magi.panel_count < VG_MAGI_MAX_PANELS );
- struct vg_magi_panel *panel = &_vg_magi.panels[ _vg_magi.panel_count ++ ];
- panel->rect[0] = 32;
- panel->rect[1] = 32;
- panel->rect[2] = w;
- panel->rect[3] = h;
- panel->title = "";
- panel->data = NULL;
- panel->minimized = 0;
- panel->flags = flags;
- panel->ui_cb = NULL;
- panel->close_cb = NULL;
- panel->min_w = w;
- panel->min_h = h;
- panel->corner = 0;
-
- if( flags & VG_MAGI_PERSISTENT )
- strcpy( panel->cmd, vg_console.input );
-
- return panel;
-}
-
-void _vg_magi_area_change( i32 d[2] )
-{
- for( u32 i=0; i<_vg_magi.panel_count; i ++ )
- {
- struct vg_magi_panel *panel = &_vg_magi.panels[ i ];
- if( panel->corner & 0x1 )
- panel->rect[0] += d[0];
- if( panel->corner & 0x2 )
- panel->rect[1] += d[1];
- }
-}
-
-static void vg_magi_getcorner( ui_rect rect, u32 id, ui_px corner[2] )
-{
- corner[0] = rect[0];
- corner[1] = rect[1];
- if( id&0x1 ) corner[0] += rect[2];
- if( id&0x2 ) corner[1] += rect[3];
-}
-
-void _vg_magi_render( ui_context *ctx )
-{
- if( _vg_magi.panel_count == 0 ) return;
-
- u32 highlight = 0xffffffff,
- top = _vg_magi.panel_count-1;
-
- if( _vg_magi.mode == k_magi_mode_none )
- {
- for( u32 i=0; i<_vg_magi.panel_count; i ++ )
- {
- struct vg_magi_panel *panel = &_vg_magi.panels[ i ];
- if( ui_inside_rect( panel->rect, ctx->mouse ) )
- highlight = i;
- }
-
- /* bring to top */
- if( (highlight < top) && ui_click_down( ctx, UI_MOUSE_ANY ) )
- {
- struct vg_magi_panel temp = _vg_magi.panels[ highlight ];
-
- for( i32 i=0, j=0; i<_vg_magi.panel_count; i ++ )
- if( i != highlight )
- _vg_magi.panels[ j ++ ] = _vg_magi.panels[ i ];
-
- _vg_magi.panels[ top ] = temp;
- highlight = top;
- }
- }
- else
- {
- highlight = top;
- struct vg_magi_panel *ptop = &_vg_magi.panels[ top ];
-
- if( _vg_magi.mode == k_magi_mode_drag )
- {
- ptop->rect[0] = _vg_magi.drag_original[0] + ctx->mouse_delta[0];
- ptop->rect[1] = _vg_magi.drag_original[1] + ctx->mouse_delta[1];
-
- ui_rect vp = { 0,0, ctx->area[0],ctx->area[1] };
-
- f32 min2 = 9999999.9f;
- for( u32 i=0; i<4; i ++ )
- {
- ui_px c0[2], c1[2];
- vg_magi_getcorner( vp, i, c0 );
- vg_magi_getcorner( ptop->rect, i, c1 );
-
- f32 dx = c0[0]-c1[0],
- dy = c0[1]-c1[1],
- d2 = dx*dx + dy*dy;
-
- if( d2 < min2 )
- {
- min2 = d2;
- ptop->corner = i;
- }
- }
- }
- else if( _vg_magi.mode == k_magi_mode_resize )
- {
- ui_px dx = ctx->mouse_delta[0];
- if( _vg_magi.drag_left ) dx = -dx;
-
- ptop->rect[2] = _vg_magi.drag_original[2] + dx;
- if( ptop->rect[2] < ptop->min_w )
- {
- ptop->rect[2] = ptop->min_w;
- dx = ptop->min_w - _vg_magi.drag_original[2];
- }
-
- if( _vg_magi.drag_left )
- ptop->rect[0] = _vg_magi.drag_original[0] - dx;
-
- if( !ptop->minimized )
- {
- ui_px dy = ctx->mouse_delta[1];
- if( _vg_magi.drag_top ) dy = -dy;
-
- ptop->rect[3] = _vg_magi.drag_original[3] + dy;
- if( ptop->rect[3] < ptop->min_h )
- {
- ptop->rect[3] = ptop->min_h;
- dy = ptop->min_h - _vg_magi.drag_original[3];
- }
-
- if( _vg_magi.drag_top )
- ptop->rect[1] = _vg_magi.drag_original[1] - dy;
- }
- }
-
- if( ui_click_up( ctx, UI_MOUSE_ANY ) )
- _vg_magi.mode = k_magi_mode_none;
- }
-
- i32 j=0;
- for( i32 i=0; i<_vg_magi.panel_count; i ++ )
- {
- struct vg_magi_panel *panel = &_vg_magi.panels[ i ];
-
- ui_rect title, rect;
- ui_split( panel->rect, k_ui_axis_h, 28, 0, title, rect );
- ui_fill( ctx, title, ui_opacity( ui_colour( ctx, k_ui_bg+7 ), 0.9f ) );
-
- ui_rect min_button, quit_button;
- ui_split( title, k_ui_axis_v, title[2]-title[3], 2, title, quit_button );
- int should_close = ui_button_text( ctx, quit_button, "X", 1 );
-
- ui_split( title, k_ui_axis_v, title[2]-title[3], 2, title, min_button );
- int should_min = ui_button_text( ctx, min_button,
- panel->minimized? "+": "-", 1 );
-
- if( panel->flags & VG_MAGI_PERSISTENT )
- {
- ui_text( ctx, title, panel->cmd, 1, k_ui_align_middle_center,
- ui_colourcont( ctx, k_ui_bg+7 ) );
- }
- else
- {
- ui_text( ctx, title, panel->title, 1, k_ui_align_middle_center,
- ui_colourcont( ctx, k_ui_bg+7 ) );
- }
-
- ui_fill( ctx, rect, ui_opacity( ui_colour( ctx, k_ui_bg+1 ), 0.7f ) );
-
- if( i == highlight )
- {
- /* TODO: enable interaction */
-
- if( ui_click_down( ctx, UI_MOUSE_MIDDLE ) )
- {
- if( panel->flags & VG_MAGI_MOVEABLE )
- {
- _vg_magi.mode = k_magi_mode_drag;
- rect_copy( panel->rect, _vg_magi.drag_original );
- }
- }
- else if( ui_click_down( ctx, UI_MOUSE_RIGHT ) )
- {
- if( panel->flags & VG_MAGI_RESIZEABLE )
- {
- _vg_magi.mode = k_magi_mode_resize;
- _vg_magi.drag_top = 0;
- _vg_magi.drag_left = 0;
-
- if( ctx->mouse[0] < panel->rect[0]+panel->rect[2]/2 )
- _vg_magi.drag_left = 1;
- if( ctx->mouse[1] < panel->rect[1]+panel->rect[3]/2 )
- _vg_magi.drag_top = 1;
-
- rect_copy( panel->rect, _vg_magi.drag_original );
- }
- }
-
- ui_outline( ctx, panel->rect, 1, ui_colour( ctx, k_ui_bg+7 ), 0 );
- }
- else
- {
- /* TODO: disable interaction */
- }
-
- if( !panel->minimized )
- panel->ui_cb( ctx, rect, panel );
-
- if( should_close == 1 )
- {
- if( panel->close_cb )
- panel->close_cb( panel );
-
- continue;
- }
-
- if( should_min == 1 )
- {
- panel->minimized ^= 0x1;
- if( panel->minimized )
- {
- panel->sh = panel->rect[3];
- panel->rect[3] = 32;
- }
- else
- {
- panel->rect[3] = panel->sh;
- }
- }
-
- if( j != i )
- _vg_magi.panels[ j ] = _vg_magi.panels[ i ];
-
- j ++;
- }
-
- _vg_magi.panel_count = j;
-}
-
-void vg_magi_restore(void)
-{
- vg_console_exec( 2, (const char *[]){ "magi.conf", "silent" } );
-}
-
-void vg_magi_save(void)
-{
- FILE *fp = fopen( "cfg/magi.conf", "w" );
-
- if( !fp )
- {
- vg_error( "Cannot open cfg/magi.conf\n" );
- return;
- }
-
- for( u32 i=0; i<_vg_magi.panel_count; i ++ )
- {
- struct vg_magi_panel *magi = &_vg_magi.panels[i];
-
- if( magi->flags & VG_MAGI_PERSISTENT )
- {
- ui_rect vp = {0,0,_vg_window.w,_vg_window.h};
- ui_px c[2], p[2];
- vg_magi_getcorner( vp, magi->corner, c );
- p[0] = magi->rect[0] - c[0];
- p[1] = magi->rect[1] - c[1];
-
- fprintf( fp, "%s\n", magi->cmd );
- fprintf( fp, "magi_pos %d %d %d %d %d %d\n",
- p[0], p[1], magi->rect[2],
- magi->minimized? magi->sh: magi->rect[3],
- (i32)magi->minimized, magi->corner );
- }
- }
-
- fclose( fp );
-}
-
-static int cmd_vg_magi_dim( int argc, const char *argv[] )
-{
- if( !_vg_magi.panel_count )
- {
- vg_error( "No active panels to apply that to.\n" );
- return 0;
- }
-
- if( argc == 0 )
- {
- vg_error( "Usage: magi_pos x y w h <M>\n" );
- return 0;
- }
-
- struct vg_magi_panel *magi = &_vg_magi.panels[ _vg_magi.panel_count-1 ];
- for( int i=0; i<4; i ++ )
- if( argc >= i+1 )
- magi->rect[i] = atoi( argv[i] );
-
- if( argc >= 5 )
- {
- magi->minimized = atoi( argv[4] );
- if( magi->minimized )
- {
- magi->sh = magi->rect[3];
- magi->rect[3] = 32;
- }
- }
-
- if( argc >= 6 )
- {
- ui_rect vp = {0,0,_vg_window.w,_vg_window.h};
- ui_px c[2];
- magi->corner = atoi( argv[5] );
- vg_magi_getcorner( vp, magi->corner, c );
- magi->rect[0] += c[0];
- magi->rect[1] += c[1];
- }
-
- return 1;
-}
-
-VG_API void _vg_magi_register(void)
-{
- vg_console_reg_cmd( "magi_pos", cmd_vg_magi_dim, NULL );
-}
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_magi.c"
-#else
-
-#define VG_MAGI_MAX_PANELS 8
-
-#define VG_MAGI_RESIZEABLE 0x1
-#define VG_MAGI_MOVEABLE 0x2
-#define VG_MAGI_PERSISTENT 0x4
-#define VG_MAGI_ALL (VG_MAGI_RESIZEABLE|VG_MAGI_MOVEABLE|VG_MAGI_PERSISTENT)
-
-struct vg_magi
-{
- struct vg_magi_panel
- {
- bool minimized;
- const char *title;
- ui_rect rect;
- ui_px sh;
-
- u32 corner; /* which corner of screen relative to? TL, TR, BL, BR */
-
- u32 flags;
- void *data;
-
- char cmd[96]; /* used for persistence */
- ui_px min_w, min_h;
-
- void(*ui_cb)( ui_context *ctx, ui_rect rect, struct vg_magi_panel *magi );
- void(*close_cb)( struct vg_magi_panel *me );
- }
- panels[ VG_MAGI_MAX_PANELS ];
- u32 panel_count;
-
- enum magi_mode
- {
- k_magi_mode_none,
- k_magi_mode_drag,
- k_magi_mode_resize
- }
- mode;
-
- bool drag_top, drag_left;
-
- ui_rect drag_original;
- ui_px drag_start[2];
-}
-extern _vg_magi;
-
-VG_API void _vg_magi_register(void);
-
-struct vg_magi_panel *_vg_magi_open( ui_px w, ui_px h, u32 flags );
-void _vg_magi_render( ui_context *ctx );
-void vg_magi_save(void);
-void vg_magi_restore(void);
-void _vg_magi_area_change( i32 d[2] );
-
-#endif
+++ /dev/null
-void *vg_malloc( u64 size )
-{
- void *buf = malloc( size );
- if( !buf )
- vg_fatal_error( "Out of memory (OS)\n" );
- return buf;
-}
-
-void vg_free( void *buf )
-{
- free( buf );
-}
-
-void *vg_realloc( void *buf, u64 size )
-{
- buf = realloc( buf, size );
- if( !buf )
- vg_fatal_error( "Out of memory (OS)\n" );
- return buf;
-}
-
-void vg_zero_mem( void *buffer, u32 length )
-{
- u8 *u8s = buffer;
- for( u32 i=0; i<length; i++ )
- u8s[i] = 0;
-}
-
-/* NOT USED IN THIS FILE */
-u32 vg_align16( u32 s )
-{
- u32 m = (s + 15) >> 4;
- return m << 4;
-}
-
-u32 vg_align8( u32 s )
-{
- u32 m = (s + 7) >> 3;
- return m << 3;
-}
-
-u32 vg_align4( u32 s )
-{
- u32 m = (s + 3) >> 2;
- return m << 2;
-}
-
-void vg_stack_init( vg_stack_allocator *stack, void *buffer, u32 capacity, const char *debug_name )
-{
- VG_ASSERT( sizeof( vg_stack_allocator ) == 24 );
- vg_zero_mem( stack, sizeof(vg_stack_allocator) );
- stack->data = buffer? buffer: vg_malloc( capacity );
- stack->capacity = capacity;
- stack->flags = buffer? 0: VG_STACK_ALLOCATOR_BUFFER_FROM_MALLOC;
-}
-
-void *vg_stack_allocate( vg_stack_allocator *stack, u32 size, u32 alignment, const char *debug_name )
-{
- if( !stack )
- return vg_malloc( size );
- VG_ASSERT( (alignment >= 1) && (alignment <= 64) );
- VG_ASSERT( ~stack->offset & 0x10000000 );
- VG_ASSERT( ~size & 0x10000000 );
-
- u32 new_usage = stack->offset + size + alignment;
- if( new_usage > stack->capacity )
- {
- vg_fatal_error( "Stack allocator overflow (capacity: %u, used: %u, new_usage: %u)\n",
- stack->capacity, stack->offset, new_usage );
- }
- while( ((u64)stack->data + stack->offset) & (alignment-1) )
- stack->offset ++;
- void *block = stack->data + stack->offset;
- stack->offset += size;
- return block;
-}
-
-void vg_stack_clear( vg_stack_allocator *stack )
-{
- stack->offset = 0;
-}
-
-void vg_stack_free( vg_stack_allocator *stack )
-{
- VG_ASSERT( stack->flags & VG_STACK_ALLOCATOR_BUFFER_FROM_MALLOC );
- vg_free( stack->data );
- vg_zero_mem( stack, sizeof(vg_stack_allocator) );
-}
-
-u32 vg_stack_offset( vg_stack_allocator *stack, void *pointer )
-{
- return pointer - stack->data;
-}
-
-void *vg_stack_pointer( vg_stack_allocator *stack, u32 offset )
-{
- return stack->data + offset;
-}
-
-void vg_stack_extend_last( vg_stack_allocator *stack, i32 extra_bytes )
-{
- stack->offset += extra_bytes;
-}
-
-static void vg_mem_print_size( u32 bytes, char buf[32] )
-{
- if( bytes > 1024*1024 )
- snprintf( buf, 32, "%umb", bytes/(1024*1024) );
- else if( bytes > 1024 )
- snprintf( buf, 32, "%ukb", bytes/1024 );
- else
- snprintf( buf, 32, "%ub", bytes );
-}
-
-#if 0
-void vg_mem_dumphex( FILE *fp, void *buffer, u32 offset, u32 bytes )
-{
- fprintf( fp, "buffer at %p, offset +%u, length %u\n", buffer, offset, bytes );
- fprintf( fp, "----------------------------------------------------------------------------\n" );
-
- u32 x = 0;
- for( u32 i=0; i<bytes; i ++ )
- {
- if( x == 0 )
- fprintf( fp, "+0x%06x | ", i );
-
- u8 byte = ((u8 *)buffer)[ offset + i ];
- fprintf( fp, "%02x ", byte );
-
- x++;
- if( x == 16 || (i+1==bytes) )
- {
- for( u32 j=0; j<16-x; j ++ )
- fputs( " ", fp );
-
- for( u32 j=0; j<x; j ++ )
- {
- u8 charbyte = ((u8 *)buffer)[ offset + i - (x-1) + j ];
- if( charbyte >= 33 && charbyte <= 126 )
- fputc( charbyte, fp );
- else
- fputc( charbyte == 0? '.': ' ', fp );
- }
-
- fputc( '\n', fp );
- x = 0;
- }
- }
-
- fprintf( fp, "----------------------------------------------------------------------------\n" );
-}
-#endif
-
-#if !defined( VG_ENGINE )
-
-#define VG_TEMP_STACK_MAX 8
-vg_stack_allocator _temp_allocator;
-u32 _temp_offsets[ VG_TEMP_STACK_MAX ];
-u32 _temp_stack_depth = 0;
-
-VG_API u32 _vg_start_temp_frame(void)
-{
- if( !_temp_allocator.data )
- vg_stack_init( &_temp_allocator, NULL, VG_MB(20), "Temp allocator" );
- VG_ASSERT( _temp_stack_depth < VG_TEMP_STACK_MAX );
- u32 offset = _temp_allocator.offset;
- _temp_offsets[ _temp_stack_depth ++ ] = offset;
- return offset;
-}
-
-VG_API void _vg_end_temp_frame( u32 whence )
-{
- VG_ASSERT( _temp_stack_depth );
- _temp_stack_depth --;
- VG_ASSERT( _temp_offsets[ _temp_stack_depth ] == whence );
- _temp_allocator.offset = whence;
-}
-
-VG_API void *_vg_temp_alloc( u32 bytes, u32 alignment )
-{
- VG_ASSERT( _temp_stack_depth );
- return vg_stack_allocate( &_temp_allocator, bytes, alignment, NULL );
-}
-
-VG_API vg_stack_allocator *_vg_temp_stack(void)
-{
- return &_temp_allocator;
-}
-
-#endif
+++ /dev/null
-#include <stdlib.h>
-
-#define VG_KB( X ) (X*1024)
-#define VG_MB( X ) (X*1024*1024)
-#define VG_GB( X ) (X*1024*1024*1024)
-#define VG_STACK_USE_HEAP NULL
-
-void *vg_malloc( u64 size );
-void *vg_realloc( void *buf, u64 size );
-void vg_free( void *buf );
-void vg_zero_mem( void *buffer, u32 length );
-
-typedef struct vg_stack_allocator vg_stack_allocator;
-
-/* system flags */
-#define VG_STACK_ALLOCATOR_BUFFER_FROM_MALLOC 0x4
-
-/* 24 bytes */
-struct vg_stack_allocator
-{
- u32 capacity; /* bytes */
- u32 offset;
- u16 flags;
- u16 unused0, unused1;
- void *data;
-};
-
-#if 0
-void vg_mem_dumphex( FILE *fp, void *buffer, u32 offset, u32 bytes );
-#endif
-
-/* NOT USED IN THIS FILE */
-u32 vg_align16( u32 s );
-u32 vg_align8( u32 s );
-u32 vg_align4( u32 s );
-
-/* If parent_stack is NULL, it will malloc a new stack of size
- * If parent_stack is not NULL, it will allocate the new stack inside of this one. This allows it to be seen in the
- * metadata as a tree structure.
- */
-void vg_stack_init( vg_stack_allocator *stack, void *buffer, u32 capacity, const char *debug_name );
-void *vg_stack_allocate( vg_stack_allocator *stack, u32 size, u32 alignment, const char *debug_name );
-void *vg_stack_allocate_locked();
-
-void vg_stack_clear( vg_stack_allocator *stack );
-void vg_stack_free( vg_stack_allocator *stack );
-void vg_stack_set_flags( vg_stack_allocator *stack, u16 append_flags );
-void vg_stack_extend_last( vg_stack_allocator *stack, i32 extra_bytes );
-
-u32 vg_stack_offset( vg_stack_allocator *stack, void *pointer );
-void *vg_stack_pointer( vg_stack_allocator *stack, u32 offset );
-
-#if !defined( VG_ENGINE )
-VG_API u32 _vg_start_temp_frame(void);
-VG_API void _vg_end_temp_frame( u32 whence );
-VG_API void *_vg_temp_alloc( u32 bytes, u32 alignment );
-VG_API vg_stack_allocator *_vg_temp_stack(void);
-#endif
+++ /dev/null
-void vg_pool_switch( vg_pool *pool, vg_pool_chain *source, vg_pool_chain *dest, u16 which )
-{
- VG_ASSERT( which );
-
- vg_pool_node *pnode = &pool->nodes[ which -1 ];
- if( source )
- {
- /* unlink from source list pointers */
- if( source->tail == which )
- source->tail = pnode->l;
- if( source->head == which )
- source->head = pnode->r;
-
- VG_ASSERT( source->count );
- source->count --;
- }
-
- /* unlink self from chain */
- if( pnode->l )
- pool->nodes[ pnode->l -1 ].r = pnode->r;
- if( pnode->r )
- pool->nodes[ pnode->r -1 ].l = pnode->l;
- pnode->r = 0;
- pnode->l = 0;
-
- /* update destination list head/tail pointers */
- if( dest )
- {
- pnode->r = dest->head;
- if( dest->head )
- pool->nodes[ dest->head -1 ].l = which;
- dest->head = which;
- if( dest->tail == 0 )
- dest->tail = which;
-
- dest->count ++;
- VG_ASSERT( dest->count ); // Overflow? in some mad scenario...
- }
-}
-
-u16 vg_pool_reference( vg_pool *pool, u16 pool_id, bool increment )
-{
- VG_ASSERT( pool_id );
- VG_ASSERT( pool );
-
- vg_pool_node *pnode = &pool->nodes[ pool_id -1 ];
- if( increment )
- {
- VG_ASSERT( pnode->refcount < 100 ); // 100 is one of the largest numbers known to man
- pnode->refcount ++;
- }
- else
- {
- VG_ASSERT( pnode->refcount > 0 );
- pnode->refcount --;
- }
-
- return pnode->refcount;
-}
-
-void vg_pool_init( vg_pool *pool, vg_pool_chain *start_chain, u16 count, vg_stack_allocator *stack )
-{
- u32 size = sizeof(vg_pool_node) * count;
- pool->nodes = vg_stack_allocate( stack, size, 8, "Pool Nodes" );
- pool->count = count;
-
- for( u16 i=0; i<count; i ++ )
- {
- u16 id = i+1;
- pool->nodes[ i ].l = id-1;
- pool->nodes[ i ].r = id==count? 0: id+1;
- pool->nodes[ i ].refcount = 0;
- pool->nodes[ i ].unused0 = 0;
- }
-
- start_chain->head = 1;
- start_chain->tail = count;
- start_chain->count = count;
- start_chain->unused0 = 0;
-}
-
-u32 vg_pool_index( vg_pool *pool, u16 id )
-{
- VG_ASSERT( id );
- VG_ASSERT( id <= pool->count );
- return id-1;
-}
-
-u16 vg_pool_next( vg_pool *pool, u16 pool_id, bool right )
-{
- VG_ASSERT( pool_id );
- if( right ) return pool->nodes[ pool_id -1 ].r;
- else return pool->nodes[ pool_id -1 ].l;
-}
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_mem_pool.c"
-#else
-
-/*
- * This is most straightforwardly a way to maintain stable ID's for various other things, it does not directly manage
- * the memory here.
- */
-
-#define VG_POOL_INCREMENT 1
-#define VG_POOL_DECREMENT 0
-
-typedef struct vg_pool vg_pool;
-typedef struct vg_pool_node vg_pool_node;
-typedef struct vg_pool_chain vg_pool_chain;
-
-struct vg_pool_node
-{
- u16 l, r, refcount, unused0;
-};
-
-struct vg_pool
-{
- vg_pool_node *nodes;
- u32 count;
-};
-
-struct vg_pool_chain
-{
- u16 head, tail, count, unused0;
-};
-
-u32 vg_pool_index( vg_pool *pool, u16 pool_id );
-u16 vg_pool_reference( vg_pool *pool, u16 pool_id, bool increment );
-void vg_pool_init( vg_pool *pool, vg_pool_chain *chain, u16 count, vg_stack_allocator *stack );
-u16 vg_pool_next( vg_pool *pool, u16 pool_id, bool right );
-void vg_pool_switch( vg_pool *pool, vg_pool_chain *source, vg_pool_chain *dest, u16 which );
-
-#endif
+++ /dev/null
-struct mem_view_data
-{
- void *base_buffer;
- u32 route[8];
- u32 route_depth;
-
- bool vis_dirty;
- u32 vis_offset;
- v4f vis_colour;
- f32 vis_inv_max;
- GLuint vis_tex;
- u32 vis_i, vis_size;
-
- struct mem_view_info
- {
- const char *display_name;
- u32 buffer_offset, buffer_size; /* offset + size into route[0]->data */
-
- bool is_stack;
- u32 stack_used_bytes,
- stack_children_start, stack_children_count; /* offset + count into this array (infos), children are sorted
- by capacity / size */
- }
- infos[ 4096 ];
- u32 info_count;
- f32 sizes[ 4096 ];
-
- f32 vis_data[256*256];
-};
-
-void squarey_layout( ui_rect rect, f32 *areas, u32 area_count, void (*cb)( u32, ui_rect, void* ), void *cb_user )
-{
- f32 area_total = 0.0f;
- for( u32 i=0; i<area_count; i ++ )
- area_total += areas[i];
-
- u32 i=0, row_start=0, row_count=1;
- f32 s = areas[0];
-
-L_LOOP_ADJUST:;
- u32 short_side = rect[3] < rect[2]? 1: 0;
- f32 norm = ((f32)rect[2] * (f32)rect[3]) / area_total,
- w = rect[ 2+short_side ],
- w2n = w*w*norm;
-L_LOOP:
- i ++;
- if( i == area_count )
- {
- cb( area_count-1, rect, cb_user );
- return;
- }
-
- f32 s0 = s*norm,
- s1 = s0+areas[i]*norm,
- cur = vg_maxf( w2n*areas[row_start]/(s0*s0), (s0*s0)/(w2n*areas[i-1]) ),
- new = vg_maxf( w2n*areas[row_start]/(s1*s1), (s1*s1)/(w2n*areas[i ]) );
-
- if( (new < cur) && (i != area_count-1) )
- {
- s += areas[ i ];
- row_count ++;
- goto L_LOOP;
- }
-
- ui_px height = s0 / w;
- ui_rect out_box = { rect[0], rect[1] };
- out_box[ 2+short_side^0x1 ] = height;
- f32 ihn = (1.0f/(f32)height) * norm;
-
- f32 x = rect[ short_side ];
- ui_px start = x, end;
- for( u32 j=0; j<row_count; j ++ )
- {
- if( j == row_count-1 )
- end = rect[short_side]+rect[2+short_side];
- else
- {
- x += areas[ row_start + j ] * ihn;
- end = x;
- }
-
- out_box[ short_side ] = start;
- out_box[ 2+short_side ] = end-start;
- cb( row_start + j, out_box, cb_user );
- start=end;
- }
-
- rect[ short_side^0x1 ] += height;
- rect[ 2+short_side^0x1 ] -= height;
-
- area_total -= s;
- s = areas[ i ];
-
- row_count = 1;
- row_start = i;
- goto L_LOOP_ADJUST;
-}
-
-struct vg_mem_draw_blocks_context
-{
- ui_context *ui_ctx;
- struct mem_view_data *mv;
- u32 root_colour;
- u32 root_id;
- u32 depth;
-
- u32 highlight_id;
- u32 highlight_colour;
- ui_rect highlight_rect;
-};
-
-static void vg_mem_view_stack( struct vg_mem_draw_blocks_context *context, ui_rect rect );
-
-static void vg_mem_draw_block_cb( u32 idx, ui_rect rect, void *user )
-{
- struct vg_mem_draw_blocks_context *context = user;
- ui_rect tmp;
- rect_copy( rect, tmp );
- tmp[2] --;
- tmp[3] --;
-
- struct mem_view_info *root_info = &context->mv->infos[ context->root_id ],
- *this_info = &context->mv->infos[ root_info->stack_children_start + idx ];
-
- u32 colour;
- if( context->root_colour ) colour = context->root_colour;
- else colour = ~0xff000000&((idx+5)*0x45d9f3b);
-
- if( this_info->is_stack )
- {
- struct vg_mem_draw_blocks_context next_level = *context;
- next_level.depth ++;
- next_level.root_colour = colour;
- next_level.root_id = root_info->stack_children_start + idx;
-
- ui_rect subrect;
- rect_copy( rect, subrect );
- vg_mem_view_stack( &next_level, subrect );
- }
- else
- {
- ui_fill( context->ui_ctx, tmp, 0x80000000 | colour );
- ui_outline( context->ui_ctx, tmp, -1, 0xff000000 | colour, 0 );
- }
-
- if( context->depth == 0 )
- {
- if( ui_inside_rect( rect, context->ui_ctx->mouse ) )
- {
- context->highlight_colour = colour;
- context->highlight_id = root_info->stack_children_start + idx;
- rect_copy( rect, context->highlight_rect );
- }
- }
-}
-
-static void vg_mem_view_stack( struct vg_mem_draw_blocks_context *context, ui_rect rect )
-{
- struct mem_view_info *info = &context->mv->infos[ context->root_id ];
- VG_ASSERT( info->is_stack );
-
- if( info->stack_used_bytes )
- {
- /* draw unused stack space as dark black */
- if( info->stack_used_bytes < info->buffer_size )
- {
- u32 short_side = rect[3] < rect[2]? 1: 0;
- f32 p = 1.0f-((f32)info->stack_used_bytes / (f32)info->buffer_size);
- ui_px h = (f32)rect[2+short_side^0x1] * p*p;
- ui_rect out_box = {rect[0], rect[1]};
- out_box[ 2+short_side^0x1 ] = h;
- out_box[ 2+short_side ] = rect[ 2+short_side ];
-
- ui_fill( context->ui_ctx, out_box, 0x80000000 );
-
- char asize[32];
- vg_mem_print_size( info->buffer_size - info->stack_used_bytes, asize );
- ui_text( context->ui_ctx, out_box, asize, 1, k_ui_align_middle_center, 0 );
-
- rect[ short_side^0x1 ] += h;
- rect[ 2+short_side^0x1 ] -= h;
- }
-
- if( info->stack_children_count )
- {
- squarey_layout( rect, &context->mv->sizes[ info->stack_children_start ], info->stack_children_count,
- vg_mem_draw_block_cb, context );
- }
- else
- ui_fill( context->ui_ctx, rect, 0x80101010 );
- }
- else
- ui_fill( context->ui_ctx, rect, 0x80000000 );
-}
-
-static void cb_vg_mem_view( ui_context *ctx, ui_rect rect, struct vg_magi_panel *magi )
-{
- struct mem_view_data *mv = magi->data;
-
- ui_rect left;
- ui_split( rect, k_ui_axis_v, 256+16, 2, left, rect );
- ui_fill( ctx, left, ui_opacity( ui_colour( ctx,k_ui_bg+1 ), 0.8f ) );
-
- /* Tree back-tracker */
- {
- ui_rect box = { left[0],left[1],left[2],24 };
- u32 new_depth = mv->route_depth;
- for( u32 i=0; i<mv->route_depth+1; i ++ )
- {
- struct mem_view_info *info = &mv->infos[ mv->route[i] ];
- if( i != mv->route_depth )
- {
- if( ui_button_text( ctx, box, info->display_name, 1 ) == 1 )
- {
- new_depth = i;
- }
- }
- else
- {
- ui_fill( ctx, box, ui_colour( ctx, k_ui_bg ) );
- ui_text( ctx, box, info->display_name, 1, k_ui_align_middle_center, 0 );
- }
-
- box[0] += 8;
- box[2] -= 8;
- box[1] += 24;
- }
- mv->route_depth = new_depth;
- ui_px v = (mv->route_depth+1)*24;
- left[1] += v;
- left[3] -= v;
- }
-
- struct vg_mem_draw_blocks_context context =
- {
- .ui_ctx = ctx,
- .mv = mv,
- .root_colour = 0,
- .root_id = mv->route[ mv->route_depth ],
- .highlight_id = 0xffffffff,
- .depth = 0
- };
- vg_mem_view_stack( &context, rect );
-
- if( context.highlight_id != 0xffffffff )
- {
- struct mem_view_info *highlight_info = &mv->infos[ context.highlight_id ];
-
- ui_outline( ctx, context.highlight_rect, 1, ui_colour( ctx,k_ui_bg+7 ), 0 );
- ui_info( ctx, left, highlight_info->display_name );
-
- char buf[32];
- vg_mem_print_size( highlight_info->buffer_size, buf );
- ui_info( ctx, left, buf );
-
- if( mv->vis_offset != highlight_info->buffer_offset )
- {
- mv->vis_offset = highlight_info->buffer_offset;
- mv->vis_i = 0;
- mv->vis_size = highlight_info->buffer_size;
- mv->vis_dirty = 1;
- mv->vis_inv_max = 1.0f;
-
- f32 nrm = 2.6f / 255.0f;
- mv->vis_colour[0] = (f32)((context.highlight_colour ) & 0xff) * nrm;
- mv->vis_colour[1] = (f32)((context.highlight_colour>>8 ) & 0xff) * nrm;
- mv->vis_colour[2] = (f32)((context.highlight_colour>>16) & 0xff) * nrm;
- mv->vis_colour[3] = 1.0f;
-
- for( u32 i=0; i<256*256; i++ )
- mv->vis_data[i] = 0.0f;
- }
-
- if( mv->vis_i+1 < mv->vis_size )
- {
- const u8 *src = mv->base_buffer + mv->vis_offset;
- for( u32 it=0; it<VG_KB(20) && (mv->vis_i+1 < mv->vis_size); it ++ )
- {
- u8 x = src[mv->vis_i], y = src[mv->vis_i+1];
- u32 coord = y*256 + x;
- mv->vis_data[ coord ] += 1.0f;
- mv->vis_i ++;
- }
-
- f32 median = (f32)mv->vis_i;
- mv->vis_inv_max = 1.0f/logf(1.0f+median*2.0f);
- mv->vis_dirty = 1;
- }
-
- if( mv->vis_dirty )
- {
- glBindTexture( GL_TEXTURE_2D, mv->vis_tex );
- glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 256, 256, GL_RED, GL_FLOAT, mv->vis_data );
- }
-
- if( highlight_info->is_stack )
- ui_info( ctx, left, "Linear Allocator (expand)" );
- else
- ui_info( ctx, left, "Leaf" );
-
- ui_rect freq_box = { left[0]+8, left[1], 256,256 };
-
- ui_flush( ctx, k_ui_shader_colour, NULL );
- ui_fill_rect( ctx, freq_box, 0xffffffff, (ui_px[4]){ 0,256,256,0 } );
-
- // FIXME FIXME
-#if 0
- struct ui_batch_shader_data_image_gradient inf = {
- .resource = &mv->vis_tex,
- .log = 1,
- .scale = mv->vis_inv_max
- };
- v4_copy( mv->vis_colour, vg_ui.colour );
- ui_flush( ctx, k_ui_shader_grad, &inf );
- v4_copy( (v4f){1,1,1,1}, vg_ui.colour );
-
- if( highlight_info->is_stack )
- {
- if( ui_click_down( ctx, UI_MOUSE_LEFT ) )
- {
- mv->route_depth ++;
- mv->route[ mv->route_depth ] = context.highlight_id;
- }
- }
-#endif
- }
-}
-
-static void cb_mem_view_close( struct vg_magi_panel *me )
-{
- struct mem_view_data *mv = me->data;
- glDeleteTextures( 1, &mv->vis_tex );
- vg_free( me->data );
-}
-
-static struct
-{
- const c8 *name;
- vg_stack_allocator *stack;
-}
-_vg_mem_named_buffers[] =
-{
-};
-
-int _CB_vg_mem_infosort( const void *a, const void *b )
-{
- const struct mem_view_info *info_a = a,
- *info_b = b;
- return (i32)(info_a->buffer_size < info_b->buffer_size) - (i32)(info_a->buffer_size > info_b->buffer_size);
-}
-
-static int cmd_vg_mem_view( int argc, const char *argv[] )
-{
- if( argc != 1 )
- {
- vg_error( "Usage: vg_mem_view <named_buffer>\n" );
- return 0;
- }
-
-#if 0
- for( u32 i=0; i<VG_ARRAY_LEN( _vg_mem_named_buffers ); i ++ )
- {
- if( !strcmp( _vg_mem_named_buffers[i].name, argv[0] ) )
- {
- struct vg_magi_panel *magi = _vg_magi_open( 512+16, 512, VG_MAGI_ALL );
- magi->title = "Memory outliner";
-
- struct mem_view_data *mv = vg_malloc(sizeof(struct mem_view_data));
- mv->route[0] = 0;
- mv->route_depth = 0;
- mv->vis_offset = 0xffffffff;
- mv->info_count = 1;
-
- /* cache all allocations in full tree */
- struct route_frame
- {
- bool init;
- vg_stack_allocator *stack;
- struct mem_view_info *info;
- u32 buffer_base_offset;
-
- u32 descend_i;
- }
- route[8];
- u32 route_depth = 0;
-
- route[0].init = 0;
- route[0].stack = _vg_mem_named_buffers[i].stack;
- route[0].info = &mv->infos[ 0 ];
- route[0].buffer_base_offset = 0;
- route[0].descend_i = 0;
-
- mv->infos[0].display_name = _vg_mem_named_buffers[i].name;
- mv->infos[0].buffer_offset = 0;
- mv->infos[0].buffer_size = _vg_mem_named_buffers[i].stack->capacity;
- mv->infos[0].is_stack = 1;
- mv->infos[0].stack_used_bytes = _vg_mem_named_buffers[i].stack->offset;
- mv->sizes[0] = sqrtf(mv->infos[0].buffer_size);
-
- mv->base_buffer = _vg_mem_named_buffers[i].stack->data;
-
- l0:{
- struct route_frame *frame = &route[ route_depth ];
-
- if( !frame->init )
- {
- frame->init = 1;
- frame->info->stack_children_start = mv->info_count;
- frame->info->stack_children_count = 0;
-
- /* create array of all immediate child allocations */
- u32 offset = frame->stack->offset - frame->stack->last_allocation_totalsize;
-
- if( (frame->stack->offset == 0) || !(frame->stack->flags & VG_STACK_ALLOCATOR_METADATA) )
- goto l1;
-
- l2:{
- vg_allocation_meta *meta = frame->stack->data + offset;
-
- if( mv->info_count == VG_ARRAY_LEN(mv->infos) )
- {
- vg_error( "Reached maximum allocation infos! (%u)\n", mv->info_count );
- goto e1;
- }
-
- struct mem_view_info *info = &mv->infos[ mv->info_count ];
- info->display_name = meta->name;
- info->buffer_offset = frame->buffer_base_offset + offset + sizeof(vg_allocation_meta);
- info->buffer_size = meta->size;
-
- mv->info_count ++;
- frame->info->stack_children_count ++;
-
- if( meta->flags & VG_ALLOCATION_FLAG_IS_STACK )
- {
- info->is_stack = 1;
- vg_stack_allocator *substack = mv->base_buffer + info->buffer_offset;
-
- info->stack_used_bytes = substack->offset;
- info->stack_children_start = 0; /* deferred to !frame->init */
- info->stack_children_count = 0;
- }
- else
- info->is_stack = 0;
-
- if( offset )
- {
- offset = meta->previous_offset;
- goto l2;
- }
- }
- }
-
- l1: if( frame->descend_i < frame->info->stack_children_count )
- {
- struct mem_view_info *info = &mv->infos[ frame->info->stack_children_start + frame->descend_i ];
- frame->descend_i ++;
-
- if( info->is_stack )
- {
- route_depth ++;
-
- struct route_frame *next_frame = &route[ route_depth ];
- next_frame->init = 0;
- next_frame->stack = mv->base_buffer + info->buffer_offset;
- next_frame->info = info;
- next_frame->buffer_base_offset = info->buffer_offset + sizeof(vg_stack_allocator);
- next_frame->descend_i = 0;
-
- goto l0;
- }
- else goto l1;
- }
- else
- {
- /* Sort children by size, calculate sqrt f32 sizes, and step down */
- qsort( &mv->infos[ frame->info->stack_children_start ], frame->info->stack_children_count,
- sizeof(struct mem_view_info), _CB_vg_mem_infosort );
-
- for( u32 i=0; i<frame->info->stack_children_count; i ++ )
- {
- u32 index = frame->info->stack_children_start + i;
- struct mem_view_info *info = &mv->infos[ index ];
- mv->sizes[ index ] = sqrtf(info->buffer_size);
- }
-
- if( route_depth )
- {
- route_depth --;
- goto l0;
- }
- }
- }
-
- vg_success( "Cached %u allocations.\n", mv->info_count );
-
- e1: glGenTextures( 1, &mv->vis_tex );
- glBindTexture( GL_TEXTURE_2D, mv->vis_tex );
- glTexImage2D( GL_TEXTURE_2D, 0, GL_R32F, 256,256, 0, GL_RED, GL_FLOAT, NULL );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
-
- magi->data = mv;
- magi->ui_cb = cb_vg_mem_view;
- magi->close_cb = cb_mem_view_close;
- return 1;
- }
- }
-#endif
-
- vg_error( "No named buffer '%s'\n", argv[0] );
- return 0;
-}
-
-static void cmd_vg_mem_view_poll( int argc, const char *argv[] )
-{
- const char *term = argv[ argc-1 ];
-
- if( argc == 1 )
- for( u32 i=0; i<VG_ARRAY_LEN( _vg_mem_named_buffers ); i ++ )
- console_suggest_score_text( _vg_mem_named_buffers[i].name, term, 0 );
-}
-
-VG_API void _vg_mem_view_register(void)
-{
- vg_console_reg_cmd( "vg_mem_view", cmd_vg_mem_view, cmd_vg_mem_view_poll );
-}
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_mem_view.c"
-#else
-extern int vg_mem_view;
-VG_API void _vg_mem_view_register(void);
-#endif
+++ /dev/null
-#if defined( VG_MSG_LEGACY )
-/* write a buffer from msg, rang checked. */
-void vg_msg_wbuf( vg_msg *msg, u8 *buf, u32 len )
-{
- if( msg->error != k_vg_msg_error_OK ) return;
- if( msg->cur.co+len > msg->max ){
- msg->error = k_vg_msg_error_overflow;
- return;
- }
-
- for( u32 i=0; i<len; i++ ){
- msg->buf[ msg->cur.co ++ ] = buf[i];
- }
-}
-#endif
-
-/* read a buffer from msg, rang checked. */
-void vg_msg_rbuf( vg_msg *msg, u8 *buf, u32 len )
-{
- if( msg->error != k_vg_msg_error_OK ) return;
- if( msg->cur.co+len > msg->max ){
- msg->error = k_vg_msg_error_overflow;
- return;
- }
-
- for( u32 i=0; i<len; i++ ){
- buf[i] = msg->buf[ msg->cur.co ++ ];
- }
-}
-
-#if defined( VG_MSG_LEGACY )
-/* write null terminated string to stream */
-void vg_msg_wstr( vg_msg *msg, const char *str )
-{
- if( msg->error != k_vg_msg_error_OK ) return;
- for( u32 i=0;; i++ ){
- vg_msg_wbuf( msg, (u8[]){ str[i] }, 1 );
- if( !str[i] ) break;
- }
-}
-#endif
-
-/* read null terminated string, range check and generate hash (djb2) */
-const char *vg_msg_rstr( vg_msg *msg, u32 *djb2 )
-{
- if( msg->error != k_vg_msg_error_OK ) return 0;
-
- u32 hash = 5381, c;
- const char *str = (void *)(&msg->buf[ msg->cur.co ]);
-
- while( (c = msg->buf[ msg->cur.co ++ ]) ){
- if( msg->cur.co >= msg->max ){
- msg->error = k_vg_msg_error_overflow;
- return 0;
- }
- hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
- }
-
- *djb2 = hash;
- return str;
-}
-
-#if defined( VG_MSG_LEGACY )
-/* begin a new frame in message stream */
-void vg_msg_frame( vg_msg *msg, const char *name )
-{
- if( msg->error != k_vg_msg_error_OK ) return;
-
- msg->cur.depth ++;
- vg_msg_wbuf( msg, (u8[]){ k_vg_msg_frame }, 1 );
- vg_msg_wstr( msg, name );
-}
-
-/* end frame in message stream */
-void vg_msg_end_frame( vg_msg *msg )
-{
- if( msg->error != k_vg_msg_error_OK ) return;
- if( !msg->cur.depth ){
- msg->error = k_vg_msg_error_unbalanced;
- return;
- }
- msg->cur.depth --;
- vg_msg_wbuf( msg, (u8[]){ k_vg_msg_endframe }, 1 );
-}
-
-/* write a KV string to stream */
-void vg_msg_wkvstr( vg_msg *msg, const char *key, const char *value )
-{
- vg_msg_wbuf( msg, (u8[]){ k_vg_msg_kvstring }, 1 );
- vg_msg_wstr( msg, key );
- vg_msg_wstr( msg, value );
-}
-
-/* write a binary block to stream */
-void vg_msg_wkvbin( vg_msg *msg, const char *key, u8 *bin, u32 len )
-{
- vg_msg_wbuf( msg, (u8[]){ k_vg_msg_kvbin }, 1 );
- vg_msg_wstr( msg, key );
- vg_msg_wbuf( msg, (u8 *)(&len), 4 );
- vg_msg_wbuf( msg, bin, len );
-}
-#endif
-
-u32 vg_msg_cmd_array_count( u8 code )
-{
- return ((code & k_vg_msg_array_count_bits)>>2) + 1;
-}
-
-u32 vg_msg_cmd_type_size( u8 code )
-{
- return 0x1 << (code & k_vg_msg_type_size_bits);
-}
-
-/* get the byte count of a sized code */
-u32 vg_msg_cmd_bytecount( u8 code )
-{
- return vg_msg_cmd_array_count( code ) * vg_msg_cmd_type_size( code );
-}
-
-u8 vg_msg_count_bits( u32 count )
-{
- VG_ASSERT( count <= 16 );
- return ((count-1)<<2);
-}
-
-#if defined( VG_MSG_LEGACY )
-/* write a sized type */
-void vg_msg_wkvnum( vg_msg *msg, const char *key, u8 type, u8 count, void *data )
-{
- u8 code = type | vg_msg_count_bits(count);
- vg_msg_wbuf( msg, &code, 1 );
- vg_msg_wstr( msg, key );
- vg_msg_wbuf( msg, data, vg_msg_cmd_bytecount(code) );
-}
-#endif
-
-void vg_msg_init( vg_msg *msg, u8 *buffer, u32 len )
-{
- msg->buf = buffer;
- msg->cur.co = 0;
- msg->cur.depth = 0;
- msg->error = k_vg_msg_error_OK;
- msg->max = len;
-}
-
-/*
- * The stream reading interface
- * -----------------------------------------------------------------------------
- */
-
-/* move the cursor through the next message. it will always read in the value or
- * create an error if it runs of the end of the stream. every possible command
- * must be handled in this function */
-int vg_msg_next( vg_msg *msg, vg_msg_cmd *cmd )
-{
- vg_msg_rbuf( msg, &cmd->code, 1 );
- if( msg->error != k_vg_msg_error_OK ) return 0;
-
- /* |sized| |count-1| |shift|
- * 0 1 0 0 0 1 0 0 0x44 (1 byte, float[2]. So, never used anyway)
- * converts to
- * 1 0 0 0 0 0 1 0 0x82
- */
- if( cmd->code == 0x44 ) cmd->code = 0x82;
-
- cmd->key_djb2 = 0;
- if( msg->error != k_vg_msg_error_OK ) return 0;
-
- if( cmd->code == k_vg_msg_frame ){
- cmd->key = vg_msg_rstr( msg, &cmd->key_djb2 );
- msg->cur.depth ++;
- }
- else if( cmd->code == k_vg_msg_endframe ){
- if( !msg->cur.depth ){
- msg->error = k_vg_msg_error_unbalanced;
- return 0;
- }
- msg->cur.depth --;
- }
- else if( cmd->code >= k_vg_msg_kv ){
- cmd->key = vg_msg_rstr( msg, &cmd->key_djb2 );
- cmd->value_djb2 = 0;
-
- if( cmd->code & k_vg_msg_type_base_bits ){
- u32 bytes = vg_msg_cmd_bytecount( cmd->code );
- cmd->value = &msg->buf[ msg->cur.co ];
- msg->cur.co += bytes;
- }
- else if( cmd->code == k_vg_msg_kvstring ){
- cmd->value = vg_msg_rstr( msg, &cmd->value_djb2 );
- }
- else if( cmd->code == k_vg_msg_kvbin ){
- vg_msg_rbuf( msg, (u8 *)(&cmd->len), 4 );
- if( msg->error != k_vg_msg_error_OK )
- return 0;
- cmd->value = &msg->buf[ msg->cur.co ];
- msg->cur.co += cmd->len;
- }
- else
- msg->error = k_vg_msg_error_unhandled_cmd;
-
- if( msg->cur.co > msg->max )
- msg->error = k_vg_msg_error_overflow;
- }
- else
- msg->error = k_vg_msg_error_unhandled_cmd;
-
- if( msg->error != k_vg_msg_error_OK )
- return 0;
- else
- return 1;
-}
-
-#if defined( VG_MSG_LEGACY )
-/* move through the frame(and subframes) until we fall out of it */
-int vg_msg_skip_frame( vg_msg *msg )
-{
- vg_msg_cmd cmd;
-
- u32 start_depth = msg->cur.depth;
- while( vg_msg_next( msg, &cmd ) )
- if( msg->cur.depth < start_depth )
- return 1;
- return 0;
-}
-
-/*
- * A more friendly but slower interface
- * -----------------------------------------------------------------------------
- */
-
-/* moves to a frame,
- * returns 0 if drops out of scope or ends.
- */
-int vg_msg_seekframe( vg_msg *msg, const char *name )
-{
- vg_msg_cursor orig = msg->cur;
- vg_msg_cmd cmd;
- while( vg_msg_next( msg, &cmd ) ){
- if( msg->cur.depth < orig.depth ){
- msg->cur = orig;
- return 0;
- }
- if( msg->cur.depth != orig.depth+1 )
- continue;
- if( cmd.code == k_vg_msg_frame )
- if( !name || VG_STRDJB2_EQ( name, cmd.key, cmd.key_djb2 ) )
- return 1;
- }
-
- msg->cur = orig;
- return 0;
-}
-#endif
-
-/*
- * Convert any type integral type to u64
- */
-u64 vg_msg_cast_to_u64( const void *src, u8 src_base, u8 src_size )
-{
- if( src_base == k_vg_msg_float )
- {
- return (u64)vg_msg_cast_to_f64( src, src_base, src_size );
- }
- else
- {
- u64 a = 0;
- memcpy( &a, src, src_size );
- return a;
- }
-}
-
-/*
- * Convert any integral type to i64
- */
-i64 vg_msg_cast_to_i64( const void *src, u8 src_base, u8 src_size )
-{
- if( src_base == k_vg_msg_float )
- {
- return (i64)vg_msg_cast_to_f64( src, src_base, src_size );
- }
- else
- {
- u64 a = 0;
- memcpy( &a, src, src_size );
-
- if( (src_base == k_vg_msg_signed) && (src_size != 8) ){
- /* extend sign bit */
- u64 sign_bit = 0x1llu << ((src_size*8)-1);
- if( a & sign_bit )
- a |= (0xffffffffffffffffllu << (64-__builtin_clzll( a )));
- }
-
- return *((i64*)&a);
- }
-}
-
-/*
- * Convert any integral type to f64
- */
-f64 vg_msg_cast_to_f64( const void *src, u8 src_base, u8 src_size )
-{
- if( src_base == k_vg_msg_float )
- {
- if( src_size == 4 )
- {
- f32 a = 0;
- memcpy( &a, src, sizeof(a) );
- return (f64)a;
- }
- else if( src_size == 8 )
- {
- f64 a = 0;
- memcpy( &a, src, sizeof(a) );
- return a;
- }
- else return 0.0;
- }
- else
- return (f64)vg_msg_cast_to_i64( src, src_base, src_size );
-}
-
-#if defined( VG_MSG_LEGACY )
-/*
- * Convert any full integral type code to another
- * Passing in non-integral codes is undefined
- */
-void vg_msg_cast( const void *src, u8 src_code, void *dst, u8 dst_code )
-{
- if( src_code == dst_code ){
- memcpy( dst, src, vg_msg_cmd_bytecount( src_code ) );
- }
- else {
- u32 src_n = vg_msg_cmd_array_count( src_code ),
- dst_n = vg_msg_cmd_array_count( dst_code ),
- src_s = vg_msg_cmd_type_size( src_code ),
- dst_s = vg_msg_cmd_type_size( dst_code ),
- src_b = src_code & k_vg_msg_type_base_bits,
- dst_b = dst_code & k_vg_msg_type_base_bits;
-
- memset( dst, 0, dst_s * dst_n );
-
- for( u32 i=0; i<VG_MIN(src_n,dst_n); i ++ ){
- const void *ptr_s = src + i*src_s;
- void *ptr_d = dst + i*dst_s;
-
- if( dst_b == k_vg_msg_unsigned ){
- u64 a = vg_msg_cast_to_u64( ptr_s, src_b, src_s );
- if ( dst_s == 1 ) *((u8 *)ptr_d) = (u8 )a;
- else if( dst_s == 2 ) *((u16*)ptr_d) = (u16)a;
- else if( dst_s == 4 ) *((u32*)ptr_d) = (u32)a;
- else if( dst_s == 8 ) *((u64*)ptr_d) = a;
- }
- else if( dst_b == k_vg_msg_signed ){
- i64 a = vg_msg_cast_to_i64( ptr_s, src_b, src_s );
- if ( dst_s == 1 ) *((i8 *)ptr_d) = (i8 )a;
- else if( dst_s == 2 ) *((i16*)ptr_d) = (i16)a;
- else if( dst_s == 4 ) *((i32*)ptr_d) = (i32)a;
- else if( dst_s == 8 ) *((i64*)ptr_d) = a;
- }
- else {
- f64 a = vg_msg_cast_to_f64( ptr_s, src_b, src_s );
- if ( dst_s == 4 ) *((f32*)ptr_d) = (f32)a;
- else if( dst_s == 8 ) *((f64*)ptr_d) = a;
- }
- }
- }
-}
-#endif
-
-/*
- * search in current level from cursor, to find kv cmd
- * returns 0 if not found
- * Cursor does not move
- * If found, the kv command is written to cmd
- */
-int vg_msg_getkvcmd( vg_msg *msg, const char *key, vg_msg_cmd *cmd )
-{
- vg_msg_cursor orig = msg->cur;
- while( vg_msg_next( msg, cmd ) ){
- if( msg->cur.depth < orig.depth ){
- msg->cur = orig;
- return 0;
- }
- if( msg->cur.depth > orig.depth )
- continue;
- if( cmd->code > k_vg_msg_kv ){
- if( VG_STRDJB2_EQ( key, cmd->key, cmd->key_djb2 ) ){
- msg->cur = orig;
- return 1;
- }
- }
- }
- msg->error = k_vg_msg_error_OK;
- msg->cur = orig;
- return 0;
-}
-
-#if defined( VG_MSG_LEGACY )
-/*
- * Read a integral KV out to dst, and perform conversion if needed
- * dst is always defined, if its not found its set to 0
- */
-int vg_msg_getkvintg( vg_msg *msg, const char *key, u8 type, void *dst, void *default_value )
-{
- vg_msg_cmd cmd;
- if( vg_msg_getkvcmd( msg, key, &cmd ) )
- {
- vg_msg_cast( cmd.value, cmd.code, dst, type );
- return 1;
- }
- else
- {
- if( default_value )
- memcpy( dst, default_value, vg_msg_cmd_bytecount(type) );
- else
- memset( dst, 0, vg_msg_cmd_bytecount(type) );
-
- return 0;
- }
-}
-
-/* helper for reading string kvs. returns NULL if not found */
-const char *vg_msg_getkvstr( vg_msg *msg, const char *key )
-{
- vg_msg_cmd cmd;
- if( vg_msg_getkvcmd( msg, key, &cmd ) )
- return cmd.value;
- else
- return NULL;
-}
-#endif
-
-#if defined( VG_MSG_LEGACY )
-int vg_msg_getkvvecf( vg_msg *msg, const char *key, u8 type,
- void *v, void *default_value )
-{
- vg_msg_cmd cmd;
- if( vg_msg_getkvcmd( msg, key, &cmd ) )
- {
- vg_msg_cast( cmd.value, cmd.code, v, type );
- return 1;
- }
- else if( default_value )
- vg_msg_cast( default_value, type, v, type );
-
- return 0;
-}
-#endif
-
-
-/* debug the thing */
-void vg_msg_print( vg_msg *msg, u32 len )
-{
- if( msg->error != k_vg_msg_error_OK ){
- printf( "Message contains errors\n" );
- return;
- }
-
- vg_msg b;
- vg_msg_init( &b, msg->buf, len );
-
- vg_msg_cmd cmd;
- while( vg_msg_next( &b, &cmd ) )
- {
- if( cmd.code == k_vg_msg_frame )
- {
- for( u32 i=0; i<b.cur.depth-1; i++ ) printf( " " );
- printf( "'%s'{\n", cmd.key );
- }
- else
- {
- for( u32 i=0; i<b.cur.depth; i++ ) printf( " " );
-
- if( cmd.code == k_vg_msg_endframe )
- printf( "}\n" );
- else if( cmd.code == k_vg_msg_kvstring )
- printf( "'%s': '%s'\n", cmd.key, (char *)cmd.value );
- else if( cmd.code == k_vg_msg_kvbin )
- printf( "'%s': <binary data> (%u bytes)\n", cmd.key, cmd.len );
- else {
- u32 base = cmd.code & k_vg_msg_type_base_bits,
- count = vg_msg_cmd_array_count( cmd.code ),
- size = vg_msg_cmd_type_size( cmd.code );
-
- printf( "'%s': ", cmd.key );
-
- if( count > 1 ) printf( "{ " );
-
- for( u32 i=0; i<count; i++ ){
- const void *p = cmd.value + size*i;
-
- if( base == k_vg_msg_unsigned ){
- printf(
-#ifdef _WIN32
- "%llu"
-#else
- "%lu"
-#endif
- , vg_msg_cast_to_u64( p, base, size ) );
- }
- else if( base == k_vg_msg_signed ){
- printf(
-#ifdef _WIN32
- "%lld"
-#else
- "%ld"
-#endif
- , vg_msg_cast_to_i64( p, base, size ) );
- }
- else
- printf( "%f", vg_msg_cast_to_f64( p, base, size ));
-
- if( i+1<count ) printf(", ");
- }
-
- if( count > 1 ) printf( " }" );
- printf( "\n" );
- }
- }
- }
-}
-
-#if defined( VG_MSG_TO_KVS )
-bool vg_kvs_append_from_legacy_msg2( vg_kvs *kvs, u32 root, void *buffer, u32 len )
-{
- vg_msg b;
- vg_msg_init( &b, buffer, len );
-
- u32 frame_stack[ 16 ];
- u32 frame_depth = 0;
- frame_stack[0] = root;
-
- vg_msg_cmd cmd;
- while( vg_msg_next( &b, &cmd ) )
- {
- if( cmd.code == k_vg_msg_frame )
- {
- VG_ASSERT( frame_depth < VG_ARRAY_LEN(frame_stack) );
- u32 next = vg_kv_append( kvs, frame_stack[frame_depth++], cmd.key, NULL );
- }
- else
- {
- if( cmd.code == k_vg_msg_endframe )
- {
- VG_ASSERT( frame_depth );
- frame_depth --;
- }
- else if( cmd.code == k_vg_msg_kvstring )
- {
- vg_kv_append( kvs, frame_stack[frame_depth], cmd.key, cmd.value );
- }
- else if( cmd.code == k_vg_msg_kvbin )
- {
- vg_warn( "Unsupported legacy kv code: binary blob.\n" );
- }
- else
- {
- u32 base = cmd.code & k_vg_msg_type_base_bits,
- count = vg_msg_cmd_array_count( cmd.code ),
- size = vg_msg_cmd_type_size( cmd.code );
- c8 formatted[ 1024 ];
- vg_str value_str;
- vg_strnull( &value_str, formatted, sizeof(formatted) );
-
- for( u32 i=0; i<count; i++ )
- {
- const void *p = cmd.value + size*i;
- if( base == k_vg_msg_unsigned )
- {
- u64 val = vg_msg_cast_to_u64( p, base, size );
- vg_strcatu64( &value_str, val, 10 );
- }
- else if( base == k_vg_msg_signed )
- {
- i64 val = vg_msg_cast_to_i64( p, base, size );
- vg_strcati64( &value_str, val, 10 );
- }
- else
- {
- f64 val = vg_msg_cast_to_f64( p, base, size );
- vg_strcatf64( &value_str, val, 10, 5 );
- }
-
- if( i+1!=count )
- vg_strcatch( &value_str, ' ' );
- }
-
- if( !vg_strgood( &value_str ) )
- return 0;
-
- vg_kv_append( kvs, frame_stack[frame_depth], cmd.key, formatted );
- }
- }
- }
-
- return 1;
-}
-#endif
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_msg.c"
-#else
-
-enum vg_msg_code{
- /* low types */
- k_vg_msg_end = 0,
- k_vg_msg_frame = 1,
- k_vg_msg_endframe = 2,
- k_vg_msg_kv = 10,
- k_vg_msg_kvstring = 11,
- k_vg_msg_kvbin = 12,
-
- /* variable sized types */
- k_vg_msg_float = 0x40,
- k_vg_msg_unsigned = 0x80,
- k_vg_msg_signed = 0xC0,
-
- /* masks */
- k_vg_msg_array_count_bits = 0x3C,
- k_vg_msg_type_size_bits = 0x03,
- k_vg_msg_type_base_bits = 0xC0,
- k_vg_msg_type_bits = k_vg_msg_type_base_bits|k_vg_msg_type_size_bits,
-
- /* sizes */
- k_vg_msg_8b = 0x00,
- k_vg_msg_16b = 0x01,
- k_vg_msg_32b = 0x02,
- k_vg_msg_64b = 0x03,
-
- /* common types */
- k_vg_msg_u8 = k_vg_msg_unsigned|k_vg_msg_8b,
- k_vg_msg_u16 = k_vg_msg_unsigned|k_vg_msg_16b,
- k_vg_msg_u32 = k_vg_msg_unsigned|k_vg_msg_32b,
- k_vg_msg_u64 = k_vg_msg_unsigned|k_vg_msg_64b,
- k_vg_msg_i8 = k_vg_msg_signed |k_vg_msg_8b,
- k_vg_msg_i16 = k_vg_msg_signed |k_vg_msg_16b,
- k_vg_msg_i32 = k_vg_msg_signed |k_vg_msg_32b,
- k_vg_msg_i64 = k_vg_msg_signed |k_vg_msg_64b,
- k_vg_msg_f32 = k_vg_msg_float |k_vg_msg_32b,
- k_vg_msg_f64 = k_vg_msg_float |k_vg_msg_64b,
-
- k_vg_msg_v2f = k_vg_msg_float |k_vg_msg_32b | (1<<2),
- k_vg_msg_v3f = k_vg_msg_float |k_vg_msg_32b | (2<<2),
- k_vg_msg_v4f = k_vg_msg_float |k_vg_msg_32b | (3<<2)
-};
-
-typedef struct vg_msg vg_msg;
-typedef struct vg_msg_cmd vg_msg_cmd;
-typedef struct vg_msg_cursor vg_msg_cursor;
-struct vg_msg
-{
- u32 max;
- u8 *buf;
-
- struct vg_msg_cursor
- {
- u32 co, depth;
- }
- cur;
-
- enum vg_msg_error
- {
- k_vg_msg_error_OK,
- k_vg_msg_error_unbalanced,
- k_vg_msg_error_overflow,
- k_vg_msg_error_unhandled_cmd
- }
- error;
-};
-
-struct vg_msg_cmd
-{
- u8 code;
-
- const char *key;
- u32 key_djb2;
-
- const void *value;
- u32 value_djb2;
-
- u32 len; /* set if binary type */
-};
-
-u32 vg_msg_cmd_array_count( u8 code );
-u32 vg_msg_cmd_type_size( u8 code );
-u32 vg_msg_cmd_bytecount( u8 code );
-u8 vg_msg_count_bits( u32 count );
-
-void vg_msg_rbuf( vg_msg *msg, u8 *buf, u32 len );
-const char *vg_msg_rstr( vg_msg *msg, u32 *djb2 );
-u64 vg_msg_cast_to_u64( const void *src, u8 src_base, u8 src_size );
-i64 vg_msg_cast_to_i64( const void *src, u8 src_base, u8 src_size );
-f64 vg_msg_cast_to_f64( const void *src, u8 src_base, u8 src_size );
-
-#if defined( VG_MSG_LEGACY )
-void vg_msg_wbuf( vg_msg *msg, u8 *buf, u32 len );
-void vg_msg_wstr( vg_msg *msg, const char *str );
-void vg_msg_frame( vg_msg *msg, const char *name );
-void vg_msg_end_frame( vg_msg *msg );
-void vg_msg_wkvstr( vg_msg *msg, const char *key, const char *value );
-void vg_msg_wkvbin( vg_msg *msg, const char *key, u8 *bin, u32 len );
-void vg_msg_wkvnum( vg_msg *msg, const char *key, u8 type, u8 count, void *data );
-
-int vg_msg_next( vg_msg *msg, vg_msg_cmd *cmd );
-int vg_msg_skip_frame( vg_msg *msg );
-int vg_msg_seekframe( vg_msg *msg, const char *name );
-void vg_msg_cast( const void *src, u8 src_code, void *dst, u8 dst_code );
-
-int vg_msg_getkvcmd( vg_msg *msg, const char *key, vg_msg_cmd *cmd );
-
-/*
- * Read a integral KV out to dst, and perform conversion if needed
- */
-int vg_msg_getkvintg( vg_msg *msg, const char *key, u8 type, void *dst, void *default_value );
-
-/* helper for reading string kvs. returns NULL if not found */
-const char *vg_msg_getkvstr( vg_msg *msg, const char *key );
-int vg_msg_getkvvecf( vg_msg *msg, const char *key, u8 type, void *v, void *default_value );
-#endif
-
-#if defined( VG_MSG_TO_KVS )
-void vg_msg_init( vg_msg *msg, u8 *buffer, u32 len );
-void vg_msg_print( vg_msg *msg, u32 len );
-bool vg_kvs_append_from_legacy_msg2( vg_kvs *kvs, u32 root, void *buffer, u32 len );
-#endif
-
-#endif
+++ /dev/null
-#if defined( VG_MULTITHREAD )
-# if defined( VG_ENGINE )
-# define vg_semaphore SDL_sem *
-# define vg_mutex SDL_mutex *
-# define VG_SEMAPHORE_INIT( SEMAPHORE, VALUE ) (SEMAPHORE = SDL_CreateSemaphore( VALUE ))
-# define VG_SEMAPHORE_FREE( SEMAPHORE ) SDL_DestroySemaphore( SEMAPHORE ); SEMAPHORE = NULL;
-# define VG_MUTEX_INIT( MUTEX ) (MUTEX = SDL_CreateMutex())
-# define VG_MUTEX_FREE( MUTEX ) SDL_DestroyMutex( MUTEX ); MUTEX = NULL;
-# define VG_MUTEX_LOCK( MUTEX ) SDL_LockMutex( MUTEX )
-# define VG_MUTEX_UNLOCK( MUTEX ) SDL_UnlockMutex( MUTEX )
-# define VG_SEMAPHORE_WAIT( SEMAPHORE ) SDL_SemWait( SEMAPHORE )
-# define VG_SEMAPHORE_POST( SEMAPHORE ) SDL_SemPost( SEMAPHORE )
-# define VG_SEMAPHORE_VALUE( SEMAPHORE ) SDL_SemValue( SEMAPHORE )
-# else
-# define vg_semaphore sem_t
-# define vg_mutex pthread_mutex_t
-# define VG_SEMAPHORE_INIT( SEMAPHORE, VALUE ) (sem_init( &SEMAPHORE, 0, VALUE )==0)
-# define VG_SEMAPHORE_FREE( SEMAPHORE ) sem_destroy( &SEMAPHORE )
-# define VG_SEMAPHORE_WAIT( SEMAPHORE ) sem_wait( &SEMAPHORE )
-# define VG_SEMAPHORE_POST( SEMAPHORE ) sem_post( &SEMAPHORE )
-static inline i32 get_semaphore_value( sem_t *sem )
-{
- int value = 0;
- sem_getvalue( sem, &value );
- return value;
-}
-# define VG_SEMAPHORE_VALUE( SEMAPHORE ) get_semaphore_value( &SEMAPHORE )
-# define VG_MUTEX_INIT( MUTEX ) (pthread_mutex_init( &MUTEX, NULL )==0)
-# define VG_MUTEX_FREE( MUTEX ) pthread_mutex_destroy( &MUTEX )
-# define VG_MUTEX_LOCK( MUTEX ) pthread_mutex_lock( &MUTEX )
-# define VG_MUTEX_UNLOCK( MUTEX ) pthread_mutex_unlock( &MUTEX )
-# endif
-#else
-# define vg_semaphore void *
-# define vg_mutex void *
-# define VG_SEMAPHORE_INIT( SEMAPHORE, VALUE ) 1
-# define VG_SEMAPHORE_FREE( SEMAPHORE ) ;
-# define VG_MUTEX_INIT( MUTEX ) 1
-# define VG_MUTEX_FREE( MUTEX ) ;
-# define VG_MUTEX_LOCK( MUTEX ) 1
-# define VG_MUTEX_UNLOCK( MUTEX ) 1
-# define VG_SEMAPHORE_WAIT( SEMAPHORE ) ;
-# define VG_SEMAPHORE_POST( SEMAPHORE ) ;
-# define VG_SEMAPHORE_VALUE( SEMAPHORE ) 0
-#endif
+++ /dev/null
-#include "vg/vg_opengl.h"
-
-static const char *gl_error_names[] =
-{
- "GL_INVALID_ENUM",
- "GL_INVALID_VALUE",
- "GL_INVALID_OPERATION",
- "GL_STACK_OVERFLOW",
- "GL_STACK_UNDERFLOW",
- "GL_OUT_OF_MEMORY",
- "GL_INVALID_FRAMEBUFFER_OPERATION"
-};
-
-void vg_opengl_log_errors(void)
-{
- u32 err_count = 0;
- GLenum err;
- while( (err = glGetError()) != GL_NO_ERROR )
- {
- if( !err_count )
- vg_info( "OpenGL error buffer:\n" );
-
- u32 err_i = err - 0x0500;
- if( err_i < VG_ARRAY_LEN(gl_error_names) )
- {
- vg_info( " %u %s\n", err, gl_error_names[ err_i ] );
- }
- else
- {
- vg_info( "%u (unknown code)\n", err );
- }
-
- err_count ++;
- }
-
- if( !err_count )
- vg_info( "OpenGL error buffer is empty.\n" );
-}
+++ /dev/null
-#include "dep/glad/glad.h"
-
-void vg_opengl_log_errors(void);
+++ /dev/null
-/*
- * Supported:
- * short flags | -abc
- * short options | -a value
- * multi-set options | -ab value
- *
- * long gnu flag | --long-opt
- * long gnu options | --long-value=test
- * standard agument | regular_thing
- */
-
-struct
-{
- struct vg_opt_reg
- {
- const char *alias, *desc;
- char alias_c;
-
- enum opt_type
- {
- k_opt_flag,
- k_opt_opt,
- k_opt_long_flag,
- k_opt_long_opt
- }
- type;
- }
- infos[32];
- u32 info_count;
-
- struct vg_arg
- {
- enum arg_type
- {
- k_arg_singles,
- k_arg_long,
- k_arg_assign,
- k_arg_regular
- }
- type;
-
- u32 arg_len;
- const char *arg, *value;
- u32 used;
- }
- args[32];
- u32 arg_count;
-}
-_vg_opt;
-
-static void _vg_opt_reg( struct vg_opt_reg reg )
-{
- if( _vg_opt.info_count < VG_ARRAY_LEN( _vg_opt.infos ) )
- _vg_opt.infos[ _vg_opt.info_count ++ ] = reg;
-}
-
-void _vg_opt_init( int argc, const char *argv[] )
-{
- if( argc+1 >= VG_ARRAY_LEN( _vg_opt.args ) )
- {
- vg_error( "Too many arguments!\n" );
- exit(-1);
- }
-
- _vg_opt.arg_count = 0;
- for( u32 i=1; i<argc; i ++ )
- {
- const char *v = argv[i];
- struct vg_arg *arg = &_vg_opt.args[ _vg_opt.arg_count ++ ];
- arg->arg = NULL;
- arg->value = NULL;
- arg->arg_len = 0;
- arg->used = 0;
- if( v[0] == '-' )
- {
- if( v[1] == '-' )
- {
- arg->arg = v+2;
- arg->type = k_arg_long;
- u32 k=2;
- while( v[ k ] )
- {
- if( v[ k ] == '=' )
- {
- arg->arg_len = k-2;
- arg->value = v + k + 1;
- arg->type = k_arg_assign;
- goto next;
- }
- k ++;
- }
- }
- else
- {
- arg->arg = v+1;
- arg->type = k_arg_singles;
- u32 k=1;
- while( v[k] )
- k ++;
- arg->arg_len = k-1;
- arg->used = ~((0x1<<arg->arg_len)-1);
- }
- }
- else
- {
- arg->type = k_arg_regular;
- arg->value = v;
- arg->arg = v;
- }
-next:;
- }
-}
-
-bool _vg_opt_check(void)
-{
- if( vg_long_opt( "help", "Helps you" ) )
- {
- for( u32 i=0; i<_vg_opt.info_count; i ++ )
- {
- struct vg_opt_reg *reg = &_vg_opt.infos[i];
- const char *desc = reg->desc? reg->desc: "";
-
- if( reg->type == k_opt_flag )
- printf( "-%c %s\n", reg->alias_c, desc );
-
- if( reg->type == k_opt_opt )
- printf( "-%c <value> %s\n", reg->alias_c, desc );
-
- if( reg->type == k_opt_long_flag )
- printf( "--%-21s %s\n", reg->alias, desc );
-
- if( reg->type == k_opt_long_opt )
- {
- char temp[32];
- snprintf( temp, 32, "--%s=<value>", reg->alias );
- printf( "%-23s %s\n", temp, desc );
- }
- }
- exit(0);
- }
-
- bool errors = 0;
- for( u32 i=0; i<_vg_opt.arg_count; i ++ )
- {
- struct vg_arg *arg = &_vg_opt.args[ i ];
- if( arg->used != 0xffffffff )
- {
- if( arg->type == k_arg_singles )
- {
- for( u32 j=0; j<32; j ++ )
- {
- if( !(arg->used & (0x1<<j)) )
- vg_error( "Unknown option '%c'\n", arg->arg[j] );
- }
- }
- else
- vg_error( "Unknown option '%s'\n", arg->arg );
- errors = 1;
- }
- }
-
- return errors == 0;
-}
-
-bool vg_opt( char c, const char *desc )
-{
- _vg_opt_reg( (struct vg_opt_reg){ .alias=NULL, .alias_c=c, .desc=desc, .type=k_opt_flag } );
- for( u32 i=0; i<_vg_opt.arg_count; i ++ )
- {
- struct vg_arg *arg = &_vg_opt.args[ i ];
- if( arg->type == k_arg_singles )
- {
- for( u32 j=0; j<arg->arg_len; j ++ )
- {
- if( arg->arg[j] == c )
- {
- arg->used |= 0x1 << j;
- return 1;
- }
- }
- }
- }
- return 0;
-}
-
-const char *vg_opt_arg( char c, const char *desc )
-{
- _vg_opt_reg( (struct vg_opt_reg){ .alias=NULL, .alias_c=c, .desc=desc, .type=k_opt_opt } );
- for( u32 i=0; i+1<_vg_opt.arg_count; i ++ )
- {
- struct vg_arg *arg = &_vg_opt.args[ i ];
- if( arg->type == k_arg_singles )
- {
- for( u32 j=0; j<arg->arg_len; j ++ )
- {
- if( arg->arg[j] == c )
- {
- arg->used |= 0x1 << j;
- return _vg_opt.args[ i + 1 ].value;
- }
- }
- }
- }
- return NULL;
-}
-
-bool vg_long_opt( char *name, const char *desc )
-{
- _vg_opt_reg( (struct vg_opt_reg){ .alias=name, .alias_c=0, .desc=desc, .type=k_opt_long_flag } );
- for( u32 i=0; i<_vg_opt.arg_count; i ++ )
- {
- struct vg_arg *arg = &_vg_opt.args[ i ];
- if( arg->type == k_arg_long )
- {
- if( !strcmp( arg->arg, name ) )
- {
- arg->used = 0xffffffff;
- return 1;
- }
- }
- }
- return 0;
-}
-
-const char *vg_long_opt_arg( char *name, const char *desc )
-{
- _vg_opt_reg( (struct vg_opt_reg){ .alias=name, .alias_c=0, .desc=desc, .type=k_opt_long_opt } );
- for( u32 i=0; i<_vg_opt.arg_count; i ++ )
- {
- struct vg_arg *arg = &_vg_opt.args[ i ];
- if( arg->type == k_arg_assign )
- {
- if( !strncmp( arg->arg, name, arg->arg_len ) )
- {
- arg->used = 0xffffffff;
- return arg->value;
- }
- }
- }
- return NULL;
-}
-
-const char *vg_arg( u32 index )
-{
- u32 count = 0;
- for( u32 i=0; i<_vg_opt.arg_count; i ++ )
- {
- struct vg_arg *arg = &_vg_opt.args[ i ];
- if( arg->type == k_arg_regular )
- {
- count ++;
- if( index+1 == count )
- {
- arg->used = 0xffffffff;
- return arg->value;
- }
- }
- }
- return NULL;
-}
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_opt.c"
-#else
-
-void _vg_opt_init( int argc, const char *argv[] );
-bool _vg_opt_check(void);
-
-/* Example: see if -c is set */
-bool vg_opt( char c, const char *desc );
-
-/* Example: get -c *value* */
-const char *vg_opt_arg( char c, const char *desc );
-
-/* Example see if --big is set */
-bool vg_long_opt( char *name, const char *desc );
-
-/* Example: get --big=value */
-const char *vg_long_opt_arg( char *name, const char *desc );
-
-/* Example: get regular_thing */
-const char *vg_arg( u32 index );
-
-#endif
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_perlin.c"
-#else
-
-f32 vg_perlin_noise2d( f32 x, f32 y, int seed );
-f32 vg_perlin_noise1d( f32 v, int seed );
-f32 vg_perlin_fract_1d( f32 v, f32 freq, int octaves, int seed );
-f32 vg_perlin_fract_2d( f32 x, f32 y, f32 freq, int octaves, int seed );
-
-#endif
+++ /dev/null
-#if !defined( VG_IMPLEMENTATION )
-
-/*
- * Tiers: each tier can only access functions from the tier below it.
- * All client code is considered to be above VG_TIER_HL
- */
-
-#define VG_TIER_0
-/* Tier0: subroutines
- *
- * Operate on simple structures or arrays, and return a code to indicate status or void. Operates purely in stack
- * area. Each function should be likely inlineable, each invocation will take up a MAXIMUM of 8kb
- *
- * Example functions:
- * v3_add( v3f a, v3f b, v3f d );
- * u32 i32_to_string( i32 i, char buffer[32] );
- *
- * Restrictions:
- * No dynamic allocation
- * No dynamic fatal errors (only assertions allowed)
- * No globals / external interaction
- * No multi-threading
- */
-
-#define VG_TIER_1
-/* Tier1: Allocating routines
- *
- * These functions are ones who require dynamic memory, or operating sizes larger than 8kb. They will either;
- * - Take some allocator as a parameter eg. vg_stack_allocator
- * - Or reference a structure that happens to have an allocator attached earlier, like vg_str.
- *
- * The only fatal errors that are allowed here are out of memory errors (eg. malloc fails, or an allocator overflows).
- *
- * Example functions:
- * void vg_strcat( vg_str *str, const c8 *substr );
- *
- * Restrictions:
- * No globals
- * Must be thread safe / does not START anything asynchronously, but can be an async call itself.
- */
-
-#define VG_TIER_2
-/* Tier2: Composite allocating routines
- *
- * Very similar to tier 1, except will allocate in multiple places and/or make use of scratch allocators.
- * These functions typically take a vg_mem_context structure which defines how exactly memory is to be allocated.
- */
-
-#define VG_API
-#define VG_API_INTERNAL
-/* Tier HL: Global, high level system functions
- *
- * These functions typically do not take any allocators, as they are pre-determined by the systems. Raw data and
- * allocations are innaccessible to client code, and functions on this level typically return a handle of small size.
- * (usually from a pool, or circular buffer).
- *
- * These types of functions are often asynchronous
- *
- * Example functions:
- * u32 vg_texture_handle( const c8 *path );
- * void vg_texture_release( u32 id );
- */
-
-#define VG_ENGINE_HOOK( X )
-#define VG_STACK_INLINE
-
-typedef unsigned char u8;
-typedef char c8;
-typedef unsigned short int u16;
-typedef unsigned int u32;
-typedef unsigned long int u64;
-typedef char i8;
-typedef signed short int i16;
-typedef signed int i32;
-typedef signed long int i64;
-typedef float f32;
-typedef double f64;
-typedef unsigned char bool;
-
-/* TODO: delete these!!!!!!! */
-typedef i32 v2i[2];
-typedef i32 v3i[3];
-typedef i32 v4i[4];
-typedef f32 v2f[2];
-typedef f32 v3f[3];
-typedef f32 v4f[4];
-typedef v2f m2x2f[2];
-typedef v3f m3x3f[3];
-typedef v3f m4x3f[4];
-typedef v4f m4x4f[4];
-typedef v3f boxf[2];
-
-/* anything compiled against VG shall implement vg_fatal_exit() somewhere. */
-void vg_fatal_exit( const char *comment );
-void vg_fatal_error( const char *fmt, ... );
-
-#define VG_ASSERT( ITEM, ... ) \
- if( !( ITEM ) ) { \
- vg_fatal_error( "Assertion failed: " VG_LOG_MCSTR(ITEM) "\n" VG_LOG_WHERE "\n" );\
- }
-
-#define VG_MIN( A, B ) ((A)<(B)?(A):(B))
-#define VG_MAX( A, B ) ((A)>(B)?(A):(B))
-#define VG_ARRAY_LEN( A ) (sizeof(A)/sizeof(A[0]))
-
-#endif
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_profiler.c"
-#else
-
-VG_API void _vg_profiler_register(void);
-VG_API void _vg_profiler_init(void);
-
-VG_API u32 _vg_profiler_create( const c8 *name, f32 default_budget_ms );
-VG_API void _vg_profiler_tick( u32 profiler_id );
-VG_API void _vg_profiler_enter_block( u32 profiler_id, const c8 *block_name );
-VG_API void _vg_profiler_exit_block( u32 profiler_id );
-VG_API void _vg_profiler_draw( ui_context *ctx, u32 profiler_id, f32 budget_ms, ui_rect panel, i32 dir, bool normalize );
-
-#endif
+++ /dev/null
-/* Font buffer generated from source file: '/home/harry/Documents/vg/src/fonts/vg_font.png' */
-0xffff0000,0,0,0,0,0,0,0,
-0xffff0000,0,0,0,0,0,0,0,
-0xffff0000,0,0,0,0,0,0,0,
-0xffff0000,0,0,0,0,0,0,0,
-0xffff0c30,0xc300c30,0xc300c30,0xc300c30,0xc300c30,0xc300c30,0xc300c30,0xc300c30,
-0xffff0810,0x8100810,0x8100810,0x8100810,0x8100810,0x8100810,0x8100810,0x8100810,
-0xffff0000,0,0,0,0,0,0,0,
-0xffff0040,0x8000c0,0x1000140,0x18001c0,0x2000240,0x28002c0,0x3000340,0x38003c0,
-0xffff0000,0,0,0,0,0,0,0,
-0xffff0000,0,0,0,0,0,0,0,
-0xffff0000,0,0,0,0,0,0,0,
-0xffff0000,0,0,0,0,0,0,0,
-0xffff0810,0x8100810,0x8100810,0x8100810,0x8100810,0x8100810,0x8100810,0x8100810,
-0xffff0c30,0xc300c30,0xc300c30,0xc300c30,0xc300c30,0xc300c30,0xc300c30,0xc300c30,
-0xffff0000,0,0,0,0,0,0,0,
-0xffff0000,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0xc300c30,0xc300c30,0xc300c30,0xc300c30,0xc300c30,0xc300c30,0xc300c30,0xc300c30,
-0x8100810,0x8100810,0x8100810,0x8100810,0x8100810,0x8100810,0x8100810,0x8100810,
-0x400040,0x400040,0x400040,0x400040,0x400040,0x400040,0x400040,0x400040,
-0x40,0x8000c0,0x1000140,0x18001c0,0x2000240,0x28002c0,0x3000340,0x38003c0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0x8100810,0x8100810,0x8100810,0x8100810,0x8100810,0x8100810,0x8100810,0x8100810,
-0xc300c30,0xc300c30,0xc300c30,0xc300c30,0xc300c30,0xc300c30,0xc300c30,0xc300c30,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0x6600000,0x1800000,0x180,0,0,0,0,
-0,0x6600000,0x1800000,0x180,0x1c00380,0,0,0,
-0xc300180,0x6600660,0x3c00660,0x3c00180,0x38001c0,0x800000,0,0x60,
-0x8100180,0x2200660,0x7e00660,0x7e00080,0x30000c0,0x2a00180,0,0x60,
-0x800180,0xff0,0x60000e0,0x6600000,0x6000060,0x1c00180,0,0xe0,
-0x180,0xff0,0x60000c0,0x6600000,0x6000060,0x1c00180,0,0xc0,
-0x180,0x660,0x7c00180,0x3200000,0x6000060,0x2a00ff0,0x7e0,0x180,
-0x180,0x660,0x3e00180,0x3800000,0x6000060,0x800ff0,0x7e0,0x180,
-0,0xff0,0x600300,0x6c00000,0x6000060,0x180,0,0x300,
-0,0xff0,0x600700,0x6600000,0x6000060,0x180,0,0x700,
-0x8100180,0x660,0x7e00660,0x7f00000,0x30000c0,0x180,0x1800000,0x1800600,
-0xc300180,0x660,0x3c00660,0x3b00000,0x38001c0,0,0x1800000,0x1800600,
-0,0,0x1800000,0,0x1c00380,0,0x1000000,0,
-0,0,0x1800000,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0x3c00180,0x3c003c0,0xe007c0,0x3c007c0,0x3c003c0,0,0x600000,0x60003e0,
-0x7e00380,0x7e007e0,0x1e007e0,0x7e007e0,0x7e007e0,0,0xe00000,0x70007f0,
-0x6600380,0x4600060,0x3e00600,0x6000060,0x6600660,0x1800180,0x1c007e0,0x3800630,
-0xcf00180,0x600060,0x7600600,0x6000060,0x6600660,0x1800180,0x38007e0,0x1c00030,
-0xdf00180,0xe001e0,0xe6007c0,0x7c000c0,0x7e007e0,0,0x7000000,0xe000f0,
-0xfb00180,0x1c001e0,0xff007e0,0x7e000c0,0x7e007e0,0,0x7000000,0xe001e0,
-0xf300180,0x3800060,0xff00060,0x6600180,0x6600060,0x1800180,0x38007e0,0x1c00180,
-0x6600180,0x7000060,0x600060,0x6600180,0x6600060,0x1800180,0x1c007e0,0x3800000,
-0x7e003c0,0x7e007e0,0x6007e0,0x7e00300,0x7e007e0,0x80,0xe00000,0x7000180,
-0x3c003c0,0x7e003c0,0x6003c0,0x3c00300,0x3c003c0,0,0x600000,0x6000180,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0x3c0,0x7c001c0,0x78007e0,0x3e003e0,0x66007e0,0x7e00660,0x6000660,0x3c003c0,
-0x3c007e0,0x7e003e0,0x7c007e0,0x3e007f0,0x66007e0,0x3e00660,0x6000ff0,0x7e007e0,
-0x7e00660,0x6600700,0x6e00600,0x3000e00,0x6600180,0x6006c0,0x6000ff0,0x6600e70,
-0x300660,0x6600600,0x6600600,0x3000c00,0x6600180,0x6007c0,0x6000db0,0x6600c30,
-0x3b00660,0x7e00600,0x66007c0,0x3e00c00,0x7e00180,0x600780,0x6000db0,0x6600c30,
-0x7f007e0,0x7c00600,0x66007c0,0x3e00c70,0x7e00180,0x600780,0x6000db0,0x6600c30,
-0x67007e0,0x6600600,0x6600600,0x3000c30,0x6600180,0x6007c0,0x6000c30,0x6600c30,
-0x7f00660,0x6600700,0x6e00600,0x3000e30,0x6600180,0xe006c0,0x6000c30,0x6600e70,
-0x3e00660,0x7e003e0,0x7c007e0,0x30007e0,0x66007e0,0x7c00660,0x7e00c30,0x66007e0,
-0x660,0x7c001c0,0x78007e0,0x30003c0,0x66007e0,0x7800660,0x3e00c30,0x66003c0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0x3c0,0x3c0,0x1800000,
-0x7c003c0,0x3c003c0,0x7e00660,0x6600c30,0xc300660,0x7e003c0,0x60003c0,0x3c00000,
-0x7e007e0,0x7e007e0,0x7e00660,0x6600c30,0xe700660,0x3e00380,0x60001c0,0x3c00000,
-0x6600660,0x6600600,0x1800660,0x6600c30,0x6600660,0xc00300,0x70000c0,0x6600000,
-0x6600660,0x6600600,0x1800660,0x6600c30,0x7e00660,0xc00300,0x30000c0,0x4200000,
-0x6600660,0x7e007c0,0x1800660,0x6600db0,0x3c007e0,0x1800300,0x18000c0,0,
-0x7e006e0,0x7c003e0,0x1800660,0x6600db0,0x3c003e0,0x1800300,0x18000c0,0,
-0x7c006e0,0x6c00060,0x1800660,0x6600db0,0x7e00060,0x3000300,0xc000c0,0,
-0x6000670,0x6e00060,0x1800660,0x7e00ff0,0x6600060,0x3000300,0xe000c0,0,
-0x60007b0,0x66007e0,0x18007e0,0x3c00ff0,0xe7007e0,0x7c00380,0x6001c0,0,
-0x60003d0,0x66003c0,0x18003c0,0x1800660,0xc3003c0,0x7e003c0,0x6003c0,0xff0,
-0,0,0,0,0,0x3c0,0x3c0,0xff0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0x3000000,0,0,0,0,0,0,0,
-0x3000000,0,0,0,0,0,0,0,
-0x1800000,0x6000000,0x600000,0,0x6000180,0x1800600,0,0,
-0x800000,0x6000000,0x600000,0,0x6000180,0x1800600,0x6000000,0,
-0x1c0,0x60003c0,0x6003c0,0x1e003c0,0x6000000,0x600,0x60007e0,0x3c003c0,
-0x3e0,0x7c007e0,0x3e007e0,0x3e007e0,0x6000380,0x38006e0,0x6000ff0,0x7e007e0,
-0x60,0x7e00600,0x7e00660,0x3000660,0x7c00180,0x18007c0,0x6000db0,0x7e00660,
-0x3e0,0x6600600,0x66006e0,0x3000660,0x7e00180,0x1800780,0x6000db0,0x6600660,
-0x660,0x6600600,0x66007c0,0x3000660,0x6600180,0x18007c0,0x6000c30,0x6600660,
-0x660,0x6600600,0x6600700,0x3e007e0,0x6600180,0x18006c0,0x6000c30,0x6600660,
-0x7e0,0x7e007e0,0x7e003e0,0x3c003e0,0x6600180,0x1800660,0x7c00c30,0x66007e0,
-0x3e0,0x7c003c0,0x3e001c0,0x3000060,0x6600180,0x1800660,0x3c00c30,0x66003c0,
-0,0,0,0x70007e0,0,0x3800000,0,0,
-0,0,0,0x60003c0,0,0x3000000,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0xc0,0x300,0,
-0,0,0,0,0,0x1c0,0x1800380,0,
-0,0,0x3000000,0,0,0x180,0x1800180,0x1ce0,
-0x3c003c0,0x1c001c0,0x3000660,0xc300c30,0xc300660,0x7e00180,0x1800180,0x3ff0,
-0x7e007e0,0x3c003c0,0x3000660,0xc300c30,0xe700660,0x7e00380,0x18001c0,0x7303ff0,
-0x6600660,0x3000300,0x3c00660,0x6600c30,0x7e00660,0xe00700,0x18000e0,0xfb03ff0,
-0x6600660,0x3000380,0x3c00660,0x6600c30,0x3c00660,0x1c00700,0x18000e0,0xdf03ff0,
-0x6600660,0x30001c0,0x3000660,0x6600db0,0x3c00660,0x3800380,0x18001c0,0xce01fe0,
-0x6600660,0x30000c0,0x3000660,0x3c00db0,0x7e007e0,0x7000180,0x1800180,0x1fe0,
-0x7e007e0,0x30003c0,0x3c007e0,0x3c00ff0,0xe7003e0,0x7e00180,0x1800180,0xfc0,
-0x7c003e0,0x3000380,0x1c003c0,0x1800660,0xc300060,0x7e001c0,0x1800380,0x300,
-0x6000060,0,0,0,0x7e0,0xc0,0x300,0,
-0x6000060,0,0,0,0x3c0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0x100,0x800100,0x800000,0,0,0,0,
-0,0x100,0x800100,0x800000,0,0,0,0,
-0,0,0,0,0x2000040,0,0x1ff81ff8,0x1ff81ff8,
-0,0x100,0x800100,0x800000,0x4000020,0,0x1c381e78,0x1c381c38,
-0,0x100,0x800100,0x800000,0x8000010,0,0x18181c78,0x18181818,
-0,0,0,0,0x8000010,0,0x19981c78,0x1b981f98,
-0,0x100,0x800100,0x800000,0x8000010,0,0x13081e78,0x1f981f98,
-0x1b66db6,0x6d800100,0x800100,0x800000,0x68000016,0x1800180,0x12081e78,0x1f181e18,
-0,0,0,0,0x8000010,0,0x10481e78,0x1e381e18,
-0x1000000,0x800100,0x8001b6,0x6d806db6,0x8000010,0x1000080,0x10c81e78,0x1c781f98,
-0x1000000,0x800100,0x800000,0,0x8000010,0x1000080,0x19981e78,0x18f81f98,
-0,0,0,0,0x8000010,0,0x18181c38,0x18181818,
-0x1000000,0x800100,0x800000,0,0x4000020,0x1000080,0x1c381c38,0x18181c38,
-0x1000000,0x800100,0x800000,0,0x2000040,0x1000080,0x1ff81ff8,0x1ff81ff8,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
+++ /dev/null
-/* Font buffer generated from source file: 'vg/src/fonts/vg_font_thin_3.png' */
-0xc3002800,0x8000020,0x8100000,0,0x3c003c18,0x100018,0,0,
-0,0,0,0,0,0,0,0,
-0x81102800,0x1c000020,0x10080010,0x2,0x20800424,0x180c18,0x30000000,0,
-0x18000000,0,0,0,0,0,0,0,
-0x102822,0x22202020,0x20040010,0x2,0x20800442,0x81018,0x8000000,0x38,
-0x24000000,0,0,0,0,0,0,0,
-0x100022,0x20525000,0x20045410,0x4,0x20400400,0x1018,0x8000000,0x8001044,
-0x440000fe,0x10380000,0,0,0,0,0,0,
-0x10007f,0x20245000,0x200438fe,0x8,0x20200400,0x2018,0x4621010,0x10000804,
-0x440000fe,0x387c0000,0,0,0,0,0,0,
-0x100022,0x1c086000,0x20043810,0x8,0x20200400,0x4018,0x2920000,0x20000404,
-0x540000fe,0x38fe0000,0,0,0,0,0,0,
-0x100022,0x2109400,0x20045410,0x3c0010,0x20100400,0x4018,0x28c0000,0x403c0208,
-0x540000fe,0x7cfe0000,0,0,0,0,0,0,
-0x22,0x2248800,0x20040010,0x20,0x20080400,0x2018,0x4000000,0x40000210,
-0x5c0000fe,0x7cfe0000,0,0,0,0,0,0,
-0x7f,0x224a9400,0x10080000,0x20,0x20080400,0x1018,0x8000010,0x203c0400,
-0xfe,0xfe7c0000,0,0,0,0,0,0,
-0x100022,0x1c046200,0x8100000,0x10002000,0x20000400,0x1018,0x8001010,0x10000810,
-0xfe,0xfe380000,0,0,0,0,0,0,
-0x22,0x8000000,0,0x20000000,0x3c003c00,0xff000c00,0x30000020,0x8001000,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0x81000000,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0xc3000000,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0x18303c70,0x7c383844,0x7c784440,0x44443c78,0x38787cfe,0x42828282,0x82fe3c10,0x3c7c407c,
-0x387c3838,0,0,0,0,0,0,0,
-0x24484048,0x40404444,0x10084840,0x44444244,0x44448210,0x42828282,0x82024630,0x42084840,
-0x44044444,0,0,0,0,0,0,0,
-0x24484044,0x40404044,0x10084840,0xaa644244,0x44448010,0x42449244,0x82044650,0x42104840,
-0x40084444,0,0,0,0,0,0,0,
-0x42484044,0x40404044,0x10085040,0xaa544244,0x44448010,0x42449228,0x82084a10,0x4204840,
-0x40084444,0,0,0,0,0,0,0,
-0x42784044,0x78705c7c,0x10086040,0xaa544278,0x54787c10,0x42449210,0x7e105a10,0x8784878,
-0x78107c3c,0,0,0,0,0,0,0,
-0x7e444044,0x40404444,0x10085040,0x924c4240,0x4c440210,0x4228aa28,0x2205210,0x10043c04,
-0x44104404,0,0,0,0,0,0,0,
-0x42444044,0x40404444,0x10084840,0x924c4240,0x44440210,0x4228aa44,0x2406210,0x20040804,
-0x44204404,0,0,0,0,0,0,0,
-0x42444048,0x40404444,0x10104840,0x92444240,0x42448210,0x4228aa82,0x82806210,0x40040844,
-0x44204444,0,0,0,0,0,0,0,
-0x42783c70,0x7c403844,0x7c60447c,0x82443c40,0x3a447c10,0x3c104482,0x7cfe3c7c,0x7e780838,
-0x38203838,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0x400004,0x40,0x4060,0,0x40,0,0x4,0x7000000,
-0,0,0,0,0,0,0,0,
-0x400004,0x380040,0x10084020,0,0x40,0,0x3008,0x73000000,
-0,0,0,0,0,0,0,0,
-0x400004,0x440040,0x4020,0,0x40,0,0x4810,0x4500606c,
-0x98000000,0,0,0,0,0,0,0,
-0x38783c3c,0x38403878,0x30384820,0x6c383838,0x38383c78,0x44428244,0x447c4810,0x4806706c,
-0xe4e00000,0,0,0,0,0,0,0,
-0x4444044,0x44404444,0x10085020,0x92444444,0x44444040,0x44429228,0x44083010,0x420c786c,
-0xe2900000,0,0,0,0,0,0,0,
-0x3c444044,0x44784444,0x10086020,0x92444444,0x44403840,0x44249210,0x4410000e,0x42d87c6c,
-0xf28e0000,0,0,0,0,0,0,0,
-0x44444044,0x78404444,0x10086020,0x82444444,0x44400440,0x44249228,0x44200000,0x7e70786c,
-0x2820000,0,0,0,0,0,0,0,
-0x44444044,0x40404444,0x10085020,0x82444464,0x44404440,0x4424aa44,0x44400000,0x20706c,
-0x44820000,0,0,0,0,0,0,0,
-0x3c783c3c,0x3c403c44,0x3808481c,0x82443858,0x3c403838,0x38184444,0x3c7c0000,0x606c,
-0x38fe0000,0,0,0,0,0,0,0,
-0,0x400400,0x80000,0x40,0x4000000,0,0x4000000,0,
-0,0,0,0,0,0,0,0,
-0,0x400400,0x300000,0x40,0x6000000,0,0x8000000,0,
-0,0,0,0,0,0,0,0,
-0,0x807800,0,0x40,0x4000000,0,0x70000000,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0x1818,0x1818,0x7c1e3c3c,0,0,0,
-0,0xdc000000,0,0,0,0,0,0,
-0xfe103882,0x82441060,0x3c002424,0x3c002424,0x82214242,0x18001800,0,0x1000,
-0xe80000,0x90000000,0,0,0,0,0,0,
-0x82284444,0x44442890,0x42000000,0x42000000,0x80010000,0x38181c7e,0x3c7c6c6c,0x6c6c2810,
-0xdca80000,0xdc6c0000,0,0,0,0,0,0,
-0x82288228,0x28284490,0x52521052,0x5a5a185a,0xaedd8868,0x783c1e7e,0x40eaae,0xee828228,
-0x88e80022,0x84aa0000,0,0,0,0,0,0,
-0x82448210,0x101044f0,0x52911091,0x52911091,0xa4898888,0x787e1e3c,0x3c5eeaae,0xee101044,
-0xc8ae0042,0xdcaa0000,0,0,0,0,0,0,
-0x82448228,0x28107c88,0x5a5a185a,0x52521052,0xb4898e8e,0x387e1c18,0x12eaae,0xee929282,
-0x429e,0xaa0000,0,0,0,0,0,0,
-0x82824444,0x44108288,0x42000000,0x42000000,0x80018a8a,0x18001800,0x3c1eeeee,0xee1000ee,
-0xd0e04240,0x70ee0000,0,0,0,0,0,0,
-0xfefe3882,0x821082f0,0x3c002424,0x3c002424,0x80016e8e,0,0x8282,0x8282aa28,
-0x90407e20,0x40820000,0,0,0,0,0,0,
-0,0,0x1818,0x1818,0,0,0,0x1038,
-0x9c400000,0x70000000,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0xe0700000,0,0,0,0,0,0,0x800000,
-0x80000000,0,0,0,0,0,0,0,
-0x8010800a,0x200,0x100,0x2008000,0,0,0x1f80001f,0x81400000,
-0xc0070040,0x38000000,0,0,0,0,0,0,
-0x8010800a,0x703,0x100,0x4004000,0,0x4,0x10040000,0x82200000,
-0x60080040,0x4000000,0,0x1e0,0,0,0,0,
-0x800a,0x1040884,0x80380100,0x8002000,0,0x8,0x10020000,0x84100000,
-0x20080040,0x4000000,0,0x210,0,0,0,0,
-0x8000,0x1041044,0x84440000,0x8002000,0x400000,0x8,0x10020000,0x80000000,
-0x80040,0x4000000,0,0x408,0,0xc03,0xf0000000,0,
-0x8000,0x1041004,0x88440000,0x10001008,0x400000,0x10,0x10010000,0x80000000,
-0x80040,0x4000000,0x200,0x80408,0x1e000000,0xffc1e07,0xf8000000,0,
-0x8000,0x7ff1003,0x10440000,0x1000102a,0x400000,0x20,0x10008000,0x80000000,
-0x100040,0x2038408,0x800400,0x40008,0x21000000,0xffc1e0f,0xfc000000,0,
-0x8000,0x1040800,0x20440000,0x1000101c,0x400000,0x20,0x10008000,0x80000000,
-0x100040,0x2044400,0x800,0x20008,0x40800000,0xffc3f0f,0xfc000000,0,
-0x8000,0x1040700,0x40780000,0x1000101c,0x7fc0001,0xf8000040,0x10004000,0x80000000,
-0x600040,0x1842400,0x1000,0x10010,0x4c800000,0xffc3f0f,0xfc000000,0,
-0x8000,0x1040080,0x80880000,0x1000102a,0x400000,0x80,0x10002000,0x80000000,
-0x100040,0x2041800,0x2001,0xf8008060,0x52800000,0xffc7f8f,0xfc000000,0,
-0x8000,0x1040041,0x18850000,0x10001008,0x400000,0x80,0x10002000,0x80000000,
-0x100040,0x2000000,0x4000,0x4080,0x52800000,0xffc7f8f,0xfc000000,0,
-0,0x1040042,0x24820000,0x10001000,0x400000,0x100,0x10001000,0x80000000,
-0x80040,0x4000000,0x2000,0x8000,0x52800000,0xffc7f8f,0xfc000000,0,
-0x80100000,0x7ff1044,0x24850000,0x8002000,0x400000,0x200,0x10000800,0x80000000,
-0x80040,0x4000000,0x1001,0xf8010000,0x52800000,0xffcffcf,0xfc000000,0,
-0x80108000,0x1040880,0x24888000,0x8002000,0xc00,0x180200,0x10000800,0x80000000,
-0x80040,0x4000000,0x800800,0x20080,0x4d000000,0xffcffc7,0xf8000000,0,
-0xe0708000,0x1040700,0x18704000,0x4004000,0x800,0x180400,0x10000400,0x80000000,
-0x80040,0x4000008,0x800400,0x40080,0,0xffcffc3,0xf0000000,0,
-0,0x1040200,0,0x2008000,0x1000,0,0x1f80001f,0x8000fff0,
-0x70000,0x38000000,0x1000200,0x80000,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0xc03e01f,0x87c07f83,0xf01f0410,0x7f07e041,0x84006304,0x81e07e0,0x1c07e01f,0x8ff84088,
-0x8808808,0x808ffc1e,0xc01e07,0xf84007f8,0x1f07f81e,0x1e00000,0,0,
-0x12041020,0x4204004,0x208410,0x8002042,0x4009486,0x8210410,0x22041020,0x40804088,
-0x8808808,0x80800421,0x1402100,0x10420400,0x20800821,0x2100000,0,0,
-0x21041040,0x4104004,0x400410,0x8002042,0x4009486,0x8408408,0x41040840,0x804084,
-0x10808410,0x80800842,0x82404080,0x20420400,0x40001040,0x84080000,0,0,
-0x21041040,0x4104004,0x400410,0x8002044,0x4009485,0x8408408,0x41040840,0x804084,
-0x10888220,0x80801042,0x80404080,0x40420400,0x40002040,0x84080000,0,0,
-0x40841040,0x4104004,0x400410,0x8002048,0x4009485,0x8408408,0x41040840,0x804084,
-0x10888140,0x80802044,0x80400080,0x80420400,0x40002021,0x4080000,0,0,
-0x4087e040,0x4104004,0x400410,0x8002070,0x4009484,0x88408410,0x49041020,0x804084,
-0x10888080,0x41804044,0x80400101,0x4207e0,0x5e00401e,0x4080000,0,0,
-0x40841040,0x4107e07,0xe04f87f0,0x8002070,0x4009484,0xc84087e0,0x4507e01f,0x804084,
-0x10888080,0x3e808048,0x80400203,0xe0220010,0x61004021,0x2180000,0,0,
-0x7f840840,0x4104004,0x408410,0x8002048,0x4008884,0x48408400,0x43041000,0x80804082,
-0x20948080,0x810048,0x80400400,0x101f8008,0x40808040,0x81e80000,0,0,
-0x40840840,0x4104004,0x408410,0x8002044,0x4008884,0x28408400,0x41040800,0x40804082,
-0x20948140,0x820050,0x80400800,0x8020008,0x40808040,0x80080000,0,0,
-0x40840840,0x4104004,0x408410,0x8002042,0x4008884,0x28408400,0x40840800,0x40804082,
-0x20948220,0x840050,0x80401000,0x8020008,0x40810040,0x80080000,0,0,
-0x40840840,0x4104004,0x408410,0x8002042,0x4008884,0x18408400,0x40040800,0x40804082,
-0x20948410,0x80880060,0x80402000,0x8020408,0x40810040,0x80080000,0,0,
-0x40841020,0x4204004,0x210410,0x8004041,0x2008084,0x18210400,0x22040840,0x80802101,
-0x40948808,0x41080021,0x404000,0x10020210,0x21010021,0x4100000,0,0,
-0x4087e01f,0x87c07f84,0x1e0410,0x7f078040,0x81f88084,0x81e0400,0x1c04083f,0x801e00,
-0x80630808,0x3e0ffc1e,0x3f87f87,0xe00201e0,0x1e01001e,0x3e00000,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0x40000,0x80000,0x400,0x40,0x6000000,0,0,0x2000000,
-0,0,0x80000,0,0,0,0,0,
-0x40000,0x80000,0x400,0x40,0x2000000,0,0,0x2000000,
-0,0,0x1001e0,0,0,0,0,0,
-0x40000,0x80001,0xe0000400,0x4002040,0x2000000,0,0,0x2000000,
-0,0xc,0x207c60,0,0,0,0,0,
-0x40000,0x80002,0x10000400,0x40,0x2000000,0,0,0x2000000,
-0,0x12,0x4060a0,0,0,0,0,0,
-0x40000,0x80004,0x8000400,0x40,0x2000000,0,0,0x2000000,
-0,0x12,0x806120,0x83803b8,0xf000000,0,0,0,
-0x3e05e01e,0x1e81e04,0x1e85c0,0xc00e042,0x2003b85,0xe01e05e0,0x1e85f03f,0x3f04084,
-0x4808410,0x4087f80c,0x806200,0x1c3c03b8,0x90877000,0,0,0,
-0x1061021,0x2182104,0x218620,0x4002044,0x2004446,0x10210610,0x21860840,0x82004084,
-0x4808410,0x40801000,0x806040,0x383e03b8,0xe0488800,0,0,0,
-0x1040840,0x84084084,0x408410,0x4002048,0x2004444,0x8408408,0x40840040,0x2004082,
-0x8888220,0x40802000,0x406044,0x703f03b8,0xe0484800,0,0,0,
-0x3d040840,0x4084087,0xe0408410,0x4002070,0x2004444,0x8408408,0x4084003e,0x2004082,
-0x8888140,0x40804000,0x3c604e,0xe03f83b8,0xf0483c00,0,0,0,
-0x43040840,0x4087f04,0x408410,0x4002050,0x2004444,0x8408408,0x40840001,0x2004081,
-0x10888080,0x40808000,0x7fc7,0xc03f83b8,0xf8480400,0,0,0,
-0x41040840,0x4084004,0x408410,0x4002048,0x2004044,0x8408408,0x40840000,0x82004081,
-0x10888140,0x40810000,0x7fc3,0x803f03b8,0x480400,0,0,0,
-0x41040840,0x84084004,0x408410,0x4002044,0x2004044,0x8408408,0x40840000,0x82004081,
-0x10948220,0x40820000,0x1,0x3e03b8,0x20480400,0,0,0,
-0x43061021,0x2182084,0x218410,0x4002042,0x1004044,0x8210610,0x21840041,0x1002100,
-0xa0a28410,0x21840000,0,0x3c03b8,0x10880400,0,0,0,
-0x3c85e01e,0x1e81f04,0x1e8410,0xe002041,0xf04044,0x81e05e0,0x1e84003e,0xf01e00,
-0x40410410,0x1e87f800,0,0x3803b8,0xf0ffc00,0,0,0,
-0,0x4,0x8000,0x2000,0,0x400,0x800000,0,
-0,0x800000,0,0,0,0,0,0,
-0,0x4,0x8000,0x4000,0,0x400,0x800000,0,
-0,0x800000,0,0,0,0,0,0,
-0,0x4,0x410000,0x18000,0,0x400,0xc00000,0,
-0,0x41000000,0,0,0,0,0,0,
-0,0x8,0x3e0000,0,0,0x400,0x800000,0,
-0,0x3e000000,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0x4,0x400000,0x40040,0,0,
-0,0,0,0,0,0,0,0,
-0xc03f,0x804804c,0xc0c07f0,0x1f00000a,0xa01f00,0xa00a0,0x3f81fc3f,0xc3fc0e00,
-0x1c0000,0,0,0,0,0,0,0,
-0xffc1e07f,0x8c0cc0ce,0x1c1e0ff8,0x20800011,0x1102080,0x110110,0x40420240,0x24021e00,
-0x1e0000,0,0,0x80000,0,0,0,0,
-0xffc1e0e1,0xc6186186,0x18330c18,0x40400000,0x4040,0,0x40420240,0x24023e00,
-0xe01f07fc,0x1f87f873,0x87387387,0x701400c0,0x1b800000,0x7,0x38000000,0,
-0xc0c330c0,0xc3303303,0x30330c18,0x48428808,0x2884642,0x68060268,0x40000200,0x7e01,
-0xf01f87fc,0x400f2,0x493cf3c8,0x8808120,0x21000000,0x9,0x24000000,0,
-0xc0c330c0,0xc1e01e03,0xf0618c38,0x48448408,0x4844844,0x84080484,0x5381ba11,0xd07e03,
-0xf81f87fc,0x400f2,0x493cf3c8,0x8808210,0x21000000,0x1040009,0x24000000,0,
-0xc0c618c0,0xc0c00c01,0xe0618ff8,0x48488208,0x8824848,0x82080882,0x51021211,0x1107e07,
-0xfc1f83f8,0x1f84fcf2,0x493cf3c0,0x80080408,0x19024e00,0x2042669,0x24000000,0,
-0xc0c618c0,0xc1e01e00,0xc0ffcffc,0x48448408,0x4844844,0x84080484,0x51021211,0xc11c3e07,
-0xfc1f01f0,0x84f2,0x493cf3c8,0x88888804,0x54400,0x4044889,0x24000000,0,
-0xc0c618c0,0xc3303300,0xc0ffcc0c,0x4e426806,0x2684842,0x88080288,0x51021211,0x41141e07,
-0xfc1e00e0,0x84f2,0x493cf3c8,0x88888804,0x1a054400,0x8f86489,0x24000000,0,
-0xc0cc0ce1,0xc6186180,0xc0c0cc0c,0x40400000,0x4040,0,0x4d02120d,0xc11c0e00,
-0x1c0000,0x1f80fcf3,0xcf3cf3c0,0x80000f3c,0x22074440,0x4400428f,0x3c000000,0,
-0xffcffc7f,0x8c0cc0c0,0xc0c0cffc,0x20800011,0x1102080,0x110110,0x40000200,0,
-0,0x80,0x48048048,0x8808120,0x22053440,0x42002c68,0x4000000,0,
-0xffcffc3f,0x8048040,0xc0c0c7f8,0x1f00000a,0xa01f00,0xa00a0,0x40000200,0,
-0,0x80,0x48048048,0x8948120,0x2180007f,0xc1000008,0x4000000,0,
-0,0,0,0x4,0x400000,0x40040,0,0,
-0,0,0,0x801e0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0xfc003f00,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0xc000,0,
-0xfc003f00,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0x1e000,0,
-0xc0000300,0xf00001ce,0,0xc0000,0,0x30000,0xc0000,0xc0000000,
-0,0,0,0,0x3ffc000,0x3ff,0xc003f000,0,
-0xc0000300,0xf00001ce,0,0xc0000,0,0x30000,0x1c0000,0xe0000000,
-0,0,0,0,0x3ffc000,0x3ff,0xc0073800,0,
-0xc0000300,0xf00001ce,0,0x3f000f,0,0x30000,0x380000,0x70000000,
-0,0,0,0x70,0x3ffc030,0x3ff,0xc00e1c00,0,
-0xc0000300,0xf00001ce,0,0x7f801f,0x80000000,0x30000,0x700000,0x38000000,
-0,0,0,0xf0,0x3800038,0x1,0xc01c0e00,0,
-0,0xf00000cc,0x38070,0xffc03f,0xc0000fc0,0x30000,0xe00000,0x1c000000,
-0,0,0,0xe0,0x380003c,0x1,0xc0380700,0,
-0,0xf00000cc,0x38070,0x1e1e039,0xc0001fc0,0x30000,0xe00000,0x1c000000,
-0,0,0,0x1c0,0x380001c,0x1,0xc0300300,0,
-0,0xf0000000,0x38070,0x3c0f039,0xc0303ff0,0,0x1c00000,0xe000000,
-0x3000,0,0,0x1c0,0x380001e,0x1,0xc0000000,0,
-0,0xf0000000,0x38070,0x3807039,0xc0703870,0,0x1c00000,0xe000000,
-0x3000,0,0,0x380,0x380000e,0x1,0xc0000000,0,
-0,0xf0000000,0x38070,0x3800039,0xc0f03870,0,0x3c00000,0xf0000c0,
-0x3000,0,0,0x380,0x380000f,0x1,0xc0000000,0,
-0,0xf0000000,0x38070,0x380003f,0xc1e03870,0,0x3800000,0x70000c0,
-0x3000,0,0,0x700,0x3800007,0x80000001,0xc0000000,0,
-0,0xf0000000,0x3fffff,0x380001f,0x83c03870,0,0x3800000,0x7000ccc,
-0x3000,0,0,0xe00,0x3800003,0xc0000001,0xc0000000,0,
-0,0xf0000000,0x3fffff,0x380000f,0x7803870,0,0x3800000,0x7000ccc,
-0x3000,0,0,0xe00,0x3800001,0xc0000001,0xc0000000,0,
-0,0xf0000000,0x3fffff,0x3c00000,0xf003870,0,0x3800000,0x70003f0,
-0x3000,0,0,0x1c00,0x3800000,0xe0000001,0xc0000000,0,
-0,0xf0000000,0x38070,0x3e00000,0x1e003ff0,0,0x3800000,0x70003f0,
-0x3000,0,0,0x1c00,0x3800000,0xe0000001,0xc0000000,0,
-0,0xf0000000,0x38070,0x1ff8000,0x3c003fc0,0,0x3800000,0x70003f0,
-0x3ffff0,0x3,0xffc00000,0x3800,0x3800000,0x70000001,0xc0000000,0,
-0,0xf0000000,0x38070,0xffc000,0x78007fc0,0,0x3800000,0x70003f0,
-0x3ffff0,0x3,0xffc00000,0x7000,0x3800000,0x38000001,0xc0000000,0,
-0,0xf0000000,0x38070,0x7fe000,0xf000f9e0,0,0x3800000,0x7000ccc,
-0x3000,0,0,0x7000,0x3800000,0x3c000001,0xc0000000,0,
-0,0x60000000,0x38070,0xf001,0xe000f0f0,0,0x3800000,0x7000ccc,
-0x3000,0,0,0xe000,0x3800000,0x1c000001,0xc0000000,0,
-0,0x60000000,0x38070,0x7003,0xc3c0e07b,0,0x3800000,0x70000c0,
-0x3000,0,0,0xe000,0x3800000,0xe000001,0xc0000000,0,
-0,0x60000000,0x38070,0x7007,0x87e0e03f,0,0x3800000,0x70000c0,
-0x3000,0,0,0x1c000,0x3800000,0xe000001,0xc0000000,0,
-0,0x60000000,0x38070,0x700f,0xff0e01f,0,0x3c00000,0xf000000,
-0x3000,0,0,0x3c000,0x3800000,0x7000001,0xc0000000,0,
-0,0,0x3fffff,0x701e,0xe70e01f,0,0x3c00000,0xf000000,
-0x3000,0,0,0x38000,0x3800000,0x3800001,0xc0000000,0,
-0xc0000300,0,0x3fffff,0x380703c,0xe70e03f,0x80000000,0x1c00000,0xe000000,
-0x3000,0,0,0x70000,0x3800000,0x1c00001,0xc0000000,0,
-0xc0000300,0,0x3fffff,0x3c0f038,0xe70e07b,0xc0000000,0x1c00000,0xe000000,
-0x3000,0,0,0x70000,0x3800000,0x1c00001,0xc0000000,0,
-0xc0000300,0x60000000,0x38070,0x1e1f030,0xe70f0f1,0xe0000000,0xe00000,0x1c000000,
-0,0xf00000,0x180,0xe0000,0x3800000,0xe00001,0xc0000000,0,
-0xc0000300,0xf0000000,0x38070,0xffe000,0xff07fe0,0xf0000000,0xe00000,0x1c000000,
-0,0xf00000,0x3c0,0xe0000,0x3800000,0xe00001,0xc0000000,0,
-0xfc003f00,0xf0000000,0x38070,0x7fc000,0x7e07fc0,0x70000000,0x700000,0x38000000,
-0,0xe00000,0x3c0,0x1c0000,0x3800000,0x700001,0xc0000000,0,
-0xfc003f00,0x60000000,0x38070,0x3f8000,0x3c01f00,0x30000000,0x380000,0x70000000,
-0,0x1c00000,0x180,0x1c0000,0x3ffc000,0x3003ff,0xc0000000,0,
-0,0,0x38070,0xc0000,0,0,0x1c0000,0xe0000000,
-0,0x3800000,0,0,0x3ffc000,0x3ff,0xc0000000,0xffffff00,
-0,0,0x38070,0xc0000,0,0,0xc0000,0xc0000000,
-0,0x3000000,0,0,0x3ffc000,0x3ff,0xc0000000,0xffffff00,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0xc00000,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0xe00000,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0xf00000,0x3f000070,0xfc000,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0xf80000,0x7f000070,0xfe000,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0x7c0000,0xff000070,0xff000,0,0,0,0,0x3fc,
-0,0,0,0,0,0,0,0,
-0x1c0000,0xf0000070,0xf000,0,0,0,0,0x7fe,
-0,0,0,0,0,0,0,0,
-0xc0000,0xe0000070,0x7000,0,0,0,0,0xfff,
-0,0,0,0,0,0x30000030,0,0,
-0,0xe0000070,0x7000,0,0,0,0,0x1e07,
-0x80000000,0,0,0,0,0x78000078,0,0,
-0,0xe0000070,0x7800,0,0,0,0,0x3c03,
-0xc0000000,0,0,0xf000,0x3fc0000,0xfc0000fc,0x3ff00,0,
-0x1,0xe0000070,0x7800,0,0,0,0,0x3801,
-0xc0000000,0,0,0x1f800,0xfff0001,0xce0001ce,0x7ff80,0,
-0x1,0xe0000070,0x7800,0,0,0xc00,0,0xc0003801,
-0xc003fc00,0,0xffff,0xf003fc00,0x1fff8003,0x87000387,0xe01c0,0,
-0x1,0xc0000070,0x3800,0,0,0x1c00,0,0xe0003801,
-0xc007fe00,0,0xffff,0xf003fc00,0x3fffc003,0x3000303,0x1c00e0,0,
-0x3,0xc0000070,0x3c00,0xfc07000,0xc00000c0,0x3800,0,0x70000001,
-0xc00e0700,0,0xffff,0xf007fe00,0x7fffe000,0,0x380070,0,
-0x3,0x80000070,0x1c00,0x1fe07001,0xe00001e0,0x7000,0,0x38000001,
-0xc01c0380,0,0xffff,0xf007fe00,0x7fffe000,0,0x300030,0,
-0x7,0x80000070,0x1e00,0x3ff07001,0xe00001e0,0xe000,0,0x1c000001,
-0xc03801c0,0,0xffff,0xf00fff00,0xfffff000,0xc0000cc0,0xc0303c30,0xc3cc000,
-0x3f,0x80000070,0x1fc0,0x38787000,0xc00000c0,0x1c000,0,0xe000003,
-0xc03000c0,0,0xffff,0xf00fff00,0xfffff000,0xc0001cc0,0xe0307c30,0x1c7ce000,
-0x3e,0x70,0x7c0,0x383c7000,0,0x38000,0,0x7000007,
-0x8030f0c0,0,0xffff,0xf01fff80,0xfffff000,0xc00038c0,0x7030e030,0x38e07000,
-0x3e,0x70,0x7c0,0x381ff000,0,0x70000,0,0x380007f,
-0x31f8c0,0,0xffff,0xf01fff80,0xfffff000,0xc00070c0,0x3830c030,0x70c03800,
-0x7,0x80000070,0x1e00,0x380fe000,0,0xe0000,0x3ffc000,0x1c000fe,
-0x339cc0,0,0xffff,0xf03fffc0,0xfffff000,0xc000e0c0,0x1c30c030,0xe0c01c00,
-0x3,0x80000070,0x1c00,0x3807c000,0,0x1c0000,0x3ffc000,0xe001fc,
-0x330cc0,0,0xffff,0xf03fffc0,0xfffff000,0xc000e0c0,0x1c30c030,0xe0c01c00,
-0x3,0x80000070,0x1c00,0,0,0x380000,0,0x7001e0,
-0x330cc0,0,0xffff,0xf03fffc0,0xfffff000,0xc00070c0,0x3830c030,0x70c03800,
-0x3,0xc0000070,0x3c00,0,0,0x380000,0,0x7001e0,
-0x330cc0,0,0xffff,0xf07fffe0,0xfffff000,0xe00038e0,0x7030c030,0x38c07000,
-0x1,0xc0000070,0x3800,0,0,0x1c0000,0,0xe000c0,
-0x330cc0,0,0xffff,0xf07fffe0,0xfffff000,0x7c001c7c,0xe030c030,0x1cc0e000,
-0x1,0xe0000070,0x7800,0,0,0xe0000,0,0x1c00000,
-0x330cc0,0,0xffff,0xf07fffe0,0xfffff000,0x3c000c3c,0xc030c030,0xcc0c000,
-0x1,0xe0000070,0x7800,0,0,0x70000,0x3ffc000,0x3800000,
-0x330cc0,0,0xffff,0xf0fffff0,0x7fffe000,0,0x300030,0,
-0,0xe0000070,0x7800,0,0,0x38000,0x3ffc000,0x7000000,
-0x339cc0,0,0xffff,0xf0fffff0,0x7fffe000,0,0x380070,0,
-0,0xe0000070,0x7000,0,0xc00001e0,0x1c000,0,0xe0000c0,
-0x31ff80,0,0xffff,0xf0fffff0,0x3fffc003,0x3000303,0x1c00e0,0,
-0,0xe0000070,0x7000,0x1,0xe00001e0,0xe000,0,0x1c0001e0,
-0x30f300,0,0xffff,0xf0fffff0,0x1fff8003,0x87000387,0xe01c0,0,
-0,0xf0000070,0xf000,0x1,0xe00001c0,0x7000,0,0x380001e0,
-0,0,0xffff,0xf0fffff0,0xfff0001,0xce0001ce,0x7ff80,0,
-0,0xff000070,0xff000,0,0xc0000380,0x3800,0,0x700000c0,
-0,0,0xffff,0xf0fffff0,0x3fc0000,0xfc0000fc,0x3ff00,0,
-0,0x7f000000,0xfe000,0,0x700,0x1c00,0,0xe0000000,
-0,0,0,0,0,0x78000078,0,0,
-0,0x3f000000,0xfc000,0,0x600,0xc00,0,0xc0000000,
-0,0,0,0,0,0x30000030,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0x1f0003f,0xfe001fff,0x3ffe00,0x1fff001f,0xff001ffe,0x3c0780,0xfff0000,0x38003c0f,
-0x801c0000,0xf003c038,0x3803ffe,0x3ffe00,0x3ffe003f,0xfc001ffe,0x7fff00,0x3c1f0000,
-0x1f8003f,0xff803fff,0x3fff00,0x3fff003f,0xff003ffe,0x3e0780,0xfff0000,0x3c003c0f,
-0x803c0000,0xf807c03c,0x7803fff,0x3fff00,0x3fff003f,0xfe003ffe,0x7fff00,0x3e1f0000,
-0x1fc003f,0xff803fff,0x3fff00,0x3fff003f,0xff003ffe,0x3e0780,0xfff0000,0x3c003c1f,
-0x3c0000,0xf807c03e,0x7803fff,0x3fff00,0x3fff003f,0xff003ffe,0x7fff00,0x3e1f0000,
-0x1fc003f,0xff803fff,0x3fff00,0x3fff003f,0xff003ffe,0x3e0780,0xffe0000,0x3c003c1f,
-0x3c0000,0xfc0fc03e,0x7803fff,0x3fff00,0x3fff003f,0xff003ffe,0x7ffe00,0x3e1f0000,
-0x3fc003c,0xf803c00,0x3c0f00,0x3c00003e,0x3c00,0x3e0780,0xf00000,0x3c003c3e,
-0x3c0000,0xfc0fc03e,0x7803c0f,0x3c1f00,0x3c0f003c,0x1f003e1e,0x1e000,0x3e1f0000,
-0x3fc003c,0x7803c00,0x3c0f00,0x3c00003e,0x3c00,0x3e0780,0xf00000,0x3c003c3e,
-0x3c0000,0xfc0fc03f,0x7803c0f,0x3c0f00,0x3c0f003c,0x1f003e1e,0x1e000,0x3e1f0000,
-0x3fc003c,0x7803c00,0x3c0f00,0x3c00003e,0x3c00,0x3e0780,0xf00000,0x3c003c3c,
-0x3c0000,0xfe1fc03f,0x7803c0f,0x3c0f00,0x3c0f003c,0x1f003e1e,0x1e000,0x3e1f0000,
-0x3fe003c,0x7803c00,0x3c0f00,0x3c00003e,0x3c00,0x3e0780,0xf00000,0x3c003c7c,
-0x3c0000,0xfe1fc03f,0x87803c0f,0x3c0f00,0x3c0f003c,0x1f003e00,0x1e000,0x3e1f0000,
-0x3fe003c,0x7803c00,0x3c0f00,0x3c00003e,0x3c00,0x3e0780,0xf00000,0x3c003c78,
-0x3c0000,0xff3fc03f,0x87803c0f,0x3c0f00,0x3c0f003c,0x1f003e00,0x1e000,0x3e1f0000,
-0x7de003c,0xf803c00,0x3c0f00,0x3c00003e,0x3c00,0x3e0780,0xf00000,0x3c003cf8,
-0x3c0000,0xff3fc03f,0x87803c0f,0x3c0f00,0x3c0f003c,0x1f003e00,0x1e000,0x3e1f0000,
-0x79e003c,0x1f803c00,0x3c0f00,0x3c00003e,0x3c00,0x3e0780,0xf00000,0x3c003cf0,
-0x3c0000,0xffffc03f,0xc7803c0f,0x3c0f00,0x3c0f003c,0x1f003e00,0x1e000,0x3e1f0000,
-0x79e003f,0xff003c00,0x3c0f00,0x3c00003e,0x3c00,0x3fff80,0xf00000,0x3c003cf0,
-0x3c0000,0xffffc03f,0xc7803c0f,0x3c0f00,0x3c0f003c,0x1f003e00,0x1e000,0x3e1f0000,
-0x79f003f,0xfe003c00,0x3c0f00,0x3ffc003e,0x3c00,0x3fff80,0xf00000,0x3c003df0,
-0x3c0000,0xf7f7c03f,0xc7803c0f,0x3e1f00,0x3c0f003e,0x1f003ffc,0x1e000,0x3e1f0000,
-0x79f003f,0xff003c00,0x3c0f00,0x3ffc003f,0xf0003c00,0x3fff80,0xf00000,0x3c003de0,
-0x3c0000,0xf7f7c03f,0xe7803c0f,0x3fff00,0x3c0f003f,0xfe003ffe,0x1e000,0x3e1f0000,
-0xf8f003f,0xff803c00,0x3c0f00,0x3ffc003f,0xf0003c00,0x3fff80,0xf00000,0x3c003fe0,
-0x3c0000,0xf7f7c03d,0xe7803c0f,0x3fff00,0x3c0f003f,0xfe003ffe,0x1e000,0x3e1f0000,
-0xf0f003c,0xf803c00,0x3c0f00,0x3ffc003f,0xf0003c1e,0x3e0780,0xf00000,0x3c003de0,
-0x3c0000,0xf3e7c03d,0xf7803c0f,0x3fff00,0x3c0f003f,0xfc001ffe,0x1e000,0x3e1f0000,
-0xfef003c,0x7803c00,0x3c0f00,0x3ffc003f,0xf0003c1e,0x3e0780,0xf00000,0x3c003df0,
-0x3c0000,0xf3e7c03d,0xf7803c0f,0x3fff00,0x3c0f003f,0xfe00001e,0x1e000,0x3e1f0000,
-0xfef003c,0x7803c00,0x3c0f00,0x3c00003e,0x3c1e,0x3e0780,0xf00000,0x3c003cf0,
-0x3c0000,0xf3e7c03c,0xf7803c0f,0x3c0000,0x3c0f003c,0x3f00001e,0x1e000,0x3e1f0000,
-0xfcf803c,0x7803c00,0x3c0f00,0x3c00003e,0x3c1e,0x3e0780,0xf00000,0x3c003cf8,
-0x3c0000,0xf1c7c03c,0xff803c0f,0x3c0000,0x3c0f003c,0x1f00001e,0x1e000,0x3e1f0000,
-0x1f8f803c,0x7803c00,0x3c0f00,0x3c00003e,0x3c1e,0x3e0780,0xf00000,0x3c003cf8,
-0x3c0000,0xf1c7c03c,0xff803c0f,0x3c0000,0x3c0f003c,0x1f00001e,0x1e000,0x3e1f0000,
-0x1f87803c,0x7803c00,0x3c0f00,0x3c00003e,0x3c1e,0x3e0780,0xf00000,0x3c003c78,
-0x3c0000,0xf1c7c03c,0x7f803c0f,0x3c0000,0x3c0f003c,0x1f00001e,0x1e000,0x3e1f0000,
-0x1f87803c,0x7803c00,0x3c0f00,0x3c00003e,0x3c1e,0x3e0780,0xf00000,0x3c003c7c,
-0x3c0000,0xf087c03c,0x7f803c0f,0x3c0000,0x3c0f003c,0x1f00001e,0x1e000,0x3e1f0000,
-0x1f07803c,0x7803c00,0x3c0f00,0x3c00003e,0x3c1e,0x3e0780,0xf00000,0x3c003c3c,
-0x3c0000,0xf007c03c,0x3f803c0f,0x3c0000,0x3c0f003c,0x1f003e1e,0x1e000,0x3e1f0000,
-0x1f07c03c,0x7803c00,0x3c0f00,0x3c00003e,0x3c1e,0x3e0780,0xf00000,0x3c003c3e,
-0x3c0000,0xf007c03c,0x3f803c0f,0x3c0000,0x3c0f003c,0x1f003e1e,0x1e000,0x3e1f0000,
-0x3e07c03c,0xf803e00,0x3c0f00,0x3e00003e,0x3e1e,0x3e0780,0xf00000,0x7c003c3e,
-0x3e0000,0xf007c03c,0x3f803e0f,0x3c0000,0x3e0f003c,0x1f003e3e,0x1e000,0x3e1f0000,
-0x3e07c03f,0xff803fff,0x3fff00,0x3fff003e,0x3ffe,0x3e0780,0x7ff0007,0xfc003c1f,
-0x3ffe00,0xf007c03c,0x1f803fff,0x3c0000,0x3fff003c,0x1f003ffe,0x1e000,0x3fff0000,
-0x3e03c03f,0xff803fff,0x3fff00,0x3fff003e,0x3ffe,0x3e0780,0xfff0007,0xfc003c1f,
-0x3ffe00,0xf007c03c,0x1f803fff,0x3c0000,0x3fff003c,0x1f003ffe,0x1e000,0x3fff0000,
-0x3c03c03f,0xff803fff,0x3fff00,0x3fff003e,0x3ffe,0x3e0780,0xfff0007,0xfc003c0f,
-0x3ffe00,0xf007c03c,0x1f803fff,0x3c0000,0x3fff003c,0x1f003ffe,0x1e000,0x3fff0000,
-0x3c03e03f,0xff001fff,0x3ffe00,0x1fff003e,0x1ffe,0x3e0780,0xfff0007,0xf8003c0f,
-0x803ffe00,0xf007c03c,0xf801fff,0x3c0000,0x1fff003c,0x1f003ffc,0x1e000,0x3ffe0000,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0x3c0000,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0x3c0000,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0x3c0000,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0x1f8003f,0xfe001fff,0x3ffe00,0x1fff001f,0xff001ffe,0x3c0780,0xfff0000,0x38003c0f,
-0x801c0000,0xf003c038,0x3803ffe,0x3ffe00,0x3ffe003f,0xfc001ffe,0x7fff00,0x3c1f0000,
-0x1fc003f,0xff803fff,0x3fff00,0x3fff003f,0xff003ffe,0x3e0780,0xfff0000,0x3c003c0f,
-0x803c0000,0xf807c03c,0x7803fff,0x3fff00,0x3fff003f,0xfe003ffe,0x7fff00,0x3e1f0000,
-0x1fc003f,0xff803fff,0x3fff00,0x3fff003f,0xff003ffe,0x3e0780,0xfff0000,0x3c003c1f,
-0x3c0000,0xfc0fc03e,0x7803fff,0x3fff00,0x3fff003f,0xff003ffe,0x7fff00,0x3e1f0000,
-0x3fc003f,0xff803fff,0x3fff00,0x3fff003f,0xff003ffe,0x3e0780,0xffe0000,0x3c003c1f,
-0x3c0000,0xfc0fc03e,0x7803fff,0x3fff00,0x3fff003f,0xff003ffe,0x7ffe00,0x3e1f0000,
-0x3fc003c,0xf803c00,0x3c0f00,0x3c00003e,0x3c00,0x3e0780,0xf00000,0x3c003c3e,
-0x3c0000,0xfc0fc03f,0x7803c0f,0x3c1f00,0x3c0f003c,0x1f003e1e,0x1e000,0x3e1f0000,
-0x3fe003c,0x7803c00,0x3c0f00,0x3c00003e,0x3c00,0x3e0780,0xf00000,0x3c003c3c,
-0x3c0000,0xfe1fc03f,0x7803c0f,0x3c0f00,0x3c0f003c,0x1f003e1e,0x1e000,0x3e1f0000,
-0x3fe003c,0x7803c00,0x3c0f00,0x3c00003e,0x3c00,0x3e0780,0xf00000,0x3c003c7c,
-0x3c0000,0xff3fc03f,0x87803c0f,0x3c0f00,0x3c0f003c,0x1f003e00,0x1e000,0x3e1f0000,
-0x7de003c,0x7803c00,0x3c0f00,0x3c00003e,0x3c00,0x3e0780,0xf00000,0x3c003c78,
-0x3c0000,0xff3fc03f,0x87803c0f,0x3c0f00,0x3c0f003c,0x1f003e00,0x1e000,0x3e1f0000,
-0x79e003c,0xf803c00,0x3c0f00,0x3c00003e,0x3c00,0x3e0780,0xf00000,0x3c003cf8,
-0x3c0000,0xffffc03f,0xc7803c0f,0x3c0f00,0x3c0f003c,0x1f003e00,0x1e000,0x3e1f0000,
-0x79f003f,0xff003c00,0x3c0f00,0x3ffc003f,0xf0003c00,0x3fff80,0xf00000,0x3c003cf0,
-0x3c0000,0xffffc03f,0xc7803c0f,0x3fff00,0x3c0f003c,0x1f003ffe,0x1e000,0x3e1f0000,
-0x79f003f,0xff003c00,0x3c0f00,0x3ffc003f,0xf0003c00,0x3fff80,0xf00000,0x3c003df0,
-0x3c0000,0xf7f7c03f,0xe7803c0f,0x3fff00,0x3c0f003f,0xfe003ffe,0x1e000,0x3e1f0000,
-0xf8f003f,0xff803c00,0x3c0f00,0x3ffc003f,0xf0003c00,0x3fff80,0xf00000,0x3c003fe0,
-0x3c0000,0xf7f7c03d,0xe7803c0f,0x3fff00,0x3c0f003f,0xfe003ffe,0x1e000,0x3e1f0000,
-0xf0f003f,0xff803c00,0x3c0f00,0x3ffc003f,0xf0003c1e,0x3fff80,0xf00000,0x3c003ff0,
-0x3c0000,0xf3e7c03d,0xf7803c0f,0x3fff00,0x3c0f003f,0xfc001ffe,0x1e000,0x3e1f0000,
-0xfef803c,0xf803c00,0x3c0f00,0x3c00003e,0x3c1e,0x3e0780,0xf00000,0x3c003df0,
-0x3c0000,0xf3e7c03c,0xf7803c0f,0x3c0000,0x3c0f003f,0xfe00001e,0x1e000,0x3e1f0000,
-0xfcf803c,0x7803c00,0x3c0f00,0x3c00003e,0x3c1e,0x3e0780,0xf00000,0x3c003cf8,
-0x3c0000,0xf1c7c03c,0xff803c0f,0x3c0000,0x3c0f003c,0x3f00001e,0x1e000,0x3e1f0000,
-0x1f8f803c,0x7803c00,0x3c0f00,0x3c00003e,0x3c1e,0x3e0780,0xf00000,0x3c003cf8,
-0x3c0000,0xf1c7c03c,0xff803c0f,0x3c0000,0x3c0f003c,0x1f00001e,0x1e000,0x3e1f0000,
-0x1f87803c,0x7803c00,0x3c0f00,0x3c00003e,0x3c1e,0x3e0780,0xf00000,0x3c003c7c,
-0x3c0000,0xf1c7c03c,0x7f803c0f,0x3c0000,0x3c0f003c,0x1f00001e,0x1e000,0x3e1f0000,
-0x1f07c03c,0x7803c00,0x3c0f00,0x3c00003e,0x3c1e,0x3e0780,0xf00000,0x3c003c7c,
-0x3c0000,0xf007c03c,0x3f803c0f,0x3c0000,0x3c0f003c,0x1f003e1e,0x1e000,0x3e1f0000,
-0x1f07c03c,0xf803e00,0x3c0f00,0x3e00003e,0x3e1e,0x3e0780,0xf00000,0x3c003c3e,
-0x3e0000,0xf007c03c,0x3f803e0f,0x3c0000,0x3e0f003c,0x1f003e3e,0x1e000,0x3e1f0000,
-0x3e07c03f,0xff803fff,0x3fff00,0x3fff003e,0x3ffe,0x3e0780,0x7ff0000,0x7c003c3f,
-0x3ffe00,0xf007c03c,0x3f803fff,0x3c0000,0x3fff003c,0x1f003ffe,0x1e000,0x3fff0000,
-0x3e07e03f,0xff803fff,0x3fff00,0x3fff003e,0x3ffe,0x3e0780,0xfff0007,0xfc003c1f,
-0x3ffe00,0xf007c03c,0x1f803fff,0x3c0000,0x3fff003c,0x1f003ffe,0x1e000,0x3fff0000,
-0x3c03e03f,0xff803fff,0x3fff00,0x3fff003e,0x3ffe,0x3e0780,0xfff0007,0xfc003c1f,
-0x803ffe00,0xf007c03c,0x1f803fff,0x3c0000,0x3fff003c,0x1f003ffe,0x1e000,0x3fff0000,
-0x3c03e03f,0xff001fff,0x3ffe00,0x1fff003e,0x1ffe,0x3e0780,0xfff0007,0xf8003c0f,
-0x803ffe00,0xf007c03c,0xf801fff,0x3c0000,0x1fff003c,0x1f003ffc,0x1e000,0x3ffe0000,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0x3c0000,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0x3c0000,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0x3c0000,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0x3c03e07c,0x7c07c07,0xc03c03c0,0x1fff803f,0xfc0007f0,0xffc00,0x3ff00003,0xe0003ffc,
-0x1ffe00,0x3ff8001f,0xfc000ffe,0,0,0,0,0,
-0x3c03e07c,0x7c07c07,0xc03e07c0,0x1fff803f,0xfe0007f8,0x1ffe00,0x3ff80003,0xc0003ffc,
-0x3ffe00,0x3ffc003f,0xfe001fff,0,0,0,0,0,
-0x3c03e07c,0x7c07c07,0xc03e07c0,0x1fff803f,0xfe0007f8,0x1ffe00,0x3ff80003,0xc0003ffc,
-0x3ffe00,0x3ffc003f,0xfe001fff,0,0,0,0,0,
-0x3c03e07c,0x7c03e0f,0x801f0f80,0x1fff803f,0xfe0007f8,0x1ffe00,0x3ff80003,0xc0003ffc,
-0x3ffe00,0x3ffc003f,0xfe001fff,0,0,0,0,0,
-0x3e03e07c,0x7c03e0f,0x801f0f80,0xfff803c,0x1e0007f8,0x1e3e00,0xf80003,0xc0003c00,
-0x3c0000,0x78003c,0x1e001e0f,0x3000,0x300000,0,0,0,
-0x1e03c07c,0x7c01f1f,0xf0f00,0xf003c,0x1e0000f8,0x1e3e00,0x780007,0xc0003c00,
-0x3c0000,0x78003c,0x1e001e0f,0x7800,0x780000,0,0,0,
-0x1e07c07c,0x7c01f1f,0xf9f00,0x1f003c,0x1e0000f8,0x1e7e00,0x780007,0xc0003c00,
-0x3c0000,0x78003c,0x1e001e0f,0xfc00,0xfc000f,0xffc003ff,0xf00ffff0,0xffff000,
-0x1e07c07c,0x7800fbe,0xf9f00,0x1f003c,0x1e0000f8,0x7c00,0x780007,0x80003c00,
-0x3c0000,0xf8003c,0x1e001e0f,0x1ce00,0x1ce001f,0xffe007ff,0xf81ffff8,0x1ffff800,
-0x1f07c07c,0x7800fbe,0x79e00,0x3e003c,0x1e0000f8,0x7c00,0x780007,0x80003c00,
-0x3c0000,0xf0003c,0x1e001e0f,0x38700,0x3870038,0x700e00,0x1c38001c,0x38001c00,
-0xf07803c,0x7800ffe,0x7fe00,0x3e003c,0x1e0000f8,0xfc00,0x780007,0x80003c00,
-0x3c0000,0xf0003c,0x1e001e0f,0x30300,0x3030030,0x300c00,0xc30000c,0x30000c00,
-0xf07803e,0x4f8007fc,0x7fe00,0x7c003c,0x1e0000f8,0xf800,0xff80007,0x80003ff8,
-0x3c0000,0xf0003f,0xfe001e0f,0,0x30,0x300c00,0xc30000c,0x30000c00,
-0xf0f803e,0x4f8007fc,0x3fc00,0x7c003c,0x1e0000f8,0x1f800,0xff8000f,0x80003ffc,
-0x3c0000,0xf0001f,0xfc001e0f,0,0x30,0x300c00,0xc30000c,0x30000c00,
-0xf0f003e,0x4f8007fc,0x3fc00,0xf8003c,0x1e0000f8,0x1f000,0xff0000f,0x80003ffc,
-0x3ffc00,0x1e0001f,0xfc001fff,0x3c00,0xc3cc030,0,0xc000000,0,
-0xf8f003e,0xef8003f8,0x1f800,0xf8003c,0x1e0000f8,0x1f000,0xff8000f,0x3ffc,
-0x3ffe00,0x1e0003f,0xfe001fff,0x7c00,0x1c7ce030,0,0xc000000,0,
-0x78f003e,0xef8003f8,0x1f800,0x1f0003c,0x1e0000f8,0x3f000,0xff8000f,0x3c,
-0x3ffe00,0x1e0003c,0x1e001fff,0xe000,0x38e07033,0xfc003cf,0xcc030300,0xf30000,
-0x78f003e,0xef0003f8,0xf000,0x1f0003c,0x1e0000f8,0x3e000,0x78000f,0x3c,
-0x3ffe00,0x1e0003c,0x1e000fff,0xc000,0x70c03833,0xfc007cf,0xcc030300,0x1f30000,
-0x78f003e,0xef0003f8,0xf000,0x3e0003c,0x1e0000f8,0x7e000,0x78000f,0x3c,
-0x3c1e00,0x3e0003c,0x1e00000f,0xc000,0xe0c01c33,0x3000e03,0xc030300,0x3830000,
-0x79e001f,0xff0007fc,0xf000,0x3e0003c,0x1e0000f8,0x7e000,0x78001f,0x3c,
-0x3c1e00,0x3c0003c,0x1e00000f,0xc000,0xe0c01c33,0x3000c03,0xc030300,0x3030000,
-0x7de001f,0xff0007fc,0xf000,0x3c0003c,0x1e0000f8,0x7c000,0x78001f,0x3c,
-0x3c1e00,0x3c0003c,0x1e00000f,0xc000,0x70c03833,0x3000c03,0xc0303e0,0x303e000,
-0x3de001f,0xff000ffc,0xf000,0x7c0003c,0x1e0000f8,0xfc000,0x78001e,0x3c,
-0x3c1e00,0x3c0003c,0x1e00000f,0xc000,0x38c07033,0x3000c03,0xc0303f0,0x303f000,
-0x3de001f,0xff000fbe,0xf000,0x780003c,0x1e0000f8,0xf8000,0x78001e,0x3c,
-0x3c1e00,0x3c0003c,0x1e00000f,0xc000,0x1cc0e033,0x3000c03,0xc030330,0x3033000,
-0x3de001f,0xff000fbe,0xf000,0xf80003c,0x1e0000f8,0x1f8000,0x78001e,0x3c00003c,
-0x3c1e00,0x780003c,0x1e00000f,0xc000,0xcc0c033,0x83000c03,0xc038330,0x3033000,
-0x3fc001f,0xff001f1f,0xf000,0xf80003c,0x1e0000f8,0x1f8000,0x78001e,0x3e00003c,
-0x3c1e00,0x780003c,0x1e00000f,0,0x31,0xf3000c03,0xc01f3f0,0x303f000,
-0x3fc001f,0xbe001f1f,0xf000,0x1f00003c,0x1e0000f8,0x1f0000,0x78001e,0x3e00003c,
-0x3c1e00,0x780003c,0x1e00000f,0,0x30,0xf3000c03,0xc00f1e0,0x301e000,
-0x1fc001f,0xbe003e0f,0x8000f000,0x1fff003c,0x1e0000f8,0x3f0000,0xf8003e,0x3e00003c,
-0x3c1e00,0x780003c,0x1e00000f,0x30300,0x3030030,0,0xc000000,0,
-0x1fc000f,0xbe003e0f,0x8000f000,0x1fff803f,0xfe0007ff,0x3fff00,0x3ff8003f,0xfe003ffc,
-0x3ffe00,0xf00003f,0xfe000fff,0x38700,0x3870030,0,0xc000000,0,
-0x1fc000f,0x1e003c07,0x8000f000,0x1fff803f,0xfe0007ff,0x3fff00,0x3ff8003f,0xfe003ffc,
-0x3ffe00,0xf00003f,0xfe001fff,0x1ce00,0x1ce0030,0,0xc000000,0,
-0x1f8000f,0x1e007c07,0xc000f000,0x1fff803f,0xfe0007ff,0x3fff00,0x3ff8003f,0xfe003ffc,
-0x3ffe00,0xf00003f,0xfe001fff,0xfc00,0xfc0030,0,0xc000000,0,
-0x1f8000e,0x1e007c07,0xc000f000,0x1fff803f,0xfe0007ff,0x3fff00,0x3ff0003f,0xfe003ffc,
-0x3ffe00,0xf00001f,0xfc001ffe,0x7800,0x780000,0,0,0,
-0,0,0,0,0,0,0,0x3e000000,
-0,0,0,0x3000,0x300000,0,0,0,
-0,0,0,0,0,0,0,0x3e000000,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0x3c01e07c,0x7c07c07,0xc03c03c0,0x3fff0000,0xf0,0xfff00,0xc00030c0,0x30f000,
-0xf000f000,0x3fff0003,0xff000000,0xfc00,0x3,0xf0000000,0,0,
-0x3c01e07c,0x7c07c07,0xc03c03c0,0x3fff0000,0x1f8,0x1fff80,0xe00070e0,0x70f801,
-0xf001f800,0x7fff8007,0xff800000,0x1fc00,0x3,0xf8000000,0,0,
-0x3c01e07c,0x7c07c07,0xc03e07c0,0x3fff00ff,0xfff003fc,0x3fffc0,0xf000f0f0,0xf0f801,
-0xf003fc00,0xffffc00e,0x1c00000,0x3fc00,0x3,0xfc000000,0,0,
-0x3c01e07c,0x7c07e0f,0xc03e07c0,0x3fff00ff,0xfff003fc,0x7fffe0,0xf801f0f8,0x1f0fc03,
-0xf007fe00,0xffffc01c,0xe00000,0x7fc00,0x3,0xfe000000,0,0,
-0x3c01e07c,0x7c03e0f,0x801f0f80,0x1f00ff,0xfff007fe,0xfc03f0,0x7c03e07c,0x3e07c03,
-0xe00fff00,0xf00fc038,0x700000,0xffc00,0xfc0003,0xff003fff,0xf003ffc0,0x3fffc000,
-0x3e03e07c,0x7c03f1f,0x801f0f80,0x1f00ff,0xfff007fe,0xf801f0,0x3e07c03e,0x7c03e07,
-0xc00f9f00,0xf007c030,0x300000,0x1ffc00,0x1fe0003,0xff803fff,0xf003ffc0,0x3fffc000,
-0x1e03c07c,0x7c01f1f,0xf0f00,0x3e00f0,0xf00f9f,0xf000f0,0x1f0f801f,0xf801f0f,
-0x801f0f80,0xf003c030,0xc0300cc0,0xc03ffc00,0x3ff0003,0xffc03fff,0xf0000000,0x30000000,
-0x1e03c07c,0x7c00fbe,0xf9f00,0x3e00f0,0xf00f0f,0xf000f0,0xf9f000f,0x9f000f9f,
-0x1f0f80,0xf003c030,0xc0301cc0,0xe03ffc00,0x7ff8003,0xffc03fff,0xf0000000,0x30000000,
-0x1f07c07c,0x7c00fbe,0x79e00,0x7c00f0,0xf01f0f,0x80f000f0,0x7fe0007,0xfe0007fe,
-0x3e07c0,0xf007c030,0xc03038c0,0x703ffc00,0xfffc003,0xffc03fff,0xf0000000,0x30000000,
-0xf07803c,0x78007fc,0x7fe00,0x7c00f0,0xf01f0f,0x80f000f0,0x3fc0003,0xfc0003fc,
-0x3e07c0,0xf00fc030,0xc03070c0,0x383ffc00,0x1fffe003,0xffc03fff,0xf0000000,0x30000000,
-0xf07803e,0x4f8007fc,0x3fc00,0xf800f0,0xf03e07,0xc0f000f0,0x1f80001,0xf80001f8,
-0x7c03e0,0xffff8030,0xc030e0c0,0x1c3ffc00,0x3ffff003,0xffc01fff,0xe003ffc0,0x30fff000,
-0xf07803e,0x4f8003f8,0x3fc00,0x1f000f0,0xf03e07,0xc0f000f0,0x1f80001,0xf80000f0,
-0x7c03e0,0xffff8030,0xc030e0c0,0x1c3ffc00,0x3ffff003,0xffc00fff,0xc003ffc0,0x30fff000,
-0xf8f803e,0x4f8003f8,0x1f800,0x1f000f0,0xf03e07,0xc0f000f0,0x3fc0003,0xfc0000f0,
-0xfffff0,0xffffe030,0xc03070c0,0x381ffc00,0x3ffff003,0xff8007ff,0x80000000,0xc03000,
-0x78f003e,0xef8003f8,0x1f800,0x3e000f0,0xf07c03,0xe0f000f0,0x7fe0007,0xfe0000f0,
-0xfffff0,0xfffff030,0xc03038e0,0x700ffc00,0x3ffff003,0xff0003ff,0,0xc03000,
-0x78f003e,0xef0007fc,0xf000,0x7c000f0,0xf07c03,0xe0f000f0,0xf9f000f,0x9f0000f0,
-0xfffff0,0xf001f030,0xfc301c7c,0xe007fc00,0x3ffff003,0xfe0001fe,0,0xc03000,
-0x78f001f,0xff0007fc,0xf000,0x7c000f0,0xf0fc03,0xf0f000f0,0x1f0f801f,0xf8000f0,
-0xfffff0,0xf000f030,0x7c300c3c,0xc003fc00,0x3ffff003,0xfc0000fc,0,0xc03000,
-0x7df001f,0xff000ffe,0xf000,0xf8000f0,0xf0f801,0xf0f801f0,0x3e07c03e,0x7c000f0,
-0xf000f0,0xf000f030,0x300000,0x1fc00,0x3,0xf8000000,0x3ffc0,0xfff000,
-0x3de001f,0xff001fbf,0xf000,0x1f8000f0,0xf0f801,0xf0fc03f0,0x7c03e07c,0x3e000f0,
-0xf000f0,0xf001f038,0x700000,0xfc00,0x3,0xf0000000,0x3ffc0,0xfff000,
-0x3de001f,0xff001f1f,0xf000,0x1f0000ff,0xfff0ffff,0xf07fffe0,0xf801f0f8,0x1f000f0,
-0xf000f0,0xfffff01c,0xe00000,0,0,0,0,0,
-0x3fe001f,0xff003f1f,0x8000f000,0x3fff00ff,0xfff0ffff,0xf03fffc0,0xf000f0f0,0xf000f0,
-0xf000f0,0xfffff00e,0x1c00000,0,0,0,0,0,
-0x3fe001f,0xbf007e0f,0xc000f000,0x3fff00ff,0xfff0ffff,0xf01fff80,0xe00070e0,0x7000f0,
-0xf000f0,0x7fffe007,0xff800000,0,0,0,0,0,
-0x1fc000f,0xbe007e0f,0xc000f000,0x3fff00ff,0xfff0ffff,0xf00fff00,0xc00030c0,0x3000f0,
-0xf000f0,0x3fffc003,0xff000000,0,0,0,0,0,
-0x1fc000f,0x1e007c07,0xc000f000,0x3fff0000,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0xf00000,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0x3fc0000,0xc00000,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0x39c0000,0x1c00000,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0x70e0000,0x3800003,0xfc000000,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0x6060000,0x7000003,0xfc000000,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0x6060000,0xe003ff0,0x3c000000,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0x70e0000,0x1c003ff0,0x7c000000,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0x39c0000,0x38003c00,0xec000000,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0x3fc0000,0x70003c01,0xcc000000,0,0,0,0,
-0,0,0,0xc00000,0,0,0,0,
-0,0xf00000,0xe0003c03,0x8c000000,0,0,0,0,
-0,0,0,0x1e00000,0,0,0,0,
-0,0,0xc0003c07,0xc000000,0,0,0,0,
-0x3f0fc03f,0xfc03f0f,0xc03f3f00,0x3f00000,0xf00003cf,0xc0000000,0,0,
-0x3f0fc0,0,0xc0003c0e,0,0,0,0,0,
-0x7f0fe07f,0xfe07f0f,0xe03f3f00,0x3300001,0xf80007cf,0xc0000000,0,0,
-0x7f0fe0,0,0xc0003c0c,0,0,0,0,0,
-0xff0c70e3,0xff0ff0f,0xf0c000c0,0xc000c003,0x9c000e03,0,0,0,
-0xe30c70,0,0xc0003c00,0x30000000,0,0,0,0,
-0xff0c30c3,0xff0ff0f,0xf0c000c0,0xc000c007,0xe000c03,0,0,0,
-0xc30c30,0,0xe0003c00,0x30000000,0,0,0,0,
-0xff0c30c3,0xff0ff0f,0xf0c000c0,0xc000c00e,0x7000c03,0,0x3,0x300000,
-0xc30c30,0,0x70003c00,0x30000000,0,0,0,0,
-0xff0c30c3,0xff0ff0f,0xf0c000c0,0xc000c01c,0x3800e03,0,0x7,0x300000,
-0xc30c30,0,0x38003c00,0x30000000,0,0,0,0,
-0xff0c30c3,0xff0ff0f,0xf000c000,0xc00038,0x1c007c3,0xc30fc,0xe,0x301c7c,
-0x3cc30c30,0,0x1ff03c00,0x30000000,0,0,0,0,
-0xff0c30c3,0xff0ff0f,0xf000c000,0xc00070,0xe003c3,0x1e30fc,0x1c,0x303cfc,
-0x7cc30c30,0,0xff03c00,0x30000000,0,0,0,0,
-0xff0c30c3,0xff0ff0f,0xf0c0c0c0,0xc0c0c0e0,0x700000,0x3f3030,0x38,0x3030c0,
-0xe0c30c30,0,0x3fff,0xf0000000,0,0,0,0,
-0xff0c30c3,0xff0ff0f,0xf0c0c0c0,0xc0c0c0c0,0x300000,0x333030,0x70,0x7030e0,
-0xc0c30c30,0,0x3fff,0xf0000000,0,0,0,0,
-0xff0c30c3,0xff0ff0f,0xf0c0c0c0,0xc0c0c0c0,0x3003cc,0x333030,0xe0,0xffe03c70,
-0xc0c30c30,0,0x3fff,0xf0000000,0,0,0,0,
-0xff0c30c3,0xff0ff0f,0xf0c0c0c0,0xc0c0c0c0,0x3007cc,0x333030,0xe0,0xffc03c38,
-0xc0c30c30,0,0x3fff,0xf0000000,0,0,0,0,
-0xff0ff0ff,0xff0ff0f,0xf000c000,0xff,0xff00e0c,0x3f3030,0x30003070,0x301c,
-0xc0ff0ff0,0,0,0,0,0,0,0,
-0xff0ff0ff,0xff0ff0f,0xf000c000,0xff,0xff00c0c,0x3f3830,0x30003038,0x300c,
-0xe0ff0ff0,0,0,0,0,0,0,0,
-0xc00030c0,0x30c000,0x30c000c0,0xc000c003,0xc000c0c,0x331f30,0x3000301c,0x3cfc,
-0x7cc00030,0,0,0,0,0,0,0,
-0xc00030c0,0x30c000,0x30c000c0,0xc000c003,0xc000c0e,0x330f30,0x3000300e,0x1cf8,
-0x3cc00030,0,0,0,0,0,0,0,
-0xc00030c0,0x30c000,0x30c000c0,0xc330c003,0xc000c07,0xc0000000,0x3ffff007,0,
-0xc00030,0,0,0,0,0,0,0,
-0xc00030c0,0x30c000,0x30c000c0,0xc3f0c003,0xc000c03,0xc0000000,0x3ffff003,0,
-0xc00030,0,0,0,0,0,0,0,
-0,0,0,0x1e00003,0xfc000000,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0xc00003,0xfc000000,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,
+++ /dev/null
-struct vg_postprocess _vg_postprocess =
-{
-#ifdef VG_3D
- .blur_effect = 1,
- .blur_strength = 0.3f,
-#endif
-};
-
-struct vg_render _vg_render =
-{
- .scale = 1.0f
-};
-
-VG_API void _vg_render_register(void)
-{
- vg_console_reg_var( "render_scale", &_vg_render.scale, k_var_dtype_f32, VG_VAR_PERSISTENT );
- vg_console_reg_var( "blur_strength", &_vg_postprocess.blur_strength, k_var_dtype_f32, 0 );
- vg_console_reg_var( "blur_effect", &_vg_postprocess.blur_effect, k_var_dtype_i32, VG_VAR_PERSISTENT );
-}
-
-VG_API void _vg_render_init(void)
-{
- VG_ASSERT( _vg_thread_has_flags( VG_THREAD_OWNS_OPENGL ) );
- f32 quad[] =
- {
- 0.00f,0.00f, 1.00f,1.00f, 0.00f,1.00f,
- 0.00f,0.00f, 1.00f,0.00f, 1.00f,1.00f,
- };
-
- glGenVertexArrays( 1, &_vg_postprocess.quad_vao );
- glGenBuffers( 1, &_vg_postprocess.quad_vbo );
- glBindVertexArray( _vg_postprocess.quad_vao );
- glBindBuffer( GL_ARRAY_BUFFER, _vg_postprocess.quad_vbo );
- glBufferData( GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STATIC_DRAW );
- glBindVertexArray( _vg_postprocess.quad_vao );
- glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, sizeof(f32)*2, (void*)0 );
- glEnableVertexAttribArray( 0 );
-
-#if defined( VG_3D )
-
- /*
- * Main framebuffer
- */
- _vg_render.fb_main = _vg_framebuffer_alloc( NULL, 3, VG_FRAMEBUFFER_GLOBAL );
- _vg_render.fb_main->display_name = "main";
- _vg_render.fb_main->resolution_div = 1;
- _vg_render.fb_main->attachments[0] = (vg_framebuffer_attachment)
- {
- "colour", k_framebuffer_attachment_type_texture,
-
- .internalformat = GL_RGB,
- .format = GL_RGB,
- .type = GL_UNSIGNED_BYTE,
- .attachment = GL_COLOR_ATTACHMENT0
- };
- _vg_render.fb_main->attachments[1] = (vg_framebuffer_attachment)
- {
- "motion", k_framebuffer_attachment_type_texture,
-
- .quality = k_framebuffer_quality_high_only,
- .internalformat = GL_RG16F,
- .format = GL_RG,
- .type = GL_FLOAT,
- .attachment = GL_COLOR_ATTACHMENT1
- };
- _vg_render.fb_main->attachments[2] = (vg_framebuffer_attachment)
- {
- "depth_stencil", k_framebuffer_attachment_type_texture_depth,
- .internalformat = GL_DEPTH24_STENCIL8,
- .format = GL_DEPTH_STENCIL,
- .type = GL_UNSIGNED_INT_24_8,
- .attachment = GL_DEPTH_STENCIL_ATTACHMENT
- };
- vg_framebuffer_init( _vg_render.fb_main );
-
- /*
- * Water reflection
- */
- _vg_render.fb_water_reflection = _vg_framebuffer_alloc( NULL, 2, VG_FRAMEBUFFER_GLOBAL );
- _vg_render.fb_water_reflection->display_name = "water_reflection";
- _vg_render.fb_water_reflection->resolution_div = 2;
- _vg_render.fb_water_reflection->attachments[0] = (vg_framebuffer_attachment)
- {
- "colour", k_framebuffer_attachment_type_texture,
- .internalformat = GL_RGB,
- .format = GL_RGB,
- .type = GL_UNSIGNED_BYTE,
- .attachment = GL_COLOR_ATTACHMENT0
- };
- _vg_render.fb_water_reflection->attachments[1] = (vg_framebuffer_attachment)
- {
- "depth_stencil", k_framebuffer_attachment_type_renderbuffer,
- .internalformat = GL_DEPTH24_STENCIL8,
- .attachment = GL_DEPTH_STENCIL_ATTACHMENT
- };
- vg_framebuffer_init( _vg_render.fb_water_reflection );
-
- /*
- * Thid rendered view from the perspective of the camera, but just
- * captures stuff thats under the water
- */
- _vg_render.fb_water_beneath = _vg_framebuffer_alloc( NULL, 2, VG_FRAMEBUFFER_GLOBAL );
- _vg_render.fb_water_beneath->display_name = "water_beneath";
- _vg_render.fb_water_beneath->resolution_div = 2;
- _vg_render.fb_water_beneath->attachments[0] = (vg_framebuffer_attachment)
- {
- "colour", k_framebuffer_attachment_type_texture,
- .internalformat = GL_RED,
- .format = GL_RED,
- .type = GL_UNSIGNED_BYTE,
- .attachment = GL_COLOR_ATTACHMENT0
- };
- _vg_render.fb_water_beneath->attachments[1] = (vg_framebuffer_attachment)
- {
- "depth_stencil", k_framebuffer_attachment_type_renderbuffer,
- .internalformat = GL_DEPTH24_STENCIL8,
- .attachment = GL_DEPTH_STENCIL_ATTACHMENT
- };
- vg_framebuffer_init( _vg_render.fb_water_beneath );
-#endif
-}
-
-void vg_render_fullscreen_quad(void)
-{
- glBindVertexArray( _vg_postprocess.quad_vao );
- glDrawArrays( GL_TRIANGLES, 0, 6 );
-}
-
-/*
- * Utility
- */
-
-void vg_postprocess_to_screen( vg_framebuffer *fb )
-{
- glBindFramebuffer( GL_FRAMEBUFFER, 0 );
- glViewport( 0,0, _vg_window.w, _vg_window.h );
-
- glEnable(GL_BLEND);
- glDisable(GL_DEPTH_TEST);
- glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA);
- glBlendEquation(GL_FUNC_ADD);
-
- v2f inverse;
- vg_framebuffer_inverse_ratio( fb, inverse );
-
-#ifdef VG_3D
- if( _vg_postprocess.blur_effect )
- {
- shader_blitblur_use();
- shader_blitblur_uTexMain( 0 );
- shader_blitblur_uTexMotion( 1 );
-
- f32 s = vg.time_frame_delta*60.0;
- shader_blitblur_uBlurStrength( _vg_postprocess.blur_strength / s );
- shader_blitblur_uInverseRatio( inverse );
-
- inverse[0] -= 0.0001f;
- inverse[1] -= 0.0001f;
- shader_blitblur_uClampUv( inverse );
- shader_blitblur_uOverrideDir( _vg_postprocess.motion_blur_override );
-
- vg_framebuffer_bind_texture( fb, 0, 0 );
- vg_framebuffer_bind_texture( fb, 1, 1 );
- }
- else
-#endif
- {
- shader_blit_use();
- shader_blit_uTexMain( 0 );
- shader_blit_uInverseRatio( vg_ui.bg_inverse_ratio );
- vg_framebuffer_bind_texture( fb, 0, 0 );
- }
-
- vg_render_fullscreen_quad();
-}
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_render.c"
-#else
-
-struct vg_postprocess
-{
- GLuint quad_vao,
- quad_vbo;
-
-#ifdef VG_3D
- i32 blur_effect;
- f32 blur_strength;
- v2f motion_blur_override;
-#endif
-}
-extern _vg_postprocess;
-
-struct vg_render
-{
- f32 scale;
-
-#if defined( VG_3D )
- vg_framebuffer *fb_main,
- *fb_water_reflection,
- *fb_water_beneath;
-#endif
-}
-extern _vg_render;
-VG_API void _vg_render_register(void);
-VG_API void _vg_render_init(void);
-
-void vg_render_fullscreen_quad(void);
-void vg_postprocess_to_screen( vg_framebuffer *fb );
-
-#endif
+++ /dev/null
-#pragma pack(push,1)
-struct rb_view_vert {
- v4f co;
- v3f n;
-};
-#pragma pack(pop)
-
-typedef struct rb_view_vert rb_view_vert;
-
-struct
-{
- GLuint vao, vbo, ebo;
- u32 sphere_start, sphere_count,
- box_start, box_count;
-}
-static vg_rb_view;
-
-VG_API void _vg_rb_view_init(void)
-{
- VG_ASSERT( _vg_thread_has_flags( VG_THREAD_OWNS_OPENGL ) );
-
- u32 H = 20,
- V = 16,
- verts_count = 0,
- tris_count = 0;
-
- /* box */
- verts_count += 4*6;
- tris_count += 2*6;
- vg_rb_view.box_count = 2*6;
- vg_rb_view.box_start = 0;
-
- /* sphere */
- verts_count += H*(V-2) + 2;
- tris_count += H*2 + (V-2)*(H*2);
- vg_rb_view.sphere_count = H*2 + (V-2)*(H*2);
-
- rb_view_vert verts[ verts_count ];
- u16 tris[ tris_count*3 ];
-
- u32 tri_index = 0,
- vert_index = 0;
-
- /* box
- * ----------------------------------------------------------- */
- for( u32 i=0; i<6; i ++ )
- {
- v3f n = {i%3==0,i%3==1,i%3==2};
- if( i >= 3 ) v3_negate( n, n );
- v3f v0, v1;
- v3_tangent_basis( n, v0, v1 );
-
- rb_view_vert *vs = &verts[vert_index];
- vert_index += 4;
-
- for( u32 j=0; j<4; j ++ )
- {
- v3_copy( n, vs[j].n );
- v3_muladds( n, v0, j&0x1?1.0f:-1.0f, vs[j].co );
- v3_muladds( vs[j].co, v1, j&0x2?1.0f:-1.0f, vs[j].co );
- vs[j].co[3] = 0.0f;
- }
-
- tris[tri_index*3+0] = i*4+0;
- tris[tri_index*3+1] = i*4+1;
- tris[tri_index*3+2] = i*4+3;
- tris[tri_index*3+3] = i*4+0;
- tris[tri_index*3+4] = i*4+3;
- tris[tri_index*3+5] = i*4+2;
- tri_index += 2;
- }
-
- /* sphere / capsule
- * ----------------------------------------------------------- */
- u32 base = vert_index;
- vg_rb_view.sphere_start = tri_index;
- v4_copy( (v4f){0,-1,0,0}, verts[vert_index].co );
- v3_copy( (v3f){0,-1,0}, verts[vert_index ++].n );
-
- for( u32 x=0; x<H; x ++ )
- {
- tris[tri_index*3+0] = base+0;
- tris[tri_index*3+1] = base+1+x;
- tris[tri_index*3+2] = base+1+((x+1)%H);
- tri_index += 1;
- }
-
- for( u32 y=1; y<V-1; y ++ )
- {
- f32 ty = ((f32)y/(f32)(V-1)) * VG_PIf;
- u32 ybase = y-1;
- for( u32 x=0; x<H; x ++ )
- {
- f32 tx = ((f32)x/(f32)H) * VG_TAUf;
-
- v4f co = { cosf(tx)*sinf(ty), -cosf(ty), sinf(tx)*sinf(ty), y>=(V/2) };
- v4_copy( co, verts[vert_index].co );
- v4_copy( co, verts[vert_index ++].n );
-
- if( y < V-2 )
- {
- tris[tri_index*3+0] = base+1 + ybase*H + x;
- tris[tri_index*3+1] = base+1 + (ybase+1)*H + ((x+1)%H);
- tris[tri_index*3+2] = base+1 + ybase*H + ((x+1)%H);
- tris[tri_index*3+3] = base+1 + ybase*H + x;
- tris[tri_index*3+4] = base+1 + (ybase+1)*H + x;
- tris[tri_index*3+5] = base+1 + (ybase+1)*H + ((x+1)%H);
- tri_index += 2;
- }
- }
- }
-
- v4_copy( (v4f){0, 1,0,1}, verts[vert_index].co );
- v3_copy( (v3f){0, 1,0}, verts[vert_index ++].n );
-
- for( u32 x=0; x<H; x ++ )
- {
- tris[tri_index*3+0] = base + (H*(V-2) + 2)-1;
- tris[tri_index*3+1] = base+1 + (V-3)*H+((x+1)%H);
- tris[tri_index*3+2] = base+1 + (V-3)*H+x;
- tri_index += 1;
- }
-
- glGenVertexArrays( 1, &vg_rb_view.vao );
- glGenBuffers( 1, &vg_rb_view.vbo );
- glGenBuffers( 1, &vg_rb_view.ebo );
- glBindVertexArray( vg_rb_view.vao );
-
- glBindBuffer( GL_ARRAY_BUFFER, vg_rb_view.vbo );
- glBufferData( GL_ARRAY_BUFFER, verts_count*sizeof(rb_view_vert), verts, GL_STATIC_DRAW );
- glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vg_rb_view.ebo );
- glBufferData( GL_ELEMENT_ARRAY_BUFFER, tris_count*3*sizeof(u16), tris, GL_STATIC_DRAW );
-
- /* 0: coordinates */
- size_t stride = sizeof(rb_view_vert);
- glVertexAttribPointer( 0, 4, GL_FLOAT, GL_FALSE, stride, (void*)0 );
- glEnableVertexAttribArray( 0 );
-
- /* 1: normal */
- glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, stride, (void *)offsetof(rb_view_vert, n) );
- glEnableVertexAttribArray( 1 );
-}
-
-void vg_rb_view_bind(void)
-{
- glEnable( GL_CULL_FACE );
- glEnable( GL_DEPTH_TEST );
-
- shader_debug_rigidbody_use();
- shader_debug_rigidbody_uPv( vg.pv );
-
- glBindVertexArray( vg_rb_view.vao );
-}
-
-void vg_rb_view_box( m4x3f mdl, boxf bbx, v4f colour )
-{
- v3f e;
- v3_sub( bbx[1], bbx[0], e );
- v3_muls( e, 0.5f, e );
-
- m4x3f mmdl;
- m4x3_identity( mmdl );
- m3x3_scale( mmdl, e );
- v3_add( bbx[0], e, mmdl[3] );
- m4x3_mul( mdl, mmdl, mmdl );
-
- shader_debug_rigidbody_uMdl( mmdl );
- shader_debug_rigidbody_uMdl1( mmdl );
- shader_debug_rigidbody_uColour( colour );
- glDrawElements( GL_TRIANGLES, vg_rb_view.box_count*3, GL_UNSIGNED_SHORT,
- (void *)(vg_rb_view.box_start*3*sizeof(u16)) );
-}
-
-void vg_rb_view_sphere( m4x3f mdl, f32 r, v4f colour )
-{
- m4x3f mmdl;
- m4x3_copy( mdl, mmdl );
- m3x3_scalef( mmdl, r );
-
- shader_debug_rigidbody_uMdl( mmdl );
- shader_debug_rigidbody_uMdl1( mmdl );
- shader_debug_rigidbody_uColour( colour );
- glDrawElements( GL_TRIANGLES, vg_rb_view.sphere_count*3, GL_UNSIGNED_SHORT,
- (void *)(vg_rb_view.sphere_start*3*sizeof(u16)) );
-}
-
-void vg_rb_view_capsule( m4x3f mdl, f32 r, f32 h, v4f colour )
-{
- m4x3f mmdl0, mmdl1;
- m4x3_identity( mmdl0 );
- m4x3_identity( mmdl1 );
- m3x3_scalef( mmdl0, r );
- m3x3_scalef( mmdl1, r );
- mmdl0[3][1] = -h*0.5f+r;
- mmdl1[3][1] = h*0.5f-r;
- m4x3_mul( mdl, mmdl0, mmdl0 );
- m4x3_mul( mdl, mmdl1, mmdl1 );
-
- shader_debug_rigidbody_uMdl( mmdl0 );
- shader_debug_rigidbody_uMdl1( mmdl1 );
- shader_debug_rigidbody_uColour( colour );
- glDrawElements( GL_TRIANGLES, vg_rb_view.sphere_count*3, GL_UNSIGNED_SHORT,
- (void *)(vg_rb_view.sphere_start*3*sizeof(u16)) );
-}
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_rigidbody_view.c"
-#else
-
-VG_API void _vg_rb_view_init(void);
-
-void vg_rb_view_bind(void);
-void vg_rb_view_box( m4x3f mdl, boxf bbx, v4f colour );
-void vg_rb_view_sphere( m4x3f mdl, f32 r, v4f colour );
-void vg_rb_view_capsule( m4x3f mdl, f32 r, f32 h, v4f colour );
-
-#endif
+++ /dev/null
-static struct ui_enum_opt vg_settings_vsync_enum[] =
-{
- { 0, "None" },
- { 1, "On" },
- {-1, "Adaptive" },
-};
-
-static struct ui_enum_opt vg_settings_quality_enum[] =
-{
- { 0, "High Quality" },
- { 1, "Faster" },
- { 2, "Absolute Minimum" },
-};
-
-static struct ui_enum_opt vg_settings_screen_mode_enum[] =
-{
- { 0, "Fullscreen (desktop)" },
- { 1, "Fullscreen (native)" },
- { 2, "Floating Window" }
-};
-
-static struct ui_enum_opt vg_settings_dsp_enum[] =
-{
- { 1, "Enabled" },
- { 0, "Disabled" },
-};
-
-struct
-{
- struct vg_setting_ranged_i32 fps_limit;
- struct vg_setting_enum vsync, quality, screenmode, audio_devices, dsp;
- i32 temp_audio_choice;
- bool open;
-}
-static vg_settings =
-{
- .fps_limit = { .label = "Fps Limit",
- .min=24, .max=300, .actual_value = &vg.fps_limit },
- .vsync = { .label = "Vsync",
- .actual_value = &_vg_window.vsync,
- .options = vg_settings_vsync_enum, .option_count = 3 },
- .quality = { .label = "Graphic Quality",
- .actual_value = &vg.quality_profile,
- .options = vg_settings_quality_enum, .option_count = 3 },
- .screenmode = { .label = "Type",
- .actual_value = &_vg_window.display_mode,
- .options = vg_settings_screen_mode_enum, .option_count=3 },
- .audio_devices = { .label = "Audio Device",
- .actual_value = &vg_settings.temp_audio_choice,
- .options = NULL, .option_count = 0 },
- .dsp = { .label = "Audio effects (reverb etc.)",
- .actual_value = &_vg_audio.dsp_enabled_ui,
- .options = vg_settings_dsp_enum, .option_count=2 },
-};
-
-static void vg_settings_ui_draw_diff( ui_context *ctx, ui_rect orig )
-{
- ui_rect l,r;
- ui_split( orig, k_ui_axis_v, -32, 0, l, r );
- ui_text( ctx, r, "*", 1, k_ui_align_middle_center, ui_colour(ctx, k_ui_blue) );
-}
-
-/* i32 settings
- * ------------------------------------------------------------------------- */
-static void vg_settings_ui_int( ui_context *ctx, char *buf, u32 len, void *userdata )
-{
- for( u32 i=0, j=0; i<len; i ++ )
- {
- if( ((buf[i] >= '0') && (buf[i] <= '9')) || (buf[i] == '\0') )
- buf[j ++] = buf[i];
- }
-}
-
-struct ui_textbox_callbacks static vg_settings_ui_int_callbacks =
-{
- .change = vg_settings_ui_int
-};
-
-static bool vg_settings_ranged_i32_valid( struct vg_setting_ranged_i32 *prop )
-{
- if( prop->new_value < prop->min ) return 0;
- if( prop->new_value > prop->max ) return 0;
- return 1;
-}
-
-static bool vg_settings_ranged_i32_diff( struct vg_setting_ranged_i32 *prop )
-{
- if( prop->new_value != *prop->actual_value ) return 1;
- else return 0;
-}
-
-static bool vg_settings_ui_ranged_i32( ui_context *ctx, struct vg_setting_ranged_i32 *prop, ui_rect rect )
-{
- ui_rect orig;
- rect_copy( rect, orig );
-
- ui_textbox( ctx, rect, prop->label, prop->buf, sizeof(prop->buf),
- 1, 0, &vg_settings_ui_int_callbacks );
- prop->new_value = atoi( prop->buf );
-
- if( vg_settings_ranged_i32_diff( prop ) )
- vg_settings_ui_draw_diff( ctx, orig );
-
- bool valid = vg_settings_ranged_i32_valid( prop );
- if( !valid )
- {
- ui_rect _null, line;
- ui_split( orig, k_ui_axis_h, -1, 0, _null, line );
- line[1] += 3;
-
- ui_fill( ctx, line, ui_colour( ctx, k_ui_red ) );
- }
-
- return valid;
-}
-
-void ui_settings_ranged_i32_init( struct vg_setting_ranged_i32 *prop )
-{
- vg_str tmp;
- vg_strnull( &tmp, prop->buf, sizeof(prop->buf) );
- vg_strcati64( &tmp, *prop->actual_value, 10 );
- prop->new_value = *prop->actual_value;
-}
-
-/* enum settings
- * ------------------------------------------------------------------------- */
-
-bool vg_settings_enum_diff( struct vg_setting_enum *prop )
-{
- if( prop->new_value != *prop->actual_value ) return 1;
- else return 0;
-}
-
-bool vg_settings_enum( ui_context *ctx, struct vg_setting_enum *prop, ui_rect rect )
-{
- ui_rect orig;
- rect_copy( rect, orig );
-
- ui_enum( ctx, rect, prop->label,
- prop->options, prop->option_count, &prop->new_value );
-
- if( vg_settings_enum_diff( prop ) )
- vg_settings_ui_draw_diff( ctx, orig );
-
- return 1;
-}
-
-void ui_settings_enum_init( struct vg_setting_enum *prop )
-{
- prop->new_value = *prop->actual_value;
-}
-
-/* .. */
-void vg_settings_ui_header( ui_context *ctx, ui_rect inout_panel, const char *name )
-{
- ui_rect rect;
- ui_standard_widget( ctx, inout_panel, rect, 2 );
- ui_text( ctx, rect, name, 1, k_ui_align_middle_center, ui_colour(ctx, k_ui_fg+3) );
-}
-
-bool vg_settings_apply_button( ui_context *ctx, ui_rect inout_panel, bool validated )
-{
- ui_rect last_row;
- ui_px height = ui_standard_widget_height( ctx, 1 );
- ui_split( inout_panel, k_ui_axis_h, -height, 8, inout_panel, last_row );
-
- const char *string = "Apply";
- if( validated )
- {
- if( ui_button( ctx, last_row, string ) == 1 )
- return 1;
- }
- else
- {
- ui_rect rect;
- ui_standard_widget( ctx, last_row, rect, 1 );
- ui_fill( ctx, rect, ui_colour( ctx, k_ui_bg+1 ) );
- ui_outline( ctx, rect, -1, ui_colour( ctx, k_ui_red ), 0 );
-
- ui_rect t = { 0,0, ui_text_line_width( ctx, string ), 14 };
- ui_rect_center( rect, t );
- ui_text( ctx, t, string, 1, k_ui_align_left, ui_colour(ctx,k_ui_fg+3) );
- }
-
- return 0;
-}
-
-static void vg_settings_video_apply(void)
-{
- if( vg_settings_enum_diff( &vg_settings.screenmode ) )
- {
- _vg_window.display_mode = vg_settings.screenmode.new_value;
-
- if( (_vg_window.display_mode == k_vg_window_fullscreen_desktop) ||
- (_vg_window.display_mode == k_vg_window_fullscreen) )
- {
- SDL_DisplayMode video_mode;
- if( SDL_GetDesktopDisplayMode( 0, &video_mode ) )
- {
- vg_error("SDL_GetDesktopDisplayMode failed: %s\n", SDL_GetError());
- }
- else
- {
- //vg.display_refresh_rate = video_mode.refresh_rate;
- _vg_window.w = video_mode.w;
- _vg_window.h = video_mode.h;
- }
- SDL_SetWindowSize( _vg_window.sdl_hwindow, _vg_window.w, _vg_window.h );
- }
-
- if( _vg_window.display_mode == k_vg_window_fullscreen_desktop )
- SDL_SetWindowFullscreen( _vg_window.sdl_hwindow, SDL_WINDOW_FULLSCREEN_DESKTOP );
- if( _vg_window.display_mode == k_vg_window_fullscreen )
- SDL_SetWindowFullscreen( _vg_window.sdl_hwindow, SDL_WINDOW_FULLSCREEN );
- if( _vg_window.display_mode == k_vg_window_windowed )
- {
- SDL_SetWindowFullscreen( _vg_window.sdl_hwindow, 0 );
- SDL_SetWindowSize( _vg_window.sdl_hwindow, 1280, 720 );
- SDL_SetWindowPosition( _vg_window.sdl_hwindow, 16, 16 );
- SDL_SetWindowMinimumSize( _vg_window.sdl_hwindow, 1280, 720 );
- SDL_SetWindowMaximumSize( _vg_window.sdl_hwindow, 4096, 4096 );
- }
- }
-
- vg.fps_limit = vg_settings.fps_limit.new_value;
- vg.quality_profile = vg_settings.quality.new_value;
- _vg_window.vsync = vg_settings.vsync.new_value;
-}
-
-static void vg_settings_video_gui( ui_context *ctx, ui_rect panel )
-{
- bool validated = 1;
- ui_rect rq;
- ui_standard_widget( ctx, panel, rq, 1 );
- vg_settings_enum( ctx, &vg_settings.quality, rq );
-
- /* FIXME */
-#if 0
- if( vg.vsync_feature == k_vsync_feature_error ){
- ui_info( panel, "There was an error activating vsync feature." );
- }
-#endif
-
- /* frame timing */
- vg_settings_ui_header( ctx, panel, "Frame Timing" );
- ui_rect duo, d0,d1;
- ui_standard_widget( ctx, panel, duo, 1 );
- ui_split_ratio( duo, k_ui_axis_v, 0.5f, 16, d0, d1 );
-
- vg_settings_enum( ctx, &vg_settings.vsync, d0 );
- validated &= vg_settings_ui_ranged_i32( ctx, &vg_settings.fps_limit, d1 );
-
- /* profiler */
- ui_standard_widget( ctx, panel, duo, 10 );
- int frame_target = _vg_window.monitor_refresh_rate;
- if( !_vg_window.vsync )
- frame_target = vg.fps_limit;
-
- _vg_profiler_draw( ctx, vg.profiler, (1.0f/(f32)frame_target)*1500.0f, duo, 1, 0 );
- ui_fill( ctx, (ui_rect){ duo[0], duo[1]+(duo[3]*2)/3, duo[2], 1 }, ui_colour(ctx, k_ui_fg) );
-
- /* window spec */
- vg_settings_ui_header( ctx, panel, "Window Specification" );
-
- ui_standard_widget( ctx, panel, duo, 1 );
- vg_settings_enum( ctx, &vg_settings.screenmode, duo );
-
- if( vg_settings_apply_button( ctx, panel, validated ) )
- vg_settings_video_apply();
-}
-
-static void vg_settings_audio_apply(void)
-{
- if( vg_settings_enum_diff( &vg_settings.audio_devices ) )
- {
- if( _vg_audio.sdl_output_device )
- {
- vg_info( "Closing audio device %d\n", _vg_audio.sdl_output_device );
- SDL_CloseAudioDevice( _vg_audio.sdl_output_device );
- _vg_audio.sdl_output_device = 0;
- }
-
- vg_strfree( &_vg_audio.device_choice );
-
- if( vg_settings.audio_devices.new_value == -1 ){ }
- else if( vg_settings.audio_devices.new_value == -2 )
- {
- vg_fatal_error( "" );
- }
- else
- {
- struct ui_enum_opt *selected = NULL, *oi;
-
- for( int i=0; i<vg_settings.audio_devices.option_count; i ++ )
- {
- oi = &vg_settings.audio_devices.options[i];
-
- if( oi->value == vg_settings.audio_devices.new_value )
- {
- selected = oi;
- break;
- }
- }
-
- vg_strnull( &_vg_audio.device_choice, NULL, 0 );
- vg_strcat( &_vg_audio.device_choice, oi->alias );
- }
-
- vg_audio_device_init();
- *vg_settings.audio_devices.actual_value = vg_settings.audio_devices.new_value;
- }
-
- if( vg_settings_enum_diff( &vg_settings.dsp ) )
- *vg_settings.dsp.actual_value = vg_settings.dsp.new_value;
-}
-
-static void vg_settings_audio_gui( ui_context *ctx, ui_rect panel )
-{
- ui_rect rq;
- ui_standard_widget( ctx, panel, rq, 1 );
- vg_settings_enum( ctx, &vg_settings.audio_devices, rq );
-
- ui_standard_widget( ctx, panel, rq, 1 );
- vg_settings_enum( ctx, &vg_settings.dsp, rq );
-
- if( vg_settings_apply_button( ctx, panel, 1 ) )
- vg_settings_audio_apply();
-}
-
-VG_API void _vg_settings_open(void)
-{
- vg_settings.open = 1;
-
- ui_settings_ranged_i32_init( &vg_settings.fps_limit );
- ui_settings_enum_init( &vg_settings.vsync );
- ui_settings_enum_init( &vg_settings.quality );
- ui_settings_enum_init( &vg_settings.screenmode );
-
- /* Create audio options */
- int count = SDL_GetNumAudioDevices( 0 );
-
- struct ui_enum_opt *options = malloc( sizeof(struct ui_enum_opt)*(count+1) );
- vg_settings.audio_devices.options = options;
- vg_settings.audio_devices.option_count = count+1;
-
- struct ui_enum_opt *o0 = &options[0];
- o0->alias = "OS Default";
- o0->value = -1;
-
- for( int i=0; i<count; i ++ )
- {
- struct ui_enum_opt *oi = &options[i+1];
-
- const char *device_name = SDL_GetAudioDeviceName( i, 0 );
- int len = strlen(device_name);
-
- oi->alias = malloc( len+1 );
- memcpy( (void *)oi->alias, device_name, len+1 );
- oi->value = i;
- }
-
- if( _vg_audio.device_choice.buffer )
- {
- vg_settings.temp_audio_choice = -2;
-
- for( int i=0; i<count; i ++ )
- {
- struct ui_enum_opt *oi = &options[i+1];
- if( !strcmp( oi->alias, _vg_audio.device_choice.buffer ) )
- {
- vg_settings.temp_audio_choice = oi->value;
- break;
- }
- }
- }
- else
- {
- vg_settings.temp_audio_choice = -1;
- }
-
- ui_settings_enum_init( &vg_settings.audio_devices );
- ui_settings_enum_init( &vg_settings.dsp );
-
-#ifdef VG_GAME_SETTINGS
- vg_game_settings_init();
-#endif
-}
-
-VG_API void _vg_settings_close(void)
-{
- vg_settings.open = 0;
-
- struct ui_enum_opt *options = vg_settings.audio_devices.options;
- for( int i=1; i < vg_settings.audio_devices.option_count; i ++ )
- free( (void *)options[i].alias );
- free( vg_settings.audio_devices.options );
-}
-
-VG_API void _vg_settings_gui( ui_context *ctx )
-{
- if( !vg_settings.open )
- return;
-
- ui_rect null;
- ui_rect screen = { 0, 0, ctx->area[0], ctx->area[1] };
- ui_rect window = { 0, 0, 1000, 700 };
- ui_rect_center( screen, window );
- ui_capture_mouse( ctx, 1 );
-
- ui_fill( ctx, window, ui_colour( ctx, k_ui_bg+1 ) );
- ui_outline( ctx, window, 1, ui_colour( ctx, k_ui_bg+7 ), 0 );
-
- ui_rect title, panel;
- ui_split( window, k_ui_axis_h, 28, 0, title, panel );
- ui_fill( ctx, title, ui_colour( ctx, k_ui_bg+7 ) );
- ui_text( ctx, title, "Settings", 1, k_ui_align_middle_center,
- ui_colourcont(ctx, k_ui_bg+7) );
-
- ui_rect quit_button;
- ui_split( title, k_ui_axis_v, title[2]-title[3], 2, title, quit_button );
-
- if( ui_button_text( ctx, quit_button, "X", 1 ) == k_ui_button_click )
- {
- _vg_settings_close();
- return;
- }
-
- ui_rect_pad( panel, (ui_px[2]){ 8, 8 } );
-
- const char *opts[] = { "video", "audio" };
-
- static i32 page = 0;
- ui_tabs( ctx, panel, panel, opts, VG_ARRAY_LEN(opts), &page );
-
- if( page == 0 )
- {
- vg_settings_video_gui( ctx, panel );
- }
- else if( page == 1 )
- vg_settings_audio_gui( ctx, panel );
-}
-
-static int cmd_vg_settings_toggle( int argc, const char *argv[] )
-{
- _vg_settings_open();
- return 0;
-}
-
-VG_API void _vg_settings_register(void)
-{
- vg_console_reg_cmd( "vg_settings", cmd_vg_settings_toggle, NULL );
-}
-
-VG_API bool _vg_settings_is_open(void)
-{
- return vg_settings.open;
-}
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_settings.c"
-#else
-VG_API void _vg_settings_register(void);
-VG_API void _vg_settings_gui( ui_context *ctx );
-VG_API void _vg_settings_open(void);
-VG_API void _vg_settings_close(void);
-VG_API bool _vg_settings_is_open(void);
-#endif
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_shader.c"
-#else
-
-typedef struct vg_shader vg_shader;
-struct vg_shader
-{
- u32 alias_offset;
- struct vg_subshader
- {
- u32 glsl, src;
- }
- vs, fs;
-
- u32 names_start, uniform_aliases_offset, uniform_count;
- bool compiled;
-};
-
-VG_API void _vg_shaders_register(void);
-VG_API void _vg_shaders_init(void);
-
-int vg_shaders_live_recompile(int argc, const char *argv[]);
-void vg_compile_shader( struct vg_shader *shader );
-void vg_recompile_shader( struct vg_shader *shader );
-void vg_free_shader( struct vg_shader *shader );
-
-#endif
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_steam2.c"
-#else
-# if defined( VG_ENGINE ) || defined( VG_SERVER )
-# if defined( VG_ENGINE ) && defined( VG_SERVER )
-# error Can't be both!
-# endif
-# else
-# error Must define VG_ENGINE or VG_SERVER
-# endif
-
-#define STEAMTIMELINE_INTERFACE_VERSION "STEAMTIMELINE_INTERFACE_V004"
-#define STEAMUTILS_INTERFACE_VERSION "SteamUtils010"
-#define STEAMGAMECOORDINATOR_INTERFACE_VERSION "SteamGameCoordinator001"
-#define STEAMHTTP_INTERFACE_VERSION "STEAMHTTP_INTERFACE_VERSION003"
-#define STEAMREMOTESTORAGE_INTERFACE_VERSION "STEAMREMOTESTORAGE_INTERFACE_VERSION016"
-#define STEAMAPPS_INTERFACE_VERSION "STEAMAPPS_INTERFACE_VERSION008"
-#define STEAMUGC_INTERFACE_VERSION "STEAMUGC_INTERFACE_VERSION021"
-#define STEAMAPPTICKET_INTERFACE_VERSION "STEAMAPPTICKET_INTERFACE_VERSION001"
-#define STEAMSCREENSHOTS_INTERFACE_VERSION "STEAMSCREENSHOTS_INTERFACE_VERSION003"
-#define STEAMHTMLSURFACE_INTERFACE_VERSION "STEAMHTMLSURFACE_INTERFACE_VERSION_005"
-#define STEAMNETWORKING_INTERFACE_VERSION "SteamNetworking006"
-#define STEAMMUSICREMOTE_INTERFACE_VERSION "STEAMMUSICREMOTE_INTERFACE_VERSION001"
-#define STEAMREMOTEPLAY_INTERFACE_VERSION "STEAMREMOTEPLAY_INTERFACE_VERSION003"
-#define STEAMNETWORKINGMESSAGES_INTERFACE_VERSION "SteamNetworkingMessages002"
-#define STEAMCONTROLLER_INTERFACE_VERSION "SteamController008"
-#define STEAMUSERSTATS_INTERFACE_VERSION "STEAMUSERSTATS_INTERFACE_VERSION013"
-#define STEAMINPUT_INTERFACE_VERSION "SteamInput006"
-#define STEAMVIDEO_INTERFACE_VERSION "STEAMVIDEO_INTERFACE_V007"
-#define STEAMINVENTORY_INTERFACE_VERSION "STEAMINVENTORY_INTERFACE_V003"
-#define STEAMMUSIC_INTERFACE_VERSION "STEAMMUSIC_INTERFACE_VERSION001"
-#define STEAMUSER_INTERFACE_VERSION "SteamUser023"
-#define STEAMGAMESERVERSTATS_INTERFACE_VERSION "SteamGameServerStats001"
-#define STEAMNETWORKINGUTILS_INTERFACE_VERSION "SteamNetworkingUtils004"
-#define STEAMGAMESERVER_INTERFACE_VERSION "SteamGameServer015"
-#define STEAMFRIENDS_INTERFACE_VERSION "SteamFriends018"
-#define STEAMNETWORKINGSOCKETS_INTERFACE_VERSION "SteamNetworkingSockets012"
-#define STEAMPARENTALSETTINGS_INTERFACE_VERSION "STEAMPARENTALSETTINGS_INTERFACE_VERSION001"
-#define STEAMMATCHMAKING_INTERFACE_VERSION "SteamMatchMaking009"
-#define STEAMMATCHMAKINGSERVERS_INTERFACE_VERSION "SteamMatchMakingServers002"
-#define STEAMGAMESEARCH_INTERFACE_VERSION "SteamMatchGameSearch001"
-#define STEAMPARTIES_INTERFACE_VERSION "SteamParties002"
-
-typedef i32 HSteamPipe;
-typedef i32 HSteamUser;
-typedef u64 SteamAPICall_t;
-typedef u64 uint64_steamid;
-typedef u32 AppId_t;
-typedef u32 SteamNetworkingPOPID;
-typedef u32 AccountID_t;
-
-typedef enum EResult EResult;
-enum EResult
-{
- k_EResultNone = 0,
- k_EResultOK = 1,
- k_EResultFail = 2,
- k_EResultNoConnection = 3,
-// k_EResultNoConnectionRetry = 4,
- k_EResultInvalidPassword = 5,
- k_EResultLoggedInElsewhere = 6,
- k_EResultInvalidProtocolVer = 7,
- k_EResultInvalidParam = 8,
- k_EResultFileNotFound = 9,
- k_EResultBusy = 10,
- k_EResultInvalidState = 11,
- k_EResultInvalidName = 12,
- k_EResultInvalidEmail = 13,
- k_EResultDuplicateName = 14,
- k_EResultAccessDenied = 15,
- k_EResultTimeout = 16,
- k_EResultBanned = 17,
- k_EResultAccountNotFound = 18,
- k_EResultInvalidSteamID = 19,
- k_EResultServiceUnavailable = 20,
- k_EResultNotLoggedOn = 21,
- k_EResultPending = 22,
- k_EResultEncryptionFailure = 23,
- k_EResultInsufficientPrivilege = 24,
- k_EResultLimitExceeded = 25,
- k_EResultRevoked = 26,
- k_EResultExpired = 27,
- k_EResultAlreadyRedeemed = 28,
- k_EResultDuplicateRequest = 29,
- k_EResultAlreadyOwned = 30,
- k_EResultIPNotFound = 31,
- k_EResultPersistFailed = 32,
- k_EResultLockingFailed = 33,
- k_EResultLogonSessionReplaced = 34,
- k_EResultConnectFailed = 35,
- k_EResultHandshakeFailed = 36,
- k_EResultIOFailure = 37,
- k_EResultRemoteDisconnect = 38,
- k_EResultShoppingCartNotFound = 39,
- k_EResultBlocked = 40,
- k_EResultIgnored = 41,
- k_EResultNoMatch = 42,
- k_EResultAccountDisabled = 43,
- k_EResultServiceReadOnly = 44,
- k_EResultAccountNotFeatured = 45,
- k_EResultAdministratorOK = 46,
- k_EResultContentVersion = 47,
- k_EResultTryAnotherCM = 48,
- k_EResultPasswordRequiredToKickSession = 49,
- k_EResultAlreadyLoggedInElsewhere = 50,
- k_EResultSuspended = 51,
- k_EResultCancelled = 52,
- k_EResultDataCorruption = 53,
- k_EResultDiskFull = 54,
- k_EResultRemoteCallFailed = 55,
- k_EResultPasswordUnset = 56,
- k_EResultExternalAccountUnlinked = 57,
- k_EResultPSNTicketInvalid = 58,
- k_EResultExternalAccountAlreadyLinked = 59,
- k_EResultRemoteFileConflict = 60,
- k_EResultIllegalPassword = 61,
- k_EResultSameAsPreviousValue = 62,
- k_EResultAccountLogonDenied = 63,
- k_EResultCannotUseOldPassword = 64,
- k_EResultInvalidLoginAuthCode = 65,
- k_EResultAccountLogonDeniedNoMail = 66,
- k_EResultHardwareNotCapableOfIPT = 67,
- k_EResultIPTInitError = 68,
- k_EResultParentalControlRestricted = 69,
- k_EResultFacebookQueryError = 70,
- k_EResultExpiredLoginAuthCode = 71,
- k_EResultIPLoginRestrictionFailed = 72,
- k_EResultAccountLockedDown = 73,
- k_EResultAccountLogonDeniedVerifiedEmailRequired = 74,
- k_EResultNoMatchingURL = 75,
- k_EResultBadResponse = 76,
- k_EResultRequirePasswordReEntry = 77,
- k_EResultValueOutOfRange = 78,
- k_EResultUnexpectedError = 79,
- k_EResultDisabled = 80,
- k_EResultInvalidCEGSubmission = 81,
- k_EResultRestrictedDevice = 82,
- k_EResultRegionLocked = 83,
- k_EResultRateLimitExceeded = 84,
- k_EResultAccountLoginDeniedNeedTwoFactor = 85,
- k_EResultItemDeleted = 86,
- k_EResultAccountLoginDeniedThrottle = 87,
- k_EResultTwoFactorCodeMismatch = 88,
- k_EResultTwoFactorActivationCodeMismatch = 89,
- k_EResultAccountAssociatedToMultiplePartners = 90,
- k_EResultNotModified = 91,
- k_EResultNoMobileDevice = 92,
- k_EResultTimeNotSynced = 93,
- k_EResultSmsCodeFailed = 94,
- k_EResultAccountLimitExceeded = 95,
- k_EResultAccountActivityLimitExceeded = 96,
- k_EResultPhoneActivityLimitExceeded = 97,
- k_EResultRefundToWallet = 98,
- k_EResultEmailSendFailure = 99,
- k_EResultNotSettled = 100,
- k_EResultNeedCaptcha = 101,
- k_EResultGSLTDenied = 102,
- k_EResultGSOwnerDenied = 103,
- k_EResultInvalidItemType = 104,
- k_EResultIPBanned = 105,
- k_EResultGSLTExpired = 106,
- k_EResultInsufficientFunds = 107,
- k_EResultTooManyPending = 108,
- k_EResultNoSiteLicensesFound = 109,
- k_EResultWGNetworkSendExceeded = 110,
- k_EResultAccountNotFriends = 111,
- k_EResultLimitedUserAccount = 112,
- k_EResultCantRemoveItem = 113,
- k_EResultAccountDeleted = 114,
- k_EResultExistingUserCancelledLicense = 115,
- k_EResultCommunityCooldown = 116,
- k_EResultNoLauncherSpecified = 117,
- k_EResultMustAgreeToSSA = 118,
- k_EResultLauncherMigrated = 119,
- k_EResultSteamRealmMismatch = 120,
- k_EResultInvalidSignature = 121,
- k_EResultParseFailure = 122,
- k_EResultNoVerifiedPhone = 123,
-};
-
-#if defined(__linux__) || defined(__APPLE__)
-# pragma pack( push, 4 )
-#else
-# pragma pack( push, 8 )
-#endif
-
-typedef struct CallbackMsg_t CallbackMsg_t;
-struct CallbackMsg_t
-{
- HSteamUser m_hSteamUser; // Specific user to whom this callback applies.
- i32 m_iCallback; // Callback identifier. (Corresponds to the k_iCallback enum in the callback structure.)
- void *m_pubParam; // Points to the callback structure
- i32 m_cubParam; // Size of the data pointed to by m_pubParam
-};
-
-typedef struct SteamAPICallCompleted_t SteamAPICallCompleted_t;
-struct SteamAPICallCompleted_t
-{
- SteamAPICall_t m_hAsyncCall;
- i32 m_iCallback;
- u32 m_cubParam;
-};
-
-// Steam universes. Each universe is a self-contained Steam instance.
-typedef enum EUniverse EUniverse;
-enum EUniverse
-{
- k_EUniverseInvalid = 0,
- k_EUniversePublic = 1,
- k_EUniverseBeta = 2,
- k_EUniverseInternal = 3,
- k_EUniverseDev = 4,
- // k_EUniverseRC = 5, // no such universe anymore
- k_EUniverseMax
-};
-
-#pragma pack( push, 1 )
-typedef struct SteamIDComponent_t SteamIDComponent_t;
-struct SteamIDComponent_t
-{
- u32 m_unAccountID : 32;
- u32 m_unAccountInstance : 20;
- u32 m_EAccountType : 4;
- EUniverse m_EUniverse : 8;
-};
-
-typedef struct CSteamID CSteamID;
-struct CSteamID
-{
- union
- {
- SteamIDComponent_t m_comp;
- u64 m_unAll64Bits;
- };
-};
-
-typedef struct GameID_t GameID_t;
-struct GameID_t
-{
- u32 m_nAppID : 24;
- u32 m_nType : 8;
- u32 m_nModID : 32;
-};
-#pragma pack(pop)
-
-enum
-{
- k_iSteamUserCallbacks = 100,
- k_iSteamUser_SteamServersConnected = 101,
- k_iSteamUser_SteamConnectFailure = 102,
- k_iSteamUser_SteamServersDisconnected = 103,
- k_iSteamUser_EncryptedAppTicketReponse = 154,
-
- k_iSteamGameServerCallbacks = 200,
-
- k_iSteamFriendsCallbacks = 300,
- k_iSteamFriends_GameOverlayActivated = 331,
- k_iSteamFriends_PersonaStateChange = 304,
-
- k_iSteamUtilsCallbacks = 700,
- k_iSteamUtils_SteamAPICallCompleted = 703,
-
- k_iSteamUserStatsCallbacks = 1100,
- k_iSteamUserStats_UserStatsReceived = 1101,
-
- k_iSteamNetworkingCallbacks = 1200,
-
- k_iSteamNetworkingSocketsCallbacks = 1220,
- k_iSteamNetworkingSockets_SteamNetConnectionStatusChangedCallback = 1221,
- k_iSteamNetworkingSockets_SteamNetAuthenticationStatus = 1222,
-
- k_iSteamNetworkingMessagesCallbacks = 1250,
- k_iSteamNetworkingUtilsCallbacks = 1280,
-
- k_iSteamUGCCallbacks = 3400,
- k_iSteamUGC_QueryCompleted = 3401,
- k_iSteamUGC_CreateItemResult = 3403,
- k_iSteamUGC_SubmitItemUpdateResult = 3404,
-};
-
-typedef struct SteamServerConnectFailure_t SteamServerConnectFailure_t;
-struct SteamServerConnectFailure_t
-{
- EResult m_eResult;
- bool m_bStillRetrying;
-};
-
-typedef struct SteamServersDisconnected_t SteamServersDisconnected_t;
-struct SteamServersDisconnected_t
-{
- EResult m_eResult;
-};
-
-/*
- * ------------------------------------------------------------------------------------------------------------------
- * MAIN
- * ------------------------------------------------------------------------------------------------------------------
- */
-
-typedef c8 SteamErrMsg[ 1024 ];
-
-typedef enum EServerMode EServerMode;
-enum EServerMode
-{
- eServerModeInvalid = 0,
- eServerModeNoAuthentication = 1, // Don't authenticate user logins and don't list on the server list
- eServerModeAuthentication = 2, // Authenticate users, list on the server list, don't run VAC on clients that connect
- eServerModeAuthenticationAndSecure = 3, // Authenticate users, list on the server list and VAC protect clients
-};
-
-typedef enum ESteamAPIInitResult ESteamAPIInitResult;
-enum ESteamAPIInitResult
-{
- k_ESteamAPIInitResult_OK = 0,
- k_ESteamAPIInitResult_FailedGeneric = 1, // Some other failure
- k_ESteamAPIInitResult_NoSteamClient = 2, // We cannot connect to Steam, steam probably isn't running
- k_ESteamAPIInitResult_VersionMismatch = 3, // Steam client appears to be out of date
-};
-
-
-#if defined( VG_ENGINE )
-extern ESteamAPIInitResult SteamInternal_SteamAPI_Init( const char *pszInternalCheckInterfaceVersions, SteamErrMsg *pOutErrMsg );
-extern void SteamAPI_Shutdown();
-extern HSteamPipe SteamAPI_GetHSteamPipe();
-extern HSteamUser SteamAPI_GetHSteamUser();
-#else
-
-/* usLegacySteamPort must be 0 */
-
-extern ESteamAPIInitResult SteamInternal_GameServer_Init_V2(
- u32 unIP, u16 usGamePort, u16 usQueryPort, EServerMode eServerMode, const c8 *pchVersionString,
- const c8 *pszInternalCheckInterfaceVersions, SteamErrMsg *pOutErrMsg );
-
-typedef void ISteamGameServer;
-extern ISteamGameServer *SteamAPI_SteamGameServer_v015();
-extern void SteamAPI_ISteamGameServer_LogOn( ISteamGameServer *self, const c8 *pszToken );
-extern void SteamAPI_ISteamGameServer_LogOnAnonymous( ISteamGameServer *self );
-extern void SteamAPI_ISteamGameServer_LogOff( ISteamGameServer *self );
-
-extern void SteamGameServer_Shutdown();
-HSteamPipe SteamGameServer_GetHSteamPipe();
-HSteamUser SteamGameServer_GetHSteamUser();
-
-enum { k_nSteamEncryptedAppTicketSymmetricKeyLen = 32 };
-extern bool SteamEncryptedAppTicket_BDecryptTicket( const u8 *rgubTicketEncrypted, u32 cubTicketEncrypted,
- u8 *rgubTicketDecrypted, u32 *pcubTicketDecrypted,
- const u8 rgubKey[k_nSteamEncryptedAppTicketSymmetricKeyLen], i32 cubKey );
-
-extern bool SteamEncryptedAppTicket_BIsTicketForApp( u8 *rgubTicketDecrypted, u32 cubTicketDecrypted, AppId_t nAppID );
-extern u32 SteamEncryptedAppTicket_GetTicketIssueTime( u8 *rgubTicketDecrypted, u32 cubTicketDecrypted );
-extern void SteamEncryptedAppTicket_GetTicketSteamID( u8 *rgubTicketDecrypted, u32 cubTicketDecrypted, CSteamID *psteamID );
-extern AppId_t SteamEncryptedAppTicket_GetTicketAppID( u8 *rgubTicketDecrypted, u32 cubTicketDecrypted );
-extern bool SteamEncryptedAppTicket_BUserOwnsAppInTicket( u8 *rgubTicketDecrypted, u32 cubTicketDecrypted, AppId_t nAppID );
-extern bool SteamEncryptedAppTicket_BUserIsVacBanned( u8 *rgubTicketDecrypted, u32 cubTicketDecrypted );
-extern bool SteamEncryptedAppTicket_BGetAppDefinedValue( u8 *rgubTicketDecrypted, u32 cubTicketDecrypted, u32 *pValue );
-extern const u8 *SteamEncryptedAppTicket_GetUserVariableData( u8 *rgubTicketDecrypted, u32 cubTicketDecrypted, u32 *pcubUserData );
-extern bool SteamEncryptedAppTicket_BIsTicketSigned( u8 *rgubTicketDecrypted, u32 cubTicketDecrypted, const u8 *pubRSAKey, u32 cubRSAKey );
-extern bool SteamEncryptedAppTicket_BIsLicenseBorrowed( u8 *rgubTicketDecrypted, u32 cubTicketDecrypted );
-extern bool SteamEncryptedAppTicket_BIsLicenseTemporary( u8 *rgubTicketDecrypted, u32 cubTicketDecrypted );
-
-#endif
-
-/* LOOP (PUT IT THREAD 0)
- * ------------------------------------------------------------------------------------------------------------------ */
-extern void SteamAPI_ManualDispatch_Init();
-extern void SteamAPI_ManualDispatch_RunFrame( HSteamPipe hSteamPipe );
-extern bool SteamAPI_ManualDispatch_GetNextCallback( HSteamPipe hSteamPipe, CallbackMsg_t *pCallbackMsg );
-extern void SteamAPI_ManualDispatch_FreeLastCallback( HSteamPipe hSteamPipe );
-extern bool SteamAPI_ManualDispatch_GetAPICallResult( HSteamPipe hSteamPipe, SteamAPICall_t hSteamAPICall,
- void *pCallback, i32 cubCallback, i32 iCallbackExpected, bool *pbFailed );
-
-/*
- * ------------------------------------------------------------------------------------------------------------------
- * ISteamFriends
- * ------------------------------------------------------------------------------------------------------------------
- */
-#if defined( VG_ENGINE )
-
-typedef void ISteamFriends;
-extern ISteamFriends *SteamAPI_SteamFriends_v018();
-
-typedef enum EActivateGameOverlayToWebPageMode EActivateGameOverlayToWebPageMode;
-enum EActivateGameOverlayToWebPageMode
-{
- k_EActivateGameOverlayToWebPageMode_Default = 0,
- k_EActivateGameOverlayToWebPageMode_Modal = 1
-};
-extern void SteamAPI_ISteamFriends_ActivateGameOverlayToWebPage( ISteamFriends *self, const c8 *pchURL,
- EActivateGameOverlayToWebPageMode eMode );
-
-void SteamFriends_ActivateGameOverlayToWebPage( const c8 *pchURL, EActivateGameOverlayToWebPageMode eMode );
-
-typedef enum EOverlayToStoreFlag EOverlayToStoreFlag;
-enum EOverlayToStoreFlag
-{
- k_EOverlayToStoreFlag_None = 0,
- k_EOverlayToStoreFlag_AddToCart = 1,
- k_EOverlayToStoreFlag_AddToCartAndShow = 2,
-};
-extern void SteamAPI_ISteamFriends_ActivateGameOverlayToStore( ISteamFriends *self, AppId_t nAppID, EOverlayToStoreFlag eFlag );
-
-extern i32 SteamAPI_ISteamFriends_GetSmallFriendAvatar( ISteamFriends *self, uint64_steamid steamIDFriend );
-extern i32 SteamAPI_ISteamFriends_GetMediumFriendAvatar( ISteamFriends *self, uint64_steamid steamIDFriend );
-extern i32 SteamAPI_ISteamFriends_GetLargeFriendAvatar( ISteamFriends *self, uint64_steamid steamIDFriend );
-extern const c8 *SteamAPI_ISteamFriends_GetPersonaName( ISteamFriends *self );
-
-typedef struct GameOverlayActivated_t GameOverlayActivated_t;
-struct GameOverlayActivated_t
-{
- bool m_bActive;
-};
-
-typedef struct PersonaStateChange_t PersonaStateChange_t;
-struct PersonaStateChange_t
-{
- u64 m_ulSteamID; // steamID of the friend who changed
- int m_nChangeFlags; // what's changed
-};
-
-typedef enum EPersonaChange EPersonaChange;
-enum EPersonaChange
-{
- k_EPersonaChangeName = 0x0001,
- k_EPersonaChangeStatus = 0x0002,
- k_EPersonaChangeComeOnline = 0x0004,
- k_EPersonaChangeGoneOffline = 0x0008,
- k_EPersonaChangeGamePlayed = 0x0010,
- k_EPersonaChangeGameServer = 0x0020,
- k_EPersonaChangeAvatar = 0x0040,
- k_EPersonaChangeJoinedSource= 0x0080,
- k_EPersonaChangeLeftSource = 0x0100,
- k_EPersonaChangeRelationshipChanged = 0x0200,
- k_EPersonaChangeNameFirstSet = 0x0400,
- k_EPersonaChangeBroadcast = 0x0800,
- k_EPersonaChangeNickname = 0x1000,
- k_EPersonaChangeSteamLevel = 0x2000,
- k_EPersonaChangeRichPresence = 0x4000,
-};
-
-typedef enum EFriendFlags EFriendFlags;
-enum EFriendFlags
-{
- k_EFriendFlagNone = 0x00,
- k_EFriendFlagBlocked = 0x01,
- k_EFriendFlagFriendshipRequested = 0x02,
- k_EFriendFlagImmediate = 0x04, // "regular" friend
- k_EFriendFlagClanMember = 0x08,
- k_EFriendFlagOnGameServer = 0x10,
- // k_EFriendFlagHasPlayedWith = 0x20, // not currently used
- // k_EFriendFlagFriendOfFriend = 0x40, // not currently used
- k_EFriendFlagRequestingFriendship = 0x80,
- k_EFriendFlagRequestingInfo = 0x100,
- k_EFriendFlagIgnored = 0x200,
- k_EFriendFlagIgnoredFriend = 0x400,
- // k_EFriendFlagSuggested = 0x800, // not used
- k_EFriendFlagChatMember = 0x1000,
- k_EFriendFlagAll = 0xFFFF,
-};
-extern bool SteamAPI_ISteamFriends_HasFriend( ISteamFriends *self, uint64_steamid steamIDFriend, i32 iFriendFlags );
-
-#endif
-
-/*
- * ------------------------------------------------------------------------------------------------------------------
- * ISteamUGC
- * ------------------------------------------------------------------------------------------------------------------
- */
-
-typedef void ISteamUGC;
-typedef u64 PublishedFileId_t;
-typedef u64 UGCQueryHandle_t;
-typedef u64 UGCUpdateHandle_t;
-typedef u64 UGCHandle_t;
-typedef u64 PublishedFileUpdateHandle_t;
-
-typedef enum EItemUpdateStatus EItemUpdateStatus;
-enum EItemUpdateStatus
-{
- k_EItemUpdateStatusInvalid = 0,
- k_EItemUpdateStatusPreparingConfig = 1,
- k_EItemUpdateStatusPreparingContent = 2,
- k_EItemUpdateStatusUploadingContent = 3,
- k_EItemUpdateStatusUploadingPreviewFile= 4,
- k_EItemUpdateStatusCommittingChanges = 5
-};
-
-typedef enum EItemState EItemState;
-enum EItemState
-{
- k_EItemStateNone = 0,
- k_EItemStateSubscribed = 1,
- k_EItemStateLegacyItem = 2,
- k_EItemStateInstalled = 4,
- k_EItemStateNeedsUpdate = 8,
- k_EItemStateDownloading = 16,
- k_EItemStateDownloadPending= 32,
- k_EItemStateDisabledLocally = 64,
-};
-
-typedef enum EWorkshopFileType EWorkshopFileType;
-enum EWorkshopFileType
-{
- k_EWorkshopFileTypeFirst = 0,
- k_EWorkshopFileTypeCommunity = 0,
- k_EWorkshopFileTypeMicrotransaction = 1,
- k_EWorkshopFileTypeCollection = 2,
- k_EWorkshopFileTypeArt = 3,
- k_EWorkshopFileTypeVideo = 4,
- k_EWorkshopFileTypeScreenshot = 5,
- k_EWorkshopFileTypeGame = 6,
- k_EWorkshopFileTypeSoftware = 7,
- k_EWorkshopFileTypeConcept = 8,
- k_EWorkshopFileTypeWebGuide = 9,
- k_EWorkshopFileTypeIntegratedGuide = 10,
- k_EWorkshopFileTypeMerch = 11,
- k_EWorkshopFileTypeControllerBinding = 12,
- k_EWorkshopFileTypeSteamworksAccessInvite = 13,
- k_EWorkshopFileTypeSteamVideo = 14,
- k_EWorkshopFileTypeGameManagedItem = 15,
- k_EWorkshopFileTypeMax = 16
-};
-
-typedef enum ERemoteStoragePublishedFileVisibility ERemoteStoragePublishedFileVisibility;
-enum ERemoteStoragePublishedFileVisibility
-{
- k_ERemoteStoragePublishedFileVisibilityPublic = 0,
- k_ERemoteStoragePublishedFileVisibilityFriendsOnly = 1,
- k_ERemoteStoragePublishedFileVisibilityPrivate = 2,
- k_ERemoteStoragePublishedFileVisibilityUnlisted = 3,
-};
-
-typedef enum EUGCMatchingUGCType EUGCMatchingUGCType;
-enum EUGCMatchingUGCType
-{
- k_EUGCMatchingUGCType_Items = 0,
- k_EUGCMatchingUGCType_Items_Mtx = 1,
- k_EUGCMatchingUGCType_Items_ReadyToUse = 2,
- k_EUGCMatchingUGCType_Collections = 3,
- k_EUGCMatchingUGCType_Artwork = 4,
- k_EUGCMatchingUGCType_Videos = 5,
- k_EUGCMatchingUGCType_Screenshots = 6,
- k_EUGCMatchingUGCType_AllGuides = 7,
- k_EUGCMatchingUGCType_WebGuides = 8,
- k_EUGCMatchingUGCType_IntegratedGuides = 9,
- k_EUGCMatchingUGCType_UsableInGame = 10,
- k_EUGCMatchingUGCType_ControllerBindings = 11,
- k_EUGCMatchingUGCType_GameManagedItems = 12,
- k_EUGCMatchingUGCType_All = ~0,
-};
-
-typedef enum EUserUGCList EUserUGCList;
-enum EUserUGCList
-{
- k_EUserUGCList_Published,
- k_EUserUGCList_VotedOn,
- k_EUserUGCList_VotedUp,
- k_EUserUGCList_VotedDown,
- k_EUserUGCList_WillVoteLater,
- k_EUserUGCList_Favorited,
- k_EUserUGCList_Subscribed,
- k_EUserUGCList_UsedOrPlayed,
- k_EUserUGCList_Followed,
-};
-
-// Sort order for user published UGC lists (defaults to creation order descending)
-typedef enum EUserUGCListSortOrder EUserUGCListSortOrder;
-enum EUserUGCListSortOrder
-{
- k_EUserUGCListSortOrder_CreationOrderDesc,
- k_EUserUGCListSortOrder_CreationOrderAsc,
- k_EUserUGCListSortOrder_TitleAsc,
- k_EUserUGCListSortOrder_LastUpdatedDesc,
- k_EUserUGCListSortOrder_SubscriptionDateDesc,
- k_EUserUGCListSortOrder_VoteScoreDesc,
- k_EUserUGCListSortOrder_ForModeration,
-};
-
-// Combination of sorting and filtering for queries across all UGC
-typedef enum EUGCQuery EUGCQuery;
-enum EUGCQuery
-{
- k_EUGCQuery_RankedByVote = 0,
- k_EUGCQuery_RankedByPublicationDate = 1,
- k_EUGCQuery_AcceptedForGameRankedByAcceptanceDate = 2,
- k_EUGCQuery_RankedByTrend = 3,
- k_EUGCQuery_FavoritedByFriendsRankedByPublicationDate = 4,
- k_EUGCQuery_CreatedByFriendsRankedByPublicationDate = 5,
- k_EUGCQuery_RankedByNumTimesReported = 6,
- k_EUGCQuery_CreatedByFollowedUsersRankedByPublicationDate = 7,
- k_EUGCQuery_NotYetRated = 8,
- k_EUGCQuery_RankedByTotalVotesAsc = 9,
- k_EUGCQuery_RankedByVotesUp = 10,
- k_EUGCQuery_RankedByTextSearch = 11,
- k_EUGCQuery_RankedByTotalUniqueSubscriptions = 12,
- k_EUGCQuery_RankedByPlaytimeTrend = 13,
- k_EUGCQuery_RankedByTotalPlaytime = 14,
- k_EUGCQuery_RankedByAveragePlaytimeTrend = 15,
- k_EUGCQuery_RankedByLifetimeAveragePlaytime = 16,
- k_EUGCQuery_RankedByPlaytimeSessionsTrend = 17,
- k_EUGCQuery_RankedByLifetimePlaytimeSessions = 18,
- k_EUGCQuery_RankedByLastUpdatedDate = 19,
-};
-
-typedef struct SteamUGCDetails_t SteamUGCDetails_t;
-struct SteamUGCDetails_t
-{
- PublishedFileId_t m_nPublishedFileId;
- EResult m_eResult;
- EWorkshopFileType m_eFileType;
- AppId_t m_nCreatorAppID;
- AppId_t m_nConsumerAppID;
- c8 m_rgchTitle[ 128+1 ];
- c8 m_rgchDescription[ 8000 ];
- u64 m_ulSteamIDOwner;
- u32 m_rtimeCreated;
- u32 m_rtimeUpdated;
- u32 m_rtimeAddedToUserList;
- ERemoteStoragePublishedFileVisibility m_eVisibility;
- bool m_bBanned;
- bool m_bAcceptedForUse;
- bool m_bTagsTruncated;
- c8 m_rgchTags[ 1024 + 1 ];
- UGCHandle_t m_hFile;
- UGCHandle_t m_hPreviewFile;
- c8 m_pchFileName[ 260 ];
- i32 m_nFileSize;
- i32 m_nPreviewFileSize;
- c8 m_rgchURL[ 256 ];
- u32 m_unVotesUp;
- u32 m_unVotesDown;
- f32 m_flScore;
- u32 m_unNumChildren;
-};
-
-typedef struct CreateItemResult_t CreateItemResult_t;
-struct CreateItemResult_t
-{
- EResult m_eResult;
- PublishedFileId_t m_nPublishedFileId;
- bool m_bUserNeedsToAcceptWorkshopLegalAgreement;
-};
-
-typedef struct SubmitItemUpdateResult_t SubmitItemUpdateResult_t;
-struct SubmitItemUpdateResult_t
-{
- EResult m_eResult;
- bool m_bUserNeedsToAcceptWorkshopLegalAgreement;
- PublishedFileId_t m_nPublishedFileId;
-};
-
-typedef struct SteamUGCQueryCompleted_t SteamUGCQueryCompleted_t;
-struct SteamUGCQueryCompleted_t
-{
- UGCQueryHandle_t m_handle;
- EResult m_eResult;
- u32 m_unNumResultsReturned;
- u32 m_unTotalMatchingResults;
- bool m_bCachedData;
- c8 m_rgchNextCursor[256];
-};
-
-#if defined( VG_ENGINE )
-extern ISteamUGC *SteamAPI_SteamUGC_v021();
-#else
-extern ISteamUGC *SteamAPI_SteamGameServerUGC_v021();
-#endif
-extern SteamAPICall_t SteamAPI_ISteamUGC_CreateItem( ISteamUGC *self, AppId_t nConsumerAppId,
- EWorkshopFileType eFileType );
-
-extern bool SteamAPI_ISteamUGC_GetItemInstallInfo( ISteamUGC *self, PublishedFileId_t nPublishedFileID,
- u64 *punSizeOnDisk, c8 *pchFolder, u32 cchFolderSize,
- u32 *punTimeStamp );
-
-extern u32 SteamAPI_ISteamUGC_GetItemState( ISteamUGC *self, PublishedFileId_t nPublishedFileID );
-
-extern bool SteamAPI_ISteamUGC_GetQueryUGCMetadata( ISteamUGC *self, UGCQueryHandle_t handle, u32 index,
- c8 *pchMetadata, u32 cchMetadatasize );
-
-extern bool SteamAPI_ISteamUGC_GetQueryUGCResult( ISteamUGC *self, UGCQueryHandle_t handle, u32 index,
- SteamUGCDetails_t *pDetails );
-
-extern u32 SteamAPI_ISteamUGC_GetSubscribedItems( ISteamUGC *self, PublishedFileId_t *pvecPublishedFileID,
- u32 cMaxEntries, bool bIncludeLocallyDisabled );
-
-extern bool SteamAPI_ISteamUGC_ReleaseQueryUGCRequest( ISteamUGC *self, UGCQueryHandle_t handle );
-extern SteamAPICall_t SteamAPI_ISteamUGC_SendQueryUGCRequest( ISteamUGC *self, UGCQueryHandle_t handle );
-extern bool SteamAPI_ISteamUGC_SetItemContent( ISteamUGC *self, UGCUpdateHandle_t handle, const c8 *pszContentFolder );
-extern bool SteamAPI_ISteamUGC_SetItemDescription( ISteamUGC *self, UGCUpdateHandle_t handle, const c8 *pchDescription );
-extern bool SteamAPI_ISteamUGC_SetItemMetadata( ISteamUGC *self, UGCUpdateHandle_t handle, const c8 *pchMetaData );
-extern bool SteamAPI_ISteamUGC_SetItemPreview( ISteamUGC *self, UGCUpdateHandle_t handle, const c8 *pszPreviewFile );
-extern bool SteamAPI_ISteamUGC_SetItemTitle( ISteamUGC *self, UGCUpdateHandle_t handle, const c8 *pchTitle );
-
-extern bool SteamAPI_ISteamUGC_SetItemVisibility( ISteamUGC *self, UGCUpdateHandle_t handle,
- ERemoteStoragePublishedFileVisibility eVisibility );
-
-extern bool SteamAPI_ISteamUGC_SetReturnMetadata( ISteamUGC *self, UGCQueryHandle_t handle, bool bReturnMetadata );
-
-extern UGCUpdateHandle_t SteamAPI_ISteamUGC_StartItemUpdate( ISteamUGC *self, AppId_t nConsumerAppId,
- PublishedFileId_t nPublishedFileID );
-
-extern SteamAPICall_t SteamAPI_ISteamUGC_SubmitItemUpdate( ISteamUGC *self, UGCUpdateHandle_t handle,
- const c8* pchChangeNote );
-
-extern UGCQueryHandle_t SteamAPI_ISteamUGC_CreateQueryUserUGCRequest(
- ISteamUGC *self, AccountID_t unAccountID, EUserUGCList eListType,
- EUGCMatchingUGCType eMatchingUGCType, EUserUGCListSortOrder eSortOrder,
- AppId_t nCreatorAppID, AppId_t nConsumerAppID, u32 unPage );
-/*
- * ------------------------------------------------------------------------------------------------------------------
- * ISteamNetworkingSockets
- * ------------------------------------------------------------------------------------------------------------------
- */
-
-typedef void ISteamNetworkingSockets;
-typedef u32 HSteamNetConnection;
-typedef u32 HSteamListenSocket;
-typedef u32 HSteamNetPollGroup;
-typedef i64 SteamNetworkingMicroseconds;
-
-#pragma pack(push,1)
-typedef struct SteamNetworkingIPAddr SteamNetworkingIPAddr;
-struct SteamNetworkingIPAddr
-{
- union
- {
- u8 m_ipv6[ 16 ];
-
- /* RFC4038, section 4.2 */
- struct IPv4MappedAddress
- {
- u64 m_8zeros;
- u16 m_0000;
- u16 m_ffff;
- u8 m_ip[ 4 ]; /* NOTE: As bytes, i.e. network byte order */
- }
- m_ipv4;
- };
-
- u16 m_port; // Host byte order
-};
-
-typedef enum ESteamNetworkingIdentityType ESteamNetworkingIdentityType;
-enum ESteamNetworkingIdentityType
-{
- k_ESteamNetworkingIdentityType_Invalid = 0,
- k_ESteamNetworkingIdentityType_SteamID = 16, // 64-bit CSteamID
- k_ESteamNetworkingIdentityType_IPAddress = 1,
- k_ESteamNetworkingIdentityType_GenericString = 2,
- k_ESteamNetworkingIdentityType_GenericBytes = 3,
- k_ESteamNetworkingIdentityType_UnknownType = 4,
- k_ESteamNetworkingIdentityType__Force32bit = 0x7fffffff,
-};
-
-typedef struct SteamNetworkingIdentity SteamNetworkingIdentity;
-struct SteamNetworkingIdentity
-{
- ESteamNetworkingIdentityType m_eType;
-
- i32 m_cbSize;
- union
- {
- u64 m_steamID64;
- c8 m_szGenericString[ 32 ];
- u8 m_genericBytes[ 32 ];
- c8 m_szUnknownRawString[ 128 ];
- SteamNetworkingIPAddr m_ip;
- u32 m_reserved[ 32 ];
- };
-};
-#pragma pack(pop)
-
-typedef enum ESteamNetworkingConfigValue ESteamNetworkingConfigValue;
-enum ESteamNetworkingConfigValue
-{
- k_ESteamNetworkingConfig_Invalid = 0,
- k_ESteamNetworkingConfig_TimeoutInitial = 24,
- k_ESteamNetworkingConfig_TimeoutConnected = 25,
- k_ESteamNetworkingConfig_SendBufferSize = 9,
- k_ESteamNetworkingConfig_ConnectionUserData = 40,
- k_ESteamNetworkingConfig_SendRateMin = 10,
- k_ESteamNetworkingConfig_SendRateMax = 11,
- k_ESteamNetworkingConfig_NagleTime = 12,
- k_ESteamNetworkingConfig_IP_AllowWithoutAuth = 23,
- k_ESteamNetworkingConfig_MTU_PacketSize = 32,
- k_ESteamNetworkingConfig_MTU_DataSize = 33,
- k_ESteamNetworkingConfig_Unencrypted = 34,
- k_ESteamNetworkingConfig_LocalVirtualPort = 38,
- k_ESteamNetworkingConfig_DualWifi_Enable = 39,
- k_ESteamNetworkingConfig_EnableDiagnosticsUI = 46,
- k_ESteamNetworkingConfig_FakePacketLoss_Send = 2,
- k_ESteamNetworkingConfig_FakePacketLoss_Recv = 3,
- k_ESteamNetworkingConfig_FakePacketLag_Send = 4,
- k_ESteamNetworkingConfig_FakePacketLag_Recv = 5,
- k_ESteamNetworkingConfig_FakePacketReorder_Send = 6,
- k_ESteamNetworkingConfig_FakePacketReorder_Recv = 7,
- k_ESteamNetworkingConfig_FakePacketReorder_Time = 8,
- k_ESteamNetworkingConfig_FakePacketDup_Send = 26,
- k_ESteamNetworkingConfig_FakePacketDup_Recv = 27,
- k_ESteamNetworkingConfig_FakePacketDup_TimeMax = 28,
- k_ESteamNetworkingConfig_PacketTraceMaxBytes = 41,
- k_ESteamNetworkingConfig_FakeRateLimit_Send_Rate = 42,
- k_ESteamNetworkingConfig_FakeRateLimit_Send_Burst = 43,
- k_ESteamNetworkingConfig_FakeRateLimit_Recv_Rate = 44,
- k_ESteamNetworkingConfig_FakeRateLimit_Recv_Burst = 45,
- k_ESteamNetworkingConfig_Callback_ConnectionStatusChanged = 201,
- k_ESteamNetworkingConfig_Callback_AuthStatusChanged = 202,
- k_ESteamNetworkingConfig_Callback_RelayNetworkStatusChanged = 203,
- k_ESteamNetworkingConfig_Callback_MessagesSessionRequest = 204,
- k_ESteamNetworkingConfig_Callback_MessagesSessionFailed = 205,
- k_ESteamNetworkingConfig_Callback_CreateConnectionSignaling = 206,
- k_ESteamNetworkingConfig_Callback_FakeIPResult = 207,
- k_ESteamNetworkingConfig_P2P_STUN_ServerList = 103,
- k_ESteamNetworkingConfig_P2P_Transport_ICE_Enable = 104,
- k_ESteamNetworkingConfig_P2P_Transport_ICE_Penalty = 105,
- k_ESteamNetworkingConfig_P2P_Transport_SDR_Penalty = 106,
- k_ESteamNetworkingConfig_SDRClient_ConsecutitivePingTimeoutsFailInitial = 19,
- k_ESteamNetworkingConfig_SDRClient_ConsecutitivePingTimeoutsFail = 20,
- k_ESteamNetworkingConfig_SDRClient_MinPingsBeforePingAccurate = 21,
- k_ESteamNetworkingConfig_SDRClient_SingleSocket = 22,
- k_ESteamNetworkingConfig_SDRClient_ForceRelayCluster = 29,
- k_ESteamNetworkingConfig_SDRClient_DebugTicketAddress = 30,
- k_ESteamNetworkingConfig_SDRClient_ForceProxyAddr = 31,
- k_ESteamNetworkingConfig_SDRClient_FakeClusterPing = 36,
- k_ESteamNetworkingConfig_LogLevel_AckRTT = 13, // [connection int32] RTT calculations for inline pings and replies
- k_ESteamNetworkingConfig_LogLevel_PacketDecode = 14, // [connection int32] log SNP packets send/recv
- k_ESteamNetworkingConfig_LogLevel_Message = 15, // [connection int32] log each message send/recv
- k_ESteamNetworkingConfig_LogLevel_PacketGaps = 16, // [connection int32] dropped packets
- k_ESteamNetworkingConfig_LogLevel_P2PRendezvous = 17, // [connection int32] P2P rendezvous messages
- k_ESteamNetworkingConfig_LogLevel_SDRRelayPings = 18, // [global int32] Ping relays
- k_ESteamNetworkingConfig_DELETED_EnumerateDevVars = 35,
- k_ESteamNetworkingConfigValue__Force32Bit = 0x7fffffff
-};
-
-typedef enum ESteamNetworkingConfigDataType ESteamNetworkingConfigDataType;
-enum ESteamNetworkingConfigDataType
-{
- k_ESteamNetworkingConfig_Int32 = 1,
- k_ESteamNetworkingConfig_Int64 = 2,
- k_ESteamNetworkingConfig_Float = 3,
- k_ESteamNetworkingConfig_String = 4,
- k_ESteamNetworkingConfig_Ptr = 5,
- k_ESteamNetworkingConfigDataType__Force32Bit = 0x7fffffff
-};
-
-#pragma pack(push,8)
-typedef struct SteamNetworkingConfigValue_t SteamNetworkingConfigValue_t;
-struct SteamNetworkingConfigValue_t
-{
- ESteamNetworkingConfigValue m_eValue;
- ESteamNetworkingConfigDataType m_eDataType;
-
- /// Option value
- union
- {
- i32 m_int32;
- i64 m_int64;
- f32 m_float;
- const c8 *m_string; // Points to your '\0'-terminated buffer
- void *m_ptr;
- }
- m_val;
-};
-
-typedef struct SteamNetworkingMessage_t SteamNetworkingMessage_t;
-struct SteamNetworkingMessage_t
-{
- void *m_pData;
- i32 m_cbSize;
- HSteamNetConnection m_conn;
- SteamNetworkingIdentity m_identityPeer;
- i64 m_nConnUserData;
- SteamNetworkingMicroseconds m_usecTimeReceived;
- i64 m_nMessageNumber;
- void (*m_pfnFreeData)( SteamNetworkingMessage_t *pMsg );
- void (*m_pfnRelease)( SteamNetworkingMessage_t *pMsg );
- i32 m_nChannel;
- i32 m_nFlags;
- i64 m_nUserData;
- u16 m_idxLane;
- u16 _pad1__;
-};
-#pragma pack(pop)
-
-#if defined( VG_ENGINE )
-extern ISteamNetworkingSockets *SteamAPI_SteamNetworkingSockets_SteamAPI_v012();
-#else
-extern ISteamNetworkingSockets *SteamAPI_SteamGameServerNetworkingSockets_SteamAPI_v012();
-#endif
-
-extern EResult SteamAPI_ISteamNetworkingSockets_AcceptConnection( ISteamNetworkingSockets *self, HSteamNetConnection hConn );
-extern bool SteamAPI_ISteamNetworkingSockets_CloseConnection( ISteamNetworkingSockets *self, HSteamNetConnection hPeer,
- i32 nReason, const c8 *pszDebug, bool bEnableLinger );
-
-extern bool SteamAPI_ISteamNetworkingSockets_CloseListenSocket( ISteamNetworkingSockets *self, HSteamListenSocket hSocket );
-extern EResult SteamAPI_ISteamNetworkingSockets_ConfigureConnectionLanes(
- ISteamNetworkingSockets *self, HSteamNetConnection hConn, i32 nNumLanes, const i32 *pLanePriorities,
- const u16 *pLaneWeights );
-
-extern HSteamNetConnection SteamAPI_ISteamNetworkingSockets_ConnectByIPAddress(
- ISteamNetworkingSockets *self,
- SteamNetworkingIPAddr *address, i32 nOptions,
- SteamNetworkingConfigValue_t *pOptions );
-
-extern HSteamListenSocket SteamAPI_ISteamNetworkingSockets_CreateListenSocketIP(
- ISteamNetworkingSockets *self, SteamNetworkingIPAddr *localAddress,
- i32 nOptions, const SteamNetworkingConfigValue_t *pOptions );
-
-extern HSteamNetPollGroup SteamAPI_ISteamNetworkingSockets_CreatePollGroup( ISteamNetworkingSockets *self );
-extern bool SteamAPI_ISteamNetworkingSockets_DestroyPollGroup(
- ISteamNetworkingSockets *self, HSteamNetPollGroup hPollGroup );
-
-extern i64 SteamAPI_ISteamNetworkingSockets_GetConnectionUserData(
- ISteamNetworkingSockets *self, HSteamNetConnection hPeer );
-
-extern i32 SteamAPI_ISteamNetworkingSockets_ReceiveMessagesOnConnection(
- ISteamNetworkingSockets *self, HSteamNetConnection hConn,
- SteamNetworkingMessage_t **ppOutMessages, i32 nMaxMessages );
-extern i32 SteamAPI_ISteamNetworkingSockets_ReceiveMessagesOnPollGroup(
- ISteamNetworkingSockets *self, HSteamNetPollGroup hPollGroup,
- SteamNetworkingMessage_t **ppOutMessages, i32 nMaxMessages );
-
-enum
-{
- k_nSteamNetworkingSend_Unreliable = 0,
- k_nSteamNetworkingSend_NoNagle = 1,
- k_nSteamNetworkingSend_UnreliableNoNagle = k_nSteamNetworkingSend_Unreliable|k_nSteamNetworkingSend_NoNagle,
- k_nSteamNetworkingSend_NoDelay = 4,
- k_nSteamNetworkingSend_UnreliableNoDelay = k_nSteamNetworkingSend_Unreliable|k_nSteamNetworkingSend_NoDelay|
- k_nSteamNetworkingSend_NoNagle,
- k_nSteamNetworkingSend_Reliable = 8,
- k_nSteamNetworkingSend_ReliableNoNagle = k_nSteamNetworkingSend_Reliable|k_nSteamNetworkingSend_NoNagle,
- k_nSteamNetworkingSend_UseCurrentThread = 16,
- k_nSteamNetworkingSend_AutoRestartBrokenSession = 32
-};
-
-extern void SteamAPI_ISteamNetworkingSockets_SendMessages(
- ISteamNetworkingSockets *self, i32 nMessages,
- SteamNetworkingMessage_t *const *pMessages, i64 *pOutMessageNumberOrResult );
-
-extern EResult SteamAPI_ISteamNetworkingSockets_SendMessageToConnection(
- ISteamNetworkingSockets *self, HSteamNetConnection hConn, const void *pData,
- u32 cbData, i32 nSendFlags, i64 *pOutMessageNumber );
-
-extern bool SteamAPI_ISteamNetworkingSockets_SetConnectionPollGroup(
- ISteamNetworkingSockets *self, HSteamNetConnection hConn, HSteamNetPollGroup hPollGroup );
-extern bool SteamAPI_ISteamNetworkingSockets_SetConnectionUserData(
- ISteamNetworkingSockets *self, HSteamNetConnection hPeer, i64 nUserData );
-
-typedef enum ESteamNetworkingConnectionState ESteamNetworkingConnectionState;
-enum ESteamNetworkingConnectionState
-{
- k_ESteamNetworkingConnectionState_None = 0,
- k_ESteamNetworkingConnectionState_Connecting = 1,
- k_ESteamNetworkingConnectionState_FindingRoute = 2,
- k_ESteamNetworkingConnectionState_Connected = 3,
- k_ESteamNetworkingConnectionState_ClosedByPeer = 4,
- k_ESteamNetworkingConnectionState_ProblemDetectedLocally = 5,
- k_ESteamNetworkingConnectionState_FinWait = -1,
- k_ESteamNetworkingConnectionState_Linger = -2,
- k_ESteamNetworkingConnectionState_Dead = -3,
- k_ESteamNetworkingConnectionState__Force32Bit = 0x7fffffff
-};
-
-/// Enumerate various causes of connection termination. These are designed to work similar
-/// to HTTP error codes: the numeric range gives you a rough classification as to the source
-/// of the problem.
-typedef enum ESteamNetConnectionEnd ESteamNetConnectionEnd;
-enum ESteamNetConnectionEnd
-{
- // Invalid/sentinel value
- k_ESteamNetConnectionEnd_Invalid = 0,
- k_ESteamNetConnectionEnd_App_Min = 1000,
- k_ESteamNetConnectionEnd_App_Generic = k_ESteamNetConnectionEnd_App_Min,
- k_ESteamNetConnectionEnd_App_Max = 1999,
- k_ESteamNetConnectionEnd_AppException_Min = 2000,
- k_ESteamNetConnectionEnd_AppException_Generic = k_ESteamNetConnectionEnd_AppException_Min,
- k_ESteamNetConnectionEnd_AppException_Max = 2999,
- k_ESteamNetConnectionEnd_Local_Min = 3000,
- k_ESteamNetConnectionEnd_Local_OfflineMode = 3001,
- k_ESteamNetConnectionEnd_Local_ManyRelayConnectivity = 3002,
- k_ESteamNetConnectionEnd_Local_HostedServerPrimaryRelay = 3003,
- k_ESteamNetConnectionEnd_Local_NetworkConfig = 3004,
- k_ESteamNetConnectionEnd_Local_Rights = 3005,
- k_ESteamNetConnectionEnd_Local_P2P_ICE_NoPublicAddresses = 3006,
- k_ESteamNetConnectionEnd_Local_Max = 3999,
- k_ESteamNetConnectionEnd_Remote_Min = 4000,
- k_ESteamNetConnectionEnd_Remote_Timeout = 4001,
- k_ESteamNetConnectionEnd_Remote_BadCrypt = 4002,
- k_ESteamNetConnectionEnd_Remote_BadCert = 4003,
- k_ESteamNetConnectionEnd_Remote_BadProtocolVersion = 4006,
- k_ESteamNetConnectionEnd_Remote_P2P_ICE_NoPublicAddresses = 4007,
- k_ESteamNetConnectionEnd_Remote_Max = 4999,
- k_ESteamNetConnectionEnd_Misc_Min = 5000,
- k_ESteamNetConnectionEnd_Misc_Generic = 5001,
- k_ESteamNetConnectionEnd_Misc_InternalError = 5002,
- k_ESteamNetConnectionEnd_Misc_Timeout = 5003,
- k_ESteamNetConnectionEnd_Misc_SteamConnectivity = 5005,
- k_ESteamNetConnectionEnd_Misc_NoRelaySessionsToClient = 5006,
- k_ESteamNetConnectionEnd_Misc_P2P_Rendezvous = 5008,
- k_ESteamNetConnectionEnd_Misc_P2P_NAT_Firewall = 5009,
- k_ESteamNetConnectionEnd_Misc_PeerSentNoConnection = 5010,
- k_ESteamNetConnectionEnd_Misc_Max = 5999,
- k_ESteamNetConnectionEnd__Force32Bit = 0x7fffffff
-};
-
-typedef enum ESteamNetworkingAvailability ESteamNetworkingAvailability;
-enum ESteamNetworkingAvailability
-{
- k_ESteamNetworkingAvailability_CannotTry = -102,
- k_ESteamNetworkingAvailability_Failed = -101,
- k_ESteamNetworkingAvailability_Previously = -100,
- k_ESteamNetworkingAvailability_Retrying = -10,
- k_ESteamNetworkingAvailability_NeverTried = 1,
- k_ESteamNetworkingAvailability_Waiting = 2,
- k_ESteamNetworkingAvailability_Attempting = 3,
- k_ESteamNetworkingAvailability_Current = 100,
- k_ESteamNetworkingAvailability_Unknown = 0,
- k_ESteamNetworkingAvailability__Force32bit = 0x7fffffff,
-};
-
-typedef struct SteamNetConnectionInfo_t SteamNetConnectionInfo_t;
-struct SteamNetConnectionInfo_t
-{
- SteamNetworkingIdentity m_identityRemote;
- i64 m_nUserData;
- HSteamListenSocket m_hListenSocket;
- SteamNetworkingIPAddr m_addrRemote;
- u16 m__pad1;
- SteamNetworkingPOPID m_idPOPRemote;
- SteamNetworkingPOPID m_idPOPRelay;
- ESteamNetworkingConnectionState m_eState;
- i32 m_eEndReason;
- c8 m_szEndDebug[ 128 ];
- c8 m_szConnectionDescription[ 128 ];
- i32 m_nFlags;
- u32 reserved[63];
-};
-
-typedef struct SteamNetConnectionStatusChangedCallback_t SteamNetConnectionStatusChangedCallback_t;
-struct SteamNetConnectionStatusChangedCallback_t
-{
- HSteamNetConnection m_hConn;
- SteamNetConnectionInfo_t m_info;
- ESteamNetworkingConnectionState m_eOldState;
-};
-
-typedef struct SteamNetAuthenticationStatus_t SteamNetAuthenticationStatus_t;
-struct SteamNetAuthenticationStatus_t
-{
- ESteamNetworkingAvailability m_eAvail;
- c8 m_debugMsg[ 256 ];
-};
-
-
-/*
- * ------------------------------------------------------------------------------------------------------------------
- * ISteamNetworkingUtils
- * ------------------------------------------------------------------------------------------------------------------
- */
-
-typedef void ISteamNetworkingUtils;
-extern ISteamNetworkingUtils *SteamAPI_SteamNetworkingUtils_SteamAPI_v004();
-extern SteamNetworkingMessage_t *SteamAPI_ISteamNetworkingUtils_AllocateMessage(
- ISteamNetworkingUtils *self, i32 cbAllocateBuffer );
-
-
-/*
- * ------------------------------------------------------------------------------------------------------------------
- * ISteamUser
- * ------------------------------------------------------------------------------------------------------------------
- */
-#if defined( VG_ENGINE )
-typedef void ISteamUser;
-extern ISteamUser *SteamAPI_SteamUser_v023();
-extern bool SteamAPI_ISteamUser_GetEncryptedAppTicket( ISteamUser *self, void *pTicket, i32 cbMaxTicket, u32 *pcbTicket );
-extern uint64_steamid SteamAPI_ISteamUser_GetSteamID( ISteamUser *self );
-extern SteamAPICall_t SteamAPI_ISteamUser_RequestEncryptedAppTicket( ISteamUser *self, void *pDataToInclude, i32 cbDataToInclude );
-
-typedef struct EncryptedAppTicketResponse_t EncryptedAppTicketResponse_t;
-struct EncryptedAppTicketResponse_t
-{
- EResult m_eResult;
-};
-
-#endif
-
-/*
- * ------------------------------------------------------------------------------------------------------------------
- * ISteamUserStats
- * ------------------------------------------------------------------------------------------------------------------
- */
-
-#if defined( VG_ENGINE )
-typedef void ISteamUserStats;
-extern ISteamUserStats *SteamAPI_SteamUserStats_v013();
-extern bool SteamAPI_ISteamUserStats_GetAchievement( ISteamUserStats *self, const c8 *pchName, bool *pbAchieved );
-extern bool SteamAPI_ISteamUserStats_SetAchievement( ISteamUserStats *self, const c8 *pchName );
-extern bool SteamAPI_ISteamUserStats_ClearAchievement( ISteamUserStats *self, const c8 *pchName );
-extern SteamAPICall_t SteamAPI_ISteamUserStats_RequestUserStats( ISteamUserStats *self, uint64_steamid steamIDUser );
-extern bool SteamAPI_ISteamUserStats_StoreStats( ISteamUserStats *self );
-
-typedef struct UserStatsReceived_t UserStatsReceived_t;
-struct UserStatsReceived_t
-{
- u64 m_nGameID;
- EResult m_eResult;
- CSteamID m_steamIDUser;
-};
-#endif
-
-/*
- * ------------------------------------------------------------------------------------------------------------------
- * ISteamUtils
- * ------------------------------------------------------------------------------------------------------------------
- */
-typedef void ISteamUtils;
-#if defined( VG_ENGINE )
-extern ISteamUtils *SteamAPI_SteamUtils_v010();
-#else
-extern ISteamUtils *SteamAPI_SteamGameServerUtils_v010();
-#endif
-
-typedef void (*SteamAPIWarningMessageHook_t)(i32, const c8 *);
-extern bool SteamAPI_ISteamUtils_GetImageSize( ISteamUtils *self, i32 iImage, u32 *pnWidth, u32 *pnHeight );
-extern bool SteamAPI_ISteamUtils_GetImageRGBA( ISteamUtils *self, i32 iImage, u8 *pubDest, i32 nDestBufferSize );
-extern void SteamAPI_ISteamUtils_SetWarningMessageHook( ISteamUtils *self, SteamAPIWarningMessageHook_t pFunction );
-
-typedef enum ESteamAPICallFailure ESteamAPICallFailure;
-enum ESteamAPICallFailure
-{
- k_ESteamAPICallFailureNone = -1,
- k_ESteamAPICallFailureSteamGone = 0,
- k_ESteamAPICallFailureNetworkFailure = 1,
- k_ESteamAPICallFailureInvalidHandle = 2,
- k_ESteamAPICallFailureMismatchedCallback = 3,
-};
-extern ESteamAPICallFailure SteamAPI_ISteamUtils_GetAPICallFailureReason( ISteamUtils *self, SteamAPICall_t hSteamAPICall );
-
-extern void SteamAPI_SteamNetworkingIPAddr_Clear( SteamNetworkingIPAddr *self );
-extern bool SteamAPI_SteamNetworkingIPAddr_ParseString( SteamNetworkingIPAddr *self, const c8 *pszStr );
-extern void SteamAPI_SteamNetworkingMessage_t_Release( SteamNetworkingMessage_t *self );
-
-#pragma pack( pop )
-
-
-/*
- * ------------------------------------------------------------------------------------------------------------------
- * VG STEAM API
- * ------------------------------------------------------------------------------------------------------------------
- */
-
-typedef struct vg_steam_api_call vg_steam_api_call;
-struct vg_steam_api
-{
- bool disabled, demo_mode;
- void (*cb_connection_changed)( SteamNetConnectionStatusChangedCallback_t *info );
-
- HSteamPipe hPipe;
- ISteamNetworkingSockets *pSteamNetworkingSockets;
- ISteamUtils *pSteamUtils;
- ISteamUGC *pSteamUGC;
- ISteamNetworkingUtils *pSteamNetworkingUtils;
-
-#if defined( VG_ENGINE )
- void (*cb_persona_changed)( PersonaStateChange_t *info );
-
- ISteamUtils *pSteamUser;
- ISteamFriends *pSteamFriends;
- ISteamUserStats *pSteamUserStats;
-
- c8 username_at_startup[ 128 ];
-#endif
-
-#if defined( VG_SERVER )
- ISteamGameServer *pSteamGameServer;
- bool is_connected;
-#endif
-
- struct vg_steam_api_call
- {
- SteamAPICall_t id;
- void *userdata;
- void( *cb )( void *result, void *userdata );
- }
- api_calls[ 32 ];
- u32 api_call_count;
-
-#if defined( VG_SERVER )
- u8 server_symmetric_key[ k_nSteamEncryptedAppTicketSymmetricKeyLen ];
-#else
- u8 app_symmetric_key[ 1024 ];
- u32 app_key_length;
-#endif
-}
-extern _steam_api;
-
-#if defined( VG_SERVER )
-VG_API bool _vg_steam_init( u32 unIP, u16 usGamePort, u16 usQueryPort, EServerMode eServerMode,
- const c8 *pchVersionString, const c8 *appid_str );
-#else
-VG_API bool _vg_steam_init(void);
-#endif
-void vg_steam_frame(void);
-VG_API void _vg_steam_shutdown(void);
-
-vg_steam_api_call *vg_alloc_async_steam_api_call(void);
-void vg_steam_set_achievement( const c8 *name, bool yes );
-
-#endif
+++ /dev/null
-i32 vg_str_storage( vg_str *str )
-{
- if( str->len == 0 )
- {
- if( str->buffer )
- {
- vg_str_dynamic *arr = (vg_str_dynamic *)str->buffer;
- return (arr-1)->len;
- }
- else return 0;
- }
- else return str->len;
-}
-
-void vg_strclip( vg_str *str, i32 i )
-{
- str->buffer[i] = '\0';
- str->i = i;
-}
-
-/*
- * Reset string. If len is 0 (dynamically allocated), buffer must be either
- * NULL or be acquired from malloc or realloc
- */
-void vg_strnull( vg_str *str, c8 *buffer, i32 len )
-{
- VG_ASSERT( len >= 0 );
-
- str->buffer = buffer;
- if( buffer )
- str->buffer[0] = '\0';
-
- str->i = 0;
- str->len = len;
-}
-
-void vg_strfree( vg_str *str )
-{
- if( str->len == 0 )
- {
- if( str->buffer )
- {
- vg_str_dynamic *arr = (vg_str_dynamic *)str->buffer;
- vg_free( arr-1 );
-
- str->buffer = NULL;
- str->i = 0;
- }
- }
-}
-
-/*
- * Double the size of the dynamically allocated string. If unallocated, alloc of
- * 16 bytes minimum.
- */
-static i32 vg_str_dynamic_grow( vg_str *str )
-{
- if( str->buffer )
- {
- vg_str_dynamic *hdr = ((vg_str_dynamic *)str->buffer) - 1;
- i32 total = (hdr->len + sizeof(vg_str_dynamic)) * 2;
- hdr = vg_realloc( hdr, total );
- hdr->len = total - sizeof(vg_str_dynamic);
- str->buffer = (c8 *)(hdr+1);
- return hdr->len;
- }
- else
- {
- vg_str_dynamic *hdr = vg_malloc(16);
- hdr->len = 16-sizeof(vg_str_dynamic);
- str->buffer = (c8 *)(hdr+1);
- str->buffer[0] = '\0';
- return hdr->len;
- }
-}
-
-static bool _vg_strcatch( vg_str *str, c8 c )
-{
- if( str->i == -1 ) return 0;
-
- i32 max = vg_str_storage( str );
- if( str->i == max )
- {
- if( str->len == 0 )
- max = vg_str_dynamic_grow( str );
- else
- {
- str->i = -1;
- str->buffer[ max-1 ] = '\0';
- return 0;
- }
- }
-
- str->buffer[ str->i ++ ] = c;
- return 1;
-}
-
-void vg_strcat_limit( vg_str *str, const c8 *append, u32 max )
-{
- if( !append || (str->i == -1) )
- return;
-
- i32 i = 0;
-
-append:;
- c8 c = append[ i ++ ];
- if( !_vg_strcatch( str, c ) )
- return;
-
- if( max && i >= max )
- return;
-
- if( c == '\0' )
- {
- str->i --;
- return;
- }
- else goto append;
-}
-
-void vg_strcat( vg_str *str, const c8 *append )
-{
- vg_strcat_limit( str, append, 0 );
-}
-
-void vg_strcatch( vg_str *str, c8 c )
-{
- _vg_strcatch( str, c );
- _vg_strcatch( str, '\x00' );
- str->i --;
-}
-
-int vg_strgood( vg_str *str )
-{
- if( str->i == -1 ) return 0;
- else return 1;
-}
-
-bool vg_str_flushfd( vg_str *str, int fd )
-{
- bool good = write( fd, str->buffer, str->i ) == str->i;
- str->i = 0;
- return good;
-}
-
-c8 vg_str_character( vg_str *str, i32 index )
-{
- return str->buffer[ index ];
-}
-
-/*
- * Returns pointer to last instance of character
- */
-i32 vg_strch( vg_str *str, i32 start, c8 c )
-{
- i32 last_index = -1;
- for( i32 i=start; i<str->i; i++ )
- if( str->buffer[i] == c )
- last_index = i;
- return last_index;
-}
-
-u32 vg_strcpy( const c8 *src, c8 *dst )
-{
- for( u32 i=0; i<32*1024; i ++ )
- {
- dst[i] = src[i];
- if( !src[i] )
- return i;
- }
-
- vg_fatal_error( "Hit string copy limit! (32 KB max length)\n" );
- return 0;
-}
-
-u32 vg_strlen( const c8 *src )
-{
- for( u32 i=0; i<32*1024; i ++ )
- if( !src[i] )
- return i;
-
- vg_fatal_error( "Hit string len limit! (32 KB max length)\n" );
- return 0;
-}
-
-u32 vg_strncpy( const c8 *src, c8 *dst, u32 len, enum strncpy_behaviour behaviour )
-{
- if( src == NULL )
- {
- dst[0] = '\0';
- return 0;
- }
-
- for( u32 i=0; i<len; i++ )
- {
- dst[i] = src[i];
-
- if( !src[i] ) return i;
-
- if( i == len-1 )
- {
- if( behaviour == k_strncpy_always_add_null )
- {
- dst[i] = '\0';
- return i;
- }
- else if( behaviour == k_strncpy_overflow_fatal )
- vg_fatal_error( "vg_strncpy to buffer with maximum length '%u' exceeded the end of the buffer.\n", len );
- }
- }
-
- return 0;
-}
-
-static void _vg_strcatf_va( vg_str *str, const c8 *fmt, va_list args )
-{
- c8 buffer[4096];
- vsnprintf( buffer, VG_ARRAY_LEN(buffer), fmt, args );
- vg_strcat( str, buffer );
-}
-
-void vg_strcatf( vg_str *str, const c8 *fmt, ... )
-{
- va_list args;
- va_start( args, fmt );
- _vg_strcatf_va( str, fmt, args );
- va_end( args );
-}
-
-u32 vg_strdjb2( const c8 *str )
-{
- u32 hash = 5381, c;
- if( str )
- while( (c = *str++) )
- hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
- return hash;
-}
-
-bool vg_strdjb2_eq( const c8 *s1, u32 h1, const c8 *s2, u32 h2 )
-{
- if( h1 == h2 )
- {
- if(!strcmp(s1, s2)) return 1;
- else return 0;
- }
- else return 0;
-}
-
-bool vg_str_eq( const c8 *s1, const c8 *s2 )
-{
- if( vg_strdjb2( s1 ) == vg_strdjb2( s2 ) )
- return !strcmp( s1, s2 );
-
- return 0;
-}
-
-#if defined( VG_UTF8 )
-static u32 utf8_byte0_byte_count( u8 c80 )
-{
- for( u32 k=2; k<4; k++ )
- {
- if( !(c80 & (0x80 >> k)) )
- return k;
- }
-
- return 0;
-}
-
-u32 str_utf8_collapse( const c8 *str, c8 *buf, u32 length )
-{
- u8 *ustr = (u8 *)str;
- u32 utf32_code = 0x00000000;
- u32 i=0, j=0, utf32_byte_ct=0;
- for(;j < length-1;)
- {
- if( ustr[i] == 0x00 )
- break;
- if( ustr[i] & 0x80 )
- {
- if( utf32_byte_ct )
- {
- utf32_byte_ct --;
- utf32_code |= (ustr[i] & 0x3F) << (utf32_byte_ct*6);
- if( !utf32_byte_ct )
- {
- const c8 *match;
- size_t c8s = anyascii( utf32_code, &match );
- for( u32 k=0; k<VG_MIN(c8s, length-1-j); k++ )
- buf[ j++ ] = (u8)match[k];
- }
- }
- else
- {
- utf32_byte_ct = utf8_byte0_byte_count( ustr[i] )-1;
- utf32_code = ustr[i] & (0x3F >> utf32_byte_ct);
- utf32_code <<= utf32_byte_ct*6;
- }
- }
- else
- {
- utf32_byte_ct = 0x00;
- buf[j ++] = str[i];
- }
- i++;
- }
- buf[j] = 0x00;
- return j;
-}
-#endif
-
-const c8 *vg_strp_info_str[] =
-{
- [k_vg_strp_ok] = "ok",
- [k_vg_strp_eof] = "eof",
- [k_vg_strp_error] = "error",
- [k_vg_strp_whitespace] = "whitespace"
-};
-
-vg_strp_info vg_strp_c8( vg_strp *p, c8 *c )
-{
- *c = 0;
- if( p->buffer == NULL )
- return k_vg_strp_eof;
-
- *c = *p->buffer;
- if( *c == '\0' )
- {
- p->buffer = NULL;
- return k_vg_strp_eof;
- }
- p->buffer ++;
-
- if( *c == '\t' || *c == '\n' || *c == ' ' || *c == '\r' )
- return k_vg_strp_whitespace;
- else
- return k_vg_strp_ok;
-}
-
-vg_strp_info vg_strp_u64( vg_strp *p, u64 *value )
-{
- c8 c;
- vg_strp_info info = k_vg_strp_whitespace;
- while( info == k_vg_strp_whitespace )
- info = vg_strp_c8( p, &c );
-
- u64 result = 0;
- bool got = 0;
- while( info == k_vg_strp_ok )
- {
- if( c >= '0' && c <= '9' )
- {
- result = result*10 + ((u64)c - (u64)'0');
- got = 1;
- }
- else
- goto err;
- info = vg_strp_c8( p, &c );
- }
- info = k_vg_strp_ok;
- goto ok;
-
- err: while( info == k_vg_strp_ok )
- info = vg_strp_c8( p, &c );
- info = k_vg_strp_error;
-
- ok: *value = result;
- return got? info: k_vg_strp_eof;
-}
-
-vg_strp_info vg_strp_i64( vg_strp *p, i64 *value )
-{
- c8 c;
- vg_strp_info info = k_vg_strp_whitespace;
- while( info == k_vg_strp_whitespace )
- info = vg_strp_c8( p, &c );
-
- i64 result = 0,
- sign = 1;
-
- if( c == '+' || c == '-' )
- {
- if( c == '-' )
- sign = -1;
- info = vg_strp_c8( p, &c );
- }
-
- bool got = 0;
- while( info == k_vg_strp_ok )
- {
- if( c >= '0' && c <= '9' )
- {
- result = result*10 + ((i64)c - (i64)'0');
- got = 1;
- }
- else
- goto err;
-
- info = vg_strp_c8( p, &c );
- }
- info = k_vg_strp_ok;
- goto ok;
-
- err: while( info == k_vg_strp_ok )
- info = vg_strp_c8( p, &c );
- info = k_vg_strp_error;
-
- ok: *value = result*sign;
- return got? info: k_vg_strp_eof;
-}
-
-vg_strp_info vg_strp_f64( vg_strp *p, f64 *value )
-{
- c8 c;
- vg_strp_info info = k_vg_strp_whitespace;
- while( info == k_vg_strp_whitespace )
- info = vg_strp_c8( p, &c );
-
- i64 result = 0,
- resultm= 0;
- u32 dp = 0;
- f64 sign = 1.0;
-
- if( c == '+' || c == '-' )
- {
- if( c == '-' )
- sign = -1.0;
- info = vg_strp_c8( p, &c );
- }
-
- bool got = 0, got_decimal = 0;
- while( info == k_vg_strp_ok )
- {
- if( c == '.' )
- {
- if( got_decimal )
- goto err;
- resultm = result;
- result = 0;
- got_decimal = 1;
- dp = 0;
- }
- else if( c >= '0' && c <= '9' )
- {
- result = result*10 + ((i64)c - (i64)'0');
- got = 1;
- dp ++;
- }
- else
- goto err;
- info = vg_strp_c8( p, &c );
- }
-
- info = k_vg_strp_ok;
- goto ok;
-
- err: while( info == k_vg_strp_ok )
- info = vg_strp_c8( p, &c );
- info = k_vg_strp_error;
-
- ok:;
- f64 int_part = 0.0, decimal_part = 0.0;
-
- if( got_decimal )
- {
- decimal_part = (f64)result;
- for( u32 i=0; i<dp; i ++ )
- decimal_part /= 10.0;
- int_part = resultm;
- }
- else int_part = result;
-
- *value = (f64)sign * (int_part + decimal_part);
- return (got||got_decimal)? info: k_vg_strp_eof;
-}
-
-static u32 vg_strcatu64_internal( c8 reverse_buffer[64], u64 value, u64 base, u32 max_characters )
-{
- VG_ASSERT( base >= 2 );
-
- if( max_characters == 0 )
- max_characters = 64;
-
- const c8 *digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- if( value )
- {
- u32 i = 0;
- while( value && (i<max_characters) )
- {
- reverse_buffer[ i ++ ] = digits[ (u32)(value % base) ];
- value /= base;
- }
- return i;
- }
- else
- {
- reverse_buffer[0] = digits[0];
- return 1;
- }
-}
-
-void vg_strcati64r( vg_str *str, i64 value, u64 base, u32 width, c8 blank_character )
-{
- VG_ASSERT( base >= 2 );
-
- c8 temp[65];
- u32 digits = vg_strcatu64_internal( temp, value<0? -value: value, base, 0 );
- if( value < 0 )
- temp[ digits ++ ] = '-';
-
- u32 padding = 0;
- if( digits > width )
- padding = 0;
- else
- padding = width - digits;
-
- for( u32 i=0; i<padding; i ++ )
- vg_strcatch( str, blank_character );
-
- for( u32 i=0; i<digits; i ++ )
- vg_strcatch( str, temp[ digits -1 -i ] );
-}
-
-void vg_strcatu64( vg_str *str, u64 value, u64 base )
-{
- VG_ASSERT( base >= 2 );
-
- c8 temp[64];
- u32 digits = vg_strcatu64_internal( temp, value, base, 0 );
- for( u32 i=0; i<digits; i ++ )
- vg_strcatch( str, temp[ digits -1 -i ] );
-}
-
-void vg_strcati64( vg_str *str, i64 value, u64 base )
-{
- VG_ASSERT( base >= 2 );
-
- if( value < 0 )
- {
- vg_strcatch( str,'-' );
- value = -value;
- }
- vg_strcatu64( str, value, base );
-}
-
-void vg_strcatf64( vg_str *str, f64 value, u64 base, u32 decimal_places )
-{
- VG_ASSERT( decimal_places );
- VG_ASSERT( base >= 2 );
-
- if( value < 0.0 )
- {
- value = -value;
- vg_strcat( str, "-" );
- }
-
- u64 m = 10;
- for( u32 i=0; i<(decimal_places-1); i ++ )
- m *= 10;
-
- // decimal part gets +1.0f because anything less than 1 does not have leading 0s when printing it in the u64 print
- u64 decimal_part = (u64)((f64)m * (value+1.0f) + 0.5),
- normal_part = (u64)value;
-
- vg_strcatu64( str, normal_part, base );
- vg_strcat( str, "." );
-
- c8 temp[64];
- u32 digits = vg_strcatu64_internal( temp, decimal_part, base, decimal_places );
- for( u32 i=0; i<digits; i ++ )
- vg_strcatch( str, temp[ digits -1 -i ] );
-}
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_string.c"
-#else
-
-/* string builder with optional dynamic memory or static buffer. */
-
-typedef struct vg_str vg_str;
-typedef struct vg_str_dynamic vg_str_dynamic;
-
-struct vg_str
-{
- c8 *buffer;
- i32 i, /* -1: error condition. otherwise, current cursor position */
- len; /* -1: dynamically allocated. otherwise, buffer length */
-};
-
-struct vg_str_dynamic
-{
- i32 len;
-};
-
-/*
- * Returns the current storage size of the string
- */
-i32 vg_str_storage( vg_str *str );
-
-/*
- * Reset string. If len is -1 (dynamically allocated), buffer must be either
- * NULL or be acquired from malloc or realloc
- */
-void vg_strnull( vg_str *str, c8 *buffer, i32 len );
-void vg_strfree( vg_str *str );
-void vg_strclip( vg_str *str, i32 i );
-
-/*
- * Append null terminated string to vg_str
- */
-void vg_strcat( vg_str *str, const c8 *append );
-void vg_strcatf( vg_str *str, const c8 *fmt, ... );
-
-/*
- * Append c8acter to vg_str
- */
-void vg_strcatch( vg_str *str, c8 c );
-
-/* Print various data types onto vg_str */
-void vg_strcati64r( vg_str *str, i64 value, u64 base, u32 width, c8 blank_c8acter );
-void vg_strcatu64( vg_str *str, u64 value, u64 base );
-void vg_strcati64( vg_str *str, i64 value, u64 base );
-void vg_strcatf64( vg_str *str, f64 value, u64 base, u32 decimal_places );
-
-/*
- * Returns 1 if string did not overflow while building
- */
-int vg_strgood( vg_str *str );
-c8 vg_str_character( vg_str *str, i32 index );
-
-/*
- * Returns pointer to last instance of c8acter
- */
-i32 vg_strch( vg_str *str, i32 start, c8 c );
-
-enum strncpy_behaviour
-{
- k_strncpy_always_add_null = 0,
- k_strncpy_allow_cutoff = 1,
- k_strncpy_overflow_fatal = 2
-};
-
-u32 vg_strcpy( const c8 *src, c8 *dst );
-u32 vg_strlen( const c8 *src );
-u32 vg_strncpy( const c8 *src, c8 *dst, u32 len, enum strncpy_behaviour behaviour );
-u32 vg_strdjb2( const c8 *str );
-bool vg_strdjb2_eq( const c8 *s1, u32 h1, const c8 *s2, u32 h2 );
-
-#define VG_STRDJB2_EQ( CS1, S2, H2 ) \
- vg_strdjb2_eq( CS1, vg_strdjb2(CS1), S2, H2 )
-
-bool vg_str_eq( const c8 *s1, const c8 *s2 );
-bool vg_str_flushfd( vg_str *str, int fd );
-
-u32 str_utf8_collapse( const c8 *str, c8 *buf, u32 length );
-
-typedef struct vg_strp vg_strp;
-struct vg_strp
-{
- const c8 *buffer;
-};
-
-typedef enum vg_strp_info vg_strp_info;
-enum vg_strp_info
-{
- k_vg_strp_ok,
- k_vg_strp_eof,
- k_vg_strp_error,
- k_vg_strp_whitespace
-};
-
-vg_strp_info vg_strp_c8( vg_strp *p, c8 *c );
-vg_strp_info vg_strp_i64( vg_strp *p, i64 *value );
-vg_strp_info vg_strp_u64( vg_strp *p, u64 *value );
-vg_strp_info vg_strp_f64( vg_strp *p, f64 *value );
-
-vg_strp_info vg_strp_vecf32( vg_strp *p, f32 *vec, u32 count );
-
-extern const c8 *vg_strp_info_str[];
-
-void vg_strcatf64( vg_str *str, f64 value, u64 base, u32 decimal_places );
-
-#endif
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_tex.c"
-#else
-
-/* TODO: Include Okaypeg alongside QOI. */
-
-typedef union qoi_rgba_t qoi_rgba_t;
-typedef struct qoi_desc qoi_desc;
-typedef struct vg_qoi_ctx vg_qoi_ctx;
-typedef struct vg_tex vg_tex;
-struct vg_tex
-{
- u32 name;
- u32 flags;
-};
-
-VG_API void _vg_tex_init(void);
-
-#pragma pack(push,1)
-union qoi_rgba_t
-{
- u8 rgba[4];
- u32 v;
-};
-
-struct qoi_desc
-{
- u32 magic;
- u32 width;
- u32 height;
- u8 channels;
- u8 colorspace;
-};
-#pragma pack(pop)
-
-# define QOI_SRGB 0
-# define QOI_LINEAR 1
-
-/* Reading qois */
-VG_TIER_0 u32 vg_qoi_stream_init( qoi_desc *desc, vg_stream *file );
-VG_TIER_0 void vg_qoi_stream_decode( qoi_desc *desc, vg_stream *file, u8 *dest_buffer, bool v_flip );
-
-/* Writing qois */
-VG_TIER_0 u32 vg_query_qoi_max_compressed_size( const qoi_desc *desc );
-VG_TIER_0 u32 vg_qoi_stream_encode( const qoi_desc *desc, const u8 *pixels, vg_stream *stream, bool v_flip );
-
-# if defined( VG_ENGINE )
-# define VG_TEX_LINEAR 0x1
-# define VG_TEX_NEAREST 0x2
-# define VG_TEX_REPEAT 0x4
-# define VG_TEX_CLAMP 0x8
-# define VG_TEX_NOMIP 0x10
-# define VG_TEX_CUBEMAP 0x20
-# define VG_TEX_ERROR 0x40
-# define VG_TEX_COMPLETE 0x80
-# define VG_TEX_FLIP_V 0x100
-# define VG_TEX_FRAMEBUFFER_ATTACHMENT 0x200
-# define VG_TEX_PRIVATE 0x400 /* used on renderbuffers... */
-
-VG_API u32 vg_tex_name( GLuint target, vg_tex *tex );
-VG_API void vg_tex_bind( GLuint target, vg_tex *tex, u32 slot );
-VG_API void vg_tex_delete( vg_tex *tex );
-VG_API void _vg_tex_load( vg_tex *out_tex, const c8 *path, u32 flags );
-VG_API bool _vg_tex_load_stream( vg_tex *out_tex, vg_stream *in_stream, u32 flags );
-# endif
-#endif
+++ /dev/null
-#define VG_THIRDPARTY
-#include "vg/vg.h"
+++ /dev/null
-#include "vg_tool.h"
-
-/* unity build of vg components */
-#include "vg_log.c"
-#include "vg_string.c"
-#include "vg_opt.c"
-#include "vg_msg.c"
-#include "vg_mem.c"
-#include "vg_mem_queue.c"
-#include "vg_io.c"
+++ /dev/null
-#pragma once
-#include "vg_log.h"
+++ /dev/null
-struct _vg_tower _vg_tower;
-
-vg_signal_id _vg_tower_create_signal( const char *name )
-{
- THREAD_0;
- VG_ASSERT( _vg_tower.signal_count < VG_ARRAY_LEN( _vg_tower.signals ) );
- vg_signal_id id = _vg_tower.signal_count;
- struct signal_info *inf = &_vg_tower.signals[ id ];
- inf->name = name;
- _vg_tower.signal_count ++;
- return id;
-}
-
-void _vg_tower_register_trigger( u64 mask, void(*fn)( vg_signal_id id, bool state ) )
-{
- THREAD_0;
- VG_ASSERT( _vg_tower.trigger_count < VG_ARRAY_LEN( _vg_tower.triggers ) );
- struct tower_trigger *trigger = &_vg_tower.triggers[ _vg_tower.trigger_count ++ ];
- trigger->mask = mask;
- trigger->fn = fn;
-}
-
-struct async_tower_info
-{
- vg_signal_id id;
- bool state;
-};
-static void _vg_tower_set_flag_recall( vg_async_task *task )
-{
- struct async_tower_info *info = (void *)task->data;
- _vg_tower_set_flag( info->id, info->state );
-}
-void _vg_tower_set_flag( vg_signal_id id, bool state )
-{
- if( vg_thread_purpose() == _thread_purpose_loader )
- {
- vg_async_task *task = vg_allocate_async_task( &vg.main_tasks, sizeof(struct async_tower_info), 1 );
- struct async_tower_info *info = (void *)task->data;
- info->id = id;
- info->state = state;
- vg_async_task_dispatch( task, _vg_tower_set_flag_recall );
- return;
- }
-
- THREAD_0;
-
- u64 bit = 0x1lu << (u64)id;
- if( state ) _vg_tower.state |= bit;
- else _vg_tower.state &= ~bit;
- vg_info( "[tower] %s:%s [%lx]\n", _vg_tower.signals[id].name, state? "true": "false", _vg_tower.state );
-
- for( u32 i=0; i<_vg_tower.trigger_count; i ++ )
- {
- struct tower_trigger *trig = &_vg_tower.triggers[i];
- if( trig->mask & bit )
- {
- trig->fn( id, state );
- }
- }
-}
-
-bool _vg_tower_clearence( u64 mask )
-{
- THREAD_0;
- return (_vg_tower.state & mask) == mask;
-}
-
-u64 _vg_tower_mask( vg_signal_id id )
-{
- u64 bit = 0x1lu << (u64)id;
- return bit;
-}
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_tower.c"
-#else
-
-typedef u8 vg_signal_id;
-
-struct _vg_tower
-{
- struct tower_trigger
- {
- u64 mask;
- void( *fn )( vg_signal_id id, bool state );
- }
- triggers[ 64 ];
-
- struct signal_info
- {
- const char *name;
- }
- signals[ 64 ];
-
- u32 trigger_count, signal_count;
- u64 state;
-}
-extern _vg_tower;
-
-vg_signal_id _vg_tower_create_signal( const char *name );
-void _vg_tower_register_trigger( u64 mask, void(*fn)( vg_signal_id id, bool state ) );
-void _vg_tower_set_flag( vg_signal_id id, bool state );
-bool _vg_tower_clearence( u64 mask );
-u64 _vg_tower_mask( vg_signal_id id );
-
-#endif
+++ /dev/null
-u32 str_lev_distance( const char *s1, const char *s2 )
-{
- u32 m = strlen( s1 ),
- n = strlen( s2 );
-
- if( m==0 ) return n;
- if( n==0 ) return m;
-
- u32 costs[ 256 ];
-
- for( u32 k=0; k<=n; k++ )
- costs[k] = k;
-
- u32 i = 0;
- for( u32 i=0; i<m; i++ ){
- costs[0] = i+1;
-
- u32 corner = i;
-
- for( u32 j=0; j<n; j++ ){
- u32 upper = costs[j+1];
-
- if( s1[i] == s2[j] )
- costs[ j+1 ] = corner;
- else{
- u32 t = (upper < corner)? upper: corner;
- costs[j+1] = ((costs[j] < t)? costs[j]: t) + 1;
- }
-
- corner = upper;
- }
- }
-
- return costs[n];
-}
-
-u32 str_lcs( const char *s1, const char *s2 )
-{
- u32 m = VG_MIN( 31, strlen( s1 ) ),
- n = VG_MIN( 31, strlen( s2 ) );
-
- int suff[32][32],
- result = 0;
-
- for( int i=0; i<=m; i++ )
- {
- for( int j=0; j<=n; j++ )
- {
- if( i == 0 || j == 0 )
- suff[i][j] = 0;
- else if( s1[i-1] == s2[j-1] )
- {
- suff[i][j] = suff[i-1][j-1] + 1;
- result = VG_MAX( result, suff[i][j] );
- }
- else
- suff[i][j] = 0;
- }
- }
-
- return result;
-}
-
-/* str must not fuckoff ever! */
-void console_suggest_score_text( const char *str, const char *input, int minscore )
-{
- if( !str )
- return;
-
- /* filter duplicates */
- for( int i=0; i<vg_console.suggestion_count; i++ )
- if( !strcmp( vg_console.suggestions[i].str, str ) )
- return;
-
- /* calc score */
- u32 score = str_lcs( str, input );
-
- if( score < minscore )
- return;
-
- int best_pos = vg_console.suggestion_count;
- for( int j=best_pos-1; j>=0; j -- )
- if( score > vg_console.suggestions[j].lev_score )
- best_pos = j;
-
- /* insert if good score */
- if( best_pos < VG_ARRAY_LEN( vg_console.suggestions ) )
- {
- int start = VG_MIN( vg_console.suggestion_count, VG_ARRAY_LEN( vg_console.suggestions )-1 );
- for( int j=start; j>best_pos; j -- )
- vg_console.suggestions[j] = vg_console.suggestions[j-1];
-
- vg_console.suggestions[ best_pos ].str = str;
- vg_console.suggestions[ best_pos ].len = strlen( str );
- vg_console.suggestions[ best_pos ].lev_score = score;
-
- if( vg_console.suggestion_count < VG_ARRAY_LEN( vg_console.suggestions ) )
- vg_console.suggestion_count ++;
- }
-}
-
-static void console_update_suggestions( ui_context *ctx )
-{
- if( ctx->focused_control_type != k_ui_control_textbox || ctx->textbuf != vg_console.input )
- return;
-
- vg_console.suggestion_count = 0;
- vg_console.suggestion_select = -1;
- vg_console.suggestion_maxlen = 0;
-
- /*
- * - must be typing something
- * - must be at the end
- * - prev char must not be a whitespace
- * - cursors should match
- */
-
- if( ctx->textbox.cursor_pos == 0 ) return;
- if( ctx->textbox.cursor_pos != ctx->textbox.cursor_user ) return;
- if( vg_console.input[ ctx->textbox.cursor_pos ] != '\0' ) return;
-
- if( (vg_console.input[ ctx->textbox.cursor_pos -1 ] == ' ') ||
- (vg_console.input[ ctx->textbox.cursor_pos -1 ] == '\t') )
- return;
-
- char temp[128];
- const char *args[32];
-
- int token_count = vg_console_tokenize( vg_console.input, temp, args );
- if( !token_count ) return;
- vg_console.suggestion_pastepos = args[token_count-1]-temp;
-
- /* Score all our commands and cvars */
- if( token_count == 1 )
- {
- for( int i=0; i<vg_console.var_count; i++ )
- {
- vg_var *cvar = &vg_console.vars[i];
- console_suggest_score_text( cvar->name, args[0], 1 );
- }
-
- for( int i=0; i<vg_console.function_count; i++ )
- {
- vg_cmd *cmd = &vg_console.functions[i];
- console_suggest_score_text( cmd->name, args[0], 1 );
- }
- }
- else
- {
- vg_cmd *cmd = vg_console_match_cmd( args[0] );
- vg_var *var = vg_console_match_var( args[0] );
-
- if( cmd )
- if( cmd->poll_suggest )
- cmd->poll_suggest( token_count-1, &args[1] );
- }
-
- /* some post processing */
- for( int i=0; i<vg_console.suggestion_count; i++ )
- {
- vg_console.suggestion_maxlen = VG_MAX( vg_console.suggestion_maxlen,
- vg_console.suggestions[i].len );
-
- if( vg_console.suggestions[i].lev_score <
- vg_console.suggestions[0].lev_score/2 )
- {
- vg_console.suggestion_count = i;
- return;
- }
- }
-}
-
-/*
- * Suggestion controls
- */
-static void _console_fetch_suggestion( ui_context *ctx )
-{
- char *target = &vg_console.input[ vg_console.suggestion_pastepos ];
-
- if( vg_console.suggestion_select == -1 )
- {
- strcpy( target, vg_console.input_copy );
- _ui_textbox_move_cursor( ctx,
- &ctx->textbox.cursor_user,
- &ctx->textbox.cursor_pos, 10000, 1 );
- }
- else
- {
- strncpy( target,
- vg_console.suggestions[ vg_console.suggestion_select ].str,
- VG_ARRAY_LEN( vg_console.input )-1 );
-
- _ui_textbox_move_cursor( ctx,
- &ctx->textbox.cursor_user,
- &ctx->textbox.cursor_pos, 10000, 1 );
- _ui_textbox_put_char( ctx, ' ' );
- }
-}
-
-static void _console_suggest_store_normal(void)
-{
- if( vg_console.suggestion_select == -1 )
- {
- char *target = &vg_console.input[ vg_console.suggestion_pastepos ];
- strcpy( vg_console.input_copy, target );
- }
-}
-
-void console_suggest_next( ui_context *ctx )
-{
- if( vg_console.suggestion_count )
- {
- _console_suggest_store_normal();
-
- vg_console.suggestion_select ++;
-
- if( vg_console.suggestion_select >= vg_console.suggestion_count )
- vg_console.suggestion_select = -1;
-
- _console_fetch_suggestion( ctx );
- }
-}
-
-void console_suggest_prev( ui_context *ctx )
-{
- if( vg_console.suggestion_count )
- {
- _console_suggest_store_normal();
-
- vg_console.suggestion_select --;
-
- if( vg_console.suggestion_select < -1 )
- vg_console.suggestion_select = vg_console.suggestion_count-1;
-
- _console_fetch_suggestion( ctx );
- }
-}
-
-static void _vg_console_on_update( ui_context *ctx, char *buf, u32 len, void *userdata )
-{
- if( buf == vg_console.input )
- {
- console_update_suggestions( ctx );
- }
-}
-
-static void console_history_get( char* buf, int entry_num )
-{
- if( !vg_console.history_count )
- return;
-
- int offset = VG_MIN( entry_num, vg_console.history_count -1 ),
- pick = (vg_console.history_last - offset) %
- VG_ARRAY_LEN( vg_console.history );
- strcpy( buf, vg_console.history[ pick ] );
-}
-
-static void _vg_console_on_up( ui_context *ctx, char *buf, u32 len, void *userdata )
-{
- if( buf == vg_console.input )
- {
- vg_console.history_pos =
- VG_MAX
- (
- 0,
- VG_MIN
- (
- vg_console.history_pos+1,
- VG_MIN
- (
- VG_ARRAY_LEN( vg_console.history ),
- vg_console.history_count - 1
- )
- )
- );
-
- console_history_get( vg_console.input, vg_console.history_pos );
- _ui_textbox_move_cursor( ctx,
- &ctx->textbox.cursor_user,
- &ctx->textbox.cursor_pos,
- VG_ARRAY_LEN(vg_console.input)-1, 1 );
- }
-}
-
-static void _vg_console_on_down( ui_context *ctx, char *buf, u32 len, void *userdata )
-{
- if( buf == vg_console.input )
- {
- vg_console.history_pos = VG_MAX( 0, vg_console.history_pos-1 );
- console_history_get( vg_console.input, vg_console.history_pos );
-
- _ui_textbox_move_cursor( ctx,
- &ctx->textbox.cursor_user,
- &ctx->textbox.cursor_pos,
- VG_ARRAY_LEN(vg_console.input)-1, 1 );
- }
-}
-
-static void _vg_console_on_enter( ui_context *ctx, char *buf, u32 len, void *userdata )
-{
- if( buf == vg_console.input )
- {
- if( !strlen( vg_console.input ) )
- return;
-
- vg_info( "%s\n", vg_console.input );
-
- if( strcmp( vg_console.input, vg_console.history[ vg_console.history_last ]) )
- {
- vg_console.history_last = ( vg_console.history_last + 1) % VG_ARRAY_LEN(vg_console.history );
- vg_console.history_count = VG_MIN( VG_ARRAY_LEN( vg_console.history ), vg_console.history_count + 1 );
- strcpy( vg_console.history[ vg_console.history_last ], vg_console.input );
- }
-
- vg_console.history_pos = -1;
- vg_execute_console_input( vg_console.input, 0, 0 );
- _ui_textbox_move_cursor( ctx, &ctx->textbox.cursor_user, &ctx->textbox.cursor_pos, -10000, 1 );
- vg_console.input[0] = '\0';
- console_update_suggestions( ctx );
- }
-
- vg_console.auto_focus = 1;
-}
-
-void vg_console_draw( ui_context *ctx )
-{
- if( !vg_console.enabled )
- return;
- VG_MUTEX_LOCK( vg_log.lock );
-
- int ptr = vg_log.log_line_current;
- int const fh = ctx->font->sy, log_lines = 32;
- int console_lines = VG_MIN( log_lines, vg_log.log_line_count );
- ui_rect rect_log = { 0, 0, ctx->area[0], log_lines*fh },
- rect_input = { 0, log_lines*fh + 1, ctx->area[0], fh*2 },
- rect_line = { 0, 0, ctx->area[0], fh };
-
- /*
- * log
- */
- u32 bg_colour = (ui_colour( ctx, k_ui_bg )&0x00ffffff)|0x9f000000;
-
- ui_fill( ctx, rect_log, bg_colour );
- rect_line[1] = rect_log[1]+rect_log[3]-fh;
-
- for( int i=0; i<console_lines; i ++ )
- {
- ptr --;
-
- if( ptr < 0 ) ptr = VG_ARRAY_LEN( vg_log.log )-1;
-
- ui_text( ctx, rect_line, vg_log.log[ptr], 1, k_ui_align_left, 0 );
- rect_line[1] -= fh;
- }
-
- /*
- * Input area
- */
- struct ui_textbox_callbacks callbacks =
- {
- .up = _vg_console_on_up,
- .down = _vg_console_on_down,
- .change = _vg_console_on_update,
- .enter = _vg_console_on_enter,
- };
-
- u32 flags = 0;
- if( vg_console.auto_focus ) flags |= UI_TEXTBOX_AUTOFOCUS;
- ui_textbox( ctx, rect_input, NULL,
- vg_console.input, VG_ARRAY_LEN(vg_console.input), 1,
- flags, &callbacks );
- vg_console.auto_focus = 0;
-
- /*
- * suggestions
- */
- if( vg_console.suggestion_count )
- {
- ui_rect rect_suggest;
- rect_copy( rect_input, rect_suggest );
-
- rect_suggest[0] += 6 + ctx->font->sx*vg_console.suggestion_pastepos;
- rect_suggest[1] += rect_input[3];
- rect_suggest[2] = ctx->font->sx * vg_console.suggestion_maxlen;
- rect_suggest[3] = vg_console.suggestion_count * fh;
-
- ui_fill( ctx, rect_suggest, bg_colour );
-
- rect_suggest[3] = fh;
-
- for( int i=0; i<vg_console.suggestion_count; i ++ )
- {
- u32 text_colour;
- if( i == vg_console.suggestion_select )
- {
- ui_fill( ctx, rect_suggest, ui_colour( ctx, k_ui_orange ) );
- text_colour = ui_colourcont( ctx, k_ui_orange );
- }
- else text_colour = ui_colourcont( ctx, k_ui_bg );
-
- ui_text( ctx, rect_suggest, vg_console.suggestions[i].str, 1, k_ui_align_left, text_colour );
-
- rect_suggest[1] += fh;
- }
- }
-
- VG_MUTEX_UNLOCK( vg_log.lock );
-}
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_ui/console.c"
-#else
-
-void vg_console_draw( ui_context *ctx );
-void console_suggest_score_text( const char *str, const char *input, int minscore );
-void console_suggest_next( ui_context *ctx );
-void console_suggest_prev( ui_context *ctx );
-
-#endif
+++ /dev/null
-void vg_filebrowser_init( struct vg_filebrowser *browser )
-{
- browser->open_result = k_dir_open_none;
- browser->view_top_entry = NULL;
- browser->whole_list = NULL;
- browser->selected_entry = NULL;
- browser->current_path[0] = '\0';
- browser->entry_count = 0;
- browser->view_top_index = 0;
- browser->slider_value = 0.0f;
- browser->mode = k_filebrowser_mode_pick_file;
- browser->filter = 0;
-}
-
-void vg_filebrowser_set_path_to_home( struct vg_filebrowser *browser )
-{
-#ifdef _WIN32
- u16 *path = NULL;
- if( SHGetKnownFolderPath( &FOLDERID_Documents, 0, NULL, &path ) == S_OK )
- {
- if( !WideCharToMultiByte( CP_UTF8, 0, path, -1, browser->current_path, sizeof(browser->current_path), NULL, NULL ) )
- {
- vg_error( "WideCharToMultiByte failed... defaulting to C:/\n" );
- vg_strncpy( "C:/", browser->current_path, sizeof(browser->current_path), k_strncpy_always_add_null );
- }
- }
- else
- {
- vg_error( "SHGetKnownFolderPath failed... defaulting to C:/\n" );
- vg_strncpy( "C:/", browser->current_path, sizeof(browser->current_path), k_strncpy_always_add_null );
- }
- CoTaskMemFree( path );
-#else
- vg_strncpy( getenv("HOME"), browser->current_path, sizeof(browser->current_path), k_strncpy_always_add_null );
-#endif
-}
-
-static bool vg_filebrowser_up( struct vg_filebrowser *browser )
-{
- vg_str str =
- {
- .buffer = browser->current_path,
- .i = strlen( browser->current_path ),
- .len = sizeof(browser->current_path)-1
- };
-
- char *sep = vg_strch( &str, '/' );
- if( sep )
- {
- sep[0] = '\0';
- return 1;
- }
- else return 0;
-}
-
-void filebrowser_textbox_callback( ui_context *ctx, char *buffer, u32 len, void *userdata )
-{
- struct vg_filebrowser *browser = userdata;
- vg_filebrowser_free_entries( browser );
- vg_filebrowser_populate( browser );
-}
-
-enum filebrowser_action vg_filebrowser_ui( ui_context *ctx, ui_rect root_rect, struct vg_filebrowser *browser )
-{
- enum filebrowser_action result_action = k_filebrowser_action_none;
-
- ui_rect panel;
- rect_copy( root_rect, panel );
- ui_rect_pad( panel, (ui_px[2]){8,8} );
-
- ui_rect top_bar, box_refresh, box_up, bottom_bar;
- ui_standard_widget( ctx, panel, top_bar, 1 );
-
- ui_px height = ui_standard_widget_height( ctx, 1 );
- ui_split( panel, k_ui_axis_h, -height, ctx->padding, panel, bottom_bar );
-
- ui_split( top_bar, k_ui_axis_v, 24, 1, box_refresh, top_bar );
- ui_split( top_bar, k_ui_axis_v, 24, 1, box_up, top_bar );
-
- struct ui_textbox_callbacks callbacks =
- {
- .enter = filebrowser_textbox_callback,
- .up = NULL,
- .down = NULL,
- .change = NULL,
- .escape = NULL,
- .userdata = browser
- };
-
- ctx->text_encoding = k_ui_text_encoding_utf8;
- ui_textbox( ctx, top_bar, NULL, browser->current_path, sizeof(browser->current_path)-1, 1, 0, &callbacks );
- ctx->text_encoding = k_ui_text_encoding_ascii_vg_extended;
-
- ctx->font = &vgf_default_large;
- if( ui_button_text( ctx, box_refresh, "\xb6", 1 ) == k_ui_button_click )
- {
- vg_filebrowser_free_entries( browser );
- vg_filebrowser_populate( browser );
- }
-
- if( ui_button_text( ctx, box_up, "\xb8", 1 ) == k_ui_button_click )
- {
- if( vg_filebrowser_up( browser ) )
- {
- vg_filebrowser_free_entries( browser );
- vg_filebrowser_populate( browser );
- }
- }
- ctx->font = &vgf_default_small;
-
- if( browser->open_result == k_dir_open_none )
- {
- ui_text( ctx, panel, "...", 1, k_ui_align_middle_center, 0 );
- }
- else if( browser->open_result == k_dir_open_ok )
- {
- ui_rect list_panel, scrollbar;
- ui_split( panel, k_ui_axis_v, -16, 8, list_panel, scrollbar );
- u32 max_view = (list_panel[3]-2) / 24;
-
- /* scrollbar */
- f32 t;
- enum ui_button_state state = ui_slider_base( ctx, scrollbar, k_ui_axis_v, 0,
- browser->entry_count+1, &browser->slider_value, &t );
- enum ui_button_state mask_using = k_ui_button_holding_inside |
- k_ui_button_holding_outside |
- k_ui_button_click;
-
- if( state & mask_using )
- {
- u32 target = browser->slider_value,
- index = browser->view_top_index;
-
- while( index != target )
- {
- struct vg_filebrowser_entry *new_top;
- if( index < target )
- {
- new_top = browser->view_top_entry->prev;
- index ++;
- }
- else
- {
- new_top = browser->view_top_entry->next;
- index --;
- }
-
- if( new_top )
- {
- browser->view_top_entry = new_top;
- browser->view_top_index = index;
- }
- else break;
- }
- }
-
- ui_fill( ctx, scrollbar, ui_colour( ctx, k_ui_bg ) );
- ui_outline( ctx, scrollbar, -1, ui_colour(ctx, k_ui_bg+2), 0 );
-
- ui_rect bar;
- rect_copy( scrollbar, bar );
- bar[3] = (f32)scrollbar[3] * vg_minf(((f32)max_view / (f32)(browser->entry_count+1)), 1.0f);
- bar[1] = scrollbar[1] + (f32)scrollbar[3] * ((f32)browser->view_top_index / (f32)(browser->entry_count+1));
-
- ui_rect bar_top;
- rect_copy( bar, bar_top );
- bar_top[3] = 1;
-
- ui_clip( scrollbar, bar, bar );
- ui_fill( ctx, bar, ui_colour( ctx, k_ui_bg+1 ) );
- ui_fill( ctx, bar_top, ui_colour( ctx, k_ui_fg ) );
-
- /* entries */
- ui_fill( ctx, list_panel, ui_colour( ctx, k_ui_bg+3 ) );
- ui_rect entry_box = { list_panel[0]+1, list_panel[1]+1, list_panel[2]-2, 24 };
- struct vg_filebrowser_entry *entry = browser->view_top_entry;
-
- bool reload_next_time = 0;
-
- for( u32 i=0; i<max_view; i ++ )
- {
- if( entry )
- {
- u32 text_colour = ui_colour( ctx, k_ui_fg );
-
- if( entry == browser->selected_entry )
- {
- ui_fill( ctx, entry_box, ui_colour( ctx, k_ui_bg ) );
- ui_outline( ctx, entry_box, -1, ui_colour( ctx, k_ui_orange ), 0 );
- }
- else
- {
- enum ui_button_state click_state = k_ui_button_none;
- click_state = ui_colourbutton( ctx, entry_box, k_ui_bg+2+(i&0x1), 0, 0 );
-
- if( click_state == k_ui_button_click )
- {
- if( entry->type == k_vg_entry_type_dir )
- {
- u32 cur_len = strlen( browser->current_path );
- if( (cur_len + strlen( entry->name ) + 2) > sizeof(browser->current_path) )
- vg_fatal_error( "Max path size exceeded." );
- else
- {
- strcat( browser->current_path, "/" );
- strcat( browser->current_path, entry->name );
- reload_next_time = 1;
- }
- }
- else
- {
- browser->selected_entry = entry;
- }
- }
- else if( click_state != k_ui_button_none )
- {
- text_colour = ui_colour( ctx, k_ui_bg );
- }
- }
-
- ui_rect icon_box, label_box;
- ui_split( entry_box, k_ui_axis_v, 24, 0, icon_box, label_box );
-
- ctx->font = &vgf_default_large;
- if( entry->type == k_vg_entry_type_dir )
- {
- ui_text( ctx, icon_box, "\xb7", 1, k_ui_align_middle_center, 0 );
- }
- else
- {
- if( entry->media_type != 0 )
- {
- const struct
- {
- const char *icon_str;
- enum ui_scheme_colour colour;
- }
- scheme[] =
- {
- [k_media_type_image] = { "\xb9", k_ui_green },
- [k_media_type_video] = { "\xba", k_ui_blue },
- [k_media_type_audio] = { "\xbb", k_ui_purple },
- [k_media_type_text ] = { "\xbc", k_ui_yellow }
- };
-
- ui_text( ctx, icon_box, scheme[entry->media_type].icon_str, 1,
- k_ui_align_middle_center, ui_colour(ctx,scheme[entry->media_type].colour) );
- }
- }
- ctx->font = &vgf_default_small;
-
- ctx->text_encoding = k_ui_text_encoding_utf8;
- ui_text( ctx, label_box, entry->name, 1, k_ui_align_middle_left, 0 );
- ctx->text_encoding = k_ui_text_encoding_ascii_vg_extended;
-
- entry_box[1] += entry_box[3];
- entry = entry->prev;
- }
- else
- break;
- }
-
- if( reload_next_time )
- {
- vg_filebrowser_free_entries( browser );
- vg_filebrowser_populate( browser );
- }
-
- ui_rect ok_box, cancel_box;
- ui_split( bottom_bar, k_ui_axis_v, -120, ctx->padding, bottom_bar, ok_box );
- ui_split( bottom_bar, k_ui_axis_v, -80, ctx->padding, bottom_bar, cancel_box );
-
- if( ui_button_text( ctx, cancel_box, "Cancel", 1 ) == k_ui_button_click )
- {
- vg_filebrowser_free_entries( browser );
- result_action = k_filebrowser_action_escape;
- }
-
- if( browser->selected_entry )
- {
- if( ui_button_text( ctx, ok_box, "OK", 1 ) == k_ui_button_click )
- {
- u32 cur_len = strlen( browser->current_path );
- if( (cur_len + strlen( browser->selected_entry->name ) + 2) > sizeof(browser->current_path) )
- vg_fatal_error( "Max path size exceeded." );
- else
- {
- strcat( browser->current_path, "/" );
- strcat( browser->current_path, browser->selected_entry->name );
- }
-
- vg_filebrowser_free_entries( browser );
- result_action = k_filebrowser_action_accept;
- }
- }
- else
- {
- ui_fill( ctx, ok_box, ui_colour( ctx, k_ui_bg ) );
- ui_text( ctx, ok_box, "OK", 1, k_ui_align_middle_center, ui_colour( ctx, k_ui_bg+4 ) );
- }
- }
- else
- {
- ui_text( ctx, panel, dir_open_result_str[browser->open_result], 1, k_ui_align_middle_center,
- ui_colour(ctx,k_ui_yellow) );
- }
-
- return result_action;
-}
-
-void vg_filebrowser_free_entries( struct vg_filebrowser *browser )
-{
- struct vg_filebrowser_entry *entry = browser->whole_list;
-
- while( entry )
- {
- struct vg_filebrowser_entry *prev = entry->prev;
-
- free( entry );
- entry = prev;
- }
-
- browser->whole_list = NULL;
- browser->view_top_entry = NULL;
- browser->selected_entry = NULL;
- browser->entry_count = 0;
- browser->view_top_index = 0;
- browser->slider_value = 0.0f;
-}
-
-void vg_filebrowser_populate( struct vg_filebrowser *browser )
-{
- VG_ASSERT( browser->whole_list == NULL );
-
- vg_dir dir;
- browser->open_result = vg_dir_open( &dir, browser->current_path );
- browser->entry_count = 0;
- browser->view_top_index = 0;
- browser->slider_value = 0.0f;
-
- if( browser->open_result == k_dir_open_is_file )
- {
- if( vg_filebrowser_up( browser ) )
- {
- browser->open_result = vg_dir_open( &dir, browser->current_path );
- }
- }
-
- if( browser->open_result != k_dir_open_ok )
- {
- return;
- }
-
- rax *rt_files = raxNew(),
- *rt_dirs = raxNew();
-
- while( vg_dir_next_entry( &dir ) )
- {
- enum vg_entry_type type = vg_dir_entry_type( &dir );
- if( type == k_vg_entry_type_unknown )
- continue;
-
- const char *entry_name = vg_dir_entry_name( &dir );
-
- enum vg_media_type media_type = k_media_type_none;
- if( type == k_vg_entry_type_file )
- {
- const char *ch = entry_name, *ext = NULL;
- while( *ch )
- {
- if( *ch == '.' )
- ext = (ch+1);
-
- ch ++;
- }
-
- if( ext )
- {
- if( !strcmp( ext, "jpg" ) || !strcmp( ext, "jpeg" ) || !strcmp( ext, "png" ) || !strcmp( ext, "tga" ) ||
- !strcmp( ext, "bmp" ) || !strcmp( ext, "psd" ) )
- {
- media_type = k_media_type_image;
- }
- else if( !strcmp( ext, "mp4" ) || !strcmp( ext, "mkv" ) || !strcmp( ext, "mov" ) )
- {
- media_type = k_media_type_video;
- }
- else if( !strcmp( ext, "opus" ) || !strcmp( ext, "ogg" ) || !strcmp( ext, "mp3" ) || !strcmp( ext, "wav" ) )
- {
- media_type = k_media_type_audio;
- }
- else if( !strcmp( ext, "txt" ) || !strcmp( ext, "conf" ) || !strcmp( ext, "cfg" ) || !strcmp( ext, "c" ) ||
- !strcmp( ext, "h" ) || !strcmp( ext, "py" ) || !strcmp( ext, "sh" ) || !strcmp( ext, "gitignore" ))
- {
- media_type = k_media_type_text;
- }
- }
-
- if( browser->filter )
- {
- if( !((0x1 << media_type) & browser->filter) )
- continue;
- }
- }
-
- u32 len = strlen( entry_name );
- struct vg_filebrowser_entry *entry = malloc( sizeof(struct vg_filebrowser_entry) + len + 1 );
- entry->next = NULL;
- entry->prev = NULL;
- entry->type = type;
- entry->media_type = media_type;
- strcpy( entry->name, entry_name );
-
- if( type == k_vg_entry_type_dir )
- {
- raxInsert( rt_dirs, (u8 *)entry->name, strlen(entry->name), entry, NULL );
- }
- else if( type == k_vg_entry_type_file )
- {
- raxInsert( rt_files, (u8 *)entry->name, strlen(entry->name), entry, NULL );
- }
- else
- continue;
-
- browser->entry_count ++;
- }
- vg_dir_close( &dir );
-
- /* compile lists */
- struct vg_filebrowser_entry *folder_list_head = NULL,
- *folder_list_tail = NULL,
- *file_list_head = NULL;
- raxIterator rt_iter;
- raxStart( &rt_iter, rt_files );
- raxSeek( &rt_iter, "$", NULL, 0 );
- while( raxPrev( &rt_iter ) )
- {
- struct vg_filebrowser_entry *entry = rt_iter.data;
- entry->prev = file_list_head;
- if( file_list_head )
- file_list_head->next = entry;
- file_list_head = entry;
- }
-
- raxStart( &rt_iter, rt_dirs );
- raxSeek( &rt_iter, "$", NULL, 0 );
- while( raxPrev( &rt_iter ) )
- {
- struct vg_filebrowser_entry *entry = rt_iter.data;
- entry->prev = folder_list_head;
- if( folder_list_head )
- folder_list_head->next = entry;
- else
- folder_list_tail = entry;
- folder_list_head = entry;
- }
-
- /* attatch the two lists */
- if( folder_list_head )
- {
- browser->whole_list = folder_list_head;
- folder_list_tail->prev = file_list_head;
-
- if( file_list_head )
- file_list_head->next = folder_list_tail;
- }
- else
- {
- browser->whole_list = file_list_head;
- }
-
- browser->view_top_entry = browser->whole_list;
-
- raxFree( rt_files );
- raxFree( rt_dirs );
-}
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_ui/filebrowser.c"
-#else
-
-struct vg_filebrowser_entry
-{
- struct vg_filebrowser_entry *prev, *next;
-
- enum vg_entry_type type;
- enum vg_media_type
- {
- k_media_type_none = 0,
- k_media_type_image = 1,
- k_media_type_video = 2,
- k_media_type_audio = 3,
- k_media_type_text = 4
- }
- media_type;
-
- char name[];
-};
-
-enum filebrowser_action
-{
- k_filebrowser_action_none,
- k_filebrowser_action_escape,
- k_filebrowser_action_accept
-};
-
-struct vg_filebrowser
-{
- char current_path[ 4096 ];
-
- enum dir_open_result open_result;
-
- struct vg_filebrowser_entry *whole_list, *view_top_entry, *selected_entry;
- u32 entry_count, view_top_index;
- f32 slider_value;
-
- enum filebrowser_mode
- {
- k_filebrowser_mode_pick_folder,
- k_filebrowser_mode_pick_file,
- }
- mode;
-
- u32 filter;
-};
-
-void vg_filebrowser_init( struct vg_filebrowser *browser );
-enum filebrowser_action vg_filebrowser_ui( ui_context *ctx, ui_rect root_rect, struct vg_filebrowser *browser );
-void vg_filebrowser_populate( struct vg_filebrowser *browser );
-void vg_filebrowser_free_entries( struct vg_filebrowser *browser );
-
-void vg_filebrowser_set_path_to_home( struct vg_filebrowser *browser );
-
-#endif
+++ /dev/null
-// TODO move this to the hconf! :D
-#include "vg/vg_default_font.gc"
-
-void ui_init( ui_context *ctx, ui_vert *verts_buf, u32 verts_max, u16 *indices_buf, u32 indices_max )
-{
- ctx->vertex_buffer = verts_buf;
- ctx->max_verts = verts_max;
- ctx->cur_vert = 0;
- ctx->vert_start = 0;
- ctx->indice_buffer = indices_buf;
- ctx->max_indices = indices_max;
- ctx->cur_indice = 0;
- ctx->indice_start = 0;
- ctx->text_encoding = k_ui_text_encoding_ascii_vg_extended;
-
- if( !verts_buf || !indices_buf )
- exit(0);
-}
-
-ui_vert *ui_fill_rect( ui_context *ctx, ui_rect rect, u32 colour, ui_px uv[4] )
-{
- /* this if far from ideal but stops us from crashing */
- if( (ctx->cur_vert + 4 > ctx->max_verts) ||
- (ctx->cur_indice + 6 > ctx->max_indices))
- {
- return &ctx->vertex_buffer[0];
- }
-
- ui_vert *vertices = &ctx->vertex_buffer[ ctx->cur_vert ];
- u16 *indices = &ctx->indice_buffer[ ctx->cur_indice ];
-
- for( int i=0; i<4; i++ )
- vertices[i].colour = colour;
-
- vertices[0].co[0] = rect[0];
- vertices[0].co[1] = rect[1];
- vertices[0].uv[0] = uv[0];
- vertices[0].uv[1] = uv[1];
- vertices[1].co[0] = rect[0]+rect[2];
- vertices[1].co[1] = rect[1];
- vertices[1].uv[0] = uv[2];
- vertices[1].uv[1] = uv[1];
- vertices[2].co[0] = rect[0]+rect[2];
- vertices[2].co[1] = rect[1]+rect[3];
- vertices[2].uv[0] = uv[2];
- vertices[2].uv[1] = uv[3];
- vertices[3].co[0] = rect[0];
- vertices[3].co[1] = rect[1]+rect[3];
- vertices[3].uv[0] = uv[0];
- vertices[3].uv[1] = uv[3];
-
- u16 start = ctx->cur_vert;
- u32 mesh[] = { 0,2,1, 0,3,2 };
-
- for( u32 i=0; i<VG_ARRAY_LEN(mesh); i++ )
- indices[i] = start+mesh[i];
-
- ctx->cur_indice += 6;
- ctx->cur_vert += 4;
-
- return vertices;
-}
-
-ui_vert *ui_fill( ui_context *ctx, ui_rect rect, u32 colour )
-{
- return ui_fill_rect( ctx, rect, colour, (ui_px[4]){ 4,4,4,4 } );
-}
-
-void ui_outline( ui_context *ctx, ui_rect rect, ui_px thickness, u32 colour, u32 mask )
-{
- /* this if far from ideal but stops us from crashing */
- if( (ctx->cur_vert + 8 > ctx->max_verts) ||
- (ctx->cur_indice + 24 > ctx->max_indices))
- return;
-
- ui_vert *vertices = &ctx->vertex_buffer[ ctx->cur_vert ];
- u16 *indices = &ctx->indice_buffer[ ctx->cur_indice ];
-
- for( int i=0; i<8; i++ )
- {
- vertices[i].uv[0] = 4;
- vertices[i].uv[1] = 4;
- vertices[i].colour = colour;
- }
-
- vertices[0].co[0] = rect[0];
- vertices[0].co[1] = rect[1];
- vertices[1].co[0] = rect[0]+rect[2];
- vertices[1].co[1] = rect[1];
- vertices[2].co[0] = rect[0]+rect[2];
- vertices[2].co[1] = rect[1]+rect[3];
- vertices[3].co[0] = rect[0];
- vertices[3].co[1] = rect[1]+rect[3];
- vertices[4].co[0] = vertices[0].co[0]-thickness;
- vertices[4].co[1] = vertices[0].co[1]-thickness;
- vertices[5].co[0] = vertices[1].co[0]+thickness;
- vertices[5].co[1] = vertices[1].co[1]-thickness;
- vertices[6].co[0] = vertices[2].co[0]+thickness;
- vertices[6].co[1] = vertices[2].co[1]+thickness;
- vertices[7].co[0] = vertices[3].co[0]-thickness;
- vertices[7].co[1] = vertices[3].co[1]+thickness;
-
- u16 start = ctx->cur_vert;
- u32 mesh[] = { 0,5,4,0,1,5, 1,6,5,1,2,6, 2,7,6,2,3,7, 3,4,7,3,0,4 };
-
- if( !mask )
- mask = UI_TOP|UI_LEFT|UI_BOTTOM|UI_RIGHT;
-
- u32 c = 0;
- for( u32 i=0; i<VG_ARRAY_LEN(mesh)/6; i++ )
- {
- if( (0x1<<i) & mask )
- {
- for( u32 j=0; j<6; j++ )
- indices[c ++] = start+mesh[i*6+j];
- }
- }
-
- ctx->cur_indice += c;
- ctx->cur_vert += 8;
-}
-
-void rect_copy( ui_rect a, ui_rect b )
-{
- for( int i=0; i<4; i++ )
- b[i] = a[i];
-}
-
-void ui_split( ui_rect rect, enum ui_axis other, ui_px width, ui_px gap,
- ui_rect l, ui_rect r )
-{
- enum ui_axis dir = other ^ 0x1;
-
- if( width < 0 ) width = rect[ 2+dir ] + width;
-
- ui_rect temp;
- rect_copy( rect, temp );
-
- l[ dir ] = temp[ dir ];
- r[ dir ] = temp[ dir ] + width + (gap/2);
- l[ other ] = temp[ other ];
- r[ other ] = temp[ other ];
- l[ 2+dir ] = width - (gap/2);
- r[ 2+dir ] = temp[ 2+dir ] - width - (gap/2);
- l[ 2+other ] = temp[ 2+other ];
- r[ 2+other ] = temp[ 2+other ];
-}
-
-void ui_split_ratio( ui_rect rect, enum ui_axis dir, float ratio,
- ui_px gap, ui_rect l, ui_rect r )
-{
- ui_px width = (float)rect[ 2+(dir^0x1) ] * ratio;
- ui_split( rect, dir, width, gap, l, r );
-}
-
-void ui_rect_pad( ui_rect rect, ui_px pad[2] )
-{
- rect[0] += pad[0];
- rect[1] += pad[1];
- rect[2] -= pad[0]*2;
- rect[3] -= pad[1]*2;
-}
-
-static ui_px ui_min( ui_px a, ui_px b ){ return a<b?a:b; }
-static ui_px ui_max( ui_px a, ui_px b ){ return a>b?a:b; }
-static ui_px ui_clamp( ui_px a, ui_px min, ui_px max )
-{
- return ui_min( max, ui_max( a, min ) );
-}
-
-int ui_clip( ui_rect parent, ui_rect child, ui_rect clipped )
-{
- ui_px parent_max[2], child_max[2];
- parent_max[0] = parent[0]+parent[2];
- parent_max[1] = parent[1]+parent[3];
- child_max[0] = child[0]+child[2];
- child_max[1] = child[1]+child[3];
-
- clipped[0] = ui_clamp( child[0], parent[0], parent_max[0] );
- clipped[1] = ui_clamp( child[1], parent[1], parent_max[1] );
- clipped[2] = ui_clamp( child_max[0], parent[0], parent_max[0] );
- clipped[3] = ui_clamp( child_max[1], parent[1], parent_max[1] );
-
- if( clipped[0] == clipped[2] ||
- clipped[1] == clipped[3] )
- return 0;
-
- clipped[2] -= clipped[0];
- clipped[3] -= clipped[1];
-
- return 1;
-}
-
-int ui_inside_rect( ui_rect rect, ui_px co[2] )
-{
- if( co[0] >= rect[0] &&
- co[1] >= rect[1] &&
- co[0] < rect[0]+rect[2] &&
- co[1] < rect[1]+rect[3] ){
- return 1;
- }
- else
- return 0;
-}
-
-int ui_click_down( ui_context *ctx, u32 mask )
-{
- if( ctx->ignore_input_frames ) return 0;
- if( (ctx->mouse_state[0] & mask) &&
- !(ctx->mouse_state[1] & mask) )
- return 1;
- else
- return 0;
-}
-
-int ui_clicking( ui_context *ctx, u32 mask )
-{
- if( ctx->ignore_input_frames ) return 0;
- return ctx->mouse_state[0] & mask;
-}
-
-int ui_click_up( ui_context *ctx, u32 mask )
-{
- if( ctx->ignore_input_frames ) return 0;
- if( (ctx->mouse_state[1] & mask) &&
- !(ctx->mouse_state[0] & mask) )
- return 1;
- else
- return 0;
-}
-
-void ui_update_mouse( ui_context *ctx, ui_px mouse[2], i32 mouse_state )
-{
- ctx->mouse_state[1] = ctx->mouse_state[0];
- ctx->mouse_state[0] = mouse_state;
- ctx->mouse_delta[0] = mouse[0]-ctx->mouse_click[0];
- ctx->mouse_delta[1] = mouse[1]-ctx->mouse_click[1];
-
- if( !ctx->mouse_pos_overriden )
- {
- ctx->mouse[0] = mouse[0];
- ctx->mouse[1] = mouse[1];
- }
-
- if( ctx->ignore_input_frames )
- {
- ctx->ignore_input_frames --;
- return;
- }
-
- if( ui_click_down(ctx, UI_MOUSE_ANY) )
- {
- ctx->mouse_click[0] = ctx->mouse[0];
- ctx->mouse_click[1] = ctx->mouse[1];
- }
-}
-
-void ui_prerender( ui_context *ctx )
-{
- ctx->cur_vert = 0;
- ctx->cur_indice = 0;
- ctx->vert_start = 0;
- ctx->indice_start = 0;
- ctx->focused_control_hit = 0;
- ctx->cursor = k_ui_cursor_default;
- ctx->wants_mouse = 0;
- ctx->mouse_pos_overriden = 0;
-}
-
-void ui_set_area( ui_context *ctx, i32 width, i32 height )
-{
- ctx->area[0] = width;
- ctx->area[1] = height;
-}
-
-void ui_ignore_input_frames( ui_context *ctx, u32 frames )
-{
- ctx->ignore_input_frames = frames;
-}
-
-void ui_capture_mouse( ui_context *ctx, bool on )
-{
- ctx->wants_mouse = on;
-}
-
-void ui_flush( ui_context *ctx, enum ui_shader shader, void *shader_data )
-{
- ui_batch batch;
- batch.vert_offset = ctx->vert_start * sizeof(ui_vert);
- batch.indice_offset = ctx->indice_start * sizeof(u16);
- batch.vert_buf = ctx->vertex_buffer + ctx->vert_start;
- batch.vert_count = ctx->cur_vert - ctx->vert_start;
- batch.indice_buf = ctx->indice_buffer + ctx->indice_start;
- batch.indice_count = ctx->cur_indice - ctx->indice_start;
-
- ctx->render_batch( ctx, &batch, shader, shader_data );
-
- ctx->indice_start = ctx->cur_indice;
- ctx->vert_start = ctx->cur_vert;
-}
-
-void ui_rect_center( ui_rect parent, ui_rect rect )
-{
- rect[0] = parent[0] + (parent[2]-rect[2])/2;
- rect[1] = parent[1] + (parent[3]-rect[3])/2;
-}
-
-void ui_fit_item( ui_rect rect, ui_px size[2], ui_rect d )
-{
- i32 rp = (i32)rect[2] * (i32)size[1],
- rc = (i32)size[0] * (i32)rect[3];
-
- enum ui_axis dir, other;
- if( rc > rp ) dir = k_ui_axis_h;
- else dir = k_ui_axis_v;
- other = dir ^ 0x1;
-
- d[2+dir] = rect[2+dir];
- d[2+other] = (rect[2+dir] * size[other]) / size[dir];
-
- ui_rect_center( rect, d );
-}
-
-ui_px ui_text_line_width( ui_context *ctx, const char *str )
-{
- int length = 0;
- const char *_c = str;
- u8 c;
-
- while( (c = *(_c ++)) )
- {
- /* skip vt colour codes */
- if( c == '\x1B' )
- {
- while( (c = *(_c ++)) )
- {
- if( c == 'm' )
- break;
- }
-
- if( c == 0 ) break;
- else continue;
- }
-
- if( c >= 32 ) length ++;
- else if( c == '\n' ) break;
- }
-
- return length * ctx->font->sx;
-}
-
-ui_px ui_text_string_height( ui_context *ctx, const char *str )
-{
- int height = 1;
- const char *_c = str;
- u8 c;
-
- while( (c = *(_c ++)) )
- {
- if( c == '\n' ) height ++;
- }
-
- return height * ctx->font->sy;
-}
-
-ui_px ui_text_aligned_x( ui_context *ctx,
- const char *str, ui_rect rect, ui_px scale,
- enum ui_align align )
-{
- enum ui_align lwr = k_ui_align_lwr & align;
- if( lwr == k_ui_align_left ){
- return rect[0];
- }
- else{
- ui_px width = ui_text_line_width( ctx, str ) * scale;
-
- if( lwr == k_ui_align_right )
- return rect[0] + rect[2]-width;
- else
- return rect[0] + (rect[2]-width)/2;
- }
-}
-
-u32 ui_colour( ui_context *ctx, enum ui_scheme_colour id )
-{
- return ctx->scheme[ id ];
-}
-
-/* get an appropriately contrasting colour given the base */
-u32 ui_colourcont( ui_context *ctx, enum ui_scheme_colour id )
-{
- if ( id < k_ui_bg+6 ) return ui_colour(ctx, k_ui_fg );
- else if( id < k_ui_fg ) return ui_colour(ctx, k_ui_bg+1 );
- else if( id < k_ui_hue ) return ui_colour(ctx, k_ui_bg+3 );
- else if( id < k_ui_red+k_ui_brighter ) return ui_colour(ctx, k_ui_fg );
- else return ui_colour(ctx, k_ui_fg+1 );
-}
-
-void ui_hex_to_norm( u32 hex, v4f norm )
-{
- norm[0] = ((hex ) & 0xff);
- norm[1] = ((hex>>8 ) & 0xff);
- norm[2] = ((hex>>16) & 0xff);
- norm[3] = ((hex>>24) & 0xff);
- v4_muls( norm, 1.0f/255.0f, norm );
-}
-
-u32 v4f_u32_colour( v4f colour )
-{
- u32 r = colour[0] * 255.0f,
- g = colour[1] * 255.0f,
- b = colour[2] * 255.0f,
- a = colour[3] * 255.0f;
-
- return r | (g<<8) | (b<<16) | (a<<24);
-}
-
-static void ui_text_glyph( const struct vg_font_face *ff, u8 glyph, ui_rect out_texcoords )
-{
- const vg_font_char *ch = &ff->map[ glyph ];
-
- out_texcoords[0] = ch->x;
- out_texcoords[1] = ch->y;
- out_texcoords[2] = ch->x + ff->cw;
- out_texcoords[3] = ch->y + ff->ch;
-}
-
-u32 ui_opacity( u32 colour, f32 opacity )
-{
- u32 alpha = opacity * 255.0f;
- return (colour & 0x00ffffff) | (alpha << 24);
-}
-
-u32 ui_ntext( ui_context *ctx,
- ui_rect rect, const char *str, u32 len, ui_px scale,
- enum ui_align align, u32 colour )
-{
- if( str == NULL )
- str = "NULL";
-
- ui_px glow_text = 0;
-
- ui_rect text_cursor;
- if( colour == 0 )
- colour = ui_colour( ctx, k_ui_fg );
-
- colour &= 0x00ffffff;
-
- const char *_c = str;
- u8 c;
-
- text_cursor[0] = ui_text_aligned_x( ctx, str, rect, scale, align );
- text_cursor[1] = rect[1];
- text_cursor[2] = ctx->font->cw*scale;
- text_cursor[3] = ctx->font->ch*scale;
-
- u32 printed_chars = 0;
-
- if( align & (k_ui_align_middle|k_ui_align_bottom) )
- {
- ui_px height = ui_text_string_height( ctx, str ) * scale;
-
- if( align & k_ui_align_bottom )
- text_cursor[1] += rect[3]-height;
- else
- text_cursor[1] += (rect[3]-height)/2;
- }
-
- u32 utf8_counter = 0;
-
- while( (c = *(_c ++)) )
- {
- if( ctx->text_encoding == k_ui_text_encoding_utf8 )
- {
- if( utf8_counter )
- {
- c = 0xbe;
- utf8_counter --;
- }
- else
- {
- if ( (c & 0xe0) == 0xc0 ) utf8_counter = 1;
- else if( (c & 0xf0) == 0xe0 ) utf8_counter = 2;
- else if( (c & 0xf8) == 0xf0 ) utf8_counter = 3;
-
- if( utf8_counter )
- c = 0xbd;
- }
- }
-
- if( printed_chars >= len )
- {
- printed_chars = 0;
- text_cursor[1] += ctx->font->sy*scale;
- text_cursor[0] = ui_text_aligned_x( ctx, _c, rect, scale, align );
- text_cursor[0] -= ctx->font->sx*scale;
-
- ui_rect glyph;
- ui_text_glyph( ctx->font, '\xb1' /*FIXME*/, glyph );
- ui_fill_rect( ctx, text_cursor, 0x00ffffff, glyph );
- text_cursor[0] += ctx->font->sx*scale;
- }
-
- if( c == '\n' )
- {
- text_cursor[1] += ctx->font->sy*scale + ctx->kern[1];
- text_cursor[0] = ui_text_aligned_x( ctx, _c, rect, scale, align );
- printed_chars = 0;
- continue;
- }
- else if( c >= 33 )
- {
- ui_rect glyph;
- ui_text_glyph( ctx->font, c, glyph );
-
- ui_rect cursor_clipped;
- if( ui_clip( rect, text_cursor, cursor_clipped ) )
- {
- if( glow_text )
- {
- cursor_clipped[1] += glow_text;
- ui_fill_rect( ctx, cursor_clipped, 0x00ffffff, glyph );
- cursor_clipped[1] -= glow_text;
- }
-
- ui_fill_rect( ctx, cursor_clipped, colour, glyph );
- }
- }
- else if( c == '\x1B' )
- {
- /* vt codes */
- _c ++;
- u16 colour_id = 0;
- for( int i=0; i<3; i ++ )
- {
- if( _c[i] )
- {
- if( _c[i] == 'm' )
- {
- _c = _c + i + 1;
-
- switch( colour_id ){
- case '0': colour = ui_colour(ctx, k_ui_fg ); break;
- case '3'|'0'<<8: colour = ui_colour(ctx, k_ui_bg ); break;
- case '3'|'1'<<8: colour = ui_colour(ctx, k_ui_red ); break;
- case '3'|'2'<<8: colour = ui_colour(ctx, k_ui_green ); break;
- case '3'|'3'<<8: colour = ui_colour(ctx, k_ui_yellow ); break;
- case '3'|'4'<<8: colour = ui_colour(ctx, k_ui_blue ); break;
- case '3'|'5'<<8: colour = ui_colour(ctx, k_ui_purple ); break;
- case '3'|'6'<<8: colour = ui_colour(ctx, k_ui_aqua ); break;
- case '3'|'7'<<8: colour = 0xffffffff; break;
- }
-
- colour &= 0x00ffffff;
- break;
- }
-
- colour_id |= _c[i] << (i*8);
- }
- else
- {
- _c = _c +i;
- break;
- }
- }
-
- continue;
- }
- else if( c == '\x06' )
- {
- glow_text = *_c;
- _c ++;
- continue;
- }
- else if( c == '\x07' )
- {
- glow_text = 0;
- colour = ui_colour( ctx, k_ui_fg ) & 0x00ffffff;
- continue;
- }
- else if( c == '\t' )
- {
- text_cursor[0] += ctx->font->sx*scale*4;
- printed_chars += 4;
- continue;
- }
-
- text_cursor[0] += ctx->font->sx*scale;
- printed_chars ++;
- }
-
- return printed_chars;
-}
-
-u32 ui_text( ui_context *ctx, ui_rect rect, const char *str, ui_px scale, enum ui_align align, u32 colour )
-{
- return ui_ntext( ctx, rect, str, 1024, scale, align, colour );
-}
-
-/*
- * Standard layout stuff
- * -----------------------------------------------------------------------------
- */
-
-void ui_panel( ui_context *ctx, ui_rect in_rect, ui_rect out_panel )
-{
- //ui_fill( ctx, in_rect, ui_colour(ctx, k_ui_bg+1 ) );
- ui_fill( ctx, in_rect, ui_opacity( ui_colour( ctx, k_ui_bg+1 ), 0.7f ) );
- ui_outline( ctx, in_rect, 1, ui_colour(ctx, k_ui_bg+7 ), 0 );
- rect_copy( in_rect, out_panel );
- ui_rect_pad( out_panel, (ui_px[2]){ 8, 8 } );
-}
-
-void ui_label( ui_context *ctx,
- ui_rect rect, const char *text, ui_px size,
- ui_px gap, ui_rect r )
-{
- ui_rect l;
- ui_px width = (ui_text_line_width(ctx,text)+ctx->font->sx) * size;
- ui_split( rect, k_ui_axis_v, width, gap, l, r );
- ui_text( ctx, l, text, 1, k_ui_align_middle_left, 0 );
-}
-
-ui_px ui_standard_widget_height( ui_context *ctx, ui_px count )
-{
- return (count * ctx->font->sy + 18) * ctx->scale;
-}
-
-void ui_standard_widget( ui_context *ctx, ui_rect inout_panel, ui_rect out_rect, ui_px count )
-{
- ui_px height = ui_standard_widget_height( ctx, count );
- ui_split( inout_panel, k_ui_axis_h, height, ctx->padding, out_rect, inout_panel );
-}
-
-void ui_info( ui_context *ctx, ui_rect inout_panel, const char *text )
-{
- ui_rect box;
- ui_standard_widget( ctx, inout_panel, box, 1 );
- ui_text( ctx, box, text, 1, k_ui_align_middle_left, 0 );
-}
-
-void ui_spacer( ui_context *ctx, ui_rect inout_panel )
-{
- ui_rect box;
- ui_standard_widget( ctx, inout_panel, box, 1 );
-
- ui_rect inner;
- rect_copy( box, inner );
- inner[3] = 1;
- inner[2] -= 16;
- ui_rect_center( box, inner );
- ui_fill( ctx, inner, ui_colour( ctx, k_ui_bg+6 ) );
-}
-
-void ui_image( ui_context *ctx, ui_rect rect, void *image_resource, bool flip )
-{
- ui_flush( ctx, k_ui_shader_colour, NULL );
- if( flip )
- ui_fill_rect( ctx, rect, 0xffffffff, (ui_px[4]){ 0,0,256,256 } );
- else
- ui_fill_rect( ctx, rect, 0xffffffff, (ui_px[4]){ 0,256,256,0 } );
- ui_flush( ctx, k_ui_shader_image, image_resource );
-}
-
-void ui_defocus_all( ui_context *ctx )
-{
- if( ctx->focused_control_type == k_ui_control_textbox )
- {
- ctx->stop_text_input();
- if( ctx->textbox.callbacks.escape )
- ctx->textbox.callbacks.escape( ctx, ctx->textbox.callbacks.userdata );
- }
-
- ctx->focused_control_id = NULL;
- ctx->focused_control_hit = 0;
- ctx->focused_control_type = k_ui_control_none;
-}
-
-enum ui_button_state ui_button_base( ui_context *ctx, ui_rect rect )
-{
- int clickup= ui_click_up(ctx, UI_MOUSE_LEFT),
- click = ui_clicking(ctx, UI_MOUSE_LEFT) | clickup,
- target = ui_inside_rect( rect, ctx->mouse_click ) && click,
- hover = ui_inside_rect( rect, ctx->mouse );
-
- if( ctx->focused_control_type != k_ui_control_none )
- {
- clickup = 0;
- click = 0;
- target = 0;
- hover = 0;
- }
-
- if( hover )
- ctx->cursor = k_ui_cursor_hand;
-
- if( click )
- {
- if( target )
- {
- if( hover )
- {
- if( clickup )
- {
- ui_ignore_input_frames( ctx, 2 );
- ui_defocus_all( ctx );
- return k_ui_button_click;
- }
- else return k_ui_button_holding_inside;
- }
- else return k_ui_button_holding_outside;
- }
- else return k_ui_button_none;
- }
- else
- {
- if( hover ) return k_ui_button_hover;
- else return k_ui_button_none;
- }
-}
-
-/* TODO: split this out into a formatless button and one that auto fills */
-enum ui_button_state ui_colourbutton( ui_context *ctx, ui_rect rect,
- enum ui_scheme_colour colour,
- enum ui_scheme_colour hover_colour,
- enum ui_scheme_colour hi_colour )
-{
- enum ui_button_state state = ui_button_base( ctx, rect );
-
- u32 col_base = ctx->scheme[ colour ],
- col_highlight = ctx->scheme[ hi_colour? hi_colour: k_ui_fg ],
- col_hover = ctx->scheme[ hover_colour? hover_colour: colour + k_ui_brighter ];
-
- if( state == k_ui_button_click )
- {
- ui_fill( ctx, rect, col_highlight );
- rect_copy( rect, ctx->click_fader );
- rect_copy( rect, ctx->click_fader_end );
- ctx->click_fader_end[3] = 0;
- ui_rect_center( rect, ctx->click_fader_end );
- ctx->click_fade_opacity = 1.0f;
- }
- else if( state == k_ui_button_holding_inside )
- {
- ui_fill( ctx, rect, col_highlight );
- }
- else if( state == k_ui_button_holding_outside )
- {
- ui_fill( ctx, rect, col_base );
- ui_outline( ctx, rect, 1, col_highlight, 0 );
- }
- else if( state == k_ui_button_hover )
- {
- ui_fill( ctx, rect, col_hover );
- }
- else ui_fill( ctx, rect, col_base );
-
- return state;
-}
-
-enum ui_button_state ui_colourbutton_text(
- ui_context *ctx,
- ui_rect rect, const char *string, ui_px scale,
- enum ui_scheme_colour colour )
-{
- enum ui_button_state state = ui_colourbutton( ctx, rect, colour, 0, 0 );
-
- u32 text_colour = ui_colourcont( ctx, colour );
- if( state == k_ui_button_holding_inside )
- text_colour = colour;
-
- ui_text( ctx, rect, string, scale, k_ui_align_middle_center, text_colour );
- return state;
-}
-
-enum ui_button_state ui_button_text( ui_context *ctx, ui_rect rect,
- const char *string, ui_px scale )
-{
- return ui_colourbutton_text( ctx, rect, string, scale, k_ui_bg+4 );
-}
-
-enum ui_button_state ui_button( ui_context *ctx,
- ui_rect inout_panel, const char *string )
-{
- ui_rect rect;
- ui_standard_widget( ctx, inout_panel, rect, 1 );
- return ui_colourbutton_text( ctx, rect, string, 1, k_ui_bg+4 );
-}
-
-static void ui_enum_post( ui_context *ctx );
-void ui_postrender( ui_context *ctx, f32 delta_time )
-{
- if( ctx->click_fade_opacity > 0.0f )
- {
- float scale = ctx->click_fade_opacity;
- scale = vg_maxf( 1.0f/255.0f, scale*scale );
-
- ctx->click_fade_opacity -= delta_time * 3.8f;
- u32 colour = (0x00ffffff & ui_colour(ctx,k_ui_fg))|0x7f000000;
-
- v4f begin, end, dest;
- for( int i=0; i<4; i++ ){
- begin[i] = ctx->click_fader[i];
- end[i] = ctx->click_fader_end[i]+1;
- }
-
- v4_lerp( end, begin, scale, dest );
-
- ui_rect rect;
- for( int i=0; i<4; i++ ){
- rect[i] = dest[i];
- }
-
- ui_fill( ctx, rect, colour );
- }
-
- if( ctx->focused_control_type == k_ui_control_enum )
- {
- ui_enum_post( ctx );
- }
- else if( ctx->focused_control_type == k_ui_control_modal )
- {
- ui_rect screen = { 0,0, ctx->area[0], ctx->area[1] };
- ui_fill( ctx, screen, 0xa0000000 );
- ui_rect box = {0,0,416,216};
-
- u32 colour = ui_colour(ctx,k_ui_fg),
- type = ctx->modal.options & UI_MODAL_TYPE_BITS;
- if ( type == 1 ) colour = ui_colour(ctx,k_ui_green);
- else if( type == 2 ) colour = ui_colour(ctx,k_ui_red);
- else if( type == 3 ) colour = ui_colour(ctx,k_ui_yellow);
-
- ui_rect_center( screen, box );
- ui_fill( ctx, box, ui_colour(ctx,k_ui_bg) );
- ui_outline( ctx, box, -1, colour, 0 );
- ui_rect_pad( box, (ui_px[]){8,8} );
-
- ui_rect message;
- rect_copy( box, message );
- message[3] = 150;
- ui_rect_center( box, message );
-
- ui_rect row0, row1;
- ui_split( message, k_ui_axis_h, -28, 0, row0, row1 );
- row0[0] += ctx->font->sx;
- ui_ntext( ctx, row0, ctx->modal.message, (box[2]/ctx->font->sx)-2, 1, k_ui_align_left, colour );
-
- ui_rect btn_ok;
- ui_split( row1, k_ui_axis_v, -120, 8, row1, btn_ok );
-
- ctx->focused_control_type = k_ui_control_none; /* HACK */
-
- bool close_modal = 0;
- if( ctx->modal.options & UI_MODAL_CANCEL )
- {
- ui_rect btn_cancel;
- ui_split( row1, k_ui_axis_v, -120, 8, row1, btn_cancel );
- if( ui_button_text( ctx, btn_cancel, "Cancel", 1 ) == k_ui_button_click )
- {
- if( ctx->modal.callbacks.close )
- ctx->modal.callbacks.close( UI_MODAL_CANCEL );
-
- close_modal = 1;
- }
- }
-
- if( ui_button_text( ctx, btn_ok, ctx->modal.ok_text, 1 ) == k_ui_button_click )
- {
- if( ctx->modal.callbacks.close )
- ctx->modal.callbacks.close( 0 );
-
- close_modal = 1;
- }
-
- if( !close_modal )
- ctx->focused_control_hit = 1;
-
- ctx->focused_control_type = k_ui_control_modal; /* HACK */
- ctx->wants_mouse = 1;
- }
-
- ui_flush( ctx, k_ui_shader_colour, NULL );
-
- if( !ctx->focused_control_hit )
- {
- ui_defocus_all( ctx );
- }
-}
-
-/*
- * checkbox
- * -----------------------------------------------------------------------------
- */
-
-enum ui_button_state ui_checkbox_base( ui_context *ctx, ui_rect box, i32 *data )
-{
- enum ui_button_state state = ui_button_base( ctx, box );
- if( state == k_ui_button_click )
- *data = (*data) ^ 0x1;
- return state;
-}
-
-int ui_checkbox( ui_context *ctx,
- ui_rect inout_panel, const char *str_label, i32 *data )
-{
- ui_rect rect, label, box;
- ui_standard_widget( ctx, inout_panel, rect, 1 );
-
- ui_split( rect, k_ui_axis_v, -rect[3], 0, label, box );
- ui_text( ctx, label, str_label, ctx->scale, k_ui_align_middle_left, 0 );
-
- enum ui_button_state state = ui_checkbox_base( ctx, box, data );
-
- if( state == k_ui_button_holding_inside )
- {
- ui_fill( ctx, box, ui_colour(ctx,k_ui_bg+2) );
- ui_outline( ctx, box, 1, ui_colour(ctx,k_ui_fg), 0 );
- }
- else if( state == k_ui_button_holding_outside )
- {
- ui_fill( ctx, box, ui_colour(ctx,k_ui_bg) );
- ui_outline( ctx, box, 1, ui_colour(ctx,k_ui_fg), 0 );
- }
- else if( state == k_ui_button_hover )
- {
- ui_fill( ctx, box, ui_colour(ctx,k_ui_bg) );
- ui_outline( ctx, box, 1, ui_colour(ctx,k_ui_fg), 0 );
- }
- else
- {
- ui_fill( ctx, box, ui_colour(ctx,k_ui_bg) );
- ui_outline( ctx, box, 1, ui_colour(ctx,k_ui_bg+4), 0 );
- }
-
- bool changed = (state == k_ui_button_click);
-
- if( *data )
- {
- ui_rect_pad( box, (ui_px[2]){4,4} );
- ui_fill( ctx, box, ui_colour(ctx, k_ui_orange ) );
- }
-
- return changed;
-}
-
-/*
- * Dropdown / Enum
- * -----------------------------------------------------------------------------
- */
-
-/*
- * unfortunately no return value since we only find out that event in the
- * postrender step.
- */
-void ui_enum( ui_context *ctx, ui_rect inout_panel, const char *str_label,
- struct ui_enum_opt *options, u32 len, i32 *value )
-{
- ui_rect rect, box;
- ui_standard_widget( ctx, inout_panel, rect, 1 );
-
- if( str_label )
- ui_label( ctx, rect, str_label, ctx->scale, 0, box );
- else
- rect_copy( rect, box );
-
- const char *display = "OUT OF RANGE";
- int valid = 0;
- for( u32 i=0; i<len; i ++ )
- {
- if( *value == options[i].value )
- {
- display = options[i].alias;
- valid = 1;
- break;
- }
- }
-
- if( ui_button_text( ctx, box, display, ctx->scale ) == 1 )
- {
- ctx->focused_control_type = k_ui_control_enum;
- ctx->ptr_enum = value;
- ctx->_enum.option_count = len;
- ctx->_enum.options = options;
- rect_copy( box, ctx->_enum.rect );
- }
-
- if( !valid )
- ui_outline( ctx, box, 1, ui_colour(ctx,k_ui_red), 0 );
-}
-
-static void ui_enum_post( ui_context *ctx )
-{
- ui_rect drawer;
- rect_copy( ctx->_enum.rect, drawer );
- drawer[3] *= ctx->_enum.option_count;
-
- int close = 0;
- int clickany= ui_click_up( ctx, UI_MOUSE_ANY ),
- hover = ui_inside_rect( drawer, ctx->mouse );
-
- if( clickany && !hover )
- return;
-
- /* HACK */
- ctx->focused_control_type = k_ui_control_none;
- i32 *value = ctx->ptr_enum;
-
- for( u32 i=0; i<ctx->_enum.option_count; i++ ){
- ui_rect button;
- ui_split( drawer, k_ui_axis_h, ctx->_enum.rect[3], 0, button,drawer );
-
- enum ui_scheme_colour colour = k_ui_bg+3;
- if( ctx->_enum.options[i].value == *value )
- colour = k_ui_orange;
-
- if( ui_colourbutton_text( ctx, button, ctx->_enum.options[i].alias,
- ctx->scale, colour ) == 1 ){
- *value = ctx->_enum.options[i].value;
- close = 1;
- }
- }
-
- /* HACK */
- ctx->focused_control_type = k_ui_control_enum;
-
- if( !close )
- ctx->focused_control_hit = 1;
-}
-
-/*
- * Slider
- * -----------------------------------------------------------------------------
- */
-
-enum ui_button_state ui_slider_base( ui_context *ctx, ui_rect box, enum ui_axis axis,
- f32 min, f32 max, f32 *value, f32 *out_t )
-{
- enum ui_button_state mask_using = k_ui_button_holding_inside |
- k_ui_button_holding_outside |
- k_ui_button_click,
- state = ui_button_base( ctx, box );
-
- f32 t;
- if( state & mask_using )
- {
- t = vg_clampf( (f32)(ctx->mouse[axis] - box[axis]) / (f32)( box[2+axis] ), 0,1 );
- *value = vg_lerpf( min, max, t );
- }
- else
- t = vg_clampf( (*value - min) / (max-min), 0.0f, 1.0f );
-
- *out_t = t;
-
- return state;
-}
-
-void ui_slider_text( ui_context *ctx, ui_rect box, const char *format, f32 value )
-{
- /* TODO: replace this one day with our own function */
- char buf[32];
- snprintf( buf, sizeof(buf), format? format: "%.2f", value );
- ui_text( ctx, box, buf, 1, k_ui_align_middle_center, 0 );
-}
-
-bool ui_slider_standard( ui_context *ctx, ui_rect box, f32 min, f32 max, f32 *value, const char *format )
-{
- f32 t;
-
- enum ui_button_state mask_using =
- k_ui_button_holding_inside |
- k_ui_button_holding_outside |
- k_ui_button_click,
- mask_brighter = mask_using | k_ui_button_hover,
- state = ui_slider_base( ctx, box, k_ui_axis_h, min, max, value, &t );
-
- ui_rect line = { box[0], box[1], t * (f32)box[2], box[3] };
- ui_fill( ctx, line, ui_colour(ctx,state&mask_brighter? k_ui_bg+4: k_ui_bg+2) );
- ui_fill( ctx, (ui_rect){ box[0]+line[2], box[1], box[2]-line[2], box[3] }, ui_colour(ctx, k_ui_bg ) );
- ui_outline( ctx, box, 1, ui_colour(ctx,state? k_ui_fg+3: k_ui_bg+3), 0 );
- ui_slider_text( ctx, box, format, *value );
-
- return (state & mask_using) && 1;
-}
-
-bool ui_slider( ui_context *ctx, ui_rect inout_panel, const char *str_label,
- f32 min, f32 max, f32 *value )
-{
- ui_rect rect, label, box;
- ui_standard_widget( ctx, inout_panel, rect, 1 );
- ui_label( ctx, rect, str_label, ctx->scale, 0, box );
- return ui_slider_standard( ctx, box, min, max, value, NULL );
-}
-
-/*
- * Colour picker
- * -----------------------------------------------------------------------------
- */
-
-bool ui_colourpicker( ui_context *ctx, ui_rect inout_panel, const char *str_label, v4f value, enum ui_colour_type type )
-{
- ui_rect widget, left, right;
- ui_standard_widget( ctx, inout_panel, widget, 8 );
- ui_split_ratio( widget, k_ui_axis_v, 0.5f, 8, left, right );
-
- ui_rect sliders[4];
- ui_split_ratio( right, k_ui_axis_h, 0.5f, 2, sliders[0], sliders[2] );
- ui_split_ratio( sliders[0], k_ui_axis_h, 0.5f, 2, sliders[0], sliders[1] );
- ui_split_ratio( sliders[2], k_ui_axis_h, 0.5f, 2, sliders[2], sliders[3] );
-
- v4f hsv;
- vg_rgb_hsv( value, hsv );
- hsv[3] = value[3];
-
- enum ui_button_state modified = 0x00;
-
- for( u32 i=0; i<4; i ++ )
- {
- const char *labels[] = { "hue %.2f", "sat %.2f", "lum %.2f", "alpha %.2f" };
-
- if( (i == 3) && (type == k_ui_colour_type_rgb) )
- {
- ui_fill( ctx, sliders[i], ui_colour( ctx, k_ui_bg ) );
- ui_text( ctx, sliders[i], "alpha 1.0", 1, k_ui_align_middle_center, ui_colour( ctx, k_ui_bg+3 ) );
- }
- else
- modified |= ui_slider_standard( ctx, sliders[i], 0.0f, 1.0f, hsv+i, labels[i] );
- }
-
- ui_rect preview, square;
- ui_split_ratio( left, k_ui_axis_v, 0.8f, 8, square, preview );
-
- u32 state = ui_button_base( ctx, square );
- modified |= state;
-
- enum ui_button_state
- mask_using =
- k_ui_button_holding_inside |
- k_ui_button_holding_outside |
- k_ui_button_click;
-
- if( state & mask_using )
- {
- for( u32 i=0; i<2; i ++ ){
- hsv[1+i] = vg_clampf(
- (f32)(ctx->mouse[i] - square[i]) / (f32)(square[2+i]),
- 0.0f, 1.0f );
- }
-
- hsv[2] = 1.0f-hsv[2];
- }
-
- if( modified & (k_ui_button_click|k_ui_button_holding_inside|k_ui_button_holding_outside) )
- {
- vg_hsv_rgb( hsv, value );
- value[3] = hsv[3];
- }
-
- ui_outline( ctx, square, 1, ui_colour(ctx, state? k_ui_fg+3: k_ui_bg+3 ), 0 );
-
- /* preview colour */
- v4f colour;
- vg_hsv_rgb( hsv, colour );
- colour[3] = 1.0f;
- ui_fill( ctx, preview, v4f_u32_colour( colour ) );
-
- /* Draw hsv shader thingy */
- ui_flush( ctx, k_ui_shader_colour, NULL );
- ui_fill_rect( ctx, square, 0xffffffff, (ui_px[4]){ 0,256,256,0 } );
-
- struct ui_batch_shader_data_hsv inf = { .hue = hsv[0] };
- ui_flush( ctx, k_ui_shader_hsv, &inf );
-
- ui_rect marker = { square[0] + hsv[1] * (f32)square[2] - 4,
- square[1] + (1.0f-hsv[2]) * (f32)square[3] - 4,
- 8, 8 },
- lx = { square[0],
- square[1] + (1.0f-hsv[2]) * (f32)square[3],
- square[2], 1 },
- ly = { square[0] + hsv[1] * (f32)square[2],
- square[1],
- 1, square[3] };
-
- ui_fill( ctx, marker, ui_colour(ctx, k_ui_fg ) );
- ui_fill( ctx, lx, ui_colour(ctx, k_ui_fg ) );
- ui_fill( ctx, ly, ui_colour(ctx, k_ui_fg ) );
-
- return modified? 1: 0;
-}
-
-/*
- * Textbox chaos
- * -----------------------------------------------------------------------------
- */
-
-static void _ui_textbox_make_selection( ui_context *ctx, int *start, int *end )
-{
- *start = VG_MIN( ctx->textbox.cursor_pos, ctx->textbox.cursor_user );
- *end = VG_MAX( ctx->textbox.cursor_pos, ctx->textbox.cursor_user );
-}
-
-void _ui_textbox_move_cursor( ui_context *ctx, int *cursor0, int *cursor1,
- int dir, int snap_together )
-{
- *cursor0 = VG_MAX( 0, ctx->textbox.cursor_user + dir );
- *cursor0 =
- VG_MIN(
- VG_MIN( ctx->textbox.len-1, strlen( ctx->textbuf )),
- *cursor0 );
-
- if( snap_together )
- *cursor1 = *cursor0;
-}
-
-static int _ui_textbox_makeroom( ui_context *ctx, int datastart, int length )
-{
- int move_to = VG_MIN( datastart+length, ctx->textbox.len-1 );
- int move_amount = strlen( ctx->textbuf )-datastart;
- int move_end = VG_MIN( move_to+move_amount, ctx->textbox.len-1 );
- move_amount = move_end-move_to;
-
- if( move_amount )
- memmove( &ctx->textbuf[ move_to ],
- &ctx->textbuf[ datastart ],
- move_end-move_to );
-
- ctx->textbuf[ move_end ] = '\0';
-
- return VG_MIN( length, ctx->textbox.len-datastart-1 );
-}
-
-int _ui_textbox_delete_char( ui_context *ctx, int direction )
-{
- int start, end;
- _ui_textbox_make_selection( ctx, &start, &end );
-
- /* There is no selection */
- if( !(end-start) ){
- if( direction == 1 ) end = VG_MIN( end+1, strlen( ctx->textbuf ) );
- else if( direction == -1 ) start = VG_MAX( start-1, 0 );
- }
-
- /* Still no selction, no need to do anything */
- if( !(end-start) )
- return start;
-
- /* Copy the end->terminator to start */
- int remaining_length = strlen( ctx->textbuf )+1-end;
- memmove( &ctx->textbuf[ start ],
- &ctx->textbuf[ end ],
- remaining_length );
- return start;
-}
-
-void _ui_textbox_to_clipboard( ui_context *ctx )
-{
- int start, end;
- _ui_textbox_make_selection( ctx, &start, &end );
- char buffer[512];
-
- if( end-start )
- {
- memcpy( buffer, &ctx->textbuf[ start ], end-start );
- buffer[ end-start ] = 0x00;
- ctx->set_clipboard_text( buffer );
- }
-}
-
-static void _ui_textbox_change_callback( ui_context *ctx )
-{
- if( ctx->textbox.callbacks.change )
- {
- ctx->textbox.callbacks.change( ctx, ctx->textbuf, ctx->textbox.len, ctx->textbox.callbacks.userdata );
-
- /* we gave permission to modify the buffer in this callback so.. */
- int len = strlen( ctx->textbuf );
- ctx->textbox.cursor_user = VG_MIN( ctx->textbox.cursor_user, len );
- ctx->textbox.cursor_pos = VG_MIN( ctx->textbox.cursor_pos, len );
- }
-}
-
-void _ui_textbox_clipboard_paste( ui_context *ctx )
-{
- if( !ctx->have_clipboard_text() )
- return;
-
- char *text = ctx->get_clipboard_text();
-
- if( !text )
- return;
-
- int datastart = _ui_textbox_delete_char( ctx, 0 );
- int length = strlen( text );
-
- if( (ctx->textbox.len - strlen(ctx->textbuf)) < length )
- {
- ui_start_modal( ctx, "Clipboard content exceeds buffer size.", NULL, UI_MODAL_BAD, NULL );
- return;
- }
-
- int cpylength = _ui_textbox_makeroom( ctx, datastart, length );
-
- memcpy( ctx->textbuf + datastart, text, cpylength);
- _ui_textbox_move_cursor( ctx,
- &ctx->textbox.cursor_user,
- &ctx->textbox.cursor_pos, cpylength, 1 );
-
- ctx->free_clipboard_text( text );
- _ui_textbox_change_callback( ctx );
-}
-
-void _ui_textbox_put_char( ui_context *ctx, char c )
-{
- ctx->textbox.cursor_user = _ui_textbox_delete_char(ctx, 0);
- if( (ctx->textbox.len - strlen(ctx->textbuf)) <= 1 ) return;
-
- if( _ui_textbox_makeroom( ctx, ctx->textbox.cursor_user, 1 ) )
- ctx->textbuf[ ctx->textbox.cursor_user ] = c;
-
- _ui_textbox_move_cursor( ctx,
- &ctx->textbox.cursor_user,
- &ctx->textbox.cursor_pos, 1, 1 );
-}
-
-/* Receed secondary cursor */
-void _ui_textbox_left_select( ui_context *ctx )
-{
- _ui_textbox_move_cursor( ctx, &ctx->textbox.cursor_user, NULL, -1, 0 );
-}
-
-/* Match and receed both cursors */
-void _ui_textbox_left( ui_context *ctx )
-{
- int cursor_diff = ctx->textbox.cursor_pos - ctx->textbox.cursor_user? 0: 1;
-
- _ui_textbox_move_cursor( ctx,
- &ctx->textbox.cursor_user,
- &ctx->textbox.cursor_pos, -cursor_diff, 1 );
-}
-
-void _ui_textbox_up( ui_context *ctx )
-{
- if( ctx->textbox.flags & UI_TEXTBOX_MULTILINE )
- {
- int line_begin = ctx->textbox.cursor_user;
-
- while( line_begin )
- {
- if( ctx->textbuf[ line_begin-1 ] == '\n' )
- {
- break;
- }
-
- line_begin --;
- }
-
- if( line_begin )
- {
- int line_above_begin = line_begin-1;
-
- while( line_above_begin )
- {
- if( ctx->textbuf[ line_above_begin-1 ] == '\n' )
- {
- break;
- }
-
- line_above_begin --;
- }
-
- int offset = ctx->textbox.cursor_user - line_begin,
- line_length_above = line_begin - line_above_begin -1;
-
- offset = VG_MIN( line_length_above, offset );
-
- ctx->textbox.cursor_user = line_above_begin+offset;
- ctx->textbox.cursor_pos = line_above_begin+offset;
- }
- else
- {
- ctx->textbox.cursor_user = line_begin;
- ctx->textbox.cursor_pos = line_begin;
- }
- }
- else
- {
- if( ctx->textbox.callbacks.up )
- {
- ctx->textbox.callbacks.up( ctx, ctx->textbuf, ctx->textbox.len, ctx->textbox.callbacks.userdata );
- }
- }
-}
-
-void _ui_textbox_down( ui_context *ctx )
-{
- if( ctx->textbox.flags & UI_TEXTBOX_MULTILINE )
- {
- int line_begin = ctx->textbox.cursor_user;
-
- while( line_begin )
- {
- if( ctx->textbuf[ line_begin-1 ] == '\n' )
- {
- break;
- }
-
- line_begin --;
- }
-
- int line_below_begin = ctx->textbox.cursor_user;
-
- while(1)
- {
- if( ctx->textbuf[ line_below_begin ] == '\0' )
- {
- ctx->textbox.cursor_user = line_below_begin;
- ctx->textbox.cursor_pos = line_below_begin;
- return;
- }
-
- if( ctx->textbuf[ line_below_begin ] == '\n' )
- {
- line_below_begin ++;
- break;
- }
-
- line_below_begin ++;
- }
-
- int line_below_end = line_below_begin;
- while(1)
- {
- if( ctx->textbuf[ line_below_end ] == '\0' ||
- ctx->textbuf[ line_below_end ] == '\n' ){
- line_below_end ++;
- break;
- }
- line_below_end ++;
- }
-
- int offset = ctx->textbox.cursor_user - line_begin,
- line_length_below = line_below_end - line_below_begin -1;
-
- offset = VG_MIN( line_length_below, offset );
-
- ctx->textbox.cursor_user = line_below_begin+offset;
- ctx->textbox.cursor_pos = line_below_begin+offset;
- }
- else
- {
- if( ctx->textbox.callbacks.down )
- {
- ctx->textbox.callbacks.down( ctx, ctx->textbuf, ctx->textbox.len, ctx->textbox.callbacks.userdata );
- }
- }
-}
-
-void _ui_textbox_right_select( ui_context *ctx )
-{
- _ui_textbox_move_cursor( ctx, &ctx->textbox.cursor_user, NULL, 1, 0 );
-}
-
-void _ui_textbox_right( ui_context *ctx )
-{
- int cursor_diff = ctx->textbox.cursor_pos - ctx->textbox.cursor_user? 0: 1;
-
- _ui_textbox_move_cursor( ctx,
- &ctx->textbox.cursor_user,
- &ctx->textbox.cursor_pos, +cursor_diff, 1 );
-}
-
-void _ui_textbox_backspace( ui_context *ctx )
-{
- if( ctx->focused_control_type == k_ui_control_textbox )
- {
- ctx->textbox.cursor_user = _ui_textbox_delete_char( ctx, -1 );
- ctx->textbox.cursor_pos = ctx->textbox.cursor_user;
- _ui_textbox_change_callback( ctx );
- }
-}
-
-void _ui_textbox_delete( ui_context *ctx )
-{
- if( ctx->focused_control_type == k_ui_control_textbox )
- {
- ctx->textbox.cursor_user = _ui_textbox_delete_char( ctx, 1 );
- ctx->textbox.cursor_pos = ctx->textbox.cursor_user;
- _ui_textbox_change_callback( ctx );
- }
-}
-
-void _ui_textbox_home_select( ui_context *ctx )
-{
- i32 start = ctx->textbox.cursor_user;
-
- if( ctx->textbox.flags & UI_TEXTBOX_MULTILINE )
- {
- while( start )
- {
- if( ctx->textbuf[start-1] == '\n' )
- break;
- else
- start --;
- }
- }
- else
- start = 0;
-
- ctx->textbox.cursor_user = start;
-}
-
-void _ui_textbox_home( ui_context *ctx )
-{
- _ui_textbox_home_select( ctx );
- ctx->textbox.cursor_pos = ctx->textbox.cursor_user;
-}
-
-void _ui_textbox_end_select( ui_context *ctx )
-{
- i32 end = ctx->textbox.cursor_user;
-
- if( ctx->textbox.flags & UI_TEXTBOX_MULTILINE )
- {
- while( ctx->textbuf[end] )
- {
- if( ctx->textbuf[end] == '\n' )
- break;
- else
- end ++;
- }
- }
- else
- end = VG_MIN( ctx->textbox.len-1, strlen(ctx->textbuf) );
-
- ctx->textbox.cursor_user = end;
-}
-
-void _ui_textbox_end( ui_context *ctx )
-{
- _ui_textbox_end_select( ctx );
- ctx->textbox.cursor_pos = ctx->textbox.cursor_user;
-}
-
-void _ui_textbox_select_all( ui_context *ctx )
-{
- _ui_textbox_move_cursor( ctx, &ctx->textbox.cursor_user, NULL, 10000, 0 );
- _ui_textbox_move_cursor( ctx, &ctx->textbox.cursor_pos, NULL, -10000, 0 );
-}
-
-void _ui_textbox_cut( ui_context *ctx )
-{
- _ui_textbox_to_clipboard( ctx );
- ctx->textbox.cursor_user = _ui_textbox_delete_char( ctx, 0 );
- ctx->textbox.cursor_pos = ctx->textbox.cursor_user;
- _ui_textbox_change_callback( ctx );
-}
-
-void _ui_textbox_enter( ui_context *ctx )
-{
- if( ctx->focused_control_type == k_ui_control_textbox )
- {
- ui_ignore_input_frames( ctx, 2 );
-
- if( ctx->textbox.callbacks.enter )
- ctx->textbox.callbacks.enter( ctx, ctx->textbuf, ctx->textbox.len, ctx->textbox.callbacks.userdata );
-
- if( ctx->focused_control_type != k_ui_control_textbox ) return;
-
- if( ctx->textbox.flags & UI_TEXTBOX_MULTILINE )
- {
- _ui_textbox_put_char( ctx, '\n' );
- _ui_textbox_change_callback( ctx );
- }
- else
- {
- if( !(ctx->textbox.flags & UI_TEXTBOX_AUTOFOCUS ) )
- ui_defocus_all( ctx );
- }
- }
-}
-
-/*
- * based on a visual character coordinate relative to the anchor of the textbox,
- * this works out the linear place in the buffer that coordinate maps to
- *
- * input coordinates go in co[0], co[1], and the result index is in co[2]
- */
-static void _ui_textbox_calc_index_from_grid( ui_context *ctx, int co[3], int wrap_length )
-{
- int i[3] = {0,0,0};
-
- char c;
- while( (c = ctx->textbuf[i[2]]) )
- {
- if( i[1]==co[1] && i[0]>=co[0] ) break;
-
- if( i[0] >= wrap_length )
- {
- i[1] ++;
- i[0] = 0;
- }
-
- if( c >= 32 && c <= 126 )
- {
- i[0] ++;
- i[2] ++;
- }
- else if( c == '\n' )
- {
- i[1] ++;
-
- if( i[1] > co[1] ) break;
-
- i[2] ++;
- i[0] = 0;
- }
- else i[2] ++;
- }
-
- co[0] = i[0];
- co[1] = i[1];
- co[2] = i[2];
-}
-
-/*
- * based on the index specied in co[2], work out the visual character
- * coordinates and store them in co[0], co[1]
- */
-static void _ui_textbox_index_calc_coords( ui_context *ctx,
- int co[3], int wrap_length )
-{
- co[0] = 0;
- co[1] = 0;
-
- char c;
- int i=0;
-
- while( (c = ctx->textbuf[i ++]) )
- {
- if( i > co[2] ) break;
- if( co[0] >= wrap_length )
- {
- co[1] ++;
- co[0] = 0;
- }
- if( c >= 32 && c <= 126 ) co[0] ++;
- else if( c == '\n' )
- {
- co[1] ++;
- co[0] = 0;
- }
- }
-}
-
-/*
- * calculate the number of characters remaining until either:
- * - the wrap_length limit is hit
- * - end of the line/string
- *
- * index must be fully populated with visual X/Y, and linear index
- */
-static int _ui_textbox_run_remaining( ui_context *ctx,
- int index[3], int wrap_length )
-{
- int i=0, printed_chars=0;
- char c;
- while( (c = ctx->textbuf[index[2] + (i ++)]) )
- {
- if( index[0]+i >= wrap_length ) break;
- if( c >= 32 && c <= 126 ) printed_chars ++;
- else if( c == '\n' ) break;
- }
-
- return printed_chars+1;
-}
-
-int ui_textbox( ui_context *ctx, ui_rect inout_panel, const char *label,
- char *buf, u32 len, u32 lines, u32 flags,
- struct ui_textbox_callbacks *callbacks )
-{
- if( lines > 1 ) flags |= UI_TEXTBOX_MULTILINE;
-
- ui_rect rect;
- ui_standard_widget( ctx, inout_panel, rect, lines );
-
- if( label )
- ui_label( ctx, rect, label, 1, 0, rect );
-
- int clickup= ui_click_up(ctx, UI_MOUSE_LEFT),
- clickdown = ui_click_down(ctx, UI_MOUSE_LEFT),
- click = ui_clicking(ctx, UI_MOUSE_LEFT) | clickup,
- target = ui_inside_rect( rect, ctx->mouse_click ) && click,
- hover = ui_inside_rect( rect, ctx->mouse );
-
- /* allow instant transitions from textbox->textbox */
- if( (ctx->focused_control_type != k_ui_control_none) &&
- (ctx->focused_control_type != k_ui_control_textbox) )
- {
- clickup = 0;
- clickdown = 0;
- click = 0;
- target = 0;
- hover = 0;
- flags &= ~UI_TEXTBOX_AUTOFOCUS;
- }
-
- u32 col_base = ui_colour(ctx, k_ui_bg ),
- col_highlight = ui_colour(ctx, k_ui_fg ),
- col_cursor = (0x00ffffff & ui_colour(ctx,k_ui_fg))|0x7f000000;
-
- ui_px border = -1;
-
- ui_rect text_rect;
- rect_copy( rect, text_rect );
-
- if( flags & UI_TEXTBOX_MULTILINE ) text_rect[3] = rect[3]-16;
- else text_rect[3] = ctx->font->sy;
-
- text_rect[2] -= 16;
- ui_rect_center( rect, text_rect );
-
- ui_px wrap_length = 1024;
-
- if( flags & UI_TEXTBOX_WRAP )
- wrap_length = text_rect[2] / ctx->font->sx;
-
- if( hover )
- {
- ctx->cursor = k_ui_cursor_ibeam;
- }
-
- if( ctx->focused_control_id == buf )
- {
- ui_fill( ctx, rect, col_base );
- ui_ntext( ctx, text_rect, buf, wrap_length, 1, k_ui_align_left, 0 );
-
- if( !(flags & UI_TEXTBOX_AUTOFOCUS) && ((clickup||clickdown) && !target))
- {
- ui_defocus_all( ctx );
- }
- else
- {
- ctx->focused_control_hit = 1;
- if( click && target )
- {
- int p0[3] ={
- (ctx->mouse_click[0] - text_rect[0]) / ctx->font->sx,
- (ctx->mouse_click[1] - text_rect[1]) / ctx->font->sy,
- -1
- },
- p1[3] = {
- (ctx->mouse[0] - text_rect[0]) / ctx->font->sx,
- (ctx->mouse[1] - text_rect[1]) / ctx->font->sy,
- -1
- };
-
- if( flags & UI_TEXTBOX_MULTILINE )
- {
- _ui_textbox_calc_index_from_grid( ctx, p0, wrap_length );
- _ui_textbox_calc_index_from_grid( ctx, p1, wrap_length );
-
- ctx->textbox.cursor_pos = p0[2];
- ctx->textbox.cursor_user = p1[2];
- }
- else
- {
- int max = strlen( buf );
- ctx->textbox.cursor_pos = VG_MAX( 0, VG_MIN( max, p0[0] )),
- ctx->textbox.cursor_user = VG_MAX( 0, VG_MIN( max, p1[0] ));
- }
- }
-
- ui_outline( ctx, rect, -2, ctx->scheme[ k_ui_orange ], 0 );
- ui_rect cursor;
-
- int c0 = ctx->textbox.cursor_pos,
- c1 = ctx->textbox.cursor_user,
- start = VG_MIN( c0, c1 ),
- end = VG_MAX( c0, c1 ),
- chars = end-start;
-
- if( flags & (UI_TEXTBOX_WRAP|UI_TEXTBOX_MULTILINE) )
- {
- int pos[3], remaining = chars;
-
- pos[2] = start;
- _ui_textbox_index_calc_coords( ctx, pos, wrap_length );
-
- if( start==end )
- {
- cursor[0] = text_rect[0] + pos[0]*ctx->font->sx-1;
- cursor[1] = text_rect[1] + pos[1]*14;
- cursor[2] = 2;
- cursor[3] = 13;
- ui_fill( ctx, cursor, col_cursor );
- rect_copy( cursor, ctx->click_fader_end );
- }
- else
- {
- while( remaining )
- {
- int run = _ui_textbox_run_remaining( ctx, pos, wrap_length );
- run = VG_MIN( run, remaining );
-
- cursor[0] = text_rect[0] + pos[0]*ctx->font->sx-1;
- cursor[1] = text_rect[1] + pos[1]*14;
- cursor[2] = (float)(run)*(float)ctx->font->sx;
- cursor[3] = 13;
-
- ui_fill( ctx, cursor, col_cursor );
-
- remaining -= run;
- pos[0] = 0;
- pos[1] ++;
- pos[2] += run;
- }
- rect_copy( cursor, ctx->click_fader_end );
- }
- }
- else
- {
- cursor[0] = text_rect[0] + start*ctx->font->sx-1;
- cursor[1] = text_rect[1];
- cursor[3] = 13;
-
- if( start==end )
- {
- cursor[2] = 2;
- }
- else
- {
- cursor[2] = (float)(chars)*(float)ctx->font->sx;
- }
-
- if( (ctx->click_fade_opacity<=0.0f) && ui_clip( rect, cursor, cursor ) )
- {
- ui_fill( ctx, cursor, col_cursor );
- }
-
- rect_copy( cursor, ctx->click_fader_end );
- }
- }
-
- return 0;
- }
-
- if( click || (flags & UI_TEXTBOX_AUTOFOCUS) )
- {
- if( (target && hover) || (flags & UI_TEXTBOX_AUTOFOCUS) )
- {
- ui_defocus_all( ctx );
-
- ui_fill( ctx, rect, col_highlight );
- ui_ignore_input_frames( ctx, 2 );
- rect_copy( rect, ctx->click_fader );
- rect_copy( rect, ctx->click_fader_end );
-
- ctx->click_fade_opacity = 1.0f;
- ctx->textbuf = buf;
- ctx->focused_control_hit = 1;
- ctx->focused_control_type = k_ui_control_textbox;
- ctx->textbox.len = len;
- ctx->textbox.flags = flags;
- ctx->textbox.cursor_pos = 0;
- ctx->textbox.cursor_user = 0;
-
- if( callbacks )
- {
- ctx->textbox.callbacks = *callbacks;
- }
- else
- {
- ctx->textbox.callbacks.change = NULL;
- ctx->textbox.callbacks.down = NULL;
- ctx->textbox.callbacks.up = NULL;
- ctx->textbox.callbacks.enter = NULL;
- ctx->textbox.callbacks.userdata = NULL;
- }
-
- ctx->start_text_input();
- }
- }
-
- ui_fill( ctx, rect, col_base );
-
- if( hover )
- {
- ui_outline( ctx, rect, -1, col_highlight, 0 );
- }
-
- ui_ntext( ctx, text_rect, buf, wrap_length, 1, k_ui_align_left, 0 );
- return 0;
-}
-
-/*
- * Tabs
- * -----------------------------------------------------------------------------
- */
-
-void ui_tabs( ui_context *ctx, ui_rect inout_panel, ui_rect out_content_panel,
- const char **titles, u32 count, i32 *page )
-{
- ui_rect bar;
- ui_standard_widget( ctx, inout_panel, bar, 1 );
-
- i32 cur_page = *page;
-
- f32 width = (f32)inout_panel[2] / (f32)count;
-
- ui_px h = (inout_panel[1] + inout_panel[3]) - (bar[1]+bar[3]);
- inout_panel[1] = bar[1]+bar[3];
- inout_panel[3] = h;
-
- ui_fill( ctx, inout_panel, ui_colour(ctx, k_ui_bg+2 ) );
- ui_outline( ctx, inout_panel, 1, ui_colour(ctx, k_ui_bg+5 ), 0 );
-
- rect_copy( inout_panel, out_content_panel );
- ui_rect_pad( out_content_panel,
- (ui_px[2]){ ctx->padding, ctx->padding } );
-
- /* place buttons */
- for( i32 i=0; i<count; i++ )
- {
- ui_rect button = {
- bar[0] + ((f32)i*width),
- bar[1],
- width,
- bar[3]-1
- };
-
- enum ui_scheme_colour colour = k_ui_bg+4;
- if( i == cur_page )
- {
- colour = k_ui_bg+2;
- ui_outline( ctx, button, 1, ui_colour(ctx, k_ui_bg+5 ),
- UI_TOP|UI_LEFT|UI_RIGHT );
- button[3] ++;
- }
-
- if( ui_colourbutton_text( ctx, button, titles[i], 1, colour ) == 1 )
- *page = i;
- }
-}
-
-/*
- * Modal UI
- * -----------------------------------------------------------------------------
- */
-void ui_start_modal( ui_context *ctx, const char *message, const char *ok_text,
- u32 options, const struct ui_modal_callbacks *callbacks )
-{
- ctx->focused_control_type = k_ui_control_modal;
- ctx->modal.message = message;
- ctx->modal.ok_text = ok_text? ok_text: "OK";
- if( callbacks )
- ctx->modal.callbacks = *callbacks;
- else
- ctx->modal.callbacks.close = NULL;
-
- ctx->modal.options = options;
- u32 type = options & UI_MODAL_TYPE_BITS;
- if( type == UI_MODAL_OK ) vg_info( message );
- else if( type == UI_MODAL_WARN ) vg_warn( message );
- else if( type == UI_MODAL_GOOD ) vg_success( message );
- else if( type == UI_MODAL_BAD ) vg_error( message );
-}
-
-/*
- * Input handling
- * -----------------------------------------------------------------------------
- */
-
-/*
- * Callback for text entry mode
- */
-void ui_proc_utf8( ui_context *ctx, const char *text )
-{
- if( ctx->focused_control_type == k_ui_control_textbox )
- {
- const char *ptr = text;
-
- while( *ptr )
- {
- if( *ptr != '`' )
- _ui_textbox_put_char( ctx, *ptr );
-
- ptr ++;
- }
-
- _ui_textbox_change_callback( ctx );
- }
-}
-
-/*
- * Development utils
- * -----------------------------------------------------------------------------
- */
-
-void ui_dev_colourview( ui_context *ctx )
-{
- ui_rect window = {ctx->area[0]-256,0,256,ctx->area[1]}, swatch;
-
- const char *names[VG_ARRAY_LEN(ctx->scheme)] = {
- [k_ui_bg] = "k_ui_bg", "k_ui_bg+1", "k_ui_bg+2", "k_ui_bg+3",
- "k_ui_bg+4", "k_ui_bg+5", "k_ui_bg+6", "k_ui_bg+7",
-
- [k_ui_fg] = "k_ui_fg", "k_ui_fg+1", "k_ui_fg+2", "k_ui_fg+3",
- "k_ui_fg+4", "k_ui_fg+5", "k_ui_fg+6", "k_ui_fg+7",
-
- [k_ui_red] = "k_ui_red", "k_ui_orange", "k_ui_yellow", "k_ui_green",
- "k_ui_aqua", "k_ui_blue", "k_ui_purple", "k_ui_gray",
- "k_ui_red+8","k_ui_orange+8","k_ui_yellow+8","k_ui_green+8",
- "k_ui_aqua+8","k_ui_blue+8","k_ui_purple+8","k_ui_gray+8" };
-
- ui_rect col[2];
- ui_split_ratio( window, k_ui_axis_v, 0.5f, 0, col[0], col[1] );
-
- for( int i=0; i<VG_ARRAY_LEN(ctx->scheme); i++ )
- {
- int which = (i/8)%2;
-
- ui_split( col[which], k_ui_axis_h, 24, 0, swatch, col[which] );
- ui_fill( ctx, swatch, ui_colour(ctx,i) );
-
- if( names[i] )
- {
- ui_text( ctx, swatch, names[i], 1, k_ui_align_middle_left, ui_colourcont(ctx,i));
- }
- }
-}
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_ui/imgui.c"
-#else
-
-typedef i16 ui_px;
-typedef ui_px ui_rect[4];
-typedef ui_px ui_point[2];
-typedef struct ui_vert ui_vert;
-typedef struct ui_context ui_context;
-typedef struct ui_batch ui_batch;
-
-enum ui_axis {
- k_ui_axis_h = 0x0u,
- k_ui_axis_v = 0x1u,
-};
-
-/* Relative to cursor p0 */
-enum ui_align
-{ /* DC BA */
- k_ui_align_lwr = 0xff,
- k_ui_align_left = 0x0000| 0x00,
- k_ui_align_right = 0x0000| 0x01,
- k_ui_align_center = 0x0000| 0x02,
-
- k_ui_align_middle = 0x0100,
- k_ui_align_middle_left = 0x0100| 0x00,
- k_ui_align_middle_right = 0x0100| 0x01,
- k_ui_align_middle_center = 0x0100| 0x02,
-
- k_ui_align_bottom = 0x0200,
- k_ui_align_bottom_left = 0x0200| 0x00,
- k_ui_align_bottom_right = 0x0200| 0x01,
- k_ui_align_bottom_center = 0x0200| 0x02,
-};
-
-enum ui_shader
-{
- k_ui_shader_colour,
- k_ui_shader_image,
- k_ui_shader_hsv,
- k_ui_shader_grad
-};
-
-typedef u32 ui_scheme[8*4];
-enum ui_scheme_colour
-{
- k_ui_bg = 0,
- k_ui_fg = 8,
- k_ui_hue = 16,
- k_ui_red = 16,
- k_ui_orange,
- k_ui_yellow,
- k_ui_green,
- k_ui_aqua,
- k_ui_blue,
- k_ui_purple,
- k_ui_gray,
- k_ui_brighter = 8
-};
-
-#define UI_RGB( STDHEX ) 0xff000000 |\
- ((STDHEX&0x000000ff)<<16) |\
- ((STDHEX&0x0000ff00) ) |\
- ((STDHEX&0x00ff0000)>>16)
-
-#define UI_TEXTBOX_MULTILINE 0x1
-#define UI_TEXTBOX_WRAP 0x2
-#define UI_TEXTBOX_AUTOFOCUS 0x4
-
-#define UI_MODAL_OK 0x0
-#define UI_MODAL_GOOD 0x1
-#define UI_MODAL_BAD 0x2
-#define UI_MODAL_WARN 0x3
-#define UI_MODAL_TYPE_BITS 0x3
-#define UI_MODAL_CANCEL 0x8
-
-#define UI_MOUSE_LEFT 1
-#define UI_MOUSE_MIDDLE 2
-#define UI_MOUSE_RIGHT 4
-#define UI_MOUSE_ANY (UI_MOUSE_LEFT|UI_MOUSE_RIGHT|UI_MOUSE_MIDDLE)
-
-#define UI_TOP 0x1
-#define UI_LEFT 0x2
-#define UI_BOTTOM 0x4
-#define UI_RIGHT 0x8
-
-#pragma pack(push,1)
-struct ui_vert
-{
- ui_px co[2];
- u16 uv[2];
- u32 colour;
-};
-#pragma pack(pop)
-
-enum ui_button_state
-{
- k_ui_button_none = 0x0,
- k_ui_button_click = 0x1,
- k_ui_button_holding_inside = 0x2,
- k_ui_button_holding_outside = 0x4,
- k_ui_button_hover = 0x8
-};
-
-struct ui_context
-{
- struct ui_vert *vertex_buffer;
- u16 *indice_buffer;
- u32 max_verts, max_indices,
- cur_vert, cur_indice,
- vert_start, indice_start;
-
- ui_px area[2];
-
- union
- {
- void *focused_control_id; /* uses the memory location of various locking
- controls as an id */
- char *textbuf;
- i32 *ptr_enum;
- };
-
- u32 focused_control_hit;
- enum ui_control_type{
- k_ui_control_none,
- k_ui_control_textbox,
- k_ui_control_enum,
- k_ui_control_modal
- }
- focused_control_type;
-
- union /* controls data that can be focused */
- {
- struct ui_textbuf
- {
- int cursor_user, cursor_pos;
- u32 len;
- u32 flags;
-
- struct ui_textbox_callbacks
- {
- void (*enter)( ui_context *ctx, char *, u32, void * ),
- (*up)( ui_context *ctx, char *, u32, void * ),
- (*down)( ui_context *ctx, char *, u32, void * ),
- (*change)( ui_context *ctx, char *, u32, void * ),
- (*escape)( ui_context *ctx, void * );
- void *userdata;
- }
- callbacks;
- }
- textbox;
-
- struct ui_enum
- {
- struct ui_enum_opt
- {
- i32 value;
- const char *alias;
- }
- *options;
- u32 option_count;
- ui_rect rect;
- }
- _enum;
- };
-
- struct ui_modal
- {
- const char *message, *ok_text;
- u32 options;
-
- struct ui_modal_callbacks
- {
- void (*close)(u32);
- }
- callbacks;
- }
- modal;
-
- ui_px mouse[2], mouse_delta[2], mouse_click[2];
- u32 mouse_state[2];
- u32 ignore_input_frames;
-
- bool mouse_pos_overriden;
- int wants_mouse;
-
- ui_rect click_fader, click_fader_end;
- float click_fade_opacity;
-
- ui_scheme scheme;
- const vg_font_face *font;
-
- ui_px kern[2];
-
- enum ui_cursor
- {
- k_ui_cursor_default,
- k_ui_cursor_ibeam,
- k_ui_cursor_hand,
- k_ui_cursor_max
- }
- cursor;
-
- enum ui_text_encoding
- {
- k_ui_text_encoding_ascii_vg_extended,
- k_ui_text_encoding_utf8
- }
- text_encoding;
-
- ui_px widget_height, scale, padding;
-
- void (*render_batch)(ui_context *ctx, ui_batch *batch,
- enum ui_shader shader, void *shader_data );
- bool (*have_clipboard_text)(void);
- char *(*get_clipboard_text)(void);
- void (*free_clipboard_text)(void *text);
- int (*set_clipboard_text)(const char *text);
-
- void (*start_text_input)(void);
- void (*stop_text_input)(void);
-};
-
-struct ui_batch_shader_data_hsv
-{
- f32 hue;
-};
-
-struct ui_batch_shader_data_image_gradient
-{
- void *image_resource;
- bool log;
- f32 scale;
-};
-
-struct ui_batch
-{
- ui_vert *vert_buf; /* base vertex array + [vert_offset] */
- u32 vert_count,
- vert_offset; /* in bytes */
-
- u16 *indice_buf; /* base indice array + [indice_offset] */
- u32 indice_count,
- indice_offset; /* in bytes */
-};
-
-/* set the memory buffer and limits of ui context */
-void ui_init( ui_context *ctx,
- ui_vert *verts_buf, u32 verts_max,
- u16 *indices_buf, u32 indices_max );
-
-/* simple fill drawing commands */
-ui_vert *ui_fill_rect( ui_context *ctx, ui_rect rect, u32 colour, ui_px uv[4] );
-ui_vert *ui_fill( ui_context *ctx, ui_rect rect, u32 colour );
-void ui_outline( ui_context *ctx, ui_rect rect, ui_px thickness, u32 colour, u32 mask );
-
-/* rect controls */
-void rect_copy( ui_rect a, ui_rect b );
-void ui_split( ui_rect rect, enum ui_axis other, ui_px width, ui_px gap, ui_rect l, ui_rect r );
-void ui_split_ratio( ui_rect rect, enum ui_axis dir, float ratio, ui_px gap, ui_rect l, ui_rect r );
-void ui_rect_pad( ui_rect rect, ui_px pad[2] );
-int ui_clip( ui_rect parent, ui_rect child, ui_rect clipped );
-int ui_inside_rect( ui_rect rect, ui_px co[2] );
-void ui_fit_item( ui_rect rect, ui_px size[2], ui_rect d );
-
-/* ui interactions */
-void ui_update_mouse( ui_context *ctx, ui_px mouse[2], i32 mouse_state );
-int ui_click_down( ui_context *ctx, u32 mask );
-int ui_clicking( ui_context *ctx, u32 mask );
-int ui_click_up( ui_context *ctx, u32 mask );
-void ui_ignore_input_frames( ui_context *ctx, u32 frames );
-void ui_capture_mouse( ui_context *ctx, bool on );
-
-/* ui cycle */
-void ui_prerender( ui_context *ctx );
-void ui_flush( ui_context *ctx, enum ui_shader shader, void *shader_data );
-void ui_rect_center( ui_rect parent, ui_rect rect );
-void ui_set_area( ui_context *ctx, i32 width, i32 height );
-
-/* text drawing */
-ui_px ui_text_line_width( ui_context *ctx, const char *str );
-ui_px ui_text_string_height( ui_context *ctx, const char *str );
-ui_px ui_text_aligned_x( ui_context *ctx,
- const char *str, ui_rect rect, ui_px scale,
- enum ui_align align );
-u32 ui_ntext( ui_context *ctx,
- ui_rect rect, const char *str, u32 len, ui_px scale,
- enum ui_align align, u32 colour );
-u32 ui_text( ui_context *ctx,
- ui_rect rect, const char *str, ui_px scale,
- enum ui_align align, u32 colour );
-
-/* colour schemes */
-u32 ui_colour( ui_context *ctx, enum ui_scheme_colour id );
-u32 ui_colourcont( ui_context *ctx, enum ui_scheme_colour id );
-
-/* generic colour functions */
-void ui_hex_to_norm( u32 hex, v4f norm );
-u32 v4f_u32_colour( v4f colour );
-u32 ui_opacity( u32 colour, f32 opacity );
-
-/* standard widgets & controls */
-ui_px ui_standard_widget_height( ui_context *ctx, ui_px count );
-void ui_standard_widget( ui_context *ctx, ui_rect inout_panel, ui_rect out_rect, ui_px count );
-void ui_panel( ui_context *ctx, ui_rect in_rect, ui_rect out_panel );
-void ui_label( ui_context *ctx, ui_rect rect, const char *text, ui_px size, ui_px gap, ui_rect r );
-void ui_info( ui_context *ctx, ui_rect inout_panel, const char *text );
-void ui_spacer( ui_context *ctx, ui_rect inout_panel );
-void ui_image( ui_context *ctx, ui_rect rect, void *image_resource, bool flip );
-
-enum ui_button_state ui_button_base( ui_context *ctx, ui_rect rect );
-
-/* TODO: split this out into a formatless button and one that auto fills */
-enum ui_button_state ui_colourbutton( ui_context *ctx, ui_rect rect,
- enum ui_scheme_colour colour,
- enum ui_scheme_colour hover_colour,
- enum ui_scheme_colour hi_colour );
-enum ui_button_state ui_colourbutton_text(
- ui_context *ctx,
- ui_rect rect, const char *string, ui_px scale,
- enum ui_scheme_colour colour );
-
-enum ui_button_state ui_button_text( ui_context *ctx, ui_rect rect, const char *string, ui_px scale );
-enum ui_button_state ui_button( ui_context *ctx, ui_rect inout_panel, const char *string );
-void ui_postrender( ui_context *ctx, f32 delta_time );
-enum ui_button_state ui_checkbox_base( ui_context *ctx, ui_rect box, i32 *data );
-int ui_checkbox( ui_context *ctx, ui_rect inout_panel, const char *str_label, i32 *data );
-void ui_enum( ui_context *ctx, ui_rect inout_panel, const char *str_label,
- struct ui_enum_opt *options, u32 len, i32 *value );
-
-enum ui_button_state ui_slider_base( ui_context *ctx,
- ui_rect box, enum ui_axis axis, f32 min, f32 max, f32 *value, f32 *out_t );
-void ui_slider_text( ui_context *ctx, ui_rect box, const char *format, f32 value );
-bool ui_slider_standard( ui_context *ctx, ui_rect box, f32 min, f32 max, f32 *value, const char *format );
-bool ui_slider( ui_context *ctx, ui_rect inout_panel, const char *str_label, f32 min, f32 max, f32 *value );
-
-enum ui_colour_type
-{
- k_ui_colour_type_rgba,
- k_ui_colour_type_rgb
-};
-
-bool ui_colourpicker( ui_context *ctx, ui_rect inout_panel, const char *str_label, v4f value, enum ui_colour_type type );
-void _ui_textbox_move_cursor( ui_context *ctx, int *cursor0, int *cursor1, int dir, int snap_together );
-int _ui_textbox_delete_char( ui_context *ctx, int direction );
-void ui_start_modal( ui_context *ctx, const char *message, const char *ok_text,
- u32 options, const struct ui_modal_callbacks *callbacks );
-
-void _ui_textbox_put_char( ui_context *ctx, char c );
-void _ui_textbox_left_select( ui_context *ctx );
-void _ui_textbox_left( ui_context *ctx );
-void _ui_textbox_up( ui_context *ctx );
-void _ui_textbox_down( ui_context *ctx );
-void _ui_textbox_right_select( ui_context *ctx );
-void _ui_textbox_right( ui_context *ctx );
-void _ui_textbox_backspace( ui_context *ctx );
-void _ui_textbox_delete( ui_context *ctx );
-void _ui_textbox_home_select( ui_context *ctx );
-void _ui_textbox_home( ui_context *ctx );
-void _ui_textbox_end_select( ui_context *ctx );
-void _ui_textbox_end( ui_context *ctx );
-void _ui_textbox_select_all( ui_context *ctx );
-void _ui_textbox_cut( ui_context *ctx );
-void _ui_textbox_enter( ui_context *ctx );
-void _ui_textbox_to_clipboard( ui_context *ctx );
-void _ui_textbox_clipboard_paste( ui_context *ctx );
-
-int ui_textbox( ui_context *ctx, ui_rect inout_panel, const char *label,
- char *buf, u32 len, u32 lines, u32 flags,
- struct ui_textbox_callbacks *callbacks );
-void ui_tabs( ui_context *ctx, ui_rect inout_panel, ui_rect out_content_panel,
- const char **titles, u32 count, i32 *page );
-void ui_defocus_all( ui_context *ctx );
-
-void ui_proc_utf8( ui_context *ctx, const char *text );
-void ui_dev_colourview( ui_context *ctx );
-
-extern vg_font_sheet vg_default_font_sheet;
-extern vg_font_face vgf_default_small, vgf_default_large, vgf_default_title;
-
-#endif
+++ /dev/null
-struct vg_ui vg_ui =
-{
- .ctx =
- {
- .scheme =
- {
- [ k_ui_bg+0 ] = UI_RGB( 0x1d2021 ),
- [ k_ui_bg+1 ] = UI_RGB( 0x282828 ),
- [ k_ui_bg+2 ] = UI_RGB( 0x3c3836 ),
- [ k_ui_bg+3 ] = UI_RGB( 0x504945 ),
- [ k_ui_bg+4 ] = UI_RGB( 0x665c54 ),
- [ k_ui_bg+5 ] = UI_RGB( 0x7c6f64 ),
- [ k_ui_bg+6 ] = UI_RGB( 0x928374 ),
- [ k_ui_bg+7 ] = UI_RGB( 0xa89984 ),
-
- [ k_ui_fg+0 ] = UI_RGB( 0xebdbb2 ),
- [ k_ui_fg+1 ] = UI_RGB( 0xfbf1c7 ),
- [ k_ui_fg+2 ] = UI_RGB( 0xd5c4a1 ),
- [ k_ui_fg+3 ] = UI_RGB( 0xbdae93 ),
- [ k_ui_fg+4 ] = UI_RGB( 0xa89984 ),
- [ k_ui_fg+5 ] = UI_RGB( 0x000000 ),
- [ k_ui_fg+6 ] = UI_RGB( 0x000000 ),
- [ k_ui_fg+7 ] = UI_RGB( 0x000000 ),
-
- [ k_ui_red ] = UI_RGB( 0xcc241d ),
- [ k_ui_orange ] = UI_RGB( 0xd65d0e ),
- [ k_ui_yellow ] = UI_RGB( 0xd79921 ),
- [ k_ui_green ] = UI_RGB( 0x98971a ),
- [ k_ui_aqua ] = UI_RGB( 0x689d6a ),
- [ k_ui_blue ] = UI_RGB( 0x458588 ),
- [ k_ui_purple ] = UI_RGB( 0xb16286 ),
- [ k_ui_gray ] = UI_RGB( 0x928374 ),
- [ k_ui_red + k_ui_brighter ] = UI_RGB( 0xfb4934 ),
- [ k_ui_orange + k_ui_brighter ] = UI_RGB( 0xfe8019 ),
- [ k_ui_yellow + k_ui_brighter ] = UI_RGB( 0xfabd2f ),
- [ k_ui_green + k_ui_brighter ] = UI_RGB( 0xb8bb26 ),
- [ k_ui_aqua + k_ui_brighter ] = UI_RGB( 0x8ec07c ),
- [ k_ui_blue + k_ui_brighter ] = UI_RGB( 0x83a598 ),
- [ k_ui_purple + k_ui_brighter ] = UI_RGB( 0xd3869b ),
- [ k_ui_gray + k_ui_brighter ] = UI_RGB( 0xa89984 ),
- },
- .font = &vgf_default_small,
- .scale = 1,
- .padding = 8,
- .widget_height = 28
- },
- .colour = {1.0f,1.0f,1.0f,1.0f},
- .bg_inverse_ratio = {1,1},
-};
-
-VG_API void vg_ui_set_screen( i32 width, i32 height )
-{
- ui_set_area( &vg_ui.ctx, width, height );
- m3x3_identity( vg_ui.pv );
- m3x3_translate( vg_ui.pv, (v3f){ -1.0f, 1.0f, 0.0f } );
- m3x3_scale( vg_ui.pv, (v3f){ 1.0f/((f32)width*0.5f), -1.0f/((f32)height*0.5f), 1.0f } );
-}
-void ui_impl_render_batch( ui_context *ctx, ui_batch *batch, enum ui_shader shader, void *shader_data )
-{
- glBindVertexArray( vg_ui.vao );
- glBindBuffer( GL_ARRAY_BUFFER, vg_ui.vbo );
- glBufferSubData( GL_ARRAY_BUFFER,
- batch->vert_offset,
- batch->vert_count*sizeof(ui_vert),
- batch->vert_buf );
-
- glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vg_ui.ebo );
- glBufferSubData( GL_ELEMENT_ARRAY_BUFFER,
- batch->indice_offset,
- batch->indice_count*sizeof(u16),
- batch->indice_buf );
-
- glDisable( GL_DEPTH_TEST );
- glDisable( GL_CULL_FACE );
- glEnable( GL_BLEND );
- glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
- glBlendEquation( GL_FUNC_ADD );
-
- if( shader == k_ui_shader_colour )
- {
- shader_vgui_use();
- shader_vgui_uPv( vg_ui.pv );
- shader_vgui_uColour( vg_ui.colour );
-
- glActiveTexture( GL_TEXTURE0 );
- glBindTexture( GL_TEXTURE_2D, vg_ui.tex_glyphs );
- shader_vgui_uTexGlyphs( 0 );
-
- vg_tex_bind( GL_TEXTURE_2D, (vg_tex *)vg_ui.tex_bg, 1 );
- shader_vgui_uTexBG( 1 );
- shader_vgui_uSpread( vg_ui.frosting );
- shader_vgui_uBGInverseRatio( vg_ui.bg_inverse_ratio );
- shader_vgui_uInverseFontSheet( vg_ui.inverse_font_sheet );
- }
- else if( shader == k_ui_shader_image )
- {
- shader_vgui_image_use();
- shader_vgui_image_uPv( vg_ui.pv );
- shader_vgui_image_uTexImage( 0 );
- shader_vgui_image_uColour( vg_ui.colour );
- vg_tex_bind( GL_TEXTURE_2D, (vg_tex *)shader_data, 0 );
- }
- else if( shader == k_ui_shader_grad )
- {
- shader_vgui_image_grad_use();
- shader_vgui_image_grad_uPv( vg_ui.pv );
- shader_vgui_image_grad_uTexImage( 0 );
- shader_vgui_image_grad_uColour( vg_ui.colour );
-
- struct ui_batch_shader_data_image_gradient *inf = shader_data;
- shader_vgui_image_grad_uLog( inf->log );
- shader_vgui_image_grad_uScale( inf->scale );
- vg_tex_bind( GL_TEXTURE_2D, (vg_tex *)inf->tex, 0 );
- }
- else if( shader == k_ui_shader_hsv )
- {
- struct ui_batch_shader_data_hsv *inf = shader_data;
- shader_vgui_image_hsv_use();
- shader_vgui_image_hsv_uPv( vg_ui.pv );
- shader_vgui_image_hsv_uHue( inf->hue );
- }
- else
- vg_fatal_error( "Invalid UI shader (%d)\n", shader );
-
- glDrawElements( GL_TRIANGLES, batch->indice_count, GL_UNSIGNED_SHORT, (void *)((size_t)batch->indice_offset) );
-}
-
-VG_API void vg_ui_post_update(void)
-{
- _vg_window_set_fpv_mouse( !vg_ui.ctx.wants_mouse );
- SDL_SetCursor( vg_ui.cursor_map[ vg_ui.ctx.cursor ] );
- SDL_ShowCursor(1);
-}
-
-void vg_ui_set_mouse_pos( ui_px x, ui_px y )
-{
- _vg_window_set_mouse( x, y );
- vg_ui.ctx.mouse[0] = x;
- vg_ui.ctx.mouse[1] = y;
- vg_ui.ctx.mouse_pos_overriden = 1;
-}
-
-void vg_ui_handle_sdl_key( ui_context *ctx, SDL_Keysym ev )
-{
- if( ctx->focused_control_type != k_ui_control_textbox )
- {
- return;
- }
-
- struct textbox_mapping
- {
- u16 mod;
- SDL_Keycode key;
-
- void (*handler)( ui_context *ctx );
- }
- mappings[] =
- {
- { 0, SDLK_LEFT, _ui_textbox_left },
- { KMOD_SHIFT, SDLK_LEFT, _ui_textbox_left_select },
- { 0, SDLK_RIGHT, _ui_textbox_right },
- { KMOD_SHIFT, SDLK_RIGHT, _ui_textbox_right_select },
- { 0, SDLK_DOWN, _ui_textbox_down },
- { 0, SDLK_UP, _ui_textbox_up },
- { 0, SDLK_BACKSPACE, _ui_textbox_backspace },
- { KMOD_SHIFT, SDLK_BACKSPACE, _ui_textbox_backspace },
- { KMOD_CTRL, SDLK_BACKSPACE, _ui_textbox_backspace },
- { 0, SDLK_DELETE, _ui_textbox_delete },
- { 0, SDLK_HOME, _ui_textbox_home },
- { KMOD_SHIFT, SDLK_HOME, _ui_textbox_home_select },
- { 0, SDLK_END, _ui_textbox_end },
- { KMOD_SHIFT, SDLK_END, _ui_textbox_end_select },
- { KMOD_CTRL, SDLK_a, _ui_textbox_select_all },
- { KMOD_CTRL, SDLK_c, _ui_textbox_to_clipboard },
- { KMOD_CTRL, SDLK_x, _ui_textbox_cut },
- { KMOD_CTRL, SDLK_v, _ui_textbox_clipboard_paste },
- { 0, SDLK_RETURN, _ui_textbox_enter },
- { 0, SDLK_ESCAPE, ui_defocus_all },
- };
-
- SDL_Keymod mod = 0;
-
- if( ev.mod & KMOD_SHIFT )
- mod |= KMOD_SHIFT;
-
- if( ev.mod & KMOD_CTRL )
- mod |= KMOD_CTRL;
-
- if( ev.mod & KMOD_ALT )
- mod |= KMOD_ALT;
-
- for( int i=0; i<VG_ARRAY_LEN( mappings ); i++ )
- {
- struct textbox_mapping *mapping = &mappings[i];
-
- if( mapping->key == ev.sym )
- {
- if( mapping->mod == 0 )
- {
- if( mod == 0 )
- {
- mapping->handler( ctx );
- return;
- }
- }
- else if( (mod & mapping->mod) == mapping->mod )
- {
- mapping->handler( ctx );
- return;
- }
- }
- }
-}
-
-bool _wrap_sdl_hasclipboard_text(void)
-{
- return SDL_HasClipboardText();
-}
-
-VG_API void _vg_ui_init(void)
-{
- VG_ASSERT( _vg_thread_has_flags( VG_THREAD_OWNS_OPENGL ) );
-
- u32 verts = 30000, indices = 20000;
- ui_init( &vg_ui.ctx, vg_malloc( sizeof(ui_vert)*verts ), verts, vg_malloc( sizeof(u16)*indices ), indices );
-
- /* callbacks */
- vg_ui.ctx.render_batch = ui_impl_render_batch;
-
- vg_ui.ctx.have_clipboard_text = _wrap_sdl_hasclipboard_text;
- vg_ui.ctx.get_clipboard_text = SDL_GetClipboardText;
- vg_ui.ctx.free_clipboard_text = SDL_free;
- vg_ui.ctx.set_clipboard_text = SDL_SetClipboardText;
- vg_ui.ctx.start_text_input = SDL_StartTextInput;
- vg_ui.ctx.stop_text_input = SDL_StopTextInput;
-
- /* Generate the buffer we are gonna be drawing to */
- glGenVertexArrays( 1, &vg_ui.vao );
- glGenBuffers( 1, &vg_ui.vbo );
- glGenBuffers( 1, &vg_ui.ebo );
-
- glBindVertexArray( vg_ui.vao );
- glBindBuffer( GL_ARRAY_BUFFER, vg_ui.vbo );
- glBufferData( GL_ARRAY_BUFFER, verts*sizeof(ui_vert), NULL, GL_DYNAMIC_DRAW );
-
- glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vg_ui.ebo );
- glBufferData( GL_ELEMENT_ARRAY_BUFFER, indices*sizeof(u16), NULL, GL_DYNAMIC_DRAW );
-
- /* Set pointers */
- u32 const stride = sizeof(ui_vert);
-
- /* XY */
- glVertexAttribPointer( 0, 2, GL_SHORT, GL_FALSE, stride, (void *)offsetof( ui_vert, co ) );
- glEnableVertexAttribArray( 0 );
-
- /* UV */
- glVertexAttribPointer( 1, 2, GL_UNSIGNED_SHORT, GL_FALSE, stride, (void *)offsetof( ui_vert, uv ) );
- glEnableVertexAttribArray( 1 );
-
- /* COLOUR */
- glVertexAttribPointer( 2, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, (void *)offsetof( ui_vert, colour ) );
- glEnableVertexAttribArray( 2 );
-
- vg_ui.cursor_map[ k_ui_cursor_default ] = SDL_CreateSystemCursor( SDL_SYSTEM_CURSOR_ARROW );
- vg_ui.cursor_map[ k_ui_cursor_hand ] = SDL_CreateSystemCursor( SDL_SYSTEM_CURSOR_HAND );
- vg_ui.cursor_map[ k_ui_cursor_ibeam ] = SDL_CreateSystemCursor( SDL_SYSTEM_CURSOR_IBEAM );
-
- /* font
- * -----------------------------------------------------
- */
-
- /* Load default font */
-
- vg_font_sheet *sheet = &vg_default_font_sheet;
- u32 pixels = 0,
- total = sheet->w*sheet->h,
- data = 0;
-
- /* This is fince since its before the load thread even starts */
- u8 image[512*512];
- while( pixels < total )
- {
- for( int b = 31; b >= 0; b-- )
- {
- image[ pixels ++ ] = (sheet->bitmap[data] & (0x1u << b))? 0xffu: 0x00u;
-
- if( pixels >= total )
- {
- total = 0;
- break;
- }
- }
- data++;
- }
-
- vg_ui.inverse_font_sheet[0] = 1.0/(f64)sheet->w;
- vg_ui.inverse_font_sheet[1] = 1.0/(f64)sheet->h;
-
- glGenTextures( 1, &vg_ui.tex_glyphs );
- glBindTexture( GL_TEXTURE_2D, vg_ui.tex_glyphs );
- glTexImage2D( GL_TEXTURE_2D, 0, GL_R8, sheet->w, sheet->h, 0, GL_RED, GL_UNSIGNED_BYTE, image );
-
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
-}
-
-void ui_free(void)
-{
- free( vg_ui.ctx.indice_buffer );
- free( vg_ui.ctx.vertex_buffer );
-}
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_ui/imgui_impl_opengl.c"
-#else
-
-struct vg_ui
-{
- GLuint vao, vbo, ebo;
- m3x3f pv;
- ui_context ctx;
- GLuint tex_glyphs;
- v2f inverse_font_sheet;
-
- SDL_Cursor *cursor_map[ k_ui_cursor_max ];
-
- /* at some point this should be implementation specific? */
- v4f colour;
- f32 frosting;
- v2f bg_inverse_ratio;
-
- vg_tex *tex_bg;
-}
-extern vg_ui;
-
-VG_API void _vg_ui_init(void);
-VG_API void vg_ui_post_update(void);
-VG_API void vg_ui_set_screen( i32 width, i32 height );
-
-#endif
+++ /dev/null
-/*
- * adapted from stb_vorbis.h, since the original does not handle mono->stereo
- */
-int stb_vorbis_get_samples_float_interleaved_stereo( stb_vorbis *f, float *buffer, int len )
-{
- int n = 0, c = 1;
- if( f->channels < 2 ) c = 0;
-
- while( n < len ) {
- int k = f->channel_buffer_end - f->channel_buffer_start;
-
- if( n+k >= len )
- k = len - n;
-
- for( int j=0; j < k; ++j ) {
- *buffer++ = f->channel_buffers[ 0 ][f->channel_buffer_start+j];
- *buffer++ = f->channel_buffers[ c ][f->channel_buffer_start+j];
- }
-
- n += k;
- f->channel_buffer_start += k;
-
- if( n == len )
- break;
-
- if( !stb_vorbis_get_frame_float( f, NULL, NULL ))
- break;
- }
-
- return n;
-}
-
-/*
- * ........ more wrecked code sorry!
- */
-int stb_vorbis_get_samples_i16_downmixed( stb_vorbis *f, signed short *buffer, int len )
-{
- int n = 0, c = 1;
- if( f->channels < 2 ) c = 0;
-
- while( n < len ) {
- int k = f->channel_buffer_end - f->channel_buffer_start;
-
- if( n+k >= len )
- k = len - n;
-
- for( int j=0; j < k; ++j ) {
- float sl = f->channel_buffers[ 0 ][f->channel_buffer_start+j],
- sr = f->channel_buffers[ c ][f->channel_buffer_start+j],
- s = 0.5f*(sl+sr);
-
- if( s < -1.0f ) s = -1.0f;
- if( s > 1.0f ) s = 1.0f;
-
- *buffer++ = s * 32767.0f;
- }
-
- n += k;
- f->channel_buffer_start += k;
-
- if( n == len )
- break;
-
- if( !stb_vorbis_get_frame_float( f, NULL, NULL ))
- break;
- }
-
- return n;
-}
+++ /dev/null
-/* This is just an extension to submodules/stb/stb_vorbis.c, so that we don't have to patch the file directly. */
-
-int stb_vorbis_get_samples_float_interleaved_stereo( stb_vorbis *f, float *buffer, int len );
-int stb_vorbis_get_samples_i16_downmixed( stb_vorbis *f, signed short *buffer, int len );
+++ /dev/null
-struct _vg_window _vg_window;
-
-void GLAPIENTRY MessageCallback( GLenum source,
- GLenum type,
- GLuint id,
- GLenum severity,
- GLsizei length,
- const GLchar* message,
- const void* userParam )
-{
- if( severity == GL_DEBUG_SEVERITY_HIGH )
- {
- vg_error( "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n",
- ( type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "" ),
- type, severity, message );
- }
- else
- {
- vg_low( "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n",
- ( type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "" ),
- type, severity, message );
- }
-}
-
-VG_API void _vg_window_register(void)
-{
- vg_console_reg_var( "vg_screen_mode", &_vg_window.display_mode, k_var_dtype_i32, VG_VAR_PERSISTENT );
- vg_console_reg_var( "vg_vsync", &_vg_window.vsync, k_var_dtype_i32, VG_VAR_PERSISTENT );
-}
-
-VG_API void _vg_window_init(void)
-{
- VG_ASSERT( _vg_thread_has_flags( VG_THREAD_OWNS_SDL|VG_THREAD_OWNS_OPENGL ) );
- SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
-#if 0
- SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3 );
- SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 3 );
-#endif
- SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 4 );
- SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 3 );
- SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE );
- SDL_GL_SetAttribute( SDL_GL_CONTEXT_RELEASE_BEHAVIOR, SDL_GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH );
- SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 );
- SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 );
- SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 );
- SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 8 );
- SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 0 );
-
- /*
- * Get monitor information
- */
- vg_info( "Getting display count\n" );
- i32 display_count = 0,
- display_index = 0,
- mode_index = 0;
-
- SDL_DisplayMode video_mode;
- if( SDL_GetDesktopDisplayMode( display_index, &video_mode ) )
- {
- vg_error( "SDL_GetDesktopDisplayMode failed: %s\n", SDL_GetError() );
- SDL_Quit();
- exit(0);
- }
-
- _vg_window.monitor_refresh_rate = video_mode.refresh_rate;
- _vg_window.w = video_mode.w;
- _vg_window.h = video_mode.h;
- if( _vg_window.display_mode == k_vg_window_windowed )
- {
- _vg_window.w = 1280;
- _vg_window.h = 720;
- }
-
-#ifndef _WIN32
- SDL_SetHint( "SDL_VIDEO_X11_XINERAMA", "1" );
- SDL_SetHint( "SDL_VIDEO_X11_XRANDR", "0" );
- SDL_SetHint( "SDL_VIDEO_X11_XVIDMODE", "0" );
-#endif
-
- u32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_INPUT_GRABBED |
- SDL_WINDOW_RESIZABLE;
-
- if( _vg_window.display_mode == k_vg_window_fullscreen )
- flags |= SDL_WINDOW_FULLSCREEN;
- else if( _vg_window.display_mode == k_vg_window_fullscreen_desktop )
- flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
-
- vg_info( "CreateWindow( %d %d %u )\n", _vg_window.w, _vg_window.h, flags );
- if(( _vg_window.sdl_hwindow = SDL_CreateWindow( "Voyager Game Engine", 0, 0, _vg_window.w, _vg_window.h, flags )))
- {
- if( _vg_window.display_mode == k_vg_window_windowed )
- SDL_SetWindowPosition( _vg_window.sdl_hwindow, video_mode.w-_vg_window.w, 0 );
- }
- else
- {
- vg_error( "SDL_CreateWindow failed: %s", SDL_GetError() );
- exit(0);
- }
-
- SDL_RaiseWindow( _vg_window.sdl_hwindow );
- SDL_SetWindowMinimumSize( _vg_window.sdl_hwindow, 1280, 720 );
- SDL_SetWindowMaximumSize( _vg_window.sdl_hwindow, 4096, 4096 );
-
- vg_info( "CreateContext\n" );
-
- /* ????? */
- if( SDL_IsTextInputActive() )
- SDL_StopTextInput();
-
- /*
- * OpenGL loading
- */
- if( ( _vg_window.sdl_hopengl = SDL_GL_CreateContext( _vg_window.sdl_hwindow ) ))
- {
- SDL_GL_GetDrawableSize( _vg_window.sdl_hwindow, &_vg_window.w, &_vg_window.h );
- vg_success( "Window created (%dx%d)\n", _vg_window.w, _vg_window.h );
- }
- else
- {
- vg_error( "SDL_GL_CreateContext failed: %s\n", SDL_GetError() );
- SDL_Quit();
- exit(0);
- }
-
- if( !gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress) )
- {
- vg_error( "Glad Failed to initialize\n" );
- SDL_GL_DeleteContext( _vg_window.sdl_hopengl );
- SDL_Quit();
- exit(0);
- }
-
- const unsigned char* glver = glGetString( GL_VERSION );
- vg_success( "Load setup complete, OpenGL version: %s\n", glver );
-
-
- glEnable ( GL_DEBUG_OUTPUT );
- glDebugMessageCallback( MessageCallback, 0 );
-
- SDL_GL_SetSwapInterval(0); /* disable vsync while loading */
- SDL_DisplayMode dispmode;
- if( !SDL_GetWindowDisplayMode( _vg_window.sdl_hwindow, &dispmode ) )
- if( dispmode.refresh_rate )
- _vg_window.monitor_refresh_rate = dispmode.refresh_rate;
-
- if( _vg_window.monitor_refresh_rate < 25 || _vg_window.monitor_refresh_rate > 300 )
- _vg_window.monitor_refresh_rate = 60;
- vg_info( "Display refresh rate: %d, we chose: %d\n", dispmode.refresh_rate, _vg_window.monitor_refresh_rate );
-
- SDL_SetRelativeMouseMode(1);
-}
-
-VG_API void _vg_window_swap(void)
-{
- /* Vsync switching
- * ----------------------------- */
- if( _vg_window.vsync && (_vg_window.vsync_feature != k_vsync_feature_error) )
- {
- /* turn on vsync if not enabled */
-
- enum vsync_feature requested = k_vsync_feature_enabled;
- if( _vg_window.vsync < 0 )
- requested = k_vsync_feature_enabled_adaptive;
-
- if( _vg_window.vsync_feature != requested )
- {
- vg_info( "Setting swap interval\n" );
- int swap_interval = 1;
- if( requested == k_vsync_feature_enabled_adaptive )
- swap_interval = -1;
-
- if( SDL_GL_SetSwapInterval( swap_interval ) == -1 )
- {
- if( requested == k_vsync_feature_enabled )
- {
- ui_start_modal( &vg_ui.ctx, "Vsync not supported on this system.\n\n"
- "You may be overriding it in your"
- " graphics \ncontrol panel.\n",
- NULL, UI_MODAL_BAD, NULL );
- }
- else
- {
- ui_start_modal( &vg_ui.ctx, "Adaptive Vsync is not supported by your system\n\n"
- "You may be overriding it in your"
- " graphics \ncontrol panel.\n",
- NULL, UI_MODAL_BAD, NULL );
- }
- _vg_window.vsync_feature = k_vsync_feature_error;
- _vg_window.vsync = 0;
- }
- else
- {
- vg_success( "Vsync enabled (%d)\n", requested );
- _vg_window.vsync_feature = requested;
- }
- }
- }
- else
- {
- if( _vg_window.vsync_feature != k_vsync_feature_disabled )
- {
- SDL_GL_SetSwapInterval( 0 );
- _vg_window.vsync_feature = k_vsync_feature_disabled;
- }
- }
-
- _vg_profiler_enter_block( vg.profiler, "vg_engine:swap" );
- SDL_GL_SwapWindow( _vg_window.sdl_hwindow );
- _vg_profiler_exit_block( vg.profiler );
-}
-
-VG_API void _vg_window_size_changed(void)
-{
- i32 w, h;
- SDL_GL_GetDrawableSize( _vg_window.sdl_hwindow, &w, &h );
-
- if( !w || !h )
- {
- vg_warn( "Got a invalid framebuffer size: %dx%d... ignoring\n", w, h );
- }
- else
- {
-
- i32 delta[2] = { w - _vg_window.w, h - _vg_window.h };
- _vg_magi_area_change( delta );
- _vg_window.w = w;
- _vg_window.h = h;
-
- vg_framebuffer_update_sizes();
- }
-}
-
-VG_API void _vg_window_set_fpv_mouse( bool yes )
-{
- if( yes )
- {
- SDL_SetWindowGrab( _vg_window.sdl_hwindow, SDL_TRUE );
- SDL_SetRelativeMouseMode( SDL_TRUE );
- }
- else
- {
- SDL_SetWindowGrab( _vg_window.sdl_hwindow, SDL_FALSE );
- SDL_SetRelativeMouseMode( SDL_FALSE );
- }
-}
-
-VG_API void _vg_window_set_mouse( i32 x, i32 y )
-{
- SDL_WarpMouseInWindow( _vg_window.sdl_hwindow, x, y );
-}
-
-VG_API void _vg_window_shutdown(void)
-{
- SDL_GL_DeleteContext( _vg_window.sdl_hopengl );
-}
+++ /dev/null
-#if defined( VG_IMPLEMENTATION )
-# include "vg/vg_window.c"
-#else
-
-enum vg_window_display_mode
-{
- k_vg_window_fullscreen_desktop = 0,
- k_vg_window_fullscreen = 1,
- k_vg_window_windowed = 2
-};
-
-struct _vg_window
-{
- SDL_Window *sdl_hwindow;
- SDL_GLContext *sdl_hopengl;
- i32 w, h, monitor_refresh_rate, vsync, display_index;
-
- i32 display_mode;
-
- enum vsync_feature
- {
- k_vsync_feature_disabled=0,
- k_vsync_feature_enabled=1,
- k_vsync_feature_enabled_adaptive=2,
- k_vsync_feature_error=3
- }
- vsync_feature;
-
- u32 swap_profiler;
-}
-extern _vg_window;
-
-VG_API void _vg_window_register(void);
-VG_API void _vg_window_init(void);
-
-VG_API void _vg_window_shutdown(void);
-VG_API void _vg_window_swap(void);
-VG_API void _vg_window_size_changed(void);
-VG_API void _vg_window_set_fpv_mouse( bool yes );
-VG_API void _vg_window_set_mouse( i32 x, i32 y );
-
-#endif