}
}
-#if 0
VG_STATIC void world_free( world_instance *world )
{
- vg_acquire_thread_sync();
+ vg_info( "Free world @%p\n", world );
/* free meshes */
mesh_free( &world->mesh_route_lines );
mesh_free( &world->mesh_geo );
mesh_free( &world->mesh_no_collide );
+ mesh_free( &world->mesh_water );
/* glDeleteBuffers silently ignores 0's and names that do not correspond to
* existing buffer objects.
/* delete textures and meshes */
glDeleteTextures( world->texture_count, world->textures );
- vg_release_thread_sync();
+ u32 world_index = world - world_global.worlds;
+ if( world_index ){
+ vg_linear_del( world_global.worlds[world_index-1].heap,
+ vg_linear_header(world->heap) );
+ }
world->status = k_world_status_unloaded;
}
-#endif
+
+/*
+ * checks:
+ * 1. to see if all audios owned by the world have been stopped
+ * 2. that this is the least significant world
+ */
+VG_STATIC int world_freeable( world_instance *world )
+{
+ if( world->status != k_world_status_unloading ) return 0;
+ u8 world_id = (world - world_global.worlds) + 1;
+
+ for( u32 i=world_id; i<vg_list_size(world_global.worlds); i++ ){
+ if( world_global.worlds[i].status != k_world_status_unloaded ){
+ return 0;
+ }
+ }
+
+ int freeable = 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)){
+ if( !audio_channel_finished( ch ) ){
+ freeable = 0;
+ break;
+ }
+ }
+ }
+ audio_unlock();
+ return freeable;
+}
VG_STATIC void world_init_blank( world_instance *world )
{
v3_copy( (v3f){1.10f, 0.89f, 0.35f}, state->g_sun_colour );
}
-VG_STATIC void world_entities_init( u32 world_id )
+/* detatches any nonlocal gates */
+VG_STATIC void world_unlink_nonlocal( world_instance *world )
{
- world_instance *world = &world_global.worlds[world_id];
-
- /* lights */
- for( u32 j=0; j<mdl_arrcount(&world->ent_light); j ++ ){
- ent_light *light = mdl_arritm( &world->ent_light, j );
-
- m4x3f to_world;
- q_m3x3( light->transform.q, to_world );
- v3_copy( light->transform.co, to_world[3] );
- m4x3_invert_affine( to_world, light->inverse_world );
+ for( u32 j=0; j<mdl_arrcount(&world->ent_gate); j ++ ){
+ ent_gate *gate = mdl_arritm( &world->ent_gate, j );
- light->angle_sin_cos[0] = sinf( light->angle * 0.5f );
- light->angle_sin_cos[1] = cosf( light->angle * 0.5f );
+ if( gate->type == k_gate_type_nonlocel ){
+ gate->type = k_gate_type_nonlocal_unlinked;
+ }
}
+}
+
+/* attatches nonlocal gates, to be called from main thread ONLY! */
+VG_STATIC void world_link_nonlocal_async( void *payload, u32 size )
+{
+ world_instance *world = payload;
+ u32 world_id = world - world_global.worlds;
- /* gates */
for( u32 j=0; j<mdl_arrcount(&world->ent_gate); j ++ ){
ent_gate *gate = mdl_arritm( &world->ent_gate, j );
- if( gate->type == k_gate_type_teleport ){
- gate_transform_update( gate );
- }
- else if( gate->type == k_gate_type_nonlocal_unlinked ){
- const char *key = mdl_pstr( &world->meta, gate->target );
+ if( gate->type == k_gate_type_nonlocal_unlinked ){
+ const char *key = mdl_pstr( &world->meta, gate->key );
vg_info( "key: %s\n", key );
for( u32 i=0; i<vg_list_size(world_global.worlds); i++ ){
ent_gate *gate2 = mdl_arritm( &other->ent_gate, j );
if( gate2->type != k_gate_type_nonlocal_unlinked ) continue;
- const char *key2 = mdl_pstr( &other->meta, gate2->target );
+ const char *key2 = mdl_pstr( &other->meta, gate2->key );
vg_info( " key2: %s\n", key2 );
if( strcmp( key, key2 ) ) continue;
matched:;
}
}
+}
+
+VG_STATIC void world_entities_init( u32 world_id )
+{
+ world_instance *world = &world_global.worlds[world_id];
+
+ /* lights */
+ for( u32 j=0; j<mdl_arrcount(&world->ent_light); j ++ ){
+ ent_light *light = mdl_arritm( &world->ent_light, j );
+
+ m4x3f to_world;
+ q_m3x3( light->transform.q, to_world );
+ v3_copy( light->transform.co, to_world[3] );
+ m4x3_invert_affine( to_world, light->inverse_world );
+
+ light->angle_sin_cos[0] = sinf( light->angle * 0.5f );
+ light->angle_sin_cos[1] = cosf( light->angle * 0.5f );
+ }
+
+ /* gates */
+ for( u32 j=0; j<mdl_arrcount(&world->ent_gate); j ++ ){
+ ent_gate *gate = mdl_arritm( &world->ent_gate, j );
+
+ if( gate->type == k_gate_type_teleport ){
+ gate_transform_update( gate );
+ }
+ }
+ vg_async_call( world_link_nonlocal_async, world, 0 );
/* water */
for( u32 j=0; j<mdl_arrcount(&world->ent_water); j++ ){
}
u32 size = heap_availible - min_overhead;
- void *heap = vg_create_linear_allocator( allocator, size,
- VG_MEMORY_SYSTEM );
+ void *heap = vg_create_linear_allocator( allocator, size, VG_MEMORY_SYSTEM );
world->heap = heap;
mdl_context *meta = &world->meta;
world_post_process( world );
mdl_close( meta );
-
world->status = k_world_status_loaded;
}