X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=fishladder.c;h=3b2c09f599c903741d874ebb04e1e6f087d45b8a;hb=fa88b9de1e8416023822f91ec88971bfadcf1702;hp=7f47fdb54a49c96a1a5e9cfe8a913f88ef590861;hpb=8f89e6bd64229500954908e79ce500f80dda774d;p=fishladder.git diff --git a/fishladder.c b/fishladder.c index 7f47fdb..3b2c09f 100644 --- a/fishladder.c +++ b/fishladder.c @@ -356,13 +356,16 @@ struct world int num_fishes; char map_name[64]; - struct career_level *ptr_career_level; + //struct career_level *ptr_career_level; + struct cmp_level *pCmpLevel; u32 score; u32 completed; u32 time; } world = {}; +void leaderboard_set_score( struct cmp_level *cmp_level, u32 score ); + static void map_free(void) { arrfree( world.data ); @@ -806,7 +809,7 @@ static int console_load_map( int argc, char const *argv[] ) if( text_source ) { vg_info( "Loading map: '%s'\n", map_path ); - world.ptr_career_level = NULL; + world.pCmpLevel = NULL; if( !map_load( text_source, argv[0] ) ) { @@ -814,17 +817,7 @@ static int console_load_map( int argc, char const *argv[] ) return 0; } - free( text_source ); - - for( int i = 0; i < vg_list_size( level_pack_1 ); i ++ ) - { - if( !strcmp( level_pack_1[i], argv[0] ) ) - { - world.ptr_career_level = career.levels + i; - break; - } - } - + free( text_source ); return 1; } else @@ -875,10 +868,13 @@ static int console_changelevel( int argc, char const *argv[] ) } void leaderboard_found( LeaderboardFindResult_t *pCallback ); +void leaderboard_downloaded( LeaderboardScoresDownloaded_t *pCallback ); + void vg_start(void) { // Steamworks callbacks sw_leaderboard_found = &leaderboard_found; + sw_leaderboard_downloaded = &leaderboard_downloaded; vg_function_push( (struct vg_cmd){ .name = "_map_write", @@ -1038,6 +1034,7 @@ void vg_start(void) void vg_free(void) { + sw_free_opengl(); console_save_map( 0, NULL ); career_serialize(); @@ -1760,11 +1757,12 @@ void vg_update(void) } // Copy into career data - if( world.ptr_career_level ) + if( world.pCmpLevel ) { - world.ptr_career_level->score = world.score; - world.ptr_career_level->time = world.time; - world.ptr_career_level->completed = world.completed; + if( world.score > world.pCmpLevel->completed_score ) + leaderboard_set_score( world.pCmpLevel, world.score ); + + world.pCmpLevel->completed_score = world.score; } simulation_stop(); // TODO: Async? @@ -2278,7 +2276,30 @@ static ui_colourset flcol_list_locked = { static struct { SteamLeaderboard_t steam_leaderboard; - int leaderboard_matches; + int leaderboard_show; + + struct leaderboard_player + { + // Internal + u64_steamid id; + i32 score; + + // To be displayed + char score_text[ 16 ]; + char player_name[ 48 ]; + GLuint texture; // Not dynamic + } + leaderboard_players[10]; + int leaderboard_count; + + struct + { + struct cmp_level *level; + + i32 score; + int is_waiting; + } + upload_request; struct cmp_level *level_selected; } @@ -2412,7 +2433,7 @@ void vg_ui(void) if( gui_button( 2 + i ) == k_button_click ) { ui_data.level_selected = &levels[i]; - ui_data.leaderboard_matches = 0; + ui_data.leaderboard_show = 0; sw_find_leaderboard( ui_data.level_selected->map_name ); } @@ -2511,8 +2532,10 @@ void vg_ui(void) if( gui_button( 3002 ) == k_button_click ) { console_changelevel( 1, &ui_data.level_selected->map_name ); + world.pCmpLevel = ui_data.level_selected; + ui_data.level_selected = NULL; - ui_data.leaderboard_matches = 0; + ui_data.leaderboard_show = 0; } gui_text( "Play", 6, 0 ); gui_end(); @@ -2522,7 +2545,7 @@ void vg_ui(void) } gui_end_right(); - if( ui_data.leaderboard_matches ) + if( ui_data.leaderboard_show ) { ui_global_ctx.cursor[0] += 16; ui_global_ctx.cursor[3] = 250; @@ -2531,21 +2554,144 @@ void vg_ui(void) gui_new_node(); { gui_fill_rect( ui_global_ctx.cursor, 0xff5a4e4d ); + + ui_rect_pad( ui_global_ctx.cursor, 8 ); + + gui_new_node(); + { + ui_global_ctx.cursor[3] = 32+8; + + for( int i = 0; i < ui_data.leaderboard_count; i ++ ) + { + gui_new_node(); + { + struct leaderboard_player *player = &ui_data.leaderboard_players[i]; + + ui_global_ctx.cursor[0] += 4; + ui_global_ctx.cursor[1] += 4; + ui_global_ctx.cursor[2] = 32; + ui_global_ctx.cursor[3] = 32; + + gui_new_node(); + { + gui_push_image( ui_global_ctx.cursor, player->texture ); + } + gui_end_right(); + + gui_text( player->player_name, 6, 0 ); + + ui_global_ctx.cursor[2] = 50; + gui_align_right(); + + gui_text( player->score_text, 6, 0 ); + } + gui_end_down(); + + ui_global_ctx.cursor[1] += 2; + + } + } + gui_end(); } gui_end(); } } } +void leaderboard_dispatch_score(void) +{ + sw_upload_leaderboard_score( + ui_data.upload_request.level->steam_leaderboard, + k_ELeaderboardUploadScoreMethodKeepBest, + ui_data.upload_request.score, + NULL, + 0 + ); + + ui_data.upload_request.is_waiting = 0; + + vg_success( "Dispatched leaderboard score\n" ); +} + void leaderboard_found( LeaderboardFindResult_t *pCallback ) { if( !pCallback->m_bLeaderboardFound ) + { vg_error( "Leaderboard could not be found\n" ); + ui_data.steam_leaderboard = 0; + } + else + { + const char *recieved_name = sw_get_leaderboard_name( pCallback->m_hSteamLeaderboard ); + + // Update UI state and request entries if this callback found the current UI level + if( ui_data.level_selected ) + { + if( !strcmp( recieved_name, ui_data.level_selected->map_name ) ) + { + sw_download_leaderboard_entries( pCallback->m_hSteamLeaderboard, k_ELeaderboardDataRequestFriends, 0, 10 ); + ui_data.level_selected->steam_leaderboard = pCallback->m_hSteamLeaderboard; + } + } + + // Dispatch the waiting request if there was one + if( ui_data.upload_request.is_waiting ) + { + if( !strcmp( recieved_name, ui_data.upload_request.level->map_name ) ) + { + ui_data.upload_request.level->steam_leaderboard = pCallback->m_hSteamLeaderboard; + leaderboard_dispatch_score(); + } + } + } +} + +void leaderboard_downloaded( LeaderboardScoresDownloaded_t *pCallback ) +{ + // Update UI if this leaderboard matches what we currently have in view + if( ui_data.level_selected->steam_leaderboard == pCallback->m_hSteamLeaderboard ) + { + vg_info( "Recieved %d entries\n", pCallback->m_cEntryCount ); + ui_data.leaderboard_count = VG_MIN( pCallback->m_cEntryCount, 10 ); + + for( int i = 0; i < ui_data.leaderboard_count; i ++ ) + { + LeaderboardEntry_t entry; + sw_get_downloaded_entry( pCallback->m_hSteamLeaderboardEntries, i, &entry, NULL, 0 ); + + struct leaderboard_player *player = &ui_data.leaderboard_players[i]; + + player->id = entry.m_steamIDUser.m_unAll64Bits; + strncpy( player->player_name, sw_get_friend_persona_name( player->id ), vg_list_size( player->player_name )-1 ); + player->score = entry.m_nScore; + + snprintf( player->score_text, vg_list_size(player->score_text), "%d", player->score ); + player->texture = sw_get_player_image( player->id ); + + if( player->texture == 0 ) + player->texture = tex_unkown.name; + } + + if( ui_data.leaderboard_count ) + ui_data.leaderboard_show = 1; + else + ui_data.leaderboard_show = 0; + } + else vg_warn( "Downloaded leaderboard does not match requested!\n" ); +} + +void leaderboard_set_score( struct cmp_level *cmp_level, u32 score ) +{ + if( ui_data.upload_request.is_waiting ) + vg_warn( "You are uploading leaderboard entries too quickly!\n" ); + + ui_data.upload_request.level = cmp_level; + ui_data.upload_request.score = score; + ui_data.upload_request.is_waiting = 1; - 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; + // If leaderboard ID has been downloaded already then just immediately dispatch this + if( cmp_level->steam_leaderboard ) + leaderboard_dispatch_score(); + else + sw_find_leaderboard( cmp_level->map_name ); }