diff --git a/Readme.txt b/Readme.txt index 37da5ee..9e1788f 100644 --- a/Readme.txt +++ b/Readme.txt @@ -11,6 +11,23 @@ website at: http://partner.steamgames.com Revision History: +---------------------------------------------------------------- +v1.24 17th July 2013 +---------------------------------------------------------------- + +User: +* Added ISteamUser::GetBadgeLevel and ISteamUser::GetPlayerSteamLevel functions + +Friends: +* Games can now initiate Steam Friend requests, removals, request -accepts and request-ignores via ISteamFriends’ ActivateGameOverlayToUser API. This prompts the user for confirmation before action is taken. + +Mac: +* Updated the OS X Content Prep tool and game wrapper for improved compatibility with OS X 10.8 (Mountain Lion). + +Linux: +* Added install script for the Steam Linux Runtime tools (run "bash tools/linux/setup.sh" to install), see tools/linux/README.txt for details. +* SteamworksExample is now available on Linux + ---------------------------------------------------------------- v1.23a 25th February 2013 ---------------------------------------------------------------- diff --git a/SteamworksExample/BaseMenu.h b/SteamworksExample/BaseMenu.h index 7d60647..2715122 100644 --- a/SteamworksExample/BaseMenu.h +++ b/SteamworksExample/BaseMenu.h @@ -198,12 +198,12 @@ public: if ( i == m_uSelectedItem ) { dwColor = D3DCOLOR_ARGB( 255, 25, 200, 25 ); - _snprintf( rgchBuffer, sizeof( rgchBuffer), "{ %s }", m_VecMenuItems[i].first.c_str() ); + sprintf_safe( rgchBuffer, "{ %s }", m_VecMenuItems[i].first.c_str() ); } else { dwColor = D3DCOLOR_ARGB( 255, 255, 255, 255 ); - _snprintf( rgchBuffer, sizeof( rgchBuffer), "%s", m_VecMenuItems[i].first.c_str() ); + sprintf_safe( rgchBuffer, "%s", m_VecMenuItems[i].first.c_str() ); } m_pGameEngine->BDrawString( g_hMenuFont, rect, dwColor, TEXTPOS_CENTER|TEXTPOS_VCENTER, rgchBuffer ); } @@ -241,4 +241,4 @@ private: T m_selection; }; -#endif // MAINMENU_H \ No newline at end of file +#endif // MAINMENU_H diff --git a/SteamworksExample/GameEngine.h b/SteamworksExample/GameEngine.h index f7b2dec..4efb8f8 100644 --- a/SteamworksExample/GameEngine.h +++ b/SteamworksExample/GameEngine.h @@ -76,7 +76,7 @@ public: virtual bool BDrawString( HGAMEFONT hFont, RECT rect, DWORD dwColor, DWORD dwFormat, const char *pchText ) = 0; // Create a new font returning our internal handle value for it (0 means failure) - virtual HGAMEFONT HCreateFont( int nHeight, int nFontWeight, bool bItalic, char * pchFont ) = 0; + virtual HGAMEFONT HCreateFont( int nHeight, int nFontWeight, bool bItalic, const char * pchFont ) = 0; // Create a new texture returning our internal handle value for it (0 means failure) virtual HGAMETEXTURE HCreateTexture( byte *pRGBAData, uint32 uWidth, uint32 uHeight ) = 0; @@ -135,4 +135,4 @@ public: virtual bool AddVoiceData( HGAMEVOICECHANNEL hChannel, const uint8 *pVoiceData, uint32 uLength ) = 0; }; -#endif // GAMEENGINE_H \ No newline at end of file +#endif // GAMEENGINE_H diff --git a/SteamworksExample/Leaderboards.cpp b/SteamworksExample/Leaderboards.cpp index 3206fc2..fa0fd7b 100644 --- a/SteamworksExample/Leaderboards.cpp +++ b/SteamworksExample/Leaderboards.cpp @@ -5,7 +5,7 @@ //============================================================================= #include "stdafx.h" -#include "leaderboards.h" +#include "Leaderboards.h" #include "BaseMenu.h" #include @@ -124,7 +124,7 @@ public: { char rgchMenuText[256]; const char *pchName = SteamFriends()->GetFriendPersonaName( m_leaderboardEntries[index].m_steamIDUser ); - _snprintf( rgchMenuText, sizeof( rgchMenuText ), "(%d) %s - %d", m_leaderboardEntries[index].m_nGlobalRank, + sprintf_safe( rgchMenuText, "(%d) %s - %d", m_leaderboardEntries[index].m_nGlobalRank, pchName, m_leaderboardEntries[index].m_nScore ); AddMenuItem( MenuItem_t( std::string( rgchMenuText ), menuItemEmpty ) ); diff --git a/SteamworksExample/Lobby.cpp b/SteamworksExample/Lobby.cpp index 37c0d13..f67fd60 100644 --- a/SteamworksExample/Lobby.cpp +++ b/SteamworksExample/Lobby.cpp @@ -49,7 +49,7 @@ public: LobbyMenuItem_t menuItem = { steamIDLobbyMember, LobbyMenuItem_t::k_ELobbyMenuItemUser }; char rgchMenuText[256]; - _snprintf( rgchMenuText, sizeof( rgchMenuText ), "%s %s", pchName, bReady ? "(READY)" : "" ); + sprintf_safe( rgchMenuText, "%s %s", pchName, bReady ? "(READY)" : "" ); AddMenuItem( MenuItem_t( std::string( rgchMenuText ), menuItem ) ); } } @@ -327,14 +327,14 @@ void CLobbyBrowser::OnLobbyMatchListCallback( LobbyMatchList_t *pCallback, bool if ( pchLobbyName && pchLobbyName[0] ) { // set the lobby name - _snprintf( lobby.m_rgchName, sizeof( lobby.m_rgchName ), "%s", pchLobbyName ); + sprintf_safe( lobby.m_rgchName, "%s", pchLobbyName ); } else { // we don't have info about the lobby yet, request it SteamMatchmaking()->RequestLobbyData( steamIDLobby ); // results will be returned via LobbyDataUpdate_t callback - _snprintf( lobby.m_rgchName, sizeof( lobby.m_rgchName ), "Lobby %d", steamIDLobby.GetAccountID() ); + sprintf_safe( lobby.m_rgchName, "Lobby %d", steamIDLobby.GetAccountID() ); } m_ListLobbies.push_back( lobby ); @@ -360,7 +360,7 @@ void CLobbyBrowser::OnLobbyDataUpdatedCallback( LobbyDataUpdate_t *pCallback ) const char *pchLobbyName = SteamMatchmaking()->GetLobbyData( iter->m_steamIDLobby, "name" ); if ( pchLobbyName[0] ) { - _snprintf( iter->m_rgchName, sizeof( iter->m_rgchName ), "%s", pchLobbyName ); + sprintf_safe( iter->m_rgchName, "%s", pchLobbyName ); // update the menu m_pMenu->Rebuild( m_ListLobbies ); } diff --git a/SteamworksExample/Main.cpp b/SteamworksExample/Main.cpp index b314513..236bd0d 100644 --- a/SteamworksExample/Main.cpp +++ b/SteamworksExample/Main.cpp @@ -5,6 +5,7 @@ //============================================================================= #include "stdafx.h" +#include "steam/steam_api.h" #if defined(WIN32) #include "gameenginewin32.h" @@ -12,6 +13,9 @@ #elif defined(OSX) #include "GameEngine.h" extern IGameEngine *CreateGameEngineOSX(); +#elif defined(SDL) + #include "GameEngine.h" + extern IGameEngine *CreateGameEngineSDL(); #endif #include "SpaceWarClient.h" @@ -208,6 +212,10 @@ static int RealMain( const char *pchCmdLine, HINSTANCE hInstance, int nCmdShow ) new CGameEngineWin32( hInstance, nCmdShow, 1024, 768 ); #elif defined(OSX) CreateGameEngineOSX(); +#elif defined(SDL) + CreateGameEngineSDL(); +#else +#error Need CreateGameEngine() #endif // This call will block and run until the game exits @@ -288,3 +296,26 @@ int main(int argc, const char **argv) return RealMain( szCmdLine, 0, 0 ); } #endif +#ifdef SDL +int main(int argc, const char **argv) +{ + char szCmdLine[1024]; + char *pszStart = szCmdLine; + char * const pszEnd = szCmdLine + Q_ARRAYSIZE(szCmdLine); + *szCmdLine = '\0'; + for ( int i = 1; i < argc; i++ ) + { + const char *parm = argv[i]; + while ( *parm && (pszStart < pszEnd) ) + { + *pszStart++ = *parm++; + } + if ( pszStart >= pszEnd ) + break; + if ( i < argc-1 ) + *pszStart++ = ' '; + } + szCmdLine[Q_ARRAYSIZE(szCmdLine) - 1] = '\0'; + return RealMain( szCmdLine, 0, 0 ); +} +#endif diff --git a/SteamworksExample/RemoteStorage.cpp b/SteamworksExample/RemoteStorage.cpp index 5644728..0c60f43 100644 --- a/SteamworksExample/RemoteStorage.cpp +++ b/SteamworksExample/RemoteStorage.cpp @@ -7,7 +7,7 @@ #include "stdafx.h" #include "RemoteStorage.h" -#include "RemoteStorageSync.h" +#include "remotestoragesync.h" #include #define CLOUDDISP_FONT_HEIGHT 20 @@ -226,8 +226,6 @@ void CRemoteStorageScreen::Show() //----------------------------------------------------------------------------- void CRemoteStorageScreen::Render() { - uint64 ulCurrentTickCount = m_pGameEngine->GetGameTickCount(); - m_bFinished = false; // Update key press information @@ -316,7 +314,7 @@ void CRemoteStorageScreen::Render() pxVertOffset = rect.bottom + CLOUDDISP_VERT_SPACING; char rgchBuffer[256]; - _snprintf( rgchBuffer, sizeof( rgchBuffer), "Num Files In Cloud: %d", m_nNumFilesInCloud ); + sprintf_safe( rgchBuffer, "Num Files In Cloud: %d", m_nNumFilesInCloud ); m_pGameEngine->BDrawString( m_hDisplayFont, rect, D3DCOLOR_ARGB( 255, 25, 200, 25 ), TEXTPOS_CENTER|TEXTPOS_VCENTER, rgchBuffer ); rect.top = pxVertOffset; @@ -325,7 +323,7 @@ void CRemoteStorageScreen::Render() rect.right = rect.left + CLOUDDISP_COLUMN_WIDTH; pxVertOffset = rect.bottom + CLOUDDISP_TEXT_HEIGHT + CLOUDDISP_VERT_SPACING; - _snprintf( rgchBuffer, sizeof( rgchBuffer), "Quota: %d bytes, %d bytes remaining", m_nBytesQuota, m_nAvailableBytes ); + sprintf_safe( rgchBuffer, "Quota: %d bytes, %d bytes remaining", m_nBytesQuota, m_nAvailableBytes ); m_pGameEngine->BDrawString( m_hDisplayFont, rect, D3DCOLOR_ARGB( 255, 25, 200, 25 ), TEXTPOS_CENTER|TEXTPOS_VCENTER, rgchBuffer ); rect.top = pxVertOffset; @@ -334,7 +332,7 @@ void CRemoteStorageScreen::Render() rect.right = rect.left + CLOUDDISP_COLUMN_WIDTH; pxVertOffset = rect.bottom + CLOUDDISP_VERT_SPACING; - _snprintf( rgchBuffer, sizeof( rgchBuffer), "Current Message:" ); + sprintf_safe( rgchBuffer, "Current Message:" ); m_pGameEngine->BDrawString( m_hDisplayFont, rect, D3DCOLOR_ARGB( 255, 25, 200, 25 ), TEXTPOS_CENTER|TEXTPOS_VCENTER, rgchBuffer ); rect.top = pxVertOffset; @@ -351,7 +349,7 @@ void CRemoteStorageScreen::Render() rect.right = rect.left + CLOUDDISP_COLUMN_WIDTH; pxVertOffset = rect.bottom + CLOUDDISP_VERT_SPACING; - _snprintf( rgchBuffer, sizeof( rgchBuffer), "Type in a new message below:" ); + sprintf_safe( rgchBuffer, "Type in a new message below:" ); m_pGameEngine->BDrawString( m_hDisplayFont, rect, D3DCOLOR_ARGB( 255, 25, 200, 25 ), TEXTPOS_CENTER|TEXTPOS_VCENTER, rgchBuffer ); rect.top = pxVertOffset; @@ -368,7 +366,7 @@ void CRemoteStorageScreen::Render() rect.right = rect.left + CLOUDDISP_COLUMN_WIDTH; pxVertOffset = rect.bottom + CLOUDDISP_TEXT_HEIGHT + CLOUDDISP_VERT_SPACING; - _snprintf( rgchBuffer, sizeof( rgchBuffer), "Hit to save, to cancel" ); + sprintf_safe( rgchBuffer, "Hit to save, to cancel" ); m_pGameEngine->BDrawString( m_hDisplayFont, rect, D3DCOLOR_ARGB( 255, 25, 200, 25 ), TEXTPOS_CENTER|TEXTPOS_VCENTER, rgchBuffer ); if ( bQuotaExceeded ) @@ -379,7 +377,7 @@ void CRemoteStorageScreen::Render() rect.right = rect.left + CLOUDDISP_COLUMN_WIDTH; pxVertOffset = rect.bottom + CLOUDDISP_TEXT_HEIGHT + CLOUDDISP_VERT_SPACING; - _snprintf( rgchBuffer, sizeof( rgchBuffer), "!! QUOTA EXCEEDED !!" ); + sprintf_safe( rgchBuffer, "!! QUOTA EXCEEDED !!" ); m_pGameEngine->BDrawString( m_hDisplayFont, rect, D3DCOLOR_ARGB( 255, 25, 200, 25 ), TEXTPOS_CENTER|TEXTPOS_VCENTER, rgchBuffer ); } } diff --git a/SteamworksExample/ServerBrowser.cpp b/SteamworksExample/ServerBrowser.cpp index a91e5ae..428913c 100644 --- a/SteamworksExample/ServerBrowser.cpp +++ b/SteamworksExample/ServerBrowser.cpp @@ -27,7 +27,7 @@ CGameServer::CGameServer( gameserveritem_t *pGameServerItem ) m_bSecure = pGameServerItem->m_bSecure; m_nServerVersion = pGameServerItem->m_nServerVersion; strncpy( m_szServerName, pGameServerItem->GetName(), ARRAYSIZE( m_szServerName ) ); - _snprintf( m_szServerString, ARRAYSIZE( m_szServerString ), "%s (%i/%i) at %s ping(%d)", pGameServerItem->GetName(), pGameServerItem->m_nPlayers, pGameServerItem->m_nMaxPlayers, pGameServerItem->m_NetAdr.GetConnectionAddressString(), pGameServerItem->m_nPing ); + sprintf_safe( m_szServerString, "%s (%i/%i) at %s ping(%d)", pGameServerItem->GetName(), pGameServerItem->m_nPlayers, pGameServerItem->m_nMaxPlayers, pGameServerItem->m_NetAdr.GetConnectionAddressString(), pGameServerItem->m_nPing ); m_steamID = pGameServerItem->m_steamID; } diff --git a/SteamworksExample/SpaceWarClient.cpp b/SteamworksExample/SpaceWarClient.cpp index 98ebcea..f5901ac 100644 --- a/SteamworksExample/SpaceWarClient.cpp +++ b/SteamworksExample/SpaceWarClient.cpp @@ -506,7 +506,7 @@ void CSpaceWarClient::SetGameState( EClientGameState eState ) //----------------------------------------------------------------------------- void CSpaceWarClient::SetConnectionFailureText( const char *pchErrorText ) { - _snprintf( m_rgchErrorText, sizeof( m_rgchErrorText ), "%s", pchErrorText ); + sprintf_safe( m_rgchErrorText, "%s", pchErrorText ); } @@ -690,7 +690,7 @@ void CSpaceWarClient::ReceiveNetworkData() { uint64 ulTimePassedMS = m_pGameEngine->GetGameTickCount() - m_ulPingSentTime; char rgchT[256]; - _snprintf( rgchT, sizeof(rgchT), "Round-trip ping time to server %d ms\n", (int)ulTimePassedMS ); + sprintf_safe( rgchT, "Round-trip ping time to server %d ms\n", (int)ulTimePassedMS ); rgchT[ sizeof(rgchT) - 1 ] = 0; OutputDebugString( rgchT ); m_ulPingSentTime = 0; @@ -785,7 +785,7 @@ void CSpaceWarClient::OnLobbyCreated( LobbyCreated_t *pCallback, bool bIOFailure // set the name of the lobby if it's ours char rgchLobbyName[256]; - _snprintf( rgchLobbyName, sizeof( rgchLobbyName ), "%s's lobby", SteamFriends()->GetPersonaName() ); + sprintf_safe( rgchLobbyName, "%s's lobby", SteamFriends()->GetPersonaName() ); SteamMatchmaking()->SetLobbyData( m_steamIDLobby, "name", rgchLobbyName ); // mark that we're in the lobby @@ -1074,8 +1074,7 @@ void CSpaceWarClient::OnGameWebCallback( GameWebCallback_t *callback ) { m_bSentWebOpen = false; char rgchString[256]; - _snprintf( rgchString, sizeof(rgchString), "User submitted following url: %s\n", callback->m_szURL ); - rgchString[ sizeof(rgchString) - 1 ] = 0; + sprintf_safe( rgchString, "User submitted following url: %s\n", callback->m_szURL ); OutputDebugString( rgchString ); } @@ -1086,7 +1085,7 @@ void CSpaceWarClient::OnGameWebCallback( GameWebCallback_t *callback ) void CSpaceWarClient::OnSteamServerConnectFailure( SteamServerConnectFailure_t *callback ) { char rgchString[256]; - _snprintf( rgchString, 256, "SteamServerConnectFailure_t: %d\n", callback->m_eResult ); + sprintf_safe( rgchString, "SteamServerConnectFailure_t: %d\n", callback->m_eResult ); m_pConnectingMenu->OnConnectFailure(); } @@ -1380,7 +1379,7 @@ void CSpaceWarClient::RunFrame() char szCurDir[MAX_PATH]; _getcwd( szCurDir, sizeof(szCurDir) ); char szURL[MAX_PATH]; - _snprintf( szURL, sizeof(szURL), "file:///%s/test.html", szCurDir ); + sprintf_safe( szURL, "file:///%s/test.html", szCurDir ); // load the test html page, it just has a steam://gamewebcallback link in it SteamFriends()->ActivateGameOverlayToWebPage( szURL ); SetGameState( k_EClientGameMenu ); @@ -1514,18 +1513,18 @@ void CSpaceWarClient::DrawHUDText() if ( m_rgSteamIDPlayers[i].IsValid() ) { - _snprintf( rgchPlayerName, ARRAYSIZE( rgchPlayerName ), "%s", SteamFriends()->GetFriendPersonaName( playerSteamID ) ); + sprintf_safe( rgchPlayerName, "%s", SteamFriends()->GetFriendPersonaName( playerSteamID ) ); } else { - _snprintf( rgchPlayerName, ARRAYSIZE( rgchPlayerName ), "Unknown Player" ); + sprintf_safe( rgchPlayerName, "Unknown Player" ); } // We also want to use the Steam Avatar image inside the HUD if it is available. // We look it up via GetMediumFriendAvatar, which returns an image index we use // to look up the actual RGBA data below. int iImage = SteamFriends()->GetMediumFriendAvatar( playerSteamID ); - HGAMETEXTURE hTexture = NULL; + HGAMETEXTURE hTexture = 0; if ( iImage != -1 ) hTexture = GetSteamImageAsTexture( iImage ); @@ -1546,7 +1545,7 @@ void CSpaceWarClient::DrawHUDText() rect.right += nAvatarWidth + nSpaceBetweenAvatarAndScore; } - _snprintf( rgchBuffer, sizeof( rgchBuffer), "%s\nScore: %2u %s", rgchPlayerName, m_rguPlayerScores[i], pszVoiceState ); + sprintf_safe( rgchBuffer, "%s\nScore: %2u %s", rgchPlayerName, m_rguPlayerScores[i], pszVoiceState ); m_pGameEngine->BDrawString( m_hHUDFont, rect, g_rgPlayerColors[i], TEXTPOS_LEFT|TEXTPOS_VCENTER, rgchBuffer ); break; case 1: @@ -1564,7 +1563,7 @@ void CSpaceWarClient::DrawHUDText() rect.left -= nAvatarWidth + nSpaceBetweenAvatarAndScore; } - _snprintf( rgchBuffer, sizeof( rgchBuffer), "%s\nScore: %2u ", rgchPlayerName, m_rguPlayerScores[i] ); + sprintf_safe( rgchBuffer, "%s\nScore: %2u ", rgchPlayerName, m_rguPlayerScores[i] ); m_pGameEngine->BDrawString( m_hHUDFont, rect, g_rgPlayerColors[i], TEXTPOS_RIGHT|TEXTPOS_VCENTER, rgchBuffer ); break; case 2: @@ -1581,7 +1580,7 @@ void CSpaceWarClient::DrawHUDText() rect.left += nAvatarWidth + nSpaceBetweenAvatarAndScore; } - _snprintf( rgchBuffer, sizeof( rgchBuffer), "%s\nScore: %2u %s", rgchPlayerName, m_rguPlayerScores[i], pszVoiceState ); + sprintf_safe( rgchBuffer, "%s\nScore: %2u %s", rgchPlayerName, m_rguPlayerScores[i], pszVoiceState ); m_pGameEngine->BDrawString( m_hHUDFont, rect, g_rgPlayerColors[i], TEXTPOS_LEFT|TEXTPOS_BOTTOM, rgchBuffer ); break; case 3: @@ -1598,7 +1597,7 @@ void CSpaceWarClient::DrawHUDText() rect.left -= nAvatarWidth + nSpaceBetweenAvatarAndScore; } - _snprintf( rgchBuffer, sizeof( rgchBuffer), "%s\nScore: %2u %s", rgchPlayerName, m_rguPlayerScores[i], pszVoiceState ); + sprintf_safe( rgchBuffer, "%s\nScore: %2u %s", rgchPlayerName, m_rguPlayerScores[i], pszVoiceState ); m_pGameEngine->BDrawString( m_hHUDFont, rect, g_rgPlayerColors[i], TEXTPOS_RIGHT|TEXTPOS_BOTTOM, rgchBuffer ); break; default: @@ -1624,9 +1623,9 @@ void CSpaceWarClient::DrawInstructions() char rgchBuffer[256]; #ifdef _PS3 - _snprintf( rgchBuffer, sizeof( rgchBuffer), "Turn Ship Left: 'Left'\nTurn Ship Right: 'Right'\nForward Thrusters: 'R2'\nReverse Thrusters: 'L2'\nFire Photon Beams: 'Cross'" ); + sprintf_safe( rgchBuffer, "Turn Ship Left: 'Left'\nTurn Ship Right: 'Right'\nForward Thrusters: 'R2'\nReverse Thrusters: 'L2'\nFire Photon Beams: 'Cross'" ); #else - _snprintf( rgchBuffer, sizeof( rgchBuffer), "Turn Ship Left: 'A'\nTurn Ship Right: 'D'\nForward Thrusters: 'W'\nReverse Thrusters: 'S'\nFire Photon Beams: 'Space'" ); + sprintf_safe( rgchBuffer, "Turn Ship Left: 'A'\nTurn Ship Right: 'D'\nForward Thrusters: 'W'\nReverse Thrusters: 'S'\nFire Photon Beams: 'Space'" ); #endif m_pGameEngine->BDrawString( m_hInstructionsFont, rect, D3DCOLOR_ARGB( 255, 25, 200, 25 ), TEXTPOS_CENTER|TEXTPOS_VCENTER, rgchBuffer ); @@ -1637,7 +1636,7 @@ void CSpaceWarClient::DrawInstructions() rect.top = LONG(m_pGameEngine->GetViewportHeight() * 0.7); rect.bottom = m_pGameEngine->GetViewportHeight(); - _snprintf( rgchBuffer, sizeof( rgchBuffer ), "Press ESC to return to the Main Menu" ); + sprintf_safe( rgchBuffer, "Press ESC to return to the Main Menu" ); m_pGameEngine->BDrawString( m_hInstructionsFont, rect, D3DCOLOR_ARGB( 255, 25, 200, 25 ), TEXTPOS_CENTER|TEXTPOS_TOP, rgchBuffer ); } @@ -1660,16 +1659,16 @@ void CSpaceWarClient::DrawConnectionAttemptText() char rgchTimeoutString[256]; if ( uSecondsLeft < 25 ) - _snprintf( rgchTimeoutString, sizeof( rgchTimeoutString ), ", timeout in %u...\n", uSecondsLeft ); + sprintf_safe( rgchTimeoutString, ", timeout in %u...\n", uSecondsLeft ); else - _snprintf( rgchTimeoutString, sizeof( rgchTimeoutString ), "...\n" ); + sprintf_safe( rgchTimeoutString, "...\n" ); char rgchBuffer[256]; if ( m_eGameState == k_EClientJoiningLobby ) - _snprintf( rgchBuffer, sizeof( rgchBuffer ), "Connecting to lobby%s", rgchTimeoutString ); + sprintf_safe( rgchBuffer, "Connecting to lobby%s", rgchTimeoutString ); else - _snprintf( rgchBuffer, sizeof( rgchBuffer ), "Connecting to server%s", rgchTimeoutString ); + sprintf_safe( rgchBuffer, "Connecting to server%s", rgchTimeoutString ); m_pGameEngine->BDrawString( m_hInstructionsFont, rect, D3DCOLOR_ARGB( 255, 25, 200, 25 ), TEXTPOS_CENTER|TEXTPOS_VCENTER, rgchBuffer ); } @@ -1689,7 +1688,7 @@ void CSpaceWarClient::DrawConnectionFailureText() rect.right = width; char rgchBuffer[256]; - _snprintf( rgchBuffer, sizeof( rgchBuffer), "%s\n", m_rgchErrorText ); + sprintf_safe( rgchBuffer, "%s\n", m_rgchErrorText ); m_pGameEngine->BDrawString( m_hInstructionsFont, rect, D3DCOLOR_ARGB( 255, 25, 200, 25 ), TEXTPOS_CENTER|TEXTPOS_VCENTER, rgchBuffer ); rect.left = 0; @@ -1697,7 +1696,7 @@ void CSpaceWarClient::DrawConnectionFailureText() rect.top = LONG(m_pGameEngine->GetViewportHeight() * 0.7); rect.bottom = m_pGameEngine->GetViewportHeight(); - _snprintf( rgchBuffer, sizeof( rgchBuffer ), "Press ESC to return to the Main Menu" ); + sprintf_safe( rgchBuffer, "Press ESC to return to the Main Menu" ); m_pGameEngine->BDrawString( m_hInstructionsFont, rect, D3DCOLOR_ARGB( 255, 25, 200, 25 ), TEXTPOS_CENTER|TEXTPOS_TOP, rgchBuffer ); } @@ -1718,12 +1717,12 @@ void CSpaceWarClient::DrawWinnerDrawOrWaitingText() char rgchBuffer[256]; if ( m_eGameState == k_EClientGameWaitingForPlayers ) { - _snprintf( rgchBuffer, sizeof( rgchBuffer), "Server is waiting for players.\n\nStarting in %d seconds...", nSecondsToRestart ); + sprintf_safe( rgchBuffer, "Server is waiting for players.\n\nStarting in %d seconds...", nSecondsToRestart ); m_pGameEngine->BDrawString( m_hInstructionsFont, rect, D3DCOLOR_ARGB( 255, 25, 200, 25 ), TEXTPOS_CENTER|TEXTPOS_VCENTER, rgchBuffer ); } else if ( m_eGameState == k_EClientGameDraw ) { - _snprintf( rgchBuffer, sizeof( rgchBuffer), "The round is a draw!\n\nStarting again in %d seconds...", nSecondsToRestart ); + sprintf_safe( rgchBuffer, "The round is a draw!\n\nStarting again in %d seconds...", nSecondsToRestart ); m_pGameEngine->BDrawString( m_hInstructionsFont, rect, D3DCOLOR_ARGB( 255, 25, 200, 25 ), TEXTPOS_CENTER|TEXTPOS_VCENTER, rgchBuffer ); } else if ( m_eGameState == k_EClientGameWinner ) @@ -1737,14 +1736,14 @@ void CSpaceWarClient::DrawWinnerDrawOrWaitingText() char rgchPlayerName[128]; if ( m_rgSteamIDPlayers[m_uPlayerWhoWonGame].IsValid() ) { - _snprintf( rgchPlayerName, ARRAYSIZE( rgchPlayerName ), "%s", SteamFriends()->GetFriendPersonaName( m_rgSteamIDPlayers[m_uPlayerWhoWonGame] ) ); + sprintf_safe( rgchPlayerName, "%s", SteamFriends()->GetFriendPersonaName( m_rgSteamIDPlayers[m_uPlayerWhoWonGame] ) ); } else { - _snprintf( rgchPlayerName, ARRAYSIZE( rgchPlayerName ), "Unknown Player" ); + sprintf_safe( rgchPlayerName, "Unknown Player" ); } - _snprintf( rgchBuffer, sizeof( rgchBuffer), "%s wins!\n\nStarting again in %d seconds...", rgchPlayerName, nSecondsToRestart ); + sprintf_safe( rgchBuffer, "%s wins!\n\nStarting again in %d seconds...", rgchPlayerName, nSecondsToRestart ); m_pGameEngine->BDrawString( m_hInstructionsFont, rect, D3DCOLOR_ARGB( 255, 25, 200, 25 ), TEXTPOS_CENTER|TEXTPOS_VCENTER, rgchBuffer ); } @@ -1798,7 +1797,7 @@ float CSpaceWarClient::PixelsToFeet( float flPixels ) //----------------------------------------------------------------------------- HGAMETEXTURE CSpaceWarClient::GetSteamImageAsTexture( int iImage ) { - HGAMETEXTURE hTexture = NULL; + HGAMETEXTURE hTexture = 0; // iImage of 0 from steam means no avatar is set if ( iImage ) @@ -1917,12 +1916,12 @@ void CSpaceWarClient::UpdateRichPresenceConnectionInfo() if ( m_eConnectedStatus == k_EClientConnectedAndAuthenticated && m_unServerIP && m_usServerPort ) { // game server connection method - _snprintf( rgchConnectString, sizeof(rgchConnectString), "+connect %d:%d", m_unServerIP, m_usServerPort ); + sprintf_safe( rgchConnectString, "+connect %d:%d", m_unServerIP, m_usServerPort ); } else if ( m_steamIDLobby.IsValid() ) { // lobby connection method - _snprintf( rgchConnectString, sizeof(rgchConnectString), "+connect_lobby %llu", m_steamIDLobby.ConvertToUint64() ); + sprintf_safe( rgchConnectString, "+connect_lobby %llu", m_steamIDLobby.ConvertToUint64() ); } SteamFriends()->SetRichPresence( "connect", rgchConnectString ); @@ -1942,7 +1941,7 @@ void CSpaceWarClient::ExecCommandLineConnect( const char *pchServerAddress, cons if ( nConverted == 5 ) { char rgchIPAddress[128]; - _snprintf( rgchIPAddress, ARRAYSIZE( rgchIPAddress ), "%d.%d.%d.%d", octet0, octet1, octet2, octet3 ); + sprintf_safe( rgchIPAddress, "%d.%d.%d.%d", octet0, octet1, octet2, octet3 ); uint32 unIPAddress = ( octet3 ) + ( octet2 << 8 ) + ( octet1 << 16 ) + ( octet0 << 24 ); InitiateServerConnection( unIPAddress, uPort ); } @@ -1959,4 +1958,4 @@ void CSpaceWarClient::ExecCommandLineConnect( const char *pchServerAddress, cons OnMenuSelection( menuItem ); } } -} \ No newline at end of file +} diff --git a/SteamworksExample/SpaceWarServer.cpp b/SteamworksExample/SpaceWarServer.cpp index 981c5a1..72b4970 100644 --- a/SteamworksExample/SpaceWarServer.cpp +++ b/SteamworksExample/SpaceWarServer.cpp @@ -33,7 +33,7 @@ CSpaceWarServer::CSpaceWarServer( IGameEngine *pGameEngine ) m_bConnectedToSteam = false; - char *pchGameDir = "spacewar"; + const char *pchGameDir = "spacewar"; uint32 unIP = INADDR_ANY; uint16 usMasterServerUpdaterPort = SPACEWAR_MASTER_SERVER_UPDATER_PORT; @@ -620,7 +620,7 @@ void CSpaceWarServer::ReceiveNetworkData() } default: char rgch[128]; - _snprintf( rgch, 128, "Invalid message %x\n", eMsg ); + sprintf_safe( rgch, "Invalid message %x\n", eMsg ); rgch[ sizeof(rgch) - 1 ] = 0; OutputDebugString( rgch ); } @@ -887,7 +887,7 @@ void CSpaceWarServer::OnPolicyResponse( GSPolicyResponse_t *pPolicyResponse ) OutputDebugString( "SpaceWarServer is not VAC Secure!\n" ); } char rgch[128]; - _snprintf( rgch, 128, "Game server SteamID: %llu\n", SteamGameServer()->GetSteamID().ConvertToUint64() ); + sprintf_safe( rgch, "Game server SteamID: %llu\n", SteamGameServer()->GetSteamID().ConvertToUint64() ); rgch[ sizeof(rgch) - 1 ] = 0; OutputDebugString( rgch ); #endif @@ -926,11 +926,11 @@ void CSpaceWarServer::SendUpdatedServerDetailsToSteam() { // If a client is running (should always be since we don't support a dedicated server) // then we'll form the name based off of it - _snprintf( rgchServerName, ARRAYSIZE( rgchServerName ), "%s's game", SpaceWarClient()->GetLocalPlayerName() ); + sprintf_safe( rgchServerName, "%s's game", SpaceWarClient()->GetLocalPlayerName() ); } else { - _snprintf( rgchServerName, ARRAYSIZE( rgchServerName ), "%s", "Spacewar!" ); + sprintf_safe( rgchServerName, "%s", "Spacewar!" ); } m_sServerName = rgchServerName; diff --git a/SteamworksExample/StatsAndAchievements.cpp b/SteamworksExample/StatsAndAchievements.cpp index 52fa4bf..7201953 100644 --- a/SteamworksExample/StatsAndAchievements.cpp +++ b/SteamworksExample/StatsAndAchievements.cpp @@ -305,9 +305,9 @@ void CStatsAndAchievements::OnUserStatsReceived( UserStatsReceived_t *pCallback { Achievement_t &ach = g_rgAchievements[iAch]; m_pSteamUserStats->GetAchievement( ach.m_pchAchievementID, &ach.m_bAchieved ); - _snprintf( ach.m_rgchName, sizeof( ach.m_rgchName ), "%s", + sprintf_safe( ach.m_rgchName, "%s", m_pSteamUserStats->GetAchievementDisplayAttribute( ach.m_pchAchievementID, "name" ) ); - _snprintf( ach.m_rgchDescription, sizeof( ach.m_rgchDescription ), "%s", + sprintf_safe( ach.m_rgchDescription, "%s", m_pSteamUserStats->GetAchievementDisplayAttribute( ach.m_pchAchievementID, "desc" ) ); } @@ -324,7 +324,7 @@ void CStatsAndAchievements::OnUserStatsReceived( UserStatsReceived_t *pCallback else { char buffer[128]; - _snprintf( buffer, sizeof(buffer), "RequestStats - failed, %d\n", pCallback->m_eResult ); + sprintf_safe( buffer, "RequestStats - failed, %d\n", pCallback->m_eResult ); buffer[ sizeof(buffer) - 1 ] = 0; OutputDebugString( buffer ); } @@ -359,7 +359,7 @@ void CStatsAndAchievements::OnUserStatsStored( UserStatsStored_t *pCallback ) else { char buffer[128]; - _snprintf( buffer, sizeof(buffer), "StoreStats - failed, %d\n", pCallback->m_eResult ); + sprintf_safe( buffer, "StoreStats - failed, %d\n", pCallback->m_eResult ); buffer[ sizeof(buffer) - 1 ] = 0; OutputDebugString( buffer ); } @@ -377,14 +377,14 @@ void CStatsAndAchievements::OnAchievementStored( UserAchievementStored_t *pCallb if ( 0 == pCallback->m_nMaxProgress ) { char buffer[128]; - _snprintf( buffer, sizeof(buffer), "Achievement '%s' unlocked!", pCallback->m_rgchAchievementName ); + sprintf_safe( buffer, "Achievement '%s' unlocked!", pCallback->m_rgchAchievementName ); buffer[ sizeof(buffer) - 1 ] = 0; OutputDebugString( buffer ); } else { char buffer[128]; - _snprintf( buffer, sizeof(buffer), "Achievement '%s' progress callback, (%d,%d)\n", + sprintf_safe( buffer, "Achievement '%s' progress callback, (%d,%d)\n", pCallback->m_rgchAchievementName, pCallback->m_nCurProgress, pCallback->m_nMaxProgress ); buffer[ sizeof(buffer) - 1 ] = 0; OutputDebugString( buffer ); @@ -407,9 +407,9 @@ void CStatsAndAchievements::OnPS3TrophiesInstalled( PS3TrophiesInstalled_t *pCal // could not display that error, you should display the appropriate message to the user then exit. char buffer[256]; if ( pCallback->m_eResult == k_EResultDiskFull ) - _snprintf( buffer, 256, "Failed to install PS3 trophies because the HD is full (required space=%llu)\n", pCallback->m_ulRequiredDiskSpace ); + sprintf_safe( buffer, "Failed to install PS3 trophies because the HD is full (required space=%llu)\n", pCallback->m_ulRequiredDiskSpace ); else - _snprintf( buffer, 256, "Failed to install PS3 trophies (%d)", pCallback->m_eResult ); + sprintf_safe( buffer, "Failed to install PS3 trophies (%d)", pCallback->m_eResult ); buffer[ sizeof(buffer) - 1 ] = 0; OutputDebugString( buffer ); @@ -442,7 +442,7 @@ void CStatsAndAchievements::Render() rect.right = width; char rgchBuffer[256]; - _snprintf( rgchBuffer, sizeof( rgchBuffer), "Unable to retrieve data from Steam\n" ); + sprintf_safe( rgchBuffer, "Unable to retrieve data from Steam\n" ); m_pGameEngine->BDrawString( m_hDisplayFont, rect, D3DCOLOR_ARGB( 255, 25, 200, 25 ), TEXTPOS_CENTER|TEXTPOS_VCENTER, rgchBuffer ); @@ -451,7 +451,7 @@ void CStatsAndAchievements::Render() rect.top = LONG(m_pGameEngine->GetViewportHeight() * 0.7); rect.bottom = m_pGameEngine->GetViewportHeight(); - _snprintf( rgchBuffer, sizeof( rgchBuffer ), "Press ESC to return to the Main Menu" ); + sprintf_safe( rgchBuffer, "Press ESC to return to the Main Menu" ); m_pGameEngine->BDrawString( m_hDisplayFont, rect, D3DCOLOR_ARGB( 255, 25, 200, 25 ), TEXTPOS_CENTER|TEXTPOS_TOP, rgchBuffer ); } @@ -541,7 +541,7 @@ void CStatsAndAchievements::Render() rect.bottom = m_pGameEngine->GetViewportHeight(); char rgchBuffer[256]; - _snprintf( rgchBuffer, sizeof( rgchBuffer ), "Press ESC to return to the Main Menu" ); + sprintf_safe( rgchBuffer, "Press ESC to return to the Main Menu" ); m_pGameEngine->BDrawString( m_hDisplayFont, rect, D3DCOLOR_ARGB( 255, 25, 200, 25 ), TEXTPOS_CENTER|TEXTPOS_TOP, rgchBuffer ); } @@ -570,7 +570,7 @@ void CStatsAndAchievements::DrawAchievementInfo( RECT &rect, Achievement_t &ach // todo: divide up so can draw image char rgchBuffer[256]; - _snprintf( rgchBuffer, sizeof( rgchBuffer), "%s: %s\n%s", + sprintf_safe( rgchBuffer, "%s: %s\n%s", ach.m_rgchName, ach.m_bAchieved ? "Unlocked" : "Locked", ach.m_rgchDescription ); @@ -582,7 +582,7 @@ void CStatsAndAchievements::DrawStatInfo( RECT &rect, const char *pchName, float { // todo: divide up so can draw image char rgchBuffer[256]; - _snprintf( rgchBuffer, sizeof( rgchBuffer), "%s: %.1f", pchName, flValue ); + sprintf_safe( rgchBuffer, "%s: %.1f", pchName, flValue ); m_pGameEngine->BDrawString( m_hDisplayFont, rect, D3DCOLOR_ARGB( 255, 25, 200, 25 ), TEXTPOS_LEFT|TEXTPOS_VCENTER, rgchBuffer ); } @@ -651,4 +651,4 @@ bool CStatsAndAchievements::SaveUserStatsOnPS3() #else return true; #endif -} \ No newline at end of file +} diff --git a/SteamworksExample/stdafx.h b/SteamworksExample/stdafx.h index 82fc350..7d5bb59 100644 --- a/SteamworksExample/stdafx.h +++ b/SteamworksExample/stdafx.h @@ -13,6 +13,8 @@ #pragma once +#include +#include #define MAX(a,b) (((a) > (b)) ? (a) : (b)) #define MIN(a,b) (((a) < (b)) ? (a) : (b)) @@ -73,8 +75,10 @@ typedef unsigned __int64 uint64; #elif defined(POSIX) +#include #include #include +#include #include #include #include @@ -183,15 +187,39 @@ extern void OutputDebugString( const char *pchMsg ); extern int Alert( const char *lpCaption, const char *lpText ); extern const char *GetUserSaveDataPath(); -// No _snprintf on POSIX, use snprintf -#ifndef _snprintf -#define _snprintf snprintf -#endif - #define Q_ARRAYSIZE(a) sizeof(a)/sizeof(a[0]) #endif // POSIX +// OUT_Z_ARRAY indicates an output array that will be null-terminated. +#if _MSC_VER >= 1600 + // Include the annotation header file. + #include + #if _MSC_VER >= 1700 + // VS 2012+ + #define OUT_Z_ARRAY _Post_z_ + #else + // VS 2010 + #define OUT_Z_ARRAY _Deref_post_z_ + #endif +#else + // gcc, clang, old versions of VS + #define OUT_Z_ARRAY +#endif + +template void sprintf_safe(OUT_Z_ARRAY char (&pDest)[maxLenInChars], const char *pFormat, ... ) +{ + va_list params; + va_start( params, pFormat ); +#ifdef POSIX + vsnprintf( pDest, maxLenInChars, pFormat, params ); +#else + _vsnprintf( pDest, maxLenInChars, pFormat, params ); +#endif + pDest[maxLenInChars - 1] = '\0'; + va_end( params ); +} + #ifdef STEAM_CEG // Steam DRM header file #include "cegclient.h" diff --git a/SteamworksExample/steam_appid.txt b/SteamworksExample/steam_appid.txt deleted file mode 100644 index 7ad8022..0000000 --- a/SteamworksExample/steam_appid.txt +++ /dev/null @@ -1 +0,0 @@ -480 \ No newline at end of file diff --git a/client/steam.exe b/client/steam.exe index c4e0bc0..e31211b 100644 Binary files a/client/steam.exe and b/client/steam.exe differ diff --git a/glmgr/glmgrcocoa.mm b/glmgr/glmgrcocoa.mm index 178bb92..42269ea 100644 --- a/glmgr/glmgrcocoa.mm +++ b/glmgr/glmgrcocoa.mm @@ -1035,6 +1035,7 @@ void GLMDisplayDB::PopulateRenderers( void ) if(vendorID) { fields.m_pciVendorID = *((UInt32*)CFDataGetBytePtr(vendorID)); + CFRelease( vendorID ); } else { @@ -1044,6 +1045,7 @@ void GLMDisplayDB::PopulateRenderers( void ) if(deviceID) { fields.m_pciDeviceID = *((UInt32*)CFDataGetBytePtr(deviceID)); + CFRelease( deviceID ); } else { @@ -1055,6 +1057,7 @@ void GLMDisplayDB::PopulateRenderers( void ) int length = CFDataGetLength(model); char *data = (char*)CFDataGetBytePtr(model); strncpy( fields.m_pciModelString, data, sizeof(fields.m_pciModelString) ); + CFRelease( model ); } else { diff --git a/public/steam/isteamapps.h b/public/steam/isteamapps.h index 54298ca..cea14d3 100644 --- a/public/steam/isteamapps.h +++ b/public/steam/isteamapps.h @@ -63,6 +63,7 @@ public: // returns current app install folder for AppID, returns folder name length virtual uint32 GetAppInstallDir( AppId_t appID, char *pchFolder, uint32 cchFolderBufferSize ) = 0; + virtual bool BIsAppInstalled( AppId_t appID ) = 0; #ifdef _PS3 // Result returned in a RegisterActivationCodeResponse_t callresult diff --git a/public/steam/isteamclient.h b/public/steam/isteamclient.h index d3fe131..53b2fbc 100644 --- a/public/steam/isteamclient.h +++ b/public/steam/isteamclient.h @@ -222,6 +222,13 @@ enum { k_iClientScreenshotsCallbacks = 2200 }; enum { k_iSteamScreenshotsCallbacks = 2300 }; enum { k_iClientAudioCallbacks = 2400 }; enum { k_iClientUnifiedMessagesCallbacks = 2500 }; +enum { k_iSteamStreamLauncherCallbacks = 2600 }; +enum { k_iClientControllerCallbacks = 2700 }; +enum { k_iSteamControllerCallbacks = 2800 }; +enum { k_iClientParentalSettingsCallbacks = 2900 }; +enum { k_iClientDeviceAuthCallbacks = 3000 }; +enum { k_iClientNetworkDeviceManagerCallbacks = 3100 }; +enum { k_iClientMusicCallbacks = 3200 }; //----------------------------------------------------------------------------- diff --git a/public/steam/isteamcontroller.h b/public/steam/isteamcontroller.h new file mode 100644 index 0000000..e7ef50d --- /dev/null +++ b/public/steam/isteamcontroller.h @@ -0,0 +1,62 @@ +//====== Copyright 1996-2013, Valve Corporation, All rights reserved. ======= +// +// Purpose: interface to valve controller +// +//============================================================================= + +#ifndef ISTEAMCONTROLLER_H +#define ISTEAMCONTROLLER_H +#ifdef _WIN32 +#pragma once +#endif + +#include "isteamclient.h" + +// callbacks +#if defined( VALVE_CALLBACK_PACK_SMALL ) +#pragma pack( push, 4 ) +#elif defined( VALVE_CALLBACK_PACK_LARGE ) +#pragma pack( push, 8 ) +#else +#error isteamclient.h must be included +#endif + + +#pragma pack( pop ) + +//----------------------------------------------------------------------------- +// Purpose: Functions for accessing stats, achievements, and leaderboard information +//----------------------------------------------------------------------------- +class ISteamController +{ +public: + +}; + +#define STEAMCONTROLLER_INTERFACE_VERSION "STEAMCONTROLLER_INTERFACE_VERSION" + +// callbacks +#if defined( VALVE_CALLBACK_PACK_SMALL ) +#pragma pack( push, 4 ) +#elif defined( VALVE_CALLBACK_PACK_LARGE ) +#pragma pack( push, 8 ) +#else +#error isteamclient.h must be included +#endif + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +/* +struct ControllerCallback_t +{ + enum { k_iCallback = k_iSteamControllerCallbacks + 1 }; + +}; +*/ + + +#pragma pack( pop ) + + +#endif // ISTEAMCONTROLLER_H diff --git a/public/steam/isteamfriends.h b/public/steam/isteamfriends.h index de51c79..6bdbfde 100644 --- a/public/steam/isteamfriends.h +++ b/public/steam/isteamfriends.h @@ -241,6 +241,10 @@ public: // "jointrade" - opens a window to a Steam Trading session that was started with the ISteamEconomy/StartTrade Web API // "stats" - opens the overlay web browser to the specified user's stats // "achievements" - opens the overlay web browser to the specified user's achievements + // "friendadd" - opens the overlay in minimal mode prompting the user to add the target user as a friend + // "friendremove" - opens the overlay in minimal mode prompting the user to remove the target friend + // "friendrequestaccept" - opens the overlay in minimal mode prompting the user to accept an incoming friend invite + // "friendrequestignore" - opens the overlay in minimal mode prompting the user to ignore an incoming friend invite virtual void ActivateGameOverlayToUser( const char *pchDialog, CSteamID steamID ) = 0; // activates game overlay web browser directly to the specified URL diff --git a/public/steam/isteamhttp.h b/public/steam/isteamhttp.h index 8d49732..9ac550a 100644 --- a/public/steam/isteamhttp.h +++ b/public/steam/isteamhttp.h @@ -87,7 +87,7 @@ public: // the correct buffer size to use. virtual bool GetHTTPResponseBodyData( HTTPRequestHandle hRequest, uint8 *pBodyDataBuffer, uint32 unBufferSize ) = 0; - // Gets the body data from a streaming HTTP response given a handle from HTTPRequestCompleted_t. Will return false if the + // Gets the body data from a streaming HTTP response given a handle from HTTPRequestDataReceived_t. Will return false if the // handle is invalid or is to a non-streaming response (meaning it wasn't sent with SendHTTPRequestAndStreamResponse), or if the buffer size and offset // do not match the size and offset sent in HTTPRequestDataReceived_t. virtual bool GetHTTPStreamingResponseBodyData( HTTPRequestHandle hRequest, uint32 cOffset, uint8 *pBodyDataBuffer, uint32 unBufferSize ) = 0; diff --git a/public/steam/isteamremotestorage.h b/public/steam/isteamremotestorage.h index 52324be..8e470de 100644 --- a/public/steam/isteamremotestorage.h +++ b/public/steam/isteamremotestorage.h @@ -101,7 +101,7 @@ enum EWorkshopFileType // Update k_EWorkshopFileTypeMax if you add values k_EWorkshopFileTypeMax = 11 - + }; enum EWorkshopVote @@ -140,113 +140,113 @@ enum EWorkshopVideoProvider //----------------------------------------------------------------------------- class ISteamRemoteStorage { - public: - // NOTE - // - // Filenames are case-insensitive, and will be converted to lowercase automatically. - // So "foo.bar" and "Foo.bar" are the same file, and if you write "Foo.bar" then - // iterate the files, the filename returned will be "foo.bar". - // +public: + // NOTE + // + // Filenames are case-insensitive, and will be converted to lowercase automatically. + // So "foo.bar" and "Foo.bar" are the same file, and if you write "Foo.bar" then + // iterate the files, the filename returned will be "foo.bar". + // - // file operations - virtual bool FileWrite( const char *pchFile, const void *pvData, int32 cubData ) = 0; - virtual int32 FileRead( const char *pchFile, void *pvData, int32 cubDataToRead ) = 0; - virtual bool FileForget( const char *pchFile ) = 0; - virtual bool FileDelete( const char *pchFile ) = 0; - virtual SteamAPICall_t FileShare( const char *pchFile ) = 0; - virtual bool SetSyncPlatforms( const char *pchFile, ERemoteStoragePlatform eRemoteStoragePlatform ) = 0; + // file operations + virtual bool FileWrite( const char *pchFile, const void *pvData, int32 cubData ) = 0; + virtual int32 FileRead( const char *pchFile, void *pvData, int32 cubDataToRead ) = 0; + virtual bool FileForget( const char *pchFile ) = 0; + virtual bool FileDelete( const char *pchFile ) = 0; + virtual SteamAPICall_t FileShare( const char *pchFile ) = 0; + virtual bool SetSyncPlatforms( const char *pchFile, ERemoteStoragePlatform eRemoteStoragePlatform ) = 0; - // file operations that cause network IO - virtual UGCFileWriteStreamHandle_t FileWriteStreamOpen( const char *pchFile ) = 0; - virtual bool FileWriteStreamWriteChunk( UGCFileWriteStreamHandle_t writeHandle, const void *pvData, int32 cubData ) = 0; - virtual bool FileWriteStreamClose( UGCFileWriteStreamHandle_t writeHandle ) = 0; - virtual bool FileWriteStreamCancel( UGCFileWriteStreamHandle_t writeHandle ) = 0; + // file operations that cause network IO + virtual UGCFileWriteStreamHandle_t FileWriteStreamOpen( const char *pchFile ) = 0; + virtual bool FileWriteStreamWriteChunk( UGCFileWriteStreamHandle_t writeHandle, const void *pvData, int32 cubData ) = 0; + virtual bool FileWriteStreamClose( UGCFileWriteStreamHandle_t writeHandle ) = 0; + virtual bool FileWriteStreamCancel( UGCFileWriteStreamHandle_t writeHandle ) = 0; - // file information - virtual bool FileExists( const char *pchFile ) = 0; - virtual bool FilePersisted( const char *pchFile ) = 0; - virtual int32 GetFileSize( const char *pchFile ) = 0; - virtual int64 GetFileTimestamp( const char *pchFile ) = 0; - virtual ERemoteStoragePlatform GetSyncPlatforms( const char *pchFile ) = 0; + // file information + virtual bool FileExists( const char *pchFile ) = 0; + virtual bool FilePersisted( const char *pchFile ) = 0; + virtual int32 GetFileSize( const char *pchFile ) = 0; + virtual int64 GetFileTimestamp( const char *pchFile ) = 0; + virtual ERemoteStoragePlatform GetSyncPlatforms( const char *pchFile ) = 0; - // iteration - virtual int32 GetFileCount() = 0; - virtual const char *GetFileNameAndSize( int iFile, int32 *pnFileSizeInBytes ) = 0; + // iteration + virtual int32 GetFileCount() = 0; + virtual const char *GetFileNameAndSize( int iFile, int32 *pnFileSizeInBytes ) = 0; - // configuration management - virtual bool GetQuota( int32 *pnTotalBytes, int32 *puAvailableBytes ) = 0; - virtual bool IsCloudEnabledForAccount() = 0; - virtual bool IsCloudEnabledForApp() = 0; - virtual void SetCloudEnabledForApp( bool bEnabled ) = 0; + // configuration management + virtual bool GetQuota( int32 *pnTotalBytes, int32 *puAvailableBytes ) = 0; + virtual bool IsCloudEnabledForAccount() = 0; + virtual bool IsCloudEnabledForApp() = 0; + virtual void SetCloudEnabledForApp( bool bEnabled ) = 0; - // user generated content + // user generated content - // Downloads a UGC file. A priority value of 0 will download the file immediately, - // otherwise it will wait to download the file until all downloads with a lower priority - // value are completed. Downloads with equal priority will occur simultaneously. - virtual SteamAPICall_t UGCDownload( UGCHandle_t hContent, uint32 unPriority ) = 0; - - // Gets the amount of data downloaded so far for a piece of content. pnBytesExpected can be 0 if function returns false - // or if the transfer hasn't started yet, so be careful to check for that before dividing to get a percentage - virtual bool GetUGCDownloadProgress( UGCHandle_t hContent, int32 *pnBytesDownloaded, int32 *pnBytesExpected ) = 0; + // Downloads a UGC file. A priority value of 0 will download the file immediately, + // otherwise it will wait to download the file until all downloads with a lower priority + // value are completed. Downloads with equal priority will occur simultaneously. + virtual SteamAPICall_t UGCDownload( UGCHandle_t hContent, uint32 unPriority ) = 0; - // Gets metadata for a file after it has been downloaded. This is the same metadata given in the RemoteStorageDownloadUGCResult_t call result - virtual bool GetUGCDetails( UGCHandle_t hContent, AppId_t *pnAppID, char **ppchName, int32 *pnFileSizeInBytes, CSteamID *pSteamIDOwner ) = 0; + // Gets the amount of data downloaded so far for a piece of content. pnBytesExpected can be 0 if function returns false + // or if the transfer hasn't started yet, so be careful to check for that before dividing to get a percentage + virtual bool GetUGCDownloadProgress( UGCHandle_t hContent, int32 *pnBytesDownloaded, int32 *pnBytesExpected ) = 0; - // After download, gets the content of the file - virtual int32 UGCRead( UGCHandle_t hContent, void *pvData, int32 cubDataToRead, uint32 cOffset ) = 0; + // Gets metadata for a file after it has been downloaded. This is the same metadata given in the RemoteStorageDownloadUGCResult_t call result + virtual bool GetUGCDetails( UGCHandle_t hContent, AppId_t *pnAppID, char **ppchName, int32 *pnFileSizeInBytes, CSteamID *pSteamIDOwner ) = 0; - // Functions to iterate through UGC that has finished downloading but has not yet been read via UGCRead() - virtual int32 GetCachedUGCCount() = 0; - virtual UGCHandle_t GetCachedUGCHandle( int32 iCachedContent ) = 0; + // After download, gets the content of the file + virtual int32 UGCRead( UGCHandle_t hContent, void *pvData, int32 cubDataToRead, uint32 cOffset ) = 0; + + // Functions to iterate through UGC that has finished downloading but has not yet been read via UGCRead() + virtual int32 GetCachedUGCCount() = 0; + virtual UGCHandle_t GetCachedUGCHandle( int32 iCachedContent ) = 0; + + // The following functions are only necessary on the Playstation 3. On PC & Mac, the Steam client will handle these operations for you + // On Playstation 3, the game controls which files are stored in the cloud, via FilePersist, FileFetch, and FileForget. - // The following functions are only necessary on the Playstation 3. On PC & Mac, the Steam client will handle these operations for you - // On Playstation 3, the game controls which files are stored in the cloud, via FilePersist, FileFetch, and FileForget. - #if defined(_PS3) || defined(_SERVER) - // Connect to Steam and get a list of files in the Cloud - results in a RemoteStorageAppSyncStatusCheck_t callback - virtual void GetFileListFromServer() = 0; - // Indicate this file should be downloaded in the next sync - virtual bool FileFetch( const char *pchFile ) = 0; - // Indicate this file should be persisted in the next sync - virtual bool FilePersist( const char *pchFile ) = 0; - // Pull any requested files down from the Cloud - results in a RemoteStorageAppSyncedClient_t callback - virtual bool SynchronizeToClient() = 0; - // Upload any requested files to the Cloud - results in a RemoteStorageAppSyncedServer_t callback - virtual bool SynchronizeToServer() = 0; - // Reset any fetch/persist/etc requests - virtual bool ResetFileRequestState() = 0; + // Connect to Steam and get a list of files in the Cloud - results in a RemoteStorageAppSyncStatusCheck_t callback + virtual void GetFileListFromServer() = 0; + // Indicate this file should be downloaded in the next sync + virtual bool FileFetch( const char *pchFile ) = 0; + // Indicate this file should be persisted in the next sync + virtual bool FilePersist( const char *pchFile ) = 0; + // Pull any requested files down from the Cloud - results in a RemoteStorageAppSyncedClient_t callback + virtual bool SynchronizeToClient() = 0; + // Upload any requested files to the Cloud - results in a RemoteStorageAppSyncedServer_t callback + virtual bool SynchronizeToServer() = 0; + // Reset any fetch/persist/etc requests + virtual bool ResetFileRequestState() = 0; #endif - // publishing UGC - virtual SteamAPICall_t PublishWorkshopFile( const char *pchFile, const char *pchPreviewFile, AppId_t nConsumerAppId, const char *pchTitle, const char *pchDescription, ERemoteStoragePublishedFileVisibility eVisibility, SteamParamStringArray_t *pTags, EWorkshopFileType eWorkshopFileType ) = 0; - virtual PublishedFileUpdateHandle_t CreatePublishedFileUpdateRequest( PublishedFileId_t unPublishedFileId ) = 0; - virtual bool UpdatePublishedFileFile( PublishedFileUpdateHandle_t updateHandle, const char *pchFile ) = 0; - virtual bool UpdatePublishedFilePreviewFile( PublishedFileUpdateHandle_t updateHandle, const char *pchPreviewFile ) = 0; - virtual bool UpdatePublishedFileTitle( PublishedFileUpdateHandle_t updateHandle, const char *pchTitle ) = 0; - virtual bool UpdatePublishedFileDescription( PublishedFileUpdateHandle_t updateHandle, const char *pchDescription ) = 0; - virtual bool UpdatePublishedFileVisibility( PublishedFileUpdateHandle_t updateHandle, ERemoteStoragePublishedFileVisibility eVisibility ) = 0; - virtual bool UpdatePublishedFileTags( PublishedFileUpdateHandle_t updateHandle, SteamParamStringArray_t *pTags ) = 0; - virtual SteamAPICall_t CommitPublishedFileUpdate( PublishedFileUpdateHandle_t updateHandle ) = 0; - virtual SteamAPICall_t GetPublishedFileDetails( PublishedFileId_t unPublishedFileId ) = 0; - virtual SteamAPICall_t DeletePublishedFile( PublishedFileId_t unPublishedFileId ) = 0; - // enumerate the files that the current user published with this app - virtual SteamAPICall_t EnumerateUserPublishedFiles( uint32 unStartIndex ) = 0; - virtual SteamAPICall_t SubscribePublishedFile( PublishedFileId_t unPublishedFileId ) = 0; - virtual SteamAPICall_t EnumerateUserSubscribedFiles( uint32 unStartIndex ) = 0; - virtual SteamAPICall_t UnsubscribePublishedFile( PublishedFileId_t unPublishedFileId ) = 0; - virtual bool UpdatePublishedFileSetChangeDescription( PublishedFileUpdateHandle_t updateHandle, const char *pchChangeDescription ) = 0; - virtual SteamAPICall_t GetPublishedItemVoteDetails( PublishedFileId_t unPublishedFileId ) = 0; - virtual SteamAPICall_t UpdateUserPublishedItemVote( PublishedFileId_t unPublishedFileId, bool bVoteUp ) = 0; - virtual SteamAPICall_t GetUserPublishedItemVoteDetails( PublishedFileId_t unPublishedFileId ) = 0; - virtual SteamAPICall_t EnumerateUserSharedWorkshopFiles( CSteamID steamId, uint32 unStartIndex, SteamParamStringArray_t *pRequiredTags, SteamParamStringArray_t *pExcludedTags ) = 0; - virtual SteamAPICall_t PublishVideo( EWorkshopVideoProvider eVideoProvider, const char *pchVideoAccount, const char *pchVideoIdentifier, const char *pchPreviewFile, AppId_t nConsumerAppId, const char *pchTitle, const char *pchDescription, ERemoteStoragePublishedFileVisibility eVisibility, SteamParamStringArray_t *pTags ) = 0; - virtual SteamAPICall_t SetUserPublishedFileAction( PublishedFileId_t unPublishedFileId, EWorkshopFileAction eAction ) = 0; - virtual SteamAPICall_t EnumeratePublishedFilesByUserAction( EWorkshopFileAction eAction, uint32 unStartIndex ) = 0; - // this method enumerates the public view of workshop files - virtual SteamAPICall_t EnumeratePublishedWorkshopFiles( EWorkshopEnumerationType eEnumerationType, uint32 unStartIndex, uint32 unCount, uint32 unDays, SteamParamStringArray_t *pTags, SteamParamStringArray_t *pUserTags ) = 0; + // publishing UGC + virtual SteamAPICall_t PublishWorkshopFile( const char *pchFile, const char *pchPreviewFile, AppId_t nConsumerAppId, const char *pchTitle, const char *pchDescription, ERemoteStoragePublishedFileVisibility eVisibility, SteamParamStringArray_t *pTags, EWorkshopFileType eWorkshopFileType ) = 0; + virtual PublishedFileUpdateHandle_t CreatePublishedFileUpdateRequest( PublishedFileId_t unPublishedFileId ) = 0; + virtual bool UpdatePublishedFileFile( PublishedFileUpdateHandle_t updateHandle, const char *pchFile ) = 0; + virtual bool UpdatePublishedFilePreviewFile( PublishedFileUpdateHandle_t updateHandle, const char *pchPreviewFile ) = 0; + virtual bool UpdatePublishedFileTitle( PublishedFileUpdateHandle_t updateHandle, const char *pchTitle ) = 0; + virtual bool UpdatePublishedFileDescription( PublishedFileUpdateHandle_t updateHandle, const char *pchDescription ) = 0; + virtual bool UpdatePublishedFileVisibility( PublishedFileUpdateHandle_t updateHandle, ERemoteStoragePublishedFileVisibility eVisibility ) = 0; + virtual bool UpdatePublishedFileTags( PublishedFileUpdateHandle_t updateHandle, SteamParamStringArray_t *pTags ) = 0; + virtual SteamAPICall_t CommitPublishedFileUpdate( PublishedFileUpdateHandle_t updateHandle ) = 0; + virtual SteamAPICall_t GetPublishedFileDetails( PublishedFileId_t unPublishedFileId ) = 0; + virtual SteamAPICall_t DeletePublishedFile( PublishedFileId_t unPublishedFileId ) = 0; + // enumerate the files that the current user published with this app + virtual SteamAPICall_t EnumerateUserPublishedFiles( uint32 unStartIndex ) = 0; + virtual SteamAPICall_t SubscribePublishedFile( PublishedFileId_t unPublishedFileId ) = 0; + virtual SteamAPICall_t EnumerateUserSubscribedFiles( uint32 unStartIndex ) = 0; + virtual SteamAPICall_t UnsubscribePublishedFile( PublishedFileId_t unPublishedFileId ) = 0; + virtual bool UpdatePublishedFileSetChangeDescription( PublishedFileUpdateHandle_t updateHandle, const char *pchChangeDescription ) = 0; + virtual SteamAPICall_t GetPublishedItemVoteDetails( PublishedFileId_t unPublishedFileId ) = 0; + virtual SteamAPICall_t UpdateUserPublishedItemVote( PublishedFileId_t unPublishedFileId, bool bVoteUp ) = 0; + virtual SteamAPICall_t GetUserPublishedItemVoteDetails( PublishedFileId_t unPublishedFileId ) = 0; + virtual SteamAPICall_t EnumerateUserSharedWorkshopFiles( CSteamID steamId, uint32 unStartIndex, SteamParamStringArray_t *pRequiredTags, SteamParamStringArray_t *pExcludedTags ) = 0; + virtual SteamAPICall_t PublishVideo( EWorkshopVideoProvider eVideoProvider, const char *pchVideoAccount, const char *pchVideoIdentifier, const char *pchPreviewFile, AppId_t nConsumerAppId, const char *pchTitle, const char *pchDescription, ERemoteStoragePublishedFileVisibility eVisibility, SteamParamStringArray_t *pTags ) = 0; + virtual SteamAPICall_t SetUserPublishedFileAction( PublishedFileId_t unPublishedFileId, EWorkshopFileAction eAction ) = 0; + virtual SteamAPICall_t EnumeratePublishedFilesByUserAction( EWorkshopFileAction eAction, uint32 unStartIndex ) = 0; + // this method enumerates the public view of workshop files + virtual SteamAPICall_t EnumeratePublishedWorkshopFiles( EWorkshopEnumerationType eEnumerationType, uint32 unStartIndex, uint32 unCount, uint32 unDays, SteamParamStringArray_t *pTags, SteamParamStringArray_t *pUserTags ) = 0; - virtual SteamAPICall_t UGCDownloadToLocation( UGCHandle_t hContent, const char *pchLocation, uint32 unPriority ) = 0; + virtual SteamAPICall_t UGCDownloadToLocation( UGCHandle_t hContent, const char *pchLocation, uint32 unPriority ) = 0; }; #define STEAMREMOTESTORAGE_INTERFACE_VERSION "STEAMREMOTESTORAGE_INTERFACE_VERSION010" @@ -399,9 +399,9 @@ struct RemoteStorageEnumerateUserSubscribedFilesResult_t }; #if defined(VALVE_CALLBACK_PACK_SMALL) - VALVE_COMPILE_TIME_ASSERT( sizeof( RemoteStorageEnumerateUserSubscribedFilesResult_t ) == (1 + 1 + 1 + 50 + 100) * 4 ); +VALVE_COMPILE_TIME_ASSERT( sizeof( RemoteStorageEnumerateUserSubscribedFilesResult_t ) == (1 + 1 + 1 + 50 + 100) * 4 ); #elif defined(VALVE_CALLBACK_PACK_LARGE) - VALVE_COMPILE_TIME_ASSERT( sizeof( RemoteStorageEnumerateUserSubscribedFilesResult_t ) == (1 + 1 + 1 + 50 + 100) * 4 + 4 ); +VALVE_COMPILE_TIME_ASSERT( sizeof( RemoteStorageEnumerateUserSubscribedFilesResult_t ) == (1 + 1 + 1 + 50 + 100) * 4 + 4 ); #else #warning You must first include isteamclient.h #endif diff --git a/public/steam/isteamuser.h b/public/steam/isteamuser.h index 6167475..9bf486e 100644 --- a/public/steam/isteamuser.h +++ b/public/steam/isteamuser.h @@ -158,6 +158,14 @@ public: // retrieve a finished ticket virtual bool GetEncryptedAppTicket( void *pTicket, int cbMaxTicket, uint32 *pcbTicket ) = 0; + // Trading Card badges data access + // if you only have one set of cards, the series will be 1 + // the user has can have two different badges for a series; the regular (max level 5) and the foil (max level 1) + virtual int GetGameBadgeLevel( int nSeries, bool bFoil ) = 0; + + // gets the Steam Level of the user, as shown on their profile + virtual int GetPlayerSteamLevel() = 0; + #ifdef _PS3 // Initiates PS3 Logon request using just PSN ticket. // @@ -197,7 +205,7 @@ public: }; -#define STEAMUSER_INTERFACE_VERSION "SteamUser016" +#define STEAMUSER_INTERFACE_VERSION "SteamUser017" // callbacks diff --git a/public/steam/isteamutils.h b/public/steam/isteamutils.h index c335338..e3f462d 100644 --- a/public/steam/isteamutils.h +++ b/public/steam/isteamutils.h @@ -154,9 +154,12 @@ public: // Returns previously entered text & length virtual uint32 GetEnteredGamepadTextLength() = 0; virtual bool GetEnteredGamepadTextInput( char *pchText, uint32 cchText ) = 0; + + // returns the language the steam client is running in, you probably want ISteamApps::GetCurrentGameLanguage instead, this is for very special usage cases + virtual const char *GetSteamUILanguage() = 0; }; -#define STEAMUTILS_INTERFACE_VERSION "SteamUtils005" +#define STEAMUTILS_INTERFACE_VERSION "SteamUtils006" // callbacks @@ -294,6 +297,7 @@ struct GamepadTextInputDismissed_t uint32 m_unSubmittedText; }; +// k_iSteamUtilsCallbacks + 15 is taken #pragma pack( pop ) diff --git a/public/steam/lib/linux32/libsdkencryptedappticket.so b/public/steam/lib/linux32/libsdkencryptedappticket.so index 93229cd..9e242c0 100644 Binary files a/public/steam/lib/linux32/libsdkencryptedappticket.so and b/public/steam/lib/linux32/libsdkencryptedappticket.so differ diff --git a/public/steam/lib/osx32/libsdkencryptedappticket.dylib b/public/steam/lib/osx32/libsdkencryptedappticket.dylib new file mode 100644 index 0000000..e243721 Binary files /dev/null and b/public/steam/lib/osx32/libsdkencryptedappticket.dylib differ diff --git a/public/steam/lib/win32/sdkencryptedappticket.dll b/public/steam/lib/win32/sdkencryptedappticket.dll index 3c58051..17ae7d6 100644 Binary files a/public/steam/lib/win32/sdkencryptedappticket.dll and b/public/steam/lib/win32/sdkencryptedappticket.dll differ diff --git a/public/steam/lib/win32/sdkencryptedappticket.lib b/public/steam/lib/win32/sdkencryptedappticket.lib index ed6f0a1..ad59865 100644 Binary files a/public/steam/lib/win32/sdkencryptedappticket.lib and b/public/steam/lib/win32/sdkencryptedappticket.lib differ diff --git a/public/steam/lib/win64/sdkencryptedappticket64.dll b/public/steam/lib/win64/sdkencryptedappticket64.dll index 325964c..e385a34 100644 Binary files a/public/steam/lib/win64/sdkencryptedappticket64.dll and b/public/steam/lib/win64/sdkencryptedappticket64.dll differ diff --git a/public/steam/lib/win64/sdkencryptedappticket64.lib b/public/steam/lib/win64/sdkencryptedappticket64.lib index 056a98c..bf5bc75 100644 Binary files a/public/steam/lib/win64/sdkencryptedappticket64.lib and b/public/steam/lib/win64/sdkencryptedappticket64.lib differ diff --git a/public/steam/steam_api.h b/public/steam/steam_api.h index bcdd7c2..b6cf596 100644 --- a/public/steam/steam_api.h +++ b/public/steam/steam_api.h @@ -22,6 +22,7 @@ #include "isteamscreenshots.h" #include "isteamhttp.h" #include "isteamunifiedmessages.h" +#include "isteamcontroller.h" #if defined( _PS3 ) #include "steamps3params.h" @@ -413,6 +414,7 @@ private: ISteamScreenshots *m_pSteamScreenshots; ISteamHTTP *m_pSteamHTTP; ISteamUnifiedMessages*m_pSteamUnifiedMessages; + ISteamController *m_pController; #ifdef _PS3 ISteamPS3OverlayRender *m_pSteamPS3OverlayRender; #endif @@ -510,8 +512,8 @@ inline bool CSteamAPIContext::Init() #if defined(USE_BREAKPAD_HANDLER) || defined(STEAM_API_EXPORTS) // this should be called before the game initialized the steam APIs -// pchDate should be of the format "Mmm dd yyyy" (such as from the __DATE__ macro ) -// pchTime should be of the format "hh:mm:ss" (such as from the __TIME__ macro ) +// pchDate should be of the format "Mmm dd yyyy" (such as from the __DATE __ macro ) +// pchTime should be of the format "hh:mm:ss" (such as from the __TIME __ macro ) // bFullMemoryDumps (Win32 only) -- writes out a uuid-full.dmp in the client/dumps folder // pvContext-- can be NULL, will be the void * context passed into m_pfnPreMinidumpCallback // PFNPreMinidumpCallback m_pfnPreMinidumpCallback -- optional callback which occurs just before a .dmp file is written during a crash. Applications can hook this to allow adding additional information into the .dmp comment stream. diff --git a/public/steam/steamclientpublic.h b/public/steam/steamclientpublic.h index c80eabb..3890876 100644 --- a/public/steam/steamclientpublic.h +++ b/public/steam/steamclientpublic.h @@ -20,7 +20,7 @@ // interface layer, no need to include anything about the implementation. #include "steamtypes.h" - +#include "steamuniverse.h" // General result codes enum EResult @@ -178,18 +178,6 @@ typedef enum } EUserHasLicenseForAppResult; -// Steam universes. Each universe is a self-contained Steam instance. -enum EUniverse -{ - k_EUniverseInvalid = 0, - k_EUniversePublic = 1, - k_EUniverseBeta = 2, - k_EUniverseInternal = 3, - k_EUniverseDev = 4, - // k_EUniverseRC = 5, // no such universe anymore - k_EUniverseMax -}; - // Steam account types enum EAccountType { @@ -235,6 +223,9 @@ enum EAppOwernshipFlags k_EAppOwernshipFlags_RegionRestricted = 4, // owns app, but not allowed to play in current region k_EAppOwernshipFlags_LowViolence = 8, // only low violence version k_EAppOwernshipFlags_InvalidPlatform = 16, // app not supported on current platform + k_EAppOwernshipFlags_SharedLicense = 32, // license was granted by authorized local device + k_EAppOwernshipFlags_FreeWeekend = 64, // owned by a free weekend licenses + k_EAppOwernshipFlags_LicenseLocked = 128, // shared license is locked (in use) by other user }; @@ -252,7 +243,8 @@ enum EAppType k_EAppType_DLC = 0x020, // down loadable content k_EAppType_Guide = 0x040, // game guide, PDF etc k_EAppType_Driver = 0x080, // hardware driver updater (ATI, Razor etc) - + k_EAppType_Config = 0x100, // hidden app used to config Steam features (backpack, sales, etc) + k_EAppType_Shortcut = 0x40000000, // just a shortcut, client side only k_EAppType_DepotOnly = 0x80000000, // placeholder since depots and apps share the same namespace }; @@ -448,6 +440,12 @@ public: { SetFromUint64( ulSteamID ); } +#ifdef INT64_DIFFERENT_FROM_INT64_T + CSteamID( uint64_t ulSteamID ) + { + SetFromUint64( (uint64)ulSteamID ); + } +#endif //----------------------------------------------------------------------------- @@ -512,6 +510,18 @@ public: } + //----------------------------------------------------------------------------- + // Purpose: Clear all fields, leaving an invalid ID. + //----------------------------------------------------------------------------- + void Clear() + { + m_steamid.m_comp.m_unAccountID = 0; + m_steamid.m_comp.m_EAccountType = k_EAccountTypeInvalid; + m_steamid.m_comp.m_EUniverse = k_EUniverseInvalid; + m_steamid.m_comp.m_unAccountInstance = 0; + } + + #if defined( INCLUDED_STEAM_COMMON_STEAMCOMMON_H ) //----------------------------------------------------------------------------- // Purpose: Initializes a steam ID from a Steam2 ID structure @@ -708,6 +718,12 @@ public: static const char * Render( uint64 ulSteamID ); // static method to render a uint64 representation of a steam ID to a string void SetFromString( const char *pchSteamID, EUniverse eDefaultUniverse ); + // SetFromString allows many partially-correct strings, constraining how + // we might be able to change things in the future. + // SetFromStringStrict requires the exact string forms that we support + // and is preferred when the caller knows it's safe to be strict. + // Returns whether the string parsed correctly. + bool SetFromStringStrict( const char *pchSteamID, EUniverse eDefaultUniverse ); bool SetFromSteam2String( const char *pchSteam2ID, EUniverse eUniverse ); inline bool operator==( const CSteamID &val ) const { return m_steamid.m_unAll64Bits == val.m_steamid.m_unAll64Bits; } @@ -826,6 +842,12 @@ public: { m_ulGameID = ulGameID; } +#ifdef INT64_DIFFERENT_FROM_INT64_T + CGameID( uint64_t ulGameID ) + { + m_ulGameID = (uint64)ulGameID; + } +#endif explicit CGameID( int32 nAppID ) { diff --git a/public/steam/steamhttpenums.h b/public/steam/steamhttpenums.h index fcfac07..ddd3a3c 100644 --- a/public/steam/steamhttpenums.h +++ b/public/steam/steamhttpenums.h @@ -24,9 +24,9 @@ enum EHTTPMethod // The remaining HTTP methods are not yet supported, per rfc2616 section 5.1.1 only GET and HEAD are required for // a compliant general purpose server. We'll likely add more as we find uses for them. - // k_EHTTPMethodOPTIONS, k_EHTTPMethodPUT, k_EHTTPMethodDELETE, + k_EHTTPMethodOPTIONS, // k_EHTTPMethodTRACE, // k_EHTTPMethodCONNECT }; diff --git a/public/steam/steamtypes.h b/public/steam/steamtypes.h index 5d94a24..440aa89 100644 --- a/public/steam/steamtypes.h +++ b/public/steam/steamtypes.h @@ -43,6 +43,9 @@ typedef unsigned __int32 uint32; typedef __int64 int64; typedef unsigned __int64 uint64; +typedef int64 lint64; +typedef uint64 ulint64; + #ifdef X64BITS typedef __int64 intp; // intp is an integer that can accomodate a pointer typedef unsigned __int64 uintp; // (ie, sizeof(intp) >= sizeof(int) && sizeof(intp) >= sizeof(void *) @@ -59,6 +62,16 @@ typedef int int32; typedef unsigned int uint32; typedef long long int64; typedef unsigned long long uint64; + +// [u]int64 are actually defined as 'long long' and gcc 64-bit +// doesn't automatically consider them the same as 'long int'. +// Changing the types for [u]int64 is complicated by +// there being many definitions, so we just +// define a 'long int' here and use it in places that would +// otherwise confuse the compiler. +typedef long int lint64; +typedef unsigned long int ulint64; + #ifdef X64BITS typedef long long intp; typedef unsigned long long uintp; diff --git a/public/steam/steamuniverse.h b/public/steam/steamuniverse.h new file mode 100644 index 0000000..dd384dc --- /dev/null +++ b/public/steam/steamuniverse.h @@ -0,0 +1,27 @@ +//========= Copyright � 1996-2008, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +//============================================================================= + +#ifndef STEAMUNIVERSE_H +#define STEAMUNIVERSE_H +#ifdef _WIN32 +#pragma once +#endif + + +// Steam universes. Each universe is a self-contained Steam instance. +enum EUniverse +{ + k_EUniverseInvalid = 0, + k_EUniversePublic = 1, + k_EUniverseBeta = 2, + k_EUniverseInternal = 3, + k_EUniverseDev = 4, + // k_EUniverseRC = 5, // no such universe anymore + k_EUniverseMax +}; + + +#endif // STEAMUNIVERSE_H diff --git a/redistributable_bin/Steam.dll b/redistributable_bin/Steam.dll index 096e53a..9d94d88 100644 Binary files a/redistributable_bin/Steam.dll and b/redistributable_bin/Steam.dll differ diff --git a/redistributable_bin/linux32/libSteam.so b/redistributable_bin/linux32/libSteam.so index e80a5e1..16d2f01 100644 Binary files a/redistributable_bin/linux32/libSteam.so and b/redistributable_bin/linux32/libSteam.so differ diff --git a/redistributable_bin/linux32/libsteam_api.so b/redistributable_bin/linux32/libsteam_api.so index 306d3ac..5de64a6 100644 Binary files a/redistributable_bin/linux32/libsteam_api.so and b/redistributable_bin/linux32/libsteam_api.so differ diff --git a/redistributable_bin/linux32/libtier0_s.so b/redistributable_bin/linux32/libtier0_s.so new file mode 100644 index 0000000..650b7e8 Binary files /dev/null and b/redistributable_bin/linux32/libtier0_s.so differ diff --git a/redistributable_bin/linux32/libvstdlib_s.so b/redistributable_bin/linux32/libvstdlib_s.so new file mode 100644 index 0000000..2ce9dbf Binary files /dev/null and b/redistributable_bin/linux32/libvstdlib_s.so differ diff --git a/redistributable_bin/linux32/steamclient.so b/redistributable_bin/linux32/steamclient.so index d3d0507..87716fa 100644 Binary files a/redistributable_bin/linux32/steamclient.so and b/redistributable_bin/linux32/steamclient.so differ diff --git a/redistributable_bin/osx32/libSteam.dylib b/redistributable_bin/osx32/libSteam.dylib index fde64b8..10e1794 100644 Binary files a/redistributable_bin/osx32/libSteam.dylib and b/redistributable_bin/osx32/libSteam.dylib differ diff --git a/redistributable_bin/osx32/libsteam_api.dylib b/redistributable_bin/osx32/libsteam_api.dylib index 073898c..815762e 100644 Binary files a/redistributable_bin/osx32/libsteam_api.dylib and b/redistributable_bin/osx32/libsteam_api.dylib differ diff --git a/redistributable_bin/osx32/libtier0_s.dylib b/redistributable_bin/osx32/libtier0_s.dylib index 3141813..85d4098 100644 Binary files a/redistributable_bin/osx32/libtier0_s.dylib and b/redistributable_bin/osx32/libtier0_s.dylib differ diff --git a/redistributable_bin/osx32/libvstdlib_s.dylib b/redistributable_bin/osx32/libvstdlib_s.dylib index f771a88..8176c60 100644 Binary files a/redistributable_bin/osx32/libvstdlib_s.dylib and b/redistributable_bin/osx32/libvstdlib_s.dylib differ diff --git a/redistributable_bin/osx32/steamclient.dylib b/redistributable_bin/osx32/steamclient.dylib index 678178c..44ecd13 100644 Binary files a/redistributable_bin/osx32/steamclient.dylib and b/redistributable_bin/osx32/steamclient.dylib differ diff --git a/redistributable_bin/steam_api.dll b/redistributable_bin/steam_api.dll index 2150263..21def0e 100644 Binary files a/redistributable_bin/steam_api.dll and b/redistributable_bin/steam_api.dll differ diff --git a/redistributable_bin/steam_api.lib b/redistributable_bin/steam_api.lib index 1da42fe..735cade 100644 Binary files a/redistributable_bin/steam_api.lib and b/redistributable_bin/steam_api.lib differ diff --git a/redistributable_bin/steamclient.dll b/redistributable_bin/steamclient.dll index d5348b1..8655348 100644 Binary files a/redistributable_bin/steamclient.dll and b/redistributable_bin/steamclient.dll differ diff --git a/redistributable_bin/tier0_s.dll b/redistributable_bin/tier0_s.dll index 76f3380..224b8d3 100644 Binary files a/redistributable_bin/tier0_s.dll and b/redistributable_bin/tier0_s.dll differ diff --git a/redistributable_bin/vstdlib_s.dll b/redistributable_bin/vstdlib_s.dll index 724c6a0..dac2147 100644 Binary files a/redistributable_bin/vstdlib_s.dll and b/redistributable_bin/vstdlib_s.dll differ diff --git a/redistributable_bin/win64/steam_api64.dll b/redistributable_bin/win64/steam_api64.dll index 358471e..50572f3 100644 Binary files a/redistributable_bin/win64/steam_api64.dll and b/redistributable_bin/win64/steam_api64.dll differ diff --git a/redistributable_bin/win64/steam_api64.lib b/redistributable_bin/win64/steam_api64.lib index 8e5bcf9..9d4592c 100644 Binary files a/redistributable_bin/win64/steam_api64.lib and b/redistributable_bin/win64/steam_api64.lib differ diff --git a/steamworksexample/DejaVuSans.ttf b/steamworksexample/DejaVuSans.ttf new file mode 100644 index 0000000..19ed0b4 Binary files /dev/null and b/steamworksexample/DejaVuSans.ttf differ diff --git a/steamworksexample/DejaVuSans.txt b/steamworksexample/DejaVuSans.txt new file mode 100644 index 0000000..710b32c --- /dev/null +++ b/steamworksexample/DejaVuSans.txt @@ -0,0 +1,58 @@ +This package was debianized by Peter Cernak on +Sun, 5 Sep 2004 17:10:26 +0200. + +It was downloaded from http://dejavu.sourceforge.net/ + +Upstream Authors: Stepan Roh (original author), + see /usr/share/doc/ttf-dejavu/AUTHORS for full list + +Copyright: + +Fonts are (c) Bitstream (see below). DejaVu changes are in public domain. + +Bitstream Vera Fonts Copyright +------------------------------ + +Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is +a trademark of Bitstream, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of the fonts accompanying this license ("Fonts") and associated +documentation files (the "Font Software"), to reproduce and distribute the +Font Software, including without limitation the rights to use, copy, merge, +publish, distribute, and/or sell copies of the Font Software, and to permit +persons to whom the Font Software is furnished to do so, subject to the +following conditions: + +The above copyright and trademark notices and this permission notice shall +be included in all copies of one or more of the Font Software typefaces. + +The Font Software may be modified, altered, or added to, and in particular +the designs of glyphs or characters in the Fonts may be modified and +additional glyphs or characters may be added to the Fonts, only if the fonts +are renamed to names not containing either the words "Bitstream" or the word +"Vera". + +This License becomes null and void to the extent applicable to Fonts or Font +Software that has been modified and is distributed under the "Bitstream +Vera" names. + +The Font Software may be sold as part of a larger software package but no +copy of one or more of the Font Software typefaces may be sold by itself. + +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, +TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME +FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING +ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE +FONT SOFTWARE. + +Except as contained in this notice, the names of Gnome, the Gnome +Foundation, and Bitstream Inc., shall not be used in advertising or +otherwise to promote the sale, use or other dealings in this Font Software +without prior written authorization from the Gnome Foundation or Bitstream +Inc., respectively. For further information, contact: fonts at gnome dot +org. diff --git a/steamworksexample/Makefile b/steamworksexample/Makefile new file mode 100644 index 0000000..02ce45e --- /dev/null +++ b/steamworksexample/Makefile @@ -0,0 +1,147 @@ +#Generated by VisualGDB project wizard. +#Visit http://visualgdb.com/makefiles for more details + +#VisualGDB: AutoSourceFiles #<--- remove this line to disable auto-updating of SOURCEFILES and EXTERNAL_LIBS +SOURCEFILES := BaseMenu.cpp clanchatroom.cpp connectingmenu.cpp gameenginesdl.cpp Leaderboards.cpp Lobby.cpp Main.cpp MainMenu.cpp p2pauth.cpp PhotonBeam.cpp QuitMenu.cpp RemoteStorage.cpp remotestoragesync.cpp ServerBrowser.cpp Ship.cpp SpaceWarClient.cpp SpaceWarEntity.cpp SpaceWarServer.cpp StarField.cpp StatsAndAchievements.cpp stdafx.cpp Sun.cpp VectorEntity.cpp voicechat.cpp + +TARGETNAME := SteamworksExampleLinux +#TARGETTYPE can be APP, STATIC or SHARED +TARGETTYPE := APP + +include flags.mak + +CONFIG ?= RELEASE + +ALL_MACROS := $(COMMON_MACROS) + +ifeq ($(CONFIG),DEBUG) + BINARYDIR = debug + CFLAGS += $(DEBUG_CFLAGS) + CXXFLAGS += $(DEBUG_CXXFLAGS) + LDFLAGS += $(DEBUG_LDFLAGS) + ALL_MACROS += $(DEBUG_MACROS) +endif + +ifeq ($(CONFIG),RELEASE) + BINARYDIR = release + CFLAGS += $(RELEASE_CFLAGS) + CXXFLAGS += $(RELEASE_CXXFLAGS) + LDFLAGS += $(RELEASE_LDFLAGS) + ALL_MACROS += $(RELEASE_MACROS) +endif + +ifeq ($(BINARYDIR),) +error: + $(error Please specify CONFIG=DEBUG/RELEASE) +endif + +EXTERNAL_LIBS := +EXTERNAL_LIBS_COPIED := $(foreach lib, $(EXTERNAL_LIBS),$(BINARYDIR)/$(notdir $(lib))) + +CFLAGS += $(addprefix -I,$(INCLUDE_DIRS)) +CXXFLAGS += $(addprefix -I,$(INCLUDE_DIRS)) + +CFLAGS += $(addprefix -D,$(ALL_MACROS)) +CXXFLAGS += $(addprefix -D,$(ALL_MACROS)) + +CXXFLAGS += $(addprefix -framework ,$(MACOS_FRAMEWORKS)) +CFLAGS += $(addprefix -framework ,$(MACOS_FRAMEWORKS)) +LDFLAGS += $(addprefix -framework ,$(MACOS_FRAMEWORKS)) + +LDFLAGS += $(addprefix -L,$(LIBRARY_DIRS)) + +LIBRARY_LDFLAGS = $(addprefix -l,$(LIBRARY_NAMES)) + +ifeq ($(IS_LINUX_PROJECT),1) + RPATH_PREFIX := -Wl,--rpath='$$ORIGIN/../ + LIBRARY_LDFLAGS += $(EXTERNAL_LIBS) + LIBRARY_LDFLAGS += -Wl,--rpath='$$ORIGIN' + LIBRARY_LDFLAGS += $(addsuffix ',$(addprefix $(RPATH_PREFIX),$(dir $(EXTERNAL_LIBS)))) + + ifeq ($(TARGETTYPE),SHARED) + LIBRARY_LDFLAGS += -Wl,-soname,$(TARGETNAME) + endif + +else + LIBRARY_LDFLAGS += $(EXTERNAL_LIBS) +endif + + +CFLAGS += $(MCUFLAGS) +CXXFLAGS += $(MCUFLAGS) +LDFLAGS += $(MCUFLAGS) + +all_make_files := Makefile flags.mak $(ADDITIONAL_MAKE_FILES) + +ifeq ($(STARTUPFILES),) + all_source_files := $(SOURCEFILES) +else + all_source_files := $(STARTUPFILES) $(filter-out $(STARTUPFILES),$(SOURCEFILES)) +endif + +source_obj1 := $(all_source_files:.cpp=.o) +source_obj2 := $(source_obj1:.c=.o) +source_objs := $(source_obj2:.S=.o) + +all_objs := $(addprefix $(BINARYDIR)/, $(notdir $(source_objs))) + +ifeq ($(GENERATE_BIN_FILE),1) +all: $(BINARYDIR)/$(basename $(TARGETNAME)).bin + +$(BINARYDIR)/$(basename $(TARGETNAME)).bin: $(BINARYDIR)/$(TARGETNAME) + $(OBJCOPY) -O binary $< $@ + +else +all: $(BINARYDIR)/$(TARGETNAME) +endif + +ifeq ($(TARGETTYPE),APP) +$(BINARYDIR)/$(TARGETNAME): $(all_objs) $(EXTERNAL_LIBS) $(BINARYDIR)/$(STEAM_API) $(BINARYDIR)/SteamworksExample.sh $(BINARYDIR)/DejaVuSans.ttf + $(LD) -o $@ $(LDFLAGS) $(START_GROUP) $(all_objs) $(LIBRARY_LDFLAGS) $(END_GROUP) + @echo "You can start the game by running $(BINARYDIR)/SteamworksExample.sh" +endif + +ifeq ($(TARGETTYPE),SHARED) +$(BINARYDIR)/$(TARGETNAME): $(all_objs) $(EXTERNAL_LIBS) + $(LD) -shared -o $@ $(LDFLAGS) $(START_GROUP) $(all_objs) $(LIBRARY_LDFLAGS) $(END_GROUP) +endif + +ifeq ($(TARGETTYPE),STATIC) +$(BINARYDIR)/$(TARGETNAME): $(all_objs) + $(AR) -r $@ $^ +endif + +-include $(all_objs:.o=.dep) + +clean: +ifeq ($(USE_DEL_TO_CLEAN),1) + del /S /Q $(BINARYDIR) +else + rm -f $(BINARYDIR)/*.o $(BINARYDIR)/*.dep $(BINARYDIR)/$(TARGETNAME) +endif + +$(BINARYDIR): + mkdir $(BINARYDIR) + +$(BINARYDIR)/$(STEAM_API): $(STEAMWORKS_SDK)/redistributable_bin/linux32/$(STEAM_API) + cp -v $< $@ + chmod +x $@ + +$(BINARYDIR)/SteamworksExample.sh: SteamworksExample.sh + cp -v $< $@ + chmod +x $@ + +$(BINARYDIR)/DejaVuSans.ttf: DejaVuSans.ttf + cp -v $< $@ + +#VisualGDB: FileSpecificTemplates #<--- VisualGDB will use the following lines to define rules for source files in subdirectories +$(BINARYDIR)/%.o : %.cpp $(all_make_files) |$(BINARYDIR) + $(CXX) $(CXXFLAGS) -c $< -o $@ -MD -MF $(@:.o=.dep) + +$(BINARYDIR)/%.o : %.c $(all_make_files) |$(BINARYDIR) + $(CC) $(CFLAGS) -c $< -o $@ -MD -MF $(@:.o=.dep) + +$(BINARYDIR)/%.o : %.S $(all_make_files) |$(BINARYDIR) + $(CC) $(CFLAGS) $(ASFLAGS) -c $< -o $@ -MD -MF $(@:.o=.dep) + +#VisualGDB: GeneratedRules #<--- All lines below are auto-generated diff --git a/steamworksexample/SteamworksExample.sh b/steamworksexample/SteamworksExample.sh new file mode 100644 index 0000000..a10de13 --- /dev/null +++ b/steamworksexample/SteamworksExample.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# +# This is a script which runs the SteamworksExample in the Steam runtime + +# The program location +TOP=$(cd "${0%/*}" && echo ${PWD}) + +PROGRAM="${TOP}/SteamworksExampleLinux" + +# Steam sets this environment variable when launching games +if [ "$STEAM_RUNTIME" = "" ]; then + export STEAM_RUNTIME="${TOP}/../../tools/linux/runtime/i386" + export LD_LIBRARY_PATH="${STEAM_RUNTIME}/lib/i386-linux-gnu:${STEAM_RUNTIME}/lib:${STEAM_RUNTIME}/usr/lib/i386-linux-gnu:${STEAM_RUNTIME}/usr/lib:${LD_LIBRARY_PATH}" +fi + +# Add the current directory to the library path to pick up libsteam_api.so +export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:." + +exec "${PROGRAM}" "$@" + +# vi: ts=4 sw=4 expandtab diff --git a/steamworksexample/flags.mak b/steamworksexample/flags.mak new file mode 100644 index 0000000..23e8af9 --- /dev/null +++ b/steamworksexample/flags.mak @@ -0,0 +1,79 @@ +#Generated by VisualGDB project wizard. +#Feel free to modify any flags you want +#Visit http://visualgdb.com/makefiles for more details + +# Set this variable to the location of the Steamworks SDK +ifeq ($(STEAMWORKS_SDK),) + STEAMWORKS_SDK := $(PWD)/.. +endif +STEAM_API := libsteam_api.so + +# Uncomment this line to use the Steam Linux Runtime SDK +# If you do this you should run the SDK setup.sh to download updates +USE_STEAM_RUNTIME=true +ifeq ($(USE_STEAM_RUNTIME),true) + ifeq ($(STEAM_RUNTIME_SDK),) + STEAM_RUNTIME_SDK := $(STEAMWORKS_SDK)/tools/linux + endif + ifeq ($(STEAM_RUNTIME_TARGET_ARCH),) + STEAM_RUNTIME_TARGET_ARCH := i386 + export STEAM_RUNTIME_TARGET_ARCH + endif + ifeq ($(STEAM_RUNTIME_ROOT),) + STEAM_RUNTIME_ROOT := $(STEAM_RUNTIME_SDK)/runtime/$(STEAM_RUNTIME_TARGET_ARCH) + export STEAM_RUNTIME_ROOT + endif + STEAM_TOOLS_BIN := $(STEAM_RUNTIME_SDK)/bin/ + + ifeq ($(realpath $(STEAM_TOOLS_BIN)),) +steam-runtime-setup: + bash $(STEAM_RUNTIME_SDK)/setup.sh --auto-upgrade + make + + endif +endif # USE_STEAM_RUNTIME + +CC := $(STEAM_TOOLS_BIN)gcc +CXX := $(STEAM_TOOLS_BIN)g++ +LD := $(CXX) +AR := $(STEAM_TOOLS_BIN)ar +OBJCOPY := $(STEAM_TOOLS_BIN)objcopy +CP := cp +SDL_CONFIG := $(STEAM_TOOLS_BIN)sdl2-config + +# Since this is an example, we'll build Debug by default +CONFIG ?= DEBUG + +COMMON_MACROS := +DEBUG_MACROS := DEBUG +RELEASE_MACROS := NDEBUG RELEASE + +MCUFLAGS := + +INCLUDE_DIRS := $(STEAMWORKS_SDK)/public +LIBRARY_DIRS := $(STEAMWORKS_SDK)/public/steam/lib/linux32 $(STEAMWORKS_SDK)/redistributable_bin/linux32 +LIBRARY_NAMES := steam_api + +CFLAGS := -g -DPOSIX -DSDL $(shell STEAM_RUNTIME_ROOT=$(STEAM_RUNTIME_ROOT) $(SDL_CONFIG) --cflags) +DEBUG_CFLAGS := -O0 +RELEASE_CFLAGS := -O3 + +CXXFLAGS := $(CFLAGS) +DEBUG_CXXFLAGS := $(DEBUG_CFLAGS) +RELEASE_CXXFLAGS := $(RELEASE_CFLAGS) + +MACOS_FRAMEWORKS := + +LDFLAGS := $(shell STEAM_RUNTIME_ROOT=$(STEAM_RUNTIME_ROOT) $(SDL_CONFIG) --libs) -lSDL2_ttf -lfreetype -lz -lGL -lopenal +DEBUG_LDFLAGS := +RELEASE_LDGLAGS := + +START_GROUP := -Wl,--start-group +END_GROUP := -Wl,--end-group + +USE_DEL_TO_CLEAN := 0 +GENERATE_BIN_FILE := 0 +ADDITIONAL_MAKE_FILES := +IS_LINUX_PROJECT := 1 + +include $(ADDITIONAL_MAKE_FILES) diff --git a/steamworksexample/gameengineosx.h b/steamworksexample/gameengineosx.h index a9219c5..fda5491 100644 --- a/steamworksexample/gameengineosx.h +++ b/steamworksexample/gameengineosx.h @@ -141,7 +141,7 @@ public: bool BDrawString( HGAMEFONT hFont, RECT rect, DWORD dwColor, DWORD dwFormat, const char *pchText ); // Create a new font returning our internal handle value for it (0 means failure) - HGAMEFONT HCreateFont( int nHeight, int nFontWeight, bool bItalic, char * pchFont ); + HGAMEFONT HCreateFont( int nHeight, int nFontWeight, bool bItalic, const char * pchFont ); // Create a new texture returning our internal handle value for it (0 means failure) HGAMETEXTURE HCreateTexture( byte *pRGBAData, uint32 uWidth, uint32 uHeight ); @@ -450,4 +450,4 @@ public: #endif }; -#endif // GAMEENGINEOSX_H \ No newline at end of file +#endif // GAMEENGINEOSX_H diff --git a/steamworksexample/gameengineosx.mm b/steamworksexample/gameengineosx.mm index 380b7da..3dc7b7a 100644 --- a/steamworksexample/gameengineosx.mm +++ b/steamworksexample/gameengineosx.mm @@ -1744,7 +1744,7 @@ HGAMETEXTURE CGameEngineGL::HCreateTexture( byte *pRGBAData, uint32 uWidth, uint //----------------------------------------------------------------------------- // Purpose: Creates a new font //----------------------------------------------------------------------------- -HGAMEFONT CGameEngineGL::HCreateFont( int nHeight, int nFontWeight, bool bItalic, char * pchFont ) +HGAMEFONT CGameEngineGL::HCreateFont( int nHeight, int nFontWeight, bool bItalic, const char * pchFont ) { #if DX9MODE extern unsigned char g_glmDebugFontMap[ 128 * 128 ]; // raster order diff --git a/steamworksexample/gameenginesdl.cpp b/steamworksexample/gameenginesdl.cpp new file mode 100644 index 0000000..ca8d7ed --- /dev/null +++ b/steamworksexample/gameenginesdl.cpp @@ -0,0 +1,1068 @@ +//========= Copyright 1996-2008, Valve LLC, All rights reserved. ============ +// +// Purpose: Main class for the game engine -- win32 implementation +// +// $NoKeywords: $ +//============================================================================= + +#include "stdafx.h" + +#include +#include +#include + +#include "gameenginesdl.h" + + +CGameEngineGL *g_engine; // dxabstract will use this.. it is set by the engine constructor + +IGameEngine *CreateGameEngineSDL() +{ + static CGameEngineGL* s_pGameEngine = NULL; + + if (!s_pGameEngine) + { + s_pGameEngine = new CGameEngineGL(); + } + + return s_pGameEngine; +} + +void OutputDebugString( const char *pchMsg ) +{ + fprintf( stderr, "%s", pchMsg ); +} + +struct Packet_t +{ + uint32 unSize; + void *pData; +}; + +class CVoiceContext +{ +public: + CVoiceContext() + { + alGenBuffers( ARRAYSIZE(m_buffers), m_buffers ); + alGenSources( 1, &m_nSource ); + + alSourcei( m_nSource, AL_LOOPING, AL_FALSE ); + + for (int i = 0; i < ARRAYSIZE(m_buffers); i++ ) + alSourcei( m_nSource, AL_BUFFER, m_buffers[i] ); + + m_nNextFreeBuffer = 0; + } + virtual ~CVoiceContext() + { + // + } + + ALuint m_buffers[4]; + ALuint m_nSource; + size_t m_nNextFreeBuffer; + std::queue m_pending; +}; + +/* Quick utility function for texture creation */ +static int +power_of_two(int input) +{ + int value = 1; + + while (value < input) { + value <<= 1; + } + return value; +} + +//----------------------------------------------------------------------------- +// Purpose: Constructor for game engine instance +//----------------------------------------------------------------------------- +CGameEngineGL::CGameEngineGL() +{ + g_engine = this; + + m_bEngineReadyForUse = false; + m_bShuttingDown = false; + m_window = NULL; + m_context = NULL; + m_nWindowWidth = 0; + m_nWindowHeight = 0; + m_ulPreviousGameTickCount = 0; + m_ulGameTickCount = 0; + m_unVoiceChannelCount = 0; + + m_hTextureWhite = 0; + m_nNextFontHandle = 1; + m_nNextTextureHandle = 1; + m_hLastTexture = 0; + + m_rgflPointsData = new GLfloat[ 3*POINT_BUFFER_TOTAL_SIZE ]; + m_rgflPointsColorData = new GLubyte[ 4*POINT_BUFFER_TOTAL_SIZE ]; + m_dwPointsToFlush = 0; + + m_rgflLinesData = new GLfloat[ 6*LINE_BUFFER_TOTAL_SIZE ]; + m_rgflLinesColorData = new GLubyte[ 8*LINE_BUFFER_TOTAL_SIZE ]; + m_dwLinesToFlush = 0; + + m_rgflQuadsData = new GLfloat [ 12*QUAD_BUFFER_TOTAL_SIZE ]; + m_rgflQuadsColorData = new GLubyte[ 16*QUAD_BUFFER_TOTAL_SIZE ]; + m_rgflQuadsTextureData = new GLfloat[ 8*QUAD_BUFFER_TOTAL_SIZE ]; + m_dwQuadsToFlush = 0; + + TTF_Init(); + + if( !BInitializeGraphics() ) + { + OutputDebugString( "!! Initializing graphics failed\n" ); + return; + } + + if ( !BInitializeAudio() ) + { + OutputDebugString( "!! Initializing audio failed\n" ); + return; + } + + m_bEngineReadyForUse = true; +} + + +//----------------------------------------------------------------------------- +// Purpose: Shutdown the game engine +//----------------------------------------------------------------------------- +void CGameEngineGL::Shutdown() +{ + // Flag that we are shutting down so the frame loop will stop running + m_bShuttingDown = true; + + if ( m_context ) { + SDL_GL_DeleteContext( m_context ); + } + + if ( m_window ) { + SDL_DestroyWindow( m_window ); + } + + if ( m_rgflPointsData ) + { + delete[] m_rgflPointsData; + m_rgflPointsData = NULL; + } + + if ( m_rgflPointsColorData ) + { + delete[] m_rgflPointsColorData; + m_rgflPointsColorData = NULL; + } + + if ( m_rgflLinesData ) + { + delete[] m_rgflLinesData; + m_rgflLinesData = NULL; + } + + if ( m_rgflLinesColorData ) + { + delete[] m_rgflLinesColorData; + m_rgflLinesColorData = NULL; + } + + if ( m_rgflQuadsData ) + { + delete[] m_rgflQuadsData; + m_rgflQuadsData = NULL; + } + + if ( m_rgflQuadsColorData ) + { + delete[] m_rgflQuadsColorData; + m_rgflQuadsColorData = NULL; + } + + if ( m_rgflQuadsTextureData ) + { + delete[] m_rgflQuadsTextureData; + m_rgflQuadsTextureData = NULL; + } + + std::map::const_iterator i; + for (i = m_MapGameFonts.begin(); i != m_MapGameFonts.end(); ++i) + { + TTF_CloseFont( i->second ); + } + m_MapGameFonts.clear(); + + TTF_Quit(); + + m_MapStrings.clear(); + m_MapTextures.clear(); + + m_dwLinesToFlush = 0; + m_dwPointsToFlush = 0; + m_dwQuadsToFlush = 0; +} + + +//----------------------------------------------------------------------------- +// Purpose: Initialize voice/audio interfaces +//----------------------------------------------------------------------------- +bool CGameEngineGL::BInitializeAudio() +{ + m_palDevice = alcOpenDevice(NULL); + if ( m_palDevice ) + { + m_palContext = alcCreateContext( m_palDevice, NULL ); + alcMakeContextCurrent( m_palContext ); + return true; + } + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: Initialize the GL rendering interfaces and default state +//----------------------------------------------------------------------------- +#define D3DADAPTER_DEFAULT 0 + +bool CGameEngineGL::BInitializeGraphics() +{ + m_nWindowWidth = 1024; + m_nWindowHeight = 768; + + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 ); + + m_window = SDL_CreateWindow( "SteamworksExample", + SDL_WINDOWPOS_CENTERED, + SDL_WINDOWPOS_CENTERED, + m_nWindowWidth, + m_nWindowHeight, + SDL_WINDOW_OPENGL ); + if ( !m_window ) { + OutputDebugString( "Couldn't create SDL window: " ); + OutputDebugString( SDL_GetError() ); + OutputDebugString( "\n" ); + return false; + } + + m_context = SDL_GL_CreateContext( m_window ); + if ( !m_context ) { + OutputDebugString( "Couldn't create OpenGL context: " ); + OutputDebugString( SDL_GetError() ); + OutputDebugString( "\n" ); + return false; + } + + SDL_GL_SetSwapInterval( 1 ); + + // Clear any errors + glGetError(); + + glClearDepth( 1.0f ); + glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); + + glEnable( GL_BLEND ); + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + + glDisable( GL_CULL_FACE ); + glDisable( GL_ALPHA_TEST ); + glDisable( GL_STENCIL_TEST ); + glDisable( GL_SCISSOR_TEST ); + glDisable( GL_LIGHTING ); + glDisable( GL_DEPTH_TEST ); + glDisable( GL_FOG ); + + glDepthMask( GL_FALSE ); + + // We always need these two + glEnableClientState( GL_COLOR_ARRAY ); + glEnableClientState( GL_VERTEX_ARRAY ); + + // This we'll enable as needed + glDisableClientState( GL_TEXTURE_COORD_ARRAY ); + + glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef( 0, 0, 0 ); + + glMatrixMode( GL_TEXTURE ); + glLoadIdentity(); + glTranslatef( 0, 0, 0 ); + + glDepthRange( 0.0f, 1.0f ); + + AdjustViewport(); + + return true; +} + +void CGameEngineGL::AdjustViewport() +{ + SDL_GetWindowSize( m_window, &m_nWindowWidth, &m_nWindowHeight ); + + // Perspective + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho( 0, m_nWindowWidth, m_nWindowHeight, 0, -1.0f, 1.0f ); + glTranslatef( 0, 0, 0 ); + + // View port has changed as well + glMatrixMode(GL_MODELVIEW); + + glViewport( 0, 0, m_nWindowWidth, m_nWindowHeight ); + glScissor( 0, 0, m_nWindowWidth, m_nWindowHeight ); + + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT ); + glFlush(); +} + +//----------------------------------------------------------------------------- +// Purpose: Updates current tick count for the game engine +//----------------------------------------------------------------------------- +void CGameEngineGL::UpdateGameTickCount() +{ + m_ulPreviousGameTickCount = m_ulGameTickCount; + m_ulGameTickCount = SDL_GetTicks(); +} + + +//----------------------------------------------------------------------------- +// Purpose: Tell the game engine to sleep for a bit if needed to limit frame rate. You must keep +// calling this repeatedly until it returns false. If it returns true it's slept a little, but more +// time may be needed. +//----------------------------------------------------------------------------- +bool CGameEngineGL::BSleepForFrameRateLimit( uint32 ulMaxFrameRate ) +{ + // Frame rate limiting + float flDesiredFrameMilliseconds = 1000.0f/ulMaxFrameRate; + + uint64 ulGameTickCount = SDL_GetTicks(); + + float flMillisecondsElapsed = (float)(ulGameTickCount - m_ulGameTickCount); + if ( flMillisecondsElapsed < flDesiredFrameMilliseconds ) + { + // If enough time is left sleep, otherwise just keep spinning so we don't go over the limit... + if ( flDesiredFrameMilliseconds - flMillisecondsElapsed > 3.0f ) + { + usleep( 5000 ); + } + else + { + // Just return right away so we busy loop, don't want to sleep too long and go over + } + + return true; + } + else + { + return false; + } +} + + +//----------------------------------------------------------------------------- +// Purpose: Set the background color to clear to +//----------------------------------------------------------------------------- +void CGameEngineGL::SetBackgroundColor( short a, short r, short g, short b ) +{ + glClearColor( (float)r/255.0f, (float)g/255.0f, (float)b/255.0f, (float)a/255.0f ); +} + +//----------------------------------------------------------------------------- +// Purpose: Start a new frame +//----------------------------------------------------------------------------- +bool CGameEngineGL::StartFrame() +{ + AdjustViewport(); + + // Pump system callbacks + MessagePump(); + + // We may now be shutting down, check and don't start a frame then + if ( BShuttingDown() ) + return false; + + #if 0 // for debug + static unsigned char counter; + counter++; + glClearColor( (float)counter/255.0f, (float)counter/255.0f, (float)counter/255.0f, (float)1.0f ); + #endif + + // Clear the screen for the new frame + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT ); + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: End the current frame +//----------------------------------------------------------------------------- +void CGameEngineGL::EndFrame() +{ + if ( BShuttingDown() ) + return; + + // Flush point buffer + BFlushPointBuffer(); + + // Flush line buffer + BFlushLineBuffer(); + + // Flush quad buffer + BFlushQuadBuffer(); + + // Swap buffers now that everything is flushed + SDL_GL_SwapWindow( m_window ); + + RunAudio(); +} + + +//----------------------------------------------------------------------------- +// Purpose: Draw a line, the engine internally manages a vertex buffer for batching these +//----------------------------------------------------------------------------- +bool CGameEngineGL::BDrawLine( float xPos0, float yPos0, DWORD dwColor0, float xPos1, float yPos1, DWORD dwColor1 ) +{ + if ( m_bShuttingDown ) + return false; + + // Check if we are out of room and need to flush the buffer + if ( m_dwLinesToFlush == LINE_BUFFER_TOTAL_SIZE ) + { + BFlushLineBuffer(); + } + + DWORD dwOffset = m_dwLinesToFlush*6; + m_rgflLinesData[dwOffset] = xPos0; + m_rgflLinesData[dwOffset+1] = yPos0; + m_rgflLinesData[dwOffset+2] = 1.0; + m_rgflLinesData[dwOffset+3] = xPos1; + m_rgflLinesData[dwOffset+4] = yPos1; + m_rgflLinesData[dwOffset+5] = 1.0; + + dwOffset = m_dwLinesToFlush*8; + m_rgflLinesColorData[dwOffset] = COLOR_RED( dwColor0 ); + m_rgflLinesColorData[dwOffset+1] = COLOR_GREEN( dwColor0 ); + m_rgflLinesColorData[dwOffset+2] = COLOR_BLUE( dwColor0 ); + m_rgflLinesColorData[dwOffset+3] = COLOR_ALPHA( dwColor0 ); + m_rgflLinesColorData[dwOffset+4] = COLOR_RED( dwColor1 ); + m_rgflLinesColorData[dwOffset+5] = COLOR_GREEN( dwColor1 ); + m_rgflLinesColorData[dwOffset+6] = COLOR_BLUE( dwColor1 ); + m_rgflLinesColorData[dwOffset+7] = COLOR_ALPHA( dwColor1 ); + + ++m_dwLinesToFlush; + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: Flush batched lines to the screen +//----------------------------------------------------------------------------- +bool CGameEngineGL::BFlushLineBuffer() +{ + if ( !m_rgflLinesColorData || !m_rgflLinesData || m_bShuttingDown ) + return false; + + if ( m_dwLinesToFlush ) + { + glColorPointer( 4, GL_UNSIGNED_BYTE, 0, m_rgflLinesColorData ); + glVertexPointer( 3, GL_FLOAT, 0, m_rgflLinesData ); + glDrawArrays( GL_LINES, 0, m_dwLinesToFlush*2 ); + + m_dwLinesToFlush = 0; + } + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: Draw a point, the engine internally manages a vertex buffer for batching these +//----------------------------------------------------------------------------- +bool CGameEngineGL::BDrawPoint( float xPos, float yPos, DWORD dwColor ) +{ + if ( m_bShuttingDown ) + return false; + + // Check if we are out of room and need to flush the buffer + if ( m_dwPointsToFlush == POINT_BUFFER_TOTAL_SIZE ) + { + BFlushPointBuffer(); + } + + DWORD dwOffset = m_dwPointsToFlush*3; + m_rgflPointsData[dwOffset] = xPos; + m_rgflPointsData[dwOffset+1] = yPos; + m_rgflPointsData[dwOffset+2] = 1.0; + + dwOffset = m_dwPointsToFlush*4; + m_rgflPointsColorData[dwOffset] = COLOR_RED( dwColor ); + m_rgflPointsColorData[dwOffset+1] = COLOR_GREEN( dwColor ); + m_rgflPointsColorData[dwOffset+2] = COLOR_BLUE( dwColor ); + m_rgflPointsColorData[dwOffset+3] = COLOR_ALPHA( dwColor ); + + ++m_dwPointsToFlush; + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: Flush batched points to the screen +//----------------------------------------------------------------------------- +bool CGameEngineGL::BFlushPointBuffer() +{ + if ( !m_rgflPointsColorData || !m_rgflPointsData || m_bShuttingDown ) + return false; + + if ( m_dwPointsToFlush ) + { + glColorPointer( 4, GL_UNSIGNED_BYTE, 0, m_rgflPointsColorData ); + glVertexPointer( 3, GL_FLOAT, 0, m_rgflPointsData ); + glDrawArrays( GL_POINTS, 0, m_dwPointsToFlush ); + + m_dwPointsToFlush = 0; + } + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: Draw a filled quad +//----------------------------------------------------------------------------- +bool CGameEngineGL::BDrawFilledQuad( float xPos0, float yPos0, float xPos1, float yPos1, DWORD dwColor ) +{ + if ( !m_hTextureWhite ) + { + byte *pRGBAData = new byte[ 1 * 1 * 4 ]; + memset( pRGBAData, 255, 1*1*4 ); + m_hTextureWhite = HCreateTexture( pRGBAData, 1, 1 ); + delete[] pRGBAData; + } + + return BDrawTexturedQuad( xPos0, yPos0, xPos1, yPos1, 0.0f, 0.0f, 1.0f, 1.0f, dwColor, m_hTextureWhite ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Draw a textured quad +//----------------------------------------------------------------------------- +bool CGameEngineGL::BDrawTexturedQuad( float xPos0, float yPos0, float xPos1, float yPos1, float u0, float v0, float u1, float v1, DWORD dwColor, HGAMETEXTURE hTexture ) +{ + if ( m_bShuttingDown ) + return false; + + // Find the texture + std::map::iterator iter; + iter = m_MapTextures.find( hTexture ); + if ( iter == m_MapTextures.end() ) + { + OutputDebugString( "BDrawTexturedQuad called with invalid hTexture value\n" ); + return false; + } + + // Check if we are out of room and need to flush the buffer, or if our texture is changing + // then we also need to flush the buffer. + if ( m_dwQuadsToFlush == QUAD_BUFFER_TOTAL_SIZE || m_hLastTexture != hTexture ) + { + BFlushQuadBuffer(); + } + + // Bind the new texture + glBindTexture( GL_TEXTURE_2D, iter->second.m_uTextureID ); + + DWORD dwOffset = m_dwQuadsToFlush*12; + m_rgflQuadsData[dwOffset] = xPos0; + m_rgflQuadsData[dwOffset+1] = yPos0; + m_rgflQuadsData[dwOffset+2] = 1.0; + m_rgflQuadsData[dwOffset+3] = xPos1; + m_rgflQuadsData[dwOffset+4] = yPos0; + m_rgflQuadsData[dwOffset+5] = 1.0; + m_rgflQuadsData[dwOffset+6] = xPos1; + m_rgflQuadsData[dwOffset+7] = yPos1; + m_rgflQuadsData[dwOffset+8] = 1.0; + m_rgflQuadsData[dwOffset+9] = xPos0; + m_rgflQuadsData[dwOffset+10] = yPos1; + m_rgflQuadsData[dwOffset+11] = 1.0; + + dwOffset = m_dwQuadsToFlush*16; + m_rgflQuadsColorData[dwOffset] = COLOR_RED( dwColor ); + m_rgflQuadsColorData[dwOffset+1] = COLOR_GREEN( dwColor ); + m_rgflQuadsColorData[dwOffset+2] = COLOR_BLUE( dwColor ); + m_rgflQuadsColorData[dwOffset+3] = COLOR_ALPHA( dwColor ); + m_rgflQuadsColorData[dwOffset+4] = COLOR_RED( dwColor ); + m_rgflQuadsColorData[dwOffset+5] = COLOR_GREEN( dwColor ); + m_rgflQuadsColorData[dwOffset+6] = COLOR_BLUE( dwColor ); + m_rgflQuadsColorData[dwOffset+7] = COLOR_ALPHA( dwColor ); + m_rgflQuadsColorData[dwOffset+8] = COLOR_RED( dwColor ); + m_rgflQuadsColorData[dwOffset+9] = COLOR_GREEN( dwColor ); + m_rgflQuadsColorData[dwOffset+10] = COLOR_BLUE( dwColor ); + m_rgflQuadsColorData[dwOffset+11] = COLOR_ALPHA( dwColor ); + m_rgflQuadsColorData[dwOffset+12] = COLOR_RED( dwColor ); + m_rgflQuadsColorData[dwOffset+13] = COLOR_GREEN( dwColor ); + m_rgflQuadsColorData[dwOffset+14] = COLOR_BLUE( dwColor ); + m_rgflQuadsColorData[dwOffset+15] = COLOR_ALPHA( dwColor ); + + dwOffset = m_dwQuadsToFlush*8; + m_rgflQuadsTextureData[dwOffset] = u0; + m_rgflQuadsTextureData[dwOffset+1] = v0; + m_rgflQuadsTextureData[dwOffset+2] = u1; + m_rgflQuadsTextureData[dwOffset+3] = v0; + m_rgflQuadsTextureData[dwOffset+4] = u1; + m_rgflQuadsTextureData[dwOffset+5] = v1; + m_rgflQuadsTextureData[dwOffset+6] = u0; + m_rgflQuadsTextureData[dwOffset+7] = v1; + + + ++m_dwQuadsToFlush; + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: Flush buffered quads +//----------------------------------------------------------------------------- +bool CGameEngineGL::BFlushQuadBuffer() +{ + if ( !m_rgflPointsColorData || !m_rgflPointsData || m_bShuttingDown ) + return false; + + if ( m_dwQuadsToFlush ) + { + glEnable( GL_TEXTURE_2D ); + glEnableClientState( GL_TEXTURE_COORD_ARRAY ); + + glColorPointer( 4, GL_UNSIGNED_BYTE, 0, m_rgflQuadsColorData ); + glVertexPointer( 3, GL_FLOAT, 0, m_rgflQuadsData ); + glTexCoordPointer( 2, GL_FLOAT, 0, m_rgflQuadsTextureData ); + glDrawArrays( GL_QUADS, 0, m_dwQuadsToFlush*4 ); + + glDisable( GL_TEXTURE_2D ); + glDisableClientState( GL_TEXTURE_COORD_ARRAY ); + + m_dwQuadsToFlush = 0; + } + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: Creates a new texture +//----------------------------------------------------------------------------- +HGAMETEXTURE CGameEngineGL::HCreateTexture( byte *pRGBAData, uint32 uWidth, uint32 uHeight ) +{ + if ( m_bShuttingDown ) + return 0; + + TextureData_t TexData; + TexData.m_uWidth = uWidth; + TexData.m_uHeight = uHeight; + TexData.m_uTextureID = 0; + + glEnable( GL_TEXTURE_2D ); + glGenTextures( 1, &TexData.m_uTextureID ); + glBindTexture( GL_TEXTURE_2D, TexData.m_uTextureID ); + + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0 ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0 ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); + + // build our texture mipmaps + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, uWidth, uHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, (void *)pRGBAData ); + glDisable( GL_TEXTURE_2D ); + + int nHandle = m_nNextTextureHandle; + ++m_nNextTextureHandle; + m_MapTextures[nHandle] = TexData; + + return nHandle; +} + + +//----------------------------------------------------------------------------- +// Purpose: Creates a new font +//----------------------------------------------------------------------------- +HGAMEFONT CGameEngineGL::HCreateFont( int nHeight, int nFontWeight, bool bItalic, const char * pchFont ) +{ + // For this sample we include a single font + pchFont = "DejaVuSans.ttf"; + + TTF_Font *font = TTF_OpenFont( pchFont, nHeight ); + if ( !font ) + { + OutputDebugString( "Couldn't create font: " ); + OutputDebugString( pchFont ); + OutputDebugString( "\n" ); + return 0; + } + + HGAMEFONT hFont = m_nNextFontHandle; + ++m_nNextFontHandle; + + int nStyle = TTF_STYLE_NORMAL; + if ( nFontWeight & FW_BOLD ) + { + nStyle |= TTF_STYLE_BOLD; + } + if ( bItalic ) + { + nStyle |= TTF_STYLE_ITALIC; + } + TTF_SetFontStyle( font, nStyle ); + + m_MapGameFonts[ hFont ] = font; + + return hFont; +} + + +//----------------------------------------------------------------------------- +// Purpose: Draws text to the screen inside the given rectangular region, using the given font +//----------------------------------------------------------------------------- +bool CGameEngineGL::BDrawString( HGAMEFONT hFont, RECT rect, DWORD dwColor, DWORD dwFormat, const char *pchText ) +{ + if ( !hFont ) + { + OutputDebugString( "Someone is calling BDrawString with a null font handle\n" ); + return false; + } + + if ( !pchText || !*pchText ) + { + return true; + } + + // Very simple cache of complete strings as whole textures. + // There are much better ways of doing efficient text rendering. + // If nothing else we should expire the strings not being used. + HGAMETEXTURE hTexture; + char szFontPrefix[32]; + sprintf( szFontPrefix, "%d:", hFont ); + std::map< std::string, HGAMETEXTURE >::iterator iter; + iter = m_MapStrings.find( std::string(szFontPrefix) + std::string(pchText) ); + if ( iter == m_MapStrings.end() ) + { + static SDL_Color white = { 0xff, 0xff, 0xff, 0xff }; + + // Calculate the text block size + int nWrapLength = 0; + int w, h; + char *s = (char *)pchText; + for ( char *p = strchr( s, '\n' ); p; p = strchr( s, '\n' ) ) + { + *p = '\0'; + if ( TTF_SizeUTF8( m_MapGameFonts[ hFont ], s, &w, &h ) == 0 ) + { + nWrapLength = std::max( w, nWrapLength ); + } + *p = '\n'; + s = p + 1; + } + if ( TTF_SizeUTF8( m_MapGameFonts[ hFont ], s, &w, &h ) == 0 ) + { + nWrapLength = std::max( w, nWrapLength ); + } + + SDL_Surface *surface = TTF_RenderUTF8_Blended_Wrapped( m_MapGameFonts[ hFont ], pchText, white, nWrapLength ); + if ( !surface ) + { + OutputDebugString( "Out of memory\n" ); + return false; + } + + uint32 uWidth = power_of_two( surface->w ); + uint32 uHeight = power_of_two( surface->h ); + byte *pRGBAData = (byte *)malloc( uWidth*uHeight*4 ); + if ( !pRGBAData ) + { + OutputDebugString( "Out of memory\n" ); + return false; + } + memset( pRGBAData, 0, uWidth*uHeight*4 ); + + byte *src = (byte*)surface->pixels; + byte *dst = pRGBAData; + memset(dst, 0xff, uWidth*4); + for ( uint32 row = 0; row < surface->h; ++row ) + { + memcpy( dst, src, surface->w * 4 ); + src += surface->pitch; + dst += uWidth * 4; + } + + hTexture = HCreateTexture( pRGBAData, uWidth, uHeight ); + free( pRGBAData ); + + // Record the actual text width and height + m_MapTextures[ hTexture ].m_uWidth = surface->w; + m_MapTextures[ hTexture ].m_uHeight = surface->h; + + SDL_FreeSurface( surface ); + + m_MapStrings[ std::string(szFontPrefix) + std::string(pchText) ] = hTexture; + } + else + { + hTexture = iter->second; + } + + int nWidth = m_MapTextures[ hTexture ].m_uWidth; + int nHeight = m_MapTextures[ hTexture ].m_uHeight; + float u = (float)nWidth / power_of_two(nWidth); + float v = (float)nHeight / power_of_two(nHeight); + + // Get text position + int nLeft = rect.left, nTop = rect.top; + if ( dwFormat & TEXTPOS_TOP ) + { + nTop = rect.top; + } + else if ( dwFormat & TEXTPOS_VCENTER ) + { + nTop = rect.top + ((rect.bottom - rect.top) - nHeight) / 2; + } + else if ( dwFormat & TEXTPOS_BOTTOM ) + { + nTop = rect.bottom - nHeight; + } + if ( dwFormat & TEXTPOS_LEFT ) + { + nLeft = rect.left; + } + else if ( dwFormat & TEXTPOS_CENTER ) + { + nLeft = rect.left + ((rect.right - rect.left) - nWidth) / 2; + } + else if ( dwFormat & TEXTPOS_RIGHT ) + { + nLeft = rect.right - nWidth; + } + +//printf("Drawing text '%s' at %d,%d %dx%d {%d,%d %d,%d}\n", pchText, nLeft, nTop, nWidth, nHeight, rect.left, rect.top, rect.right, rect.bottom); + return BDrawTexturedQuad( nLeft, nTop, nLeft + nWidth, nTop + nHeight, 0.0f, 0.0f, u, v, dwColor, hTexture ); +} + +void CGameEngineGL::UpdateKey( uint32_t vkKey, int nDown ) +{ + if ( nDown ) + m_SetKeysDown.insert( vkKey ); + else + m_SetKeysDown.erase( vkKey ); +} + +//----------------------------------------------------------------------------- +// Purpose: Message pump for OS messages +//----------------------------------------------------------------------------- +void CGameEngineGL::MessagePump() +{ + SDL_Event event; + + do + { + if ( SDL_PollEvent(&event) <= 0 ) + break; + + if ( event.type == SDL_KEYDOWN || event.type == SDL_KEYUP ) + { + DWORD dwVK = 0; + switch (event.key.keysym.sym) + { + case SDLK_BACKSPACE: dwVK = VK_BACK; break; + case SDLK_TAB: dwVK = VK_TAB; break; + case SDLK_RETURN: dwVK = VK_RETURN; break; + case SDLK_LSHIFT: dwVK = VK_SHIFT; break; + case SDLK_RSHIFT: dwVK = VK_SHIFT; break; + case SDLK_LCTRL: dwVK = VK_CONTROL; break; + case SDLK_RCTRL: dwVK = VK_CONTROL; break; + case SDLK_ESCAPE: dwVK = VK_ESCAPE; break; + case SDLK_SPACE: dwVK = VK_SPACE; break; + case SDLK_LEFT: dwVK = VK_LEFT; break; + case SDLK_UP: dwVK = VK_UP; break; + case SDLK_RIGHT: dwVK = VK_RIGHT; break; + case SDLK_DOWN: dwVK = VK_DOWN; break; + case SDLK_SELECT: dwVK = VK_SELECT; break; + case SDLK_F5: dwVK = VK_F5; break; + default: + { + if ( event.key.keysym.sym >= SDLK_a && event.key.keysym.sym <= SDLK_z ) + { + dwVK = 'A' + event.key.keysym.sym - SDLK_a; + } + } + break; + } + + if (dwVK) + { + if ( event.type == SDL_KEYDOWN ) + { + m_SetKeysDown.insert( dwVK ); + } + else + { + m_SetKeysDown.erase( dwVK ); + } + } + } + else if ( event.type == SDL_QUIT ) + { + CreateGameEngineSDL()->Shutdown(); + } + + } while ( !BShuttingDown() ); +} + +//----------------------------------------------------------------------------- +// Purpose: Find out if a key is currently down +//----------------------------------------------------------------------------- +bool CGameEngineGL::BIsKeyDown( DWORD dwVK ) +{ + std::set::iterator iter; + iter = m_SetKeysDown.find( dwVK ); + if ( iter != m_SetKeysDown.end() ) + return true; + + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: Get a down key value +//----------------------------------------------------------------------------- +bool CGameEngineGL::BGetFirstKeyDown( DWORD *pdwVK ) +{ + std::set::iterator iter; + iter = m_SetKeysDown.begin(); + if ( iter != m_SetKeysDown.end() ) + { + *pdwVK = *iter; + m_SetKeysDown.erase( iter ); + return true; + } + else + { + return false; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +HGAMEVOICECHANNEL CGameEngineGL::HCreateVoiceChannel() +{ + m_unVoiceChannelCount++; + CVoiceContext* pVoiceContext = new CVoiceContext; + + m_MapVoiceChannel[m_unVoiceChannelCount] = pVoiceContext; + + return m_unVoiceChannelCount; +} + +void CGameEngineGL::RunAudio() +{ + std::map::iterator iter; + + for( iter = m_MapVoiceChannel.begin(); iter!=m_MapVoiceChannel.end(); ++iter) + { + CVoiceContext* pVoice = iter->second; + + const int nBufferCount = ARRAYSIZE( pVoice->m_buffers ); + ALint nQueued, nProcessed; + alGetSourcei( pVoice->m_nSource, AL_BUFFERS_QUEUED, &nQueued ); + alGetSourcei( pVoice->m_nSource, AL_BUFFERS_PROCESSED, &nProcessed ); + + if ( ( nQueued == nBufferCount ) && ( nProcessed == 0 ) ) + { // No room at the inn + continue; + } + + ALuint nBufferID; + for ( int i = 0; i < nProcessed; i++ ) + alSourceUnqueueBuffers( pVoice->m_nSource, 1, &nBufferID ); + + int nMaxToQueue = nBufferCount - nQueued + nProcessed; + bool bQueued = false; + + while ( nMaxToQueue && !pVoice->m_pending.empty() ) + { + Packet_t &packet = pVoice->m_pending.front(); + + nBufferID = pVoice->m_buffers[ pVoice->m_nNextFreeBuffer ]; + alBufferData( nBufferID, AL_FORMAT_MONO16, packet.pData, packet.unSize, VOICE_OUTPUT_SAMPLE_RATE_IDEAL ); + pVoice->m_nNextFreeBuffer = (pVoice->m_nNextFreeBuffer + 1 ) % nBufferCount; + + alSourceQueueBuffers( pVoice->m_nSource, 1, &nBufferID); + + nMaxToQueue--; + free( packet.pData ); + pVoice->m_pending.pop(); + bQueued = true; + } + + if ( bQueued && ( (nQueued-nProcessed) == 0 ) ) + { + alSourcePlay( pVoice->m_nSource ); + } + } +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CGameEngineGL::DestroyVoiceChannel( HGAMEVOICECHANNEL hChannel ) +{ + std::map::iterator iter; + iter = m_MapVoiceChannel.find( hChannel ); + if ( iter != m_MapVoiceChannel.end() ) + { + CVoiceContext* pVoiceContext = iter->second; + + // free outstanding voice packets + + while( !pVoiceContext->m_pending.empty() ) + { + free( pVoiceContext->m_pending.front().pData ); + pVoiceContext->m_pending.pop(); + } + + delete pVoiceContext; + m_MapVoiceChannel.erase( iter ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CGameEngineGL::AddVoiceData( HGAMEVOICECHANNEL hChannel, const uint8 *pVoiceData, uint32 uLength ) +{ + std::map::iterator iter; + iter = m_MapVoiceChannel.find( hChannel ); + if ( iter == m_MapVoiceChannel.end() ) + return false; // channel not found + + CVoiceContext* pVoiceContext = iter->second; + + Packet_t packet; + + packet.pData = malloc ( uLength ); + memcpy( packet.pData, pVoiceData, uLength ); + packet.unSize = uLength; + + pVoiceContext->m_pending.push( packet ); + + return true; +} + diff --git a/steamworksexample/gameenginesdl.h b/steamworksexample/gameenginesdl.h new file mode 100644 index 0000000..5bb47ab --- /dev/null +++ b/steamworksexample/gameenginesdl.h @@ -0,0 +1,247 @@ +//========= Copyright � 1996-2008, Valve LLC, All rights reserved. ============ +// +// Purpose: Main class for the game engine -- SDL implementation +// +// $NoKeywords: $ +//============================================================================= + +#ifndef GAMEENGINESDL_H +#define GAMEENGINESDL_H + +typedef unsigned char byte; + +#include "GameEngine.h" + +#include +#include + +#include "SDL.h" +#include "SDL_opengl.h" +#include "SDL_ttf.h" + +#include +#include +#include + + + +// How big is the vertex buffer for batching lines in total? +// NOTE: This must be a multiple of the batch size below!!! (crashes will occur if it isn't) +#define LINE_BUFFER_TOTAL_SIZE 1000 + +// How many lines do we put in the buffer in between flushes? +// +// This should be enough smaller than the total size so that draw calls +// can finish using the data before we wrap around and discard it. +#define LINE_BUFFER_BATCH_SIZE 250 + +// How big is the vertex buffer for batching points in total? +// NOTE: This must be a multiple of the batch size below!!! (crashes will occur if it isn't) +#define POINT_BUFFER_TOTAL_SIZE 1800 + +// How many points do we put in the buffer in between flushes? +// +// This should be enough smaller than the total size so that draw calls +// can finish using the data before we wrap around and discard it. +#define POINT_BUFFER_BATCH_SIZE 600 + +// How big is the vertex buffer for batching quads in total? +// NOTE: This must be a multiple of the batch size below!!! (crashes will occur if it isn't) +#define QUAD_BUFFER_TOTAL_SIZE 1000 + +// How many quads do we put in the buffer in between flushes? +// +// This should be enough smaller than the total size so that draw calls +// can finish using the data before we wrap around and discard it. +#define QUAD_BUFFER_BATCH_SIZE 250 + + + +class CVoiceContext; +class GLString; + +class CGameEngineGL : public IGameEngine +{ +public: + + // Constructor + CGameEngineGL(); + + // Destructor + ~CGameEngineGL() { Shutdown(); } + + // Check if the game engine is initialized ok and ready for use + bool BReadyForUse() { return m_bEngineReadyForUse; } + + // Check if the engine is shutting down + bool BShuttingDown() { return m_bShuttingDown; } + + // Set the background color + void SetBackgroundColor( short a, short r, short g, short b ); + + // Start a frame, clear(), beginscene(), etc + bool StartFrame(); + + // Finish a frame, endscene(), present(), etc. + void EndFrame(); + + // Shutdown the game engine + void Shutdown(); + + // Pump messages from the OS + void MessagePump(); + + // Accessors for game screen size + int32 GetViewportWidth() { return m_nWindowWidth; } + int32 GetViewportHeight() { return m_nWindowHeight; } + + // Function for drawing text to the screen, dwFormat is a combination of flags like DT_LEFT, TEXTPOS_VCENTER etc... + bool BDrawString( HGAMEFONT hFont, RECT rect, DWORD dwColor, DWORD dwFormat, const char *pchText ); + + // Create a new font returning our internal handle value for it (0 means failure) + HGAMEFONT HCreateFont( int nHeight, int nFontWeight, bool bItalic, const char * pchFont ); + + // Create a new texture returning our internal handle value for it (0 means failure) + HGAMETEXTURE HCreateTexture( byte *pRGBAData, uint32 uWidth, uint32 uHeight ); + + // Draw a line, the engine itself will manage batching these (although you can explicitly flush if you need to) + bool BDrawLine( float xPos0, float yPos0, DWORD dwColor0, float xPos1, float yPos1, DWORD dwColor1 ); + + // Flush the line buffer + bool BFlushLineBuffer(); + + // Draw a point, the engine itself will manage batching these (although you can explicitly flush if you need to) + bool BDrawPoint( float xPos, float yPos, DWORD dwColor ); + + // Flush the point buffer + bool BFlushPointBuffer(); + + // Draw a filled quad + bool BDrawFilledQuad( float xPos0, float yPos0, float xPos1, float yPos1, DWORD dwColor ); + + // Draw a textured rectangle + bool BDrawTexturedQuad( float xPos0, float yPos0, float xPos1, float yPos1, + float u0, float v0, float u1, float v1, DWORD dwColor, HGAMETEXTURE hTexture ); + + // Flush any still cached quad buffers + bool BFlushQuadBuffer(); + + // Get the current state of a key + bool BIsKeyDown( DWORD dwVK ); + + // Get the first (in some arbitrary order) key down, if any + bool BGetFirstKeyDown( DWORD *pdwVK ); + + // Get current tick count for the game engine + uint64 GetGameTickCount() { return m_ulGameTickCount; } + + // Get the tick count elapsed since the previous frame + // bugbug - We use this time to compute things like thrust and acceleration in the game, + // so it's important in doesn't jump ahead by large increments... Need a better + // way to handle that. + uint64 GetGameTicksFrameDelta() { return m_ulGameTickCount - m_ulPreviousGameTickCount; } + + // Tell the game engine to update current tick count + void UpdateGameTickCount(); + + // Tell the game engine to sleep for a bit if needed to limit frame rate + bool BSleepForFrameRateLimit( uint32 ulMaxFrameRate ); + + // Check if the game engine hwnd currently has focus (and a working d3d device) + bool BGameEngineHasFocus() { return true; } + + // Voice chat functions + virtual HGAMEVOICECHANNEL HCreateVoiceChannel(); + virtual void DestroyVoiceChannel( HGAMEVOICECHANNEL hChannel ); + virtual bool AddVoiceData( HGAMEVOICECHANNEL hChannel, const uint8 *pVoiceData, uint32 uLength ); + + void AdjustViewport(); + + // Initialize graphics + bool BInitializeGraphics(); + + // Initialize the debug font library + bool BInitializeCellDbgFont(); + + bool BInitializeAudio(); + + void RunAudio(); + + void UpdateKey( uint32_t vkKey, int nDown ); + + // Tracks whether the engine is ready for use + bool m_bEngineReadyForUse; + + // Tracks if we are shutting down + bool m_bShuttingDown; + + // The SDL window + SDL_Window *m_window; + SDL_GLContext m_context; + + // Size of the window to display the game in + int32 m_nWindowWidth; + int32 m_nWindowHeight; + + // Current game time in milliseconds + uint64 m_ulGameTickCount; + + // Game time at the start of the previous frame + uint64 m_ulPreviousGameTickCount; + + // White texture used when drawing filled quads + HGAMETEXTURE m_hTextureWhite; + + // Pointer to actual data for points + GLfloat *m_rgflPointsData; + GLubyte *m_rgflPointsColorData; + + // How many points are outstanding needing flush + DWORD m_dwPointsToFlush; + + // Pointer to actual data for lines + GLfloat *m_rgflLinesData; + GLubyte *m_rgflLinesColorData; + + + // How many lines are outstanding needing flush + DWORD m_dwLinesToFlush; + + // Pointer to actual data for quads + GLfloat *m_rgflQuadsData; + GLubyte *m_rgflQuadsColorData; + GLfloat *m_rgflQuadsTextureData; + + // How many lines are outstanding needing flush + DWORD m_dwQuadsToFlush; + + // Map of font handles we have given out + HGAMEFONT m_nNextFontHandle; + std::map< HGAMEFONT, TTF_Font * > m_MapGameFonts; + std::map< std::string, HGAMETEXTURE > m_MapStrings; + + // Map of handles to texture objects + struct TextureData_t + { + uint32 m_uWidth; + uint32 m_uHeight; + GLuint m_uTextureID; + }; + std::map m_MapTextures; + HGAMETEXTURE m_nNextTextureHandle; + + // Last bound texture, used to know when we must flush + HGAMETEXTURE m_hLastTexture; + + // Map of button state, translated to VK for win32. + std::set< DWORD > m_SetKeysDown; + + ALCcontext* m_palContext; + ALCdevice* m_palDevice; + + // Map of voice handles + std::map m_MapVoiceChannel; + uint32 m_unVoiceChannelCount; +}; + +#endif // GAMEENGINESDL_H diff --git a/steamworksexample/gameenginewin32.cpp b/steamworksexample/gameenginewin32.cpp index c58e461..5bfdf0e 100644 --- a/steamworksexample/gameenginewin32.cpp +++ b/steamworksexample/gameenginewin32.cpp @@ -1537,7 +1537,7 @@ HGAMETEXTURE CGameEngineWin32::HCreateTexture( byte *pRGBAData, uint32 uWidth, u //----------------------------------------------------------------------------- // Purpose: Creates a new font //----------------------------------------------------------------------------- -HGAMEFONT CGameEngineWin32::HCreateFont( int nHeight, int nFontWeight, bool bItalic, char * pchFont ) +HGAMEFONT CGameEngineWin32::HCreateFont( int nHeight, int nFontWeight, bool bItalic, const char * pchFont ) { if ( !m_pD3D9Device ) return 0; @@ -1803,4 +1803,4 @@ bool CGameEngineWin32::AddVoiceData( HGAMEVOICECHANNEL hChannel, const uint8 *pV } return true; -} \ No newline at end of file +} diff --git a/steamworksexample/gameenginewin32.h b/steamworksexample/gameenginewin32.h index d475015..3188f64 100644 --- a/steamworksexample/gameenginewin32.h +++ b/steamworksexample/gameenginewin32.h @@ -116,7 +116,7 @@ public: bool BDrawString( HGAMEFONT hFont, RECT rect, DWORD dwColor, DWORD dwFormat, const char *pchText ); // Create a new font returning our internal handle value for it (0 means failure) - HGAMEFONT HCreateFont( int nHeight, int nFontWeight, bool bItalic, char * pchFont ); + HGAMEFONT HCreateFont( int nHeight, int nFontWeight, bool bItalic, const char * pchFont ); // Create a new texture returning our internal handle value for it (0 means failure) HGAMETEXTURE HCreateTexture( byte *pRGBAData, uint32 uWidth, uint32 uHeight ); @@ -350,4 +350,4 @@ private: uint32 m_unVoiceChannelCount; }; -#endif // GAMEENGINEWIN32_H \ No newline at end of file +#endif // GAMEENGINEWIN32_H diff --git a/steamworksexample/voicechat.cpp b/steamworksexample/voicechat.cpp index ecfd94c..6c2ac41 100644 --- a/steamworksexample/voicechat.cpp +++ b/steamworksexample/voicechat.cpp @@ -97,7 +97,7 @@ void CVoiceChat::RunFrame() const uint8* pVoiceData = (const uint8*) buffer; pVoiceData += sizeof(MsgVoiceChatData_t); - EVoiceResult res = SteamUser()->DecompressVoice( pVoiceData , nBytesWritten, + res = SteamUser()->DecompressVoice( pVoiceData , nBytesWritten, m_ubUncompressedVoice, sizeof( m_ubUncompressedVoice ), &numUncompressedBytes, VOICE_OUTPUT_SAMPLE_RATE ); if ( res == k_EVoiceResultOK && numUncompressedBytes > 0 ) @@ -193,7 +193,7 @@ void CVoiceChat::MarkPlayerAsActive( CSteamID steamID ) } /*char szText[100]; - _snprintf(szText, 100, "CVoiceChat::AddPlayerToSession: %s.\n", SteamFriends()->GetFriendPersonaName( steamID ) ); + sprintf_safe(szText, "CVoiceChat::AddPlayerToSession: %s.\n", SteamFriends()->GetFriendPersonaName( steamID ) ); OutputDebugString( szText ); */ VoiceChatConnection_t session; @@ -352,4 +352,4 @@ void CVoiceChat::SendMessageToAll( const void *pubData, uint32 cubData ) iter->second.ulLastSentTime = ulTimeNow; } } -} \ No newline at end of file +} diff --git a/tools/ContentPrep.zip b/tools/ContentPrep.zip index 54cb707..b6132c3 100644 Binary files a/tools/ContentPrep.zip and b/tools/ContentPrep.zip differ diff --git a/tools/drm/Release/drmunpackp.dll b/tools/drm/Release/drmunpackp.dll index 66f889a..e44be9b 100644 Binary files a/tools/drm/Release/drmunpackp.dll and b/tools/drm/Release/drmunpackp.dll differ diff --git a/tools/drm/Release/steamdrmp.dll b/tools/drm/Release/steamdrmp.dll index a95fda7..d2079ba 100644 Binary files a/tools/drm/Release/steamdrmp.dll and b/tools/drm/Release/steamdrmp.dll differ diff --git a/tools/drm/drmtoolp.exe b/tools/drm/drmtoolp.exe index 023ab62..e0308fe 100644 Binary files a/tools/drm/drmtoolp.exe and b/tools/drm/drmtoolp.exe differ diff --git a/tools/drm/ubuntu12_32/drmtoolp b/tools/drm/ubuntu12_32/drmtoolp new file mode 100644 index 0000000..021314a Binary files /dev/null and b/tools/drm/ubuntu12_32/drmtoolp differ diff --git a/tools/drm/ubuntu12_32/drmunpackp.so b/tools/drm/ubuntu12_32/drmunpackp.so new file mode 100644 index 0000000..bc6532c Binary files /dev/null and b/tools/drm/ubuntu12_32/drmunpackp.so differ diff --git a/tools/drm/ubuntu12_32/steamdrmp.so b/tools/drm/ubuntu12_32/steamdrmp.so new file mode 100644 index 0000000..480848e Binary files /dev/null and b/tools/drm/ubuntu12_32/steamdrmp.so differ diff --git a/tools/drm/ubuntu12_64/drmtoolp b/tools/drm/ubuntu12_64/drmtoolp new file mode 100644 index 0000000..f4f500b Binary files /dev/null and b/tools/drm/ubuntu12_64/drmtoolp differ diff --git a/tools/drm/ubuntu12_64/drmunpackp.so b/tools/drm/ubuntu12_64/drmunpackp.so new file mode 100644 index 0000000..356d8af Binary files /dev/null and b/tools/drm/ubuntu12_64/drmunpackp.so differ diff --git a/tools/drm/ubuntu12_64/steamdrmp.so b/tools/drm/ubuntu12_64/steamdrmp.so new file mode 100644 index 0000000..1975741 Binary files /dev/null and b/tools/drm/ubuntu12_64/steamdrmp.so differ diff --git a/tools/drm/win64/Release/drmunpackp.dll b/tools/drm/win64/Release/drmunpackp.dll index c062e32..5c47329 100644 Binary files a/tools/drm/win64/Release/drmunpackp.dll and b/tools/drm/win64/Release/drmunpackp.dll differ diff --git a/tools/drm/win64/Release/steamdrmp.dll b/tools/drm/win64/Release/steamdrmp.dll index 6f026e7..2f69589 100644 Binary files a/tools/drm/win64/Release/steamdrmp.dll and b/tools/drm/win64/Release/steamdrmp.dll differ diff --git a/tools/linux/README.txt b/tools/linux/README.txt new file mode 100644 index 0000000..585a96c --- /dev/null +++ b/tools/linux/README.txt @@ -0,0 +1,70 @@ + +This is a set of tools targeting the Steam Linux Runtime. + +Setup +------------- + +The first time you install the runtime SDK, you should run the setup +script from the command line to download the set of packages you need +for development: + bash setup.sh + +You can pick your target architecture(s) and either the release or debug +version of the runtime. The debug runtime is built without optimizations +and includes full source code. + +You can re-run the script at any time to reconfigure the SDK. There are +a number of command line options for automating the script, which you can +see by running the script with the --help option. + + +Updates +------- + +You can run the setup script at any time to get the latest version of the SDK: + setup.sh --auto-update + +If you need to get an old version, you can specify it with --version: + setup.sh --version=2013-02-22 + + +Builds +------- + +Use the appropriate shell script to set up the environment for building with +the runtime, or just look to see what environment variables it sets and use +them directly in your build process. + +For example to run a shell targeting 32-bit architecture: + shell-i386.sh + +For example to run a shell targeting 64-bit architecture: + shell-amd64.sh + + +Testing +------- + +Once you have built a program that targets the runtime, you can verify +that all the dependencies are covered by the runtime with: + runtime/scripts/check-program.sh | grep " /usr" + +(note that the C library, OpenGL and 3D drivers are outside the runtime) + +You can run programs in the runtime environment for testing with: + run.sh +e.g. + run.sh ./MyGame -windowed + +You can debug your programs in the runtime environment with run.sh as well: + run.sh gdb MyGame + (gdb) r -windowed + + +More Info +--------- + +You can get the scripts used to build these tools and report issues at: + https://github.com/ValveSoftware/steam-runtime + +Enjoy! diff --git a/tools/linux/setup.sh b/tools/linux/setup.sh new file mode 100644 index 0000000..0b6a864 --- /dev/null +++ b/tools/linux/setup.sh @@ -0,0 +1,368 @@ +#!/bin/bash +# +# This script runs a shell with the environment set up for the Steam runtime +# development environment. + +# The top level of the cross-compiler tree +ORIG_PWD="${PWD}" +TOP=$(cd "${0%/*}" 2>/dev/null; echo "${PWD}") +cd "${TOP}" + +CONFIG=.config +ARCHITECTURES="i386 amd64" +ARCHIVE_EXT="tar.xz" +RUNTIME_VERSION=latest + +exit_usage() +{ + echo "Usage: $0 [--host=] [--target=] [--debug|--release] [--version=] [--depot=] [--perforce] [--reset] [--auto-update] [--checkonly]" >&2 + exit 1 +} + +function has_command() +{ + command -v $1 >/dev/null + return $? +} + +function detect_arch() +{ + case $(uname -m) in + *64) + echo "amd64" + ;; + *) + echo "i386" + ;; + esac +} + +function reset_sdk() +{ + if [ "${AUTO_UPGRADE}" != "true" ]; then + echo "This will clean the SDK and redownload packages." + read -p "Are you sure you want to continue? [y/N]: " response + if [ "${response}" != "y" -a "${response}" != "Y" ]; then + exit 2 + fi + fi + + rm -rf checksums ${ARCHITECTURES} runtime* + echo "Reset complete." + echo +} + +declare -a ARGS=("$@") +while [ "$1" ]; do + case "$1" in + --relaunch) + RELAUNCHED=true + ;; + --host=*) + HOST_ARCH=$(expr "$1" : '[^=]*=\(.*\)') + ;; + --target=*) + TARGET_ARCH=$(expr "$1" : '[^=]*=\(.*\)') + ;; + --debug) + RUNTIME_FLAVOR="debug" + ;; + --release) + RUNTIME_FLAVOR="release" + ;; + --version=*) + RUNTIME_VERSION=$(expr "$1" : '[^=]*=\(.*\)') + ;; + --depot=*) + URL_PREFIX=$(expr "$1" : '[^=]*=\(.*\)') + ;; + --perforce) + USE_P4=true + ;; + --reset) + if [ "${RELAUNCHED}" != "true" ]; then + reset_sdk + fi + ;; + --auto-update|--auto-upgrade) + AUTO_UPGRADE=true + ;; + --checkonly) + CHECK_ONLY=true + ;; + -h|--help) + exit_usage + ;; + -*) + echo "Unknown command line parameter: $1" >&2 + exit_usage + ;; + *) + break + ;; + esac + + shift +done + +function check_curl() +{ + if ! has_command curl; then + if has_command apt-get; then + echo "Installing curl to download packages..." + sudo apt-get install curl + echo + else + echo "Please install curl to download packages." + exit 2 + fi + fi +} + +# Make sure we have curl to download packages +check_curl + +if [ -z "${HOST_ARCH}" ]; then + HOST_ARCH=$(grep HOST_ARCH ${CONFIG} 2>/dev/null | awk -F= '{print $2}') + if [ "${HOST_ARCH}" = "" ]; then + HOST_ARCH=$(detect_arch) + fi +fi + +DEFAULT_TARGET=$(grep TARGET_ARCH ${CONFIG} 2>/dev/null | awk -F= '{print $2}') +if [ "${DEFAULT_TARGET}" = "" ]; then + # Most people are targeting i386 (for now!) + DEFAULT_TARGET=i386 +fi +if [ -z "${TARGET_ARCH}" -a "${AUTO_UPGRADE}" = "true" ]; then + TARGET_ARCH="${DEFAULT_TARGET}" +fi +if [ -z "${TARGET_ARCH}" ]; then + cat <<__EOF__ +====================================== +Which architectures would you like to target? + 1) i386 (x86 32-bit) + 2) amd64 (x64 64-bit) + 3) all supported architectures +__EOF__ + read -p "Default ${DEFAULT_TARGET}: " response + case "${response}" in + 1|i386) + TARGET_ARCH=i386 + ;; + 2|amd64) + TARGET_ARCH=amd64 + ;; + 3|all) + TARGET_ARCH="${ARCHITECTURES}" + ;; + *) + TARGET_ARCH="${DEFAULT_TARGET}" + ;; + esac + echo "Set target architecture to: ${TARGET_ARCH}" + echo +fi + +DEFAULT_FLAVOR=$(grep RUNTIME_FLAVOR ${CONFIG} 2>/dev/null | awk -F= '{print $2}') +if [ "${DEFAULT_FLAVOR}" = "" ]; then + DEFAULT_FLAVOR=release +fi +if [ -z "${RUNTIME_FLAVOR}" -a "${AUTO_UPGRADE}" = "true" ]; then + RUNTIME_FLAVOR="${DEFAULT_FLAVOR}" +fi +if [ -z "${RUNTIME_FLAVOR}" ]; then + cat <<__EOF__ +====================================== +Which runtime flavor would you like to use? + 1) release + 2) debug +__EOF__ + read -p "Default ${DEFAULT_FLAVOR}: " response + case "${response}" in + 1) RUNTIME_FLAVOR=release;; + 2) RUNTIME_FLAVOR=debug;; + *) RUNTIME_FLAVOR="${DEFAULT_FLAVOR}";; + esac + echo "Set runtime flavor to: ${RUNTIME_FLAVOR}" + echo +fi + +if [ -z "${URL_PREFIX}" ]; then + URL_PREFIX="http://media.steampowered.com/client/runtime" +fi + +# Make everything writable if we're using Perforce +if [ "${USE_P4}" = "true" ]; then + chmod -R +w . +fi + +# Save our config +: >${CONFIG} +echo "HOST_ARCH=${HOST_ARCH}" >>${CONFIG} +echo "TARGET_ARCH=${TARGET_ARCH}" >>${CONFIG} +echo "RUNTIME_FLAVOR=${RUNTIME_FLAVOR}" >>${CONFIG} + + +UPDATED_FILES_RETURNCODE=42 + +function update_archive() +{ + local NAME=$1 + local DEST=$2 + + if [ -z "${NAME}" -o -z "${DEST}" ]; then + echo "Internal error: update_archive " 2>&1 + exit 255 + fi + + # Download the latest archive checksum and see if we already have it + local ARCHIVE="${NAME}_${RUNTIME_VERSION}.${ARCHIVE_EXT}" + local CHECKSUM_FILE="${ARCHIVE}.md5" + local CHECKSUM=$(curl -sf "${URL_PREFIX}/${CHECKSUM_FILE}") + if [ "${CHECKSUM}" = "" ]; then + # No updates available + return 0 + fi + if [ -f "checksums/${CHECKSUM_FILE}" ] && \ + [ "$(cat "checksums/${CHECKSUM_FILE}")" = "${CHECKSUM}" ]; then + # We're all done! + return 0 + fi + + if [ "$CHECK_ONLY" = "true" ]; then + echo "Update available: ${URL_PREFIX}/${ARCHIVE}" + return 1 + fi + + # Download and extract the archive + echo "Installing ${URL_PREFIX}/${ARCHIVE}..." + curl -#f "${URL_PREFIX}/${ARCHIVE}" | tar xJf - --strip-components=1 -C "${DEST}" + + # Update the checksum + mkdir -p checksums + rm -f checksums/${NAME}_* + echo "${CHECKSUM}" >"checksums/${CHECKSUM_FILE}" + + # All done! + return ${UPDATED_FILES_RETURNCODE} +} + +function fold_case() +{ + echo "Removing files with the same case..." + find . \( -type f -o -type l \) | sort -f | uniq -i -d | while read file; do + find "$(dirname "$file")" -iname "$(basename "$file")" | while read other; do + if [ "$other" != "$file" ]; then + rm -v "$other" + fi + done + done +} + +function p4reconcile() +{ + P4LOG=/tmp/p4.log + fold_case + p4 reconcile -f ... >"${P4LOG}" + echo "Perforce log is in ${P4LOG}" +} + +# Update SDK files and restart if necessary +if [ "${RELAUNCHED}" = "true" ]; then + response=n +elif [ "${AUTO_UPGRADE}" = "true" ]; then + response=y +else + echo "======================================" + read -p "Update base SDK? [Y/n]: " response +fi +if [ "${response}" != "n" ]; then + update_archive steam-runtime-sdk . + case $? in + 0) + if [ "${AUTO_UPGRADE}" != "true" ]; then + echo "No updates available." + fi + ;; + ${UPDATED_FILES_RETURNCODE}) + echo + cd "${ORIG_PWD}" + exec "$0" --relaunch --host="${HOST_ARCH}" --target="${TARGET_ARCH}" --${RUNTIME_FLAVOR} "${ARGS[@]}" + ;; + esac + echo +fi + +# Update tools +if [ "${AUTO_UPGRADE}" = "true" ]; then + response=y +else + echo "======================================" + read -p "Update tools? [Y/n]: " response +fi +if [ "${response}" != "n" ]; then + AVAILABLE_UPDATES=false + for host_arch in ${HOST_ARCH}; do + for target_arch in ${TARGET_ARCH}; do + update_archive x-tools-${host_arch}-${target_arch} . + case $? in + 0) + ;; + *) + AVAILABLE_UPDATES=true + ;; + esac + done + done + if [ "${AVAILABLE_UPDATES}" != "true" -a "${AUTO_UPGRADE}" != "true" ]; then + echo "No updates available." + fi + echo +fi + +# Update runtime +if [ "${AUTO_UPGRADE}" = "true" ]; then + response=y +else + echo "======================================" + read -p "Update runtime? [Y/n]: " response +fi +if [ "${response}" != "n" ]; then + AVAILABLE_UPDATES=false + for target_arch in ${TARGET_ARCH}; do + mkdir -p runtime-${RUNTIME_FLAVOR} + update_archive steam-runtime-dev-${RUNTIME_FLAVOR}-${target_arch} runtime-${RUNTIME_FLAVOR} + case $? in + 0) + ;; + *) + AVAILABLE_UPDATES=true + ;; + esac + done + if [ "${AVAILABLE_UPDATES}" != "true" -a "${AUTO_UPGRADE}" != "true" ]; then + echo "No updates available." + fi + echo +fi +rm -f runtime || exit 16 +ln -s runtime-${RUNTIME_FLAVOR} runtime + +# Set up symbolic link to automatically find source when debugging +if [ "${RUNTIME_FLAVOR}" = "debug" ]; then + rm -f /tmp/source && \ + ln -sf "${TOP}/runtime-${RUNTIME_FLAVOR}/source" /tmp/source +fi + +if [ "${USE_P4}" = "true" ]; then + echo "======================================" + echo "Creating Perforce changelist..." + p4reconcile + echo +fi + +echo "======================================" +echo "Update complete!" + +# vi: ts=4 sw=4 expandtab