leaderboard have picture
[fishladder.git] / vg / vg_steamworks.h
index b14e9eaf63decf3916e97911584b291499a39941..c0baba54bcca3dea04b42f4e9e0a411c913f4bdc 100644 (file)
@@ -547,6 +547,14 @@ int                SteamAPI_ISteamUserStats_SetAchievement( ISteamUserStats *self, const char
 
 ESteamAPICallFailure SteamAPI_ISteamUtils_GetAPICallFailureReason( ISteamUtils* self, SteamAPICall_t hSteamAPICall );
 
+// Friends
+char                                   *SteamAPI_ISteamFriends_GetPersonaName( ISteamFriends *self );
+const char                     *SteamAPI_ISteamFriends_GetFriendPersonaName( ISteamFriends *self, u64_steamid steamIDFriend );
+u64_steamid             SteamAPI_ISteamUser_GetSteamID( ISteamUser *self );
+int                                     SteamAPI_ISteamFriends_GetSmallFriendAvatar( ISteamFriends *self, u64_steamid steamIDFriend ); // 32x32
+int    SteamAPI_ISteamUtils_GetImageSize( ISteamUtils *self, int iImage, u32 *pnWidth, u32 *pnHeight );
+int    SteamAPI_ISteamUtils_GetImageRGBA( ISteamUtils *self, int iImage, u8 *pubDest, int nDestBufferSize );
+
 // Leaderboards
 SteamAPICall_t SteamAPI_ISteamUserStats_FindOrCreateLeaderboard( ISteamUserStats* self, const char * pchLeaderboardName, ELeaderboardSortMethod eLeaderboardSortMethod, ELeaderboardDisplayType eLeaderboardDisplayType );
 SteamAPICall_t SteamAPI_ISteamUserStats_FindLeaderboard( ISteamUserStats* self, const char * pchLeaderboardName );
@@ -560,6 +568,18 @@ int SteamAPI_ISteamUserStats_GetDownloadedLeaderboardEntry( ISteamUserStats* sel
 SteamAPICall_t SteamAPI_ISteamUserStats_UploadLeaderboardScore( ISteamUserStats* self, SteamLeaderboard_t hSteamLeaderboard, ELeaderboardUploadScoreMethod eLeaderboardUploadScoreMethod, i32 nScore, const i32 * pScoreDetails, int cScoreDetailsCount );
 SteamAPICall_t SteamAPI_ISteamUserStats_AttachLeaderboardUGC( ISteamUserStats* self, SteamLeaderboard_t hSteamLeaderboard, UGCHandle_t hUGC );
 
+#define sw_get_image_size(...) SteamAPI_ISteamUtils_GetImageSize( steam_api_classes.utils, __VA_ARGS__ )
+#define sw_get_image_rgba(...) SteamAPI_ISteamUtils_GetImageRGBA( steam_api_classes.utils, __VA_ARGS__ )
+#define sw_get_small_friend_avatar(...) SteamAPI_ISteamFriends_GetSmallFriendAvatar( steam_api_classes.friends, __VA_ARGS__ )
+#define sw_get_steamid() SteamAPI_ISteamUser_GetSteamID( steam_api_classes.friends )
+#define sw_get_friend_persona_name(...) SteamAPI_ISteamFriends_GetFriendPersonaName( steam_api_classes.friends, __VA_ARGS__ )
+#define sw_get_persona_name() SteamAPI_ISteamFriends_GetPersonaName( steam_api_classes.friends )
+#define sw_find_leaderboard(...) SteamAPI_ISteamUserStats_FindLeaderboard( steam_api_classes.stats, __VA_ARGS__ );
+#define sw_get_leaderboard_name(...) SteamAPI_ISteamUserStats_GetLeaderboardName( steam_api_classes.stats, __VA_ARGS__ )
+#define sw_download_leaderboard_entries(...) SteamAPI_ISteamUserStats_DownloadLeaderboardEntries( steam_api_classes.stats, __VA_ARGS__ )
+#define sw_get_downloaded_entry(...) SteamAPI_ISteamUserStats_GetDownloadedLeaderboardEntry( steam_api_classes.stats, __VA_ARGS__ )
+#define sw_upload_leaderboard_score(...) SteamAPI_ISteamUserStats_UploadLeaderboardScore( steam_api_classes.stats, __VA_ARGS__ )
+
 HSteamPipe SteamAPI_GetHSteamPipe();
 HSteamUser SteamAPI_GetHSteamUser();
 
@@ -573,8 +593,115 @@ struct
        
        HSteamPipe                      pipe;
        
+       struct cached_player
+       {
+               u64_steamid id;
+               GLuint          avatar_texture;         // tex_unkown.name
+               
+               struct cached_player *l, *r;
+       }
+       cached_players[20];
+       
+       struct cached_player *cache_head, *cache_tail;
+       
+       u32 cache_count;
+       
 } steam_api_classes;
 
+static void _sw_cache_push( struct cached_player *player )
+{
+       player->l = NULL;
+       player->r = steam_api_classes.cache_head;
+       if( steam_api_classes.cache_head ) steam_api_classes.cache_head->l = player;
+       if( !steam_api_classes.cache_tail ) steam_api_classes.cache_tail = player;
+       steam_api_classes.cache_head = player;
+       steam_api_classes.cache_count ++;
+}
+
+static void _sw_cache_evict( struct cached_player *player )
+{
+       if( player == steam_api_classes.cache_tail ) steam_api_classes.cache_tail = player->l;
+       if( player == steam_api_classes.cache_head ) steam_api_classes.cache_head = player->r;
+       if( player->l ) player->l->r = player->r;
+       if( player->r ) player->r->l = player->l;
+       steam_api_classes.cache_count --;
+}
+
+static void _sw_access_cache( struct cached_player *player )
+{
+       _sw_cache_evict( player );
+       _sw_cache_push( player );
+}
+
+static GLuint sw_get_player_image( u64_steamid usr )
+{
+       // Look for player in cache
+       for( int i = 0; i < steam_api_classes.cache_count; i ++ )
+       {
+               struct cached_player *player = &steam_api_classes.cached_players[i];
+               
+               if( player->id == usr )
+               {
+                       _sw_access_cache( player );
+                       return player->avatar_texture;
+               }
+       }
+       
+       struct cached_player *dest;
+       
+       if( steam_api_classes.cache_count == vg_list_size( steam_api_classes.cached_players ) )
+       {
+               dest = steam_api_classes.cache_tail;
+               _sw_access_cache( dest );
+               
+               // Delete previous before creating a new one
+               glDeleteTextures( 1, &dest->avatar_texture );
+       }
+       else
+       {
+               dest = &steam_api_classes.cached_players[ steam_api_classes.cache_count ];
+               _sw_cache_push( dest );
+       }
+       
+       dest->id = usr;
+       dest->avatar_texture = 0;
+       
+       // Upload new image
+       u32 x = 32, y = 32;
+       int steam_image;
+       
+       steam_image = sw_get_small_friend_avatar( usr );
+       if( !steam_image )
+               return 0;
+               
+       if( !sw_get_image_size( steam_image, &x, &y ) )
+               return 0;
+               
+       u8 * img_buf = (u8 *)malloc( x * y * 4 );
+       
+       if( !sw_get_image_rgba(steam_image, img_buf, x * y * 4) )
+       {
+               free( img_buf );
+               return 0;
+       }
+       
+       glGenTextures( 1, &dest->avatar_texture );
+       glBindTexture( GL_TEXTURE_2D, dest->avatar_texture );
+       
+       glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, img_buf );
+       glGenerateMipmap( GL_TEXTURE_2D );
+       
+       glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
+       glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
+       
+       glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+       glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+       
+       free( img_buf );
+       
+       return dest->avatar_texture;
+}
+
 ISteamFriends          *SteamAPI_SteamFriends_v017();
 ISteamUser                     *SteamAPI_SteamUser_v021();
 ISteamUserStats        *SteamAPI_SteamUserStats_v012();
@@ -586,6 +713,14 @@ static void sw_exit(void)
        SteamAPI_Shutdown();
 }
 
+// Needs to be manually called by client unfortunately
+static void sw_free_opengl(void)
+{
+       for( int i = 0; i < steam_api_classes.cache_count; i ++ )
+               if( steam_api_classes.cached_players[i].avatar_texture )
+                       glDeleteTextures( 1, &steam_api_classes.cached_players[i].avatar_texture );
+}
+
 static int sw_init(void)
 {
        #if defined(VALVE_CALLBACK_PACK_SMALL)
@@ -638,6 +773,7 @@ static int sw_init(void)
 
 
 void (*sw_leaderboard_found)( LeaderboardFindResult_t *pCallback );
+void (*sw_leaderboard_downloaded)( LeaderboardScoresDownloaded_t *pCallback );
 
 static void sw_event_loop(void)
 {
@@ -674,6 +810,9 @@ static void sw_event_loop(void)
                                        case SW_CBID_LeaderboardFindResult:
                                                if( sw_leaderboard_found ) sw_leaderboard_found( (LeaderboardFindResult_t*)pTmpCallResult );
                                        break;
+                                       case SW_CBID_LeaderboardScoresDownloaded:
+                                               if( sw_leaderboard_downloaded ) sw_leaderboard_downloaded( (LeaderboardScoresDownloaded_t*)pTmpCallResult );
+                                       break;
                                        default:break;
                                }
                        } 
@@ -729,13 +868,3 @@ static void sw_set_achievement( const char *vg_ach_name )
                vg_success( "Achievement set: '%s'\n", vg_ach_name );
        }
 }
-
-static void sw_find_leaderboard( const char *name )
-{
-       SteamAPI_ISteamUserStats_FindLeaderboard( steam_api_classes.stats, name );
-}
-
-static const char *sw_get_leaderboard_name( SteamLeaderboard_t hSteamLeaderboard )
-{
-       return SteamAPI_ISteamUserStats_GetLeaderboardName( steam_api_classes.stats, hSteamLeaderboard );
-}