leaderboard have picture
[fishladder.git] / fishladder.c
index 7f47fdb54a49c96a1a5e9cfe8a913f88ef590861..3b2c09f599c903741d874ebb04e1e6f087d45b8a 100644 (file)
@@ -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 );
 }