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 );
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();
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();
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)
void (*sw_leaderboard_found)( LeaderboardFindResult_t *pCallback );
+void (*sw_leaderboard_downloaded)( LeaderboardScoresDownloaded_t *pCallback );
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;
}
}
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 );
-}