diff options
Diffstat (limited to 'common/xbox/xbox_launch.h')
| -rw-r--r-- | common/xbox/xbox_launch.h | 295 |
1 files changed, 295 insertions, 0 deletions
diff --git a/common/xbox/xbox_launch.h b/common/xbox/xbox_launch.h new file mode 100644 index 0000000..a0a9e66 --- /dev/null +++ b/common/xbox/xbox_launch.h @@ -0,0 +1,295 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Xbox Launch Routines. +// +//=====================================================================================// + +#ifndef _XBOX_LAUNCH_H_ +#define _XBOX_LAUNCH_H_ + +#pragma once + +#ifndef _CERT +#pragma comment( lib, "xbdm.lib" ) +#endif + +// id and version are used to tag the data blob, currently only need a singe hardcoded id +// when the version and id don't match, the data blob is not ours +#define VALVE_LAUNCH_ID (('V'<<24)|('A'<<16)|('L'<<8)|('V'<<0)) +#define VALVE_LAUNCH_VERSION 1 + +// launch flags +#define LF_ISDEBUGGING 0x80000000 // set if session was active prior to launch +#define LF_INTERNALLAUNCH 0x00000001 // set if launch was internal (as opposed to dashboard) +#define LF_EXITFROMINSTALLER 0x00000002 // set if exit was from an installer +#define LF_EXITFROMGAME 0x00000004 // set if exit was from a game +#define LF_EXITFROMCHOOSER 0x00000008 // set if exit was from the chooser +#define LF_GAMERESTART 0x00000010 // set if game wants to restart self (skips appchooser) +#define LF_INVITERESTART 0x00000020 // set if game was invited from another app (launches TF and fires off session connect) + +#pragma pack(1) +struct launchHeader_t +{ + unsigned int id; + unsigned int version; + unsigned int flags; + + int nStorageID; + int nUserID; + int bForceEnglish; + XNKID nInviteSessionID; + + // for caller defined data, occurs after this header + // limited to slightly less than MAX_LAUNCH_DATA_SIZE + unsigned int nDataSize; +}; +#pragma pack() + +// per docs, no larger than MAX_LAUNCH_DATA_SIZE +union xboxLaunchData_t +{ + launchHeader_t header; + char data[MAX_LAUNCH_DATA_SIZE]; +}; + +//-------------------------------------------------------------------------------------- +// Simple class to wrap the peristsent launch payload. +// +// Can be used by an application that does not use tier0 (i.e. the launcher). +// Primarily designed to be anchored in tier0, so multiple systems can easily query and +// set the persistent payload. +//-------------------------------------------------------------------------------------- +class CXboxLaunch +{ +public: + CXboxLaunch() + { + ResetLaunchData(); + } + + void ResetLaunchData() + { + // invalid until established + // nonzero identifies a valid payload + m_LaunchDataSize = 0; + + m_Launch.header.id = 0; + m_Launch.header.version = 0; + m_Launch.header.flags = 0; + + m_Launch.header.nStorageID = XBX_INVALID_STORAGE_ID; + m_Launch.header.nUserID = XBX_INVALID_USER_ID; + m_Launch.header.bForceEnglish = false; + + memset( &m_Launch.header.nInviteSessionID, 0, sizeof( m_Launch.header.nInviteSessionID ) ); + + m_Launch.header.nDataSize = 0; + } + + // Returns how much space can be used by caller + int MaxPayloadSize() + { + return sizeof( xboxLaunchData_t ) - sizeof( launchHeader_t ); + } + + bool SetLaunchData( void *pData, int dataSize, int flags = 0 ) + { + if ( pData && dataSize && dataSize > MaxPayloadSize() ) + { + // not enough room + return false; + } + + if ( pData && dataSize && dataSize <= MaxPayloadSize() ) + { + memcpy( m_Launch.data + sizeof( launchHeader_t ), pData, dataSize ); + m_Launch.header.nDataSize = dataSize; + } + else + { + m_Launch.header.nDataSize = 0; + } + + flags |= LF_INTERNALLAUNCH; +#if !defined( _CERT ) + if ( DmIsDebuggerPresent() ) + { + flags |= LF_ISDEBUGGING; + } +#endif + m_Launch.header.id = VALVE_LAUNCH_ID; + m_Launch.header.version = VALVE_LAUNCH_VERSION; + m_Launch.header.flags = flags; + + XSetLaunchData( &m_Launch, MAX_LAUNCH_DATA_SIZE ); + + // assume successful, mark as valid + m_LaunchDataSize = MAX_LAUNCH_DATA_SIZE; + + return true; + } + + //-------------------------------------------------------------------------------------- + // Returns TRUE if the launch data blob is available. FALSE otherwise. + // Caller is expected to validate and interpret contents based on ID. + //-------------------------------------------------------------------------------------- + bool GetLaunchData( unsigned int *pID, void **pData, int *pDataSize ) + { + if ( !m_LaunchDataSize ) + { + // purposely not doing this in the constructor (unstable as used by tier0), but on first fetch + bool bValid = false; + DWORD dwLaunchDataSize; + DWORD dwStatus = XGetLaunchDataSize( &dwLaunchDataSize ); + if ( dwStatus == ERROR_SUCCESS && dwLaunchDataSize <= MAX_LAUNCH_DATA_SIZE ) + { + dwStatus = XGetLaunchData( (void*)&m_Launch, dwLaunchDataSize ); + if ( dwStatus == ERROR_SUCCESS ) + { + bValid = true; + m_LaunchDataSize = dwLaunchDataSize; + } + } + + if ( !bValid ) + { + ResetLaunchData(); + } + } + + // a valid launch payload could be ours (re-launch) or from an alternate booter (demo launcher) + if ( m_LaunchDataSize == MAX_LAUNCH_DATA_SIZE && m_Launch.header.id == VALVE_LAUNCH_ID && m_Launch.header.version == VALVE_LAUNCH_VERSION ) + { + // internal recognized format + if ( pID ) + { + *pID = m_Launch.header.id; + } + if ( pData ) + { + *pData = m_Launch.data + sizeof( launchHeader_t ); + } + if ( pDataSize ) + { + *pDataSize = m_Launch.header.nDataSize; + } + } + else if ( m_LaunchDataSize ) + { + // not ours, unknown format, caller interprets + if ( pID ) + { + // assume payload was packaged with an initial ID + *pID = *(unsigned int *)m_Launch.data; + } + if ( pData ) + { + *pData = m_Launch.data; + } + if ( pDataSize ) + { + *pDataSize = m_LaunchDataSize; + } + } + + // valid when data is available (not necessarily valve's tag) + return m_LaunchDataSize != 0; + } + + //-------------------------------------------------------------------------------------- + // Returns TRUE if the launch data blob is available. FALSE otherwise. + // Data blob could be ours or not. + //-------------------------------------------------------------------------------------- + bool RestoreLaunchData() + { + return GetLaunchData( NULL, NULL, NULL ); + } + + //-------------------------------------------------------------------------------------- + // Restores the data blob. If the data blob is not ours, resets it. + //-------------------------------------------------------------------------------------- + void RestoreOrResetLaunchData() + { + RestoreLaunchData(); + if ( m_Launch.header.id != VALVE_LAUNCH_ID || m_Launch.header.version != VALVE_LAUNCH_VERSION ) + { + // not interested in somebody else's data + ResetLaunchData(); + } + } + + //-------------------------------------------------------------------------------------- + // Returns OUR internal launch flags. + //-------------------------------------------------------------------------------------- + int GetLaunchFlags() + { + // establish the data + RestoreOrResetLaunchData(); + return m_Launch.header.flags; + } + + int GetStorageID( void ) + { + RestoreOrResetLaunchData(); + return m_Launch.header.nStorageID; + } + void SetStorageID( int storageID ) + { + RestoreOrResetLaunchData(); + m_Launch.header.nStorageID = storageID; + } + + int GetUserID( void ) + { + RestoreOrResetLaunchData(); + return m_Launch.header.nUserID; + } + void SetUserID( int userID ) + { + RestoreOrResetLaunchData(); + m_Launch.header.nUserID = userID; + } + + bool GetForceEnglish( void ) + { + RestoreOrResetLaunchData(); + return m_Launch.header.bForceEnglish ? true : false; + } + void SetForceEnglish( bool bForceEnglish ) + { + RestoreOrResetLaunchData(); + m_Launch.header.bForceEnglish = bForceEnglish; + } + + void GetInviteSessionID( XNKID *pSessionID ) + { + RestoreOrResetLaunchData(); + *pSessionID = m_Launch.header.nInviteSessionID; + } + void SetInviteSessionID( XNKID *pSessionID ) + { + RestoreOrResetLaunchData(); + m_Launch.header.nInviteSessionID = *pSessionID; + } + + void Launch( const char *pNewImageName = NULL ) + { + if ( !pNewImageName ) + { + pNewImageName = "default.xex"; + } + + XLaunchNewImage( pNewImageName, 0 ); + } + +private: + xboxLaunchData_t m_Launch; + DWORD m_LaunchDataSize; +}; + +#if defined( PLATFORM_H ) +// For applications that use tier0.dll +PLATFORM_INTERFACE CXboxLaunch *XboxLaunch(); +#endif + +#endif |