semantics and world reloading
[carveJwlIkooP6JGAAIwe30JlM.git] / world.h
diff --git a/world.h b/world.h
index 7084ff17334e7b9195abfc2ff584576bccefcbc1..66b3b28f2c0b14a961cf7ea04ef4b27321332cc7 100644 (file)
--- a/world.h
+++ b/world.h
@@ -56,16 +56,17 @@ enum geo_type
 static const float k_light_cube_size = 8.0f;
 
 struct world_instance {
+
    /* Fixed items
     * -------------------------------------------------------
     */
 
    void *heap;
-   char  world_name[ 64 ];
    enum world_status{
       k_world_status_unloaded = 0,
       k_world_status_loading = 1,
-      k_world_status_loaded = 2
+      k_world_status_loaded = 2,
+      k_world_status_unloading = 3  /* dont spawn sounds and stuff */
    }
    status;
 
@@ -79,6 +80,8 @@ struct world_instance {
    }
    water;
 
+   f64 time;
+
    /* STD140 */
    struct ub_world_lighting{
       v4f g_cube_min,
@@ -124,7 +127,6 @@ struct world_instance {
    float probabilities[3];
 
    v3i light_cubes;
-
    struct framebuffer heightmap;
 
    /*
@@ -153,6 +155,7 @@ struct world_instance {
    * surfaces;
    u32 surface_count;
 
+   ent_worldinfo info;
    mdl_array_ptr ent_spawn,
                  ent_gate,
                  ent_light,
@@ -165,7 +168,11 @@ struct world_instance {
                  ent_audio_clip,
                  ent_audio,
                  ent_volume,
-                 ent_traffic;
+                 ent_traffic,
+                 ent_skateshop,
+                 ent_marker,
+                 ent_camera,
+                 ent_swspreview;
 
    ent_gate *rendering_gate;
 
@@ -198,6 +205,7 @@ struct world_global{
     * --------------------------------------------------------------------------
     */
    void *heap;
+   char *load_target;
 
    /* rendering */
    glmesh skydome;
@@ -231,10 +239,7 @@ struct world_global{
    v3f render_gate_pos;
    int in_volume;
 
-   int switching_to_new_world;
-
    world_instance worlds[4];
-   u32            world_count;
    u32            active_world;
 
    /* text particles */
@@ -261,6 +266,7 @@ struct world_global{
    u32 text_particle_count;
 }
 static world_global;
+VG_STATIC void entity_call( world_instance *world, ent_call *call );
 
 VG_STATIC world_instance *get_active_world( void )
 {
@@ -405,42 +411,42 @@ VG_STATIC void world_init(void)
                                                    VG_MEMORY_SYSTEM );
 }
 
-typedef struct ent_call ent_call;
-struct ent_call{
-   ent_index ent;
-   u32 function;
-   void *data;
-};
-
-VG_STATIC void entity_call( world_instance *world, ent_call *call );
-
 VG_STATIC void ent_volume_call( world_instance *world, ent_call *call )
 {
-   ent_volume *volume = mdl_arritm( &world->ent_volume, call->ent.index );
-   if( !volume->target.type ) return;
+   u32 index = mdl_entity_id_id( call->id );
+   ent_volume *volume = mdl_arritm( &world->ent_volume, index );
+   if( !volume->target ) return;
 
    if( call->function == k_ent_function_trigger ){
-      call->ent = volume->target;
+      call->id = volume->target;
 
       if( volume->type == k_volume_subtype_particle ){
          float *co = alloca( sizeof(float)*3 );
-         co[0] = vg_randf()*2.0f-1.0f;
-         co[1] = vg_randf()*2.0f-1.0f;
-         co[2] = vg_randf()*2.0f-1.0f;
+         co[0] = vg_randf64()*2.0f-1.0f;
+         co[1] = vg_randf64()*2.0f-1.0f;
+         co[2] = vg_randf64()*2.0f-1.0f;
          m4x3_mulv( volume->to_world, co, co );
 
          call->function = k_ent_function_particle_spawn;
          call->data = co;
          entity_call( world, call );
       }
-      else
+      else{
          entity_call( world, call );
+      }
    }
 }
 
 VG_STATIC void ent_audio_call( world_instance *world, ent_call *call )
 {
-   ent_audio *audio = mdl_arritm( &world->ent_audio, call->ent.index );
+   if( world->status == k_world_status_unloading ){
+      vg_warn( "cannot modify audio while unloading world\n" );
+      return;
+   }
+
+   u8 world_id = (world - world_global.worlds) + 1;
+   u32 index = mdl_entity_id_id( call->id );
+   ent_audio *audio = mdl_arritm( &world->ent_audio, index );
 
    v3f sound_co;
 
@@ -453,7 +459,7 @@ VG_STATIC void ent_audio_call( world_instance *world, ent_call *call )
    else
       vg_fatal_error( "ent_audio_call (invalid function id)" );
 
-   float chance = vg_randf()*100.0f,
+   float chance = vg_randf64()*100.0f,
          bar = 0.0f;
 
    for( u32 i=0; i<audio->clip_count; i++ ){
@@ -466,7 +472,6 @@ VG_STATIC void ent_audio_call( world_instance *world, ent_call *call )
       bar += p;
 
       if( chance < bar ){
-
          audio_lock();
 
          if( audio->behaviour == k_channel_behaviour_unlimited ){
@@ -482,6 +487,7 @@ VG_STATIC void ent_audio_call( world_instance *world, ent_call *call )
             if( ch ){
                audio_channel_init( ch, &clip->clip, audio->flags );
                audio_channel_group( ch, audio->group );
+               audio_channel_world( ch, world_id );
                audio_channel_set_spacial( ch, sound_co, audio->transform.s[0] );
                audio_channel_edit_volume( ch, audio->volume, 1 );
                ch = audio_relinquish_channel( ch );
@@ -513,6 +519,7 @@ VG_STATIC void ent_audio_call( world_instance *world, ent_call *call )
             if( ch ){
                audio_channel_init( ch, &clip->clip, audio->flags );
                audio_channel_group( ch, audio->group );
+               audio_channel_world( ch, world_id );
                audio_channel_fadein( ch, audio->crossfade );
                ch = audio_relinquish_channel( ch );
             }
@@ -524,13 +531,26 @@ VG_STATIC void ent_audio_call( world_instance *world, ent_call *call )
    }
 }
 
-VG_STATIC void entity_call( world_instance *world, ent_call *call )
+/* finds any active playing in world and fades them out, we can only do this 
+ * while unloading */
+VG_STATIC void world_fadeout_audio( world_instance *world )
 {
-   if( call->ent.type == k_ent_volume ){
-      ent_volume_call( world, call );
-   } else if( call->ent.type == k_ent_audio ){
-      ent_audio_call( world, call );
+   if( world->status != k_world_status_unloading ){
+      vg_fatal_error( "World status must be set to 'unloading', to fadeout"
+                      " audio.\n" );
+   }
+
+   u8 world_id = (world - world_global.worlds) + 1;
+
+   audio_lock();
+   for( u32 i=0; i<AUDIO_CHANNELS; i++ ){
+      audio_channel *ch = &vg_audio.channels[i];
+
+      if( ch->allocated && (ch->world_id == world_id) ){
+         ch = audio_channel_fadeout( ch, 1.0f );
+      }
    }
+   audio_unlock();
 }
 
 VG_STATIC void world_update( world_instance *world, v3f pos )
@@ -684,9 +704,8 @@ VG_STATIC void world_update( world_instance *world, v3f pos )
 
             if( !world_global.in_volume ){
                ent_call basecall;
-               basecall.ent.index = idx;
-               basecall.ent.type = k_ent_volume;
                basecall.function = k_ent_function_trigger;
+               basecall.id = mdl_entity_id( k_ent_volume, idx );
                basecall.data = NULL;
 
                entity_call( world, &basecall );
@@ -700,9 +719,7 @@ VG_STATIC void world_update( world_instance *world, v3f pos )
 
          for( int j=0; j<random_ticks; j++ ){
             ent_call basecall;
-            basecall.ent.index = idx;
-            basecall.ent.type = k_ent_volume;
-            basecall.function = k_ent_function_trigger;
+            basecall.id = mdl_entity_id( k_ent_volume, idx );
             basecall.data = NULL;
 
             entity_call( world, &basecall );
@@ -851,7 +868,7 @@ VG_STATIC struct world_surface *ray_hit_surface( world_instance *world,
  */
 
 VG_STATIC 
-enum audio_sprite_type world_audio_sample_sprite_random(v3f origin, v3f output);
+enum audio_sprite_type world_audio_sample_sprite_kandom(v3f origin, v3f output);
 VG_STATIC void world_audio_sample_distances( v3f co, int *index, float *value );
 
 #include "audio.h"
@@ -862,9 +879,9 @@ VG_STATIC void world_audio_sample_distances( v3f co, int *index, float *value );
 VG_STATIC 
 enum audio_sprite_type world_audio_sample_sprite_random(v3f origin, v3f output)
 {
-   v3f chance = { (vg_randf()-0.5f) * 30.0f, 
+   v3f chance = { (vg_randf64()-0.5f) * 30.0f, 
                   8.0f,
-                  (vg_randf()-0.5f) * 30.0f };
+                  (vg_randf64()-0.5f) * 30.0f };
    
    v3f pos;
    v3_add( chance, origin, pos );