VG_STATIC void audio_ambient_sprite_play( v3f co, audio_clip *clip )
{
audio_lock();
- u32 channel_id = 31342352;
- audio_channel *ch = audio_get_group_idle_channel( channel_id, 4 );
+ u16 group_id = 0xfff0;
+ audio_channel *ch = audio_get_group_idle_channel( group_id, 4 );
if( ch ){
audio_channel_init( ch, clip, AUDIO_FLAG_SPACIAL_3D );
- audio_channel_group( ch, channel_id );
+ audio_channel_group( ch, group_id );
audio_channel_set_spacial( ch, co, 80.0f );
audio_channel_edit_volume( ch, 1.0f, 1 );
ch = audio_relinquish_channel( ch );
#{
_fields_ = [("type",c_uint32),
("target", c_uint32),
+ ("key",c_uint32),
("dimensions", c_float*3),
("co", (c_float*3)*2),
("q", (c_float*4)*2),
#}
#}
elif obj_data.tipo == 'nonlocal':#{
- gate.target = sr_compile_string(obj_data.key)
+ gate.target = 0
+ gate.key = sr_compile_string(obj_data.key)
gate.type = 2
#}
else: gate.type = 0
/* generic reciever */
VG_STATIC void workshop_async_any_complete( void *data, u32 size )
{
- workshop_end_op();
+ skaterift_end_op();
}
/*
*/
VG_STATIC void workshop_op_item_scan(void)
{
- workshop_begin_op( k_workshop_op_item_scan );
+ skaterift_begin_op( k_workshop_op_item_scan );
vg_loader_start( workshop_scan_thread, NULL );
}
vg_info( "skateshop_call\n" );
if( menu.active ) return;
+ if( skaterift.async_op != k_async_op_none ) return;
if( call->function == k_ent_function_trigger ){
if( localplayer.subsystem != k_player_subsystem_walk ){
struct ent_gate{
u32 type,
- target;
+ target,
+ key;
v3f dimensions,
co[2];
#define SR_NETWORKED
#define VG_DEVWINDOW
+
#include "common.h"
#include "conf.h"
#include "steam.h"
#include "entity.c"
#include "workshop.c"
-VG_STATIC struct player_avatar localplayer_avatar;
-VG_STATIC struct player_model localplayer_models[3];
-VG_STATIC int skaterift_status = 0;
-
#include "network.h"
#include "menu.h"
#include "vehicle.h"
+static struct player_avatar localplayer_avatar;
+static struct player_model localplayer_models[3];
+
+
int main( int argc, char *argv[] )
{
vg_mem.use_libc_malloc = 0;
player_model_load( &localplayer_models[0], "models/ch_new.mdl" );
player_model_load( &localplayer_models[1], "models/ch_outlaw.mdl" );
player_model_load( &localplayer_models[2], "models/ch_jordan.mdl" );
-
- /* load default board */
-#if 0
- player_board_load( &localplayer_boards[0],
- "models/boards/skaterift_fish.mdl" );
-#endif
/* FIXME: hack */
shader_model_character_view_register();
VG_STATIC void async_skaterift_complete( void *payload, u32 size )
{
- skaterift_status = 1;
-
localplayer.viewable_world = get_active_world();
localplayer_cmd_respawn( 1, (const char *[]){ "start" } );
+
+ skaterift_end_op();
}
VG_STATIC void vg_load(void)
{
+ vg_console_reg_cmd( "changeworld", skaterift_change_world_command, NULL );
+
vg_loader_step( render_init, NULL );
vg_loader_step( menu_init, NULL );
vg_loader_step( world_init, NULL );
player_avatar_load( &localplayer_avatar, "models/ch_new.mdl" );
player__use_avatar( &localplayer, &localplayer_avatar );
player__use_model( &localplayer, &localplayer_models[cl_playermdl_id] );
- //localplayer.board = &localplayer_boards[0];
player__bind( &localplayer );
/* --------------------- */
vg_loader_step( audio_init, audio_free );
/* 'systems' are completely loaded now */
- /* load home world */
-
+ /* load home/permanent world */
world_load( 0, "maps/mp_spawn.mdl" );
- world_load( 1, "maps/mp_mtzero.mdl" );
vg_console_load_autos();
menu_link();
vg_line( (v3f){ 0.0f, 0.0f, 0.0f }, (v3f){ 0.0f, 0.0f, 1.0f }, 0xff0000ff );
}
+static void skaterift_change_world_preupdate(void);
VG_STATIC void vg_update(void)
{
steam_update();
-
skaterift_preupdate_inputs();
+ if( skaterift.async_op == k_async_op_clientloading ) return;
+ if( skaterift.async_op == k_async_op_world_preloading ){
+ skaterift_change_world_preupdate();
+ }
- if( skaterift_status == 1 ){
- draw_origin_axis();
- network_update();
-
- player__pre_update( &localplayer );
- global_skateshop_preupdate();
+ draw_origin_axis();
+ network_update();
+
+ player__pre_update( &localplayer );
+ global_skateshop_preupdate();
- world_update( get_active_world(), localplayer.rb.co );
- audio_ambient_sprites_update( get_active_world(), localplayer.rb.co );
- //gui_helper_action( localplayer.input_use, "\x7f Hello \x1f""A \x1e\x84" );
- }
+ world_update( get_active_world(), localplayer.rb.co );
+ audio_ambient_sprites_update( get_active_world(), localplayer.rb.co );
+ //gui_helper_action( localplayer.input_use, "\x7f Hello \x1f""A \x1e\x84" );
}
VG_STATIC void vg_update_fixed(void)
{
- if( skaterift_status == 1 ){
- world_routes_fixedupdate( get_active_world() );
+ if( skaterift.async_op == k_async_op_clientloading ) return;
- player__update( &localplayer );
- vehicle_update_fixed();
- }
+ world_routes_fixedupdate( get_active_world() );
+ player__update( &localplayer );
+ vehicle_update_fixed();
}
VG_STATIC void vg_update_post(void)
{
- if( skaterift_status == 1 ){
- player__post_update( &localplayer );
+ if( skaterift.async_op == k_async_op_clientloading ) return;
- float dist;
- int sample_index;
- world_audio_sample_distances( localplayer.rb.co, &sample_index, &dist );
+ player__post_update( &localplayer );
- audio_lock();
- vg_dsp.echo_distances[sample_index] = dist;
+ float dist;
+ int sample_index;
+ world_audio_sample_distances( localplayer.rb.co, &sample_index, &dist );
- v3f ears = { 1.0f,0.0f,0.0f };
- m3x3_mulv( main_camera.transform, ears, ears );
- v3_copy( ears, vg_audio.external_listener_ears );
- v3_copy( main_camera.transform[3], vg_audio.external_listener_pos );
+ audio_lock();
+ vg_dsp.echo_distances[sample_index] = dist;
- if( localplayer.gate_waiting ){
- m4x3_mulv( localplayer.gate_waiting->transport,
- vg_audio.external_listener_pos,
- vg_audio.external_listener_pos );
- }
+ v3f ears = { 1.0f,0.0f,0.0f };
+ m3x3_mulv( main_camera.transform, ears, ears );
+ v3_copy( ears, vg_audio.external_listener_ears );
+ v3_copy( main_camera.transform[3], vg_audio.external_listener_pos );
- v3_copy( localplayer.rb.v, vg_audio.external_lister_velocity );
- audio_unlock();
-
- vg.time_rate = 1.0f-menu.factive;
- vehicle_update_post();
+ if( localplayer.gate_waiting ){
+ m4x3_mulv( localplayer.gate_waiting->transport,
+ vg_audio.external_listener_pos,
+ vg_audio.external_listener_pos );
}
+
+ v3_copy( localplayer.rb.v, vg_audio.external_lister_velocity );
+ audio_unlock();
+
+ vg.time_rate = 1.0f-menu.factive;
+ vehicle_update_post();
}
VG_STATIC void vg_framebuffer_resize( int w, int h )
VG_STATIC void vg_render(void)
{
- if( skaterift_status == 0 ){
+ if( skaterift.async_op == k_async_op_clientloading ){
_vg_loader_render();
return;
}
VG_STATIC void vg_gui(void)
{
- if( skaterift_status == 0 ){
- return;
- }
+ if( skaterift.async_op == k_async_op_clientloading ) return;
menu_update();
if( menu.active ){
render_view_framebuffer_ui();
}
+static void async_skaterift_world_loaded( void *payload, u32 size )
+{
+ skaterift_end_op();
+}
+
+static void skaterift_world_changer_thread( void *data )
+{
+ const char *path = data;
+ world_load( 1, world_global.load_target );
+ vg_async_call( async_skaterift_world_loaded, NULL, 0 );
+}
+
+/* holding pattern before we can start loading the new world, since we might be
+ * waiting for audio to stop */
+static void skaterift_change_world_preupdate(void)
+{
+ for( u32 i=1; i<vg_list_size(world_global.worlds); i++ ){
+ world_instance *inst = &world_global.worlds[i];
+
+ if( inst->status == k_world_status_unloading ){
+ if( world_freeable( inst ) ){
+ world_free( inst );
+ }
+ return;
+ }
+ }
+
+ vg_info( "worlds cleared, begining load\n" );
+ skaterift_shift_op( k_async_op_world_loading );
+
+ /* finally can start the loader */
+ vg_loader_start( skaterift_world_changer_thread, NULL );
+}
+
+/* places all loaded worlds into unloading state */
+static void skaterift_change_world( const char *world_path )
+{
+ vg_info( "switching to %s\n", world_path );
+
+ if( world_global.active_world != 0 ){
+ vg_error( "Cannot change worlds while in non-root world\n" );
+ }
+ else{
+ skaterift_begin_op( k_async_op_world_preloading );
+
+ vg_linear_clear( vg_mem.scratch );
+ world_global.load_target = vg_linear_alloc( vg_mem.scratch, 1024 );
+ vg_strncpy( world_path, world_global.load_target,
+ 1024, k_strncpy_overflow_fatal );
+
+ vg_info( "unloading old worlds\n" );
+ world_unlink_nonlocal( &world_global.worlds[0] );
+
+ for( u32 i=1; i<vg_list_size(world_global.worlds); i++ ){
+ world_instance *inst = &world_global.worlds[i];
+
+ if( inst->status == k_world_status_loaded ){
+ inst->status = k_world_status_unloading;
+ world_fadeout_audio( inst );
+ }
+ }
+ }
+}
+
+static int skaterift_change_world_command( int argc, const char *argv[] )
+{
+ if( argc == 1 )
+ skaterift_change_world( argv[0] );
+
+ return 0;
+}
+
#else
#include "skaterift_imgui_dev.c"
--- /dev/null
+#ifndef SKATERIFT_H
+#define SKATERIFT_H
+
+#include "common.h"
+
+struct{
+ enum async_operation{
+ k_async_op_none,
+ k_async_op_clientloading,
+ k_async_op_world_preloading,
+ k_async_op_world_loading,
+ k_workshop_form_op_loading_model,
+ k_workshop_form_op_downloading_submission,
+ k_workshop_form_op_publishing_update,
+ k_workshop_op_item_scan,
+ k_workshop_op_item_load
+ }
+ async_op;
+}
+static skaterift = { .async_op = k_async_op_clientloading };
+
+
+/* Skaterift api */
+
+static void skaterift_change_world( const char *world_path );
+static int skaterift_change_world_command( int argc, const char *argv[] );
+
+
+
+
+
+/*
+ * Start a new operation or crash if we are already running one. you can avoid
+ * crashing the game by checking the async status yourself before calling.
+ */
+VG_STATIC void skaterift_begin_op( enum async_operation op )
+{
+ if( skaterift.async_op != k_async_op_none ){
+ vg_fatal_error( "Async executing op(%d), tried to start op(%d)\n",
+ skaterift.async_op, op );
+ }
+
+ skaterift.async_op = op;
+ vg_info( "Starting op( %d )\n", op );
+}
+
+/*
+ * Switch operation for those who have multiple parts
+ */
+VG_STATIC void skaterift_shift_op( enum async_operation op )
+{
+ if( skaterift.async_op == k_async_op_none ){
+ vg_fatal_error( "No current op, cannot shift operation (%d)\n", op );
+ }
+
+ skaterift.async_op = op;
+ vg_info( "Shifting to op( %d )\n", op );
+}
+
+/*
+ * Finished operation, otheres can now run
+ */
+VG_STATIC void skaterift_end_op(void)
+{
+ vg_info( "Finishing op( %d )\n", skaterift.async_op );
+ skaterift.async_op = k_async_op_none;
+}
+
+#endif /* SKATERIFT_H */
*/
VG_STATIC void workshop_quit_form(void)
{
- workshop_begin_op( k_workshop_form_op_none ); /* safeguard */
+ skaterift_begin_op( k_async_op_none ); /* safeguard */
player_board_unload( &workshop_form.board_model );
workshop_form.file_intent = k_workshop_form_file_intent_none;
}
workshop_form.page = k_workshop_form_hidden;
- workshop_end_op();
+ skaterift_end_op();
}
/*
vg_error( "Error with the submitted file (%d)\n", result->m_eResult );
}
- workshop_end_op();
+ skaterift_end_op();
}
struct workshop_package_info {
if( !info->success ){
workshop_form.page = k_workshop_form_closing_bad;
workshop_form.failure_or_success_string = info->failure_reason;
- workshop_end_op();
+ skaterift_end_op();
return;
}
workshop_form.page = k_workshop_form_closing_bad;
workshop_form.failure_or_success_string = errstr;
- workshop_end_op();
+ skaterift_end_op();
}
}
}
}
- workshop_begin_op( k_workshop_form_op_publishing_update );
+ skaterift_begin_op( k_workshop_form_op_publishing_update );
player_board_unload( &workshop_form.board_model );
workshop_form.file_intent = k_workshop_form_file_intent_none;
workshop_form.file_intent = k_workshop_form_file_intent_new;
vg_success( "workshop async load complete\n" );
- workshop_end_op();
+ skaterift_end_op();
}
/*
*/
VG_STATIC void workshop_form_loadmodel_async_error( void *payload, u32 size )
{
- workshop_end_op();
+ skaterift_end_op();
}
/*
*/
VG_STATIC void workshop_op_load_model(void)
{
- workshop_begin_op( k_workshop_form_op_loading_model );
+ skaterift_begin_op( k_workshop_form_op_loading_model );
vg_loader_start( _workshop_form_load_thread, NULL );
}
vg_success( "Loaded workshop preview image\n" );
}
- workshop_end_op();
+ skaterift_end_op();
}
struct workshop_loadpreview_info {
else{
vg_error( "Error while donwloading UGC preview( %d )\n",
result->m_eResult );
- workshop_end_op();
+ skaterift_end_op();
}
}
result_index,
&details ) )
{
- workshop_begin_op( k_workshop_form_op_downloading_submission );
+ skaterift_begin_op( k_workshop_form_op_downloading_submission );
workshop_reset_submission_data();
workshop_form.submission.submit_description = 0;
workshop_form.submission.submit_file_and_image = 0;
if( details.m_hPreviewFile == 0 ){
vg_error( "m_hPreviewFile is 0\n" );
- workshop_end_op();
+ skaterift_end_op();
}
else{
/* Now need to begin downloading the image so we can display it */
}
else{
vg_error( "GetQueryUGCResult: Index out of range\n" );
- workshop_end_op();
+ skaterift_end_op();
}
}
ui_rect quit_button;
ui_split( title, k_ui_axis_v, title[2]-title[3], 2, title, quit_button );
- if( workshop.operation == k_workshop_form_op_none ){
+ if( skaterift.async_op == k_async_op_none ){
if( ui_button_text( quit_button, "X", 1 ) ){
workshop_quit_form();
return;
* escapes here and we show them a basic string
*/
- if( workshop.operation != k_workshop_form_op_none ){
+ if( skaterift.async_op != k_async_op_none ){
const char *op_string = "The programmer has not bothered to describe "
"the current operation that is running.";
- switch(workshop.operation){
+ switch( skaterift.async_op ){
case k_workshop_form_op_loading_model:
op_string = "Operation in progress: Loading model file.";
break;
#define VG_GAME
#include "vg/vg.h"
#include "vg/vg_steam_remote_storage.h"
-
-struct workshop{
- enum workshop_operation{
- k_workshop_form_op_none,
- k_workshop_form_op_loading_model,
- k_workshop_form_op_downloading_submission,
- k_workshop_form_op_publishing_update,
- k_workshop_op_item_scan,
- k_workshop_op_item_load
- }
- operation;
-}
-static workshop;
+#include "skaterift.h"
struct workshop_file_info{
u64 author;
VG_STATIC void workshop_load_metadata( const char *path,
struct workshop_file_info *info );
-/*
- * Start a new operation and crash if we are already running one.
- */
-VG_STATIC int workshop_begin_op( enum workshop_operation op )
-{
- if( workshop.operation != k_workshop_form_op_none ){
- vg_error( "Workshop form currently executing op(%d), tried to "
- "start op(%d)\n", workshop.operation, op );
- return 0;
- }
-
- workshop.operation = op;
- vg_info( "Starting op( %d )\n", op );
- return 1;
-}
-
-/*
- * Finished operation, otheres can now run
- */
-VG_STATIC void workshop_end_op(void)
-{
- vg_info( "Finishing op( %d )\n", workshop.operation );
- workshop.operation = k_workshop_form_op_none;
-}
-
#endif /* WORKSHOP_H */
*/
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;
float probabilities[3];
v3i light_cubes;
-
struct framebuffer heightmap;
/*
* --------------------------------------------------------------------------
*/
void *heap;
+ char *load_target;
/* rendering */
glmesh skydome;
v3f render_gate_pos;
int in_volume;
- int switching_to_new_world;
-
world_instance worlds[4];
u32 active_world;
VG_STATIC void ent_audio_call( world_instance *world, ent_call *call )
{
+ 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 );
bar += p;
if( chance < bar ){
-
audio_lock();
if( audio->behaviour == k_channel_behaviour_unlimited ){
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 );
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 );
}
}
}
+/* 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( 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 )
{
world_global.sky_time += world_global.sky_rate * vg.time_delta;
#ifndef WORLD_GATE_H
#define WORLD_GATE_H
+#include "skaterift.h"
#include "common.h"
#include "model.h"
#include "entity.h"
gate->type == k_gate_type_nonlocal_unlinked )
continue;
+ if( gate->type == k_gate_type_nonlocel ){
+ if( skaterift.async_op == k_async_op_world_loading ||
+ skaterift.async_op == k_async_op_world_preloading ){
+ continue;
+ }
+ }
+
if( gate_intersect( gate, pos, last ) ){
return gate;
}
}
}
-#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;
}
/*
- * Copyright (C) 2021-2022 Mt.ZERO Software, Harry Godden - All Rights Reserved
+ * Copyright (C) 2021-2023 Mt.ZERO Software, Harry Godden - All Rights Reserved
*/
#ifndef WORLD_RENDER_H
render_gate( world, gate, cam, layer_depth );
}
else if( gate->type == k_gate_type_nonlocel ){
- world_instance *dest_world = &world_global.worlds[ gate->target ];
- render_gate( dest_world, gate, cam, layer_depth );
+ if( skaterift.async_op != k_async_op_world_loading &&
+ skaterift.async_op != k_async_op_world_preloading ){
+ world_instance *dest_world = &world_global.worlds[ gate->target ];
+ render_gate( dest_world, gate, cam, layer_depth );
+ }
}
else
world->rendering_gate = NULL;