el patcho
authorhgn <hgodden00@gmail.com>
Fri, 15 Aug 2025 00:38:53 +0000 (00:38 +0000)
committerhgn <hgodden00@gmail.com>
Fri, 15 Aug 2025 00:38:53 +0000 (00:38 +0000)
17 files changed:
build.c
qrenderdoc.cap [new file with mode: 0644]
src/addon.c
src/client.c
src/client.h
src/ent_skateshop.c
src/model.c
src/player_render.c
src/save2.c
src/save2.h
src/scene.c
src/scene.h
src/world.h
src/world_gen.c
src/world_load.c
src/world_routes.c
src/world_sfd.c

diff --git a/build.c b/build.c
index a5150c3383bd5332e44da4233b8c71b082e05215..5c74ba42384d376d7a9cd9f9425c839a15767189 100644 (file)
--- a/build.c
+++ b/build.c
@@ -162,6 +162,17 @@ void build_game_content( struct vg_project *proj )
 
 void vg_build_scripts(void)
 {
+   if( vg_long_opt( "qt", "quick test stuff" ) )
+   {
+      c8 formatted[ 1024 ];
+      vg_str value_str;
+      vg_strnull( &value_str, formatted, sizeof(formatted) );
+      vg_strcatf64( &value_str, 0.008f, 10, 5 );
+      vg_strcatch( &value_str, ' ' );
+      vg_strcatf64( &value_str, 2.008f, 10, 5 );
+      vg_info( "Formatted: %s\n", formatted );
+   }
+
    if( vg_long_opt( "skaterift", "Make skaterift" ) )
    {
       struct vg_project proj;
diff --git a/qrenderdoc.cap b/qrenderdoc.cap
new file mode 100644 (file)
index 0000000..3e80303
--- /dev/null
@@ -0,0 +1,33 @@
+{
+    "rdocCaptureSettings": 1,
+    "settings": {
+        "autoStart": false,
+        "commandLine": "--no-steam --noauth",
+        "environment": [
+            {
+                "separator": "Platform style",
+                "type": "Set",
+                "value": "/usr/lib/gcc/x86_64-linux-gnu/12/libasan.so:./libworkaround-27653.so",
+                "variable": "LD_PRELOAD"
+            }
+        ],
+        "executable": "/home/harry/source/skaterift/bin/skaterift/skaterift",
+        "inject": false,
+        "numQueuedFrames": 0,
+        "options": {
+            "allowFullscreen": true,
+            "allowVSync": true,
+            "apiValidation": false,
+            "captureAllCmdLists": false,
+            "captureCallstacks": false,
+            "captureCallstacksOnlyDraws": false,
+            "debugOutputMute": true,
+            "delayForDebugger": 0,
+            "hookIntoChildren": false,
+            "refAllResources": false,
+            "verifyBufferAccess": false
+        },
+        "queuedFrameCap": 0,
+        "workingDir": ""
+    }
+}
index 0ed7edcf3c61f2183f144cc3fa5d887e4f6e10e1..939b0d3303e38504150d9f435bc40008842ada24 100644 (file)
@@ -193,7 +193,7 @@ void addon_make_savedata_path( addon_id id, char out_buf[ 256 ] )
 {
    char uid[ ADDON_UID_MAX ];
    addon_make_uid( id, uid );
-   snprintf( out_buf, 256, "savedata/%s.bkv", uid );
+   snprintf( out_buf, 256, "savedata/%s.kv", uid );
 }
 
 u32 addon_uid_get_custom_part( const char *uid, char out_cpart[ ADDON_CPART_MAX ] )
@@ -376,16 +376,20 @@ static bool addon_try_load_metadata( addon_reg *reg, const char *folder_path )
    }
    else 
    {
+      bool ok = 0;
       u32 size;
-      void *legacy_msg_buf = vg_file_read( NULL, path_buf, &size, 0 );
-
-      if( legacy_msg_buf )
+      u32 temp_frame = _vg_start_temp_frame();
       {
-         vg_kvs_append_from_legacy_msg2( &reg->metadata, 0, legacy_msg_buf, size );
-         vg_free( legacy_msg_buf );
-         return 1;
+         void *legacy_msg_buf = vg_file_read( _vg_temp_stack(), path_buf, &size, 0 );
+
+         if( legacy_msg_buf )
+         {
+            vg_kvs_append_from_legacy_msg2( &reg->metadata, 0, legacy_msg_buf, size );
+            ok = 1;
+         }
       }
-      else return 0;
+      _vg_end_temp_frame( temp_frame );
+      return ok;
    }
 }
 
index 55486ca4440f6f301388f3b416d76f0f0c18ac1d..4a617698ea61ec10063420a735da86b7ab8ef56f 100644 (file)
@@ -88,8 +88,9 @@ void client_event_handler( vg_event_info *info )
    else if( info->type == k_vg_event_init )
    {
       _vg_loader_set_user_information( "Initializing subsystems" );
+      _vg_loader_increment( +2 );
 
-      _vg_async_context_push_groups( SKATERIFT_LOAD_GROUP );
+      _vg_async_context_push_groups( SKATERIFT_LOAD_GROUP, 0 );
       _demo_check_init();
       _render_init();
       _remote_players_init();
@@ -98,6 +99,7 @@ void client_event_handler( vg_event_info *info )
       _user_profile_init();
       _particles_init();
       _addon_system_init();
+      _savedata_init();
 
       _player_init();
       _player_render_init();
@@ -123,36 +125,53 @@ void client_event_handler( vg_event_info *info )
    }
    else if( info->type == k_vg_event_pre_update )
    {
+      if( _vg_async_group_count( SKATERIFT_LOAD_GROUP ) )
+         return;
 
-#if 0
-         if( co_step( co, 1 ) )
+      if( skaterift.main_save_handle == 0 )
+      {
+         _vg_loader_set_user_information( "Loading savedata" );
+         skaterift.main_save_handle = _savedata_handle( 0 );
+         _vg_loader_increment( -1 );
+      }
+
+      if( !skaterift.loaded_mainsave )
+      {
+         if( _savefile_state( skaterift.main_save_handle ) == k_savefile_ready )
          {
-            /* initializing / loading world. */
-            vg_loader_set_user_information( "Loading savedata" );
-            skaterift_load_mainsave();
+            addon_id world_to_load = _world.default_hub_addon;
 
-            if( skaterift.override_load_world )
-               _world.load_addon = _addon_mount_from_folder_path( skaterift.override_load_world, k_addon_type_world, ".mdl" );
+            vg_kvs *kvs = _savefile_kvs( skaterift.main_save_handle );
+            u32 player_block = vg_kv_find( kvs, 0, "player" );
+            if( player_block )
+            {
+               const c8 *location = vg_kv_read_string( kvs, player_block, "location", NULL );
+               if( location )
+               {
+                  /* do do do parsing the location thingy! */
+               }
+            }
 
             _world.loader_instance = &_world.main;
             _world.loader_preview_mode = 0;
-            _world.loader_stack = _world.stack;
+            _world.loader_stack = &_world.stack;
+            _world_loader_set_addon( world_to_load );
+            _world.loader_state = k_world_loader_ready;
 
-            if( !_world.load_addon )
-            {
-               vg_warn( "Falling back to default hub world...\n" );
-               _world.load_addon = _world.default_hub_addon;
-            }
-
-            _world_loader_set_addon( _world.load_addon );
+            skaterift.loaded_mainsave = 1;
          }
+      }
+
+#if 0
+            if( skaterift.override_load_world )
+               _world.load_addon = _addon_mount_from_folder_path( skaterift.override_load_world, k_addon_type_world, ".mdl" );
 #endif
 
 
       skaterift_preupdate_inputs();
       world_switcher_update();
 
-      if( !skaterift.ready_to_show_game )
+      if( _vg_loader_visible() )
          return;
 
       //draw_origin_axis();
@@ -207,7 +226,7 @@ void client_event_handler( vg_event_info *info )
    }
    else if( info->type == k_vg_event_fixed_update )
    {
-      if( !skaterift.ready_to_show_game )
+      if( _vg_loader_visible() )
          return;
 
       world_routes_fixedupdate( &_world.main );
@@ -215,7 +234,7 @@ void client_event_handler( vg_event_info *info )
    }
    else if( info->type == k_vg_event_post_update )
    {
-      if( !skaterift.ready_to_show_game )
+      if( _vg_loader_visible() )
          return;
 
       player__post_update();
@@ -246,209 +265,201 @@ void client_event_handler( vg_event_info *info )
    }
    else if( info->type == k_vg_event_render )
    {
-      if( !skaterift.ready_to_show_game )
-         return;
-
       glBindFramebuffer( GL_FRAMEBUFFER, 0 );
 
       glViewport( 0,0, _vg_window.w, _vg_window.h );
       glDisable( GL_DEPTH_TEST );
       glDisable( GL_BLEND );
 
-      glClearColor( 1.0f, 0.0f, 0.0f, 0.0f );
+      glClearColor( 0.1f, 0.0f, 0.3f, 0.0f );
       glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
 
+      if( _vg_loader_visible() )
+         return;
+
       /* RENDER main game 
        * ------------------------------------------------------------------------------------------------------------ */
+      if( (_cutscene.state >= k_cutscene_state_ready) && _cutscene.player_binding )
       {
-         if( (_cutscene.state >= k_cutscene_state_ready) && _cutscene.player_binding )
-         {
-            struct cs_instance *inst = _cutscene.player_binding;
-            ms_skeleton *sk = &localplayer.skeleton;
-            for( u32 i=0; i<sk->bone_count; i ++ )
-               m4x3_copy( inst->skinning_data[i], localplayer.final_mtx[i] );
-         }
-         else if( skaterift.activity == k_skaterift_replay ){}
-         else
-         {
-            player__animate();
-            _replay2_record_local_frame();
-         }
-
-         animate_remote_players();
-         player__pre_render();
+         struct cs_instance *inst = _cutscene.player_binding;
+         ms_skeleton *sk = &localplayer.skeleton;
+         for( u32 i=0; i<sk->bone_count; i ++ )
+            m4x3_copy( inst->skinning_data[i], localplayer.final_mtx[i] );
+      }
+      else if( skaterift.activity == k_skaterift_replay ){}
+      else
+      {
+         player__animate();
+         _replay2_record_local_frame();
+      }
 
+      animate_remote_players();
+      player__pre_render();
 
-         /* world entity driven camera 
-          * ------------------------------------------------------------------------------ */
-         if( _world.entity_set_camera )
-         {
-            _world.entity_set_camera = 0;
-            _world.entity_camera_modulate = vg_minf( 1.0f, _world.entity_camera_modulate+vg.time_frame_delta );
-         }
-         else
-         {
-            _world.entity_camera_modulate = vg_maxf( 0.0f, _world.entity_camera_modulate-vg.time_frame_delta );
-         }
-         
-         vg_camera_lerp( &localplayer.cam, &_world.entity_driven_camera,
-                         vg_smoothstepf(_world.entity_camera_modulate), &g_render.cam );
 
-         /* replay camera 
-          * ------------------------------------------------------------------ */
-         if( skaterift.activity == k_skaterift_replay )
-         {
-            _replay2_get_camera( &g_render.cam );
-         }
+      /* world entity driven camera 
+       * ------------------------------------------------------------------------------ */
+      if( _world.entity_set_camera )
+      {
+         _world.entity_set_camera = 0;
+         _world.entity_camera_modulate = vg_minf( 1.0f, _world.entity_camera_modulate+vg.time_frame_delta );
+      }
+      else
+      {
+         _world.entity_camera_modulate = vg_maxf( 0.0f, _world.entity_camera_modulate-vg.time_frame_delta );
+      }
 
-         if( skaterift.activity == k_skaterift_spectate )
-         {
-            _network_get_spectate_cam( &g_render.cam );
-         }
+      vg_camera_lerp( &localplayer.cam, &_world.entity_driven_camera,
+                      vg_smoothstepf(_world.entity_camera_modulate), &g_render.cam );
 
-         g_render.cam.nearz = 0.1f;
-         g_render.cam.farz  = 2100.0f;
+      /* replay camera 
+       * ------------------------------------------------------------------ */
+      if( skaterift.activity == k_skaterift_replay )
+      {
+         _replay2_get_camera( &g_render.cam );
+      }
 
-         /* menu override camera 
-          * -------------------------------------------------------------------- */
-         if( (skaterift.activity == k_skaterift_menu) && menu.bg_cam )
-         {
-            ent_camera_unpack( menu.bg_cam, &g_render.cam );
-         }
+      if( skaterift.activity == k_skaterift_spectate )
+      {
+         _network_get_spectate_cam( &g_render.cam );
+      }
 
-         /* cutscene camera TODO: Fix the action camera 
-          * ---------------------------------------------------------------- */
-         ent_camera *cs_cam = _cutscene_active_camera();
-         if( cs_cam )
-            ent_camera_unpack( cs_cam, &g_render.cam );
+      g_render.cam.nearz = 0.1f;
+      g_render.cam.farz  = 2100.0f;
 
-         world_map_get_transition_cam( &g_render.cam );
+      /* menu override camera 
+       * -------------------------------------------------------------------- */
+      if( (skaterift.activity == k_skaterift_menu) && menu.bg_cam )
+      {
+         ent_camera_unpack( menu.bg_cam, &g_render.cam );
+      }
 
-         vg_camera_update_transform( &g_render.cam );
+      /* cutscene camera TODO: Fix the action camera 
+       * ---------------------------------------------------------------- */
+      ent_camera *cs_cam = _cutscene_active_camera();
+      if( cs_cam )
+         ent_camera_unpack( cs_cam, &g_render.cam );
 
-         vg_camera_update_view( &g_render.cam );
-         vg_camera_update_projection( &g_render.cam, _vg_window.w, _vg_window.h );
-         vg_camera_finalize( &g_render.cam );
+      world_map_get_transition_cam( &g_render.cam );
 
+      vg_camera_update_transform( &g_render.cam );
+      vg_camera_update_view( &g_render.cam );
+      vg_camera_update_projection( &g_render.cam, _vg_window.w, _vg_window.h );
+      vg_camera_finalize( &g_render.cam );
 
 
 
+      bool render_actual_game = !menu_viewing_map();
+      bool render_stenciled = 0;
 
+      if( render_actual_game )
+      {
+         world_instance *world = &_world.main;
+         render_world_cubemaps( world );
+      }
 
+      /* variable res target */
+      vg_framebuffer_bind( _vg_render.fb_main, _vg_render.scale );
+      glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
+      glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT );
 
-         bool render_actual_game = !menu_viewing_map();
-         bool render_stenciled = 0;
+      if( !render_actual_game )
+      {
+         render_world_map();
 
-         if( render_actual_game )
+         if( world_map_get_transition_cam(NULL) )
          {
-            world_instance *world = &_world.main;
-            render_world_cubemaps( world );
+            glEnable( GL_STENCIL_TEST );
+            glDisable( GL_DEPTH_TEST );
+            glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
+            glStencilFunc( GL_ALWAYS, 1, 0xFF );
+            glStencilMask( 0xFF );
+            
+            shader_blit_transition_use();
+            shader_blit_transition_uInverseRatio( (v2f){1.0f,1.0f} );
+            shader_blit_transition_uT( -(sqrtf(2)+0.5f) * world_map.spawn_timer );
+            render_fsquad();
+            render_stenciled = 1;
+            render_actual_game = 1;
          }
+      }
 
-         /* variable res target */
-         vg_framebuffer_bind( _vg_render.fb_main, _vg_render.scale );
-         glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
-         glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT );
-
-         if( !render_actual_game )
-         {
-            render_world_map();
-
-            if( world_map_get_transition_cam(NULL) )
-            {
-               glEnable( GL_STENCIL_TEST );
-               glDisable( GL_DEPTH_TEST );
-               glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
-               glStencilFunc( GL_ALWAYS, 1, 0xFF );
-               glStencilMask( 0xFF );
-               
-               shader_blit_transition_use();
-               shader_blit_transition_uInverseRatio( (v2f){1.0f,1.0f} );
-               shader_blit_transition_uT( -(sqrtf(2)+0.5f) * world_map.spawn_timer );
-               render_fsquad();
-               render_stenciled = 1;
-               render_actual_game = 1;
-            }
-         }
+      if( render_actual_game )
+      {
+         /* Draw world */
+         glEnable( GL_DEPTH_TEST );
+         world_prerender( &_world.main );
 
-         if( render_actual_game )
-         {
-            /* Draw world */
-            glEnable( GL_DEPTH_TEST );
-            world_prerender( &_world.main );
+         render_world( &_world.main, &g_render.cam, render_stenciled, 0, 1, 1, _vg_render.fb_main );
 
-            render_world( &_world.main, &g_render.cam, render_stenciled, 0, 1, 1, _vg_render.fb_main );
+         particle_system_update( &particles_grind, vg.time_delta );
+         //particle_system_debug( &particles_grind );
+         particle_system_prerender( &particles_grind );
+         particle_system_render( &particles_grind, &g_render.cam );
+         
+         ent_tornado_pre_update();
+         particle_system_update( &particles_env, vg.time_delta );
+         particle_system_prerender( &particles_env );
+         particle_system_render( &particles_env, &g_render.cam );
 
-            particle_system_update( &particles_grind, vg.time_delta );
-            //particle_system_debug( &particles_grind );
-            particle_system_prerender( &particles_grind );
-            particle_system_render( &particles_grind, &g_render.cam );
-            
-            ent_tornado_pre_update();
-            particle_system_update( &particles_env, vg.time_delta );
-            particle_system_prerender( &particles_env );
-            particle_system_render( &particles_env, &g_render.cam );
+         player_glide_render_effects( &g_render.cam );
+      }
 
-            player_glide_render_effects( &g_render.cam );
-         }
+      glEnable( GL_DEPTH_TEST );
 
-         glEnable( GL_DEPTH_TEST );
+      /* full res target */
+      glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+      glViewport( 0,0, _vg_window.w, _vg_window.h );
 
-         /* full res target */
-         glBindFramebuffer( GL_FRAMEBUFFER, 0 );
-         glViewport( 0,0, _vg_window.w, _vg_window.h );
+      if( render_actual_game && !render_stenciled )
+      {
+         bool render_player_transparent = 1;
 
-         if( render_actual_game && !render_stenciled )
+         if( (skaterift.activity == k_skaterift_menu) &&
+             (menu.page == k_menu_page_main) && 
+             (menu.main_index == k_menu_main_guide) )
          {
-            bool render_player_transparent = 1;
-
-            if( (skaterift.activity == k_skaterift_menu) &&
-                (menu.page == k_menu_page_main) && 
-                (menu.main_index == k_menu_main_guide) )
-            {
-               render_player_transparent = 0;
-            }
+            render_player_transparent = 0;
+         }
 
-            if( skaterift.activity == k_skaterift_replay )
-               render_player_transparent = 0;
+         if( skaterift.activity == k_skaterift_replay )
+            render_player_transparent = 0;
 
-            if( render_player_transparent )
-            {
-               static vg_camera small_cam;      /* DOES NOT NEED TO BE STATIC BUT MINGW 
-                                                SAIS OTHERWISE */
+         if( render_player_transparent )
+         {
+            static vg_camera small_cam;      /* DOES NOT NEED TO BE STATIC BUT MINGW 
+                                             SAIS OTHERWISE */
 
-               m4x3_copy( g_render.cam.transform, small_cam.transform );
+            m4x3_copy( g_render.cam.transform, small_cam.transform );
 
-               small_cam.fov = g_render.cam.fov;
-               small_cam.nearz = 0.05f;
-               small_cam.farz  = 60.0f;
+            small_cam.fov = g_render.cam.fov;
+            small_cam.nearz = 0.05f;
+            small_cam.farz  = 60.0f;
 
-               vg_camera_update_view( &small_cam );
-               vg_camera_update_projection( &small_cam, _vg_window.w, _vg_window.h );
-               vg_camera_finalize( &small_cam );
+            vg_camera_update_view( &small_cam );
+            vg_camera_update_projection( &small_cam, _vg_window.w, _vg_window.h );
+            vg_camera_finalize( &small_cam );
 
-               /* Draw player to window buffer and blend background ontop */
-               player__render( &small_cam );
-            }
-
-            /* continue with variable rate */
-            vg_framebuffer_bind( _vg_render.fb_main, _vg_render.scale );
-            render_world_gates( &_world.main, &g_render.cam, _vg_render.fb_main );
+            /* Draw player to window buffer and blend background ontop */
+            player__render( &small_cam );
          }
 
-         /* composite */
-         if( (skaterift.activity == k_skaterift_menu) && menu.bg_blur )
-            v2_muls( (v2f){ 0.04f, 0.001f }, 1.0f-skaterift.time_rate, g_render.blur_override );
-         else 
-            v2_zero( g_render.blur_override );
+         /* continue with variable rate */
+         vg_framebuffer_bind( _vg_render.fb_main, _vg_render.scale );
+         render_world_gates( &_world.main, &g_render.cam, _vg_render.fb_main );
+      }
 
-         vg_postprocess_to_screen( _vg_render.fb_main );
-         _cutscene_render_fadeout();
+      /* composite */
+      if( (skaterift.activity == k_skaterift_menu) && menu.bg_blur )
+         v2_muls( (v2f){ 0.04f, 0.001f }, 1.0f-skaterift.time_rate, g_render.blur_override );
+      else 
+         v2_zero( g_render.blur_override );
 
-         if( !_gui_helpers_active() )
-            control_overlay_render();
-      }
+      vg_postprocess_to_screen( _vg_render.fb_main );
+      _cutscene_render_fadeout();
 
+      if( !_gui_helpers_active() )
+         control_overlay_render();
 
       m4x4_copy( g_render.cam.mtx.pv, vg.pv );
       
@@ -461,7 +472,7 @@ void client_event_handler( vg_event_info *info )
    }
    else if( info->type == k_vg_event_gui )
    {
-      if( !skaterift.ready_to_show_game )
+      if( _vg_loader_visible() )
          return;
 
       glBindFramebuffer( GL_FRAMEBUFFER, 0 );
index 36d1865e7c11838174080c125b10e8ba747e6b49..5a954ca05a119dbec8a80424dde84dff8832f02d 100644 (file)
@@ -44,8 +44,9 @@ struct skaterift_globals
 
    f32 boost_scale;
    bool no_save_location;
+   u16 main_save_handle;
 
-   bool ready_to_show_game;
+   bool loaded_mainsave;
 }
 extern skaterift;
 
index efe5a2921fea6e60ff7a097acc6834b057e95016..161bc761cea9445d91ffabc3d31dac223daf7cd7 100644 (file)
@@ -640,7 +640,7 @@ void charshop_gui( ui_context *ctx )
          for( u32 i=0; i<prop_count; i ++ )
          {
             editer_property *prop = af_arritm( &model->editer_property, i );
-            const char *alias = af_str( &model->model.packed_strings, prop->pstr_alias );
+            const char *alias = af_str( model->model.packed_strings, prop->pstr_alias );
 
             if( prop->ui_type == k_editer_type_toggle )
             {
index 187b4911e0bf342bb32906f4a1bca475dc42cce2..167ca8cb78e057db6caf32737b4539a8ac242e67 100644 (file)
@@ -47,13 +47,17 @@ VG_TIER_2 static void vg_model_stream_materials( vg_model_stream_context *ctx, v
       array_file_ptr v106_data;
       array_file_ptr v110_data;
 
-#if (VG_MODEL_VERSION_MIN <= 105)
       if( ctx->model->version <= 105 )
+#if (VG_MODEL_VERSION_MIN <= 105)
          af_load_array( &ctx->af, &v101_materials, "mdl_material", _vg_temp_stack(), sizeof(struct mdl_material_v101) );
-      else
+#else
+         vg_fatal_error( "Unsupported model version (%u)\n", ctx->model->version );
 #endif
-      if( ctx->model->version <= 109 )
+      else if( ctx->model->version <= 109 )
+      {
          af_load_array( &ctx->af, &v106_data, "shader_data", _vg_temp_stack(), 1 );
+         vg_mem_dumphex( stdout, v106_data.data, 0, v106_data.count );
+      }
       else
          af_load_array( &ctx->af, &v110_data, "shader_props", _vg_temp_stack(), 1 );
 
@@ -61,9 +65,9 @@ VG_TIER_2 static void vg_model_stream_materials( vg_model_stream_context *ctx, v
       vg_kvs_init( &kvs, _vg_temp_stack() );
 
       /* step1 ----------------------------- */
-#if (VG_MODEL_VERSION_MIN <= 105)
       if( ctx->model->version <= 105 )
       {
+#if (VG_MODEL_VERSION_MIN <= 105)
          for( u32 i=0; i<ctx->model->material_count; i ++ )
          {
             mdl_material *mat = &ctx->model->materials[ i ];
@@ -94,24 +98,24 @@ VG_TIER_2 static void vg_model_stream_materials( vg_model_stream_context *ctx, v
                vg_kv_append_vf32( &kvs, mat->props.kv_root, "deep_colour", old->colour1, 4 );
             }
          }
-      }
-
-      else
+#else
+         VG_ASSERT(0);
 #endif
-
-      if( ctx->model->version <= 109 )
+      }
+      else if( ctx->model->version <= 109 )
       {
          for( u32 i=0; i<ctx->model->material_count; i ++ )
          {
             mdl_material *mat = &ctx->model->materials[ i ];
-            mat->props.kv_root = vg_kv_append( &kvs, 0, NULL, NULL );
-            vg_kv_append( &kvs, mat->props.kv_root, "version", "106" );
+            u32 root = vg_kv_append( &kvs, 0, NULL, NULL );
+            vg_kv_append( &kvs, root, "version", "106" );
 
             void *buffer = NULL;
             if( v106_data.data )
                buffer = v106_data.data + mat->props.kvs.offset;
 
-            vg_kvs_append_from_legacy_msg2( &kvs, mat->props.kv_root, buffer, mat->props.kvs.size );
+            vg_kvs_append_from_legacy_msg2( &kvs, root, buffer, mat->props.kvs.size );
+            mat->props.kv_root = root;
          }
       }
       else
@@ -119,8 +123,8 @@ VG_TIER_2 static void vg_model_stream_materials( vg_model_stream_context *ctx, v
          for( u32 i=0; i<ctx->model->material_count; i ++ )
          {
             mdl_material *mat = &ctx->model->materials[ i ];
-            mat->props.kv_root = vg_kv_append( &kvs, 0, NULL, NULL );
-            vg_kv_append( &kvs, mat->props.kv_root, "version", "110" );
+            u32 root = vg_kv_append( &kvs, 0, NULL, NULL );
+            vg_kv_append( &kvs, root, "version", "110" );
 
             const c8 *buffer = NULL;
             if( v110_data.data )
@@ -130,14 +134,12 @@ VG_TIER_2 static void vg_model_stream_materials( vg_model_stream_context *ctx, v
             vg_buffer_stream_open( &kv_stream, buffer, mat->props.kvs.size, VG_STREAM_READ );
 
             vg_kv_parser parser;
-            vg_kv_parser_init( &parser, &kvs, mat->props.kv_root );
+            vg_kv_parser_init( &parser, &kvs, root );
             vg_kv_parse_stream( &parser, &kv_stream );
+            mat->props.kv_root = root;
          }
       }
 
-      vg_kv_write wtest = { .fp = stdout, .depth = 0 };
-      vg_kv_print_tree( &wtest, &kvs, 0 );
-
       /* step2 ----------------------------- */
       for( u32 i=0; i<ctx->model->material_count; i ++ )
       {
@@ -145,6 +147,11 @@ VG_TIER_2 static void vg_model_stream_materials( vg_model_stream_context *ctx, v
          u32 root = mat->props.kv_root;
          union shader_props *props = &ctx->model->shader_props[ i ];
 
+         vg_stream stream = { .flags=VG_STREAM_FILE|VG_STREAM_WRITE, .fp = stdout };
+         vg_kv_write writer;
+         vg_kv_write_init( &writer, &stream );
+         vg_kv_write_tree( &writer, &kvs, root );
+
          if( mat->shader == k_shader_standard || 
              mat->shader == k_shader_standard_cutout || 
              mat->shader == k_shader_foliage ||
index 28e5319acadceb29c72652db0a92b2ac093a3320..d2407ade6ffd9cc720f33846b109e42bad3ca998 100644 (file)
@@ -209,6 +209,7 @@ void player_model_load( player_model *pm, const c8 *path, vg_stack_allocator *st
          vg_low( "Reference skeleton has a bone called '%s', retargetee has no such bone..\n", sb->name );
    }
 
+   vg_model_stream_textures_gpu( &ctx );
    vg_model_stream_meshes_gpu( &ctx, fixup_table );
    vg_model_stream_close( &ctx );
 }
index ee49a84f52e1f8187f9d9a113368e8bb23922212..9677bc8a0bfa889a3c280c63f493b35c0f52e513 100644 (file)
 // In the future
 // #define MAX_SAVE_SLOTS 4
 
-VG_API void _skaterift_autosave_post_update( void )
-{
-   VG_ASSERT(0);
-}
-
-#if 0
-
 struct
 {
    struct savefile
    {
-      bool ready;
+      enum savefile_state state;
       vg_stack_allocator stack;
       vg_kvs kvs;
 
       u16 addon_id; /* 0 for main save */
+      u16 reference_count;
    }
    files[ MAX_SAVE_FILES ];
-   vg_pool pool;
-   vg_pool_chain inactive, active;
 }
 _savedata;
 
-void _savedata_init(void)
-{
-   vg_pool_init( &_savedata.pool, &_savedata.inactive, MAX_SAVE_FILES, &vg.rtmem );
-}
-
-
-// Loading 
-while( ... )
-{
-   if( stage == init )
-   {
-      world->savefile = savedata_handle( world->addon );
-      if( world->savefile )
-         stage = read_save;
-   }
-   else if( stage == read_save )
-   {
-      if( savedata_loaded( world->savefile ) )
-      {
-         // read save
-         stage = ready;
-      }
-   }
-}
-
-
-// Game loop
-if( autosave_timer() )
+VG_API void _savedata_init(void)
 {
-   world_autosave(); -> savedata_sync( world->savefile );
+   for( u32 i=0; i<MAX_SAVE_FILES; i ++ )
+      vg_stack_init( &_savedata.files[i].stack, VG_STACK_USE_HEAP, VG_KB(64), "Savedata KVs" );
 }
 
-// Unload
-savedata_sync( world->savefile );
-savedata_release_handle( world->addon );
-
-
-
-
-
-
-
-static u16 _savedata_handle_fork( u16 save_handle )
+VG_API void _skaterift_autosave_post_update( void )
 {
-   VG_ASSERT( _vg_thread_has_flags( VG_THREAD_MAIN ) );
-   if( vg_pool_reference( &_savedata.pool, save_handle, 1 ) == 1 )
-      vg_pool_switch( &_savedata.pool, &_savedata.inactive, &_savedata.active );
-
-   return save_handle;
 }
 
-void _savedata_handle_release( u16 save_handle )
+struct savedata_task
 {
-   VG_ASSERT( _vg_thread_has_flags( VG_THREAD_MAIN ) );
-   if( vg_pool_reference( &_savedata.pool, save_handle, 0 ) == 0 )
-      vg_pool_switch( &_savedata.pool, &_savedata.active, &_savedata.inactive );
-}
+   u16 savefile_id;
+   bool read;
 
-struct savedata_async_info
-{
-   u16 save_handle;
+   u32 buffer_length;
+   c8 buffer[];
 };
-static savedata_async( vg_async_queue *queue, void( *fn )(u16), u16 handle )
-{
-   vg_async_task *task = vg_allocate_async_task( queue, sizeof(struct savedata_async_info), 1 );
-   struct savedata_async_info *info = (void *)complete_task->data;
-   info->save_handle = handle;
-   vg_async_task_dispatch( task, savedata_load );
-}
-
-static savedata_task_complete( vg_async_task *task )
+static void _savedata_complete_task( struct savedata_task *in_args, vg_async_info *async )
 {
    VG_ASSERT( _vg_thread_has_flags( VG_THREAD_MAIN ) );
-   struct savedata_async_info *info = (void *)task->data;
-   struct savefile *sf = &_savedata.files[ vg_pool_index( &_savedata.pool, info->save_handle ) ];
-   sf->ready = 1;
-   _savedata_handle_release( info->save_handle );
+   VG_ASSERT( in_args->savefile_id );
+   struct savefile *save = &_savedata.files[ in_args->savefile_id-1 ];
+   save->state = k_savefile_ready;
+   save->reference_count --;
 }
-
-void savedata_load( vg_async_task *task )
+static void _savedata_readwrite_task( struct savedata_task *in_args, vg_async_info *async )
 {
    VG_ASSERT( _vg_thread_has_flags( VG_THREAD_BACKGROUND ) );
-   struct savedata_async_info *info = (void *)task->data;
-   struct savefile *sf = &_savedata.files[ vg_pool_index( &_savedata.pool, info->save_handle ) ];
+   VG_ASSERT( in_args->savefile_id );
+   struct savefile *save = &_savedata.files[ in_args->savefile_id-1 ];
 
-   vg_stack_clear( &sf->stack );
-   vg_kvs_init( &sf->kvs, &sf->stack );
-   
-   c8 path[ 256 ];
-   addon_make_savedata_path( sf->addon_id, path );
+   c8 save_path[ 256 ];
+   if( save->addon_id )
+      addon_make_savedata_path( save->addon_id, save_path );
+   else
+      strcpy( save_path, "savedata/game.kv" );
 
-   vg_file file;
-   if( vg_file_stream_open( &file, path ) )
+   if( in_args->read )
    {
-      vg_kv_parser parser;
-      vg_kv_parser_init( &parser, &sf->kvs, 0 );
-
-      c8 chunk[ 1024 ];
-read_more:;
-      u32 l = vg_file_stream( &file, chunk, sizeof(chunk) );
-      vg_kv_parse_buffer( &parser, chunk, l );
-
-      if( l == sizeof(chunk) )
-         goto read_more;
+      vg_info( "Reading savefile.. '%s'\n", save_path );
 
-      vg_file_stream_close( &file );
+      if( !vg_kv_read_file( &save->kvs, save_path, &save->stack ) )
+         vg_kvs_init( &save->kvs, &save->stack );
    }
    else
-      vg_low( "Savefile '%s' did not exist yet. Creating.\n" );
+   {
+      vg_stream stream;
+      VG_ASSERT( vg_file_stream_open( &stream, save_path, VG_STREAM_WRITE ) );
+      vg_stream_write( &stream, in_args->buffer, in_args->buffer_length );
+      vg_file_stream_close( &stream );
+   }
 
-   vg_async_task *complete_task = vg_allocate_async_task( &vg.main_tasks, sizeof(struct savedata_async_info), 1 );
-   struct savedata_async_info *info = (void *)complete_task->data;
-   info->save_handle = info->save
-   vg_async_task_dispatch( load_task, savedata_load );
+   struct savedata_task *out_args = _vg_async_alloc( VG_THREAD_MAIN_ID, sizeof(struct savedata_task) );
+   out_args->savefile_id = in_args->savefile_id;
+   _vg_async_send( out_args, (vg_async_fn)_savedata_complete_task );
 }
 
-u16 _savedata_handle( addon_id addon )
+VG_API u16 _savedata_handle( addon_id addon )
 {
    VG_ASSERT( _vg_thread_has_flags( VG_THREAD_MAIN ) );
 
-   u16 save_handle = _savedata.active.head;
-   while( save_handle )
+   u16 unused_save = 0;
+   for( u16 i=0; i<MAX_SAVE_FILES; i ++ )
    {
-      if( _savedata.files[ vg_pool_index( &_savedata.pool, save_handle ) ].addon_id == addon )
-         return _savedata_handle_fork( save_handle );
-
-      save_handle = vg_pool_next( &_savedata.pool, save_handle, 1 );
+      struct savefile *save = &_savedata.files[i];
+      if( (save->addon_id == addon) && (save->state != k_savefile_not_init) )
+      {
+         save->reference_count ++;
+         return i+1;
+      }
+      else if( save->reference_count == 0 )
+         unused_save = i+1;
    }
 
-   save_handle = _savedata.inactive.tail;
-   if( save_handle )
-   {
-      vg_async_task *load_task = vg_allocate_async_task( &vg.loader_tasks, sizeof(struct savedata_async_info), 1 );
-      struct savedata_async_info *info = (void *)load_task->data;
-      info->save_handle = _savedata_handle_fork( save_handle );
-      vg_async_task_dispatch( load_task, savedata_load );
-      return _savedata_handle_fork( save_handle );
-   }
+   VG_ASSERT( unused_save );
 
-   return 0;
+   struct savefile *save = &_savedata.files[unused_save-1];
+   save->reference_count ++; // for me
+   save->reference_count ++; // for load task
+   save->state = k_savefile_loading;
+   save->addon_id = addon;
+   vg_stack_clear( &save->stack );
+
+   struct savedata_task *out_args = _vg_async_alloc( VG_THREAD_ASYNC_ID, sizeof(struct savedata_task) );
+   out_args->savefile_id = unused_save;
+   out_args->read = 1;
+   _vg_async_send( out_args, (vg_async_fn)_savedata_readwrite_task );
+   return unused_save;
 }
 
-bool _savedata_ready( u16 save_handle )
+VG_API void savedata_release_handle( u16 save_handle )
 {
-   VG_ASSERT( _vg_thread_has_flags( VG_THREAD_MAIN ) );
-   return _savedata.files[ vg_pool_index( &_savedata.pool, save_handle ) ].ready;
+   VG_ASSERT( save_handle );
+   struct savefile *save = &_savedata.files[save_handle-1];
+   VG_ASSERT( save->reference_count );
+   save->reference_count --;
+}
+
+VG_API enum savefile_state _savefile_state( u16 save_handle )
+{
+   VG_ASSERT( save_handle );
+   return _savedata.files[ save_handle-1 ].state;
 }
 
-#endif
+VG_API vg_kvs *_savefile_kvs( u16 save_handle )
+{
+   VG_ASSERT( save_handle );
+   struct savefile *save = &_savedata.files[save_handle-1];
+   VG_ASSERT( save->state == k_savefile_ready );
+   return &save->kvs;
+}
+
+VG_API void _savedata_write( u16 save_handle )
+{
+   VG_ASSERT( save_handle );
+   struct savefile *save = &_savedata.files[save_handle-1];
+   save->reference_count ++;
+
+   struct savedata_task *out_args = _vg_async_alloc( VG_THREAD_ASYNC_ID, sizeof(struct savedata_task) + VG_KB(128) );
+   out_args->savefile_id = save_handle;
+   out_args->read = 0;
+
+   vg_stream stream;
+   vg_buffer_stream_open( &stream, out_args->buffer, VG_KB(128), VG_STREAM_WRITE );
+   vg_kv_write writer;
+   vg_kv_write_init( &writer, &stream );
+   vg_kv_write_tree( &writer, &save->kvs, 0 );
+   out_args->buffer_length = stream.byte_count;
+
+   _vg_async_send( out_args, (vg_async_fn)_savedata_readwrite_task );
+}
index 9fc2689d2eb50f09968bdece59399c6e1c62a8a9..2898b0e72d931363f8fe1e1eb6bcca5339db7ca2 100644 (file)
@@ -2,6 +2,18 @@
 # include "src/save2.c"
 #else
 
+enum savefile_state
+{
+   k_savefile_not_init,
+   k_savefile_loading,
+   k_savefile_ready
+};
+
+VG_API void _savedata_init(void);
 VG_API void _skaterift_autosave_post_update( void );
 
+VG_API u16 _savedata_handle( addon_id addon );
+VG_API enum savefile_state _savefile_state( u16 save_handle );
+VG_API vg_kvs *_savefile_kvs( u16 save_handle );
+
 #endif
index 5baf15916555921c07a9d5321cee6196417eede4..8ff721d3a1a977c93f65cf547066807493e27e8e 100644 (file)
@@ -111,9 +111,8 @@ VG_TIER_0 void scene_builder_push_vert( scene_builder_context *ctx, scene_vert *
    ctx->scene.vertex_count ++;
 }
 
-VG_TIER_0 void scene_builder_get_submesh( scene_builder_context *ctx, mdl_submesh *sm )
+VG_TIER_0 void scene_builder_copy_submesh_indices( scene_builder_context *ctx, mdl_submesh *sm )
 {
-   vg_zero_mem( sm, sizeof(mdl_submesh) );
    sm->indice_start = ctx->current_submesh.indice_start;
    sm->indice_count = ctx->scene.indice_count - sm->indice_start;
    sm->vertex_start = ctx->current_submesh.vertex_start;
@@ -187,8 +186,8 @@ VG_TIER_2 void scene_builder_upload_async( scene_builder_context *ctx, scene_mes
    out_args->scene.vertex_count = ctx->scene.vertex_count;
    out_args->scene.indice_count = ctx->scene.indice_count;
    out_args->out_mesh = out_mesh;
-   memcpy( out_args->scene.vertex_buffer, ctx->scene.vertex_buffer, sizeof(scene_vert) * ctx->scene.vertex_count );
-   memcpy( out_args->scene.indice_buffer, ctx->scene.indice_buffer, sizeof(u32) * ctx->scene.indice_count );
+   memcpy( out_args->scene.vertex_buffer, vg_stack_pointer( &ctx->vertex_stack, 0 ), sizeof(scene_vert) * ctx->scene.vertex_count );
+   memcpy( out_args->scene.indice_buffer, vg_stack_pointer( &ctx->indice_stack, 0 ), sizeof(u32) * ctx->scene.indice_count );
    _vg_async_send( out_args, (vg_async_fn)scene_upload_task );
 }
 
index afe1d9bffdb9973f2ae977ebbe1f0072f15e5a5d..01be4a491b75efada1a4b5709489290fda8ba649 100644 (file)
@@ -51,7 +51,7 @@ VG_TIER_0 void scene_vert_pack_norm( scene_vert *vert, v3f norm, f32 blend );
 VG_TIER_0 void scene_builder_add_model_submesh( scene_builder_context *ctx, vg_model *model, mdl_submesh *sm, m4x3f transform );
 VG_TIER_0 void scene_builder_push_tri( scene_builder_context *ctx, u32 tri[3] );
 VG_TIER_0 void scene_builder_push_vert( scene_builder_context *ctx, scene_vert *v );
-VG_TIER_0 void scene_builder_get_submesh( scene_builder_context *ctx, mdl_submesh *sm );
+VG_TIER_0 void scene_builder_copy_submesh_indices( scene_builder_context *ctx, mdl_submesh *sm );
 VG_TIER_0 void scene_builder_set_vertex_flags( scene_builder_context *ctx, u32 start, u32 count, u16 flags );
 VG_TIER_2 void scene_builder_upload_async( scene_builder_context *ctx, scene_mesh *out_mesh );
 VG_TIER_0 void scene_builder_save_scene( scene_builder_context *ctx, vg_scene *out_scene );
index d1a4cf88ce90cb2f4b473cb9a2eee5d824e1cb95..53c2390497a2b83432b0fc565ad61795e56d641c 100644 (file)
@@ -33,6 +33,9 @@ static i32   k_debug_light_indices   = 0,
 #define WORLD_SURFACE_HAS_TRAFFIC 0x1
 #define WORLD_SURFACE_HAS_PROPS   0x2
 
+/* TODO: Break this down into main/preview world structures. So that world instances no longer exist finally,
+ *       and _world referes to the actual loaded world, not possibly anything else. */
+
 struct world_instance 
 {
    bool complete;
@@ -162,6 +165,8 @@ struct world_static
     */
    vg_stack_allocator stack, preview_stack;
 
+   u16 save_handle;
+
    u32 current_run_version;
    f64 last_gate_hit_time;
 
index b20b7e1a74c9572c22cc51f1aba0252564b9ec74..45a69e2856531963b7cc70844d2dd9551c2636cb 100644 (file)
@@ -172,7 +172,7 @@ static void world_unpack_submesh_dynamic( world_instance *world, scene_builder_c
    m4x3f identity;
    m4x3_identity( identity );
    scene_builder_add_model_submesh( builder, &world->meta, sm, identity );
-   scene_builder_get_submesh( builder, sm );
+   scene_builder_copy_submesh_indices( builder, sm );
    sm->flags |= k_submesh_flag_consumed;
 }
 
@@ -204,7 +204,7 @@ void world_gen_generate_meshes( world_instance *world )
       if( surf->info.flags & k_material_flag_collision )
          world_add_all_if_material( midentity, &geo_ctx, &world->meta, i );
 
-      scene_builder_get_submesh( &geo_ctx, &surf->sm_geo );
+      scene_builder_copy_submesh_indices( &geo_ctx, &surf->sm_geo );
       scene_builder_set_vertex_flags( &geo_ctx,
                                       surf->sm_geo.vertex_start,
                                       surf->sm_geo.vertex_count, 
@@ -240,7 +240,7 @@ void world_gen_generate_meshes( world_instance *world )
       if( !_world.loader_preview_mode )
          if( surf->info.flags & k_material_flag_grow_grass )
             world_apply_procedural_foliage( world, &trans_ctx, surf );
-      scene_builder_get_submesh( &trans_ctx, &surf->sm_no_collide );
+      scene_builder_copy_submesh_indices( &trans_ctx, &surf->sm_no_collide );
    }
 
    if( _world.loader_preview_mode )
@@ -675,11 +675,8 @@ void world_gen_load_surfaces( world_instance *world )
 
    world->surface_count = world->meta.material_count+1;
    world->surfaces = vg_stack_allocate( world->stack, sizeof(struct world_surface)*world->surface_count, 8, "Surfaces" );
+   vg_zero_mem( world->surfaces, sizeof(struct world_surface)*world->surface_count );
 
-   /* error material */
-   struct world_surface *errmat = &world->surfaces[0];
-   memset( errmat, 0, sizeof(struct world_surface) );
-                       
    for( u32 i=0; i<world->meta.material_count; i++ )
    {
       struct world_surface *surf = &world->surfaces[i+1];
index 5abdace3a79feca57706ca86319f79bf02c5b86a..0a0b4cf8c1be8dfd5003c12dcb5a3e2573d1c925 100644 (file)
@@ -3,7 +3,7 @@
  */
 static void world_instance_load_mdl( world_instance *world, const char *path, vg_stack_allocator *stack )
 {
-   _vg_loader_set_user_information( "Loading world data" );
+   //_vg_loader_set_user_information( "Loading world data" );
    world_init_blank( world );
    world->stack = stack;
    
@@ -130,7 +130,7 @@ static void world_instance_load_mdl( world_instance *world, const char *path, vg
    }
    _vg_end_temp_frame( temp_frame );
 
-   _vg_loader_set_user_information( "Compiling world details" );
+   //_vg_loader_set_user_information( "Compiling world details" );
    time_t seconds = time(NULL) % ((u32)vg_maxf(1.0f,k_day_length)*60);
    world->time  = ((f64)(seconds)/(k_day_length*60.0));
    world->time += (world->info.timezone/24.0);
@@ -199,7 +199,7 @@ static void world_instance_load_mdl( world_instance *world, const char *path, vg
       world->routes_ui = vg_stack_allocate( stack, sizeof(struct route_ui)*af_arrcount(&world->ent_route), 8, "Route UI buffer" );
       ent_script_alloc( world, stack );
 
-      _vg_loader_set_user_information( "Postprocessing world" );
+      //_vg_loader_set_user_information( "Postprocessing world" );
       _vg_async_send( _vg_async_alloc( VG_THREAD_MAIN_ID, 0 ), (vg_async_fn)async_world_postprocess );
    }
 }
@@ -216,8 +216,6 @@ void skaterift_world_load_t1( struct world_load_info *in_args, vg_async_info *as
    if( !in_args->OK )
       return;
 
-   _vg_loader_set_user_information( "Scanning world directory" );
-
    addon_reg *reg = addon_details( _world.load_addon );
    _world.loader_instance->addon_id = _world.load_addon;
 
@@ -307,78 +305,6 @@ void skaterift_world_load_t1( struct world_load_info *in_args, vg_async_info *as
    _vg_async_send( _vg_async_alloc( VG_THREAD_MAIN_ID, 0 ), (vg_async_fn)async_world_loader_done );
 }
 
-struct world_savedata_info
-{
-   //savedata_file save;
-   world_instance *instance;
-};
-
-void async_worldsave_go( struct world_savedata_info *in_args, vg_async_info *async )
-{
-   VG_ASSERT( _vg_thread_has_flags( VG_THREAD_MAIN ) );
-   VG_ASSERT( 0 );
-
-   // FIXME FIXME FIXME
-   
-#if 0
-   struct world_savedata_info *info = (void *)task->data;
-
-   /* start entities in the world */
-   world_entity_start( info->instance, &info->save.kvs );
-
-   /* start player in the world */
-   if( _world.travelled_through_nonlocal_gate )
-   {
-      player__transport( _world.copy_of_nonlocal_sender.transport );
-      _world.travelled_through_nonlocal_gate = 0;
-      vg_success( "Successfuly consumed linked non-local gates composite transport matrix.\n" );
-   }
-   else
-   {
-      bool restored_player_position = 0;
-      
-      u32 player_block = vg_kv_find( &info->save.kvs, 0, "player" );
-      if( player_block )
-      {
-         if( vg_kv_read_vf32( &info->save.kvs, player_block, "co", NULL, localplayer.rb.co, 3 ) )
-            restored_player_position = 1;
-      }
-
-      if( !restored_player_position )
-         world_default_spawn_pos( info->instance, localplayer.rb.co );
-
-      player__reset();
-   }
-
-   network_send_item( k_netmsg_playeritem_world0 );
-   _world.loader_state = k_world_loader_done;
-   _world.load_addon = 0;
-   menu_on_world_change( _world.main.addon_id );
-   relink_all_remote_player_worlds();
-
-   vg_audio_lock();
-   vg_audio_oneshot( &audio_ui[2], 1.0f, 0.0f, 0, 0 );
-   vg_audio_unlock();
-#endif
-}
-
-void load_world_savedata_t1( void *_, vg_async_info *async )
-{
-   VG_ASSERT( _vg_thread_has_flags( VG_THREAD_BACKGROUND ) );
-   VG_ASSERT( 0 );
-   // FIXME FIXME
-#if 0
-   vg_async_task *task = vg_allocate_async_task( &vg.main_tasks, sizeof(struct world_savedata_info), 1 );
-   struct world_savedata_info *info = (void *)task->data;
-
-   info->instance = _world.loader_instance;
-
-   addon_make_savedata_path( _world.load_addon, info->save.path );
-   savedata_file_read( &info->save );
-   vg_async_task_dispatch( task, async_worldsave_go );
-#endif
-}
-
 void world_switcher_update(void)
 {
    if( !_world.load_addon )
@@ -413,6 +339,7 @@ void world_switcher_update(void)
 
    if( _world.loader_state == k_world_loader_ready )
    {
+      _vg_loader_set_user_information( "Loading world..." );
       _world.loader_state = k_world_loader_loading;
       vg_stack_clear( _world.loader_stack );
       
@@ -433,7 +360,52 @@ void world_switcher_update(void)
       else
       {
          _world.loader_state = k_world_loader_load_savedata;
-         _vg_async_send( _vg_async_alloc( VG_THREAD_ASYNC_ID, 0 ), (vg_async_fn)load_world_savedata_t1 );
+         _vg_loader_set_user_information( "Loading world savedata..." );
+         _world.save_handle = _savedata_handle( _world.load_addon );
+      }
+   }
+
+   if( _world.loader_state == k_world_loader_load_savedata )
+   {
+      if( _savefile_state( _world.save_handle ) == k_savefile_ready )
+      {
+         _world.loader_state = k_world_loader_done;
+
+         vg_kvs *kvs = _savefile_kvs( _world.save_handle );
+         world_entity_start( &_world.main, kvs );
+
+         /* start player in the world */
+         if( _world.travelled_through_nonlocal_gate )
+         {
+            player__transport( _world.copy_of_nonlocal_sender.transport );
+            _world.travelled_through_nonlocal_gate = 0;
+            vg_success( "Successfuly consumed linked non-local gates composite transport matrix.\n" );
+         }
+         else
+         {
+            bool restored_player_position = 0;
+            
+            u32 player_block = vg_kv_find( kvs, 0, "player" );
+            if( player_block )
+            {
+               if( vg_kv_read_vf32( kvs, player_block, "co", NULL, localplayer.rb.co, 3 ) )
+                  restored_player_position = 1;
+            }
+
+            if( !restored_player_position )
+               world_default_spawn_pos( &_world.main, localplayer.rb.co );
+
+            player__reset();
+         }
+
+         network_send_item( k_netmsg_playeritem_world0 );
+         menu_on_world_change( _world.main.addon_id );
+         relink_all_remote_player_worlds();
+
+         vg_audio_lock();
+         vg_audio_oneshot( &audio_ui[2], 1.0f, 0.0f, 0, 0 );
+         vg_audio_unlock();
+         _vg_loader_increment( -1 );
       }
    }
 }
index 79972f878b6103b824c7ed46c4f5cd14585e9f4e..74f3a2650b4a5ee556eb46781909aa7ea948b388 100644 (file)
@@ -487,12 +487,9 @@ static void world_routes_gen_meshes( world_instance *world, u32 route_id, scene_
       }
    }
 
-   scene_builder_get_submesh( builder, &route->sm );
+   scene_builder_copy_submesh_indices( builder, &route->sm );
 }
 
-struct world_surface *world_tri_index_surface( world_instance *world, 
-                                                 u32 index );
-
 /* 
  * Create the strips of colour that run through the world along course paths
  */
index 4f1b01e135938c2cd11b3e7db36e1e6ab000d4a1..232c5a3013b4958899db16ac4a5d72dac776f28c 100644 (file)
@@ -1,6 +1,7 @@
 struct world_sfd world_sfd;
 
-static f32 sfd_encode_glyph( char c ){
+static f32 sfd_encode_glyph( char c )
+{
    int value = 0;
    if( c >= 'a' && c <= 'z' )
       value = c-'a'+11;
@@ -33,9 +34,11 @@ static f32 sfd_encode_glyph( char c ){
    return (float)value;
 }
 
-static void sfd_clear( u32 row ){
+static void sfd_clear( u32 row )
+{
    u32 row_h = world_sfd.h -1 -row;
-   for( int i=0; i<world_sfd.w; i++ ){
+   for( int i=0; i<world_sfd.w; i++ )
+   {
       u32 idx = (world_sfd.w*row_h + i) * 2;
       world_sfd.buffer[idx] = 0.0f;
    }
@@ -74,6 +77,7 @@ void sfd_encode( v2i co, const char *str, enum world_sfd_align align )
 
 void world_sfd_compile_active_scores(void)
 {
+#if 0
    world_instance *world = &_world.main;
    
    struct leaderboard_cache *board = NULL;
@@ -188,10 +192,12 @@ void world_sfd_compile_active_scores(void)
       sfd_encode( (v2i){-1,4}, "No records", k_world_sfd_center );
    }
 #endif
+#endif
 }
 
 void world_sfd_update( world_instance *world, v3f pos )
 {
+#if 0
    if( af_arrcount( &world->ent_route ) )
    {
       u32 closest = 0;
@@ -251,6 +257,7 @@ void world_sfd_update( world_instance *world, v3f pos )
       else
          *cur = *target;
    }
+#endif
 }
 
 void bind_terrain_noise(void);
@@ -358,6 +365,7 @@ static void _world_sfd_load_content( void *_, vg_async_info *async )
 
 VG_API void _world_sfd_init(void)
 {
+#if 0
    VG_ASSERT( _vg_thread_has_flags( VG_THREAD_MAIN ) );
    _vg_async_send( _vg_async_alloc( VG_THREAD_ASYNC_ID, 0 ), (vg_async_fn)_world_sfd_load_content );
 
@@ -370,4 +378,5 @@ VG_API void _world_sfd_init(void)
 
    for( i32 i=0; i<w*h*2; i++ )
       world_sfd.buffer[i] = 0.0f;
+#endif
 }