From: hgn Date: Wed, 12 Feb 2025 23:42:35 +0000 (+0000) Subject: added support for loading a preview version of the world. just reduced details etc X-Git-Url: https://skaterift.com/git/?a=commitdiff_plain;h=ff78c35e5637bd1a53eaec66e5d11521229c2a2e;p=carveJwlIkooP6JGAAIwe30JlM.git added support for loading a preview version of the world. just reduced details etc --- diff --git a/build.c b/build.c index e679783..34245b5 100644 --- a/build.c +++ b/build.c @@ -100,6 +100,7 @@ void build_shaders(void){ _S( "scene_standard_alphatest", "scene.vs", "scene_standard_alphatest.fs" ); _S( "scene_foliage", "scene_foliage.vs", "scene_foliage.fs" ); _S( "scene_override", "scene_override.vs", "scene_override.fs" ); + _S( "scene_preview", "scene_override.vs", "scene_preview.fs" ); _S( "scene_fxglow", "scene_fxglow.vs", "scene_fxglow.fs" ); _S( "scene_vertex_blend", "scene.vs", "scene_vertex_blend.fs" ); _S( "scene_terrain", "scene.vs", "scene_terrain.fs" ); diff --git a/content_skaterift/maps/sr002-local-dev_hub-cm-straw.qoi b/content_skaterift/maps/sr002-local-dev_hub-cm-straw.qoi new file mode 100644 index 0000000..c441340 Binary files /dev/null and b/content_skaterift/maps/sr002-local-dev_hub-cm-straw.qoi differ diff --git a/content_skaterift/maps/sr002-local-mp_mtzero-cm-straw.qoi b/content_skaterift/maps/sr002-local-mp_mtzero-cm-straw.qoi new file mode 100644 index 0000000..2274a14 Binary files /dev/null and b/content_skaterift/maps/sr002-local-mp_mtzero-cm-straw.qoi differ diff --git a/shaders/scene_preview.fs b/shaders/scene_preview.fs new file mode 100644 index 0000000..0cc5ee0 --- /dev/null +++ b/shaders/scene_preview.fs @@ -0,0 +1,42 @@ +in vec2 aUv; +in vec4 aNorm; +in vec3 aCo; +in vec3 aWorldCo; + +uniform bool uAlphatest; +uniform vec4 uMapInfo; /* x: min, y: max, z: iso line amount */ + +layout (location = 0) out vec4 oColour; + +#include "motion_vectors_fs.glsl" + +void main() +{ + vec2 ssuv = gl_FragCoord.xy; + vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), ssuv) ); + float dither = fract( vDither.g / 71.0 ) - 0.5; + + float dy0 = aCo.y - uMapInfo.x; + float dy1 = uMapInfo.y - aCo.y; + + if( min(dy0,dy1)*0.5 + dither < 0.51 ) + discard; + + compute_motion_vectors(); + + vec3 vfrag = vec3(aUv.xy,0.0); + vec3 qnorm = aNorm.xyz; + + qnorm = normalize(floor(aNorm.xyz*4.0)*0.25); + qnorm += vec3(0.001,0.0,0.0); + + if( uAlphatest ){ + //vec4 vSample = texture( uTexMain, aUv ); + //if( vSample.a < 0.5 ) + // discard; + } + else{ + } + + oColour = vec4( vfrag, 1.0 ); +} diff --git a/src/client.c b/src/client.c index 0896d89..60b09fe 100644 --- a/src/client.c +++ b/src/client.c @@ -88,7 +88,7 @@ int main( int argc, char *argv[] ) { network_set_host( "skaterift.com", NULL ); vg_mem.use_libc_malloc = 0; - vg_set_mem_quota( 160*1024*1024 ); + vg_set_mem_quota( 200*1024*1024 ); vg_enter( argc, argv, "Voyager Game Engine" ); return 0; } diff --git a/src/menu.c b/src/menu.c index 6f8c48d..b6fa197 100644 --- a/src/menu.c +++ b/src/menu.c @@ -114,7 +114,7 @@ static bool menu_slider( ui_context *ctx, } static bool menu_button( ui_context *ctx, - ui_rect inout_panel, bool select, const char *text ) + ui_rect inout_panel, bool select, bool clickable, const char *text ) { ui_rect rect; menu_standard_widget( ctx, inout_panel, rect, 1 ); @@ -127,42 +127,50 @@ static bool menu_button( ui_context *ctx, { menu_decor_select( ctx, rect ); - if( button_down( k_srbind_maccept ) ) + if( clickable && button_down( k_srbind_maccept ) ) state = k_ui_button_click; } } else { - state = ui_button_base( ctx, rect ); + if( clickable ) + state = ui_button_base( ctx, rect ); select = 0; } - if( state == k_ui_button_click ) - { - ui_fill( ctx, rect, GUI_COL_DARK ); - } - else if( state == k_ui_button_holding_inside ) + if( clickable ) { - ui_fill( ctx, rect, GUI_COL_DARK ); + if( state == k_ui_button_click ) + { + ui_fill( ctx, rect, GUI_COL_DARK ); + } + else if( state == k_ui_button_holding_inside ) + { + ui_fill( ctx, rect, GUI_COL_DARK ); + } + else if( state == k_ui_button_holding_outside ) + { + ui_fill( ctx, rect, GUI_COL_DARK ); + ui_outline( ctx, rect, 1, GUI_COL_CLICK, 0 ); + } + else if( state == k_ui_button_hover ) + { + ui_fill( ctx, rect, GUI_COL_ACTIVE ); + ui_outline( ctx, rect, 1, GUI_COL_CLICK, 0 ); + } + else + { + ui_fill( ctx, rect, select? GUI_COL_ACTIVE: GUI_COL_NORM ); + if( select ) + ui_outline( ctx, rect, 1, GUI_COL_HI, 0 ); + } } - else if( state == k_ui_button_holding_outside ) + else { ui_fill( ctx, rect, GUI_COL_DARK ); - ui_outline( ctx, rect, 1, GUI_COL_CLICK, 0 ); - } - else if( state == k_ui_button_hover ) - { - ui_fill( ctx, rect, GUI_COL_ACTIVE ); - ui_outline( ctx, rect, 1, GUI_COL_CLICK, 0 ); - } - else - { - ui_fill( ctx, rect, select? GUI_COL_ACTIVE: GUI_COL_NORM ); - if( select ) - ui_outline( ctx, rect, 1, GUI_COL_HI, 0 ); } - ui_text( ctx, rect, text, 1, k_ui_align_middle_center, 0 ); + ui_text( ctx, rect, text, 1, k_ui_align_middle_center, clickable? 0: ui_colour(ctx,k_ui_bg) ); if( state == k_ui_button_click ) { @@ -301,6 +309,44 @@ static void menu_link_modal( const char *url ) menu.web_choice = 0; } +static void menu_update_world_list(void) +{ + menu.world_list_total_count = addon_count( k_addon_type_world, ADDON_REG_HIDDEN ); + + if( menu.world_list_selected_index >= menu.world_list_total_count ) + vg_fatal_error( "World list index out of range! (%d >= %d)\n", + menu.world_list_selected_index, menu.world_list_total_count ); + + u32 selected_world_index = menu.world_list_selected_index, + page_base = (selected_world_index / MENU_WORLD_COUNT) * MENU_WORLD_COUNT; + + menu.world_list_display_count = 0; + + for( u32 i=0; i= menu.world_list_total_count ) + menu.world_list_entries[i] = NULL; + else + { + addon_reg *reg = get_addon_from_index( k_addon_type_world, world_index, ADDON_REG_HIDDEN ); + menu.world_list_entries[ menu.world_list_display_count ] = reg; + + vg_msg msg; + vg_msg_init( &msg, reg->metadata, reg->metadata_len ); + + const char *name = vg_msg_getkvstr( &msg, "location" ); + + if( !name ) + name = reg->alias.foldername; + + menu.world_list_names[ menu.world_list_display_count ] = name; + menu.world_list_display_count ++; + } + } +} + void menu_gui( ui_context *ctx ) { if( button_down( k_srbind_mopen ) ) @@ -390,19 +436,16 @@ void menu_gui( ui_context *ctx ) i32 R = menu_nav( &menu.web_choice, mh, 2 ); - if( menu_button( ctx, a, R==0, "Steam Overlay" ) ) + if( menu_button( ctx, a, R==0, steam_ready, "Steam Overlay" ) ) { - if( steam_ready ) - { - ISteamFriends *hSteamFriends = SteamAPI_SteamFriends(); - SteamAPI_ISteamFriends_ActivateGameOverlayToWebPage( hSteamFriends, - menu.web_link, - k_EActivateGameOverlayToWebPageMode_Default ); - menu.web_link = NULL; - } + ISteamFriends *hSteamFriends = SteamAPI_SteamFriends(); + SteamAPI_ISteamFriends_ActivateGameOverlayToWebPage( hSteamFriends, + menu.web_link, + k_EActivateGameOverlayToWebPageMode_Default ); + menu.web_link = NULL; } - if( menu_button( ctx, b, R==1, "Web Browser" ) ) + if( menu_button( ctx, b, R==1, 1, "Web Browser" ) ) { char buf[512]; vg_str str; @@ -420,7 +463,7 @@ void menu_gui( ui_context *ctx ) menu.web_link = NULL; } - if( menu_button( ctx, c, R==2, "No" ) || button_down( k_srbind_mback ) ) + if( menu_button( ctx, c, R==2, 1, "No" ) || button_down( k_srbind_mback ) ) { audio_lock(); audio_oneshot( &audio_ui[3], 1.0f, 0.0f ); @@ -485,7 +528,7 @@ void menu_gui( ui_context *ctx ) ui_rect end = { panel[0], panel[1] + panel[3] - 64, panel[2], 64 }; - if( menu_button( ctx, end, 1, "Back" ) || button_down( k_srbind_mback ) ) + if( menu_button( ctx, end, 1, 1, "Back" ) || button_down( k_srbind_mback ) ) { menu.page = k_menu_page_main; } @@ -520,7 +563,7 @@ void menu_gui( ui_context *ctx ) ui_rect end = { panel[0], panel[1] + panel[3] - 100, panel[2], 100 }; menu_checkbox( ctx, end, R == 2, "Don't show this again", &menu.skip_starter ); - if( menu_button( ctx, end, R == 3, "OK" ) ) + if( menu_button( ctx, end, R == 3, 1, "OK" ) ) { menu.page = k_menu_page_main; skaterift.activity = k_skaterift_default; @@ -555,14 +598,13 @@ void menu_gui( ui_context *ctx ) ui_rect end = { panel[0], panel[1] + panel[3] - 48, panel[2], 48 }, a,b; ui_split_ratio( end, k_ui_axis_v, 0.5f, 2, a, b ); - if( menu_button( ctx, a, R == 0, "Store Page" ) ) + if( menu_button( ctx, a, R == 0, steam_ready, "Store Page" ) ) { - if( steam_ready ) - SteamAPI_ISteamFriends_ActivateGameOverlayToStore( - SteamAPI_SteamFriends(), 2103940, k_EOverlayToStoreFlag_None); + SteamAPI_ISteamFriends_ActivateGameOverlayToStore( + SteamAPI_SteamFriends(), 2103940, k_EOverlayToStoreFlag_None); } - if( menu_button( ctx, b, R == 1, "Nah" ) || button_down( k_srbind_mback ) ) + if( menu_button( ctx, b, R == 1, 1, "Nah" ) || button_down( k_srbind_mback ) ) { audio_lock(); audio_oneshot( &audio_ui[3], 1.0f, 0.0f ); @@ -573,6 +615,56 @@ void menu_gui( ui_context *ctx ) goto menu_draw; } + else if( menu.page == k_menu_page_world_select ) + { + ctx->font = &vgf_default_large; + + ui_rect left_world_list = { 0, 0, 300, vg.window_y }; + ui_fill( ctx, left_world_list, ui_opacity( GUI_COL_DARK, 0.35f ) ); + + ui_rect title; + ui_split( left_world_list, k_ui_axis_h, 28, 0, title, left_world_list ); + ui_text( ctx, title, "Locations", 1, k_ui_align_middle_center, 0 ); + + i32 selected_world_index = menu.world_list_selected_index, + page = selected_world_index / MENU_WORLD_COUNT, + page_base = page * MENU_WORLD_COUNT, + max_page = (menu.world_list_total_count-1) / MENU_WORLD_COUNT; + + i32 R = menu_nav( &menu.world_list_selected_index, mv, menu.world_list_total_count-1 ); + + + + if( menu_button( ctx, left_world_list, R == -999, page>0, "\x94" ) ) + menu.world_list_selected_index = (page-1)*MENU_WORLD_COUNT; + + for( u32 i=0; i= (page_base+MENU_WORLD_COUNT) ) + { + menu_update_world_list(); + } + + + + + if( /*menu_button( ctx, end, 1, 1, "Back" ) ||*/ button_down( k_srbind_mback ) ) + { + menu.page = k_menu_page_main; + } + + goto menu_draw; + } /* TOP BAR * -------------------------------------------------------------------*/ @@ -839,19 +931,25 @@ void menu_gui( ui_context *ctx ) { i32 R = menu_nav( &menu.main_row, mv, 2 ); - if( menu_button( ctx, list, R == 0, "Resume" ) ) + if( menu_button( ctx, list, R == 0, 1, "Resume" ) ) { skaterift.activity = k_skaterift_default; return; } - if( menu_button( ctx, list, R == 1, "Credits" ) ) + if( menu_button( ctx, list, R == 1, 1, "Change World" ) ) + { + menu.page = k_menu_page_world_select; + menu_update_world_list(); + } + + if( menu_button( ctx, list, R == 2, 1, "Credits" ) ) { menu.page = k_menu_page_credits; } ui_rect end = { list[0], list[1]+list[3]-64, list[2], 72 }; - if( menu_button( ctx, end, R == 2, "Quit Game" ) ) + if( menu_button( ctx, end, R == 3, 1, "Quit Game" ) ) { vg.window_should_close = 1; } @@ -889,7 +987,7 @@ void menu_gui( ui_context *ctx ) ui_rect end = { list[0], list[1]+list[3]-64, list[2], 72 }; ctx->font = &vgf_default_small; menu_heading( ctx, end, "Advanced", 0 ); - if( menu_button( ctx, end, R == 8, "Open Engine Settings" ) ) + if( menu_button( ctx, end, R == 8, 1, "Open Engine Settings" ) ) { vg_settings_open(); } @@ -949,7 +1047,7 @@ void menu_gui( ui_context *ctx ) vs[2].co[1] = vs[0].co[1] + 84 + vgf_default_large.sy*11 + 16; vs[3].co[1] = vs[2].co[1]; } - if( menu_button( ctx, list, R == 0, "Where to go" ) ) + if( menu_button( ctx, list, R == 0, 1, "Where to go" ) ) menu.guide_sel = 1; if( menu.guide_sel == 3 ) @@ -976,11 +1074,11 @@ void menu_gui( ui_context *ctx ) vs[2].co[1] = vs[0].co[1] + 84 + vgf_default_large.sy*7 + 16; vs[3].co[1] = vs[2].co[1]; } - if( menu_button( ctx, list, R == 1, "Playing Online" ) ) + if( menu_button( ctx, list, R == 1, 1, "Playing Online" ) ) menu.guide_sel = 3; menu_heading( ctx, list, "Controls", 0 ); - if( menu_button( ctx, list, R == 2, "Skating \xb2" ) ) + if( menu_button( ctx, list, R == 2, 1, "Skating \xb2" ) ) { menu.guide_sel = 0; menu_link_modal( @@ -988,7 +1086,7 @@ void menu_gui( ui_context *ctx ) } //if( menu.guide_sel == 0 || menu.guide_sel > 3 ) menu_try_find_cam( 3 ); - if( menu_button( ctx, list, R == 3, "Tricks \xb2" ) ) + if( menu_button( ctx, list, R == 3, 1, "Tricks \xb2" ) ) { menu.guide_sel = 0; menu_link_modal( @@ -996,19 +1094,19 @@ void menu_gui( ui_context *ctx ) } menu_heading( ctx, list, "Workshop", 0 ); - if( menu_button( ctx, list, R == 4, "Create a Board \xb2" ) ) + if( menu_button( ctx, list, R == 4, 1, "Create a Board \xb2" ) ) { menu.guide_sel = 0; menu_link_modal( "https://skaterift.com/index.php?page=workshop_board" ); } - if( menu_button( ctx, list, R == 5, "Create a World \xb2" ) ) + if( menu_button( ctx, list, R == 5, 1, "Create a World \xb2" ) ) { menu.guide_sel = 0; menu_link_modal( "https://skaterift.com/index.php?page=workshop_world" ); } - if( menu_button( ctx, list, R == 6, "Create a Playermodel \xb2" ) ) + if( menu_button( ctx, list, R == 6, 1, "Create a Playermodel \xb2" ) ) { menu.guide_sel = 0; menu_link_modal( diff --git a/src/menu.h b/src/menu.h index 5a6dbc4..be5cbbe 100644 --- a/src/menu.h +++ b/src/menu.h @@ -1,6 +1,7 @@ #pragma once #define MENU_STACK_SIZE 8 +#define MENU_WORLD_COUNT 4 #include "vg/vg_engine.h" #include "entity.h" @@ -13,6 +14,7 @@ enum menu_page k_menu_page_main, k_menu_page_credits, k_menu_page_help, + k_menu_page_world_select }; enum menu_main_subpage @@ -46,6 +48,13 @@ struct global_menu i32 web_choice; GLuint prem_tex; + + addon_reg *world_list_entries[ MENU_WORLD_COUNT ]; + const char *world_list_names[ MENU_WORLD_COUNT ]; + + i32 world_list_display_count, + world_list_total_count, + world_list_selected_index; } extern menu; diff --git a/src/player.c b/src/player.c index 7daea11..473c147 100644 --- a/src/player.c +++ b/src/player.c @@ -210,7 +210,7 @@ void player__pass_gate( u32 id ) k_strncpy_overflow_fatal ); addon_reg *reg = get_addon_from_index( k_addon_type_world, gate->addon_reg, 0 ); - skaterift_switch_world_start( reg ); + skaterift_load_world_start( reg, 0 ); return; } else diff --git a/src/save.c b/src/save.c index fe8c0b6..432f341 100644 --- a/src/save.c +++ b/src/save.c @@ -244,16 +244,14 @@ void skaterift_load_mainsave(void) reg_id = addon_match( &q ); if( reg_id != 0xffffffff ) { - _world.switch_to_addon = - get_addon_from_index( k_addon_type_world, reg_id, 0 ); + _world.loader_reg = get_addon_from_index( k_addon_type_world, reg_id, 0 ); } else { char buf[ADDON_UID_MAX]; addon_alias_uid( &q, buf ); - vg_error( "While loading player location from save file, " - "couldn't find addon '%s'\n", buf ); + vg_error( "While loading player location from save file, couldn't find addon '%s'\n", buf ); } } } @@ -272,8 +270,7 @@ void skaterift_load_mainsave(void) else { vg_info( "Starting new story!\n" ); - _world.switch_to_addon = - addon_mount_local_addon( "maps/dev_heaven", k_addon_type_world, ".mdl" ); + _world.loader_reg = addon_mount_local_addon( "maps/dev_heaven", k_addon_type_world, ".mdl" ); _skaterift_script_hook( 2, (const char *[]){ "unlock", "intro" } ); } } diff --git a/src/skaterift.c b/src/skaterift.c index f31e604..590282b 100644 --- a/src/skaterift.c +++ b/src/skaterift.c @@ -69,20 +69,19 @@ static addon_reg *skaterift_mount_world_unloadable( const char *path, u32 ext ) { addon_reg *reg = addon_mount_local_addon( path, k_addon_type_world, ".mdl" ); if( !reg ) vg_fatal_error( "world not found\n" ); - reg->flags |= (ADDON_REG_HIDDEN | ext); + reg->flags |= (ext); return reg; } static void skaterift_load_world_content(void) { /* hub world */ - _world.default_hub_addon = - skaterift_mount_world_unloadable( "maps/dev_hub", 0 ); - skaterift_mount_world_unloadable( "maps/dev_heaven", 0 ); + _world.default_hub_addon = skaterift_mount_world_unloadable( "maps/dev_hub", 0 ); + skaterift_mount_world_unloadable( "maps/dev_heaven", ADDON_REG_HIDDEN ); skaterift_mount_world_unloadable( "maps/mp_spawn", ADDON_REG_CITY|ADDON_REG_PREMIUM ); skaterift_mount_world_unloadable( "maps/mp_mtzero", ADDON_REG_MTZERO|ADDON_REG_PREMIUM ); skaterift_mount_world_unloadable( "maps/dev_tutorial", 0 ); - skaterift_mount_world_unloadable( "maps/dev_flatworld", 0 ); + skaterift_mount_world_unloadable( "maps/dev_flatworld", ADDON_REG_HIDDEN ); skaterift_mount_world_unloadable( "maps/mp_line1", ADDON_REG_PREMIUM ); } @@ -93,11 +92,9 @@ static void skaterift_load_player_content(void) player_load_animation_reference( "models/ch_none.mdl" ); player_load_animations( "metascenes/skater.ms" ); - player_model_load( &localplayer.fallback_model, "models/ch_none.mdl", - vg_mem.rtmemory ); + player_model_load( &localplayer.fallback_model, "models/ch_none.mdl", vg_mem.rtmemory ); player__bind(); - player_board_load( &localplayer.fallback_board, "models/board_none.mdl", - vg_mem.rtmemory ); + player_board_load( &localplayer.fallback_board, "models/board_none.mdl", vg_mem.rtmemory ); } void game_load(void) @@ -106,7 +103,7 @@ void game_load(void) vg_loader_set_user_information( "Initializing subsystems" ); - vg_console_reg_cmd( "switch_world", skaterift_switch_world_command, NULL ); + vg_console_reg_cmd( "load_world", skaterift_load_world_command, NULL ); vg_console_reg_var( "immobile", &localplayer.immobile, k_var_dtype_i32, 0 ); vg_loader_step( menu_init, NULL ); vg_loader_step( control_overlay_init, NULL ); @@ -146,10 +143,14 @@ void game_load(void) vg_loader_set_user_information( "Loading savedata" ); skaterift_load_mainsave(); - if( !_world.switch_to_addon ) + _world.loader_instance = &_world.main; + _world.loader_preview_mode = 0; + _world.loader_heap = _world.heap; + + if( !_world.loader_reg ) { vg_warn( "Falling back to default hub world...\n" ); - _world.switch_to_addon = _world.default_hub_addon; + _world.loader_reg = _world.default_hub_addon; } world_switcher_thread( NULL ); @@ -298,6 +299,9 @@ static void render_player_transparent(void) player__render( &small_cam ); } + + + static void render_scene(void) { /* Draw world */ @@ -334,8 +338,13 @@ static void render_scene(void) render_world_routes( world, world, identity, &g_render.cam, 0, 1 ); return; } - - render_world( &_world.main, &g_render.cam, 0, 0, 1, 1 ); + + if( _world.preview_instance.complete ) + { + render_world_preview(); + } + else + render_world( &_world.main, &g_render.cam, 0, 0, 1, 1 ); particle_system_update( &particles_grind, vg.time_delta ); //particle_system_debug( &particles_grind ); diff --git a/src/world.c b/src/world.c index 2600113..382a9eb 100644 --- a/src/world.c +++ b/src/world.c @@ -23,8 +23,10 @@ void world_init(void) /* Allocate dynamic world memory arena */ u32 max_size = 76*1024*1024; - _world.heap = vg_create_linear_allocator( vg_mem.rtmemory, max_size, - VG_MEMORY_SYSTEM ); + _world.heap = vg_create_linear_allocator( vg_mem.rtmemory, max_size, VG_MEMORY_SYSTEM ); + + max_size = 32*1024*1024; + _world.preview_heap = vg_create_linear_allocator( vg_mem.rtmemory, max_size, VG_MEMORY_SYSTEM ); } void skaterift_world_get_save_path( addon_reg *world_reg, char buf[128] ) diff --git a/src/world.h b/src/world.h index 7cd280f..89be65e 100644 --- a/src/world.h +++ b/src/world.h @@ -58,6 +58,8 @@ static i32 k_debug_light_indices = 0, struct world_instance { + bool complete; + addon_reg *addon; void *heap; @@ -228,7 +230,7 @@ struct world_static * Allocated as system memory * -------------------------------------------------------------------------- */ - void *heap; + void *heap, *preview_heap; u32 current_run_version; double time, rewind_from, rewind_to; @@ -236,8 +238,8 @@ struct world_static u32 active_trigger_volumes[8]; u32 active_trigger_volume_count; - world_instance main; - addon_reg *default_hub_addon, *switch_to_addon; + world_instance main, preview_instance; + addon_reg *default_hub_addon; addon_reg *previous_world_addon; char nonlocal_destination_key[32]; @@ -255,6 +257,11 @@ struct world_static } loader_state; + addon_reg *loader_reg; + world_instance *loader_instance; + void *loader_heap; + bool loader_preview_mode; + enum world_event { k_world_event_none = 0, @@ -271,16 +278,9 @@ struct world_static } extern _world; -struct world_load_args -{ - addon_reg *reg; - world_instance *instance; - void *heap; -}; - void world_init(void); -void skaterift_world_load_thread( void *_args ); +void skaterift_world_load_thread( void *_ ); void world_update( world_instance *world, v3f pos ); bool world_set_event( enum world_event activity ); diff --git a/src/world_entity.c b/src/world_entity.c index 025126a..3c5eed2 100644 --- a/src/world_entity.c +++ b/src/world_entity.c @@ -319,9 +319,9 @@ void world_gen_entities_init( world_instance *world ) world->entity_list[index ++] = mdl_entity_id( type, j ); } - world->entity_bh = bh_create( world->heap, &bh_system_entity_list, world, - indexed_count, 2 ); + world->entity_bh = bh_create( world->heap, &bh_system_entity_list, world, indexed_count, 2 ); + /* FIXME: This should be scene geometry instead?????????? */ world->tar_min = world->entity_bh->nodes[0].bbx[0][1]; world->tar_max = world->entity_bh->nodes[0].bbx[1][1] + 20.0f; diff --git a/src/world_gate.c b/src/world_gate.c index adf0bd2..f8fb4fb 100644 --- a/src/world_gate.c +++ b/src/world_gate.c @@ -326,6 +326,7 @@ void nonlocal_gate_cubemap_path( addon_reg *world_addon, const char *gate_key, c vg_str path_str; vg_strnull( &path_str, path, 256 ); + vg_strcat( &path_str, "maps/" ); vg_strcat( &path_str, id ); vg_strcat( &path_str, "-cm-" ); vg_strcat( &path_str, gate_key ); diff --git a/src/world_gen.c b/src/world_gen.c index 30ee158..cd1e570 100644 --- a/src/world_gen.c +++ b/src/world_gen.c @@ -230,7 +230,8 @@ void world_gen_generate_meshes( world_instance *world ) vg_info( "Generating collidable geometry\n" ); - for( u32 i=0; isurface_count; i++ ){ + for( u32 i=0; isurface_count; i++ ) + { struct world_surface *surf = &world->surfaces[ i ]; if( surf->info.flags & k_material_flag_collision ) @@ -267,8 +268,12 @@ void world_gen_generate_meshes( world_instance *world ) /* need send off the memory to the gpu before we can create the bvh. */ vg_async_stall(); - vg_info( "creating bvh\n" ); - world->geo_bh = scene_bh_create( world->heap, &world->scene_geo ); + + if( !_world.loader_preview_mode ) + { + vg_info( "creating bvh\n" ); + world->geo_bh = scene_bh_create( world->heap, &world->scene_geo ); + } /* * Generate scene: non-collidable geometry @@ -280,27 +285,33 @@ void world_gen_generate_meshes( world_instance *world ) &world->mesh_no_collide, 250000, 500000 ); - for( u32 i=0; isurface_count; i++ ){ + for( u32 i=0; isurface_count; i++ ) + { struct world_surface *surf = &world->surfaces[ i ]; - if( !(surf->info.flags & k_material_flag_collision) ){ - world_add_all_if_material( midentity, - &world->scene_no_collide, &world->meta, i ); - } + if( !(surf->info.flags & k_material_flag_collision) ) + world_add_all_if_material( midentity, &world->scene_no_collide, &world->meta, i ); - if( surf->info.flags & k_material_flag_grow_grass ){ - world_apply_procedural_foliage( world, &world->scene_no_collide, - surf ); + if( !_world.loader_preview_mode ) + { + if( surf->info.flags & k_material_flag_grow_grass ) + world_apply_procedural_foliage( world, &world->scene_no_collide, surf ); } scene_copy_slice( &world->scene_no_collide, &surf->sm_no_collide ); } + if( _world.loader_preview_mode ) + goto IL_UPLOAD; + /* unpack traffic models.. TODO: should we just put all these submeshes in a * dynamic models list? and then the actual entitities point to the * models. we only have 2 types at the moment which need dynamic models but * would make sense to do this when/if we have more. + * + * update to self: there were more than 2 and we never gave a shit anyway. */ + for( u32 i=0; ient_traffic ); i++ ) { ent_traffic *vehc = af_arritm( &world->ent_traffic, i ); @@ -362,11 +373,13 @@ void world_gen_generate_meshes( world_instance *world ) } } +IL_UPLOAD: vg_async_dispatch( call, async_scene_upload ); } /* signed distance function for cone */ -static f32 fsd_cone_infinite( v3f p, v2f c ){ +static f32 fsd_cone_infinite( v3f p, v2f c ) +{ v2f q = { v2_length( (v2f){ p[0], p[2] } ), -p[1] }; float s = vg_maxf( 0.0f, v2_dot( q, c ) ); @@ -718,38 +731,40 @@ void async_world_postprocess( void *payload, u32 _size ) /* Loads textures from the pack file */ void world_gen_load_surfaces( world_instance *world ) { - vg_info( "Loading textures\n" ); - world->texture_count = 0; - - world->texture_count = world->meta.texture_count+1; - world->textures = vg_linear_alloc( world->heap, - vg_align8(sizeof(GLuint)*world->texture_count) ); - world->textures[0] = vg.tex_missing; - - for( u32 i=0; imeta.texture_count; i++ ) + if( _world.loader_preview_mode ) + { + world->texture_count = 0; + } + else { - mdl_texture *tex = &world->meta.textures[ i ]; + vg_info( "Loading textures\n" ); + world->texture_count = world->meta.texture_count+1; + world->textures = vg_linear_alloc( world->heap, vg_align8(sizeof(GLuint)*world->texture_count) ); + world->textures[0] = vg.tex_missing; - if( !tex->file.pack_size ) + for( u32 i=0; imeta.texture_count; i++ ) { - vg_fatal_error( "World models must have packed textures!" ); - } + mdl_texture *tex = &world->meta.textures[ i ]; - vg_linear_clear( vg_mem.scratch ); - void *src_data = vg_linear_alloc( vg_mem.scratch, - tex->file.pack_size ); - mdl_fread_pack_file( &world->meta, &tex->file, src_data ); + if( !tex->file.pack_size ) + { + vg_fatal_error( "World models must have packed textures!" ); + } - vg_tex2d_load_qoi_async( src_data, tex->file.pack_size, - VG_TEX2D_NEAREST|VG_TEX2D_REPEAT, - &world->textures[i+1] ); + vg_linear_clear( vg_mem.scratch ); + void *src_data = vg_linear_alloc( vg_mem.scratch, tex->file.pack_size ); + mdl_fread_pack_file( &world->meta, &tex->file, src_data ); + + vg_tex2d_load_qoi_async( src_data, tex->file.pack_size, + VG_TEX2D_NEAREST|VG_TEX2D_REPEAT, + &world->textures[i+1] ); + } } vg_info( "Loading materials\n" ); world->surface_count = world->meta.material_count+1; - world->surfaces = vg_linear_alloc( world->heap, - vg_align8(sizeof(struct world_surface)*world->surface_count) ); + world->surfaces = vg_linear_alloc( world->heap, vg_align8(sizeof(struct world_surface)*world->surface_count) ); /* error material */ struct world_surface *errmat = &world->surfaces[0]; @@ -767,8 +782,7 @@ void world_gen_load_surfaces( world_instance *world ) world->ub_lighting.g_water_fog = props->fog_scale; } - if( surf->info.shader == k_shader_standard_cutout || - surf->info.shader == k_shader_foliage ) + if( surf->info.shader == k_shader_standard_cutout || surf->info.shader == k_shader_foliage ) { struct shader_props_standard *props = surf->info.props.compiled; surf->alpha_tex = props->tex_diffuse; diff --git a/src/world_load.c b/src/world_load.c index b75a80d..ba69fcc 100644 --- a/src/world_load.c +++ b/src/world_load.c @@ -14,8 +14,7 @@ /* * load the .mdl file located in path as a world instance */ -static void world_instance_load_mdl( world_instance *world, const char *path, - void *heap ) +static void world_instance_load_mdl( world_instance *world, const char *path, void *heap ) { vg_loader_set_user_information( "Loading world data" ); @@ -31,49 +30,52 @@ static void world_instance_load_mdl( world_instance *world, const char *path, mdl_load_metadata_block( meta, world->heap ); mdl_load_mesh_block( meta, world->heap ); - vg_info( "%u\n", sizeof(ent_cubemap) ); + bool load_all = !_world.loader_preview_mode; - AF_LOAD_ARRAY_STRUCT( af, &world->ent_gate, ent_gate, heap ); - AF_LOAD_ARRAY_STRUCT( af, &world->ent_camera, ent_camera, heap ); - -#if (MDL_VERSION_MIN <= 107) - if( meta->version <= 107 ) + if( load_all ) { - array_file_ptr legacy_cameras; - af_load_array( af, &legacy_cameras, "ent_camera", - vg_mem.scratch, sizeof(struct ent_camera_v107) ); + AF_LOAD_ARRAY_STRUCT( af, &world->ent_gate, ent_gate, heap ); + AF_LOAD_ARRAY_STRUCT( af, &world->ent_camera, ent_camera, heap ); - for( u32 i=0; iversion <= 107 ) { - fix_ent_camera_v107( af_arritm( &legacy_cameras, i ), - af_arritm( &world->ent_camera, i ) ); + array_file_ptr legacy_cameras; + af_load_array( af, &legacy_cameras, "ent_camera", + vg_mem.scratch, sizeof(struct ent_camera_v107) ); + + for( u32 i=0; ient_camera, i ) ); + } } - } #endif - AF_LOAD_ARRAY_STRUCT( af, &world->ent_spawn, ent_spawn, heap ); - AF_LOAD_ARRAY_STRUCT( af, &world->ent_light, ent_light, heap ); - AF_LOAD_ARRAY_STRUCT( af, &world->ent_route_node,ent_route_node, heap ); - AF_LOAD_ARRAY_STRUCT( af, &world->ent_path_index,ent_path_index, heap ); - AF_LOAD_ARRAY_STRUCT( af, &world->ent_checkpoint,ent_checkpoint, heap ); - AF_LOAD_ARRAY_STRUCT( af, &world->ent_route, ent_route, heap ); - AF_LOAD_ARRAY_STRUCT( af, &world->ent_water, ent_water, heap ); - AF_LOAD_ARRAY_STRUCT( af, &world->ent_audio_clip,ent_audio_clip, heap ); - AF_LOAD_ARRAY_STRUCT( af, &world->ent_audio, ent_audio, heap ); - AF_LOAD_ARRAY_STRUCT( af, &world->ent_volume, ent_volume, heap ); - AF_LOAD_ARRAY_STRUCT( af, &world->ent_traffic, ent_traffic, heap ); - AF_LOAD_ARRAY_STRUCT( af, &world->ent_marker, ent_marker, heap ); - AF_LOAD_ARRAY_STRUCT( af, &world->ent_skateshop, ent_skateshop, heap ); - AF_LOAD_ARRAY_STRUCT( af, &world->ent_swspreview,ent_swspreview, heap ); - AF_LOAD_ARRAY_STRUCT( af, &world->ent_ccmd, ent_ccmd, heap ); - AF_LOAD_ARRAY_STRUCT( af, &world->ent_objective, ent_objective, heap ); - AF_LOAD_ARRAY_STRUCT( af, &world->ent_challenge, ent_challenge, heap ); - AF_LOAD_ARRAY_STRUCT( af, &world->ent_relay, ent_relay, heap ); - AF_LOAD_ARRAY_STRUCT( af, &world->ent_cubemap, ent_cubemap, heap ); - AF_LOAD_ARRAY_STRUCT( af, &world->ent_miniworld, ent_miniworld, heap ); - AF_LOAD_ARRAY_STRUCT( af, &world->ent_prop, ent_prop, heap ); - AF_LOAD_ARRAY_STRUCT( af, &world->ent_region, ent_region, heap ); - AF_LOAD_ARRAY_STRUCT( af, &world->ent_glider, ent_glider, heap ); + AF_LOAD_ARRAY_STRUCT( af, &world->ent_spawn, ent_spawn, heap ); + AF_LOAD_ARRAY_STRUCT( af, &world->ent_light, ent_light, heap ); + AF_LOAD_ARRAY_STRUCT( af, &world->ent_route_node,ent_route_node, heap ); + AF_LOAD_ARRAY_STRUCT( af, &world->ent_path_index,ent_path_index, heap ); + AF_LOAD_ARRAY_STRUCT( af, &world->ent_checkpoint,ent_checkpoint, heap ); + AF_LOAD_ARRAY_STRUCT( af, &world->ent_route, ent_route, heap ); + AF_LOAD_ARRAY_STRUCT( af, &world->ent_water, ent_water, heap ); + AF_LOAD_ARRAY_STRUCT( af, &world->ent_audio_clip,ent_audio_clip, heap ); + AF_LOAD_ARRAY_STRUCT( af, &world->ent_audio, ent_audio, heap ); + AF_LOAD_ARRAY_STRUCT( af, &world->ent_volume, ent_volume, heap ); + AF_LOAD_ARRAY_STRUCT( af, &world->ent_traffic, ent_traffic, heap ); + AF_LOAD_ARRAY_STRUCT( af, &world->ent_marker, ent_marker, heap ); + AF_LOAD_ARRAY_STRUCT( af, &world->ent_skateshop, ent_skateshop, heap ); + AF_LOAD_ARRAY_STRUCT( af, &world->ent_swspreview,ent_swspreview, heap ); + AF_LOAD_ARRAY_STRUCT( af, &world->ent_ccmd, ent_ccmd, heap ); + AF_LOAD_ARRAY_STRUCT( af, &world->ent_objective, ent_objective, heap ); + AF_LOAD_ARRAY_STRUCT( af, &world->ent_challenge, ent_challenge, heap ); + AF_LOAD_ARRAY_STRUCT( af, &world->ent_relay, ent_relay, heap ); + AF_LOAD_ARRAY_STRUCT( af, &world->ent_cubemap, ent_cubemap, heap ); + AF_LOAD_ARRAY_STRUCT( af, &world->ent_miniworld, ent_miniworld, heap ); + AF_LOAD_ARRAY_STRUCT( af, &world->ent_prop, ent_prop, heap ); + AF_LOAD_ARRAY_STRUCT( af, &world->ent_region, ent_region, heap ); + AF_LOAD_ARRAY_STRUCT( af, &world->ent_glider, ent_glider, heap ); + } array_file_ptr infos; AF_LOAD_ARRAY_STRUCT( af, &infos, ent_worldinfo, vg_mem.scratch ); @@ -103,8 +105,10 @@ static void world_instance_load_mdl( world_instance *world, const char *path, world->info.flags = 0; } - world->events = vg_linear_alloc( heap, - af_arrcount(&world->ent_challenge)*sizeof(struct event_info) ); + if( load_all ) + { + world->events = vg_linear_alloc( heap, af_arrcount(&world->ent_challenge)*sizeof(struct event_info) ); + } vg_loader_set_user_information( "Compiling world details" ); @@ -116,17 +120,28 @@ static void world_instance_load_mdl( world_instance *world, const char *path, u64 t4 = SDL_GetPerformanceCounter(); world_gen_load_surfaces( world ); u64 t5 = SDL_GetPerformanceCounter(); - world_gen_routes_ent_init( world ); - world_gen_entities_init( world ); + + if( load_all ) + { + world_gen_routes_ent_init( world ); + world_gen_entities_init( world ); + } + u64 t6 = SDL_GetPerformanceCounter(); /* main bulk */ u64 t0 = SDL_GetPerformanceCounter(); world_gen_generate_meshes( world ); u64 t1 = SDL_GetPerformanceCounter(); - world_gen_routes_generate( world ); + + if( load_all ) + world_gen_routes_generate( world ); + u64 t2 = SDL_GetPerformanceCounter(); - world_gen_compute_light_indices( world ); + + if( load_all ) + world_gen_compute_light_indices( world ); + u64 t3 = SDL_GetPerformanceCounter(); mdl_close( meta ); @@ -147,24 +162,27 @@ static void world_instance_load_mdl( world_instance *world, const char *path, ftime_mesh, ftime_route, ftime_ind, ftime_tex, ftime_ent ); /* allocate leaderboard buffers */ - u32 bs = af_arrcount(&world->ent_route)*sizeof(struct leaderboard_cache); - world->leaderboard_cache = vg_linear_alloc( heap, bs ); - - for( u32 i=0; ient_route ); i ++ ) + if( load_all ) { - struct leaderboard_cache *board = &world->leaderboard_cache[i]; - board->data = vg_linear_alloc( heap, NETWORK_REQUEST_MAX ); - board->status = k_request_status_client_error; - board->cache_time = 0.0; - board->data_len = 0; - } + u32 bs = af_arrcount(&world->ent_route)*sizeof(struct leaderboard_cache); + world->leaderboard_cache = vg_linear_alloc( heap, bs ); - world->routes_ui = vg_linear_alloc( heap, - sizeof(struct route_ui)*af_arrcount(&world->ent_route) ); + for( u32 i=0; ient_route ); i ++ ) + { + struct leaderboard_cache *board = &world->leaderboard_cache[i]; + board->data = vg_linear_alloc( heap, NETWORK_REQUEST_MAX ); + board->status = k_request_status_client_error; + board->cache_time = 0.0; + board->data_len = 0; + } - vg_loader_set_user_information( "Postprocessing world" ); - vg_async_call( async_world_postprocess, world, 0 ); - vg_async_stall(); + world->routes_ui = vg_linear_alloc( heap, + sizeof(struct route_ui)*af_arrcount(&world->ent_route) ); + + vg_loader_set_user_information( "Postprocessing world" ); + vg_async_call( async_world_postprocess, world, 0 ); + vg_async_stall(); + } vg_loader_set_user_information( NULL ); } @@ -172,24 +190,25 @@ static void world_instance_load_mdl( world_instance *world, const char *path, static void async_world_loader_done( void *payload, u32 size ) { _world.loader_state = k_world_loader_done; + _world.loader_instance->complete = 1; } -void skaterift_world_load_thread( void *_args ) +void skaterift_world_load_thread( void *_ ) { vg_loader_set_user_information( "Scanning world directory" ); - struct world_load_args args = *((struct world_load_args *)_args); - args.instance->addon = args.reg; + addon_reg *reg = _world.loader_reg; + _world.loader_instance->addon = reg; char uid[ADDON_UID_MAX]; - addon_alias_uid( &args.reg->alias, uid ); + addon_alias_uid( &_world.loader_reg->alias, uid ); vg_info( "LOAD WORLD %s @%d\n", uid ); char path_buf[4096]; vg_str path; vg_strnull( &path, path_buf, 4096 ); - addon_get_content_folder( args.reg, &path, 1 ); + addon_get_content_folder( reg, &path, 1 ); vg_str folder = path; if( !vg_strgood( &folder ) ) @@ -263,7 +282,7 @@ void skaterift_world_load_thread( void *_args ) vg_fatal_error( "No .mdl files found in the map folder.\n" ); } - world_instance_load_mdl( args.instance, mdl_path, args.heap ); + world_instance_load_mdl( _world.loader_instance, mdl_path, _world.loader_heap ); vg_async_call( async_world_loader_done, NULL, 0 ); vg_async_stall(); @@ -312,15 +331,13 @@ void async_start_player_from_worldsave( void *payload, u32 size ) } } -void load_player_from_world_savedata_thread( void *_args ) +void load_player_from_world_savedata_thread( void *_ ) { - struct world_load_args *args = _args; - vg_async_item *call = vg_async_alloc( sizeof(struct world_savedata_thread_data) ); struct world_savedata_thread_data *data = call->payload; - data->instance = args->instance; - skaterift_world_get_save_path( args->reg, data->save.path ); + data->instance = _world.loader_instance; + skaterift_world_get_save_path( _world.loader_reg, data->save.path ); savedata_file_read( &data->save ); vg_async_dispatch( call, async_start_player_from_worldsave ); @@ -329,31 +346,29 @@ void load_player_from_world_savedata_thread( void *_args ) void async_world_switcher_done( void *payload, u32 size ) { - _world.switch_to_addon = NULL; - g_client.unreadyness --; + _world.loader_reg = NULL; + + if( !_world.loader_preview_mode ) + g_client.unreadyness --; } void world_switcher_thread( void *_ ) { - struct world_load_args args = - { - .reg = _world.switch_to_addon, - .instance = &_world.main, - .heap = _world.heap - }; - - skaterift_world_load_thread( &args ); + skaterift_world_load_thread( NULL ); vg_async_stall(); - load_player_from_world_savedata_thread( &args ); - vg_async_stall(); + if( !_world.loader_preview_mode ) + { + load_player_from_world_savedata_thread( NULL ); + vg_async_stall(); + } vg_async_call( async_world_switcher_done, NULL, 0 ); } void world_switcher_update(void) { - if( !_world.switch_to_addon ) + if( !_world.loader_reg ) return; if( _world.loader_state == k_world_loader_saving_current ) @@ -389,6 +404,7 @@ void world_switcher_update(void) _skaterift_script_unlink_all_challenges(); world_instance_free_graphics_data( &_world.main ); + _world.main.complete = 0; _world.loader_state = k_world_loader_ready; vg_loader_set_user_information( "Waiting for loading thread" ); } @@ -400,13 +416,13 @@ void world_switcher_update(void) _world.loader_state = k_world_loader_loading; vg_linear_clear( vg_async.buffer ); - vg_linear_clear( _world.heap ); + vg_linear_clear( _world.loader_heap ); vg_loader_start( world_switcher_thread, NULL ); } } } -void skaterift_switch_world_start( addon_reg *reg ) +void skaterift_load_world_start( addon_reg *reg, bool preview ) { if( g_client.unreadyness ) { @@ -420,45 +436,58 @@ void skaterift_switch_world_start( addon_reg *reg ) return; } - if( _world.main.addon == reg ) - { - vg_warn( "World is already loaded\n" ); - return; - } + world_instance *world = preview? &_world.preview_instance: &_world.main; if( !reg ) { - if( _world.main.addon ) + if( world->addon ) { - reg = _world.main.addon; + reg = world->addon; } else { - vg_error( "Loaded world has no associated addon registration." - " Can't reload this!\n" ); + vg_error( "Loaded world has no associated addon registration, can't reload this!\n" ); return; } } - if( reg != _world.main.addon ) - _world.previous_world_addon = _world.main.addon; + if( !preview ) + { + if( reg != world->addon ) + _world.previous_world_addon = _world.main.addon; - g_client.unreadyness ++; - _world.loader_state = k_world_loader_saving_current; - vg_loader_set_user_information( "Saving current world" ); + g_client.unreadyness ++; + _world.loader_state = k_world_loader_saving_current; + vg_loader_set_user_information( "Saving current world" ); + } + else + _world.loader_state = k_world_loader_ready; char buf[76]; addon_alias_uid( ®->alias, buf ); - vg_info( "switching to: %s\n", buf ); + vg_info( "loading world: %s %s\n", buf, preview? "(preview mode)": "" ); vg_linear_clear( vg_mem.scratch ); /* ?? */ - world_fadeout_audio( &_world.main ); - _world.switch_to_addon = reg; + if( preview ) + { + if( world->complete ) + { + world_instance_free_graphics_data( world ); + world->complete = 0; + } + } + else + world_fadeout_audio( &_world.main ); + + _world.loader_reg = reg; + _world.loader_instance = world; + _world.loader_heap = preview? _world.preview_heap: _world.heap; + _world.loader_preview_mode = preview; } /* console command for the above function */ -int skaterift_switch_world_command( int argc, const char *argv[] ) +int skaterift_load_world_command( int argc, const char *argv[] ) { if( !vg_loader_availible() ) { @@ -466,14 +495,24 @@ int skaterift_switch_world_command( int argc, const char *argv[] ) return 0; } - if( argc == 1 ) + if( argc >= 1 ) { if( !strcmp( argv[0], "reload" ) ) { - skaterift_switch_world_start( NULL ); + skaterift_load_world_start( NULL, 0 ); return 0; } + bool preview = 0; + + if( argc >= 2 ) + { + if( !strcmp( argv[1], "preview" ) ) + { + preview = 1; + } + } + addon_alias q; addon_uid_to_alias( argv[0], &q ); @@ -481,7 +520,7 @@ int skaterift_switch_world_command( int argc, const char *argv[] ) if( reg_id != 0xffffffff ) { addon_reg *reg = get_addon_from_index( k_addon_type_world, reg_id, 0 ); - skaterift_switch_world_start( reg ); + skaterift_load_world_start( reg, preview ); } else { @@ -521,7 +560,8 @@ void world_instance_free_graphics_data( world_instance *world ) glDeleteTextures( 1, &world->tex_light_cubes ); /* delete textures and meshes */ - glDeleteTextures( world->texture_count-1, world->textures+1 ); + if( world->texture_count ) + glDeleteTextures( world->texture_count-1, world->textures+1 ); for( u32 i=0; ient_cubemap); i++ ) { @@ -531,7 +571,8 @@ void world_instance_free_graphics_data( world_instance *world ) glDeleteRenderbuffers( 1, &cm->renderbuffer_id ); } - glDeleteTextures( world->nonlocal_gate_count, world->nonlocal_gates_cubemaps ); + if( world->nonlocal_gate_count ) + glDeleteTextures( world->nonlocal_gate_count, world->nonlocal_gates_cubemaps ); } /* @@ -586,4 +627,9 @@ void world_init_blank( world_instance *world ) v3_copy( (v3f){0.25f, 0.17f, 0.51f}, state->g_sunset_ambient ); v3_copy( (v3f){1.000f, 0.809f, 0.318f}, state->g_sun_colour ); #endif + + world->tbo_light_entities = 0; + world->tex_light_entities = 0; + world->tex_light_cubes = 0; + world->nonlocal_gates_cubemaps = NULL; } diff --git a/src/world_load.h b/src/world_load.h index fbd9226..f175bd2 100644 --- a/src/world_load.h +++ b/src/world_load.h @@ -4,8 +4,8 @@ #include "world.h" #include "addon.h" -int skaterift_switch_world_command( int argc, const char *argv[] ); -void skaterift_switch_world_start( addon_reg *reg ); +int skaterift_load_world_command( int argc, const char *argv[] ); +void skaterift_load_world_start( addon_reg *reg, bool preview_mode ); void world_switcher_update(void); void world_switcher_thread( void *_ ); void world_instance_free_graphics_data( world_instance *world ); diff --git a/src/world_render.c b/src/world_render.c index 12b94fa..afcc357 100644 --- a/src/world_render.c +++ b/src/world_render.c @@ -12,6 +12,8 @@ #include "ent_skateshop.h" #include "shaders/model_entity.h" #include "shaders/model_sky_cubemap.h" +#include "shaders/scene_preview.h" +#include "shaders/scene_override.h" struct world_render world_render; @@ -760,8 +762,7 @@ static void bindpoint_terrain( world_instance *world, shader_scene_terrain_uSandColour( props->sand_colour ); } -static void bindpoint_override( world_instance *world, - struct world_surface *mat ) +static void bindpoint_override( world_instance *world, struct world_surface *mat ) { if( mat->info.flags & k_material_flag_collision ) { @@ -775,6 +776,17 @@ static void bindpoint_override( world_instance *world, } } +static void bindpoint_world_preview( world_instance *world, struct world_surface *mat ) +{ + if( mat->info.flags & k_material_flag_collision ) + { + } + else + { + } +} + + static void render_terrain( world_instance *world, vg_camera *cam ) { shader_scene_terrain_use(); @@ -1277,6 +1289,48 @@ void render_world_override( world_instance *world, render_world_fxglow( world, world, cam, mmdl, 0, 0, 1 ); } +void render_world_preview(void) +{ + world_instance *world = &_world.preview_instance; + struct world_pass pass = + { + .cam = &g_render.cam, + .fn_bind = bindpoint_world_preview, + .fn_set_mdl = shader_scene_preview_uMdl, + .fn_set_uPvmPrev = shader_scene_preview_uPvmPrev, + .fn_set_uNormalMtx = shader_scene_preview_uNormalMtx, + .shader = k_shader_override + }; + + shader_scene_preview_use(); + shader_scene_preview_uPv( pass.cam->mtx.pv ); + shader_scene_preview_uMapInfo((v4f){-1000.0f, 1000.0f, 0.0f, 0.0f}); + //shader_scene_preview_uMapInfo((v4f){world->tar_min, world->tar_max, 1.0f, 0.0f}); + + m4x3f mmdl; + m4x3_identity( mmdl ); + + m4x4f mpvm_prev; + m4x3_expand( mmdl, mpvm_prev ); + m4x4_mul( pass.cam->mtx_prev.pv, mpvm_prev, mpvm_prev ); + + m3x3f mnormal; + m3x3_inv( mmdl, mnormal ); + m3x3_transpose( mnormal, mnormal ); + v3_normalize( mnormal[0] ); + v3_normalize( mnormal[1] ); + v3_normalize( mnormal[2] ); + + glDisable( GL_CULL_FACE ); + mesh_bind( &world->mesh_geo ); + pass.geo_type = k_world_geo_type_solid; + render_world_override_pass( world, &pass, mmdl, mnormal, mpvm_prev ); + mesh_bind( &world->mesh_no_collide ); + pass.geo_type = k_world_geo_type_nonsolid; + render_world_override_pass( world, &pass, mmdl, mnormal, mpvm_prev ); + glEnable( GL_CULL_FACE ); +} + static void render_cubemap_side( world_instance *world, v3f co, m3x3f rotation, u32 side ) { vg_camera cam; diff --git a/src/world_render.h b/src/world_render.h index 8d512cb..6e6915b 100644 --- a/src/world_render.h +++ b/src/world_render.h @@ -83,6 +83,7 @@ void render_world_override( world_instance *world, m4x3f mmdl, vg_camera *cam, ent_spawn *dest_spawn, v4f map_info ); +void render_world_preview(void); void render_world_gates( world_instance *world, vg_camera *cam ); void imgui_world_light_edit( ui_context *ctx, world_instance *world );