From: hgn Date: Mon, 17 Feb 2025 20:03:07 +0000 (+0000) Subject: new world menu proto X-Git-Url: https://skaterift.com/git/?a=commitdiff_plain;h=2d2674602d600281436c822e79d701b086116978;p=carveJwlIkooP6JGAAIwe30JlM.git new world menu proto --- diff --git a/build.c b/build.c index 34245b5..cb72732 100644 --- a/build.c +++ b/build.c @@ -122,6 +122,7 @@ void build_shaders(void){ _S( "model_board_view", "model.vs", "model_character_view.fs" ); _S( "model_entity", "model.vs", "model_entity.fs" ); _S( "model_gate", "model.vs", "model_gate_lq.fs" ); + _S( "model_superworld", "model.vs", "model_superworld.fs" ); _S( "model_gate_unlinked", "model.vs", "model_gate_unlinked.fs" ); _S( "model_font", "model_font.vs", "model_font.fs" ); diff --git a/content_skaterift/maps/mp_spawn/main.mdl b/content_skaterift/maps/mp_spawn/main.mdl index 7f454e0..eefd82e 100644 Binary files a/content_skaterift/maps/mp_spawn/main.mdl and b/content_skaterift/maps/mp_spawn/main.mdl differ diff --git a/content_skaterift/models/rs_superworlds.mdl b/content_skaterift/models/rs_superworlds.mdl new file mode 100644 index 0000000..71733c5 Binary files /dev/null and b/content_skaterift/models/rs_superworlds.mdl differ diff --git a/content_skaterift/models/world_error.mdl b/content_skaterift/models/world_error.mdl new file mode 100644 index 0000000..4c97e37 Binary files /dev/null and b/content_skaterift/models/world_error.mdl differ diff --git a/shaders/model_superworld.fs b/shaders/model_superworld.fs new file mode 100644 index 0000000..e713e21 --- /dev/null +++ b/shaders/model_superworld.fs @@ -0,0 +1,27 @@ +out vec4 FragColor; + +uniform float uTime; +uniform vec3 uCam; +uniform vec4 uColour; + +in vec3 aNorm; +in vec2 aUv; +in vec3 aCo; +in vec3 aWorldCo; + +void main() +{ + vec2 ssuv = gl_FragCoord.xy; + float opacity = 1.0-smoothstep(0.0,1.0,aUv.y+uColour.a); + + vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), ssuv) ); + float dither = fract( vDither.g / 71.0 ) - 0.5; + + vec3 halfdir = normalize(aWorldCo - uCam); + float fresnel = pow(1.0 - dot(aNorm,-halfdir), 2.0); + + float fmap = fresnel+dither + (aUv.y-0.2)*0.2; + float f1bit = step(0.5,fmap); + + FragColor = vec4( mix( vec3(0.02,0.02,0.08), vec3( 0.3, 0.6, 0.94 ), f1bit ), 1.0 ); +} diff --git a/shaders/scene_override.fs b/shaders/scene_override.fs index ec2a89a..4561fe4 100644 --- a/shaders/scene_override.fs +++ b/shaders/scene_override.fs @@ -7,6 +7,7 @@ uniform vec4 uPlayerPos; /* w: distance to uSpawnPos */ uniform vec4 uSpawnPos; /* w: inverse distance to uPlayerPos */ uniform bool uAlphatest; uniform vec4 uMapInfo; /* x: min, y: max, z: iso line amount */ +uniform vec4 uSurfaceInfo; #include "light_clearskies_stddef.glsl" #include "common_scene.glsl" @@ -78,6 +79,8 @@ void main(){ vfrag *= 1.0f+(lg*0.2*uMapInfo.z); } + vfrag -= (1.0-uSurfaceInfo.x)*0.1; + oColour = vec4( vfrag, 1.0 ); //oColour = vec4( vfrag, 1.0 ); } diff --git a/shaders/scene_preview.fs b/shaders/scene_preview.fs index 0cc5ee0..e749699 100644 --- a/shaders/scene_preview.fs +++ b/shaders/scene_preview.fs @@ -5,6 +5,8 @@ in vec3 aWorldCo; uniform bool uAlphatest; uniform vec4 uMapInfo; /* x: min, y: max, z: iso line amount */ +uniform vec3 uCamera; +uniform vec4 uSurfaceInfo; /* x: skate surface flag */ layout (location = 0) out vec4 oColour; @@ -24,7 +26,6 @@ void main() compute_motion_vectors(); - vec3 vfrag = vec3(aUv.xy,0.0); vec3 qnorm = aNorm.xyz; qnorm = normalize(floor(aNorm.xyz*4.0)*0.25); @@ -38,5 +39,22 @@ void main() else{ } + if( aNorm.y < -0.2 ) discard; + + vec3 halfdir = normalize(aWorldCo - uCamera); + float fresnel = pow(qnorm.y,2.0)*0.5;//pow(1.0-dot(-halfdir,qnorm),1.0); + + vec3 grid = step(fract(aWorldCo/15.0),vec3(0.04)); + float fgrid = max(grid.x,grid.z)*pow(aNorm.y,2.0); + + vec3 vfrag = vec3(step(0.5,fresnel+dither));//vec3( step(grid,vec3(0.1)) ); + + float height_ramp = aWorldCo.y * 0.01; + float rando_uv = clamp(aUv.y,0.0,1.0); + + float fmap = fresnel+dither+fgrid+(uSurfaceInfo.x-0.5)*0.7; + float f1bit = step(0.5,fmap); + + vfrag = mix( vec3(0.1,0.1,0.2), vec3( 0.2, 0.4, 0.8 ), f1bit ); oColour = vec4( vfrag, 1.0 ); } diff --git a/src/addon.c b/src/addon.c index 5cfd075..ab80e9f 100644 --- a/src/addon.c +++ b/src/addon.c @@ -10,19 +10,31 @@ struct addon_system addon_system; -u32 addon_count( enum addon_type type, u32 ignoreflags ) +static bool addon_filter( addon_reg *reg, u32 whitelist, u32 blacklist ) { - if( ignoreflags ){ + if( whitelist && !(reg->flags & whitelist) ) + return 0; + + if( reg->flags & blacklist ) + return 0; + + return 1; +} + +u32 addon_count( enum addon_type type, u32 whitelist, u32 blacklist ) +{ + if( whitelist || blacklist ) + { u32 typecount = 0, count = 0; - for( u32 i=0; typecountalias.type == type ){ + if( reg->alias.type == type ) + { typecount ++; - if( reg->flags & ignoreflags ) - continue; - - count ++; + if( addon_filter( reg, whitelist, blacklist ) ) + count ++; } } @@ -34,38 +46,44 @@ u32 addon_count( enum addon_type type, u32 ignoreflags ) /* these kind of suck, oh well. */ -addon_reg *get_addon_from_index( enum addon_type type, u32 index, - u32 ignoreflags ) +addon_reg *get_addon_from_index( enum addon_type type, u32 index, u32 whitelist, u32 blacklist ) { u32 typecount = 0, count = 0; - for( u32 i=0; typecountalias.type == type ){ + if( reg->alias.type == type ) + { typecount ++; - if( reg->flags & ignoreflags ) - continue; - - if( index == count ) - return reg; + if( addon_filter( reg, whitelist, blacklist ) ) + { + if( index == count ) + return reg; - count ++; + count ++; + } } } return NULL; } -u32 get_index_from_addon( enum addon_type type, addon_reg *a ) +u32 get_index_from_addon( enum addon_type type, addon_reg *a, u32 whitelist, u32 blacklist ) { u32 count = 0; - for( u32 i=0; countalias.type == type ){ - if( reg == a ) - return count; + if( reg->alias.type == type ) + { + if( addon_filter( reg, whitelist, blacklist ) ) + { + if( reg == a ) + return count; - count ++; + count ++; + } } } @@ -279,9 +297,10 @@ static void addon_set_foldername( addon_reg *reg, const char name[64] ){ /* * Create a new registry */ -static addon_reg *addon_alloc_reg( PublishedFileId_t workshop_id, - enum addon_type type ){ - if( addon_system.registry_count == ADDON_MOUNTED_MAX ){ +static addon_reg *addon_alloc_reg( PublishedFileId_t workshop_id, enum addon_type type ) +{ + if( addon_system.registry_count == ADDON_MOUNTED_MAX ) + { vg_error( "You have too many addons installed!\n" ); return NULL; } @@ -294,10 +313,12 @@ static addon_reg *addon_alloc_reg( PublishedFileId_t workshop_id, reg->alias.foldername[0] = '\0'; reg->alias.type = type; - if( workshop_id ){ + if( workshop_id ) + { char foldername[64]; snprintf( foldername, 64, PRINTF_U64, workshop_id ); addon_set_foldername( reg, foldername ); + reg->flags |= ADDON_REG_WORKSHOP; } return reg; } @@ -352,15 +373,13 @@ static void addon_mount_finish( addon_reg *reg ){ /* * Mount a fully packaged addon, one that certainly has a addon.inf */ -static addon_reg *addon_mount_workshop_folder( PublishedFileId_t workshop_id, - vg_str folder_path ) +static addon_reg *addon_mount_workshop_folder( PublishedFileId_t workshop_id, vg_str folder_path ) { addon_reg *reg = addon_alloc_reg( workshop_id, k_addon_type_none ); if( !reg ) return NULL; - if( !addon_try_load_metadata( reg, folder_path ) ){ + if( !addon_try_load_metadata( reg, folder_path ) ) return NULL; - } enum addon_type type = k_addon_type_none; vg_msg msg; @@ -467,11 +486,14 @@ addon_reg *addon_mount_local_addon( const char *folder, */ void addon_mount_workshop_items(void) { - if( skaterift.demo_mode ){ + if( skaterift.demo_mode ) + { vg_info( "Won't load workshop items in demo mode\n" ); return; } - if( !steam_ready ) return; + + if( !steam_ready ) + return; /* * Steam workshop scan @@ -480,19 +502,20 @@ void addon_mount_workshop_items(void) PublishedFileId_t workshop_ids[ ADDON_MOUNTED_MAX ]; u32 workshop_count = ADDON_MOUNTED_MAX; - vg_async_item *call = vg_async_alloc( - sizeof(struct async_workshop_installed_files_info)); + vg_async_item *call = vg_async_alloc( sizeof(struct async_workshop_installed_files_info)); struct async_workshop_installed_files_info *info = call->payload; info->buffer = workshop_ids; info->len = &workshop_count; vg_async_dispatch( call, async_workshop_get_installed_files ); vg_async_stall(); - for( u32 j=0; jalias.workshop_id == id ) @@ -617,8 +640,9 @@ u16 addon_cache_fetch( enum addon_type type, u32 reg_index ) { addon_reg *reg = NULL; - if( reg_index < addon_count( type, 0 ) ){ - reg = get_addon_from_index( type, reg_index, 0 ); + if( reg_index < addon_count( type, 0,0 ) ) + { + reg = get_addon_from_index( type, reg_index, 0,0 ); if( reg->cache_id ) return reg->cache_id; } @@ -637,8 +661,8 @@ u16 addon_cache_alloc( enum addon_type type, u32 reg_index ) struct addon_cache_entry *new_entry = vg_pool_item( &cache->pool, new_id ); addon_reg *reg = NULL; - if( reg_index < addon_count( type, 0 ) ) - reg = get_addon_from_index( type, reg_index, 0 ); + if( reg_index < addon_count( type, 0,0 ) ) + reg = get_addon_from_index( type, reg_index, 0,0 ); if( new_entry ){ if( new_entry->reg_ptr ) @@ -788,7 +812,7 @@ static void T1_addon_cache_load_loop(void *_) vg_info( "process cache load request (%u#%u, reg:%u)\n", type, id, entry->reg_index ); - if( entry->reg_index >= addon_count(type,0) ) + if( entry->reg_index >= addon_count(type,0,0) ) { /* should maybe have a different value for this case */ entry->state = k_addon_cache_state_none; @@ -799,7 +823,7 @@ static void T1_addon_cache_load_loop(void *_) SDL_AtomicUnlock( &addon_system.sl_cache_using_resources ); /* continue with the request */ - addon_reg *reg = get_addon_from_index( type, entry->reg_index, 0 ); + addon_reg *reg = get_addon_from_index( type, entry->reg_index, 0,0 ); entry->reg_ptr = reg; vg_str folder; diff --git a/src/addon.h b/src/addon.h index db51af1..9cbfb68 100644 --- a/src/addon.h +++ b/src/addon.h @@ -20,6 +20,11 @@ struct addon_alias #define ADDON_REG_CITY 0x4 #define ADDON_REG_PREMIUM 0x8 +#define ADDON_REG_CAMPAIGN 0x10 +#define ADDON_REG_WORKSHOP 0x20 +#define ADDON_REG_VENUS 0x40 +#define ADDON_REG_INFINITE 0x80 + struct addon_system { struct addon_reg @@ -67,10 +72,9 @@ struct addon_system extern addon_system; void addon_system_init( void ); -u32 addon_count( enum addon_type type, u32 ignoreflags ); -addon_reg *get_addon_from_index( enum addon_type type, u32 index, - u32 ignoreflags ); -u32 get_index_from_addon( enum addon_type type, addon_reg *a ); +u32 addon_count( enum addon_type type, u32 whitelist, u32 blacklist ); +addon_reg *get_addon_from_index( enum addon_type type, u32 index, u32 whitelist, u32 blacklist ); +u32 get_index_from_addon( enum addon_type type, addon_reg *a, u32 whitelist, u32 blacklist ); int addon_get_content_folder( addon_reg *reg, vg_str *folder, int async); /* scanning routines */ diff --git a/src/ent_skateshop.c b/src/ent_skateshop.c index 0de8a03..edbc142 100644 --- a/src/ent_skateshop.c +++ b/src/ent_skateshop.c @@ -179,11 +179,13 @@ void skateshop_init(void) vg_async_call( skateshop_init_async, NULL, 0 ); } -static u16 skateshop_selected_cache_id(void){ - if( addon_count(k_addon_type_board, ADDON_REG_HIDDEN) ){ +static u16 skateshop_selected_cache_id(void) +{ + if( addon_count(k_addon_type_board, 0,ADDON_REG_HIDDEN) ) + { addon_reg *reg = get_addon_from_index( k_addon_type_board, global_skateshop.selected_board_id, - ADDON_REG_HIDDEN ); + 0, ADDON_REG_HIDDEN ); return reg->cache_id; } else return 0; @@ -271,9 +273,11 @@ void ent_skateshop_preupdate( ent_focus_context *ctx ) } } - u32 valid_count = addon_count( k_addon_type_board, 0 ); - if( button_down( k_srbind_mright ) ){ - if( global_skateshop.selected_board_id+1 < valid_count ){ + u32 valid_count = addon_count( k_addon_type_board, 0,0 ); + if( button_down( k_srbind_mright ) ) + { + if( global_skateshop.selected_board_id+1 < valid_count ) + { global_skateshop.selected_board_id ++; } } @@ -298,11 +302,12 @@ void ent_skateshop_preupdate( ent_focus_context *ctx ) return; } } - else if( shop->type == k_skateshop_type_charshop ){ + else if( shop->type == k_skateshop_type_charshop ) + { if( !vg_loader_availible() ) return; int changed = 0; - u32 valid_count = addon_count( k_addon_type_player, ADDON_REG_HIDDEN ); + u32 valid_count = addon_count( k_addon_type_player, 0, ADDON_REG_HIDDEN ); if( button_down( k_srbind_mleft ) ){ if( global_skateshop.selected_player_id > 0 ){ @@ -326,13 +331,11 @@ void ent_skateshop_preupdate( ent_focus_context *ctx ) changed = 1; } - if( changed ){ - addon_reg *addon = get_addon_from_index( - k_addon_type_player, global_skateshop.selected_player_id, - ADDON_REG_HIDDEN ); - - u32 real_id = get_index_from_addon( - k_addon_type_player, addon ); + if( changed ) + { + addon_reg *addon = get_addon_from_index( k_addon_type_player, global_skateshop.selected_player_id, + 0, ADDON_REG_HIDDEN ); + u32 real_id = get_index_from_addon( k_addon_type_player, addon,0,0 ); player__use_model( real_id ); } @@ -536,7 +539,7 @@ fade_out:; mlocal[3][2] = -0.7f; m4x3_mul( mrack, mlocal, mmdl ); - u32 valid_count = addon_count(k_addon_type_board,0); + u32 valid_count = addon_count(k_addon_type_board,0,0); if( valid_count ){ char buf[16]; vg_str str; @@ -623,7 +626,7 @@ static void skateshop_render_worldshop( ent_skateshop *shop ){ global_skateshop.render.world_title = "missing: workshop.title"; addon_reg *reg = get_addon_from_index( k_addon_type_world, - global_skateshop.selected_world_id, ADDON_REG_HIDDEN ); + global_skateshop.selected_world_id, 0, ADDON_REG_HIDDEN ); if( !reg ) goto none; @@ -658,7 +661,7 @@ none:; vg_strnull( &info, buftext, 128 ); vg_strnull( &subtext, bufsubtext, 128 ); - u32 valid_count = addon_count(k_addon_type_world,ADDON_REG_HIDDEN); + u32 valid_count = addon_count(k_addon_type_world,0,ADDON_REG_HIDDEN); if( valid_count ) { vg_strcati32( &info, global_skateshop.selected_world_id+1 ); @@ -674,7 +677,7 @@ none:; else { addon_reg *reg = get_addon_from_index( k_addon_type_world, - global_skateshop.selected_world_id, ADDON_REG_HIDDEN ); + global_skateshop.selected_world_id, 0, ADDON_REG_HIDDEN ); if( reg->alias.workshop_id ) vg_strcat( &subtext, "(Workshop) " ); diff --git a/src/font.h b/src/font.h index 3e225e8..af27a4c 100644 --- a/src/font.h +++ b/src/font.h @@ -16,6 +16,7 @@ enum efont_SRglyph{ k_SRglyph_ctrl_center = 0x03, /* useful when text is scaled down */ k_SRglyph_ctrl_baseline = 0x04, /* . */ k_SRglyph_ctrl_top = 0x05, /* . */ + k_SRglyph_ctrl_glow = 0x06, /* glow text */ k_SRglyph_mod_circle = 0x1e, /* surround and center next charater */ k_SRglyph_mod_square = 0x1f, /* surround and center next character */ k_SRglyph_ascii_min = 0x20, /* standard ascii */ diff --git a/src/input.h b/src/input.h index 3377824..ff912c1 100644 --- a/src/input.h +++ b/src/input.h @@ -25,6 +25,7 @@ enum sr_bind k_srbind_mback, k_srbind_maccept, k_srbind_mopen, + k_srbind_mclose, k_srbind_mhub, k_srbind_replay_play, k_srbind_replay_freecam, @@ -92,6 +93,7 @@ static vg_input_op *input_button_list[] = { [k_srbind_mdown] = INPUT_BASIC( SDLK_DOWN, SDL_CONTROLLER_BUTTON_DPAD_DOWN ), [k_srbind_mback] = INPUT_BASIC( SDLK_ESCAPE, SDL_CONTROLLER_BUTTON_B ), [k_srbind_mopen] = INPUT_BASIC( SDLK_ESCAPE, SDL_CONTROLLER_BUTTON_START ), +[k_srbind_mclose]= (vg_input_op[]){ vg_joy_button, SDL_CONTROLLER_BUTTON_START, vg_end }, [k_srbind_mhub] = INPUT_BASIC( SDLK_h, SDL_CONTROLLER_BUTTON_Y ), [k_srbind_maccept] = (vg_input_op[]){ vg_keyboard, SDLK_e, vg_gui_visible, 0, diff --git a/src/menu.c b/src/menu.c index b6fa197..b4abd2b 100644 --- a/src/menu.c +++ b/src/menu.c @@ -25,11 +25,52 @@ void menu_at_begin(void) void menu_init(void) { - vg_console_reg_var( "skip_starter_menu", &menu.skip_starter, - k_var_dtype_i32, VG_VAR_PERSISTENT ); + vg_console_reg_var( "skip_starter_menu", &menu.skip_starter, k_var_dtype_i32, VG_VAR_PERSISTENT ); vg_tex2d_load_qoi_async_file( "textures/prem.qoi", - VG_TEX2D_CLAMP|VG_TEX2D_NOMIP|VG_TEX2D_NEAREST, - &menu.prem_tex ); + VG_TEX2D_CLAMP|VG_TEX2D_NOMIP|VG_TEX2D_NEAREST, &menu.prem_tex ); +} + +static void menu_update_world_filter(void) +{ + menu.world_list_whitelist = 0; + menu.world_list_blacklist = 0;//ADDON_REG_HIDDEN; + + if( world_map.superworld_list_selected == k_superworld_campaign ) + menu.world_list_whitelist = ADDON_REG_CAMPAIGN; + else if( world_map.superworld_list_selected == k_superworld_infinite ) + menu.world_list_whitelist = ADDON_REG_INFINITE; + else if( world_map.superworld_list_selected == k_superworld_steam_workshop ) + menu.world_list_whitelist = ADDON_REG_WORKSHOP; + else if( world_map.superworld_list_selected == k_superworld_venus_moon ) + menu.world_list_whitelist = ADDON_REG_VENUS; +} + +void menu_figure_out_where_to_start_world_select( addon_reg *addon_reg ) +{ + if( addon_reg == NULL ) + return; + + i32 super_id = 0; + if( addon_reg->flags & ADDON_REG_CAMPAIGN ) super_id = k_superworld_campaign; + if( addon_reg->flags & ADDON_REG_INFINITE ) super_id = k_superworld_infinite; + if( addon_reg->flags & ADDON_REG_WORKSHOP ) super_id = k_superworld_steam_workshop; + if( addon_reg->flags & ADDON_REG_VENUS ) super_id = k_superworld_venus_moon; + + world_map.superworld_actual_world = super_id; + world_map.superworld_list_selected = super_id; + + menu_update_world_filter(); + u32 index = get_index_from_addon( k_addon_type_world, addon_reg, + menu.world_list_whitelist, menu.world_list_blacklist ); + menu.world_list_selected_index[ super_id ] = (index == 0xffffffff)? 0: index; + menu.clicked_world_reg = addon_reg; + + vg_msg msg; + vg_msg_init( &msg, addon_reg->metadata, addon_reg->metadata_len ); + const char *name = vg_msg_getkvstr( &msg, "location" ); + if( !name ) + name = addon_reg->alias.foldername; + menu.clicked_world_name = name; } void menu_open( enum menu_page page ) @@ -62,8 +103,7 @@ static void menu_decor_select( ui_context *ctx, ui_rect rect ) static void menu_standard_widget( ui_context *ctx, ui_rect inout_panel, ui_rect rect, ui_px s ) { - ui_split( inout_panel, k_ui_axis_h, ctx->font->sy*s*2, - 8, rect, inout_panel ); + ui_split( inout_panel, k_ui_axis_h, ctx->font->sy*s*2, 8, rect, inout_panel ); } static bool menu_slider( ui_context *ctx, @@ -309,20 +349,28 @@ static void menu_link_modal( const char *url ) menu.web_choice = 0; } -static void menu_update_world_list(void) +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 ); + menu_update_world_filter(); + menu.world_list_total_count = addon_count( k_addon_type_world, + menu.world_list_whitelist, menu.world_list_blacklist ); + menu.world_list_display_count = 0; - u32 selected_world_index = menu.world_list_selected_index, - page_base = (selected_world_index / MENU_WORLD_COUNT) * MENU_WORLD_COUNT; + i32 *selected_world_index = &menu.world_list_selected_index[ world_map.superworld_list_selected ]; + if( menu.world_list_total_count ) + { + if( *selected_world_index >= menu.world_list_total_count ) + { + vg_fatal_error( "World list index out of range! (%d >= %d)\n", + *selected_world_index, menu.world_list_total_count ); + } + } - menu.world_list_display_count = 0; + i32 max_display_count = menu.world_list_nominal_display_count; + if( max_display_count <= 0 ) max_display_count = 1; - for( u32 i=0; ifont = &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; } + menu.bg_blur = 0; goto menu_draw; } +#endif /* TOP BAR * -------------------------------------------------------------------*/ + VG_ASSERT( menu.page == k_menu_page_main ); + ctx->font = &vgf_default_title; ui_px height = ctx->font->ch + 16; ui_rect topbar = { 0, 0, vg.window_x, height }; @@ -736,8 +757,7 @@ void menu_gui( ui_context *ctx ) ui_outline( ctx, box, 1, GUI_COL_ACTIVE, 0 ); } else - ui_fill( ctx, box, - i==menu.main_index? GUI_COL_ACTIVE: GUI_COL_NORM ); + ui_fill( ctx, box, i==menu.main_index? GUI_COL_ACTIVE: GUI_COL_NORM ); ui_text( ctx, box, opts[i], 1, k_ui_align_middle_center, 0 ); } @@ -757,176 +777,443 @@ void menu_gui( ui_context *ctx ) } if( draw ) - ui_fill( ctx, - (ui_rect){ x+8,0, vg.window_x-(x+8),height }, GUI_COL_NORM ); + ui_fill( ctx, (ui_rect){ x+8,0, vg.window_x-(x+8),height }, GUI_COL_NORM ); else { x = vg.window_x/2 - x/2; - ui_fill( ctx, - (ui_rect){ 0, 0, x-8, height }, GUI_COL_NORM ); + ui_fill( ctx, (ui_rect){ 0, 0, x-8, height }, GUI_COL_NORM ); } } + bool menu_backable_to_exit = 1; + +/* PAGE map */ if( menu.main_index == k_menu_main_map ) { + menu_backable_to_exit = (vg_input.display_input_method == k_input_method_kbm); menu.bg_blur = 0; - ctx->font = &vgf_default_large; - ui_rect title = { vg.window_x/2- 512/2, height+8, 512, 64 }; - ui_px x = 8, - y = height+8; + ui_rect title_box = { vg.window_x/2 - 300/2, height + 8, 300, 100 }; - struct ui_vert *vs = ui_fill( ctx, (ui_rect){ x,y, 0,height }, GUI_COL_DARK ); + ui_rect upper_title, lower_title; + ui_split( title_box, k_ui_axis_h, title_box[3]-24, 0, upper_title, lower_title ); - char buf[64]; - vg_str str; - vg_strnull( &str, buf, sizeof(buf) ); + const char *title_text = NULL, + *subtitle_text = NULL; - world_instance *world = &_world.main; - const char *world_name = af_str( &world->meta.af, world->info.pstr_name ); - vg_strnull( &str, buf, sizeof(buf) ); - vg_strcat( &str, world_name ); - - ui_px w = ui_text( ctx, (ui_rect){ x+8, y, 1000, height }, buf, 1, - k_ui_align_middle_left, 0 ); + if( world_map.activity == k_map_activity_local_world ) + { + world_instance *world = &_world.main; + title_text = af_str( &world->meta.af, world->info.pstr_name ); + subtitle_text = "Current Location"; - w *= ctx->font->sx; - x += w + 16; + ctx->font = &vgf_default_title; + upper_title[2] = ui_text_line_width(ctx,title_text) + 24; + upper_title[0] = (vg.window_x - upper_title[2])/2; - vs[1].co[0] = x + 8; - vs[2].co[0] = x; - x = 8; - y += 8 + height; + /* main title (world location, world status) + * --------------------------------------------------------------------- + */ + bool go_to_super = 0; - ui_rect stat_panel = { x,y, 256,vg.window_y-y }; - u32 c0 = ui_opacity( GUI_COL_DARK, 0.36f ); - vs = ui_fill( ctx, stat_panel, c0 ); + ui_px back_box_size = 48; - ui_rect_pad( stat_panel, (ui_px[2]){8,0} ); + ctx->font = &vgf_default_title; + ui_rect back_box = { upper_title[0] - (back_box_size + 8), title_box[1] + ((title_box[3]-back_box_size)/2), + back_box_size, back_box_size }; + if( ui_button_text( ctx, back_box, "<", 1 ) == k_ui_button_click ) + { + go_to_super = 1; + } + + if( vg_input.display_input_method == k_input_method_controller ) + { + char buf[32]; + vg_str helper_text; + vg_strnull( &helper_text, buf, 32 ); + vg_input_string( &helper_text, input_button_list[k_srbind_mback], 1 ); + + ui_rect helper_label_box = { back_box[0] + (back_box[2]-32)/2, back_box[1] + back_box[3]-4, 32, 32 }; + ui_fill( ctx, helper_label_box, ui_opacity( GUI_COL_DARK, 0.36f ) ); + ui_text( ctx, helper_label_box, buf, 1, k_ui_align_middle_center, 0 ); + + if( button_down( k_srbind_mback ) ) + { + audio_lock(); + audio_oneshot( &audio_ui[3], 1.0f, 0.0f ); + audio_unlock(); + go_to_super = 1; + } + } + + ctx->font = &vgf_default_title; + ui_rect super_location_box = { back_box[0] - (120+8), back_box[1], 120, 32 }; + ui_text( ctx, super_location_box, "Earth", 1, k_ui_align_middle_center, ui_colour( ctx, k_ui_gray ) ); - for( u32 i=0; ient_region ); i ++ ) - { - ent_region *region = af_arritm( &world->ent_region, i ); - if( !region->zone_volume ) - continue; + if( go_to_super ) + { + world_map.activity = k_map_activity_galaxy; + menu_update_world_list(); + } - const char *title = af_str( &world->meta.af, region->pstr_title ); +#if 0 ctx->font = &vgf_default_large; + ui_rect title = { vg.window_x/2- 512/2, height+8, 512, 64 }; + + ui_px x = 8, + y = height+8; + + struct ui_vert *vs = ui_fill( ctx, (ui_rect){ x,y, 0,height }, GUI_COL_DARK ); + + char buf[64]; + vg_str str; + vg_strnull( &str, buf, sizeof(buf) ); - ui_rect title_box; - menu_standard_widget( ctx, stat_panel, title_box, 1 ); + world_instance *world = &_world.main; + const char *world_name = af_str( &world->meta.af, world->info.pstr_name ); + vg_strnull( &str, buf, sizeof(buf) ); + vg_strcat( &str, world_name ); - stat_panel[0] += 16; - stat_panel[2] -= 16; - ctx->font = &vgf_default_small; + ui_px w = ui_text( ctx, (ui_rect){ x+8, y, 1000, height }, buf, 1, + k_ui_align_middle_left, 0 ); - ent_volume *volume = af_arritm(&world->ent_volume, - mdl_entity_id_id(region->zone_volume)); + w *= ctx->font->sx; + x += w + 16; - u32 combined = k_ent_route_flag_achieve_gold | - k_ent_route_flag_achieve_silver; + vs[1].co[0] = x + 8; + vs[2].co[0] = x; - char buf[128]; - vg_str str; + x = 8; + y += 8 + height; + + ui_rect stat_panel = { x,y, 256,vg.window_y-y }; + u32 c0 = ui_opacity( GUI_COL_DARK, 0.36f ); + vs = ui_fill( ctx, stat_panel, c0 ); + + ui_rect_pad( stat_panel, (ui_px[2]){8,0} ); - for( u32 j=0; jent_route); j ++ ) + for( u32 i=0; ient_region ); i ++ ) { - ent_route *route = af_arritm(&world->ent_route, j ); + ent_region *region = af_arritm( &world->ent_region, i ); - v3f local; - m4x3_mulv( volume->to_local, route->board_transform[3], local ); - if( !((fabsf(local[0]) <= 1.0f) && - (fabsf(local[1]) <= 1.0f) && - (fabsf(local[2]) <= 1.0f)) ) - { + if( !region->zone_volume ) continue; + + const char *title = af_str( &world->meta.af, region->pstr_title ); + ctx->font = &vgf_default_large; + + ui_rect title_box; + menu_standard_widget( ctx, stat_panel, title_box, 1 ); + + stat_panel[0] += 16; + stat_panel[2] -= 16; + ctx->font = &vgf_default_small; + + ent_volume *volume = af_arritm(&world->ent_volume, + mdl_entity_id_id(region->zone_volume)); + + u32 combined = k_ent_route_flag_achieve_gold | + k_ent_route_flag_achieve_silver; + + char buf[128]; + vg_str str; + + for( u32 j=0; jent_route); j ++ ) + { + ent_route *route = af_arritm(&world->ent_route, j ); + + v3f local; + m4x3_mulv( volume->to_local, route->board_transform[3], local ); + if( !((fabsf(local[0]) <= 1.0f) && + (fabsf(local[1]) <= 1.0f) && + (fabsf(local[2]) <= 1.0f)) ) + { + continue; + } + + combined &= route->flags; + + vg_strnull( &str, buf, sizeof(buf) ); + vg_strcat( &str, "(Race) " ); + vg_strcat( &str, af_str( &world->meta.af, route->pstr_name )); + + if( route->flags & k_ent_route_flag_achieve_silver ) + vg_strcat( &str, " \xb3"); + if( route->flags & k_ent_route_flag_achieve_gold ) + vg_strcat( &str, "\xb3"); + + ui_rect r; + ui_standard_widget( ctx, stat_panel, r, 1 ); + ui_text( ctx, r, buf, 1, k_ui_align_middle_left, + medal_colour( ctx, route->flags ) ); + } + + for( u32 j=0; jent_challenge); j ++ ) + { + ent_challenge *challenge = af_arritm( &world->ent_challenge, j ); + + v3f local; + m4x3_mulv( volume->to_local, challenge->transform.co, local ); + if( !((fabsf(local[0]) <= 1.0f) && + (fabsf(local[1]) <= 1.0f) && + (fabsf(local[2]) <= 1.0f)) ) + { + continue; + } + + vg_strnull( &str, buf, sizeof(buf) ); + vg_strcat( &str, af_str( &world->meta.af,challenge->pstr_alias)); + + u32 flags = 0x00; + if( challenge->status ) + { + flags |= k_ent_route_flag_achieve_gold; + flags |= k_ent_route_flag_achieve_silver; + vg_strcat( &str, " \xb3\xb3" ); + } + + combined &= flags; + + ui_rect r; + ui_standard_widget( ctx, stat_panel, r, 1 ); + ui_text( ctx, r, buf, 1, + k_ui_align_middle_left, medal_colour( ctx, flags ) ); } - combined &= route->flags; + stat_panel[0] -= 16; + stat_panel[2] += 16; + + u32 title_col = 0; + if( combined & k_ent_route_flag_achieve_gold ) + title_col = ui_colour( ctx, k_ui_yellow ); + else if( combined & k_ent_route_flag_achieve_silver ) + title_col = ui_colour( ctx, k_ui_fg ); + + menu_heading( ctx, title_box, title, title_col ); + } + + vs[2].co[1] = stat_panel[1]; + vs[3].co[1] = stat_panel[1]; - vg_strnull( &str, buf, sizeof(buf) ); - vg_strcat( &str, "(Race) " ); - vg_strcat( &str, af_str( &world->meta.af, route->pstr_name )); + ui_rect back_button = {0,0,300,32}; + ui_rect_center( (ui_rect){0,0,vg.window_x,vg.window_y}, back_button ); + if( ui_button_text( ctx, back_button, "up", 1 ) == k_ui_button_click ) + { + world_map.activity = k_map_activity_ + } +#endif + } + else if( world_map.activity >= k_map_activity_galaxy ) + { + ui_rect panel = { 24, height+24, WORKSHOP_PREVIEW_WIDTH+8, vg.window_y-(height+24+24) }; + ui_fill( ctx, panel, ui_opacity( GUI_COL_DARK, 0.35f ) ); - if( route->flags & k_ent_route_flag_achieve_silver ) - vg_strcat( &str, " \xb3"); - if( route->flags & k_ent_route_flag_achieve_gold ) - vg_strcat( &str, "\xb3"); - ui_rect r; - ui_standard_widget( ctx, stat_panel, r, 1 ); - ui_text( ctx, r, buf, 1, k_ui_align_middle_left, - medal_colour( ctx, route->flags ) ); + title_text = menu.clicked_world_name? menu.clicked_world_name: "..."; + subtitle_text = (menu.clicked_world_reg == _world.main.addon)? "Current Location": NULL; + + ctx->font = &vgf_default_title; + upper_title[2] = ui_text_line_width(ctx,title_text) + 24; + upper_title[0] = panel[0]+panel[2] + ((vg.window_x - (panel[0]+panel[2])) - upper_title[2])/2; + lower_title[0] = panel[0]+panel[2] + 24; + lower_title[2] = (vg.window_x - (lower_title[0]+24)); + + + /* planet box + * -------------------------------------------------------------------------------------------------------- */ + ui_rect planet_box; + ui_split( panel, k_ui_axis_h, WORKSHOP_PREVIEW_HEIGHT, 8, planet_box, panel ); + + planet_box[0] += 4; + planet_box[2] = WORKSHOP_PREVIEW_WIDTH; + planet_box[3] = WORKSHOP_PREVIEW_HEIGHT; + ui_image( ctx, planet_box, &g_render.fb_workshop_preview->attachments[0].id ); + + ui_rect planet_box_title; + ui_split( planet_box, k_ui_axis_h, 28, 0, planet_box_title, planet_box ); + ui_fill( ctx, planet_box_title, ui_opacity( GUI_COL_DARK, 0.2f ) ); + ctx->font = &vgf_default_large; + ui_text( ctx, planet_box_title, _superworld_names[world_map.superworld_list_selected], 1, + k_ui_align_middle_center, ui_colour(ctx,k_ui_yellow) ); + + ui_px change_w = 48, + change_h = 160, + change_y = planet_box[1] + (planet_box[3]-80)/2; + + /* << */ + bool superworld_changed = 0; + ui_rect change_box_l = { panel[0], change_y, change_w, change_h }; + if( world_map.superworld_actual_world < world_map.superworld_list_selected ) + { + ui_rect helper_box = { change_box_l[0], planet_box_title[1]+planet_box_title[3], 300, 24 }; + ctx->font = &vgf_default_small; + ui_text( ctx, helper_box, "<< Current location", 1, k_ui_align_middle_left, ui_colour(ctx,k_ui_yellow) ); + } + ctx->font = &vgf_default_title; + if( menu_button( ctx, change_box_l, 0, world_map.superworld_list_selected > 0, "<" ) ) + { + world_map.superworld_list_selected --; + superworld_changed = 1; + } + + /* >> */ + ui_rect change_box_r = { (panel[0]+panel[2]) - change_w, change_y, change_w, change_h }; + if( world_map.superworld_actual_world > world_map.superworld_list_selected ) + { + ui_rect helper_box = { change_box_r[0] - 300, planet_box_title[1]+planet_box_title[3], 300, 24 }; + ctx->font = &vgf_default_small; + ui_text( ctx, helper_box, "Current location >>", 1, k_ui_align_middle_right, ui_colour(ctx,k_ui_yellow) ); + } + ctx->font = &vgf_default_title; + if( menu_button( ctx, change_box_r, 0, world_map.superworld_list_selected < k_superworld_max-1, ">" ) ) + { + world_map.superworld_list_selected ++; + superworld_changed = 1; } - for( u32 j=0; jent_challenge); j ++ ) + /* controller input */ + if( mh ) { - ent_challenge *challenge = af_arritm( &world->ent_challenge, j ); + i32 s = world_map.superworld_list_selected - mh; + if( s < 0 ) s = 0; + if( s > k_superworld_max -1 ) s = k_superworld_max -1; - v3f local; - m4x3_mulv( volume->to_local, challenge->transform.co, local ); - if( !((fabsf(local[0]) <= 1.0f) && - (fabsf(local[1]) <= 1.0f) && - (fabsf(local[2]) <= 1.0f)) ) + if( s != world_map.superworld_list_selected ) { - continue; + world_map.superworld_list_selected = s; + superworld_changed = 1; } + } - vg_strnull( &str, buf, sizeof(buf) ); - vg_strcat( &str, af_str( &world->meta.af,challenge->pstr_alias)); + /* World list + * -------------------------------------------------------------------------------------------- */ + ui_rect title; + ui_split( panel, k_ui_axis_h, 28, 0, title, panel ); + ctx->font = &vgf_default_large; + ui_text( ctx, title, "Locations", 1, k_ui_align_middle_center, 0 ); + + i32 nominal_count = ((panel[3]+8) / (ctx->font->sy*2 + 8)) - 2; + if( nominal_count > MENU_WORLD_MAX_COUNT ) + nominal_count = MENU_WORLD_MAX_COUNT; + if( nominal_count <= 0 ) + nominal_count = 1; + + if( superworld_changed || (nominal_count != menu.world_list_nominal_display_count) ) + { + menu.world_list_nominal_display_count = nominal_count; + menu_update_world_list(); + } + + i32 *selected_world_index = &menu.world_list_selected_index[ world_map.superworld_list_selected ], + page = (*selected_world_index) / menu.world_list_nominal_display_count, + page_base = page * menu.world_list_nominal_display_count, + max_page = (menu.world_list_total_count-1) / menu.world_list_nominal_display_count; + + i32 R = menu_nav( selected_world_index, mv, menu.world_list_total_count-1 ); + + + if( menu_button( ctx, panel, R == -999, page>0, "\x94" ) ) + *selected_world_index = (page-1)*menu.world_list_nominal_display_count; + + for( u32 i=0; ifont->sy*2, 8, sel_box, _null ); + ui_outline( ctx, sel_box, 2, ui_colour(ctx,k_ui_fg), 0 ); + } - u32 flags = 0x00; - if( challenge->status ) + if( menu_button( ctx, panel, R == (page_base + i), !selected, menu.world_list_names[i] ) ) { - flags |= k_ent_route_flag_achieve_gold; - flags |= k_ent_route_flag_achieve_silver; - vg_strcat( &str, " \xb3\xb3" ); + menu.clicked_world_reg = reg; + menu.clicked_world_name = menu.world_list_names[i]; } + } + + if( menu_button( ctx, panel, R == -999, page= (page_base+menu.world_list_nominal_display_count)) ) + { + menu_update_world_list(); + } - ui_rect r; - ui_standard_widget( ctx, stat_panel, r, 1 ); - ui_text( ctx, r, buf, 1, - k_ui_align_middle_left, medal_colour( ctx, flags ) ); + if( (_world.loader_state == k_world_loader_done) && (menu.clicked_world_reg) ) + { + bool do_load = 0; + + if( _world.preview_instance.complete ) + { + if( _world.preview_instance.addon != menu.clicked_world_reg ) + do_load = 1; + } + else + do_load = 1; + + if( do_load ) + skaterift_load_world_start( menu.clicked_world_reg, 1 ); } - stat_panel[0] -= 16; - stat_panel[2] += 16; + ctx->font = &vgf_default_title; + ui_px remainder = vg.window_x - (panel[0] + panel[2]), + width = 400, + height = ctx->font->sy*2; + + ui_rect enter_world_box = { panel[0] + panel[2] + (remainder-width)/2, vg.window_y - (height + 24), + width, height }; + + char buf[64]; + vg_str enter_helper; + vg_strnull( &enter_helper, buf, sizeof(buf) ); + vg_strcat( &enter_helper, "Enter location " ); + if( vg_input.display_input_method == k_input_method_controller ) + vg_input_string( &enter_helper, input_button_list[k_srbind_mhub], 1 ); - u32 title_col = 0; - if( combined & k_ent_route_flag_achieve_gold ) - title_col = ui_colour( ctx, k_ui_yellow ); - else if( combined & k_ent_route_flag_achieve_silver ) - title_col = ui_colour( ctx, k_ui_fg ); + bool enter_location = 0; + if( menu_button( ctx, enter_world_box, 0, menu.clicked_world_reg?1:0, buf ) ) + enter_location = 1; - menu_heading( ctx, title_box, title, title_col ); + if( button_down( k_srbind_mhub ) ) + enter_location = 1; + + if( enter_location && menu.clicked_world_reg ) + { + if( menu.clicked_world_reg != _world.main.addon ) + skaterift_load_world_start( menu.clicked_world_reg, 0 ); + + world_map.activity = k_map_activity_local_world; + world_map.superworld_actual_world = world_map.superworld_list_selected; + } } - vs[2].co[1] = stat_panel[1]; - vs[3].co[1] = stat_panel[1]; - } - else - { - if( button_down( k_srbind_mback ) ) + /* Render title & subtitle + * --------------------------------------------------------------------------------------------------- + */ + + ctx->font = &vgf_default_title; + ui_text( ctx, upper_title, title_text, 1, k_ui_align_middle_center, ui_colour( ctx, k_ui_yellow ) ); + + if( subtitle_text ) { - audio_lock(); - audio_oneshot( &audio_ui[3], 1.0f, 0.0f ); - audio_unlock(); - skaterift.activity = k_skaterift_default; - return; + ctx->font = &vgf_default_large; + ui_text( ctx, lower_title, subtitle_text, 1, k_ui_align_middle_center, 0 ); } - - ui_rect list0 = { vg.window_x/2 - 512/2, height+32, - 512, vg.window_y-height-64 }, list; + } + else /* menu.main_index != k_menu_main_map) */ + { + ui_rect list0 = { vg.window_x/2 - 512/2, height+32, 512, vg.window_y-height-64 }, list; rect_copy( list0, list ); ui_rect_pad( list, (ui_px[2]){8,8} ); - /* MAIN / MAIN - * -------------------------------------------------------------------*/ - +/* PAGE main */ if( menu.main_index == k_menu_main_main ) { i32 R = menu_nav( &menu.main_row, mv, 2 ); @@ -937,23 +1224,18 @@ void menu_gui( ui_context *ctx ) return; } - 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" ) ) + if( menu_button( ctx, list, R == 1, 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 == 3, 1, "Quit Game" ) ) + if( menu_button( ctx, end, R == 2, 1, "Quit Game" ) ) { vg.window_should_close = 1; } } +/* PAGE settings */ else if( menu.main_index == k_menu_main_settings ) { ui_fill( ctx, list0, ui_opacity( GUI_COL_DARK, 0.36f ) ); @@ -992,6 +1274,7 @@ void menu_gui( ui_context *ctx ) vg_settings_open(); } } +/* PAGE guide */ else if( menu.main_index == k_menu_main_guide ) { list0[0] = 8; @@ -1114,6 +1397,15 @@ void menu_gui( ui_context *ctx ) } } } + + if( button_down( k_srbind_mback ) && menu_backable_to_exit ) + { + audio_lock(); + audio_oneshot( &audio_ui[3], 1.0f, 0.0f ); + audio_unlock(); + srinput.state = k_input_state_resume; + skaterift.activity = k_skaterift_default; + } menu_draw: diff --git a/src/menu.h b/src/menu.h index be5cbbe..05f5928 100644 --- a/src/menu.h +++ b/src/menu.h @@ -1,10 +1,11 @@ #pragma once #define MENU_STACK_SIZE 8 -#define MENU_WORLD_COUNT 4 +#define MENU_WORLD_MAX_COUNT 10 #include "vg/vg_engine.h" #include "entity.h" +#include "world_map.h" enum menu_page { @@ -14,7 +15,6 @@ enum menu_page k_menu_page_main, k_menu_page_credits, k_menu_page_help, - k_menu_page_world_select }; enum menu_main_subpage @@ -49,12 +49,18 @@ struct global_menu GLuint prem_tex; - addon_reg *world_list_entries[ MENU_WORLD_COUNT ]; - const char *world_list_names[ MENU_WORLD_COUNT ]; + addon_reg *world_list_entries[ MENU_WORLD_MAX_COUNT ]; + const char *world_list_names[ MENU_WORLD_MAX_COUNT ]; i32 world_list_display_count, world_list_total_count, - world_list_selected_index; + world_list_selected_index[ k_superworld_max ], + world_list_nominal_display_count; + u32 world_list_whitelist, + world_list_blacklist; + + addon_reg *clicked_world_reg; + const char *clicked_world_name; } extern menu; @@ -63,3 +69,6 @@ void menu_at_begin(void); void menu_gui( ui_context *ctx ); void menu_open( enum menu_page page ); bool menu_viewing_map(void); +bool menu_viewing_preview(void); +void menu_update_world_list(void); +void menu_figure_out_where_to_start_world_select( addon_reg *addon_reg ); diff --git a/src/player.c b/src/player.c index 473c147..9e3f0c9 100644 --- a/src/player.c +++ b/src/player.c @@ -209,7 +209,7 @@ void player__pass_gate( u32 id ) _world.nonlocal_destination_key, 32, k_strncpy_overflow_fatal ); - addon_reg *reg = get_addon_from_index( k_addon_type_world, gate->addon_reg, 0 ); + addon_reg *reg = get_addon_from_index( k_addon_type_world, gate->addon_reg, 0,0 ); skaterift_load_world_start( reg, 0 ); return; } diff --git a/src/save.c b/src/save.c index 432f341..4b4f125 100644 --- a/src/save.c +++ b/src/save.c @@ -212,8 +212,8 @@ void skaterift_load_mainsave(void) vg_msg_getkvintg( &kvsav, "ach", k_vg_msg_u32, &ach, NULL ); skaterift.achievements |= ach; - u32 board_reg_id = time(NULL) % addon_count( k_addon_type_board, 0 ), - player_reg_id = (time(NULL)+44) % addon_count( k_addon_type_player, 0 ); + u32 board_reg_id = time(NULL) % addon_count( k_addon_type_board, 0,0 ), + player_reg_id = (time(NULL)+44) % addon_count( k_addon_type_player, 0,0 ); vg_msg_cursor orig = kvsav.cur; if( vg_msg_seekframe( &kvsav, "player" ) ) @@ -244,7 +244,7 @@ void skaterift_load_mainsave(void) reg_id = addon_match( &q ); if( reg_id != 0xffffffff ) { - _world.loader_reg = 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,0 ); } else { diff --git a/src/skaterift.c b/src/skaterift.c index 590282b..e4cb625 100644 --- a/src/skaterift.c +++ b/src/skaterift.c @@ -77,12 +77,12 @@ 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", 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_heaven", ADDON_REG_CAMPAIGN | ADDON_REG_HIDDEN ); + skaterift_mount_world_unloadable( "maps/mp_spawn", ADDON_REG_CAMPAIGN | ADDON_REG_CITY|ADDON_REG_PREMIUM ); + skaterift_mount_world_unloadable( "maps/mp_mtzero", ADDON_REG_CAMPAIGN | ADDON_REG_MTZERO|ADDON_REG_PREMIUM ); + skaterift_mount_world_unloadable( "maps/dev_tutorial",ADDON_REG_CAMPAIGN ); skaterift_mount_world_unloadable( "maps/dev_flatworld", ADDON_REG_HIDDEN ); - skaterift_mount_world_unloadable( "maps/mp_line1", ADDON_REG_PREMIUM ); + skaterift_mount_world_unloadable( "maps/mp_line1", ADDON_REG_CAMPAIGN | ADDON_REG_PREMIUM ); } static void skaterift_load_player_content(void) @@ -119,6 +119,7 @@ void game_load(void) vg_loader_step( addon_system_init, NULL ); vg_loader_step( workshop_init, NULL ); vg_loader_step( skateshop_init, NULL ); + vg_loader_step( world_map_init, NULL ); vg_loader_step( ent_tornado_init, NULL ); vg_loader_step( skaterift_replay_init, NULL ); vg_loader_step( skaterift_load_player_content, NULL ); @@ -152,8 +153,10 @@ void game_load(void) vg_warn( "Falling back to default hub world...\n" ); _world.loader_reg = _world.default_hub_addon; } + menu_figure_out_where_to_start_world_select( _world.loader_reg ); world_switcher_thread( NULL ); + /* add autosave function to exit list */ vg_loader_step( NULL, skaterift_autosave_synchronous ); } @@ -292,7 +295,7 @@ static void render_player_transparent(void) small_cam.farz = 60.0f; vg_camera_update_view( &small_cam ); - vg_camera_update_projection( &small_cam ); + vg_camera_update_projection( &small_cam, vg.window_x, vg.window_y ); vg_camera_finalize( &small_cam ); /* Draw player to window buffer and blend background ontop */ @@ -304,59 +307,6 @@ static void render_player_transparent(void) static void render_scene(void) { - /* Draw world */ - glEnable( GL_DEPTH_TEST ); - - world_prerender( &_world.main ); - - if( menu_viewing_map() ) - { - world_instance *world = &_world.main; - glDrawBuffers( 1, (GLenum[]){ GL_COLOR_ATTACHMENT0 } ); - - v3f bg; - v3_muls( world->ub_lighting.g_daysky_colour, - world->ub_lighting.g_day_phase - - world->ub_lighting.g_sunset_phase*0.1f, bg ); - - v3_muladds( bg, world->ub_lighting.g_sunset_colour, - (1.0f-0.5f)*world->ub_lighting.g_sunset_phase, bg ); - - v3_muladds( bg, world->ub_lighting.g_nightsky_colour, - (1.0f-world->ub_lighting.g_day_phase), bg ); - - glClearColor( bg[0], bg[1], bg[2], 0.0f ); - glClear( GL_COLOR_BUFFER_BIT ); - glDrawBuffers( 2, (GLenum[]){ GL_COLOR_ATTACHMENT0, - GL_COLOR_ATTACHMENT1 } ); - - m4x3f identity; - m4x3_identity( identity ); - render_world_override( world, world, identity, &g_render.cam, - world_map.close_spawn, - (v4f){world->tar_min, world->tar_max, 1.0f, 0.0f}); - render_world_routes( world, world, identity, &g_render.cam, 0, 1 ); - return; - } - - 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 ); - particle_system_prerender( &particles_grind ); - particle_system_render( &particles_grind, &g_render.cam ); - - ent_tornado_pre_update(); - particle_system_update( &particles_env, vg.time_delta ); - particle_system_prerender( &particles_env ); - particle_system_render( &particles_env, &g_render.cam ); - - player_glide_render_effects( &g_render.cam ); } m4x3f *_TEMP_VAR = NULL; @@ -400,17 +350,6 @@ static void skaterift_composite_maincamera(void) g_render.cam.farz = 3100.0f; } - if( global_miniworld.transition ){ - f32 dt = vg.time_frame_delta / 2.0f, - s = vg_signf( global_miniworld.transition ); - global_miniworld.t += s * dt; - - if( (global_miniworld.t > 1.0f) || (global_miniworld.t < 0.0f) ){ - global_miniworld.t = vg_clampf( global_miniworld.t, 0.0f, 1.0f ); - global_miniworld.transition = 0; - } - } - ent_camera *cs_cam = _cutscene_active_camera(); if( cs_cam ) ent_camera_unpack( cs_cam, &g_render.cam ); @@ -423,7 +362,7 @@ static void skaterift_composite_maincamera(void) _TEMP_VAR = NULL; } vg_camera_update_view( &g_render.cam ); - vg_camera_update_projection( &g_render.cam ); + vg_camera_update_projection( &g_render.cam, vg.window_x, vg.window_y ); vg_camera_finalize( &g_render.cam ); } @@ -454,8 +393,9 @@ static void render_main_game(void) skaterift_composite_maincamera(); - /* --------------------------------------------------------------------- */ - if( !menu_viewing_map() ) + bool render_actual_game = !menu_viewing_map(); + + if( render_actual_game ) { world_instance *world = &_world.main; render_world_cubemaps( world ); @@ -466,33 +406,68 @@ static void render_main_game(void) glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT ); - render_scene(); + if( render_actual_game ) + { + /* Draw world */ + glEnable( GL_DEPTH_TEST ); + world_prerender( &_world.main ); + +#if 0 + if( menu_viewing_preview() ) + { + glClearColor( 0.1f, 0.1f, 0.2f, 0.0f ); + glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT ); + + if( _world.preview_instance.complete ) + render_world_preview(); + + return; + } +#endif + + render_world( &_world.main, &g_render.cam, 0, 0, 1, 1 ); + + particle_system_update( &particles_grind, vg.time_delta ); + //particle_system_debug( &particles_grind ); + particle_system_prerender( &particles_grind ); + particle_system_render( &particles_grind, &g_render.cam ); + + ent_tornado_pre_update(); + particle_system_update( &particles_env, vg.time_delta ); + particle_system_prerender( &particles_env ); + particle_system_render( &particles_env, &g_render.cam ); + + player_glide_render_effects( &g_render.cam ); + } + else + { + render_world_map(); + } + glEnable( GL_DEPTH_TEST ); /* full res target */ glBindFramebuffer( GL_FRAMEBUFFER, 0 ); glViewport( 0,0, vg.window_x, vg.window_y ); - render_player_transparent(); /* needs to read the depth buffer before we fuck - it up with the oblique rendering inside the - portals */ - - /* continue with variable rate */ - if( !global_miniworld.transition && !menu_viewing_map() ) + if( render_actual_game ) { + render_player_transparent(); /* needs to read the depth buffer before we fuck + it up with the oblique rendering inside the + portals */ + + /* continue with variable rate */ vg_framebuffer_bind( g_render.fb_main, k_render_scale ); render_world_gates( &_world.main, &g_render.cam ); } /* composite */ - if( (skaterift.activity == k_skaterift_menu) && menu.bg_blur ) - v2_muls( (v2f){ 0.04f, 0.001f }, 1.0f-skaterift.time_rate, - g_render.blur_override ); + v2_muls( (v2f){ 0.04f, 0.001f }, 1.0f-skaterift.time_rate, g_render.blur_override ); else v2_zero( g_render.blur_override ); - postprocess_to_screen( g_render.fb_main ); + postprocess_to_screen( g_render.fb_main ); skaterift_replay_post_render(); control_overlay_render(); } @@ -560,6 +535,10 @@ void vg_gui( ui_context *ctx ) } } +void vg_framebuffer_resize( int w, int h ) +{ +} + #include "addon.c" #include "addon_types.c" #include "audio.c" diff --git a/src/workshop.c b/src/workshop.c index 6399c46..8b27a42 100644 --- a/src/workshop.c +++ b/src/workshop.c @@ -961,7 +961,7 @@ static void workshop_render_player_preview(void) vg_camera_update_transform( &cam ); vg_camera_update_view( &cam ); - vg_camera_update_projection( &cam ); + vg_camera_update_projection( &cam, WORKSHOP_PREVIEW_WIDTH, WORKSHOP_PREVIEW_HEIGHT ); vg_camera_finalize( &cam ); render_playermodel( &cam, &_world.main, 0, @@ -1035,7 +1035,7 @@ static void workshop_render_board_preview(void) vg_camera_update_transform( &cam ); vg_camera_update_view( &cam ); - vg_camera_update_projection( &cam ); + vg_camera_update_projection( &cam, WORKSHOP_PREVIEW_WIDTH, WORKSHOP_PREVIEW_HEIGHT ); vg_camera_finalize( &cam ); m4x3f mmdl, mmdl1; diff --git a/src/world_entity.c b/src/world_entity.c index 3c5eed2..7ded96b 100644 --- a/src/world_entity.c +++ b/src/world_entity.c @@ -211,7 +211,7 @@ void world_gen_entities_init( world_instance *world ) { if( gate->addon_reg != 0xffffffff ) { - addon_reg *reg = get_addon_from_index( k_addon_type_world, gate->addon_reg, 0 ); + addon_reg *reg = get_addon_from_index( k_addon_type_world, gate->addon_reg, 0,0 ); char cubemap_path[256]; nonlocal_gate_cubemap_path( reg, af_str( &world->meta.af, gate->key ), cubemap_path ); diff --git a/src/world_gate.c b/src/world_gate.c index f8fb4fb..d7faf6f 100644 --- a/src/world_gate.c +++ b/src/world_gate.c @@ -147,7 +147,7 @@ int render_gate( world_instance *world, world_instance *world_inside, m4x3_mul( gate->transport, cam->transform, world_gates.cam.transform ); vg_camera_update_view( &world_gates.cam ); - vg_camera_update_projection( &world_gates.cam ); + vg_camera_update_projection( &world_gates.cam, vg.window_x, vg.window_y ); /* Add special clipping plane to projection */ v4f surface; @@ -408,7 +408,7 @@ void world_link_gates_async( void *payload, u32 size ) if( !(_world.copy_of_nonlocal_sender.flags & k_ent_gate_no_linkback) ) { - gate->addon_reg = get_index_from_addon( k_addon_type_world, _world.previous_world_addon ); + gate->addon_reg = get_index_from_addon( k_addon_type_world, _world.previous_world_addon,0,0 ); if( gate->addon_reg != 0xffffffff ) { diff --git a/src/world_load.c b/src/world_load.c index ba69fcc..bb87551 100644 --- a/src/world_load.c +++ b/src/world_load.c @@ -46,8 +46,7 @@ static void world_instance_load_mdl( world_instance *world, const char *path, vo for( u32 i=0; ient_camera, i ) ); + fix_ent_camera_v107( af_arritm( &legacy_cameras, i ), af_arritm( &world->ent_camera, i ) ); } } #endif @@ -57,7 +56,12 @@ static void world_instance_load_mdl( world_instance *world, const char *path, vo 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_route, ent_route, heap ); + + if( load_all ) + { 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 ); @@ -279,7 +283,8 @@ void skaterift_world_load_thread( void *_ ) } else { - vg_fatal_error( "No .mdl files found in the map folder.\n" ); + vg_error( "No .mdl files found in the map folder!\n" ); + strcpy( mdl_path, "models/world_error.mdl" ); } world_instance_load_mdl( _world.loader_instance, mdl_path, _world.loader_heap ); @@ -519,7 +524,8 @@ int skaterift_load_world_command( int argc, const char *argv[] ) u32 reg_id = addon_match( &q ); if( reg_id != 0xffffffff ) { - addon_reg *reg = get_addon_from_index( k_addon_type_world, reg_id, 0 ); + addon_reg *reg = get_addon_from_index( k_addon_type_world, reg_id, 0,0 ); + menu_figure_out_where_to_start_world_select( reg ); skaterift_load_world_start( reg, preview ); } else @@ -531,9 +537,9 @@ int skaterift_load_world_command( int argc, const char *argv[] ) { vg_info( "worlds availible to load:\n" ); - for( int i=0; ialias, buf ); diff --git a/src/world_map.c b/src/world_map.c index 9752533..ced1cba 100644 --- a/src/world_map.c +++ b/src/world_map.c @@ -5,6 +5,7 @@ #include "gui.h" #include "menu.h" #include "scene.h" +#include "shaders/model_superworld.h" struct world_map world_map; @@ -40,8 +41,7 @@ static void respawn_world_to_plane_pos( v3f pos, v2f plane_pos ) plane_pos[1] = co[2]; } -static void respawn_map_draw_icon( vg_camera *cam, - enum gui_icon icon, v3f pos, f32 size ) +static void respawn_map_draw_icon( vg_camera *cam, enum gui_icon icon, v3f pos, f32 size ) { v4f v; v3_copy( pos, v ); @@ -54,6 +54,7 @@ static void respawn_map_draw_icon( vg_camera *cam, static void world_map_select_close(void) { +#if 0 world_map.sel_spawn = world_map.close_spawn; gui_helper_reset( k_gui_helper_mode_default ); @@ -62,15 +63,12 @@ static void world_map_select_close(void) vg_strcat( &text, "Spawn Here" ); if( gui_new_helper( input_button_list[k_srbind_mback], &text ) ) vg_strcat( &text, "Back" ); -} - -void world_map_click(void) -{ - world_map_select_close(); +#endif } static void world_map_help_normal(void) { +#if 0 gui_helper_reset( k_gui_helper_mode_default ); vg_str text; @@ -80,14 +78,22 @@ static void world_map_help_normal(void) if( gui_new_helper( input_button_list[k_srbind_maccept], &text ) ) vg_strcat( &text, "Select" ); +#if 0 if( gui_new_helper( input_button_list[k_srbind_mback], &text ) ) vg_strcat( &text, "Exit" ); +#endif +#endif } void world_map_pre_update(void) { if( menu_viewing_map() ) { + if( world_map.activity == k_map_activity_galaxy ) + { + return; + } + if( !world_map.view_ready ) { world_instance *world = &_world.main; @@ -118,6 +124,7 @@ void world_map_pre_update(void) v3f *bbx = world->scene_geo.bbx; f32 *pos = world_map.plane_pos; +#if 0 v2f steer; joystick_state( k_srjoystick_steer, steer ); v2_normalize_clamp( steer ); @@ -130,6 +137,7 @@ void world_map_pre_update(void) m2x2_mulv( rm, steer, steer ); v2_muladds( pos, steer, vg.time_frame_delta * 200.0f, pos ); } +#endif f32 bd_target = 400.0f, interp = vg.time_frame_delta*2.0f; @@ -168,7 +176,7 @@ void world_map_pre_update(void) vg_camera_update_transform( cam ); vg_camera_update_view( cam ); - vg_camera_update_projection( cam ); + vg_camera_update_projection( cam, vg.window_x, vg.window_y ); vg_camera_finalize( cam ); /* pick spawn */ @@ -194,6 +202,7 @@ void world_map_pre_update(void) spawn->transform.s[0] = d2; } +#if 0 if( button_down( k_srbind_maccept ) ) { if( world_map.sel_spawn ) @@ -216,13 +225,8 @@ void world_map_pre_update(void) world_map.sel_spawn = NULL; world_map_help_normal(); } - else - { - srinput.state = k_input_state_resume; - skaterift.activity = k_skaterift_default; - return; - } } +#endif /* icons * ---------------------*/ @@ -314,3 +318,155 @@ void world_map_pre_update(void) respawn_map_draw_icon( cam, k_gui_icon_glider, glider->transform.co, 1 ); } } + +void render_world_map(void) +{ + glEnable( GL_DEPTH_TEST ); + + if( world_map.activity == k_map_activity_local_world ) + { + world_instance *world = &_world.main; + world_prerender( world ); + + glDrawBuffers( 1, (GLenum[]){ GL_COLOR_ATTACHMENT0 } ); + + v3f bg; + v3_muls( world->ub_lighting.g_daysky_colour, + world->ub_lighting.g_day_phase - + world->ub_lighting.g_sunset_phase*0.1f, bg ); + + v3_muladds( bg, world->ub_lighting.g_sunset_colour, + (1.0f-0.5f)*world->ub_lighting.g_sunset_phase, bg ); + + v3_muladds( bg, world->ub_lighting.g_nightsky_colour, + (1.0f-world->ub_lighting.g_day_phase), bg ); + + glClearColor( bg[0], bg[1], bg[2], 0.0f ); + glClear( GL_COLOR_BUFFER_BIT ); + glDrawBuffers( 2, (GLenum[]){ GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 } ); + + m4x3f identity; + m4x3_identity( identity ); + render_world_override( world, world, identity, &g_render.cam, + world_map.close_spawn, + (v4f){world->tar_min, world->tar_max, 1.0f, 0.0f}); + render_world_routes( world, world, identity, &g_render.cam, 0, 1 ); + } + else + { + glDrawBuffers( 1, (GLenum[]){ GL_COLOR_ATTACHMENT0 } ); + glClearColor( 0.1f,0.1f,0.2f, 0.0f ); + glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT ); + + if( _world.preview_instance.complete ) + { + world_instance *world = &_world.preview_instance; + vg_camera cam; + v3f dir; + dir[0] = -sqrtf(0.5f); + dir[2] = sqrtf(0.5f); + dir[1] = 1.0f; + v3_normalize(dir); + + v3f centroid; + v3_add( world->scene_geo.bbx[0], world->scene_geo.bbx[1], centroid ); + v3_muls( centroid, 0.5f, centroid ); + v3_muladds( centroid, dir, 900.0f, cam.pos ); + + f32 t = vg.time_real * 0.1; + + v3f ofs = { + vg_perlin_fract_1d( t, 2.0f, 2, 300 ), + vg_perlin_fract_1d( t+43.5f, 2.0f, 2, 301 ), + vg_perlin_fract_1d( t+80.2f, 2.0f, 2, 302 ), + }; + + v3_muladds( cam.pos, ofs, 40.0f, cam.pos ); + + cam.angles[0] = 0.25f * VG_PIf + ofs[0]*0.1f; + cam.angles[1] = 0.25f * VG_PIf + ofs[1]*0.1f; + cam.angles[2] = ofs[2]*0.01f; + cam.farz = 5000.0f; + cam.nearz = 10.0f; + cam.fov = 40.0f; + + vg_camera_update_transform( &cam ); + vg_camera_update_view( &cam ); + vg_camera_update_projection( &cam, vg.window_x, vg.window_y ); + vg_camera_finalize( &cam ); + vg_camera_finalize( &cam ); + + render_world_preview( &cam ); + + if( world->complete ) + { + for( u32 i=0; ient_route); i++ ) + { + ent_route *route = af_arritm( &world->ent_route, i ); + + v4f colour; + v4_copy( route->colour, colour ); + v3_muls( colour, 1.6666f, colour ); + gui_icon_setcolour( colour ); + respawn_map_draw_icon( &cam, k_gui_icon_rift_run_2d, route->anon.transform.co, 0.5f ); + } + } + } + + vg_framebuffer_bind( g_render.fb_workshop_preview, 1.0f ); + glClearColor( 0.02f,0.02f,0.08f, 0.0f ); + glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT ); + + vg_camera cam, *smooth_cam = &world_map.superworld_cam; + ent_camera *cam_temp = af_arritm( &world_map.ent_camera, world_map.superworld_list_selected ); + ent_camera_unpack( cam_temp, &cam ); + + vg_camera_lerp( smooth_cam, &cam, vg.time_frame_delta * 6.0f, smooth_cam ); + vg_camera_update_transform( smooth_cam ); + vg_camera_update_view( smooth_cam ); + vg_camera_update_projection( smooth_cam, WORKSHOP_PREVIEW_WIDTH, WORKSHOP_PREVIEW_HEIGHT ); + vg_camera_finalize( smooth_cam ); + + shader_model_superworld_use(); + shader_model_superworld_uPv( smooth_cam->mtx.pv ); + shader_model_superworld_uCam( smooth_cam->pos ); + shader_model_superworld_uColour( (v4f){0.4f,0.8f,0.0f,0.0f} ); + shader_model_superworld_uTime( vg.time*0.25f ); + + mesh_bind( &world_map.superworld_mesh ); + mdl_context *model = &world_map.superworld_meta; + for( u32 i=0; imesh_count; i ++ ) + { + mdl_mesh *mesh = &model->meshes[i]; + + q_axis_angle( mesh->transform.q, (v3f){0,1,0}, vg.time_real*0.4f ); + + m4x3f mmdl; + mdl_transform_m4x3( &mesh->transform, mmdl ); + shader_model_superworld_uMdl( mmdl ); + + for( u32 j=0; jsubmesh_count; j ++ ) + { + mdl_submesh *submesh = &model->submeshes[ mesh->submesh_start + j ]; + mdl_draw_submesh( submesh ); + } + } + + glDrawBuffers( 2, (GLenum[]){ GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 } ); + } +} + +void world_map_init(void) +{ + mdl_context *model = &world_map.superworld_meta; + mdl_open( model, "models/rs_superworlds.mdl", vg_mem.rtmemory ); + mdl_load_metadata_block( model, vg_mem.rtmemory ); + mdl_async_load_glmesh( model, &world_map.superworld_mesh, NULL ); + AF_LOAD_ARRAY_STRUCT( &model->af, &world_map.ent_camera, ent_camera, vg_mem.rtmemory ); + AF_LOAD_ARRAY_STRUCT( &model->af, &world_map.ent_marker, ent_marker, vg_mem.rtmemory ); + mdl_close( model ); + + world_map.superworld_cam.nearz = 0.1f; + world_map.superworld_cam.farz = 250.0f; + world_map.superworld_cam.fov = 90.0f; +} diff --git a/src/world_map.h b/src/world_map.h index fc29d78..d78cd77 100644 --- a/src/world_map.h +++ b/src/world_map.h @@ -2,6 +2,14 @@ #include "vg/vg_platform.h" #include "vg/vg_camera.h" #include "world_entity.h" +enum superworld +{ + k_superworld_venus_moon = 0, + k_superworld_infinite, + k_superworld_campaign, + k_superworld_steam_workshop, + k_superworld_max +}; struct world_map { @@ -13,6 +21,35 @@ struct world_map vg_camera cam; bool view_ready; + + enum map_activity + { + k_map_activity_local_world, + k_map_activity_galaxy + } + activity; + + mdl_context superworld_meta; + glmesh superworld_mesh; + array_file_ptr ent_camera, + ent_marker, + ent_challenge; + + i32 superworld_list_selected, + superworld_actual_world; + + vg_camera superworld_cam; } extern world_map; void world_map_pre_update(void); +void render_world_map(void); +void world_map_init(void); + + +const char *_superworld_names[] = +{ + [k_superworld_venus_moon] = "One of Venus's moons", + [k_superworld_infinite] = "Infinite Dimension", + [k_superworld_campaign] = "Earth", + [k_superworld_steam_workshop] = "Steam Workshop Planet", +}; diff --git a/src/world_render.c b/src/world_render.c index afcc357..2206739 100644 --- a/src/world_render.c +++ b/src/world_render.c @@ -764,6 +764,9 @@ static void bindpoint_terrain( world_instance *world, static void bindpoint_override( world_instance *world, struct world_surface *mat ) { + f32 skate_surface = mat->info.flags & k_material_flag_skate_target? 1.0f: 0.0f; + shader_scene_override_uSurfaceInfo( (v4f){ skate_surface, 0,0,0 } ); + if( mat->info.flags & k_material_flag_collision ) { shader_scene_override_uAlphatest(0); @@ -778,6 +781,9 @@ static void bindpoint_override( world_instance *world, struct world_surface *mat static void bindpoint_world_preview( world_instance *world, struct world_surface *mat ) { + f32 skate_surface = mat->info.flags & k_material_flag_skate_target? 1.0f: 0.0f; + shader_scene_preview_uSurfaceInfo( (v4f){ skate_surface, 0,0,0 } ); + if( mat->info.flags & k_material_flag_collision ) { } @@ -1289,12 +1295,13 @@ void render_world_override( world_instance *world, render_world_fxglow( world, world, cam, mmdl, 0, 0, 1 ); } -void render_world_preview(void) +void render_world_preview( vg_camera *cam ) { world_instance *world = &_world.preview_instance; + struct world_pass pass = { - .cam = &g_render.cam, + .cam = cam, .fn_bind = bindpoint_world_preview, .fn_set_mdl = shader_scene_preview_uMdl, .fn_set_uPvmPrev = shader_scene_preview_uPvmPrev, @@ -1304,6 +1311,7 @@ void render_world_preview(void) shader_scene_preview_use(); shader_scene_preview_uPv( pass.cam->mtx.pv ); + shader_scene_preview_uCamera( pass.cam->pos ); 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}); @@ -1321,10 +1329,12 @@ void render_world_preview(void) v3_normalize( mnormal[1] ); v3_normalize( mnormal[2] ); - glDisable( GL_CULL_FACE ); + glEnable( 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 ); + + glDisable( GL_CULL_FACE ); mesh_bind( &world->mesh_no_collide ); pass.geo_type = k_world_geo_type_nonsolid; render_world_override_pass( world, &pass, mmdl, mnormal, mpvm_prev ); diff --git a/src/world_render.h b/src/world_render.h index 6e6915b..2f0437e 100644 --- a/src/world_render.h +++ b/src/world_render.h @@ -83,7 +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_preview( vg_camera *cam ); void render_world_gates( world_instance *world, vg_camera *cam ); void imgui_world_light_edit( ui_context *ctx, world_instance *world );