From: hgn Date: Tue, 18 Feb 2025 20:06:51 +0000 (+0000) Subject: yes menu X-Git-Url: https://harrygodden.com/git/?a=commitdiff_plain;h=0671b357c7fbe213649ebf101f8aee6677cc7e4f;p=carveJwlIkooP6JGAAIwe30JlM.git yes menu --- diff --git a/content_skaterift/models/rs_icons.mdl b/content_skaterift/models/rs_icons.mdl index ecbe3bc..a9ada53 100644 Binary files a/content_skaterift/models/rs_icons.mdl and b/content_skaterift/models/rs_icons.mdl differ diff --git a/src/gui.h b/src/gui.h index dc38d32..93a4613 100644 --- a/src/gui.h +++ b/src/gui.h @@ -23,6 +23,7 @@ enum gui_icon { k_gui_icon_rift_run_2d, k_gui_icon_friend, k_gui_icon_player, + k_gui_icon_player2d, k_gui_icon_rift_run_gold, k_gui_icon_rift_run_silver, k_gui_icon_glider, @@ -313,6 +314,7 @@ static void gui_init(void) gui.icons[ k_gui_icon_rift_run_2d ] = gui_find_icon( "icon_rift_run2d" ); gui.icons[ k_gui_icon_friend ] = gui_find_icon( "icon_friend" ); gui.icons[ k_gui_icon_player ] = gui_find_icon( "icon_player" ); + gui.icons[ k_gui_icon_player2d ] = gui_find_icon( "icon_player2d" ); gui.icons[ k_gui_icon_glider ] = gui_find_icon( "icon_glider" ); gui.icons[ k_gui_icon_spawn ] = gui_find_icon( "icon_spawn" ); gui.icons[ k_gui_icon_spawn_select ] = gui_find_icon( "icon_spawn_select" ); diff --git a/src/menu.c b/src/menu.c index b4abd2b..692ffe3 100644 --- a/src/menu.c +++ b/src/menu.c @@ -45,7 +45,7 @@ static void menu_update_world_filter(void) menu.world_list_whitelist = ADDON_REG_VENUS; } -void menu_figure_out_where_to_start_world_select( addon_reg *addon_reg ) +void menu_on_world_change( addon_reg *addon_reg ) { if( addon_reg == NULL ) return; @@ -71,6 +71,8 @@ void menu_figure_out_where_to_start_world_select( addon_reg *addon_reg ) if( !name ) name = addon_reg->alias.foldername; menu.clicked_world_name = name; + + world_map_initialize_view(); } void menu_open( enum menu_page page ) @@ -153,12 +155,8 @@ static bool menu_slider( ui_context *ctx, return (state & mask_using) && 1; } -static bool menu_button( ui_context *ctx, - ui_rect inout_panel, bool select, bool clickable, const char *text ) +bool menu_button_rect( ui_context *ctx, ui_rect rect, bool select, bool clickable, const char *text ) { - ui_rect rect; - menu_standard_widget( ctx, inout_panel, rect, 1 ); - enum ui_button_state state = k_ui_button_none; if( vg_input.display_input_method == k_input_method_controller ) @@ -222,6 +220,13 @@ static bool menu_button( ui_context *ctx, else return 0; } +static bool menu_button( ui_context *ctx, ui_rect inout_panel, bool select, bool clickable, const char *text ) +{ + ui_rect rect; + menu_standard_widget( ctx, inout_panel, rect, 1 ); + return menu_button_rect( ctx, rect, select, clickable, text ); +} + static bool menu_checkbox( ui_context *ctx, ui_rect inout_panel, bool select, const char *str_label, i32 *data ) { @@ -793,419 +798,7 @@ void menu_gui( ui_context *ctx ) menu_backable_to_exit = (vg_input.display_input_method == k_input_method_kbm); menu.bg_blur = 0; - ui_rect title_box = { vg.window_x/2 - 300/2, height + 8, 300, 100 }; - - ui_rect upper_title, lower_title; - ui_split( title_box, k_ui_axis_h, title_box[3]-24, 0, upper_title, lower_title ); - - const char *title_text = NULL, - *subtitle_text = NULL; - - 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"; - - 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; - - - /* main title (world location, world status) - * --------------------------------------------------------------------- - */ - bool go_to_super = 0; - - ui_px back_box_size = 48; - - 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 ) ); - - - if( go_to_super ) - { - world_map.activity = k_map_activity_galaxy; - menu_update_world_list(); - } - -#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) ); - - 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 ); - - w *= ctx->font->sx; - x += w + 16; - - vs[1].co[0] = x + 8; - vs[2].co[0] = x; - - 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 i=0; ient_region ); i ++ ) - { - ent_region *region = af_arritm( &world->ent_region, i ); - - 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 ) ); - } - - 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]; - - 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 ) ); - - - 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; - } - - /* controller input */ - if( mh ) - { - i32 s = world_map.superworld_list_selected - mh; - if( s < 0 ) s = 0; - if( s > k_superworld_max -1 ) s = k_superworld_max -1; - - if( s != world_map.superworld_list_selected ) - { - world_map.superworld_list_selected = s; - superworld_changed = 1; - } - } - - /* 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 ); - } - - if( menu_button( ctx, panel, R == (page_base + i), !selected, menu.world_list_names[i] ) ) - { - 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(); - } - - 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 ); - } - - 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 ); - - bool enter_location = 0; - if( menu_button( ctx, enter_world_box, 0, menu.clicked_world_reg?1:0, buf ) ) - enter_location = 1; - - 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; - } - } - - /* 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 ) - { - ctx->font = &vgf_default_large; - ui_text( ctx, lower_title, subtitle_text, 1, k_ui_align_middle_center, 0 ); - } + world_map_gui( ctx, (ui_rect){ 0, height, vg.window_x, vg.window_y - height }, mh, mv, &menu_backable_to_exit ); } else /* menu.main_index != k_menu_main_map) */ { diff --git a/src/menu.h b/src/menu.h index 05f5928..f8a96a0 100644 --- a/src/menu.h +++ b/src/menu.h @@ -71,4 +71,5 @@ 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 ); +void menu_on_world_change( addon_reg *addon_reg ); +bool menu_button_rect( ui_context *ctx, ui_rect rect, bool select, bool clickable, const char *text ); diff --git a/src/skaterift.c b/src/skaterift.c index e4cb625..0bee2f3 100644 --- a/src/skaterift.c +++ b/src/skaterift.c @@ -76,7 +76,7 @@ static addon_reg *skaterift_mount_world_unloadable( const char *path, u32 ext ) static void skaterift_load_world_content(void) { /* hub world */ - _world.default_hub_addon = skaterift_mount_world_unloadable( "maps/dev_hub", 0 ); + _world.default_hub_addon = skaterift_mount_world_unloadable( "maps/dev_hub", ADDON_REG_CAMPAIGN ); 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 ); @@ -153,9 +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 ); - + + vg_async_stall(); + menu_on_world_change( _world.main.addon ); /* add autosave function to exit list */ vg_loader_step( NULL, skaterift_autosave_synchronous ); @@ -227,7 +228,6 @@ void vg_pre_update(void) world_update( &_world.main, localplayer.rb.co ); audio_ambient_sprites_update( &_world.main, listen_co ); - world_map_pre_update(); } void vg_fixed_update(void) @@ -343,17 +343,15 @@ static void skaterift_composite_maincamera(void) ent_camera_unpack( menu.bg_cam, &g_render.cam ); } - if( menu_viewing_map() ) - { - vg_camera_copy( &world_map.cam, &g_render.cam ); - g_render.cam.nearz = 4.0f; - g_render.cam.farz = 3100.0f; - } - ent_camera *cs_cam = _cutscene_active_camera(); if( cs_cam ) ent_camera_unpack( cs_cam, &g_render.cam ); + if( world_map.sel_spawn && (world_map.spawn_timer > 0.0f) ) + { + vg_camera_copy( &world_map.final_cam, &g_render.cam ); + } + vg_camera_update_transform( &g_render.cam ); if( _TEMP_VAR ) @@ -361,6 +359,7 @@ static void skaterift_composite_maincamera(void) m4x3_copy( _TEMP_VAR[0], g_render.cam.transform ); _TEMP_VAR = NULL; } + vg_camera_update_view( &g_render.cam ); vg_camera_update_projection( &g_render.cam, vg.window_x, vg.window_y ); vg_camera_finalize( &g_render.cam ); @@ -394,6 +393,7 @@ static void render_main_game(void) skaterift_composite_maincamera(); bool render_actual_game = !menu_viewing_map(); + bool render_stenciled = 0; if( render_actual_game ) { @@ -406,6 +406,27 @@ 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 ); + if( !render_actual_game ) + { + render_world_map(); + + if( world_map.sel_spawn && (world_map.spawn_timer > 0.0f) ) + { + glEnable( GL_STENCIL_TEST ); + glDisable( GL_DEPTH_TEST ); + glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE ); + glStencilFunc( GL_ALWAYS, 1, 0xFF ); + glStencilMask( 0xFF ); + + shader_blit_transition_use(); + shader_blit_transition_uInverseRatio( (v2f){1.0f,1.0f} ); + shader_blit_transition_uT( -(sqrtf(2)+0.5f) * world_map.spawn_timer ); + render_fsquad(); + render_stenciled = 1; + render_actual_game = 1; + } + } + if( render_actual_game ) { /* Draw world */ @@ -425,7 +446,7 @@ static void render_main_game(void) } #endif - render_world( &_world.main, &g_render.cam, 0, 0, 1, 1 ); + render_world( &_world.main, &g_render.cam, render_stenciled, 0, 1, 1 ); particle_system_update( &particles_grind, vg.time_delta ); //particle_system_debug( &particles_grind ); @@ -439,10 +460,6 @@ static void render_main_game(void) player_glide_render_effects( &g_render.cam ); } - else - { - render_world_map(); - } glEnable( GL_DEPTH_TEST ); @@ -450,7 +467,7 @@ static void render_main_game(void) glBindFramebuffer( GL_FRAMEBUFFER, 0 ); glViewport( 0,0, vg.window_x, vg.window_y ); - if( render_actual_game ) + if( render_actual_game && !render_stenciled ) { render_player_transparent(); /* needs to read the depth buffer before we fuck it up with the oblique rendering inside the diff --git a/src/world_load.c b/src/world_load.c index bb87551..6124964 100644 --- a/src/world_load.c +++ b/src/world_load.c @@ -525,7 +525,7 @@ int skaterift_load_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,0 ); - menu_figure_out_where_to_start_world_select( reg ); + menu_on_world_change( reg ); skaterift_load_world_start( reg, preview ); } else diff --git a/src/world_map.c b/src/world_map.c index ced1cba..214647e 100644 --- a/src/world_map.c +++ b/src/world_map.c @@ -85,247 +85,108 @@ static void world_map_help_normal(void) #endif } -void world_map_pre_update(void) +void world_map_initialize_view(void) { - if( menu_viewing_map() ) - { - if( world_map.activity == k_map_activity_galaxy ) - { - return; - } - - if( !world_map.view_ready ) - { - world_instance *world = &_world.main; - v3f *bbx = world->scene_geo.bbx; + world_instance *world = &_world.main; + v3f *bbx = world->scene_geo.bbx; - respawn_world_to_plane_pos( localplayer.rb.co, world_map.plane_pos ); - world_map.boom_dist = 400.0f; - world_map.home_select = 0; - world_map.view_ready = 1; - world_map.sel_spawn = NULL; - world_map.close_spawn = NULL; + respawn_world_to_plane_pos( localplayer.rb.co, world_map.plane_pos ); + world_map.boom_dist = 400.0f; + world_map.view_ready = 1; + world_map.sel_spawn = NULL; + world_map.close_spawn = NULL; + world_map.smooth_warm = 0; +} - world_map_help_normal(); - } - } +static void world_map_update_final_camera( vg_camera *cam ) +{ + if( world_map.smooth_warm ) + vg_camera_lerp( &world_map.smoothed_cam, cam, vg.time_frame_delta*3.0f, &world_map.smoothed_cam ); else { - if( world_map.view_ready ) - { - gui_helper_reset( k_gui_helper_mode_clear ); - world_map.view_ready = 0; - } - - return; + world_map.smooth_warm = 1; + vg_camera_copy( cam, &world_map.smoothed_cam ); } - world_instance *world = &_world.main; - v3f *bbx = world->scene_geo.bbx; - f32 *pos = world_map.plane_pos; + world_map.final_cam.farz = 5000.0f; + world_map.final_cam.nearz = 10.0f; -#if 0 - v2f steer; - joystick_state( k_srjoystick_steer, steer ); - v2_normalize_clamp( steer ); - - if( !world_map.sel_spawn ) + if( world_map.sel_spawn && (world_map.spawn_timer > 0.0f) ) { - f32 *pos = world_map.plane_pos; - m2x2f rm; - m2x2_create_rotation( rm, -0.25f*VG_PIf ); - m2x2_mulv( rm, steer, steer ); - v2_muladds( pos, steer, vg.time_frame_delta * 200.0f, pos ); + f32 t = vg_smoothstepf( world_map.spawn_timer ); + vg_camera_lerp( &localplayer.cam, &world_map.smoothed_cam, t, &world_map.final_cam ); + world_map.final_cam.nearz = vg_lerpf( 0.1f, 10.0f, t ); } -#endif - - f32 bd_target = 400.0f, - interp = vg.time_frame_delta*2.0f; - - if( world_map.sel_spawn ) + else { - v2f pp; - respawn_world_to_plane_pos( world_map.sel_spawn->transform.co, pp ); - v2_lerp( pos, pp, interp, pos ); - - bd_target = 200.0f; + vg_camera_copy( &world_map.smoothed_cam, &world_map.final_cam ); } - world_map.boom_dist = vg_lerpf( world_map.boom_dist, bd_target, interp ); - - v2_minv( (v2f){ bbx[1][0], bbx[1][2] }, pos, pos ); - v2_maxv( (v2f){ bbx[0][0], bbx[0][2] }, pos, pos ); - - /* update camera */ - vg_camera *cam = &world_map.cam; - v3f dir; - world_map_get_dir(dir); - - v4f plane; - world_map_get_plane( plane ); - - v3f co = { pos[0], plane[3]*plane[1], pos[1] }; - v3_muladds( co, dir, world_map.boom_dist, cam->pos ); - - vg_line_cross( co, VG__RED, 10.0f ); - - cam->angles[0] = 0.25f * VG_PIf; - cam->angles[1] = 0.25f * VG_PIf; - 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_update_transform( &world_map.final_cam ); + vg_camera_update_view( &world_map.final_cam ); + vg_camera_update_projection( &world_map.final_cam, vg.window_x, vg.window_y ); + vg_camera_finalize( &world_map.final_cam ); + vg_camera_finalize( &world_map.final_cam ); +} - /* pick spawn */ - f32 closest2 = INFINITY; - v2f centroid = { 0, 0 }; +void render_world_map(void) +{ + glEnable( GL_DEPTH_TEST ); - for( u32 i=0; ient_spawn); i++ ) + if( world_map.activity == k_map_activity_local_world ) { - ent_spawn *spawn = af_arritm(&world->ent_spawn,i); + world_instance *world = &_world.main; - v4f v; - v3_copy( spawn->transform.co, v ); - v[3] = 1.0f; - m4x4_mulv( cam->mtx.pv, v, v ); - v2_divs( v, v[3], v ); + /* update camera based on input position and zoom + * ---------------------------------------------------------------------------------------- */ + vg_camera cam; + v3f dir; + world_map_get_dir(dir); - f32 d2 = v2_dist2(v, centroid); - if( d2 < closest2 ) - { - world_map.close_spawn = spawn; - closest2 = d2; - } - spawn->transform.s[0] = d2; - } + v4f plane; + world_map_get_plane( plane ); -#if 0 - if( button_down( k_srbind_maccept ) ) - { - if( world_map.sel_spawn ) - { - skaterift.activity = k_skaterift_default; - srinput.state = k_input_state_resume; - player__spawn( world_map.sel_spawn ); - return; - } - else - { - world_map_select_close(); - } - } + v3f co = { world_map.plane_pos[0], plane[3]*plane[1], world_map.plane_pos[1] }; + v3_muladds( co, dir, world_map.boom_dist, cam.pos ); - if( button_down( k_srbind_mback ) ) - { - if( world_map.sel_spawn ) - { - world_map.sel_spawn = NULL; - world_map_help_normal(); - } - } -#endif + cam.angles[0] = 0.25f * VG_PIf; + cam.angles[1] = 0.25f * VG_PIf; + cam.angles[2] = 0.0f; + cam.fov = 40.0f; - /* icons - * ---------------------*/ - for( u32 i=0; ient_challenge); i++ ) - { - ent_challenge *challenge = af_arritm( &world->ent_challenge, i ); - if( challenge->flags & k_ent_challenge_locked ) - continue; + world_map_update_final_camera( &cam ); - enum gui_icon icon = k_gui_icon_exclaim_2d; - if( challenge->flags & k_ent_challenge_is_story ) + /* update closest spawn based on camera + * ------------------------------------------------------------------------------------------- */ + f32 closest2 = INFINITY; + for( u32 i=0; ient_spawn); i++ ) { - icon = k_gui_icon_story2d; - if( world->events[i].story_script ) + ent_spawn *spawn = af_arritm(&world->ent_spawn,i); + + if( world_map.sel_spawn ) { - if( world->events[i].story_script->viewed_time ) + spawn->transform.s[0] = ( spawn == world_map.sel_spawn )? 0.0f: 10000.0f; + } + else + { + v4f v; + v3_copy( spawn->transform.co, v ); + v[3] = 1.0f; + m4x4_mulv( world_map.final_cam.mtx.pv, v, v ); + v2_divs( v, v[3], v ); + + f32 d2 = v2_dist2(v, world_map.view_centroid); + if( d2 < closest2 ) { - icon = k_gui_icon_story_done2d; + world_map.close_spawn = spawn; + closest2 = d2; } + spawn->transform.s[0] = d2; } } - else - { - if( challenge->status ) - icon = k_gui_icon_tick_2d; - } - respawn_map_draw_icon( cam, icon, challenge->transform.co, 1.0f ); - } - - for( u32 i=0; ient_spawn); i ++ ) - { - ent_spawn *spawn = af_arritm( &world->ent_spawn, i ); + /* Do the rendering of the world in override shader + * ------------------------------------------------------------------------------------------------- */ - if( spawn->transform.s[0] > 0.3f ) - continue; - - f32 s = 1.0f-(spawn->transform.s[0] / 0.3f); - respawn_map_draw_icon( cam, - spawn==world_map.sel_spawn? - k_gui_icon_spawn_select: k_gui_icon_spawn, - spawn->transform.co, s ); - } - - for( u32 i=0; ient_skateshop); i++ ) - { - ent_skateshop *shop = af_arritm( &world->ent_skateshop, i ); - if( shop->type == k_skateshop_type_boardshop ) - { - respawn_map_draw_icon( cam, k_gui_icon_board, shop->transform.co, 1 ); - } - else if( shop->type == k_skateshop_type_worldshop ) - { - respawn_map_draw_icon( cam, k_gui_icon_world, shop->transform.co, 1 ); - } - } - - for( u32 i=0; ient_gate); i++ ) - { - ent_gate *gate = af_arritm( &world->ent_gate, i ); - if( gate->flags & k_ent_gate_nonlocal ) - { - respawn_map_draw_icon( cam, k_gui_icon_rift, gate->co[0], 1 ); - } - } - - 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->board_transform[3], 1 ); - } - - for( u32 i=0; ient_glider); i ++ ) - { - ent_glider *glider = af_arritm( &world->ent_glider, i ); - - v4f colour = { 1,1,1,1 }; - - if( !(glider->flags & 0x1) ) - v3_muls( colour, 0.5f, colour ); - gui_icon_setcolour( colour ); - - 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 } ); @@ -347,12 +208,103 @@ void render_world_map(void) m4x3f identity; m4x3_identity( identity ); - render_world_override( world, world, identity, &g_render.cam, - world_map.close_spawn, + render_world_override( world, world, identity, &world_map.final_cam, + world_map.sel_spawn? world_map.sel_spawn: 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 ); + render_world_routes( world, world, identity, &world_map.final_cam, 0, 1 ); + + /* Add icons to the map + * ------------------------------------------------------------------------------------------------- */ + for( u32 i=0; ient_challenge); i++ ) + { + ent_challenge *challenge = af_arritm( &world->ent_challenge, i ); + if( challenge->flags & k_ent_challenge_locked ) + continue; + + enum gui_icon icon = k_gui_icon_exclaim_2d; + if( challenge->flags & k_ent_challenge_is_story ) + { + icon = k_gui_icon_story2d; + if( world->events[i].story_script ) + { + if( world->events[i].story_script->viewed_time ) + { + icon = k_gui_icon_story_done2d; + } + } + } + else + { + if( challenge->status ) + icon = k_gui_icon_tick_2d; + } + + respawn_map_draw_icon( &world_map.final_cam, icon, challenge->transform.co, 1.0f ); + } + + for( u32 i=0; ient_spawn); i ++ ) + { + ent_spawn *spawn = af_arritm( &world->ent_spawn, i ); + + if( spawn->transform.s[0] > 0.3f ) + continue; + + f32 s = 1.0f-(spawn->transform.s[0] / 0.3f); + respawn_map_draw_icon( &world_map.final_cam, + spawn==world_map.sel_spawn? k_gui_icon_spawn_select: k_gui_icon_spawn, + spawn->transform.co, s ); + } + + for( u32 i=0; ient_skateshop); i++ ) + { + ent_skateshop *shop = af_arritm( &world->ent_skateshop, i ); + if( shop->type == k_skateshop_type_boardshop ) + { + respawn_map_draw_icon( &world_map.final_cam, k_gui_icon_board, shop->transform.co, 1 ); + } + else if( shop->type == k_skateshop_type_worldshop ) + { + respawn_map_draw_icon( &world_map.final_cam, k_gui_icon_world, shop->transform.co, 1 ); + } + } + + for( u32 i=0; ient_gate); i++ ) + { + ent_gate *gate = af_arritm( &world->ent_gate, i ); + if( gate->flags & k_ent_gate_nonlocal ) + { + respawn_map_draw_icon( &world_map.final_cam, k_gui_icon_rift, gate->co[0], 1 ); + } + } + + 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( &world_map.final_cam, k_gui_icon_rift_run_2d, route->board_transform[3], 1 ); + } + + for( u32 i=0; ient_glider); i ++ ) + { + ent_glider *glider = af_arritm( &world->ent_glider, i ); + + v4f colour = { 1,1,1,1 }; + + if( !(glider->flags & 0x1) ) + v3_muls( colour, 0.5f, colour ); + gui_icon_setcolour( colour ); + + respawn_map_draw_icon( &world_map.final_cam, k_gui_icon_glider, glider->transform.co, 1 ); + } + + gui_icon_setcolour( (v4f){1,1,1,1} ); + respawn_map_draw_icon( &world_map.final_cam, k_gui_icon_player2d, localplayer.rb.co, 1.0f ); } - else + else if( world_map.activity == k_map_activity_galaxy ) { glDrawBuffers( 1, (GLenum[]){ GL_COLOR_ATTACHMENT0 } ); glClearColor( 0.1f,0.1f,0.2f, 0.0f ); @@ -363,8 +315,8 @@ void render_world_map(void) world_instance *world = &_world.preview_instance; vg_camera cam; v3f dir; - dir[0] = -sqrtf(0.5f); - dir[2] = sqrtf(0.5f); + dir[0] = -1.0f; + dir[2] = 1.0f; dir[1] = 1.0f; v3_normalize(dir); @@ -383,20 +335,23 @@ void render_world_map(void) 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; + v3_negate( dir, dir ); + v3_angles( dir, cam.angles ); + v3f v0, v1; + v3_sub( centroid, cam.pos, v0 ); + v3_sub( world->scene_geo.bbx[1], cam.pos, v1 ); + v3_normalize( v0 ); + v3_normalize( v1 ); - 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 ); + f32 a = v3_dot(v0,v1); + cam.fov = acosf( a ) * 45.0f; - render_world_preview( &cam ); + cam.angles[0] -= 0.07f*a + ofs[0]*0.1f; + cam.angles[1] += 0.03f*a + ofs[1]*0.1f; + cam.angles[2] = ofs[2]*0.01f; + + world_map_update_final_camera( &cam ); + render_world_preview( &world_map.final_cam ); if( world->complete ) { @@ -408,7 +363,7 @@ void render_world_map(void) 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 ); + respawn_map_draw_icon( &world_map.final_cam, k_gui_icon_rift_run_2d, route->anon.transform.co, 0.5f ); } } } @@ -456,6 +411,553 @@ void render_world_map(void) } } +void world_map_gui( ui_context *ctx, ui_rect main_area, i32 mh, i32 mv, bool *allow_back_to_exit ) +{ + ui_rect title_box = { main_area[2]/2 - 300/2, main_area[1] + 8, 300, 100 }; + + ui_rect upper_title, lower_title; + ui_split( title_box, k_ui_axis_h, title_box[3]-24, 0, upper_title, lower_title ); + + const char *title_text = NULL, + *subtitle_text = NULL; + + if( world_map.activity == k_map_activity_local_world ) + { + world_instance *world = &_world.main; + + world_map.boom_dist = 400.0f; + + if( world_map.sel_spawn ) + { + /* focus camera down onto spawn */ + v2f pp; + respawn_world_to_plane_pos( world_map.sel_spawn->transform.co, pp ); + v2_lerp( world_map.plane_pos, pp, vg.time_frame_delta*2.0f, world_map.plane_pos ); + world_map.boom_dist = 200.0f; + + /* Spawn selected UI + * --------------------------------------------------------------------------------------------------- */ + + if( world_map.spawn_timer > 0.0f ) + { + world_map.spawn_timer -= vg.time_frame_delta/2.0f; + + if( world_map.spawn_timer <= 0.0f ) + { + skaterift.activity = k_skaterift_default; + srinput.state = k_input_state_resume; + world_map.sel_spawn = NULL; + } + } + else + { + *allow_back_to_exit = 0; + + ui_px spawn_box_width = 500; + ui_rect spawn_box = { main_area[0] + (main_area[2]-spawn_box_width)/2, main_area[1] + 32, + spawn_box_width, 100 }; + ui_fill( ctx, spawn_box, ui_opacity( GUI_COL_DARK, 0.36f ) ); + + ctx->font = &vgf_default_title; + ui_rect label_box = { spawn_box[0], spawn_box[1] + 8, spawn_box[2], 48 }; + ui_text( ctx, label_box, "Spawnpoint", 1, k_ui_align_center, ui_colour(ctx,k_ui_yellow) ); + + bool spawn_here = 0, + exit_spawn = 0; + + ui_rect no_box = { spawn_box[0] + spawn_box[2]-32, spawn_box[1], 32, 32 }; + if( menu_button_rect( ctx, no_box, 0, 1, "X" ) ) + { + exit_spawn = 1; + } + + ctx->font = &vgf_default_large; + ui_rect yes_box = { spawn_box[0]+(spawn_box[2]-100)/2, spawn_box[1]+spawn_box[3]-32, 100, 32 }; + if( menu_button_rect( ctx, yes_box, vg_input.display_input_method == k_input_method_controller, 1, "Spawn" ) ) + { + spawn_here = 1; + } + + if( button_down( k_srbind_maccept ) ) + spawn_here = 1; + if( button_down( k_srbind_mback ) ) + exit_spawn = 1; + + if( spawn_here ) + { + player__spawn( world_map.sel_spawn ); + world_map.spawn_timer = 1.0f; + } + else if( exit_spawn ) + { + world_map.sel_spawn = NULL; + } + } + } + else + { + title_text = af_str( &world->meta.af, world->info.pstr_name ); + subtitle_text = "Current Location"; + ctx->font = &vgf_default_title; + upper_title[2] = ui_text_line_width(ctx,title_text) + 24; + upper_title[0] = main_area[0] + (main_area[2] - upper_title[2])/2; + + /* Update camera input variables based on user input + * -------------------------------------------------------------------------------------------- */ + + v2f steer; + joystick_state( k_srjoystick_steer, steer ); + v2_normalize_clamp( steer ); + + m2x2f rm; + m2x2_create_rotation( rm, -0.25f*VG_PIf ); + m2x2_mulv( rm, steer, steer ); + v2_muladds( world_map.plane_pos, steer, vg.time_frame_delta * 200.0f, world_map.plane_pos ); + + v3f *bbx = world->scene_geo.bbx; + v2_minv( (v2f){ bbx[1][0], bbx[1][2] }, world_map.plane_pos, world_map.plane_pos ); + v2_maxv( (v2f){ bbx[0][0], bbx[0][2] }, world_map.plane_pos, world_map.plane_pos ); + + if( vg_input.display_input_method == k_input_method_kbm ) + { + world_map.view_centroid[0] = ((f32)ctx->mouse[0] / (f32)vg.window_x)*2.0f - 1.0f; + world_map.view_centroid[1] = -(((f32)ctx->mouse[1] / (f32)vg.window_y)*2.0f - 1.0f); + } + else + { + world_map.view_centroid[0] = 0.0f; + world_map.view_centroid[1] = 0.0f; + } + + /* draw information about the world's name and option to go up to the galaxy + * ------------------------------------------------------------------------------------------------------ */ + bool go_to_super = 0; + ctx->font = &vgf_default_title; + ui_px back_box_size = 48; + 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_mhub], 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_mhub ) ) + { + 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 ) ); + + if( go_to_super ) + { + world_map.activity = k_map_activity_galaxy; + menu_update_world_list(); + } + + /* Draw world completion list + * ------------------------------------------------------------------------------------------------------- */ + if( af_arrcount( &world->ent_region ) ) + { + ui_rect stat_panel = { main_area[0]+main_area[2]-(256+8), main_area[1]+8, 256, main_area[3]-16 }; + u32 c0 = ui_opacity( GUI_COL_DARK, 0.36f ); + ui_fill( ctx, stat_panel, c0 ); + + ui_rect_pad( stat_panel, (ui_px[2]){8,0} ); + + for( u32 i=0; ient_region ); i ++ ) + { + ent_region *region = af_arritm( &world->ent_region, i ); + + 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 ) ); + } + + 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 ); + } + } + + /* allow selecting of a spawnpoint + * ------------------------------------------------------------------------------------------------------ */ + + if( ctx->focused_control_type == k_ui_control_none ) + { + if( world_map.close_spawn ) + { + if( vg_input.display_input_method == k_input_method_kbm ) + { + if( ui_inside_rect( main_area, ctx->mouse ) ) + { + if( ui_click_up(ctx, UI_MOUSE_LEFT) ) + { + world_map.sel_spawn = world_map.close_spawn; + } + } + } + else + { + if( button_down( k_srbind_maccept ) ) + world_map.sel_spawn = world_map.close_spawn; + } + } + } + } + + +#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) ); + + 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 ); + + w *= ctx->font->sx; + x += w + 16; + + vs[1].co[0] = x + 8; + vs[2].co[0] = x; + + x = 8; + y += 8 + height; + + vs[2].co[1] = stat_panel[1]; + vs[3].co[1] = stat_panel[1]; + + 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, main_area[1]+24, WORKSHOP_PREVIEW_WIDTH+8, main_area[3]-(24+24) }; + ui_fill( ctx, panel, ui_opacity( GUI_COL_DARK, 0.35f ) ); + + + 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] + ((main_area[2] - (panel[0]+panel[2])) - upper_title[2])/2; + lower_title[0] = panel[0]+panel[2] + 24; + lower_title[2] = (main_area[2] - (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; + } + + /* controller input */ + if( mh ) + { + i32 s = world_map.superworld_list_selected - mh; + if( s < 0 ) s = 0; + if( s > k_superworld_max -1 ) s = k_superworld_max -1; + + if( s != world_map.superworld_list_selected ) + { + world_map.superworld_list_selected = s; + superworld_changed = 1; + } + } + + /* 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; + world_map.smooth_warm = 0; + } + + for( u32 i=0; ifont->sy*2, 8, sel_box, _null ); + ui_outline( ctx, sel_box, 2, ui_colour(ctx,k_ui_fg), 0 ); + } + + if( menu_button( ctx, panel, R == (page_base + i), !selected, menu.world_list_names[i] ) ) + { + 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(); + } + + 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 ); + } + + ctx->font = &vgf_default_title; + ui_px remainder = main_area[2] - (panel[0] + panel[2]), + width = 400, + height = ctx->font->sy*2; + + ui_rect enter_world_box = { panel[0]+panel[2] + (remainder-width)/2, main_area[3] - (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 ); + + bool enter_location = 0; + if( menu_button( ctx, enter_world_box, 0, menu.clicked_world_reg?1:0, buf ) ) + enter_location = 1; + + 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; + } + } + + /* Render title & subtitle + * --------------------------------------------------------------------------------------------------- + */ + + if( title_text ) + { + 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 ) + { + ctx->font = &vgf_default_large; + ui_text( ctx, lower_title, subtitle_text, 1, k_ui_align_middle_center, 0 ); + } + } +} + void world_map_init(void) { mdl_context *model = &world_map.superworld_meta; @@ -469,4 +971,10 @@ void world_map_init(void) world_map.superworld_cam.nearz = 0.1f; world_map.superworld_cam.farz = 250.0f; world_map.superworld_cam.fov = 90.0f; + world_map.smoothed_cam.nearz = 0.1f; + world_map.smoothed_cam.farz = 250.0f; + world_map.smoothed_cam.fov = 90.0f; + world_map.final_cam.nearz = 0.1f; + world_map.final_cam.farz = 250.0f; + world_map.final_cam.fov = 90.0f; } diff --git a/src/world_map.h b/src/world_map.h index d78cd77..95dd782 100644 --- a/src/world_map.h +++ b/src/world_map.h @@ -15,12 +15,13 @@ struct world_map { v2f plane_pos; f32 boom_dist; - u32 home_select; ent_spawn *sel_spawn, *close_spawn; - vg_camera cam; + vg_camera smoothed_cam, final_cam; + bool smooth_warm; bool view_ready; + f32 spawn_timer; enum map_activity { @@ -39,12 +40,13 @@ struct world_map superworld_actual_world; vg_camera superworld_cam; + v2f view_centroid; } extern world_map; -void world_map_pre_update(void); +void world_map_gui( ui_context *ctx, ui_rect main_area, i32 mh, i32 mv, bool *allow_back_to_exit ); void render_world_map(void); void world_map_init(void); - +void world_map_initialize_view(void); const char *_superworld_names[] = { diff --git a/src/world_render.c b/src/world_render.c index 2206739..e91ee0c 100644 --- a/src/world_render.c +++ b/src/world_render.c @@ -1089,14 +1089,16 @@ void render_world( world_instance *world, vg_camera *cam, int stenciled, int viewing_from_gate, int with_water, int with_cubemaps ) { - if( stenciled ){ + if( stenciled ) + { glClear( GL_DEPTH_BUFFER_BIT ); glStencilFunc( GL_EQUAL, 1, 0xFF ); glStencilMask( 0x00 ); glEnable( GL_CULL_FACE ); glEnable( GL_STENCIL_TEST ); } - else { + else + { glStencilMask( 0xFF ); glStencilFunc( GL_ALWAYS, 1, 0xFF ); glDisable( GL_STENCIL_TEST ); @@ -1115,7 +1117,8 @@ void render_world( world_instance *world, vg_camera *cam, render_world_foliage( world, cam ); render_terrain( world, cam ); - if( !viewing_from_gate ){ + if( !viewing_from_gate ) + { #if 0 world_entity_focus_render(); #endif @@ -1140,14 +1143,16 @@ void render_world( world_instance *world, vg_camera *cam, } } - if( !viewing_from_gate ){ + if( !viewing_from_gate ) + { f32 greyout = 0.0f; #if 0 if( mdl_entity_id_type(_world.focused_entity) == k_ent_challenge ) greyout = _world.focus_strength; #endif - if( greyout > 0.0f ){ + if( greyout > 0.0f ) + { glDrawBuffers( 1, (GLenum[]){ GL_COLOR_ATTACHMENT0 } ); glEnable(GL_BLEND); glDisable(GL_DEPTH_TEST); @@ -1269,7 +1274,7 @@ void render_world_override( world_instance *world, v4f uPlayerPos, uSpawnPos; v4_zero( uPlayerPos ); v4_zero( uSpawnPos ); - v3_copy( (v3f){0,0,0}, uPlayerPos ); + v3_copy( localplayer.rb.co, uPlayerPos ); if( dest_spawn && (v3_dist2(dest_spawn->transform.co,uPlayerPos) > 0.1f) ) v3_copy( dest_spawn->transform.co, uSpawnPos );