This commit is contained in:
Riley Labrecque
2014-01-29 13:11:56 +02:00
parent 6e588c2100
commit 1fe25a6746
77 changed files with 4061 additions and 347 deletions
+31
View File
@@ -11,6 +11,37 @@ website at: http://partner.steamgames.com
Revision History:
----------------------------------------------------------------
v1.12 10th November 2010
----------------------------------------------------------------
Cloud
* added a set of function to handle publishing User Generated Content (UGC) files to the backend, and to download others users UGC files. This enables games to have users easily publish & share content with each other.
Leaderboards
* added ISteamUserStats::DownloadLeaderboardEntriesForUsers(), which downloads scores for an arbitrary set of users
* added ISteamUserStats::AttachLeaderboardUGC(), to attach a clouded file to a leaderboard entry
Friends
* added ISteamFriends::RequestUserInformation(), to asynchronously request a users persona name & avatar by steamID
* added ISteamFriends::RequestClanOfficerList(), to asynchronously download the set of officers for a clan. GetClanOwner(), GetClanOfficerCount(), and GetClanOfficerByIndex() can then be used to access the data.
Matchmaking
* added k_ELobbyTypePrivate option to creating lobbies - this means that the lobby won't show up to friends or be returned in searches
* added LobbyDataUpdate_t::m_bSuccess, to easily check if a RequestLobbyData() call failed to find the specified lobby
Authentication
* added ISteamApps::GetEarliestPurchaseUnixTime(), for games that want to reward users who have played for a long time
* added ISteamApps::BIsSubscribedFromFreeWeekend(), so games can show different offers or information for users who currently only have rights to play the game due to a free weekend promotion
* added ISteamGameServer::GetAuthSessionTicket(), BeginAuthSession(), EndAuthSession(), and CancelAuthTicket(), matching what exists in ISteamUser. This allows game servers and clients to authenticate each other in a unified manner.
Steamworks Example
* added OpenGL and OSX support
PS3
* added several functions regarding PS3 support. This is still a work in progress, and no PS3 binaries are included.
----------------------------------------------------------------
v1.11 23rd August 2010
----------------------------------------------------------------
+14 -2
View File
@@ -1,4 +1,4 @@
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
//========= Copyright � 1996-2008, Valve LLC, All rights reserved. ============
//
// Purpose: Main class for the game engine
//
@@ -21,6 +21,9 @@ typedef int HGAMEVERTBUF;
typedef int HGAMETEXTURE;
// Typedef for voice channels
typedef int HGAMEVOICECHANNEL;
// BDrawText position flags
#define TEXTPOS_TOP 0x00000000
#define TEXTPOS_LEFT 0x00000000
@@ -29,6 +32,11 @@ typedef int HGAMETEXTURE;
#define TEXTPOS_VCENTER 0x00000004
#define TEXTPOS_BOTTOM 0x00000008
#define VOICE_OUTPUT_SAMPLE_RATE 11000 // real sample rate is 11025 but for XAudio2 it must be a multiple of XAUDIO2_QUANTUM_DENOMINATOR
#define VOICE_OUTPUT_SAMPLE_RATE_IDEAL 11025
#define BYTES_PER_SAMPLE 2
//
// Interface that needs to be implemented for game engines on all platforms
//
@@ -36,7 +44,7 @@ class IGameEngine
{
public:
// Just here to stop warnings on non-virtual destructor in PS3 build
// Just here to stop warnings on non-virtual destructor in gcc builds
virtual ~IGameEngine() {};
// Check if the game engine is initialized ok and ready for use
@@ -121,6 +129,10 @@ public:
// Check if the game engine hwnd currently has focus (and a working d3d device)
virtual bool BGameEngineHasFocus() = 0;
// Voice chat functions
virtual HGAMEVOICECHANNEL HCreateVoiceChannel() = 0;
virtual void DestroyVoiceChannel( HGAMEVOICECHANNEL hChannel ) = 0;
virtual bool AddVoiceData( HGAMEVOICECHANNEL hChannel, const uint8 *pVoiceData, uint32 uLength ) = 0;
};
#endif // GAMEENGINE_H
+2 -1
View File
@@ -1,4 +1,4 @@
//========= Copyright © 1996-2009, Valve LLC, All rights reserved. ============
//========= Copyright � 1996-2009, Valve LLC, All rights reserved. ============
//
// Purpose: Class for tracking leaderboards
//
@@ -6,6 +6,7 @@
#include "stdafx.h"
#include "leaderboards.h"
#include "BaseMenu.h"
#include <math.h>
//-----------------------------------------------------------------------------
+62 -168
View File
@@ -1,4 +1,4 @@
//====== Copyright © 1996-2008, Valve Corporation, All rights reserved. =======
//====== Copyright � 1996-2008, Valve Corporation, All rights reserved. =======
//
// Purpose: Main file for the SteamworksExample app
//
@@ -6,20 +6,21 @@
#include "stdafx.h"
#ifdef WIN32
#include "gameenginewin32.h"
#elif _PS3
#include "gameengineps3.h"
#if defined(WIN32)
#include "gameenginewin32.h"
#define atoll _atoi64
#elif defined(OSX)
#include "GameEngine.h"
extern IGameEngine *CreateGameEngineOSX();
#endif
#include "SpaceWarClient.h"
//-----------------------------------------------------------------------------
// Purpose: Wrapper around SteamAPI_WriteMiniDump which can be used directly
// as a se translator
//-----------------------------------------------------------------------------
#ifndef _PS3
#ifdef _WIN32
void MiniDumpFunction( unsigned int nExceptionCode, EXCEPTION_POINTERS *pException )
{
// You can build and set an arbitrary comment to embed in the minidump here,
@@ -32,6 +33,14 @@ void MiniDumpFunction( unsigned int nExceptionCode, EXCEPTION_POINTERS *pExcepti
}
#endif
static int Alert( const char *lpCaption, const char *lpText )
{
#ifndef _WIN32
fprintf( stderr, "Message: '%s', Detail: '%s'\n", lpCaption, lpText );
#else
return ::MessageBox( NULL, lpText, lpCaption, MB_OK );
#endif
}
//-----------------------------------------------------------------------------
// Purpose: callback hook for debug text emitted from the Steam API
@@ -50,16 +59,17 @@ extern "C" void __cdecl SteamAPIDebugTextHook( int nSeverity, const char *pchDeb
}
}
//-----------------------------------------------------------------------------
// Purpose: Main loop code shared between all platforms
//-----------------------------------------------------------------------------
void RunGameLoop( IGameEngine *pGameEngine, char *pchServerAddress, char *pchLobbyID )
void RunGameLoop( IGameEngine *pGameEngine, const char *pchServerAddress, const char *pchLobbyID )
{
// Make sure it initialized ok
if ( pGameEngine->BReadyForUse() )
{
// Initialize the game
CSpaceWarClient *pGameClient = new CSpaceWarClient( pGameEngine, SteamUser()->GetSteamID() );
CSpaceWarClient *pGameClient = new CSpaceWarClient( pGameEngine );
// Black background
pGameEngine->SetBackgroundColor( 0, 0, 0, 0 );
@@ -82,11 +92,7 @@ void RunGameLoop( IGameEngine *pGameEngine, char *pchServerAddress, char *pchLob
// if +connect_lobby was used to specify a lobby to join, connect now
if ( pchLobbyID )
{
#ifndef _PS3
CSteamID steamIDLobby( (uint64)_atoi64( pchLobbyID ) );
#else
CSteamID steamIDLobby( (uint64)atoll( pchLobbyID ) );
#endif
if ( steamIDLobby.IsValid() )
{
// act just like we had selected it from the menu
@@ -96,9 +102,7 @@ void RunGameLoop( IGameEngine *pGameEngine, char *pchServerAddress, char *pchLob
}
// test a user specific secret before entering main loop
#ifndef _PS3
Steamworks_TestSecret();
#endif
pGameClient->RetrieveEncryptedAppTicket();
@@ -132,11 +136,8 @@ void RunGameLoop( IGameEngine *pGameEngine, char *pchServerAddress, char *pchLob
//-----------------------------------------------------------------------------
// Purpose: Real main entry point for the program
//-----------------------------------------------------------------------------
#ifdef WIN32
int APIENTRY RealMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
#ifndef _PS3
static int RealMain( const char *pchCmdLine, HINSTANCE hInstance, int nCmdShow )
{
if ( SteamAPI_RestartAppIfNecessary( k_uAppIdInvalid ) )
@@ -155,7 +156,7 @@ int APIENTRY RealMain(HINSTANCE hInstance,
if ( !Steamworks_InitCEGLibrary() )
{
OutputDebugString( "Steamworks_InitCEGLibrary() failed\n" );
::MessageBox( NULL, "Steam must be running to play this game (InitDrmLibrary() failed).\n", "Fatal Error", MB_OK );
Alert( "Fatal Error", "Steam must be running to play this game (InitDrmLibrary() failed).\n" );
return EXIT_FAILURE;
}
@@ -169,7 +170,7 @@ int APIENTRY RealMain(HINSTANCE hInstance,
if ( !SteamAPI_Init() )
{
OutputDebugString( "SteamAPI_Init() failed\n" );
::MessageBox( NULL, "Steam must be running to play this game (SteamAPI_Init() failed).\n", "Fatal Error", MB_OK );
Alert( "Fatal Error", "Steam must be running to play this game (SteamAPI_Init() failed).\n" );
return EXIT_FAILURE;
}
@@ -187,9 +188,8 @@ int APIENTRY RealMain(HINSTANCE hInstance,
// Steam will pass this when a user has used the Steam Server browser to find
// a server for our game and is trying to join it.
const char *pchConnectParam = "+connect";
char *pchCmdLine = ::GetCommandLine();
char *pchConnect = strstr( pchCmdLine, pchConnectParam );
char *pchServerAddress = NULL;
const char *pchConnect = strstr( pchCmdLine, pchConnectParam );
const char *pchServerAddress = NULL;
if ( pchConnect && strlen( pchCmdLine ) > (pchConnect - pchCmdLine) + strlen( pchConnectParam ) + 1 )
{
// Address should be right after the +connect, +1 on the end to skip the space
@@ -199,8 +199,8 @@ int APIENTRY RealMain(HINSTANCE hInstance,
// look for +connect_lobby lobbyid paramter on the command line
// Steam will pass this in if a user taken up an invite to a lobby
const char *pchConnectLobbyParam = "+connect_lobby";
char *pchConnectLobby = strstr( pchCmdLine, pchConnectParam );
char *pchLobbyID = NULL;
const char *pchConnectLobby = strstr( pchCmdLine, pchConnectParam );
const char *pchLobbyID = NULL;
if ( pchConnectLobby && strlen( pchCmdLine ) > (pchConnectLobby - pchCmdLine) + strlen( pchConnectLobbyParam ) + 1 )
{
// Address should be right after the +connect, +1 on the end to skip the space
@@ -212,8 +212,13 @@ int APIENTRY RealMain(HINSTANCE hInstance,
// Construct a new instance of the game engine
// bugbug jmccaskey - make screen resolution dynamic, maybe take it on command line?
CGameEngineWin32 *pGameEngine = new CGameEngineWin32( hInstance, nCmdShow, 1024, 768 );
IGameEngine *pGameEngine =
#if defined(_WIN32)
new CGameEngineWin32( hInstance, nCmdShow, 1024, 768 );
#else if defined(OSX)
CreateGameEngineOSX();
#endif
// This call will block and run until the game exits
RunGameLoop( pGameEngine, pchServerAddress, pchLobbyID );
@@ -248,13 +253,13 @@ int APIENTRY WinMain(HINSTANCE hInstance,
// We don't want to mask exceptions (or report them to Steam!) when debugging.
// If you would like to step through the exception handler, attach a debugger
// after running the game outside of the debugger.
return RealMain( hInstance, hPrevInstance, lpCmdLine, nCmdShow );
return RealMain( lpCmdLine, hInstance, nCmdShow );
}
_set_se_translator( MiniDumpFunction );
try // this try block allows the SE translator to work
{
return RealMain( hInstance, hPrevInstance, lpCmdLine, nCmdShow );
return RealMain( lpCmdLine, hInstance, nCmdShow );
}
catch( ... )
{
@@ -263,143 +268,32 @@ int APIENTRY WinMain(HINSTANCE hInstance,
}
#endif
//-----------------------------------------------------------------------------
// Purpose: Main entry point for the program -- ps3
//-----------------------------------------------------------------------------
#ifdef _PS3
//-----------------------------------------------------------------------------
// Purpose: Loads the Steam PS3 module
//-----------------------------------------------------------------------------
sys_prx_id_t g_sys_prx_id_steam = -1;
static bool LoadSteamPS3Module()
#ifdef OSX
int main(int argc, const char **argv)
{
g_sys_prx_id_steam = sys_prx_load_module( SYS_APP_HOME "/steam_api_ps3.sprx", 0, NULL );
if ( g_sys_prx_id_steam < CELL_OK )
{
OutputDebugString( "LoadSteamModule() - failed to load steam_api_ps3\n" );
return false;
}
char szCmdLine[1024];
char *pszStart = szCmdLine;
char * const pszEnd = szCmdLine + ARRAYSIZE(szCmdLine);
int modres;
int res = sys_prx_start_module( g_sys_prx_id_steam, 0, NULL, &modres, 0, NULL);
if ( res < CELL_OK )
{
OutputDebugString( "LoadSteamModule() - failed to start steam_api_ps3\n" );
return false;
}
return true;
*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[ARRAYSIZE(szCmdLine) - 1] = '\0';
return RealMain( szCmdLine, 0, 0 );
}
//-----------------------------------------------------------------------------
// Purpose: Unloads the Steam PS3 module
//-----------------------------------------------------------------------------
static bool UnloadSteamPS3Module()
{
// check if loaded
if ( g_sys_prx_id_steam < CELL_OK )
return false;
int modres;
int res = sys_prx_stop_module( g_sys_prx_id_steam, 0, NULL, &modres, 0, NULL);
if ( res < CELL_OK )
{
OutputDebugString( "LoadSteamModule() - failed to stop steam_api_ps3\n" );
return false;
}
res = sys_prx_unload_module( g_sys_prx_id_steam, 0, NULL );
if ( res < CELL_OK )
{
OutputDebugString( "LoadSteamModule() - failed to unload steam_api_ps3\n" );
return false;
}
g_sys_prx_id_steam = -1;
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Initializes Steam PS3 params for our application
//-----------------------------------------------------------------------------
bool SetSteamPS3Params( SteamPS3Params_t *pParams )
{
// Steam needs the system cache path
CellSysCacheParam sysCacheParams;
memset( &sysCacheParams, 0, sizeof( CellSysCacheParam ) );
if ( cellSysCacheMount( &sysCacheParams ) < 0 )
return false;
// configure the Steamworks PS3 parameters. All params need to be set
strncpy( pParams->m_rgchInstallationPath, SYS_APP_HOME, STEAM_PS3_PATH_MAX );
strncpy( pParams->m_rgchSystemCache, sysCacheParams.getCachePath, STEAM_PS3_PATH_MAX );
return true;
}
// Global for PS3 params
SteamPS3Params_t g_SteamPS3Params;
//-----------------------------------------------------------------------------
// Purpose: Main entry point for the program -- ps3
//-----------------------------------------------------------------------------
int main( int argc, char *argv[] )
{
printf( "PS3 main\n" );
// Initialize 6 SPUs but reserve 1 SPU as a raw SPU for PSGL
sys_spu_initialize(6, 1);
// Load Steam
if ( !LoadSteamPS3Module() )
return EXIT_FAILURE;
// No restart app if necessary, or CEG initialization on PS3
// Initialize SteamAPI, if this fails we bail out since we depend on Steam for lots of stuff.
// You don't necessarily have to though if you write your code to check whether all the Steam
// interfaces are NULL before using them and provide alternate paths when they are unavailable.
if ( !SetSteamPS3Params( &g_SteamPS3Params ) )
{
OutputDebugString( "SetSteamPS3Params() failed\n" );
return EXIT_FAILURE;
}
if ( !SteamAPI_Init( &g_SteamPS3Params ) )
{
OutputDebugString( "SteamAPI_Init() failed\n" );
return EXIT_FAILURE;
}
// set our debug handler
SteamClient()->SetWarningMessageHook( &SteamAPIDebugTextHook );
// bugbug ps3
SteamUser()->LogOn( "jmccaskeybeta", "test123" );
// No overlay notification position setting on PS3
// No +connect support on PS3 since Steam isn't launching us
// Construct a new instance of the game engine
// bugbug jmccaskey - make screen resolution dynamic, maybe take it on command line?
CGameEnginePS3 *pGameEngine = new CGameEnginePS3();
// This call will block and run until the game exits
RunGameLoop( pGameEngine, NULL, NULL );
// Shutdown the SteamAPI
SteamAPI_Shutdown();
// Unload Steam
UnloadSteamPS3Module();
// exit
return 0;
}
#endif
#endif
+32 -2
View File
@@ -32,10 +32,16 @@ enum EMessage
k_EMsgClientLeavingServer = k_EMsgClientBegin+4,
k_EMsgClientPing = k_EMsgClientBegin+5,
// P2P messages
k_EMsgP2PBegin = 500,
// P2P authentication messages
k_EMsgP2PBegin = 600,
k_EMsgP2PSendingTicket = k_EMsgP2PBegin+1,
// voice chat messages
k_EMsgVoiceChatBegin = 700,
k_EMsgVoiceChatPing = k_EMsgVoiceChatBegin+1, // just a keep alive message
k_EMsgVoiceChatData = k_EMsgVoiceChatBegin+2, // voice data from another player
// force 32-bit size enum so the wire protocol doesn't get outgrown later
k_EForceDWORD = 0x7fffffff,
@@ -211,6 +217,30 @@ private:
uint64 m_ulSteamID;
};
// voice chat ping
struct MsgVoiceChatPing_t
{
MsgVoiceChatPing_t() : m_dwMessageType( LittleDWord( k_EMsgVoiceChatPing ) ) {}
DWORD GetMessageType() const { return LittleDWord( m_dwMessageType ); }
private:
const DWORD m_dwMessageType;
};
// voice chat data
struct MsgVoiceChatData_t
{
MsgVoiceChatData_t() : m_dwMessageType( LittleDWord( k_EMsgVoiceChatData ) ) {}
DWORD GetMessageType() const { return LittleDWord( m_dwMessageType ); }
void SetDataLength( uint32 unLength ) { m_uDataLength = LittleDWord( unLength ); }
uint32 GetDataLength() const { return LittleDWord( m_uDataLength ); }
private:
const DWORD m_dwMessageType;
uint32 m_uDataLength;
};
#pragma pack( pop )
#endif // MESSAGES_H
+162 -24
View File
@@ -7,7 +7,8 @@
#include "stdafx.h"
#include "RemoteStorage.h"
#include "BaseMenu.h"
#include "RemoteStorageSync.h"
#include <assert.h>
#define CLOUDDISP_FONT_HEIGHT 20
#define CLOUDDISP_COLUMN_WIDTH 600
@@ -30,11 +31,135 @@
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Purpose: CRemoteStorage implementation
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CRemoteStorage::CRemoteStorage( IGameEngine *pGameEngine )
: m_pGameEngine( pGameEngine )
CRemoteStorage::CRemoteStorage( IGameEngine *pGameEngine ) : m_pGameEngine( pGameEngine ), m_pRemoteStorageSync(NULL)
{
m_pRemoteStorageScreen = new CRemoteStorageScreen( pGameEngine );
#ifdef _PS3
m_pRemoteStorageSync = new CRemoteStorageSync( pGameEngine );
#endif
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CRemoteStorage::~CRemoteStorage()
{
if ( m_pRemoteStorageSync )
{
assert( m_pRemoteStorageSync->BFinished() );
delete m_pRemoteStorageSync;
}
delete m_pRemoteStorageScreen;
}
//-----------------------------------------------------------------------------
// Purpose: Called when the user selects view remote storage files
//-----------------------------------------------------------------------------
void CRemoteStorage::Show()
{
m_eState = k_ERemoteStorageStateIdle;
CheckState();
}
//-----------------------------------------------------------------------------
// Purpose: Check's if we have finished our current step and should advance to the next
//
// NOTE: These steps are not necessary for platforms where the Steam client is running. On those platforms,
// the Steam client will take care of synchronization and m_pRemoteStorageSync will be NULL
//-----------------------------------------------------------------------------
void CRemoteStorage::CheckState()
{
switch( m_eState )
{
default:
case k_ERemoteStorageStateIdle:
if ( m_pRemoteStorageSync )
m_pRemoteStorageSync->SynchronizeToClient();
// advance to next state
m_eState = k_ERemoteStorageStateSyncToClient;
// fall through
case k_ERemoteStorageStateSyncToClient:
if ( m_pRemoteStorageSync && !m_pRemoteStorageSync->BFinished() )
break;
// advance to next state
m_eState = k_ERemoteStorageStateDisplayMessage;
m_pRemoteStorageScreen->Show();
break;
case k_ERemoteStorageStateDisplayMessage:
if ( !m_pRemoteStorageScreen->BFinished() )
break;
// advance to next state
m_eState = k_ERemoteStorageStateSyncToServer;
if ( m_pRemoteStorageSync )
m_pRemoteStorageSync->SynchronizeToServer();
// fall through
case k_ERemoteStorageStateSyncToServer:
if ( m_pRemoteStorageSync && !m_pRemoteStorageSync->BFinished() )
break;
// complete. Return to the main menu
m_eState = k_ERemoteStorageStateIdle;
SpaceWarClient()->SetGameState( k_EClientGameMenu );
break;
}
}
//-----------------------------------------------------------------------------
// Purpose: Called once per frame
//-----------------------------------------------------------------------------
void CRemoteStorage::Render()
{
if ( m_pRemoteStorageSync && (m_eState == k_ERemoteStorageStateSyncToClient || m_eState == k_ERemoteStorageStateSyncToServer) )
m_pRemoteStorageSync->Render();
if ( m_eState == k_ERemoteStorageStateDisplayMessage )
m_pRemoteStorageScreen->Render();
CheckState();
}
//-----------------------------------------------------------------------------
// Purpose: A sync menu item has been selected
//-----------------------------------------------------------------------------
void CRemoteStorage::OnMenuSelection( ERemoteStorageSyncMenuCommand selection )
{
if ( m_pRemoteStorageSync )
m_pRemoteStorageSync->OnMenuSelection( selection );
}
//-----------------------------------------------------------------------------
// Purpose: CRemoteStorageScreen implementation
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CRemoteStorageScreen::CRemoteStorageScreen( IGameEngine *pGameEngine ) : m_pGameEngine( pGameEngine )
{
m_rgchGreeting[0] = 0;
strncpy( m_rgchGreeting, "<none>", sizeof( m_rgchGreeting ) );
@@ -46,24 +171,30 @@ CRemoteStorage::CRemoteStorage( IGameEngine *pGameEngine )
if ( !m_hDisplayFont )
OutputDebugString( "RemoteStorage font was not created properly, text won't draw\n" );
GetFileStats();
GetFileStats();
}
if ( m_pSteamRemoteStorage->FileExists( MESSAGE_FILE_NAME ) )
//-----------------------------------------------------------------------------
// Purpose: Load the user's saved message
//-----------------------------------------------------------------------------
void CRemoteStorageScreen::LoadMessage()
{
if ( !m_pSteamRemoteStorage->FileExists( MESSAGE_FILE_NAME ) )
return;
int32 cubFile = m_pSteamRemoteStorage->GetFileSize( MESSAGE_FILE_NAME );
if ( cubFile >= sizeof( m_rgchGreeting ) )
{
int32 cubFile = m_pSteamRemoteStorage->GetFileSize( MESSAGE_FILE_NAME );
if ( cubFile >= sizeof( m_rgchGreeting ) )
{
// ?? too big, nuke it
char c = 0;
OutputDebugString( "RemoteStorage: File was larger than expected. . .\n" );
m_pSteamRemoteStorage->FileWrite( MESSAGE_FILE_NAME, &c, 1 );
}
else
{
int32 cubRead = m_pSteamRemoteStorage->FileRead( MESSAGE_FILE_NAME, m_rgchGreeting, sizeof( m_rgchGreeting ) - 1 );
m_rgchGreeting[cubRead] = 0; // null-terminate
}
// ?? too big, nuke it
char c = 0;
OutputDebugString( "RemoteStorage: File was larger than expected. . .\n" );
m_pSteamRemoteStorage->FileWrite( MESSAGE_FILE_NAME, &c, 1 );
}
else
{
int32 cubRead = m_pSteamRemoteStorage->FileRead( MESSAGE_FILE_NAME, m_rgchGreeting, sizeof( m_rgchGreeting ) - 1 );
m_rgchGreeting[cubRead] = 0; // null-terminate
}
}
@@ -71,7 +202,7 @@ CRemoteStorage::CRemoteStorage( IGameEngine *pGameEngine )
//-----------------------------------------------------------------------------
// Purpose: Update stats on our files in the Cloud
//-----------------------------------------------------------------------------
void CRemoteStorage::GetFileStats()
void CRemoteStorageScreen::GetFileStats()
{
m_nBytesQuota = 0;
m_nAvailableBytes = 0;
@@ -80,10 +211,20 @@ void CRemoteStorage::GetFileStats()
}
//-----------------------------------------------------------------------------
// Purpose: Called when the user selects view remote storage files
//-----------------------------------------------------------------------------
void CRemoteStorageScreen::Show()
{
GetFileStats();
LoadMessage();
}
//-----------------------------------------------------------------------------
// Purpose: Render the Remote Storage page
//-----------------------------------------------------------------------------
void CRemoteStorage::Render()
void CRemoteStorageScreen::Render()
{
uint64 ulCurrentTickCount = m_pGameEngine->GetGameTickCount();
@@ -241,8 +382,5 @@ void CRemoteStorage::Render()
_snprintf( rgchBuffer, sizeof( rgchBuffer), "!! QUOTA EXCEEDED !!" );
m_pGameEngine->BDrawString( m_hDisplayFont, rect, D3DCOLOR_ARGB( 255, 25, 200, 25 ), TEXTPOS_CENTER|TEXTPOS_VCENTER, rgchBuffer );
}
}
}
+57 -3
View File
@@ -13,26 +13,78 @@
class ISteamUser;
class CSpaceWarClient;
class IRemoteStorageSync;
class CRemoteStorageScreen;
enum ERemoteStorageSyncMenuCommand
{
k_EMenuCommandNone = 0,
k_EMenuCommandProgress = 1,
k_EMenuCommandSyncComplete = 2,
k_EMenuCommandKeepClient = 3,
k_EMenuCommandKeepServer = 4
};
//-----------------------------------------------------------------------------
// Purpose: Example of Steam Cloud
//-----------------------------------------------------------------------------
class CRemoteStorage
{
public:
// Constructor
CRemoteStorage( IGameEngine *pGameEngine );
~CRemoteStorage();
// call when user changes to this menu
void Show();
// Display the remote storage screen
void Render();
// A sync menu item has been selected
void OnMenuSelection( ERemoteStorageSyncMenuCommand selection );
private:
void CheckState();
enum ERemoteStorageState
{
k_ERemoteStorageStateIdle,
k_ERemoteStorageStateSyncToClient,
k_ERemoteStorageStateDisplayMessage,
k_ERemoteStorageStateSyncToServer,
};
IGameEngine *m_pGameEngine;
ERemoteStorageState m_eState;
IRemoteStorageSync *m_pRemoteStorageSync;
CRemoteStorageScreen *m_pRemoteStorageScreen;
};
//-----------------------------------------------------------------------------
// Purpose: Screen where user can enter their custom messasge
//-----------------------------------------------------------------------------
class CRemoteStorageScreen
{
public:
CRemoteStorageScreen( IGameEngine *pGameEngine );
// call when user changes to this menu
void Show();
// Display the remote storage screen
void Render();
// Done showing this page?
bool BFinished() { return m_bFinished; }
private:
void GetFileStats();
void LoadMessage();
// Engine
// Game engine
IGameEngine *m_pGameEngine;
// Display font
@@ -55,4 +107,6 @@ private:
int32 m_nAvailableBytes;
};
#endif
-2
View File
@@ -89,9 +89,7 @@ void CServerBrowser::RefreshInternetServers()
m_pMenu->Rebuild( m_ListGameServers, m_bRequestingServers );
#ifndef _PS3
Steamworks_TestSecret();
#endif
// Allocate some filters, there are some common pre-defined values that can be used:
//
-2
View File
@@ -502,9 +502,7 @@ void CShip::SetExploding( bool bExploding )
if ( m_bExploding == bExploding )
return;
#ifndef _PS3
Steamworks_TestSecret();
#endif
// Track that we are exploding, and disable collision detection
m_bExploding = bExploding;
+8 -4
View File
@@ -120,18 +120,18 @@ inline T QWordSwap( T dw )
#ifndef _PS3
#define LittleShort( val ) ( val )
#define LittleInt16( val ) ( val )
#define LittleWord( val ) ( val )
#define LittleLong( val ) ( val )
#define LittleInt32( val ) ( val )
#define LittleDWord( val ) ( val )
#define LittleQWord( val ) ( val )
#define LittleFloat( val ) ( val )
#else
#define LittleShort( val ) WordSwap( val )
#define LittleInt16( val ) WordSwap( val )
#define LittleWord( val ) WordSwap( val )
#define LittleLong( val ) DWordSwap( val )
#define LittleInt32( val ) DWordSwap( val )
#define LittleDWord( val ) DWordSwap( val )
#define LittleQWord( val ) QWordSwap( val )
#define LittleFloat( val ) DWordSwap( val )
@@ -178,6 +178,10 @@ enum EClientGameState
k_EClientRemoteStorage,
k_EClientLeaderboards,
k_EClientMinidump,
k_EClientConnectingToSteam,
k_EClientLinkSteamAccount,
k_EClientAutoCreateAccount,
k_EClientRetrySteamConnection,
};
+161 -21
View File
@@ -1,4 +1,4 @@
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
//========= Copyright � 1996-2008, Valve LLC, All rights reserved. ============
//
// Purpose: Main class for the space war game client
//
@@ -8,6 +8,7 @@
#include "stdafx.h"
#include "SpaceWarClient.h"
#include "SpaceWarServer.h"
#include "connectingmenu.h"
#include "MainMenu.h"
#include "QuitMenu.h"
#include "stdlib.h"
@@ -16,6 +17,7 @@
#include "Leaderboards.h"
#include "Lobby.h"
#include "p2pauth.h"
#include "voicechat.h"
#include "steam/steamencryptedappticket.h"
CSpaceWarClient *g_pSpaceWarClient = NULL;
@@ -24,14 +26,15 @@ CSpaceWarClient* SpaceWarClient() { return g_pSpaceWarClient; }
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CSpaceWarClient::CSpaceWarClient( IGameEngine *pGameEngine, CSteamID steamIDUser ) :
CSpaceWarClient::CSpaceWarClient( IGameEngine *pGameEngine ) :
m_CallbackP2PSessionConnectFail( this, &CSpaceWarClient::OnP2PSessionConnectFail ),
m_LobbyGameCreated( this, &CSpaceWarClient::OnLobbyGameCreated ),
m_AvatarImageLoadedCreated( this, &CSpaceWarClient::OnAvatarImageLoaded ),
m_IPCFailureCallback( this, &CSpaceWarClient::OnIPCFailure ),
m_SteamShutdownCallback( this, &CSpaceWarClient::OnSteamShutdown )
m_SteamShutdownCallback( this, &CSpaceWarClient::OnSteamShutdown ),
m_SteamServersConnected( this, &CSpaceWarClient::OnSteamServersConnected ),
m_SteamServerConnectFailure( this, &CSpaceWarClient::OnSteamServerConnectFailure )
{
m_SteamIDLocalUser = steamIDUser;
Init( pGameEngine );
}
@@ -42,9 +45,25 @@ CSpaceWarClient::CSpaceWarClient( IGameEngine *pGameEngine, CSteamID steamIDUser
//-----------------------------------------------------------------------------
void CSpaceWarClient::Init( IGameEngine *pGameEngine )
{
// On PC/OSX we always know the user has a SteamID and is logged in already,
// as Steam enforces this before game launch. On PS3 however the game must
// initiate the logon and we need to check the state here and block the user
// while Steam connects.
if ( SteamUser()->BLoggedOn() )
{
m_SteamIDLocalUser = SteamUser()->GetSteamID();
m_eGameState = k_EClientGameMenu;
}
#ifdef _PS3
else
{
m_eGameState = k_EClientConnectingToSteam;
SteamUser()->LogOn( true );
}
#endif
g_pSpaceWarClient = this;
m_pGameEngine = pGameEngine;
m_eGameState = k_EClientGameMenu;
m_uPlayerWhoWonGame = 0;
m_ulStateTransitionTime = m_pGameEngine->GetGameTickCount();
m_ulLastNetworkDataReceivedTime = 0;
@@ -80,6 +99,9 @@ void CSpaceWarClient::Init( IGameEngine *pGameEngine )
// Initialize main menu
m_pMainMenu = new CMainMenu( pGameEngine );
// Initialize connecting menu
m_pConnectingMenu = new CConnectingMenu( pGameEngine );
// Initialize pause menu
m_pQuitMenu = new CQuitMenu( pGameEngine );
@@ -101,6 +123,9 @@ void CSpaceWarClient::Init( IGameEngine *pGameEngine )
// Remote Storage page
m_pRemoteStorage = new CRemoteStorage( pGameEngine );
// P2P voice chat
m_pVoiceChat = new CVoiceChat( pGameEngine );
}
@@ -130,6 +155,9 @@ CSpaceWarClient::~CSpaceWarClient()
if ( m_pMainMenu )
delete m_pMainMenu;
if ( m_pConnectingMenu )
delete m_pConnectingMenu;
if ( m_pQuitMenu )
delete m_pQuitMenu;
@@ -142,6 +170,9 @@ CSpaceWarClient::~CSpaceWarClient()
if ( m_pServerBrowser )
delete m_pServerBrowser;
if ( m_pVoiceChat )
delete m_pVoiceChat;
for( uint32 i = 0; i < MAX_PLAYERS_PER_SERVER; ++i )
{
if ( m_rgpShips[i] )
@@ -171,6 +202,11 @@ void CSpaceWarClient::DisconnectFromServer()
m_pP2PAuthedGame->EndGame();
}
if ( m_pVoiceChat )
{
m_pVoiceChat->StopVoiceChat();
}
// forget the game server ID
if ( m_steamIDGameServer.IsValid() )
{
@@ -207,9 +243,7 @@ void CSpaceWarClient::OnReceiveServerInfo( CSteamID steamIDGameServer, bool bVAC
msg.SetSteamID( SteamUser()->GetSteamID().ConvertToUint64() );
#endif
#ifndef _PS3
Steamworks_TestSecret();
#endif
if ( msg.GetTokenLen() < 1 )
OutputDebugString( "Warning: Looks like InitiateGameConnection didn't give us a good token\n" );
@@ -362,7 +396,11 @@ void CSpaceWarClient::OnReceiveServerUpdate( ServerSpaceWarUpdateData_t *pUpdate
}
}
// Update the ships
// update all players that are active
if ( m_pVoiceChat )
m_pVoiceChat->MarkAllPlayersInactive();
// Update the players
for( uint32 i=0; i < MAX_PLAYERS_PER_SERVER; ++i )
{
// Update steamid array with data from server
@@ -392,6 +430,9 @@ void CSpaceWarClient::OnReceiveServerUpdate( ServerSpaceWarUpdateData_t *pUpdate
m_rgpShips[i]->SetIsLocalPlayer( false );
m_rgpShips[i]->OnReceiveServerUpdate( pUpdateData->AccessShipUpdateData( i ) );
if ( m_pVoiceChat )
m_pVoiceChat->MarkPlayerAsActive( m_rgSteamIDPlayers[i] );
}
else
{
@@ -622,10 +663,19 @@ void CSpaceWarClient::ReceiveNetworkData()
break;
}
}
else
else
{
// the message is from another player
EMessage eMsg = (EMessage)LittleDWord( *(DWORD*)pchRecvBuf );
m_pP2PAuthedGame->HandleMessage( eMsg, pchRecvBuf );
if ( m_pP2PAuthedGame->HandleMessage( eMsg, pchRecvBuf ) )
continue; // this was a P2P auth message
if ( m_pVoiceChat->HandleMessage( steamIDRemote, eMsg, pchRecvBuf ) )
continue;
// Unhandled message
OutputDebugString( "Received unknown message on our listen socket\n" );
}
}
@@ -791,6 +841,15 @@ void CSpaceWarClient::OnMenuSelection( LeaderboardMenuItem_t selection )
}
//-----------------------------------------------------------------------------
// Purpose: Handles menu actions when viewing the remote storage sync screen
//-----------------------------------------------------------------------------
void CSpaceWarClient::OnMenuSelection( ERemoteStorageSyncMenuCommand selection )
{
m_pRemoteStorage->OnMenuSelection( selection );
}
//-----------------------------------------------------------------------------
// Purpose: does work on transitioning from one game state to another
//-----------------------------------------------------------------------------
@@ -844,6 +903,16 @@ void CSpaceWarClient::OnGameStateChanged( EClientGameState eGameStateNew )
// we've switched to the leaderboard menu
m_pLeaderboards->Show();
}
else if ( m_eGameState == k_EClientGameActive )
{
// start voice chat
m_pVoiceChat->StartVoiceChat();
}
else if ( m_eGameState == k_EClientRemoteStorage )
{
// we've switched to the remote storage menu
m_pRemoteStorage->Show();
}
}
//-----------------------------------------------------------------------------
@@ -857,7 +926,7 @@ void CSpaceWarClient::OnIPCFailure( IPCFailure_t *failure )
if ( !bExiting )
{
OutputDebugString( "Steam IPC Failure, shutting down\n" );
#if defined( WIN32 )
#if defined( _WIN32 )
::MessageBoxA( NULL, "Connection to Steam Lost, Exiting", "Steam Connection Error", MB_OK );
#endif
m_pGameEngine->Shutdown();
@@ -882,6 +951,32 @@ void CSpaceWarClient::OnSteamShutdown( SteamShutdown_t *callback )
}
//-----------------------------------------------------------------------------
// Purpose: Handles notification that we are now connected to Steam
//-----------------------------------------------------------------------------
void CSpaceWarClient::OnSteamServersConnected( SteamServersConnected_t *callback )
{
if ( SteamUser()->BLoggedOn() )
m_eGameState = k_EClientGameMenu;
else
{
OutputDebugString( "Got SteamServersConnected_t, but not logged on?\n" );
}
}
//-----------------------------------------------------------------------------
// Purpose: Handles notification that we are now connected to Steam
//-----------------------------------------------------------------------------
void CSpaceWarClient::OnSteamServerConnectFailure( SteamServerConnectFailure_t *callback )
{
char rgchString[256];
_snprintf( rgchString, 256, "SteamServerConnectFailure_t: %d\n", callback->m_eResult );
m_pConnectingMenu->OnConnectFailure();
}
//-----------------------------------------------------------------------------
// Purpose: Main frame function, updates the state of the world and performs rendering
//-----------------------------------------------------------------------------
@@ -926,6 +1021,40 @@ void CSpaceWarClient::RunFrame()
// Update state for everything
switch ( m_eGameState )
{
case k_EClientConnectingToSteam:
m_pStarField->Render();
m_pConnectingMenu->RunFrame();
break;
case k_EClientRetrySteamConnection:
#ifdef _PS3
m_pStarField->Render();
SteamUser()->LogOn( true );
m_pConnectingMenu->Reset();
SetGameState( k_EClientConnectingToSteam );
#else
OutputDebugString( "Invalidate state k_EClientRetrySteamConnection hit on non-PS3 platform" );
#endif
break;
case k_EClientLinkSteamAccount:
#ifdef _PS3
m_pStarField->Render();
SteamUser()->LogOnAndLinkSteamAccountToPSN( true, "jmccaskeybeta", "test123" );
m_pConnectingMenu->Reset();
SetGameState( k_EClientConnectingToSteam );
#else
OutputDebugString( "Invalidate state k_EClientLinkSteamAccount hit on non-PS3 platform" );
#endif
break;
case k_EClientAutoCreateAccount:
#ifdef _PS3
m_pStarField->Render();
m_pConnectingMenu->Reset();
SteamUser()->LogOnAndCreateNewSteamAccountIfNeeded( true );
SetGameState( k_EClientConnectingToSteam );
#else
OutputDebugString( "Invalidate state k_EClientAutoCreateAccount hit on non-PS3 platform" );
#endif
break;
case k_EClientGameMenu:
m_pStarField->Render();
m_pMainMenu->RunFrame();
@@ -1045,13 +1174,10 @@ void CSpaceWarClient::RunFrame()
case k_EClientRemoteStorage:
m_pStarField->Render();
m_pRemoteStorage->Render();
if ( m_pRemoteStorage->BFinished() )
SetGameState( k_EClientGameMenu );
break;
case k_EClientMinidump:
#ifndef _PS3
#ifdef _WIN32
RaiseException( EXCEPTION_NONCONTINUABLE_EXCEPTION,
EXCEPTION_NONCONTINUABLE,
0, NULL );
@@ -1088,12 +1214,17 @@ void CSpaceWarClient::RunFrame()
DrawHUDText();
DrawWinnerDrawOrWaitingText();
m_pVoiceChat->RunFrame();
if ( bEscapePressed )
SetGameState( k_EClientGameQuitMenu );
break;
case k_EClientGameActive:
m_pStarField->Render();
// Update all the entities...
m_pSun->RunFrame();
@@ -1105,9 +1236,12 @@ void CSpaceWarClient::RunFrame()
DrawHUDText();
m_pStatsAndAchievements->RunFrame();
m_pVoiceChat->RunFrame();
if ( bEscapePressed )
SetGameState( k_EClientGameQuitMenu );
break;
case k_EClientGameExiting:
DisconnectFromServer();
@@ -1233,9 +1367,13 @@ void CSpaceWarClient::DrawHUDText()
// players on the same game server as us (if using the Steam game server auth API)
// and on ourself.
char rgchPlayerName[128];
CSteamID playerSteamID( m_rgSteamIDPlayers[i] );
const char *pszVoiceState = m_pVoiceChat->IsPlayerTalking( playerSteamID ) ? "(VoiceChat)" : "";
if ( m_rgSteamIDPlayers[i].IsValid() )
{
_snprintf( rgchPlayerName, ARRAYSIZE( rgchPlayerName ), "%s", SteamFriends()->GetFriendPersonaName( m_rgSteamIDPlayers[i] ) );
_snprintf( rgchPlayerName, ARRAYSIZE( rgchPlayerName ), "%s", SteamFriends()->GetFriendPersonaName( playerSteamID ) );
}
else
{
@@ -1245,7 +1383,7 @@ void CSpaceWarClient::DrawHUDText()
// 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( m_rgSteamIDPlayers[i] );
int iImage = SteamFriends()->GetMediumFriendAvatar( playerSteamID );
HGAMETEXTURE hTexture = NULL;
if ( iImage != -1 )
hTexture = GetSteamImageAsTexture( iImage );
@@ -1267,7 +1405,7 @@ void CSpaceWarClient::DrawHUDText()
rect.right += nAvatarWidth + nSpaceBetweenAvatarAndScore;
}
_snprintf( rgchBuffer, sizeof( rgchBuffer), "%s\nScore: %2u", rgchPlayerName, m_rguPlayerScores[i] );
_snprintf( rgchBuffer, sizeof( 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:
@@ -1285,7 +1423,7 @@ void CSpaceWarClient::DrawHUDText()
rect.left -= nAvatarWidth + nSpaceBetweenAvatarAndScore;
}
_snprintf( rgchBuffer, sizeof( rgchBuffer), "%s\nScore: %2u", rgchPlayerName, m_rguPlayerScores[i] );
_snprintf( rgchBuffer, sizeof( rgchBuffer), "%s\nScore: %2u ", rgchPlayerName, m_rguPlayerScores[i], pszVoiceState );
m_pGameEngine->BDrawString( m_hHUDFont, rect, g_rgPlayerColors[i], TEXTPOS_RIGHT|TEXTPOS_VCENTER, rgchBuffer );
break;
case 2:
@@ -1302,7 +1440,7 @@ void CSpaceWarClient::DrawHUDText()
rect.left += nAvatarWidth + nSpaceBetweenAvatarAndScore;
}
_snprintf( rgchBuffer, sizeof( rgchBuffer), "%s\nScore: %2u", rgchPlayerName, m_rguPlayerScores[i] );
_snprintf( rgchBuffer, sizeof( 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:
@@ -1319,7 +1457,7 @@ void CSpaceWarClient::DrawHUDText()
rect.left -= nAvatarWidth + nSpaceBetweenAvatarAndScore;
}
_snprintf( rgchBuffer, sizeof( rgchBuffer), "%s\nScore: %2u", rgchPlayerName, m_rguPlayerScores[i] );
_snprintf( rgchBuffer, sizeof( 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:
@@ -1582,6 +1720,7 @@ void CSpaceWarClient::OnRequestEncryptedAppTicket( EncryptedAppTicketResponse_t
SteamUser()->GetEncryptedAppTicket( rgubTicket, sizeof( rgubTicket), &cubTicket );
#ifdef _WIN32
// normally at this point you transmit the encrypted ticket to the service that knows the decryption key
// this code is just to demonstrate the ticket cracking library
@@ -1608,6 +1747,7 @@ void CSpaceWarClient::OnRequestEncryptedAppTicket( EncryptedAppTicketResponse_t
uint32 *punSecretData = (uint32 *)SteamEncryptedAppTicket_GetUserVariableData( rgubDecrypted, cubDecrypted, &cubData );
if ( cubData != sizeof( uint32 ) || *punSecretData != k_unSecretData )
OutputDebugString( "Failed to retrieve secret data\n" );
#endif
}
else if ( pEncryptedAppTicketResponse->m_eResult == k_EResultLimitExceeded )
{
+20 -10
View File
@@ -1,4 +1,4 @@
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
//========= Copyright � 1996-2008, Valve LLC, All rights reserved. ============
//
// Purpose: Main class for the space war game client
//
@@ -18,14 +18,8 @@
#include "StatsAndAchievements.h"
#include "RemoteStorage.h"
// Must define this stuff before BaseMenu.h as it depends on calling back into us through these accessors
class CSpaceWarClient;
extern CSpaceWarClient *g_pSpaceWarClient;
CSpaceWarClient *SpaceWarClient();
#include "BaseMenu.h"
// Forward class declaration
class CConnectingMenu;
class CMainMenu;
class CQuitMenu;
class CSpaceWarServer;
@@ -35,6 +29,7 @@ class CLobby;
class CLeaderboards;
class CP2PAuthPlayer;
class CP2PAuthedGame;
class CVoiceChat;
// Height of the HUD font
#define HUD_FONT_HEIGHT 18
@@ -89,12 +84,11 @@ struct LeaderboardMenuItem_t
};
class CSpaceWarClient
{
public:
//Constructor
CSpaceWarClient( IGameEngine *pEngine, CSteamID steamIDUser );
CSpaceWarClient( IGameEngine *pEngine );
// Shared init for all constructors
void Init( IGameEngine *pGameEngine );
@@ -146,6 +140,7 @@ public:
void OnMenuSelection( LobbyMenuItem_t selection );
void OnMenuSelection( LeaderboardMenuItem_t selection );
void OnMenuSelection( ERemoteStorageSyncMenuCommand selection );
// Set game state
void SetGameState( EClientGameState eState );
@@ -322,6 +317,9 @@ private:
// Main menu instance
CMainMenu *m_pMainMenu;
// Connecting menu instance
CConnectingMenu *m_pConnectingMenu;
// Pause menu instance
CQuitMenu *m_pQuitMenu;
@@ -352,14 +350,22 @@ private:
// callback for when the lobby game server has started
STEAM_CALLBACK( CSpaceWarClient, OnLobbyGameCreated, LobbyGameCreated_t, m_LobbyGameCreated );
STEAM_CALLBACK( CSpaceWarClient, OnAvatarImageLoaded, AvatarImageLoaded_t, m_AvatarImageLoadedCreated );
// callbacks for Steam connection state
STEAM_CALLBACK( CSpaceWarClient, OnSteamServersConnected, SteamServersConnected_t, m_SteamServersConnected );
STEAM_CALLBACK( CSpaceWarClient, OnSteamServerConnectFailure, SteamServerConnectFailure_t, m_SteamServerConnectFailure );
// lobby browser menu
CLobbyBrowser *m_pLobbyBrowser;
// local lobby display
CLobby *m_pLobby;
// p2p game auth manager
CP2PAuthedGame *m_pP2PAuthedGame;
// p2p voice chat
CVoiceChat *m_pVoiceChat;
// connection handler
STEAM_CALLBACK( CSpaceWarClient, OnP2PSessionConnectFail, P2PSessionConnectFail_t, m_CallbackP2PSessionConnectFail );
@@ -375,4 +381,8 @@ private:
CCallResult< CSpaceWarClient, EncryptedAppTicketResponse_t > m_SteamCallResultEncryptedAppTicket;
};
// Must define this stuff before BaseMenu.h as it depends on calling back into us through these accessors
extern CSpaceWarClient *g_pSpaceWarClient;
CSpaceWarClient *SpaceWarClient();
#endif // SPACEWARCLIENT_H
+21 -10
View File
@@ -1,4 +1,4 @@
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
//========= Copyright � 1996-2008, Valve LLC, All rights reserved. ============
//
// Purpose: Class for rendering the starfield
//
@@ -16,31 +16,42 @@ CStarField::CStarField( IGameEngine *pGameEngine )
{
m_pGameEngine = pGameEngine;
StarVertex_t StarVertex;
int32 width = pGameEngine->GetViewportWidth();
int32 height = pGameEngine->GetViewportHeight();
Init();
}
void CStarField::Init()
{
StarVertex_t StarVertex;
m_nWidth = m_pGameEngine->GetViewportWidth();
m_nHeight = m_pGameEngine->GetViewportHeight();
m_VecStars.clear();
// Generate star field data
for( int i=0; i < STARFIELD_STAR_COUNT; ++i )
{
int32 nRand = (rand()%(255-50))+50; //value between 50 and 255 for shades of gray
StarVertex.color = D3DCOLOR_ARGB( 255, nRand, nRand, nRand );
StarVertex.x = (float)(rand()%width);
StarVertex.y = (float)(rand()%height);
StarVertex.x = (float)(rand()%m_nWidth);
StarVertex.y = (float)(rand()%m_nHeight);
m_VecStars.push_back( StarVertex );
// bugbug jmccaskey - sometimes make "big stars" which are 4 points right next to each other?
}
}
//-----------------------------------------------------------------------------
// Purpose: Render the star field
//-----------------------------------------------------------------------------
void CStarField::Render()
{
if ( ( m_pGameEngine->GetViewportWidth() != m_nWidth ) || ( m_pGameEngine->GetViewportHeight() != m_nHeight ) )
{
Init();
}
for( size_t i = 0; i < m_VecStars.size(); ++i )
{
m_pGameEngine->BDrawPoint( m_VecStars[i].x, m_VecStars[i].y, m_VecStars[i].color );
+7 -1
View File
@@ -1,4 +1,4 @@
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
//========= Copyright � 1996-2008, Valve LLC, All rights reserved. ============
//
// Purpose: Class for rendering the starfield
//
@@ -29,6 +29,12 @@ public:
void Render();
private:
void Init();
private:
int m_nWidth;
int m_nHeight;
// Game engine instance we are running under
IGameEngine *m_pGameEngine;
@@ -82,12 +82,6 @@ void CStatsAndAchievements::RunFrame()
return;
}
// If yes, are we connected to the back end? if no, wait
if ( !m_pSteamUser->BLoggedOn() )
{
return;
}
// If yes, request our stats
bool bSuccess = m_pSteamUserStats->RequestCurrentStats( );
+20 -4
View File
@@ -97,7 +97,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
CommandLine="copy ..\redistributable_bin\steam_api.dll $(OutDir)&#x0D;&#x0A;copy ..\public\steam\lib\win32\sdkencryptedappticket.dll $(OutDir)"
CommandLine="copy ..\redistributable_bin\steam_api.dll $(OutDir)&#x0D;&#x0A;copy ..\public\steam\lib\win32\sdkencryptedappticket.dll $(OutDir)&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
@@ -181,7 +181,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
CommandLine="copy ..\redistributable_bin\win64\steam_api64.dll $(OutDir)&#x0D;&#x0A;copy ..\public\steam\lib\win64\sdkencryptedappticket64.dll $(OutDir)"
CommandLine="copy ..\redistributable_bin\win64\steam_api64.dll $(OutDir)&#x0D;&#x0A;copy ..\public\steam\lib\win64\sdkencryptedappticket64.dll $(OutDir)&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
@@ -263,7 +263,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
CommandLine="copy ..\redistributable_bin\steam_api.dll $(OutDir)&#x0D;&#x0A;copy ..\public\steam\lib\win32\sdkencryptedappticket.dll $(OutDir)"
CommandLine="copy ..\redistributable_bin\steam_api.dll $(OutDir)&#x0D;&#x0A;copy ..\public\steam\lib\win32\sdkencryptedappticket.dll $(OutDir)&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
@@ -346,7 +346,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
CommandLine="copy ..\redistributable_bin\win64\steam_api64.dll $(OutDir)&#x0D;&#x0A;copy ..\public\steam\lib\win64\sdkencryptedappticket64.dll $(OutDir)"
CommandLine="copy ..\redistributable_bin\win64\steam_api64.dll $(OutDir)&#x0D;&#x0A;copy ..\public\steam\lib\win64\sdkencryptedappticket64.dll $(OutDir)&#x0D;&#x0A;"
/>
</Configuration>
</Configurations>
@@ -385,6 +385,10 @@
RelativePath=".\BaseMenu.cpp"
>
</File>
<File
RelativePath=".\connectingmenu.cpp"
>
</File>
<File
RelativePath=".\Leaderboards.cpp"
>
@@ -445,6 +449,10 @@
RelativePath=".\Sun.cpp"
>
</File>
<File
RelativePath=".\voicechat.cpp"
>
</File>
</Filter>
</Filter>
<Filter
@@ -479,6 +487,10 @@
RelativePath=".\BaseMenu.h"
>
</File>
<File
RelativePath=".\connectingmenu.h"
>
</File>
<File
RelativePath=".\Leaderboards.h"
>
@@ -551,6 +563,10 @@
RelativePath=".\Sun.h"
>
</File>
<File
RelativePath=".\voicechat.h"
>
</File>
</Filter>
</Filter>
</Files>
+8 -8
View File
@@ -63,7 +63,7 @@ void CNetworkTransport::OnP2PSessionRequest( P2PSessionRequest_t *pP2PSessionReq
//-----------------------------------------------------------------------------
// Purpose: another user has sent us a packet - do we accept?
// Purpose: we send a packet to another user but it failed
//-----------------------------------------------------------------------------
void CNetworkTransport::OnP2PSessionConnectFail( P2PSessionConnectFail_t *pP2PSessionConnectFail )
{
@@ -380,7 +380,7 @@ bool CP2PAuthedGame::HandleMessage( EMessage eMsg, void *pMessage )
{
if ( m_rgpP2PAuthPlayer[i]->HandleMessage( eMsg, pMessage ) )
{
return true;
return true; // message handled
}
}
}
@@ -391,18 +391,18 @@ bool CP2PAuthedGame::HandleMessage( EMessage eMsg, void *pMessage )
if ( m_rgpQueuedMessage[i] == NULL )
{
m_rgpQueuedMessage[i] = pMsg;
return false;
return true; // message handled
}
}
break;
}
default:
{
OutputDebugString( "Received unknown message on our listen socket\n" );
break;
}
// this is not a P2P auth message
break;
}
return true;
// message didn't got handled here
return false;
}
+37 -38
View File
@@ -1,4 +1,4 @@
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
//========= Copyright � 1996-2008, Valve LLC, All rights reserved. ============
//
// Purpose:
//
@@ -55,6 +55,9 @@
#include "d3d9.h"
#include "d3dx9.h"
// XAudio2 header files
#include <xaudio2.h>
typedef __int16 int16;
typedef unsigned __int16 uint16;
typedef __int32 int32;
@@ -68,39 +71,24 @@ typedef unsigned __int64 uint64;
#include "steam/isteammatchmaking.h"
#include "steam/steam_gameserver.h"
#ifdef STEAM_CEG
// Steam DRM header file
#include "cegclient.h"
#else
#define Steamworks_InitCEGLibrary() (true)
#define Steamworks_TermCEGLibrary() (true)
#define Steamworks_TestSecret() (true)
#define Steamworks_SelfCheck() (true)
#endif
#elif _PS3
#elif defined(POSIX)
#include <stdio.h>
#include <stddef.h>
#include <cell/error.h>
#include <sys/process.h>
#include <sys/paths.h>
#include <sys/prx.h>
#include <sys/spu_initialize.h>
#include <sys/memory.h>
#include <PSGL/psgl.h>
#include <PSGL/psglu.h>
#include <sys/types.h>
#include <string.h>
#include <string>
#include <sys/socket.h>
#include <netinet/in.h>
#include <cell/fios/fios_common.h>
#include <cell/fios/fios_memory.h>
#include <cell/fios/fios_configuration.h>
#include <cell/fios/fios_time.h>
#include <cell/dbgfont.h>
#include <cell/pad/libpad.h>
#include <sysutil/sysutil_syscache.h>
#include <string.h>
#if defined(_PS3)
#include "stdafx_ps3.h"
#elif defined(OSX)
#include <OpenGL/OpenGL.h>
#endif
// Need to define some types on POSIX
typedef short int16;
@@ -111,6 +99,7 @@ typedef long long int64;
typedef unsigned long long uint64;
typedef uint32 DWORD;
typedef DWORD HWND;
typedef DWORD HINSTANCE;
typedef short SHORT;
typedef long LONG;
typedef unsigned char byte;
@@ -128,7 +117,7 @@ typedef unsigned char uint8;
#define FW_EXTRABOLD 800
#define FW_HEAVY 900
/* Some VK_ defines from windows, we'll map these to PS3 controls */
/* Some VK_ defines from windows, we'll map these for posix */
#define VK_BACK 0x08
#define VK_TAB 0x09
#define VK_RETURN 0x0D
@@ -136,7 +125,9 @@ typedef unsigned char uint8;
#define VK_CONTROL 0x11
#define VK_ESCAPE 0x1B
#define VK_SPACE 0x20
#define VK_LEFT 0x25
#define VK_UP 0x26
#define VK_RIGHT 0x27
#define VK_DOWN 0x28
#define VK_SELECT 0x29
@@ -177,16 +168,24 @@ typedef struct tagRECT
#include "steam/isteammatchmaking.h"
#include "steam/steam_gameserver.h"
extern CellDbgFontConsoleId g_DbgFontConsoleID;
static void OutputDebugString( const char *pchMsg )
{
printf( "%s", pchMsg );
cellDbgFontConsolePrintf( g_DbgFontConsoleID, "%s", pchMsg );
}
extern void OutputDebugString( const char *pchMsg );
// No _snprintf on PS3, use sprintf
// No _snprintf on POSIX, use snprintf
#ifndef _snprintf
#define _snprintf snprintf
#endif
#define ARRAYSIZE(a) sizeof(a)/sizeof(a[0])
#endif // _PS3
#endif // POSIX
#ifdef STEAM_CEG
// Steam DRM header file
#include "cegclient.h"
#else
#define Steamworks_InitCEGLibrary() (true)
#define Steamworks_TermCEGLibrary() (true)
#define Steamworks_TestSecret() (true)
#define Steamworks_SelfCheck() (true)
#endif
BIN
View File
Binary file not shown.
+9 -1
View File
@@ -28,9 +28,17 @@ public:
// Takes AppID of DLC and checks if the user owns the DLC & if the DLC is installed
virtual bool BIsDlcInstalled( AppId_t appID ) = 0;
// returns the Unix time of the purchase of the app
virtual uint32 GetEarliestPurchaseUnixTime( AppId_t nAppID ) = 0;
// Checks if the user is subscribed to the current app through a free weekend
// This function will return false for users who have a retail or other type of license
// Before using, please ask your Valve technical contact how to package and secure your free weekened
virtual bool BIsSubscribedFromFreeWeekend() = 0;
};
#define STEAMAPPS_INTERFACE_VERSION "STEAMAPPS_INTERFACE_VERSION003"
#define STEAMAPPS_INTERFACE_VERSION "STEAMAPPS_INTERFACE_VERSION004"
// callbacks
#pragma pack( push, 8 )
+28
View File
@@ -0,0 +1,28 @@
//====== Copyright 1996-2008, Valve Corporation, All rights reserved. =======
//
// Purpose: a private, but well versioned, interface to get at critical bits
// of a steam3 appticket - consumed by the simple drm wrapper to let it
// ask about ownership with greater confidence.
//
//=============================================================================
#ifndef ISTEAMAPPTICKET_H
#define ISTEAMAPPTICKET_H
#pragma once
//-----------------------------------------------------------------------------
// Purpose: hand out a reasonable "future proof" view of an app ownership ticket
// the raw (signed) buffer, and indices into that buffer where the appid and
// steamid are located. the sizes of the appid and steamid are implicit in
// (each version of) the interface - currently uin32 appid and uint64 steamid
//-----------------------------------------------------------------------------
class ISteamAppTicket
{
public:
virtual uint32 GetAppOwnershipTicketData( uint32 nAppID, void *pvBuffer, uint32 cbBufferLength, uint32 *piAppId, uint32 *piSteamId, uint32 *piSignature, uint32 *pcbSignature ) = 0;
};
#define STEAMAPPTICKET_INTERFACE_VERSION "STEAMAPPTICKET_INTERFACE_VERSION001"
#endif // ISTEAMAPPTICKET_H
+4 -1
View File
@@ -130,9 +130,12 @@ public:
// callbacks will occur directly after the API function is called that generated the warning or message
virtual void SetWarningMessageHook( SteamAPIWarningMessageHook_t pFunction ) = 0;
// Trigger global shutdown for the DLL
virtual bool BShutdownIfAllPipesClosed() = 0;
};
#define STEAMCLIENT_INTERFACE_VERSION "SteamClient009"
#define STEAMCLIENT_INTERFACE_VERSION "SteamClient010"
//-----------------------------------------------------------------------------
// Purpose: Base values for callback identifiers, each callback must
+54 -1
View File
@@ -86,6 +86,18 @@ enum
k_cwchPersonaNameMax = 32,
};
//-----------------------------------------------------------------------------
// Purpose: user restriction flags
//-----------------------------------------------------------------------------
enum EUserRestriction
{
k_nUserRestrictionNone = 0, // no known chat/content restriction
k_nUserRestrictionUnknown = 1, // we don't know yet (user offline)
k_nUserRestrictionChat = 2, // user is not allowed to send/recv text/voice chat
};
// size limit on chat room or member metadata
const uint32 k_cubChatMetadataMax = 8192;
@@ -196,9 +208,37 @@ public:
// gets the large (184x184) avatar of the current user, which is a handle to be used in IClientUtils::GetImageRGBA(), or 0 if none set
// returns -1 if this image has yet to be loaded, in this case wait for a AvatarImageLoaded_t callback and then call this again
virtual int GetLargeFriendAvatar( CSteamID steamIDFriend ) = 0;
// requests information about a user - persona name & avatar
// if bRequireNameOnly is set, then the avatar of a user isn't downloaded
// - it's a lot slower to download avatars and churns the local cache, so if you don't need avatars, don't request them
// if returns true, it means that data is being requested, and a PersonaStateChanged_t callback will be posted when it's retrieved
// if returns false, it means that we already have all the details about that user, and functions can be called immediately
virtual bool RequestUserInformation( CSteamID steamIDUser, bool bRequireNameOnly ) = 0;
// requests information about a clan officer list
// when complete, data is returned in ClanOfficerListResponse_t call result
// this makes available the calls below
// you can only ask about clans that a user is a member of
// note that this won't download avatars automatically; if you get an officer,
// and no avatar image is available, call RequestUserInformation( steamID, false ) to download the avatar
virtual SteamAPICall_t RequestClanOfficerList( CSteamID steamIDClan ) = 0;
// iteration of clan officers - can only be done when a RequestClanOfficerList() call has completed
// returns the steamID of the clan owner
virtual CSteamID GetClanOwner( CSteamID steamIDClan ) = 0;
// returns the number of officers in a clan (including the owner)
virtual int GetClanOfficerCount( CSteamID steamIDClan ) = 0;
// returns the steamID of a clan officer, by index, of range [0,GetClanOfficerCount)
virtual CSteamID GetClanOfficerByIndex( CSteamID steamIDClan, int iOfficer ) = 0;
// if current user is chat restricted, he can't send or receive any text/voice chat messages.
// the user can't see custom avatars. But the user can be online and send/recv game invites.
// a chat restricted user can't add friends or join any groups.
virtual uint32 GetUserRestrictions() = 0;
};
#define STEAMFRIENDS_INTERFACE_VERSION "SteamFriends007"
#define STEAMFRIENDS_INTERFACE_VERSION "SteamFriends008"
// callbacks
#pragma pack( push, 8 )
@@ -281,6 +321,19 @@ struct AvatarImageLoaded_t
int m_iTall; // height of the loaded image
};
//-----------------------------------------------------------------------------
// Purpose: marks the return of a request officer list call
//-----------------------------------------------------------------------------
struct ClanOfficerListResponse_t
{
enum { k_iCallback = k_iSteamFriendsCallbacks + 35 };
CSteamID m_steamIDClan;
int m_cOfficers;
uint8 m_bSuccess;
};
#pragma pack( pop )
#endif // ISTEAMFRIENDS_H
+18
View File
@@ -113,6 +113,24 @@ public:
// After receiving a user's authentication data, and passing it to SendUserConnectAndAuthenticate, use this function
// to determine if the user owns downloadable content specified by the provided AppID.
virtual EUserHasLicenseForAppResult UserHasLicenseForApp( CSteamID steamID, AppId_t appID ) = 0;
// New auth system APIs - do not mix with the old auth system APIs.
// ----------------------------------------------------------------
// Retrieve ticket to be sent to the entity who wishes to authenticate you ( using BeginAuthSession API ).
// pcbTicket retrieves the length of the actual ticket.
virtual HAuthTicket GetAuthSessionTicket( void *pTicket, int cbMaxTicket, uint32 *pcbTicket ) = 0;
// Authenticate ticket ( from GetAuthSessionTicket ) from entity steamID to be sure it is valid and isnt reused
// Registers for callbacks if the entity goes offline or cancels the ticket ( see ValidateAuthTicketResponse_t callback and EAuthSessionResponse )
virtual EBeginAuthSessionResult BeginAuthSession( const void *pAuthTicket, int cbAuthTicket, CSteamID steamID ) = 0;
// Stop tracking started by BeginAuthSession - called when no longer playing game with this entity
virtual void EndAuthSession( CSteamID steamID ) = 0;
// Cancel auth ticket from GetAuthSessionTicket, called when no longer playing game with the entity you gave the ticket to
virtual void CancelAuthTicket( HAuthTicket hAuthTicket ) = 0;
};
#define STEAMGAMESERVER_INTERFACE_VERSION "SteamGameServer010"
+5 -1
View File
@@ -19,6 +19,7 @@
// lobby type description
enum ELobbyType
{
k_ELobbyTypePrivate = 0, // only way to join the lobby is to invite to someone else
k_ELobbyTypeFriendsOnly = 1, // shows for friends or invitees, but not in lobby list
k_ELobbyTypePublic = 2, // visible for friends and in lobby list
k_ELobbyTypeInvisible = 3, // returned by search, but not visible to other friends
@@ -204,7 +205,8 @@ public:
// this will send down all the metadata associated with a lobby
// this is an asynchronous call
// returns false if the local user is not connected to the Steam servers
// restart are returned by a LobbyDataUpdate_t callback
// results will be returned by a LobbyDataUpdate_t callback
// if the specified lobby doesn't exist, LobbyDataUpdate_t::m_bSuccess will be set to false
virtual bool RequestLobbyData( CSteamID steamIDLobby ) = 0;
// sets the game server associated with the lobby
@@ -530,6 +532,8 @@ struct LobbyDataUpdate_t
uint64 m_ulSteamIDLobby; // steamID of the Lobby
uint64 m_ulSteamIDMember; // steamID of the member whose data changed, or the room itself
uint8 m_bSuccess; // true if we lobby data was successfully changed;
// will only be false if RequestLobbyData() was called on a lobby that no longer exists
};
+136 -3
View File
@@ -12,6 +12,27 @@
#include "isteamclient.h"
// A handle to a piece of user generated content
typedef uint64 UGCHandle_t;
const UGCHandle_t k_UGCHandleInvalid = 0xffffffffffffffffull;
// Ways to handle a synchronization conflict
enum EResolveConflict
{
k_EResolveConflictKeepClient = 1, // The local version of each file will be used to overwrite the server version
k_EResolveConflictKeepServer = 2, // The server version of each file will be used to overwrite the local version
};
enum ERemoteStoragePlatform
{
k_ERemoteStoragePlatformNone = 0,
k_ERemoteStoragePlatformWindows = (1 << 0),
k_ERemoteStoragePlatformOSX = (1 << 1 ),
k_ERemoteStoragePlatformPS3 = (1 << 2),
k_ERemoteStoragePlatformAll = 0xffffffff
};
//-----------------------------------------------------------------------------
// Purpose: Functions for accessing, reading and writing files stored remotely
// and cached locally
@@ -28,18 +49,130 @@ class ISteamRemoteStorage
// file operations
virtual bool FileWrite( const char *pchFile, const void *pvData, int32 cubData ) = 0;
virtual int32 GetFileSize( const char *pchFile ) = 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 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;
// quota management
// 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
virtual SteamAPICall_t UGCDownload( UGCHandle_t hContent ) = 0;
virtual bool GetUGCDetails( UGCHandle_t hContent, AppId_t *pnAppID, char **ppchName, int32 *pnFileSizeInBytes, CSteamID *pSteamIDOwner ) = 0;
virtual int32 UGCRead( UGCHandle_t hContent, void *pvData, int32 cubDataToRead ) = 0;
// user generated content iteration
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
#if _PS3
// synchronization
virtual bool SynchronizeToClient() = 0;
virtual bool SynchronizeToServer() = 0;
virtual bool ResolveSyncConflict( EResolveConflict eResolveConflict ) = 0;
#endif
};
#define STEAMREMOTESTORAGE_INTERFACE_VERSION "STEAMREMOTESTORAGE_INTERFACE_VERSION002"
#define STEAMREMOTESTORAGE_INTERFACE_VERSION "STEAMREMOTESTORAGE_INTERFACE_VERSION004"
// callbacks
#pragma pack( push, 8 )
//-----------------------------------------------------------------------------
// Purpose: sent when the local file cache is fully synced with the server for an app
// That means that an application can be started and has all latest files
//-----------------------------------------------------------------------------
struct RemoteStorageAppSyncedClient_t
{
enum { k_iCallback = k_iClientRemoteStorageCallbacks + 1 };
AppId_t m_nAppID;
EResult m_eResult;
int m_unNumDownloads;
};
//-----------------------------------------------------------------------------
// Purpose: sent when the server is fully synced with the local file cache for an app
// That means that we can shutdown Steam and our data is stored on the server
//-----------------------------------------------------------------------------
struct RemoteStorageAppSyncedServer_t
{
enum { k_iCallback = k_iClientRemoteStorageCallbacks + 2 };
AppId_t m_nAppID;
EResult m_eResult;
int m_unNumUploads;
};
//-----------------------------------------------------------------------------
// Purpose: Status of up and downloads during a sync session
//
//-----------------------------------------------------------------------------
struct RemoteStorageAppSyncProgress_t
{
enum { k_iCallback = k_iClientRemoteStorageCallbacks + 3 };
char m_rgchCurrentFile[260]; // Current file being transferred
AppId_t m_nAppID; // App this info relates to
uint32 m_uBytesTransferredThisChunk; // Bytes transferred this chunk
double m_dAppPercentComplete; // Percent complete that this app's transfers are
bool m_bUploading; // if false, downloading
};
//
// IMPORTANT! k_iClientRemoteStorageCallbacks + 4-5 are used, see iclientremotestorage.h
//
//-----------------------------------------------------------------------------
// Purpose: Sent after a conflict resolution attempt.
//-----------------------------------------------------------------------------
struct RemoteStorageConflictResolution_t
{
enum { k_iCallback = k_iClientRemoteStorageCallbacks + 6 };
AppId_t m_nAppID;
EResult m_eResult;
};
//-----------------------------------------------------------------------------
// Purpose: The result of a call to FileShare()
//-----------------------------------------------------------------------------
struct RemoteStorageFileShareResult_t
{
enum { k_iCallback = k_iClientRemoteStorageCallbacks + 7 };
EResult m_eResult; // The result of the operation
UGCHandle_t m_hFile; // The handle that can be shared with users and features
};
//-----------------------------------------------------------------------------
// Purpose: The result of a call to UGCDownload()
//-----------------------------------------------------------------------------
struct RemoteStorageDownloadUGCResult_t
{
enum { k_iCallback = k_iClientRemoteStorageCallbacks + 8 };
EResult m_eResult; // The result of the operation.
UGCHandle_t m_hFile; // The handle to the file that was attempted to be downloaded.
AppId_t m_nAppID; // ID of the app that created this file.
int32 m_nSizeInBytes; // The size of the file that was downloaded, in bytes.
char *m_pchFileName; // The name of the file that was downloaded. This pointer is
// not guaranteed to be valid indefinitely.
uint64 m_ulSteamIDOwner; // Steam ID of the user who created this content.
};
#pragma pack( pop )
#endif // ISTEAMREMOTESTORAGE_H
+33 -5
View File
@@ -132,11 +132,6 @@ public:
// (i.e a SteamServersConnected_t has been issued) and may not catch all forms of NAT.
virtual bool BIsBehindNAT() = 0;
#ifdef _PS3
// Logs a user into Steam by using his login name and password
virtual void LogOn( const char *pchUserName, const char *pchPassword ) = 0;
#endif
// set data to be replicated to friends so that they can join your game
// CSteamID steamIDGameServer - the steamID of the game server, received from the game server by the client
// uint32 unIPServer, uint16 usPortServer - the IP address of the game server
@@ -150,6 +145,39 @@ public:
// retrieve a finished ticket
virtual bool GetEncryptedAppTicket( void *pTicket, int cbMaxTicket, uint32 *pcbTicket ) = 0;
#ifdef _PS3
// Initiates PS3 Logon request using just PSN ticket.
//
// PARAMS: bInteractive - If set tells Steam to go ahead and show the PS3 NetStart dialog if needed to
// prompt the user for network setup/PSN logon before initiating the Steam side of the logon.
//
// Listen for SteamServersConnected_t or SteamServerConnectFailure_t for status. SteamServerConnectFailure_t
// may return with EResult k_EResultPSNAccountUnlinked if the PSN account is unknown to Steam. You should
// then call LogOnAndLinkSteamAccountToPSN() after prompting the user for credentials to establish a link.
// Future calls to LogOn() after the one time link call should succeed as long as the user is connected to PSN.
virtual void LogOn( bool bInteractive ) = 0;
// Initiates a request to logon with a specific steam username/password and create a PSN account link at
// the same time. Should call this only if LogOn() has failed and indicated the PSN account is unlinked.
//
// PARAMS: bInteractive - If set tells Steam to go ahead and show the PS3 NetStart dialog if needed to
// prompt the user for network setup/PSN logon before initiating the Steam side of the logon. pchUserName
// should be the users Steam username, and pchPassword should be the users Steam password.
//
// Listen for SteamServersConnected_t or SteamServerConnectFailure_t for status. SteamServerConnectFailure_t
// may return with EResult k_EResultPSNAccountAlreadyLinked if already linked to another account.
virtual void LogOnAndLinkSteamAccountToPSN( bool bInteractive, const char *pchUserName, const char *pchPassword ) = 0;
// Final logon option for PS3, this logs into an existing account if already linked, but if not already linked
// creates a new account using the info in the PSN ticket to generate a unique account name. The new account is
// then linked to the PSN ticket. This is the faster option for new users who don't have an existing Steam account
// to get into multiplayer.
//
// PARAMS: bInteractive - If set tells Steam to go ahead and show the PS3 NetStart dialog if needed to
// prompt the user for network setup/PSN logon before initiating the Steam side of the logon.
virtual void LogOnAndCreateNewSteamAccountIfNeeded( bool bInteractive ) = 0;
#endif
};
#define STEAMUSER_INTERFACE_VERSION "SteamUser014"
+24 -2
View File
@@ -11,6 +11,7 @@
#endif
#include "isteamclient.h"
#include "isteamremotestorage.h"
// size limit on stat or achievement name (UTF-8 encoded)
enum { k_cchStatNameMax = 128 };
@@ -33,6 +34,7 @@ enum ELeaderboardDataRequest
k_ELeaderboardDataRequestGlobal = 0,
k_ELeaderboardDataRequestGlobalAroundUser = 1,
k_ELeaderboardDataRequestFriends = 2,
k_ELeaderboardDataRequestUsers = 3
};
// the sort order of a leaderboard
@@ -68,6 +70,7 @@ struct LeaderboardEntry_t
int32 m_nGlobalRank; // [1..N], where N is the number of users with an entry in the leaderboard
int32 m_nScore; // score as set in the leaderboard
int32 m_cDetails; // number of int32 details available for this entry
UGCHandle_t m_hUGC; // handle for UGC attached to the entry
};
#pragma pack( pop )
@@ -173,6 +176,10 @@ public:
// e.g. DownloadLeaderboardEntries( hLeaderboard, k_ELeaderboardDataRequestGlobalAroundUser, -3, 3 ) will return 7 rows, 3 before the user, 3 after
// k_ELeaderboardDataRequestFriends requests all the rows for friends of the current user
virtual SteamAPICall_t DownloadLeaderboardEntries( SteamLeaderboard_t hSteamLeaderboard, ELeaderboardDataRequest eLeaderboardDataRequest, int nRangeStart, int nRangeEnd ) = 0;
// as above, but downloads leaderboard entries for an arbitrary set of users - ELeaderboardDataRequest is k_ELeaderboardDataRequestUsers
// if a user doesn't have a leaderboard entry, they won't be included in the result
// a max of 100 users can be downloaded at a time, with only one outstanding call at a time
virtual SteamAPICall_t DownloadLeaderboardEntriesForUsers( SteamLeaderboard_t hSteamLeaderboard, CSteamID *prgUsers, int cUsers ) = 0;
// Returns data about a single leaderboard entry
// use a for loop from 0 to LeaderboardScoresDownloaded_t::m_cEntryCount to get all the downloaded entries
@@ -196,13 +203,17 @@ public:
// pScoreDetails points to an array of int32's, cScoreDetailsCount is the number of int32's in the list
virtual SteamAPICall_t UploadLeaderboardScore( SteamLeaderboard_t hSteamLeaderboard, ELeaderboardUploadScoreMethod eLeaderboardUploadScoreMethod, int32 nScore, const int32 *pScoreDetails, int cScoreDetailsCount ) = 0;
// Attaches a piece of user generated content the user's entry on a leaderboard.
// hContent is a handle to a piece of user generated content that was shared using ISteamUserRemoteStorage::FileShare().
// This call is asynchronous, with the result returned in LeaderboardUGCSet_t.
virtual SteamAPICall_t AttachLeaderboardUGC( SteamLeaderboard_t hSteamLeaderboard, UGCHandle_t hUGC ) = 0;
// Retrieves the number of players currently playing your game (online + offline)
// This call is asynchronous, with the result returned in NumberOfCurrentPlayers_t
virtual SteamAPICall_t GetNumberOfCurrentPlayers() = 0;
};
#define STEAMUSERSTATS_INTERFACE_VERSION "STEAMUSERSTATS_INTERFACE_VERSION007"
#define STEAMUSERSTATS_INTERFACE_VERSION "STEAMUSERSTATS_INTERFACE_VERSION009"
// callbacks
#pragma pack( push, 8 )
@@ -296,6 +307,7 @@ struct NumberOfCurrentPlayers_t
};
//-----------------------------------------------------------------------------
// Purpose: Callback indicating that a user's stats have been unloaded.
// Call RequestUserStats again to access stats for this user
@@ -325,6 +337,16 @@ struct UserAchievementIconFetched_t
// IMPORTANT! k_iSteamUserStatsCallbacks + 10 is used, see iclientuserstats.h
//
//-----------------------------------------------------------------------------
// Purpose: call result indicating UGC has been uploaded, returned as a result of SetLeaderboardUGC()
//-----------------------------------------------------------------------------
struct LeaderboardUGCSet_t
{
enum { k_iCallback = k_iSteamUserStatsCallbacks + 11 };
EResult m_eResult; // The result of the operation
SteamLeaderboard_t m_hSteamLeaderboard; // the leaderboard handle that was
};
#pragma pack( pop )
+26
View File
@@ -109,6 +109,7 @@ public:
// refresh the screen with Present or SwapBuffers to allow the overlay to do it's work.
virtual bool BOverlayNeedsPresent() = 0;
#ifndef _PS3
// Asynchronous call to check if an executable file has been signed using the public key set on the signing tab
// of the partner site, for example to refuse to load modified executable files.
// The result is returned in CheckFileSignature_t.
@@ -118,6 +119,12 @@ public:
// k_ECheckFileSignatureInvalidSignature - The file exists, and the signing tab has been set for this file, but the file is either not signed or the signature does not match.
// k_ECheckFileSignatureValidSignature - The file is signed and the signature is valid.
virtual SteamAPICall_t CheckFileSignature( const char *szFileName ) = 0;
#endif
#ifdef _PS3
virtual void PostPS3SysutilCallback( uint64_t status, uint64_t param, void* userdata ) = 0;
virtual bool BIsReadyToShutdown() = 0;
#endif
};
#define STEAMUTILS_INTERFACE_VERSION "SteamUtils005"
@@ -184,6 +191,25 @@ struct CheckFileSignature_t
ECheckFileSignature m_eCheckFileSignature;
};
#ifdef _PS3
//-----------------------------------------------------------------------------
// callback for NetCtlNetStartDialog finishing on PS3
//-----------------------------------------------------------------------------
struct NetStartDialogFinished_t
{
enum { k_iCallback = k_iSteamUtilsCallbacks + 6 };
};
//-----------------------------------------------------------------------------
// callback for NetCtlNetStartDialog unloaded on PS3
//-----------------------------------------------------------------------------
struct NetStartDialogUnloaded_t
{
enum { k_iCallback = k_iSteamUtilsCallbacks + 7 };
};
#endif
#pragma pack( pop )
#endif // ISTEAMUTILS_H
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+27 -1
View File
@@ -80,6 +80,7 @@ S_API void SteamAPI_SetMiniDumpComment( const char *pchMsg );
// 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.
S_API void SteamAPI_UseBreakpadCrashHandler( char const *pchVersion, char const *pchDate, char const *pchTime, bool bFullMemoryDumps, void *pvContext, PFNPreMinidumpCallback m_pfnPreMinidumpCallback );
S_API void SteamAPI_SetBreakpadAppID( uint32 unAppID );
// interface pointers, configured by SteamAPI_Init()
S_API ISteamClient *SteamClient();
@@ -90,10 +91,35 @@ S_API ISteamClient *SteamClient();
// The following structure must be passed to when loading steam_api_ps3.prx
//----------------------------------------------------------------------------------------------------------------------------------------------------------//
#define STEAM_PS3_PATH_MAX 1055
#define STEAM_PS3_SERVICE_ID_MAX 32
struct SteamPS3Params_t
{
void *pReserved;
AppId_t m_nAppId;
char m_rgchInstallationPath[ STEAM_PS3_PATH_MAX ];
char m_rgchSystemCache[ STEAM_PS3_PATH_MAX ];
char m_rgchSystemCache[ STEAM_PS3_PATH_MAX ]; // temp working cache, not persistent
char m_rgchGameData[ STEAM_PS3_PATH_MAX ]; // persistent game data path for storing user data
char m_rgchNpServiceID[ STEAM_PS3_SERVICE_ID_MAX ];
// Should be SYS_TTYP3 through SYS_TTYP10, if it's 0 then Steam won't spawn a
// thread to read console input at all. Using this let's you use Steam console commands
// like: profile_on, profile_off, profile_dump, mem_stats, mem_validate.
unsigned int m_cSteamInputTTY;
struct Ps3netInit_t
{
bool m_bNeedInit;
bool m_bNeedInitEx;
void *m_pMemory;
int m_nMemorySize;
int m_flags;
} m_sysNetInitInfo;
struct Ps3jpgInit_t
{
bool m_bNeedInit;
} m_sysJpgInitInfo;
};
+16 -6
View File
@@ -81,6 +81,10 @@ enum EResult
k_EResultDiskFull = 54, // Operation canceled - not enough disk space.
k_EResultRemoteCallFailed = 55, // an remote call or IPC call failed
k_EResultPasswordUnset = 56, // Password could not be verified as it's unset server side
k_EResultPSNAccountUnlinked = 57, // Attempt to logon from a PS3 failed because the PSN online id is not linked to a Steam account
k_EResultPSNTicketInvalid = 58, // PSN ticket was invalid
k_EResultPSNAccountAlreadyLinked = 59, // PSN account is already linked to some other account, must explicitly request to replace/delete the link first
k_EResultRemoteFileConflict = 60, // The sync cannot resume due to a conflict between the local and remote files
};
// Error codes for use with the voice functions
@@ -92,6 +96,8 @@ enum EVoiceResult
k_EVoiceResultNoData = 3,
k_EVoiceResultBufferTooSmall = 4,
k_EVoiceResultDataCorrupted = 5,
k_EVoiceResultRestricted = 6,
};
// Result codes to GSHandleClientDeny/Kick
@@ -198,6 +204,9 @@ enum ESteamUserStatType
k_ESteamUserStatTypeAVGRATE = 3,
k_ESteamUserStatTypeACHIEVEMENTS = 4,
k_ESteamUserStatTypeGROUPACHIEVEMENTS = 5,
// max, for sanity checks
k_ESteamUserStatTypeMAX
};
@@ -229,6 +238,8 @@ enum EChatRoomEnterResponse
k_EChatRoomEnterResponseError = 5, // Unexpected Error
k_EChatRoomEnterResponseBanned = 6, // You are banned from this chat room and may not join
k_EChatRoomEnterResponseLimited = 7, // Joining this chat is not allowed because you are a limited user (no value on account)
k_EChatRoomEnterResponseClanDisabled = 8, // Attempt to join a clan chat when the clan is locked or disabled
k_EChatRoomEnterResponseCommunityBan = 9, // Attempt to join a chat when the user has a community lock on their account
};
@@ -645,21 +656,20 @@ inline bool CSteamID::IsValid() const
return true;
}
// generic invalid CSteamID
const CSteamID k_steamIDNil;
#define k_steamIDNil CSteamID()
// This steamID comes from a user game connection to an out of date GS that hasnt implemented the protocol
// to provide its steamID
const CSteamID k_steamIDOutofDateGS( 0, 0, k_EUniverseInvalid, k_EAccountTypeInvalid );
#define k_steamIDOutofDateGS CSteamID( 0, 0, k_EUniverseInvalid, k_EAccountTypeInvalid )
// This steamID comes from a user game connection to an sv_lan GS
const CSteamID k_steamIDLanModeGS( 0, 0, k_EUniversePublic, k_EAccountTypeInvalid );
#define k_steamIDLanModeGS CSteamID( 0, 0, k_EUniversePublic, k_EAccountTypeInvalid )
// This steamID can come from a user game connection to a GS that has just booted but hasnt yet even initialized
// its steam3 component and started logging on.
const CSteamID k_steamIDNotInitYetGS( 1, 0, k_EUniverseInvalid, k_EAccountTypeInvalid );
#define k_steamIDNotInitYetGS CSteamID( 1, 0, k_EUniverseInvalid, k_EAccountTypeInvalid )
// This steamID can come from a user game connection to a GS that isn't using the steam authentication system but still
// wants to support the "Join Game" option in the friends list
const CSteamID k_steamIDNonSteamGS( 2, 0, k_EUniverseInvalid, k_EAccountTypeInvalid );
#define k_steamIDNonSteamGS CSteamID( 2, 0, k_EUniverseInvalid, k_EAccountTypeInvalid )
#ifdef STEAM
+27
View File
@@ -0,0 +1,27 @@
//====== Copyright 1996-2008, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#ifndef STEAM_PS3PARAMSINTERNAL_API_H
#define STEAM_PS3PARAMSINTERNAL_API_H
#ifdef _WIN32
#pragma once
#endif
//-----------------------------------------------------------------------------
// Purpose: Params used only internally at Valve. This is the reserved pointer of SteamPS3Params_t
//-----------------------------------------------------------------------------
struct SteamPS3ParamsInternal_t
{
int m_nVersion;
EUniverse m_eUniverse;
const char *m_pchCMForce; // list of CMs in form "IP:port;IP:port" or "IP;IP"
};
#define STEAM_PS3_PARAMS_INTERNAL_VERSION 1
#endif // STEAM_PS3PARAMSINTERNAL_API_H
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+38
View File
@@ -0,0 +1,38 @@
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
//
// Purpose: Class to define the connecting game menu
//
// $NoKeywords: $
//=============================================================================
#include "stdafx.h"
#include "connectingmenu.h"
#include "SpaceWar.h"
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CConnectingMenu::CConnectingMenu( IGameEngine *pGameEngine ) : CBaseMenu<EClientGameState>( pGameEngine )
{
m_bInitialLogonFailed = false;
AddMenuItem( MenuItem_t( "Connecting...", k_EClientConnectingToSteam ) );
}
void CConnectingMenu::Reset()
{
m_bInitialLogonFailed = false;
ClearMenuItems();
AddMenuItem( MenuItem_t( "Connecting...", k_EClientConnectingToSteam ) );
}
void CConnectingMenu::OnConnectFailure()
{
m_bInitialLogonFailed = true;
ClearMenuItems();
AddMenuItem( MenuItem_t( "Retry Connecting", k_EClientRetrySteamConnection ) );
AddMenuItem( MenuItem_t( "Link Existing Account", k_EClientLinkSteamAccount ) );
AddMenuItem( MenuItem_t( "Autocreate Account", k_EClientAutoCreateAccount ) );
}
+31
View File
@@ -0,0 +1,31 @@
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
//
// Purpose: Class to define the main game menu
//
// $NoKeywords: $
//=============================================================================
#ifndef CONNECTINGMENU_H
#define CONNECTINGMENU_H
#include <string>
#include <vector>
#include "GameEngine.h"
#include "SpaceWar.h"
#include "BaseMenu.h"
#include "SpaceWarClient.h"
class CConnectingMenu : public CBaseMenu<EClientGameState>
{
public:
// Constructor
CConnectingMenu( IGameEngine *pGameEngine );
void Reset();
void OnConnectFailure();
private:
bool m_bInitialLogonFailed;
};
#endif // CONNECTINGMENU_H
+204
View File
@@ -0,0 +1,204 @@
//========= Copyright � 1996-2008, Valve LLC, All rights reserved. ============
//
// Purpose: Main class for the game engine -- osx implementation
//
// $NoKeywords: $
//=============================================================================
#ifndef GAMEENGINEOSX_H
#define GAMEENGINEOSX_H
#include "GameEngine.h"
#include <string>
#include <set>
#include <map>
class CVoiceContext;
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, 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 );
private:
void AdjustViewport();
// Initialize the GL rendering interfaces and default state
bool BInitializeGL();
// Initialize the debug font library
bool BInitializeCellDbgFont();
bool BInitializeAudio();
void RunAudio();
void UpdateKey( uint32_t vkKey, int nDown );
private:
// Tracks whether the engine is ready for use
bool m_bEngineReadyForUse;
// Tracks if we are shutting down
bool m_bShuttingDown;
// 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;
NSOpenGLView *m_view;
NSWindow *m_window;
// 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, void* > m_MapGameFonts;
std::map< std::string, GLString * > m_MapStrings;
// Map of handles to texture objects
struct TextureData_t
{
uint32 m_uWidth;
uint32 m_uHeight;
GLuint m_uTextureID;
};
std::map<HGAMETEXTURE, TextureData_t> 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<HGAMEVOICECHANNEL, CVoiceContext* > m_MapVoiceChannel;
uint32 m_unVoiceChannelCount;
};
#endif // GAMEENGINEOSX_H
File diff suppressed because it is too large Load Diff
+181 -20
View File
@@ -9,6 +9,10 @@
#include "GameEngineWin32.h"
#include <map>
#ifndef SAFE_RELEASE
#define SAFE_RELEASE( x ) if ( 0 != ( x ) ) { ( x )->Release(); x = 0; }
#endif
// Allocate static member
std::map<HWND, CGameEngineWin32* > CGameEngineWin32::m_MapEngineInstances;
@@ -71,6 +75,46 @@ LRESULT CALLBACK GameWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam
return DefWindowProc(hWnd, msg, wParam, lParam);
}
class CVoiceContext : public IXAudio2VoiceCallback
{
public:
CVoiceContext() : m_hBufferEndEvent( CreateEvent( NULL, FALSE, FALSE, NULL ) )
{
m_pSourceVoice = NULL;
}
virtual ~CVoiceContext()
{
CloseHandle( m_hBufferEndEvent );
}
STDMETHOD_( void, OnVoiceProcessingPassStart )( UINT32 )
{
}
STDMETHOD_( void, OnVoiceProcessingPassEnd )()
{
}
STDMETHOD_( void, OnStreamEnd )()
{
}
STDMETHOD_( void, OnBufferStart )( void* )
{
}
STDMETHOD_( void, OnBufferEnd )( void* pContext )
{
free( pContext ); // free the sound buffer
SetEvent( m_hBufferEndEvent );
}
STDMETHOD_( void, OnLoopEnd )( void* )
{
}
STDMETHOD_( void, OnVoiceError )( void*, HRESULT )
{
}
HANDLE m_hBufferEndEvent;
IXAudio2SourceVoice* m_pSourceVoice;
};
//-----------------------------------------------------------------------------
// Purpose: Constructor for game engine instance
@@ -83,6 +127,9 @@ CGameEngineWin32::CGameEngineWin32( HINSTANCE hInstance, int nShowCommand, int32
m_hWnd = NULL;
m_pD3D9Interface = NULL;
m_pD3D9Device = NULL;
m_pXAudio2 = NULL;
m_pMasteringVoice = NULL;
m_unVoiceChannelCount = 0; // 0 == invalid handle
m_nWindowWidth = nWindowWidth;
m_nWindowHeight = nWindowHeight;
m_nNextFontHandle = 1;
@@ -107,12 +154,14 @@ CGameEngineWin32::CGameEngineWin32( HINSTANCE hInstance, int nShowCommand, int32
m_ulGameTickCount = 0;
m_dwBackgroundColor = D3DCOLOR_ARGB(0, 255, 255, 255 );
// for XAudio2
CoInitializeEx( NULL, COINIT_MULTITHREADED );
// restrict this main game thread to the first processor, so query performance counter won't jump on crappy AMD cpus
DWORD dwThreadAffinityMask = 0x01;
::SetThreadAffinityMask( ::GetCurrentThread(), dwThreadAffinityMask );
// Setup timing data
LARGE_INTEGER l;
::QueryPerformanceFrequency( &l );
m_ulPerfCounterToMillisecondsDivisor = l.QuadPart/1000;
@@ -139,8 +188,21 @@ CGameEngineWin32::CGameEngineWin32( HINSTANCE hInstance, int nShowCommand, int32
m_nViewportWidth = r.right-r.left;
m_nViewportHeight = r.bottom-r.top;
m_bEngineReadyForUse = true;
// initialzie XAudio2 interface
if( FAILED( XAudio2Create( &m_pXAudio2, 0 ) ) )
{
::MessageBoxA( NULL, "Failed to init XAudio2 engine", "SteamworksExample - Fatal error", MB_OK | MB_ICONERROR );
return;
}
// Create a mastering voice
if( FAILED( m_pXAudio2->CreateMasteringVoice( &m_pMasteringVoice, XAUDIO2_DEFAULT_CHANNELS, VOICE_OUTPUT_SAMPLE_RATE ) ) )
{
::MessageBoxA( NULL, "Failed to create mastering voice", "SteamworksExample - Fatal error", MB_OK | MB_ICONERROR );
return;
}
m_bEngineReadyForUse = true;
}
@@ -157,8 +219,7 @@ void CGameEngineWin32::Shutdown()
std::map<HGAMEFONT, ID3DXFont *>::iterator iter;
for( iter = m_MapFontInstances.begin(); iter != m_MapFontInstances.end(); ++iter )
{
iter->second->Release();
iter->second = NULL;
SAFE_RELEASE( iter->second );
}
m_MapFontInstances.clear();
}
@@ -170,8 +231,7 @@ void CGameEngineWin32::Shutdown()
{
if ( iter->second.m_bIsLocked )
iter->second.m_pBuffer->Unlock();
iter->second.m_pBuffer->Release();
iter->second.m_pBuffer = NULL;
SAFE_RELEASE( iter->second.m_pBuffer );
}
m_MapVertexBuffers.clear();
}
@@ -188,26 +248,24 @@ void CGameEngineWin32::Shutdown()
}
if ( iter->second.m_pTexture )
{
iter->second.m_pTexture->Release();
iter->second.m_pTexture = NULL;
SAFE_RELEASE( iter->second.m_pTexture );
}
}
m_MapTextures.clear();
}
// All XAudio2 interfaces are released when the engine is destroyed, but being tidy
if ( m_pMasteringVoice )
{
m_pMasteringVoice->DestroyVoice();
m_pMasteringVoice = NULL;
}
// Cleanup D3D
if ( m_pD3D9Device )
{
m_pD3D9Device->Release();
m_pD3D9Device = NULL;
}
if ( m_pD3D9Interface )
{
m_pD3D9Interface->Release();
m_pD3D9Interface = NULL;
}
SAFE_RELEASE( m_pD3D9Device );
SAFE_RELEASE( m_pD3D9Interface );
SAFE_RELEASE( m_pXAudio2 );
// Destroy our window
if ( m_hWnd )
{
@@ -239,6 +297,8 @@ void CGameEngineWin32::Shutdown()
}
m_hInstance = NULL;
}
CoUninitialize();
}
@@ -1643,3 +1703,104 @@ void CGameEngineWin32::RemoveInstanceFromHWNDMap( HWND hWnd )
m_MapEngineInstances.erase( iter );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
HGAMEVOICECHANNEL CGameEngineWin32::HCreateVoiceChannel()
{
if ( !m_pXAudio2 )
return 0;
m_unVoiceChannelCount++;
CVoiceContext* pVoiceContext = new CVoiceContext;
// The format we sample voice in.
WAVEFORMATEX voicesampleformat =
{
WAVE_FORMAT_PCM, // wFormatTag
1, // nChannels
VOICE_OUTPUT_SAMPLE_RATE,// nSamplesPerSec
VOICE_OUTPUT_SAMPLE_RATE*BYTES_PER_SAMPLE, // nAvgBytesPerSec
2, // nBlockAlign
8*BYTES_PER_SAMPLE, // wBitsPerSample
sizeof(WAVEFORMATEX) // cbSize
};
if( FAILED( m_pXAudio2->CreateSourceVoice( &pVoiceContext->m_pSourceVoice, &voicesampleformat , 0, 1.0f, pVoiceContext ) ) )
{
delete pVoiceContext;
return 0; // failed
}
pVoiceContext->m_pSourceVoice->Start( 0, 0 );
m_MapVoiceChannel[m_unVoiceChannelCount] = pVoiceContext;
return m_unVoiceChannelCount;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CGameEngineWin32::DestroyVoiceChannel( HGAMEVOICECHANNEL hChannel )
{
std::map<HGAMEVOICECHANNEL, CVoiceContext* >::iterator iter;
iter = m_MapVoiceChannel.find( hChannel );
if ( iter != m_MapVoiceChannel.end() )
{
CVoiceContext* pVoiceContext = iter->second;
XAUDIO2_VOICE_STATE state;
for(;;)
{
pVoiceContext->m_pSourceVoice->GetState( &state );
if( !state.BuffersQueued )
break;
WaitForSingleObject( pVoiceContext->m_hBufferEndEvent, INFINITE );
}
pVoiceContext->m_pSourceVoice->Stop( 0 );
pVoiceContext->m_pSourceVoice->DestroyVoice();
delete pVoiceContext;
m_MapVoiceChannel.erase( iter );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CGameEngineWin32::AddVoiceData( HGAMEVOICECHANNEL hChannel, const uint8 *pVoiceData, uint32 uLength )
{
std::map<HGAMEVOICECHANNEL, CVoiceContext* >::iterator iter;
iter = m_MapVoiceChannel.find( hChannel );
if ( iter == m_MapVoiceChannel.end() )
return false; // channel not found
CVoiceContext* pVoiceContext = iter->second;
//
// At this point we have a buffer full of audio and enough room to submit it, so
// let's submit it and get another read request going.
uint8 *pBuffer = (uint8 *) malloc( uLength );
memcpy( pBuffer, pVoiceData, uLength );
XAUDIO2_BUFFER buf = {0};
buf.AudioBytes = uLength;
buf.pAudioData = pBuffer;
buf.pContext = pBuffer; // the buffer is freed again in CVoiceContext::OnBufferEnd
if ( FAILED( pVoiceContext->m_pSourceVoice->SubmitSourceBuffer( &buf ) ) )
{
free ( pBuffer );
return false;
}
return true;
}
+12
View File
@@ -67,6 +67,8 @@ struct TexturedQuadVertex_t
float u, v; // texture coordinates
};
class CVoiceContext;
// WndProc declaration
LRESULT CALLBACK GameWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );
@@ -165,6 +167,10 @@ public:
// Check if the game engine hwnd currently has focus (and a working d3d device)
bool BGameEngineHasFocus() { return ::GetForegroundWindow() == m_hWnd && !m_bDeviceLost; }
// voice chat sound engine
virtual HGAMEVOICECHANNEL HCreateVoiceChannel();
virtual void DestroyVoiceChannel( HGAMEVOICECHANNEL hChannel );
virtual bool AddVoiceData( HGAMEVOICECHANNEL hChannel, const uint8 *pVoiceData, uint32 uLength );
// Track the state of keyboard input (these are public, but not part of the public interface)
void RecordKeyDown( DWORD dwVK );
@@ -336,6 +342,12 @@ private:
// Presentation parameters, saved in case of lost device needing reset
D3DPRESENT_PARAMETERS m_d3dpp;
IXAudio2* m_pXAudio2;
IXAudio2MasteringVoice* m_pMasteringVoice;
// Map of font handles to font objects
std::map<HGAMEVOICECHANNEL, CVoiceContext* > m_MapVoiceChannel;
uint32 m_unVoiceChannelCount;
};
#endif // GAMEENGINEWIN32_H
+42
View File
@@ -0,0 +1,42 @@
#import <Cocoa/Cocoa.h>
#import <OpenGL/gl.h>
#import <OpenGL/glext.h>
#import <OpenGL/OpenGL.h>
#import <OpenGL/CGLContext.h>
@interface GLString : NSObject {
CGLContextObj cgl_ctx; // current context at time of texture creation
GLuint texName;
NSSize texSize;
NSAttributedString * string;
NSFont * font;
NSColor * textColor; // default is opaque white
NSRect border;
uint32_t flags;
BOOL requiresUpdate;
}
- (id) initWithString:(NSString *)aString withFont:(NSFont *)inFont withTextColor:(NSColor *)color inBox:(NSRect *)box withFlags:(uint32_t) inFlags;
- (void) dealloc;
- (GLuint) texName; // 0 if no texture allocated
- (NSSize) texSize; // actually size of texture generated in texels, (0, 0) if no texture allocated
- (NSColor *) textColor; // get the pre-multiplied default text color (includes alpha) string attributes could override this
- (NSRect) border; // bounds for rect
- (NSFont *)font;
- (uint32_t) flags; // get the pre-multiplied default text color (includes alpha) string attributes could override this
- (void) setFont:(NSFont *)inFont;
- (void) setColor:(NSColor *)color;
- (void) setBox:(NSRect *)box;
- (void) setFlags:(uint32_t) inFlags;
- (void) genTexture; // generates the texture without drawing texture to current context
- (void) drawWithBounds:(NSRect)bounds; // will update the texture if required due to change in settings (note context should be setup to be orthographic scaled to per pixel scale)
- (void) drawAtPoint:(NSPoint)point;
@end
+246
View File
@@ -0,0 +1,246 @@
#include "stdafx.h"
#include "GameEngine.h"
#import "glstringosx.h"
// GLString follows
@implementation GLString
- (void) deleteTexture
{
if (texName && cgl_ctx) {
(*cgl_ctx->disp.delete_textures)(cgl_ctx->rend, 1, &texName);
texName = 0; // ensure it is zeroed for failure cases
cgl_ctx = 0;
}
}
- (void) dealloc
{
[self deleteTexture];
[textColor release];
[string release];
[super dealloc];
}
// designated initializer
- (id) initWithString:(NSString *)aString withFont:(NSFont *) inFont withTextColor:(NSColor *)color inBox:(NSRect *)box withFlags:(uint32_t) inFlags
{
[super init];
cgl_ctx = NULL;
texName = 0;
texSize.width = 0.0f;
texSize.height = 0.0f;
[color retain];
textColor = color;
[inFont retain];
font = inFont;
flags = inFlags;
NSMutableDictionary *attribs = [NSMutableDictionary dictionary];
[attribs setObject: font forKey: NSFontAttributeName];
[attribs setObject: textColor forKey: NSForegroundColorAttributeName];
string = [[NSAttributedString alloc] initWithString:aString attributes:attribs];
border = *box;
requiresUpdate = YES;
return self;
}
- (void) setFont:(NSFont *)inFont
{
if ( [font isEqual: inFont] )
return;
[string release];
[font release];
[inFont retain];
font = inFont;
NSMutableDictionary *attribs = [NSMutableDictionary dictionary];
[attribs setObject: font forKey: NSFontAttributeName];
[attribs setObject: textColor forKey: NSForegroundColorAttributeName];
string = [[NSAttributedString alloc] initWithString:[string string] attributes:attribs];
requiresUpdate = YES;
}
- (void) setColor:(NSColor *)color
{
if ( [textColor isEqual:color] )
return;
[string release];
[textColor release];
[color retain];
textColor = color;
NSMutableDictionary *attribs = [NSMutableDictionary dictionary];
[attribs setObject: font forKey: NSFontAttributeName];
[attribs setObject: textColor forKey: NSForegroundColorAttributeName];
string = [[NSAttributedString alloc] initWithString:[string string] attributes:attribs];
requiresUpdate = YES;
}
- (void) setBox:(NSRect *)box
{
if ( NSEqualRects(border, *box ) )
return;
border = *box;
requiresUpdate = YES;
}
- (void) setFlags:(uint32_t) inFlags
{
if ( inFlags == flags )
return;
flags = inFlags;
requiresUpdate = YES;
}
- (void) genTexture; // generates the texture without drawing texture to current context
{
NSImage * image;
NSBitmapImageRep * bitmap;
NSSize previousSize = texSize;
image = [[NSImage alloc] initWithSize:border.size];
[image lockFocus];
[[NSGraphicsContext currentContext] setShouldAntialias:YES];
[textColor set];
float x = 0.0f;
float y = (border.size.height - [string size].height)/2;
if ( flags & TEXTPOS_CENTER )
x = (border.size.width - [string size].width)/2;
else if ( flags & TEXTPOS_RIGHT )
x = border.size.width - [string size].width;
[string drawAtPoint:NSMakePoint(x, y)]; // draw at offset position
bitmap = [[NSBitmapImageRep alloc] initWithFocusedViewRect:NSMakeRect (0.0f, 0.0f, border.size.width, border.size.height)];
[image unlockFocus];
texSize.width = [bitmap pixelsWide];
texSize.height = [bitmap pixelsHigh];
if (cgl_ctx = CGLGetCurrentContext ())
{ // if we successfully retrieve a current context (required)
glPushAttrib(GL_TEXTURE_BIT);
if (0 == texName) glGenTextures (1, &texName);
glBindTexture (GL_TEXTURE_RECTANGLE_EXT, texName);
if (NSEqualSizes(previousSize, texSize)) {
glTexSubImage2D(GL_TEXTURE_RECTANGLE_EXT,0,0,0,texSize.width,texSize.height,[bitmap hasAlpha] ? GL_RGBA : GL_RGB,GL_UNSIGNED_BYTE,[bitmap bitmapData]);
} else {
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, texSize.width, texSize.height, 0, [bitmap hasAlpha] ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, [bitmap bitmapData]);
}
glPopAttrib();
}
else
{
NSLog (@"-genTexture: Failure to get current OpenGL context\n");
}
[bitmap release];
[image release];
requiresUpdate = NO;
}
- (GLuint) texName
{
return texName;
}
- (NSSize) texSize
{
return texSize;
}
- (void) setTextColor:(NSColor *)color // set default text color
{
[color retain];
[textColor release];
textColor = color;
requiresUpdate = YES;
}
- (NSColor *) textColor
{
return textColor;
}
- (NSRect) border
{
return border;
}
- (NSFont *)font
{
return font;
}
- (uint32_t) flags
{
return flags;
}
- (void) drawWithBounds:(NSRect)bounds
{
if (requiresUpdate)
[self genTexture];
if (texName)
{
glPushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT | GL_COLOR_BUFFER_BIT); // GL_COLOR_BUFFER_BIT for glBlendFunc, GL_ENABLE_BIT for glEnable / glDisable
glDisable (GL_DEPTH_TEST); // ensure text is not remove by depth buffer test.
glEnable (GL_BLEND); // for text fading
glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // ditto
glEnable (GL_TEXTURE_RECTANGLE_EXT);
glBindTexture (GL_TEXTURE_RECTANGLE_EXT, texName);
glBegin (GL_QUADS);
glTexCoord2f (0.0f, 0.0f); // draw upper left in world coordinates
glVertex2f (bounds.origin.x, bounds.origin.y);
glTexCoord2f (0.0f, texSize.height); // draw lower left in world coordinates
glVertex2f (bounds.origin.x, bounds.origin.y + bounds.size.height);
glTexCoord2f (texSize.width, texSize.height); // draw upper right in world coordinates
glVertex2f (bounds.origin.x + bounds.size.width, bounds.origin.y + bounds.size.height);
glTexCoord2f (texSize.width, 0.0f); // draw lower right in world coordinates
glVertex2f (bounds.origin.x + bounds.size.width, bounds.origin.y);
glEnd ();
glPopAttrib();
}
}
- (void) drawAtPoint:(NSPoint)point
{
if (requiresUpdate)
[self genTexture]; // ensure size is calculated for bounds
if (texName) // if successful
[self drawWithBounds:NSMakeRect (point.x, point.y, texSize.width, texSize.height)];
}
@end
+1
View File
@@ -0,0 +1 @@
480
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDocumentTypes</key>
<array/>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>com.valvesoftware.steam.steamworksexample</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
<array/>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSMinimumSystemVersion</key>
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
<key>NSMainNibFile</key>
<string></string>
<key>NSPrincipalClass</key>
<string></string>
<key>NSServices</key>
<array/>
<key>UTExportedTypeDeclarations</key>
<array/>
<key>UTImportedTypeDeclarations</key>
<array/>
</dict>
</plist>
+257
View File
@@ -0,0 +1,257 @@
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
//
// Purpose: Class for tracking stats and achievements
//
// $NoKeywords: $
//=============================================================================
#include "stdafx.h"
#include "remotestoragesync.h"
#include "BaseMenu.h"
//-----------------------------------------------------------------------------
// NOTE
//
// The following code is for synchronizing files while the game is running
// This is only necessary when on the Playstation 3, as the Steam client handles
// these operations when on PC/Mac.
//
//-----------------------------------------------------------------------------
#ifdef _PS3
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CRemoteStorageSyncMenu::CRemoteStorageSyncMenu( IGameEngine *pGameEngine ) : CBaseMenu<ERemoteStorageSyncMenuCommand>( pGameEngine )
{
}
//-----------------------------------------------------------------------------
// Purpose: Shows the synchronization progress menu
//-----------------------------------------------------------------------------
void CRemoteStorageSyncMenu::ShowSyncProgress( ESyncOperation eSyncOperation, double dPercentComplete )
{
if ( eSyncOperation == k_ESyncOperationIdle )
return;
PushSelectedItem();
ClearMenuItems();
// Create progress text
char buffer[260];
const char *pchFormat = (eSyncOperation == k_ESyncOperationToClient ) ? "Syncing to client (%d%%)" : "Syncing to server(%d%%)";
sprintf( buffer, pchFormat, (int)dPercentComplete );
AddMenuItem( CRemoteStorageSyncMenu::MenuItem_t( buffer, k_EMenuCommandProgress ) );
PopSelectedItem();
}
//-----------------------------------------------------------------------------
// Purpose: Shows the synchronization progress menu
//-----------------------------------------------------------------------------
void CRemoteStorageSyncMenu::ShowSyncComplete( ESyncOperation eSyncOperation, bool bSuccess )
{
if ( eSyncOperation == k_ESyncOperationIdle )
return;
PushSelectedItem();
ClearMenuItems();
// Create progress text
char buffer[260];
const char *pchResult = bSuccess ? "complete" : "failed";
const char *pchFormat = (eSyncOperation == k_ESyncOperationToClient ) ? "Sync to client %s.. press X" : "Sync to server %s.. press X";
sprintf( buffer, pchFormat, pchResult );
AddMenuItem( CRemoteStorageSyncMenu::MenuItem_t( buffer, k_EMenuCommandSyncComplete ) );
PopSelectedItem();
}
//-----------------------------------------------------------------------------
// Purpose: Shows the conflict menu
//-----------------------------------------------------------------------------
void CRemoteStorageSyncMenu::ShowConflict()
{
PushSelectedItem();
ClearMenuItems();
// Description
AddMenuItem( CRemoteStorageSyncMenu::MenuItem_t( "There is a conflict between the local & server versions of your files:", k_EMenuCommandNone ) );
// options
AddMenuItem( CRemoteStorageSyncMenu::MenuItem_t( "- Keep the local client versions", k_EMenuCommandKeepClient ) );
AddMenuItem( CRemoteStorageSyncMenu::MenuItem_t( "- Keep the remote server versions", k_EMenuCommandKeepServer ) );
PopSelectedItem();
}
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CRemoteStorageSync::CRemoteStorageSync( IGameEngine *pGameEngine ) :
m_eSyncOperation( k_ESyncOperationIdle ),
m_menu( pGameEngine ),
m_callbackAppSyncClientComplete( this, &CRemoteStorageSync::OnAppSyncClientComplete ),
m_callbackAppSyncServerComplete( this, &CRemoteStorageSync::OnAppSyncServerComplete ),
m_callbackAppSyncProgress( this, &CRemoteStorageSync::OnAppSyncProgress ),
m_callbackConflictResolution( this, &CRemoteStorageSync::OnConflictResolution )
{
}
//-----------------------------------------------------------------------------
// Purpose: Start synchronizing files to the client
//-----------------------------------------------------------------------------
void CRemoteStorageSync::SynchronizeToClient()
{
if ( m_eSyncOperation != k_ESyncOperationIdle )
return;
if ( !SteamRemoteStorage()->SynchronizeToClient() )
return;
m_eSyncOperation = k_ESyncOperationToClient;
m_menu.ShowSyncProgress( m_eSyncOperation, 0.0 );
}
//-----------------------------------------------------------------------------
// Purpose: Start synchronizing files to the server
//-----------------------------------------------------------------------------
void CRemoteStorageSync::SynchronizeToServer()
{
if ( m_eSyncOperation != k_ESyncOperationIdle )
return;
if ( !SteamRemoteStorage()->SynchronizeToServer() )
return;
m_eSyncOperation = k_ESyncOperationToServer;
m_menu.ShowSyncProgress( m_eSyncOperation, 0.0 );
}
//-----------------------------------------------------------------------------
// Purpose: Called each frame. Draw's menu
//-----------------------------------------------------------------------------
void CRemoteStorageSync::Render()
{
m_menu.RunFrame();
}
//-----------------------------------------------------------------------------
// Purpose: Returns true if we are done synchronizing
//-----------------------------------------------------------------------------
bool CRemoteStorageSync::BFinished()
{
return m_eSyncOperation == k_ESyncOperationIdle;
}
//-----------------------------------------------------------------------------
// Purpose: Called periodically by Steam when a synchronization is in progress
//-----------------------------------------------------------------------------
void CRemoteStorageSync::OnAppSyncProgress( RemoteStorageAppSyncProgress_t *pParam )
{
// make sure the update is for us
if ( pParam->m_nAppID != SteamUtils()->GetAppID() )
return;
// make sure the update is in the direction we expect
if ( m_eSyncOperation == k_ESyncOperationIdle || (pParam->m_bUploading && m_eSyncOperation != k_ESyncOperationToServer) )
return;
m_menu.ShowSyncProgress( m_eSyncOperation, pParam->m_dAppPercentComplete );
}
//-----------------------------------------------------------------------------
// Purpose: Called by Steam when a synchronization to the client is complete
//-----------------------------------------------------------------------------
void CRemoteStorageSync::OnAppSyncClientComplete( RemoteStorageAppSyncedClient_t *pParam )
{
// make sure the update is for us
if ( pParam->m_nAppID != SteamUtils()->GetAppID() )
return;
// make sure the update is in the direction we expect
if ( m_eSyncOperation != k_ESyncOperationToClient )
return;
// check for errors
if ( pParam->m_eResult == k_EResultRemoteFileConflict )
{
m_menu.ShowConflict();
return;
}
m_menu.ShowSyncComplete( m_eSyncOperation, pParam->m_eResult == k_EResultOK );
}
//-----------------------------------------------------------------------------
// Purpose: Called by Steam when a synchronization to the server is complete
//-----------------------------------------------------------------------------
void CRemoteStorageSync::OnAppSyncServerComplete( RemoteStorageAppSyncedServer_t *pParam )
{
// make sure the update is for us
if ( pParam->m_nAppID != SteamUtils()->GetAppID() )
return;
// make sure the update is in the direction we expect
if ( m_eSyncOperation != k_ESyncOperationToServer )
return;
// check for errors
if ( pParam->m_eResult == k_EResultRemoteFileConflict )
{
m_menu.ShowConflict();
return;
}
m_menu.ShowSyncComplete( m_eSyncOperation, pParam->m_eResult == k_EResultOK );
}
//-----------------------------------------------------------------------------
// Purpose: Called by Steam when a conflict resolution has completed
//-----------------------------------------------------------------------------
void CRemoteStorageSync::OnConflictResolution( RemoteStorageConflictResolution_t *pParam )
{
// make sure the update is for us
if ( pParam->m_nAppID != SteamUtils()->GetAppID() )
return;
// check for errors
m_menu.ShowSyncComplete( m_eSyncOperation, pParam->m_eResult == k_EResultOK );
}
//-----------------------------------------------------------------------------
// Purpose: A sync menu item has been selected
//-----------------------------------------------------------------------------
void CRemoteStorageSync::OnMenuSelection( ERemoteStorageSyncMenuCommand selection )
{
switch( selection )
{
case k_EMenuCommandSyncComplete:
m_eSyncOperation = k_ESyncOperationIdle;
break;
case k_EMenuCommandKeepClient:
m_menu.ShowSyncProgress( m_eSyncOperation, 0.0 );
SteamRemoteStorage()->ResolveSyncConflict( k_EResolveConflictKeepClient );
break;
case k_EMenuCommandKeepServer:
m_menu.ShowSyncProgress( m_eSyncOperation, 0.0 );
SteamRemoteStorage()->ResolveSyncConflict( k_EResolveConflictKeepServer );
break;
}
}
#endif
+87
View File
@@ -0,0 +1,87 @@
//========= Copyright © 1996-2008, Valve LLC, All rights reserved. ============
//
// Purpose: Class for tracking stats and achievements
//
// $NoKeywords: $
//=============================================================================
#ifndef REMOTE_STORAGE_SYNC_H
#define REMOTE_STORAGE_SYNC_H
#include "SpaceWar.h"
#include "GameEngine.h"
#include "BaseMenu.h"
//-----------------------------------------------------------------------------
// NOTE
//
// The following code is for synchronizing files while the game is running
// This is only necessary when on the Playstation 3, as the Steam client handles
// these operations when on PC/Mac.
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Purpose: Interface for sync screen
//-----------------------------------------------------------------------------
class IRemoteStorageSync
{
public:
virtual void SynchronizeToClient() = 0;
virtual void SynchronizeToServer() = 0;
virtual void Render() = 0;
virtual bool BFinished() = 0;
virtual void OnMenuSelection( ERemoteStorageSyncMenuCommand selection ) = 0;
};
#ifdef _PS3
enum ESyncOperation
{
k_ESyncOperationIdle,
k_ESyncOperationToClient,
k_ESyncOperationToServer
};
//-----------------------------------------------------------------------------
// Purpose: Menu shown for synchronization progress and prompting user to resolve a conflict
//-----------------------------------------------------------------------------
class CRemoteStorageSyncMenu : public CBaseMenu< ERemoteStorageSyncMenuCommand >
{
public:
CRemoteStorageSyncMenu( IGameEngine *pGameEngine );
void ShowSyncProgress( ESyncOperation eSyncOperation, double dPercentComplete );
void ShowSyncComplete( ESyncOperation eSyncOperation, bool bSuccess );
void ShowConflict();
};
//-----------------------------------------------------------------------------
// Purpose: Synchronizes files with Steam
//-----------------------------------------------------------------------------
class CRemoteStorageSync : public IRemoteStorageSync
{
public:
// Constructor
CRemoteStorageSync( IGameEngine *pGameEngine );
// IRemoteStorageSync implementations
virtual void SynchronizeToClient();
virtual void SynchronizeToServer();
virtual void Render();
virtual bool BFinished();
virtual void OnMenuSelection( ERemoteStorageSyncMenuCommand selection );
private:
// synchronization updates
STEAM_CALLBACK( CRemoteStorageSync, OnAppSyncClientComplete, RemoteStorageAppSyncedClient_t, m_callbackAppSyncClientComplete );
STEAM_CALLBACK( CRemoteStorageSync, OnAppSyncServerComplete, RemoteStorageAppSyncedServer_t, m_callbackAppSyncServerComplete );
STEAM_CALLBACK( CRemoteStorageSync, OnAppSyncProgress, RemoteStorageAppSyncProgress_t, m_callbackAppSyncProgress );
STEAM_CALLBACK( CRemoteStorageSync, OnConflictResolution, RemoteStorageConflictResolution_t, m_callbackConflictResolution );
CRemoteStorageSyncMenu m_menu;
ESyncOperation m_eSyncOperation;
};
#endif // !_PS3
#endif
@@ -0,0 +1,428 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
503C6CB61268F34200B66E3B /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 503C6CB51268F34200B66E3B /* Cocoa.framework */; };
503C6D0F1268F49F00B66E3B /* BaseMenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 503C6CD91268F49F00B66E3B /* BaseMenu.cpp */; };
503C6D101268F49F00B66E3B /* connectingmenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 503C6CDB1268F49F00B66E3B /* connectingmenu.cpp */; };
503C6D121268F49F00B66E3B /* gameengineosx.mm in Sources */ = {isa = PBXBuildFile; fileRef = 503C6CE01268F49F00B66E3B /* gameengineosx.mm */; };
503C6D131268F49F00B66E3B /* glstringosx.mm in Sources */ = {isa = PBXBuildFile; fileRef = 503C6CE21268F49F00B66E3B /* glstringosx.mm */; };
503C6D141268F49F00B66E3B /* Leaderboards.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 503C6CE31268F49F00B66E3B /* Leaderboards.cpp */; };
503C6D151268F49F00B66E3B /* Lobby.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 503C6CE51268F49F00B66E3B /* Lobby.cpp */; };
503C6D161268F49F00B66E3B /* Main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 503C6CE71268F49F00B66E3B /* Main.cpp */; };
503C6D171268F49F00B66E3B /* MainMenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 503C6CE81268F49F00B66E3B /* MainMenu.cpp */; };
503C6D191268F49F00B66E3B /* p2pauth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 503C6CED1268F49F00B66E3B /* p2pauth.cpp */; };
503C6D1A1268F49F00B66E3B /* PhotonBeam.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 503C6CEF1268F49F00B66E3B /* PhotonBeam.cpp */; };
503C6D1B1268F49F00B66E3B /* QuitMenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 503C6CF11268F49F00B66E3B /* QuitMenu.cpp */; };
503C6D1C1268F49F00B66E3B /* RemoteStorage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 503C6CF31268F49F00B66E3B /* RemoteStorage.cpp */; };
503C6D1D1268F49F00B66E3B /* ServerBrowser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 503C6CF51268F49F00B66E3B /* ServerBrowser.cpp */; };
503C6D1E1268F49F00B66E3B /* Ship.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 503C6CF81268F49F00B66E3B /* Ship.cpp */; };
503C6D1F1268F49F00B66E3B /* SpaceWarClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 503C6CFB1268F49F00B66E3B /* SpaceWarClient.cpp */; };
503C6D201268F49F00B66E3B /* SpaceWarEntity.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 503C6CFD1268F49F00B66E3B /* SpaceWarEntity.cpp */; };
503C6D221268F49F00B66E3B /* SpaceWarServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 503C6D011268F49F00B66E3B /* SpaceWarServer.cpp */; };
503C6D231268F49F00B66E3B /* StarField.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 503C6D031268F49F00B66E3B /* StarField.cpp */; };
503C6D241268F49F00B66E3B /* StatsAndAchievements.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 503C6D051268F49F00B66E3B /* StatsAndAchievements.cpp */; };
503C6D251268F49F00B66E3B /* stdafx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 503C6D071268F49F00B66E3B /* stdafx.cpp */; };
503C6D261268F49F00B66E3B /* Sun.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 503C6D091268F49F00B66E3B /* Sun.cpp */; };
503C6D271268F49F00B66E3B /* VectorEntity.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 503C6D0B1268F49F00B66E3B /* VectorEntity.cpp */; };
503C6D281268F49F00B66E3B /* voicechat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 503C6D0D1268F49F00B66E3B /* voicechat.cpp */; };
503C6DAC1268FE1000B66E3B /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 503C6DAA1268FE1000B66E3B /* OpenAL.framework */; };
503C6DAD1268FE1000B66E3B /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 503C6DAB1268FE1000B66E3B /* OpenGL.framework */; };
503C6DB41269002800B66E3B /* libsteam_api.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 503C6DB31269002800B66E3B /* libsteam_api.dylib */; };
504EDCBC126901EC00F96D63 /* libsteam_api.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 503C6DB31269002800B66E3B /* libsteam_api.dylib */; };
504EDCC21269026C00F96D63 /* steam_appid.txt in CopyFiles */ = {isa = PBXBuildFile; fileRef = 504EDCC01269025A00F96D63 /* steam_appid.txt */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
504EDCBB126901D200F96D63 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 6;
files = (
504EDCC21269026C00F96D63 /* steam_appid.txt in CopyFiles */,
504EDCBC126901EC00F96D63 /* libsteam_api.dylib in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
503C6CB21268F34200B66E3B /* steamworksexample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = steamworksexample.app; sourceTree = BUILT_PRODUCTS_DIR; };
503C6CB51268F34200B66E3B /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
503C6CD91268F49F00B66E3B /* BaseMenu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BaseMenu.cpp; sourceTree = "<group>"; };
503C6CDA1268F49F00B66E3B /* BaseMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BaseMenu.h; sourceTree = "<group>"; };
503C6CDB1268F49F00B66E3B /* connectingmenu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = connectingmenu.cpp; sourceTree = "<group>"; };
503C6CDC1268F49F00B66E3B /* connectingmenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = connectingmenu.h; sourceTree = "<group>"; };
503C6CDD1268F49F00B66E3B /* GameEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GameEngine.h; sourceTree = "<group>"; };
503C6CDF1268F49F00B66E3B /* gameengineosx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gameengineosx.h; sourceTree = "<group>"; };
503C6CE01268F49F00B66E3B /* gameengineosx.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = gameengineosx.mm; sourceTree = "<group>"; };
503C6CE11268F49F00B66E3B /* glstringosx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = glstringosx.h; sourceTree = "<group>"; };
503C6CE21268F49F00B66E3B /* glstringosx.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = glstringosx.mm; sourceTree = "<group>"; };
503C6CE31268F49F00B66E3B /* Leaderboards.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Leaderboards.cpp; sourceTree = "<group>"; };
503C6CE41268F49F00B66E3B /* Leaderboards.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Leaderboards.h; sourceTree = "<group>"; };
503C6CE51268F49F00B66E3B /* Lobby.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Lobby.cpp; sourceTree = "<group>"; };
503C6CE61268F49F00B66E3B /* Lobby.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Lobby.h; sourceTree = "<group>"; };
503C6CE71268F49F00B66E3B /* Main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Main.cpp; sourceTree = "<group>"; };
503C6CE81268F49F00B66E3B /* MainMenu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MainMenu.cpp; sourceTree = "<group>"; };
503C6CE91268F49F00B66E3B /* MainMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainMenu.h; sourceTree = "<group>"; };
503C6CEA1268F49F00B66E3B /* Messages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Messages.h; sourceTree = "<group>"; };
503C6CED1268F49F00B66E3B /* p2pauth.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = p2pauth.cpp; sourceTree = "<group>"; };
503C6CEE1268F49F00B66E3B /* p2pauth.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = p2pauth.h; sourceTree = "<group>"; };
503C6CEF1268F49F00B66E3B /* PhotonBeam.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PhotonBeam.cpp; sourceTree = "<group>"; };
503C6CF01268F49F00B66E3B /* PhotonBeam.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PhotonBeam.h; sourceTree = "<group>"; };
503C6CF11268F49F00B66E3B /* QuitMenu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QuitMenu.cpp; sourceTree = "<group>"; };
503C6CF21268F49F00B66E3B /* QuitMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QuitMenu.h; sourceTree = "<group>"; };
503C6CF31268F49F00B66E3B /* RemoteStorage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RemoteStorage.cpp; sourceTree = "<group>"; };
503C6CF41268F49F00B66E3B /* RemoteStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemoteStorage.h; sourceTree = "<group>"; };
503C6CF51268F49F00B66E3B /* ServerBrowser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ServerBrowser.cpp; sourceTree = "<group>"; };
503C6CF61268F49F00B66E3B /* ServerBrowser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ServerBrowser.h; sourceTree = "<group>"; };
503C6CF71268F49F00B66E3B /* ServerBrowserMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ServerBrowserMenu.h; sourceTree = "<group>"; };
503C6CF81268F49F00B66E3B /* Ship.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Ship.cpp; sourceTree = "<group>"; };
503C6CF91268F49F00B66E3B /* Ship.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Ship.h; sourceTree = "<group>"; };
503C6CFA1268F49F00B66E3B /* SpaceWar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpaceWar.h; sourceTree = "<group>"; };
503C6CFB1268F49F00B66E3B /* SpaceWarClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpaceWarClient.cpp; sourceTree = "<group>"; };
503C6CFC1268F49F00B66E3B /* SpaceWarClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpaceWarClient.h; sourceTree = "<group>"; };
503C6CFD1268F49F00B66E3B /* SpaceWarEntity.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpaceWarEntity.cpp; sourceTree = "<group>"; };
503C6CFE1268F49F00B66E3B /* SpaceWarEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpaceWarEntity.h; sourceTree = "<group>"; };
503C6CFF1268F49F00B66E3B /* SpaceWarRes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpaceWarRes.h; sourceTree = "<group>"; };
503C6D011268F49F00B66E3B /* SpaceWarServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpaceWarServer.cpp; sourceTree = "<group>"; };
503C6D021268F49F00B66E3B /* SpaceWarServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpaceWarServer.h; sourceTree = "<group>"; };
503C6D031268F49F00B66E3B /* StarField.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StarField.cpp; sourceTree = "<group>"; };
503C6D041268F49F00B66E3B /* StarField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StarField.h; sourceTree = "<group>"; };
503C6D051268F49F00B66E3B /* StatsAndAchievements.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StatsAndAchievements.cpp; sourceTree = "<group>"; };
503C6D061268F49F00B66E3B /* StatsAndAchievements.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StatsAndAchievements.h; sourceTree = "<group>"; };
503C6D071268F49F00B66E3B /* stdafx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stdafx.cpp; sourceTree = "<group>"; };
503C6D081268F49F00B66E3B /* stdafx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stdafx.h; sourceTree = "<group>"; };
503C6D091268F49F00B66E3B /* Sun.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Sun.cpp; sourceTree = "<group>"; };
503C6D0A1268F49F00B66E3B /* Sun.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Sun.h; sourceTree = "<group>"; };
503C6D0B1268F49F00B66E3B /* VectorEntity.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VectorEntity.cpp; sourceTree = "<group>"; };
503C6D0C1268F49F00B66E3B /* VectorEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VectorEntity.h; sourceTree = "<group>"; };
503C6D0D1268F49F00B66E3B /* voicechat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = voicechat.cpp; sourceTree = "<group>"; };
503C6D0E1268F49F00B66E3B /* voicechat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = voicechat.h; sourceTree = "<group>"; };
503C6DAA1268FE1000B66E3B /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = System/Library/Frameworks/OpenAL.framework; sourceTree = SDKROOT; };
503C6DAB1268FE1000B66E3B /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
503C6DB31269002800B66E3B /* libsteam_api.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsteam_api.dylib; path = /Users/joer/Source/Steam3/main/src/lib/osx32/release/libsteam_api.dylib; sourceTree = "<absolute>"; };
504EDCB4126900D600F96D63 /* steamworksexample-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "steamworksexample-Info.plist"; path = "osx/steamworksexample-Info.plist"; sourceTree = "<group>"; };
504EDCC01269025A00F96D63 /* steam_appid.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = steam_appid.txt; path = osx/steam_appid.txt; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
503C6CAF1268F34200B66E3B /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
503C6DB41269002800B66E3B /* libsteam_api.dylib in Frameworks */,
503C6DAC1268FE1000B66E3B /* OpenAL.framework in Frameworks */,
503C6DAD1268FE1000B66E3B /* OpenGL.framework in Frameworks */,
503C6CB61268F34200B66E3B /* Cocoa.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
503C6CA31268F34200B66E3B = {
isa = PBXGroup;
children = (
503C6DAA1268FE1000B66E3B /* OpenAL.framework */,
503C6DAB1268FE1000B66E3B /* OpenGL.framework */,
503C6D291268F4EE00B66E3B /* Headers */,
503C6CAB1268F34200B66E3B /* Source */,
503C6CAC1268F34200B66E3B /* Resources */,
503C6CAD1268F34200B66E3B /* Frameworks */,
503C6CB31268F34200B66E3B /* Products */,
);
sourceTree = "<group>";
};
503C6CAB1268F34200B66E3B /* Source */ = {
isa = PBXGroup;
children = (
503C6CED1268F49F00B66E3B /* p2pauth.cpp */,
503C6CEF1268F49F00B66E3B /* PhotonBeam.cpp */,
503C6CF11268F49F00B66E3B /* QuitMenu.cpp */,
503C6CF31268F49F00B66E3B /* RemoteStorage.cpp */,
503C6CF51268F49F00B66E3B /* ServerBrowser.cpp */,
503C6CF81268F49F00B66E3B /* Ship.cpp */,
503C6CFB1268F49F00B66E3B /* SpaceWarClient.cpp */,
503C6CFD1268F49F00B66E3B /* SpaceWarEntity.cpp */,
503C6D011268F49F00B66E3B /* SpaceWarServer.cpp */,
503C6D031268F49F00B66E3B /* StarField.cpp */,
503C6D051268F49F00B66E3B /* StatsAndAchievements.cpp */,
503C6D071268F49F00B66E3B /* stdafx.cpp */,
503C6D091268F49F00B66E3B /* Sun.cpp */,
503C6D0B1268F49F00B66E3B /* VectorEntity.cpp */,
503C6D0D1268F49F00B66E3B /* voicechat.cpp */,
503C6CD91268F49F00B66E3B /* BaseMenu.cpp */,
503C6CDB1268F49F00B66E3B /* connectingmenu.cpp */,
503C6CE01268F49F00B66E3B /* gameengineosx.mm */,
503C6CE21268F49F00B66E3B /* glstringosx.mm */,
503C6CE31268F49F00B66E3B /* Leaderboards.cpp */,
503C6CE51268F49F00B66E3B /* Lobby.cpp */,
503C6CE71268F49F00B66E3B /* Main.cpp */,
503C6CE81268F49F00B66E3B /* MainMenu.cpp */,
);
name = Source;
sourceTree = "<group>";
};
503C6CAC1268F34200B66E3B /* Resources */ = {
isa = PBXGroup;
children = (
504EDCC01269025A00F96D63 /* steam_appid.txt */,
504EDCB4126900D600F96D63 /* steamworksexample-Info.plist */,
);
name = Resources;
sourceTree = "<group>";
};
503C6CAD1268F34200B66E3B /* Frameworks */ = {
isa = PBXGroup;
children = (
503C6DB31269002800B66E3B /* libsteam_api.dylib */,
503C6CB51268F34200B66E3B /* Cocoa.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
503C6CB31268F34200B66E3B /* Products */ = {
isa = PBXGroup;
children = (
503C6CB21268F34200B66E3B /* steamworksexample.app */,
);
name = Products;
sourceTree = "<group>";
};
503C6D291268F4EE00B66E3B /* Headers */ = {
isa = PBXGroup;
children = (
503C6CEE1268F49F00B66E3B /* p2pauth.h */,
503C6CF01268F49F00B66E3B /* PhotonBeam.h */,
503C6CF21268F49F00B66E3B /* QuitMenu.h */,
503C6CF41268F49F00B66E3B /* RemoteStorage.h */,
503C6CF61268F49F00B66E3B /* ServerBrowser.h */,
503C6CF71268F49F00B66E3B /* ServerBrowserMenu.h */,
503C6CF91268F49F00B66E3B /* Ship.h */,
503C6CFA1268F49F00B66E3B /* SpaceWar.h */,
503C6CFC1268F49F00B66E3B /* SpaceWarClient.h */,
503C6CFE1268F49F00B66E3B /* SpaceWarEntity.h */,
503C6CFF1268F49F00B66E3B /* SpaceWarRes.h */,
503C6D021268F49F00B66E3B /* SpaceWarServer.h */,
503C6D041268F49F00B66E3B /* StarField.h */,
503C6D061268F49F00B66E3B /* StatsAndAchievements.h */,
503C6D081268F49F00B66E3B /* stdafx.h */,
503C6D0A1268F49F00B66E3B /* Sun.h */,
503C6D0C1268F49F00B66E3B /* VectorEntity.h */,
503C6D0E1268F49F00B66E3B /* voicechat.h */,
503C6CDA1268F49F00B66E3B /* BaseMenu.h */,
503C6CDC1268F49F00B66E3B /* connectingmenu.h */,
503C6CDD1268F49F00B66E3B /* GameEngine.h */,
503C6CDF1268F49F00B66E3B /* gameengineosx.h */,
503C6CE11268F49F00B66E3B /* glstringosx.h */,
503C6CE41268F49F00B66E3B /* Leaderboards.h */,
503C6CE61268F49F00B66E3B /* Lobby.h */,
503C6CE91268F49F00B66E3B /* MainMenu.h */,
503C6CEA1268F49F00B66E3B /* Messages.h */,
);
name = Headers;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
503C6CB11268F34200B66E3B /* steamworksexample */ = {
isa = PBXNativeTarget;
buildConfigurationList = 503C6CC91268F34200B66E3B /* Build configuration list for PBXNativeTarget "steamworksexample" */;
buildPhases = (
503C6CAE1268F34200B66E3B /* Sources */,
503C6CAF1268F34200B66E3B /* Frameworks */,
503C6CB01268F34200B66E3B /* Resources */,
504EDCBB126901D200F96D63 /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = steamworksexample;
productName = steamworksexample;
productReference = 503C6CB21268F34200B66E3B /* steamworksexample.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
503C6CA51268F34200B66E3B /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 503C6CA81268F34200B66E3B /* Build configuration list for PBXProject "steamworksexample" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 503C6CA31268F34200B66E3B;
productRefGroup = 503C6CB31268F34200B66E3B /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
503C6CB11268F34200B66E3B /* steamworksexample */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
503C6CB01268F34200B66E3B /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
503C6CAE1268F34200B66E3B /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
503C6D0F1268F49F00B66E3B /* BaseMenu.cpp in Sources */,
503C6D101268F49F00B66E3B /* connectingmenu.cpp in Sources */,
503C6D121268F49F00B66E3B /* gameengineosx.mm in Sources */,
503C6D131268F49F00B66E3B /* glstringosx.mm in Sources */,
503C6D141268F49F00B66E3B /* Leaderboards.cpp in Sources */,
503C6D151268F49F00B66E3B /* Lobby.cpp in Sources */,
503C6D161268F49F00B66E3B /* Main.cpp in Sources */,
503C6D171268F49F00B66E3B /* MainMenu.cpp in Sources */,
503C6D191268F49F00B66E3B /* p2pauth.cpp in Sources */,
503C6D1A1268F49F00B66E3B /* PhotonBeam.cpp in Sources */,
503C6D1B1268F49F00B66E3B /* QuitMenu.cpp in Sources */,
503C6D1C1268F49F00B66E3B /* RemoteStorage.cpp in Sources */,
503C6D1D1268F49F00B66E3B /* ServerBrowser.cpp in Sources */,
503C6D1E1268F49F00B66E3B /* Ship.cpp in Sources */,
503C6D1F1268F49F00B66E3B /* SpaceWarClient.cpp in Sources */,
503C6D201268F49F00B66E3B /* SpaceWarEntity.cpp in Sources */,
503C6D221268F49F00B66E3B /* SpaceWarServer.cpp in Sources */,
503C6D231268F49F00B66E3B /* StarField.cpp in Sources */,
503C6D241268F49F00B66E3B /* StatsAndAchievements.cpp in Sources */,
503C6D251268F49F00B66E3B /* stdafx.cpp in Sources */,
503C6D261268F49F00B66E3B /* Sun.cpp in Sources */,
503C6D271268F49F00B66E3B /* VectorEntity.cpp in Sources */,
503C6D281268F49F00B66E3B /* voicechat.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
503C6CC71268F34200B66E3B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = DEBUG;
"GCC_PREPROCESSOR_DEFINITIONS[arch=*]" = (
POSIX,
OSX,
);
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.5;
ONLY_ACTIVE_ARCH = YES;
PREBINDING = NO;
SDKROOT = macosx10.5;
USER_HEADER_SEARCH_PATHS = ../public;
};
name = Debug;
};
503C6CC81268F34200B66E3B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
GCC_C_LANGUAGE_STANDARD = gnu99;
"GCC_PREPROCESSOR_DEFINITIONS[arch=*]" = (
POSIX,
OSX,
);
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.5;
PREBINDING = NO;
SDKROOT = macosx10.5;
USER_HEADER_SEARCH_PATHS = ../public;
};
name = Release;
};
503C6CCA1268F34200B66E3B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_MODEL_TUNING = G5;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
INFOPLIST_FILE = "osx/steamworksexample-Info.plist";
INSTALL_PATH = "$(HOME)/Applications";
LIBRARY_SEARCH_PATHS = (
../lib/osx32/release,
"\"$(SRCROOT)/../lib/osx32/release\"",
../redistributable_bin/osx32/,
);
PRODUCT_NAME = steamworksexample;
WRAPPER_EXTENSION = app;
};
name = Debug;
};
503C6CCB1268F34200B66E3B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
COPY_PHASE_STRIP = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_MODEL_TUNING = G5;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "";
INFOPLIST_FILE = "osx/steamworksexample-Info.plist";
INSTALL_PATH = "$(HOME)/Applications";
LIBRARY_SEARCH_PATHS = (
../lib/osx32/debug,
"\"$(SRCROOT)/../lib/osx32/release\"",
../redistributable_bin/osx32/,
);
PRODUCT_NAME = steamworksexample;
WRAPPER_EXTENSION = app;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
503C6CA81268F34200B66E3B /* Build configuration list for PBXProject "steamworksexample" */ = {
isa = XCConfigurationList;
buildConfigurations = (
503C6CC71268F34200B66E3B /* Debug */,
503C6CC81268F34200B66E3B /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
503C6CC91268F34200B66E3B /* Build configuration list for PBXNativeTarget "steamworksexample" */ = {
isa = XCConfigurationList;
buildConfigurations = (
503C6CCA1268F34200B66E3B /* Debug */,
503C6CCB1268F34200B66E3B /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 503C6CA51268F34200B66E3B /* Project object */;
}
+355
View File
@@ -0,0 +1,355 @@
//========= Copyright © 1996-2010, Valve LLC, All rights reserved. ============
//
// Purpose:Class for P2P voice chat
//
// $NoKeywords: $
//=============================================================================
#include "stdafx.h"
#include "voicechat.h"
CVoiceChat::CVoiceChat( IGameEngine *pGameEngine ) :
m_CallbackP2PSessionRequest( this, &CVoiceChat::OnP2PSessionRequest ),
m_CallbackP2PSessionConnectFail( this, &CVoiceChat::OnP2PSessionConnectFail )
{
m_pGameEngine = pGameEngine;
m_bIsActive = false;
m_ulLastTimeTalked = 0;
m_hVoiceLoopback = 0;
}
CVoiceChat::~CVoiceChat()
{
m_pGameEngine = NULL;
}
//-----------------------------------------------------------------------------
// Purpose: another user has sent us a packet - do we accept?
//-----------------------------------------------------------------------------
void CVoiceChat::OnP2PSessionRequest( P2PSessionRequest_t *pP2PSessionRequest )
{
std::map< uint64, VoiceChatConnection_t >::iterator iter;
iter = m_MapConnections.find( pP2PSessionRequest->m_steamIDRemote.ConvertToUint64() );
if ( iter != m_MapConnections.end() )
{
// we play with this user
iter->second.eLastError = k_EP2PSessionErrorNone; // our connection is now working
// the packet itself will come through when you call SteamNetworking()->ReadP2PPacket()
SteamNetworking()->AcceptP2PSessionWithUser( pP2PSessionRequest->m_steamIDRemote );
}
}
//-----------------------------------------------------------------------------
// Purpose: we send a packet to another user but it failed
//-----------------------------------------------------------------------------
void CVoiceChat::OnP2PSessionConnectFail( P2PSessionConnectFail_t *pP2PSessionConnectFail )
{
std::map< uint64, VoiceChatConnection_t >::iterator iter;
iter = m_MapConnections.find( pP2PSessionConnectFail->m_steamIDRemote.ConvertToUint64() );
if ( iter != m_MapConnections.end() )
{
// connection to that user failed
iter->second.eLastError = (EP2PSessionError) pP2PSessionConnectFail->m_eP2PSessionError;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CVoiceChat::RunFrame()
{
if ( m_bIsActive )
{
// read local microphone input
uint32 nBytesAvalaible = 0;
EVoiceResult res = SteamUser()->GetAvailableVoice( &nBytesAvalaible, NULL );
if ( res == k_EVoiceResultOK && nBytesAvalaible > 0 )
{
uint32 nBytesWritten = 0;
MsgVoiceChatData_t msg;
// don't send more then 1 KB at a time
uint8 buffer[ 1024+sizeof(msg) ];
res = SteamUser()->GetVoice( true, buffer+sizeof(msg), 1024, &nBytesWritten, false, NULL, 0, NULL );
if ( res == k_EVoiceResultOK && nBytesWritten > 0 )
{
// assemble message
msg.SetDataLength( nBytesWritten );
memcpy( buffer, &msg, sizeof(msg) );
SendMessageToAll( buffer, sizeof(msg)+nBytesWritten );
m_ulLastTimeTalked = m_pGameEngine->GetGameTickCount();
// if local voice loopback is enabled, play it back now
if ( m_hVoiceLoopback != 0 )
{
// Uncompress the voice data, buffer holds up to 1 second of data
uint32 numUncompressedBytes = 0;
const uint8* pVoiceData = (const uint8*) buffer;
pVoiceData += sizeof(MsgVoiceChatData_t);
EVoiceResult res = SteamUser()->DecompressVoice( pVoiceData , nBytesWritten,
m_ubUncompressedVoice, sizeof( m_ubUncompressedVoice ), &numUncompressedBytes );
if ( res == k_EVoiceResultOK && numUncompressedBytes > 0 )
{
m_pGameEngine->AddVoiceData( m_hVoiceLoopback, m_ubUncompressedVoice, numUncompressedBytes );
}
}
}
}
CheckConnections();
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CVoiceChat::HandleMessage( CSteamID fromSteamID, EMessage eMsg, const void *pMessage )
{
if ( eMsg != k_EMsgVoiceChatPing && eMsg != k_EMsgVoiceChatData )
return false; // we don't handle these messages
std::map< uint64, VoiceChatConnection_t >::iterator iter;
iter = m_MapConnections.find( fromSteamID.ConvertToUint64() );
if ( iter != m_MapConnections.end() )
{
VoiceChatConnection_t &chatClient = iter->second;
chatClient.eLastError = k_EP2PSessionErrorNone; // our connection is working
if ( eMsg == k_EMsgVoiceChatData )
{
const MsgVoiceChatData_t *pMsgVoiceData = (const MsgVoiceChatData_t *) pMessage;
chatClient.ulLastReceiveVoiceTime = m_pGameEngine->GetGameTickCount();
// Uncompress the voice data, buffer holds up to 1 second of data
uint8 pbUncompressedVoice[ VOICE_OUTPUT_SAMPLE_RATE * BYTES_PER_SAMPLE ];
uint32 numUncompressedBytes = 0;
const uint8* pVoiceData = (const uint8*) pMessage;
pVoiceData += sizeof(MsgVoiceChatData_t);
EVoiceResult res = SteamUser()->DecompressVoice( pVoiceData , pMsgVoiceData->GetDataLength(),
pbUncompressedVoice, sizeof( pbUncompressedVoice ), &numUncompressedBytes );
if ( res == k_EVoiceResultOK && numUncompressedBytes > 0 )
{
// play it again Sam
if ( chatClient.hVoiceChannel == 0 )
{
chatClient.hVoiceChannel = m_pGameEngine->HCreateVoiceChannel();
}
m_pGameEngine->AddVoiceData( chatClient.hVoiceChannel, pbUncompressedVoice, numUncompressedBytes );
}
}
}
return true;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CVoiceChat::MarkAllPlayersInactive()
{
std::map< uint64, VoiceChatConnection_t >::iterator iter;
for( iter = m_MapConnections.begin(); iter != m_MapConnections.end(); ++iter )
{
iter->second.bActive = false;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CVoiceChat::MarkPlayerAsActive( CSteamID steamID )
{
if ( !m_bIsActive )
return;
if ( m_SteamIDLocalUser == steamID )
return;
std::map< uint64, VoiceChatConnection_t >::iterator iter;
iter = m_MapConnections.find( steamID.ConvertToUint64() );
if ( iter != m_MapConnections.end() )
{
// player already has a session object, no new object created
iter->second.bActive = true;
return;
}
/*char szText[100];
_snprintf(szText, 100, "CVoiceChat::AddPlayerToSession: %s.\n", SteamFriends()->GetFriendPersonaName( steamID ) );
OutputDebugString( szText ); */
VoiceChatConnection_t session;
session.eLastError = k_EP2PSessionErrorTimeout;
session.ulLastReceiveVoiceTime = 0;
session.ulLastSentTime = 0;
session.hVoiceChannel = 0;
session.bActive = true;
m_MapConnections[ steamID.ConvertToUint64() ] = session;
return;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CVoiceChat::IsPlayerTalking( CSteamID steamID )
{
if ( steamID == m_SteamIDLocalUser )
{
// thats ourself
if ( m_ulLastTimeTalked + 250 > m_pGameEngine->GetGameTickCount() )
return true;
}
else
{
std::map< uint64, VoiceChatConnection_t >::iterator iter;
iter = m_MapConnections.find( steamID.ConvertToUint64() );
if ( iter != m_MapConnections.end() )
{
if ( iter->second.eLastError == k_EP2PSessionErrorNone )
{
if ( (iter->second.ulLastReceiveVoiceTime + 250) > m_pGameEngine->GetGameTickCount() )
{
// user talked less then 250msec ago, assume still active
return true;
}
}
}
}
return false;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CVoiceChat::StartVoiceChat()
{
if ( !m_bIsActive )
{
m_SteamIDLocalUser = SteamUser()->GetSteamID();
SteamUser()->StartVoiceRecording();
m_bIsActive = true;
// here you can enable optional local voice loopback:
// m_hVoiceLoopback = m_pGameEngine->HCreateVoiceChannel();
}
return true;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CVoiceChat::StopVoiceChat()
{
if ( m_bIsActive )
{
std::map< uint64, VoiceChatConnection_t >::iterator iter;
for( iter = m_MapConnections.begin(); iter != m_MapConnections.end(); ++iter )
{
CSteamID steamID( iter->first );
m_pGameEngine->DestroyVoiceChannel( iter->second.hVoiceChannel );
SteamNetworking()->CloseP2PSessionWithUser( steamID );
}
m_MapConnections.clear();
if ( m_hVoiceLoopback )
{
m_pGameEngine->DestroyVoiceChannel( m_hVoiceLoopback );
m_hVoiceLoopback = 0;
}
SteamUser()->StopVoiceRecording();
m_bIsActive = false;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CVoiceChat::CheckConnections()
{
const uint64 ulTimeNow = m_pGameEngine->GetGameTickCount();
const uint64 ulTimeoutLimit = 10 * 1000; // 10 seconds
//
std::map< uint64, VoiceChatConnection_t >::iterator iter;
for( iter = m_MapConnections.begin(); iter != m_MapConnections.end(); ++iter )
{
if ( iter->second.bActive )
{
const EP2PSessionError eLastError = iter->second.eLastError;
CSteamID steamID( iter->first );
if ( eLastError == k_EP2PSessionErrorNone || eLastError == k_EP2PSessionErrorTimeout )
{
if ( iter->second.ulLastSentTime + ulTimeoutLimit < ulTimeNow )
{
// time for a ping
MsgVoiceChatPing_t msg;
SteamNetworking()->SendP2PPacket( steamID, &msg, sizeof(msg), k_EP2PSendUnreliable );
iter->second.ulLastSentTime = ulTimeNow;
}
}
}
else
{
// found inactive connection, destroy
CSteamID steamID( iter->first );
SteamNetworking()->CloseP2PSessionWithUser( steamID );
m_pGameEngine->DestroyVoiceChannel( iter->second.hVoiceChannel );
m_MapConnections.erase( iter );
break; // break since the iterator became bad
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CVoiceChat::SendMessageToAll( const void *pubData, uint32 cubData )
{
const uint64 ulTimeNow = m_pGameEngine->GetGameTickCount();
//
std::map< uint64, VoiceChatConnection_t >::iterator iter;
for( iter = m_MapConnections.begin(); iter != m_MapConnections.end(); ++iter )
{
const EP2PSessionError eLastError = iter->second.eLastError;
CSteamID steamID( iter->first );
if ( eLastError == k_EP2PSessionErrorNone )
{
SteamNetworking()->SendP2PPacket( steamID, pubData, cubData, k_EP2PSendUnreliableNoDelay );
iter->second.ulLastSentTime = ulTimeNow;
}
}
}
+65
View File
@@ -0,0 +1,65 @@
//========= Copyright © 1996-2010, Valve LLC, All rights reserved. ============
//
// Purpose: Class for P2P voice chat
//
// $NoKeywords: $
//=============================================================================
#ifndef VOICE_CHAT_H
#define VOICE_CHAT_H
#include "GameEngine.h"
#include "SpaceWar.h"
#include "Messages.h"
typedef struct VoiceChatConnection_s
{
EP2PSessionError eLastError; // ErrorNone means we have a session
uint64 ulLastReceiveVoiceTime;
uint64 ulLastSentTime;
HGAMEVOICECHANNEL hVoiceChannel; // engine voice channel for this player
bool bActive;
} VoiceChatConnection_t;
class CVoiceChat
{
public:
CVoiceChat( IGameEngine *pGameEngine );
~CVoiceChat();
bool StartVoiceChat();
void StopVoiceChat();
// chat control
void MarkAllPlayersInactive();
void MarkPlayerAsActive( CSteamID steamID );
bool IsPlayerTalking( CSteamID steamID );
// chat engine
void RunFrame();
bool HandleMessage( CSteamID fromSteamID, EMessage eMsg, const void *pMessage );
void SendMessageToAll( const void *pubData, uint32 cubData );
private:
STEAM_CALLBACK( CVoiceChat, OnP2PSessionRequest, P2PSessionRequest_t, m_CallbackP2PSessionRequest );
STEAM_CALLBACK( CVoiceChat, OnP2PSessionConnectFail, P2PSessionConnectFail_t, m_CallbackP2PSessionConnectFail );
void CheckConnections();
// Pointer to engine instance (so we can play sound)
IGameEngine *m_pGameEngine;
// map of voice chat sessions with other players
std::map< uint64, VoiceChatConnection_t > m_MapConnections;
CSteamID m_SteamIDLocalUser; // ourself
bool m_bIsActive; // is voice chat system active
uint64 m_ulLastTimeTalked; // last time we've talked ourself
HGAMEVOICECHANNEL m_hVoiceLoopback;
uint8 m_ubUncompressedVoice[ VOICE_OUTPUT_SAMPLE_RATE * BYTES_PER_SAMPLE ]; // too big for the stack
};
#endif
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,5 +1,10 @@
"InstallScript"
{
// Install scripts on the Gold Master are only necessary for Games for Windows titles.
// Otherwise this file doesn't need to be shipped on the GM and the Steam client
// will run the install script shipped with your depots at a later point
"Run Process"
{
"VCRedist"
Binary file not shown.