X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=fishladder.c;h=7f47fdb54a49c96a1a5e9cfe8a913f88ef590861;hb=8f89e6bd64229500954908e79ce500f80dda774d;hp=7cda200bd7727d537cc849e214f27d7c3c3e5ec1;hpb=e00ea4ccba1891970699f9b5b78ba1ebaada2974;p=fishladder.git diff --git a/fishladder.c b/fishladder.c index 7cda200..7f47fdb 100644 --- a/fishladder.c +++ b/fishladder.c @@ -874,8 +874,12 @@ static int console_changelevel( int argc, char const *argv[] ) return 0; } +void leaderboard_found( LeaderboardFindResult_t *pCallback ); void vg_start(void) { + // Steamworks callbacks + sw_leaderboard_found = &leaderboard_found; + vg_function_push( (struct vg_cmd){ .name = "_map_write", .function = console_save_map @@ -2240,102 +2244,76 @@ void vg_render(void) use_mesh( &world.numbers ); draw_numbers( (v3f){ 2.0f, (float)world.h-1.875f, 0.3333f }, world.score ); - - // Level selection UI - use_mesh( &world.circle ); - float ratio = ((float)vg_window_x/(float)vg_window_y); - - m3x3f ui_view = M3X3_IDENTITY; - m3x3_scale( ui_view, (v3f){ 1.0f, ratio, 1.0f } ); - glUniformMatrix3fv( SHADER_UNIFORM( shader_tile_colour, "uPv" ), 1, GL_FALSE, (float *)ui_view ); +} - // Calculate mouse in UIsp - v3f mouse_ui_space = { ((float)vg_mouse[0] / (float)(vg_window_x)) * 2.0f - 1.0f, - (((float)vg_mouse[1] / (float)(vg_window_y)) * 2.0f - 1.0f)*(-1.0f/ratio), 0.0125f }; +static ui_colourset flcol_list_a = { + .main = 0xff877979, + .hover = 0xffa09393, + .active = 0xffbfb1b0 +}; +static ui_colourset flcol_list_b = { + .main = 0xff7c6e6e, + .hover = 0xffa09393, + .active = 0xffbfb1b0 +}; - // Get selected level - const float selection_scale = 0.05f; - int const level_count = vg_list_size( level_pack_1 ); - int level_select = -1; - - if( mouse_ui_space[0] <= -0.8f ) - { - float levels_range = (float)level_count*selection_scale*0.6f; - float level_offset = ((-mouse_ui_space[1] + levels_range) / levels_range) * 0.5f * (float)level_count; - level_select = ceilf( level_offset ); +static ui_colourset flcol_list_complete_a = { + .main = 0xff62a064, + .hover = 0xff8dc18f, + .active = 0xffb2ddb3 +}; - // Draw selector - if( level_select >= 0 && level_select < vg_list_size( level_pack_1 ) ) - { - glUniform4f( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 0.369768f, 0.3654f, 0.42f, 1.0f ); - - use_mesh( &world.tile ); - glUniform3f( SHADER_UNIFORM( shader_tile_colour, "uOffset" ), - -1.0f, - ((float)level_count - (float)level_select * 2.0f ) * selection_scale * 0.6f, - selection_scale - ); - draw_mesh( 2, 2 ); - - use_mesh( &world.circle ); - - if( vg_get_button_down( "primary" ) ) - { - console_changelevel( 1, level_pack_1 + level_select ); - } - } - } - else mouse_ui_space[1] = INFINITY; +static ui_colourset flcol_list_complete_b = { + .main = 0xff79b37b, + .hover = 0xff8dc18f, + .active = 0xffb2ddb3 +}; - glUniform4f( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 0.4f, 0.39f, 0.45f, 1.0f ); +static ui_colourset flcol_list_locked = { + .main = 0xff655959, + .hover = 0xff655959, + .active = 0xff655959 +}; - // Draw levels - for( int i = 0; i < level_count; i ++ ) - { - struct career_level *clevel = &career.levels[i]; - - v3f level_ui_space = { - -0.97f, - ((float)level_count - (float)i * 2.0f ) * selection_scale * 0.6f + selection_scale * 0.5f, - selection_scale * 0.5f - }; - - float scale = vg_clampf( 1.0f - fabsf(level_ui_space[1] - mouse_ui_space[1]) * 2.0f, 0.9f, 1.0f ); - level_ui_space[2] *= scale; - - glUniform3fv( SHADER_UNIFORM( shader_tile_colour, "uOffset" ), 1, level_ui_space ); - - if( clevel->completed ) - draw_mesh( filled_start, filled_count ); - else - draw_mesh( empty_start, empty_count ); - } - - // Level scores - glUniform4f( SHADER_UNIFORM( shader_tile_colour, "uColour" ), 0.4f*1.25f, 0.39f*1.25f, 0.45f*1.25f, 1.0f ); - - use_mesh( &world.numbers ); - for( int i = 0; i < level_count; i ++ ) - { - struct career_level *clevel = &career.levels[i]; +static struct +{ + SteamLeaderboard_t steam_leaderboard; + int leaderboard_matches; - v3f level_ui_space = { - -0.94f, - ((float)level_count - (float)i * 2.0f ) * selection_scale * 0.6f + selection_scale * 0.5f, - 0.02f - }; - - if( clevel->completed ) - draw_numbers( level_ui_space, clevel->score ); - - level_ui_space[0] = -0.975f; - level_ui_space[1] -= 0.01f; - draw_numbers( level_ui_space, i ); - } -} + struct cmp_level *level_selected; +} +ui_data; void vg_ui(void) { + // UI memory + static int pack_selection = 0; + static struct pack_info + { + struct cmp_level *levels; + u32 level_count; + const char *name; + } + pack_infos[] = + { + { + .levels = cmp_levels_tutorials, + .level_count = vg_list_size(cmp_levels_tutorials), + .name = "Training" + }, + { + .levels = cmp_levels_basic, + .level_count = vg_list_size(cmp_levels_basic), + .name = "Main" + }, + { + .levels = cmp_levels_grad, + .level_count = vg_list_size(cmp_levels_tutorials), + .name = "Expert" + } + }; + + // UI Code ui_global_ctx.cursor[0] = 0; ui_global_ctx.cursor[1] = 0; ui_global_ctx.cursor[2] = 256; @@ -2346,49 +2324,228 @@ void vg_ui(void) gui_new_node(); { + gui_capture_mouse( 9999 ); gui_fill_rect( ui_global_ctx.cursor, 0xff5577ff ); - gui_text( "MARBLE COMPUTING", 4, 0 ); + gui_text( "ASSIGNMENTS", 8, 0 ); - ui_global_ctx.cursor[1] += 45; - ui_global_ctx.cursor[3] = 709; + ui_global_ctx.cursor[1] += 30; + ui_global_ctx.cursor[3] = 25; - // Level scroll view gui_new_node(); { - gui_fill_rect( ui_global_ctx.cursor, 0xffff7729 ); - gui_set_clip( ui_global_ctx.cursor ); - - ui_global_ctx.cursor[2] = 16; - gui_align_right(); + ui_rect_pad( ui_global_ctx.cursor, 2 ); + ui_global_ctx.cursor[2] = 84; + for( int i = 0; i < 3; i ++ ) + { + if( i == pack_selection ) + gui_override_colours( &flcol_list_locked ); + + if( gui_button( 2000 + i ) == k_button_click ) + pack_selection = i; + + ui_global_ctx.cursor[1] += 2; + gui_text( pack_infos[i].name, 4, 0 ); + gui_end_right(); + + gui_reset_colours(); + } + } + gui_end_down(); + + ui_global_ctx.cursor[3] = 500; + + // DRAW LEVEL SELECTION LIST + { + struct cmp_level *levels = pack_infos[ pack_selection ].levels; + int count = pack_infos[ pack_selection ].level_count; + int unlocked = 3000; + static struct ui_scrollbar sb = { .bar_height = 400 }; - ui_scrollbar( &ui_global_ctx, &sb, 0 ); - ui_global_ctx.cursor[2] = 240; - ui_global_ctx.cursor[3] = 50; - gui_align_left(); + ui_px view_height = ui_global_ctx.cursor[3]; + ui_px level_height = 50; + + // Level scroll view + gui_new_node(); + { + gui_fill_rect( ui_global_ctx.cursor, 0xff5a4e4d ); + gui_set_clip( ui_global_ctx.cursor ); + + ui_global_ctx.cursor[2] = 14; + gui_align_right(); + + ui_px content_height = count*level_height; + if( content_height > view_height ) + { + ui_scrollbar( &ui_global_ctx, &sb, 1 ); + ui_global_ctx.cursor[1] -= ui_calculate_content_scroll( &sb, content_height ); + } + else + { + gui_fill_rect( ui_global_ctx.cursor, 0xff807373 ); + } + + ui_global_ctx.cursor[2] = 240; + ui_global_ctx.cursor[3] = level_height; + gui_align_left(); + + for( int i = 0; i < count; i ++ ) + { + struct cmp_level *lvl_info = &levels[i]; + + if( i < unlocked ) + { + if( lvl_info->completed_score != 0 ) + gui_override_colours( i&0x1? &flcol_list_complete_a: &flcol_list_complete_b ); + else + gui_override_colours( i&0x1? &flcol_list_a: &flcol_list_b ); + } + else + gui_override_colours( &flcol_list_locked ); + + if( i < unlocked ) + { + if( gui_button( 2 + i ) == k_button_click ) + { + ui_data.level_selected = &levels[i]; + ui_data.leaderboard_matches = 0; + sw_find_leaderboard( ui_data.level_selected->map_name ); + } + + ui_global_ctx.override_colour = 0xffffffff; + gui_text( lvl_info->title, 6, 0 ); + ui_global_ctx.cursor[1] += 18; + gui_text( "incomplete", 4, 0 ); + } + else + { + gui_button( 2 + i ); + + ui_global_ctx.override_colour = 0xff786f6f; + gui_text( "???", 6, 0 ); + ui_global_ctx.cursor[1] += 18; + gui_text( "locked", 4, 0 ); + } + + gui_end_down(); + } + + gui_reset_colours(); + gui_release_clip(); + } + gui_end_down(); + } + } + gui_end_right(); + + // Selected level UI + // ============================================================ + + if( ui_data.level_selected ) + { + ui_global_ctx.cursor[0] += 16; + ui_global_ctx.cursor[1] += 16; + ui_global_ctx.cursor[2] = 512-40; + ui_global_ctx.cursor[3] = 560-16; + + gui_new_node(); + { + gui_capture_mouse( 9999 ); + + gui_fill_rect( ui_global_ctx.cursor, 0xff5a4e4d ); + ui_global_ctx.cursor[1] += 4; + gui_text( ui_data.level_selected->title, 6, 0 ); + + ui_global_ctx.cursor[1] += 30; + ui_rect_pad( ui_global_ctx.cursor, 8 ); + ui_global_ctx.cursor[3] = 300; + + gui_new_node(); + { + gui_fill_rect( ui_global_ctx.cursor, 0xff655959 ); + } + gui_end_down(); + + ui_text_use_paragraph( &ui_global_ctx ); + ui_global_ctx.cursor[1] += 2; + + gui_text( ui_data.level_selected->description, 5, 0 ); + ui_text_use_title( &ui_global_ctx ); + + // Buttons at the bottom + ui_global_ctx.cursor[3] = 30; + ui_global_ctx.cursor[2] = 80; + + gui_align_bottom(); + ui_global_ctx.cursor[1] -= 8; - ui_px content_height = vg_list_size(cmp_levels_basic)*ui_global_ctx.cursor[3]; - ui_global_ctx.cursor[1] -= ui_calculate_content_scroll( &sb, content_height ); + if( gui_button( 3000 ) == k_button_click ) + { + ui_data.level_selected = NULL; + } + gui_text( "Back", 6, 0 ); + gui_end(); + + gui_align_right(); + ui_global_ctx.cursor[2] = 170; + ui_global_ctx.cursor[0] -= 8 + 170 + 2; - for( int i = 0; i < vg_list_size(cmp_levels_basic); i ++ ) { - struct cmp_level *lvl_info = &cmp_levels_basic[i]; + gui_override_colours( &flcol_list_locked ); + if( gui_button( 3001 ) == k_button_click ) + vg_error( "UNIMPLEMENTED\n" ); + + gui_text( "Restore Solution", 6, 0 ); + gui_end_right(); + } - gui_new_node(); + ui_global_ctx.cursor[0] += 2; + ui_global_ctx.cursor[2] = 80; + + { + gui_override_colours( &flcol_list_complete_a ); + if( gui_button( 3002 ) == k_button_click ) { - gui_fill_rect( ui_global_ctx.cursor, i&0x1?0xff23fce45:0xff8722f8 ); - gui_text( lvl_info->title, 3, 0 ); + console_changelevel( 1, &ui_data.level_selected->map_name ); + ui_data.level_selected = NULL; + ui_data.leaderboard_matches = 0; } - gui_end_down(); + gui_text( "Play", 6, 0 ); + gui_end(); } - gui_release_clip(); + gui_reset_colours(); + } + gui_end_right(); + + if( ui_data.leaderboard_matches ) + { + ui_global_ctx.cursor[0] += 16; + ui_global_ctx.cursor[3] = 250; + + // If has results + gui_new_node(); + { + gui_fill_rect( ui_global_ctx.cursor, 0xff5a4e4d ); + } + gui_end(); } - gui_end_down(); } - gui_end(); +} + +void leaderboard_found( LeaderboardFindResult_t *pCallback ) +{ + if( !pCallback->m_bLeaderboardFound ) + vg_error( "Leaderboard could not be found\n" ); + + ui_data.steam_leaderboard = pCallback->m_hSteamLeaderboard; + ui_data.leaderboard_matches = 0; + + if( ui_data.level_selected ) + if( !strcmp( sw_get_leaderboard_name( ui_data.steam_leaderboard ), ui_data.level_selected->map_name ) ) + ui_data.leaderboard_matches = 1; }