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;
if( !name )
name = addon_reg->alias.foldername;
menu.clicked_world_name = name;
+
+ world_map_initialize_view();
}
void menu_open( enum menu_page page )
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 )
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 )
{
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; i<af_arrcount( &world->ent_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; j<af_arrcount(&world->ent_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; j<af_arrcount(&world->ent_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; i<menu.world_list_display_count; i ++ )
- {
- addon_reg *reg = menu.world_list_entries[i];
-
- bool selected = reg == menu.clicked_world_reg;
-
- if( selected )
- {
- ui_rect sel_box, _null;
- ui_split( panel, k_ui_axis_h, ctx->font->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<max_page, "\x96" ) )
- *selected_world_index = (page+1)*menu.world_list_nominal_display_count;
-
- if( (*selected_world_index < page_base) ||
- (*selected_world_index >= (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) */
{
#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; i<af_arrcount(&world->ent_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; i<af_arrcount(&world->ent_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; i<af_arrcount(&world->ent_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; i<af_arrcount(&world->ent_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; i<af_arrcount(&world->ent_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; i<af_arrcount(&world->ent_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; i<af_arrcount(&world->ent_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; i<af_arrcount(&world->ent_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 } );
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; i<af_arrcount(&world->ent_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; i<af_arrcount(&world->ent_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; i<af_arrcount(&world->ent_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; i<af_arrcount(&world->ent_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; i<af_arrcount(&world->ent_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; i<af_arrcount(&world->ent_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 );
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);
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 )
{
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 );
}
}
}
}
}
+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; i<af_arrcount( &world->ent_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; j<af_arrcount(&world->ent_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; j<af_arrcount(&world->ent_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; i<menu.world_list_display_count; i ++ )
+ {
+ addon_reg *reg = menu.world_list_entries[i];
+
+ bool selected = reg == menu.clicked_world_reg;
+
+ if( selected )
+ {
+ ui_rect sel_box, _null;
+ ui_split( panel, k_ui_axis_h, ctx->font->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<max_page, "\x96" ) )
+ *selected_world_index = (page+1)*menu.world_list_nominal_display_count;
+
+ if( (*selected_world_index < page_base) ||
+ (*selected_world_index >= (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;
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;
}