model fmt & heisenbug
[carveJwlIkooP6JGAAIwe30JlM.git] / world.h
diff --git a/world.h b/world.h
index 8b1b1dc079ff159e06e6197837f0637e4a6a1e46..7b265cd96d1513ea47452fbacd91841d64fe91a8 100644 (file)
--- a/world.h
+++ b/world.h
@@ -94,8 +94,6 @@ VG_STATIC struct gworld
       u32  indices_head;
       u32  vertex_head;
 
-      float last_notch;
-
       struct route_ui_segment
       {
          float length;
@@ -113,6 +111,12 @@ VG_STATIC struct gworld
    v3f render_gate_pos;
    int active_route_board;
 
+   /* This is a small flag we use to changelevel.
+    * It will not be cleared until all sounds stop playing 
+    */
+   int   switching_to_new_world;
+   char  world_name[ 64 ];
+
    /*
     * Dynamically allocated when world_load is called.
     *
@@ -286,23 +290,12 @@ VG_STATIC struct gworld
 
    rigidbody rb_geo;
 
-   /* TODO Maybe make this less hardcoded */
+   /* TODO Maybe make this less hardcoded...
+    *      im on it, boss*/
    mdl_submesh sm_geo_std_oob,   sm_geo_std, sm_geo_vb,
                sm_foliage_main,  sm_foliage_alphatest,
                sm_graffiti, sm_subworld, sm_terrain;
 
-   /*
-    * Allocated AFTER all previous buffers are done
-    * --------------------------------------------------------------------------
-    */
-
-   struct instance_cache
-   {
-      mdl_context *mdl;
-      u32 pstr_file;
-   }
-   instance_cache[32];
-   u32 instance_cache_count;
 }
 world;
 
@@ -333,6 +326,47 @@ VG_STATIC int ray_world( v3f pos, v3f dir, ray_hit *hit );
  * -----------------------------------------------------------------------------
  */
 
+VG_STATIC int world_stop_sound( int argc, const char *argv[] )
+{
+   /* 
+    * None of our world audio runs as one shots, they always have a player.
+    * Therefore it is safe to delete clip data after the players are
+    * disconnected
+    */
+   audio_lock();
+   for( int i=0; i<world.audio_things_count; i++ )
+   {
+      struct world_audio_thing *at = &world.audio_things[i];
+
+      if( audio_player_is_playing( &at->player ) )
+      {
+         u32 cflags = audio_player_get_flags( &at->player );
+         audio_player_set_flags( &at->player, cflags | AUDIO_FLAG_KILL );
+      }
+   }
+   audio_unlock();
+
+   return 0;
+}
+
+VG_STATIC int world_change_world( int argc, const char *argv[] )
+{
+   if( argc == 0 )
+   {
+      vg_info( "%s\n", world.world_name );
+      return 0;
+   }
+   else
+   {
+      vg_info( "Switching world...\n" );
+      strcpy( world.world_name, argv[0] );
+      world.switching_to_new_world = 1;
+      world_stop_sound( 0, NULL );
+   }
+
+   return 0;
+}
+
 VG_STATIC void world_init(void)
 {
    vg_convar_push( (struct vg_convar){
@@ -343,6 +377,18 @@ VG_STATIC void world_init(void)
       .persistent = 0
    });
 
+       vg_function_push( (struct vg_cmd)
+   {
+               .name = "world_stop_sound",
+               .function = world_stop_sound
+       });
+
+       vg_function_push( (struct vg_cmd)
+   {
+               .name = "world",
+               .function = world_change_world
+       });
+
    world.sky_rate = 1.0;
    world.sky_target_rate = 1.0;
 
@@ -381,11 +427,38 @@ VG_STATIC void world_init(void)
 
    /* Allocate dynamic world memory arena */
    u32 max_size = 72*1024*1024;
-   world.dynamic_vgl = vg_create_linear_allocator( vg_mem.rtmemory, max_size );
+   world.dynamic_vgl = vg_create_linear_allocator( vg_mem.rtmemory, max_size,
+                                                   VG_MEMORY_SYSTEM );
 }
 
 VG_STATIC void world_update( v3f pos )
 {
+   if( world.switching_to_new_world )
+   {
+      int all_stopped = 1;
+
+      audio_lock();
+      for( int i=0; i<world.audio_things_count; i++ )
+      {
+         struct world_audio_thing *at = &world.audio_things[i];
+
+         if( audio_player_is_playing( &at->player ) )
+         {
+            all_stopped = 0;
+            break;
+         }
+      }
+      audio_unlock();
+
+      if( all_stopped )
+      {
+         world.switching_to_new_world = 0;
+         world_unload();
+         world_load();
+      }
+   }
+
+
    world.sky_time += world.sky_rate * vg.time_delta;
    world.sky_rate = vg_lerp( world.sky_rate, world.sky_target_rate, 
                                  vg.time_delta * 5.0 );