Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

451 lines
11 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Xbox Launch Routines.
  4. //
  5. //=====================================================================================//
  6. #ifndef _XBOX_LAUNCH_H_
  7. #define _XBOX_LAUNCH_H_
  8. #pragma once
  9. #ifndef _CERT
  10. #pragma comment( lib, "xbdm.lib" )
  11. #endif
  12. // id and version are used to tag the data blob, currently only need a singe hardcoded id
  13. // when the version and id don't match, the data blob is not ours
  14. #define VALVE_LAUNCH_ID (('V'<<24)|('A'<<16)|('L'<<8)|('V'<<0))
  15. #define VALVE_LAUNCH_VERSION 1
  16. // launch flags
  17. #define LF_ISDEBUGGING 0x80000000 // set if session was active prior to launch
  18. #define LF_INTERNALLAUNCH 0x00000001 // set if launch was internal (as opposed to dashboard)
  19. #define LF_EXITFROMINSTALLER 0x00000002 // set if exit was from an installer
  20. #define LF_EXITFROMGAME 0x00000004 // set if exit was from a game
  21. #define LF_EXITFROMCHOOSER 0x00000008 // set if exit was from the chooser
  22. #define LF_WARMRESTART 0x00000010 // set if game wants to restart self (skips intro movies)
  23. #define LF_INSTALLEDTOCACHE 0x00000040 // set if installer populated or validated cache partition
  24. #define LF_UNKNOWNDATA 0x00000080
  25. #pragma pack(1)
  26. struct launchHeader_t
  27. {
  28. unsigned int id;
  29. unsigned int version;
  30. unsigned int flags;
  31. int nUserID;
  32. int nCtrlr2Storage[4];
  33. char nSlot2Ctrlr[4];
  34. char nSlot2Guest[4];
  35. int numGameUsers;
  36. int bForceEnglish;
  37. // increments at each engine re-launch
  38. DWORD nAttractID;
  39. // for caller defined data, occurs after this header
  40. // limited to slightly less than MAX_LAUNCH_DATA_SIZE
  41. unsigned int nDataSize;
  42. };
  43. #pragma pack()
  44. // per docs, no larger than MAX_LAUNCH_DATA_SIZE
  45. union xboxLaunchData_t
  46. {
  47. launchHeader_t header;
  48. char data[MAX_LAUNCH_DATA_SIZE];
  49. };
  50. //--------------------------------------------------------------------------------------
  51. // Simple class to wrap the peristsent launch payload.
  52. //
  53. // Can be used by an application that does not use tier0 (i.e. the launcher).
  54. // Primarily designed to be anchored in tier0, so multiple systems can easily query and
  55. // set the persistent payload.
  56. //--------------------------------------------------------------------------------------
  57. class CXboxLaunch
  58. {
  59. public:
  60. CXboxLaunch()
  61. {
  62. ResetLaunchData();
  63. }
  64. void ResetLaunchData()
  65. {
  66. // invalid until established
  67. // nonzero identifies a valid payload
  68. m_LaunchDataSize = 0;
  69. m_Launch.header.id = 0;
  70. m_Launch.header.version = 0;
  71. m_Launch.header.flags = 0;
  72. m_Launch.header.nUserID = XBX_INVALID_USER_ID;
  73. m_Launch.header.bForceEnglish = false;
  74. m_Launch.header.nCtrlr2Storage[0] = XBX_INVALID_STORAGE_ID;
  75. m_Launch.header.nCtrlr2Storage[1] = XBX_INVALID_STORAGE_ID;
  76. m_Launch.header.nCtrlr2Storage[2] = XBX_INVALID_STORAGE_ID;
  77. m_Launch.header.nCtrlr2Storage[3] = XBX_INVALID_STORAGE_ID;
  78. m_Launch.header.nSlot2Ctrlr[0] = 0;
  79. m_Launch.header.nSlot2Ctrlr[1] = 1;
  80. m_Launch.header.nSlot2Ctrlr[2] = 2;
  81. m_Launch.header.nSlot2Ctrlr[3] = 3;
  82. m_Launch.header.nSlot2Guest[0] = 0;
  83. m_Launch.header.nSlot2Guest[1] = 0;
  84. m_Launch.header.nSlot2Guest[2] = 0;
  85. m_Launch.header.nSlot2Guest[3] = 0;
  86. m_Launch.header.numGameUsers = 0;
  87. m_Launch.header.nAttractID = 0;
  88. m_Launch.header.nDataSize = 0;
  89. }
  90. // Returns how much space can be used by caller
  91. int MaxPayloadSize()
  92. {
  93. return sizeof( xboxLaunchData_t ) - sizeof( launchHeader_t );
  94. }
  95. bool SetLaunchData( void *pData, int dataSize, int flags = 0 )
  96. {
  97. #if defined( _DEMO )
  98. if ( pData && ( flags & LF_UNKNOWNDATA ) )
  99. {
  100. // not ours, put the demo structure back as-is
  101. XSetLaunchData( pData, dataSize );
  102. m_LaunchDataSize = dataSize;
  103. return true;
  104. }
  105. #endif
  106. if ( pData && dataSize && dataSize > MaxPayloadSize() )
  107. {
  108. // not enough room
  109. return false;
  110. }
  111. if ( pData && dataSize && dataSize <= MaxPayloadSize() )
  112. {
  113. memcpy( m_Launch.data + sizeof( launchHeader_t ), pData, dataSize );
  114. m_Launch.header.nDataSize = dataSize;
  115. }
  116. else
  117. {
  118. m_Launch.header.nDataSize = 0;
  119. }
  120. flags |= LF_INTERNALLAUNCH;
  121. #if !defined( _CERT )
  122. if ( DmIsDebuggerPresent() )
  123. {
  124. flags |= LF_ISDEBUGGING;
  125. }
  126. #endif
  127. m_Launch.header.id = VALVE_LAUNCH_ID;
  128. m_Launch.header.version = VALVE_LAUNCH_VERSION;
  129. m_Launch.header.flags = flags;
  130. XSetLaunchData( &m_Launch, MAX_LAUNCH_DATA_SIZE );
  131. // assume successful, mark as valid
  132. m_LaunchDataSize = MAX_LAUNCH_DATA_SIZE;
  133. return true;
  134. }
  135. //--------------------------------------------------------------------------------------
  136. // Returns TRUE if the launch data blob is available. FALSE otherwise.
  137. // Caller is expected to validate and interpret contents based on ID.
  138. //--------------------------------------------------------------------------------------
  139. bool GetLaunchData( unsigned int *pID, void **pData, int *pDataSize )
  140. {
  141. if ( !m_LaunchDataSize )
  142. {
  143. // purposely not doing this in the constructor (unstable as used by tier0), but on first fetch
  144. bool bValid = false;
  145. DWORD dwLaunchDataSize;
  146. DWORD dwStatus = XGetLaunchDataSize( &dwLaunchDataSize );
  147. if ( dwStatus == ERROR_SUCCESS && dwLaunchDataSize <= MAX_LAUNCH_DATA_SIZE )
  148. {
  149. dwStatus = XGetLaunchData( (void*)&m_Launch, dwLaunchDataSize );
  150. if ( dwStatus == ERROR_SUCCESS )
  151. {
  152. bValid = true;
  153. m_LaunchDataSize = dwLaunchDataSize;
  154. }
  155. }
  156. if ( !bValid )
  157. {
  158. ResetLaunchData();
  159. }
  160. }
  161. // a valid launch payload could be ours (re-launch) or from an alternate booter (demo launcher)
  162. if ( m_LaunchDataSize == MAX_LAUNCH_DATA_SIZE && m_Launch.header.id == VALVE_LAUNCH_ID && m_Launch.header.version == VALVE_LAUNCH_VERSION )
  163. {
  164. // internal recognized format
  165. if ( pID )
  166. {
  167. *pID = m_Launch.header.id;
  168. }
  169. if ( pData )
  170. {
  171. *pData = m_Launch.data + sizeof( launchHeader_t );
  172. }
  173. if ( pDataSize )
  174. {
  175. *pDataSize = m_Launch.header.nDataSize;
  176. }
  177. }
  178. else if ( m_LaunchDataSize )
  179. {
  180. // not ours, unknown format, caller interprets
  181. if ( pID )
  182. {
  183. // assume payload was packaged with an initial ID
  184. *pID = *(unsigned int *)m_Launch.data;
  185. }
  186. if ( pData )
  187. {
  188. *pData = m_Launch.data;
  189. }
  190. if ( pDataSize )
  191. {
  192. *pDataSize = m_LaunchDataSize;
  193. }
  194. }
  195. else if ( !m_LaunchDataSize )
  196. {
  197. // mark for caller as all invalid
  198. if ( pID )
  199. {
  200. *pID = 0;
  201. }
  202. if ( pData )
  203. {
  204. *pData = NULL;
  205. }
  206. if ( pDataSize )
  207. {
  208. *pDataSize = 0;
  209. }
  210. }
  211. // valid when any data is available (not necessarily valve's tag)
  212. return ( m_LaunchDataSize != 0 );
  213. }
  214. //--------------------------------------------------------------------------------------
  215. // Returns TRUE if the launch data blob is available. FALSE otherwise.
  216. // Data blob could be ours or not.
  217. //--------------------------------------------------------------------------------------
  218. bool RestoreLaunchData()
  219. {
  220. return GetLaunchData( NULL, NULL, NULL );
  221. }
  222. //--------------------------------------------------------------------------------------
  223. // Restores the data blob. If the data blob is not ours, resets it.
  224. //--------------------------------------------------------------------------------------
  225. void RestoreOrResetLaunchData()
  226. {
  227. RestoreLaunchData();
  228. #if !defined( _DEMO )
  229. if ( m_Launch.header.id != VALVE_LAUNCH_ID || m_Launch.header.version != VALVE_LAUNCH_VERSION )
  230. {
  231. // not interested in somebody else's data
  232. ResetLaunchData();
  233. }
  234. #endif
  235. }
  236. //--------------------------------------------------------------------------------------
  237. // Returns OUR internal launch flags.
  238. //--------------------------------------------------------------------------------------
  239. int GetLaunchFlags()
  240. {
  241. // establish the data
  242. RestoreOrResetLaunchData();
  243. #if defined( _DEMO )
  244. if ( m_Launch.header.id && m_Launch.header.id != VALVE_LAUNCH_ID )
  245. {
  246. return 0;
  247. }
  248. #endif
  249. return m_Launch.header.flags;
  250. }
  251. void SetLaunchFlags( unsigned int ufNewFlags )
  252. {
  253. #if defined( _DEMO )
  254. if ( m_Launch.header.id && m_Launch.header.id != VALVE_LAUNCH_ID )
  255. {
  256. return;
  257. }
  258. #endif
  259. m_Launch.header.flags = ufNewFlags;
  260. }
  261. void GetStorageID( int storageID[4] )
  262. {
  263. RestoreOrResetLaunchData();
  264. #if defined( _DEMO )
  265. if ( m_Launch.header.id && m_Launch.header.id != VALVE_LAUNCH_ID )
  266. {
  267. storageID[0] = XBX_INVALID_STORAGE_ID;
  268. storageID[1] = XBX_INVALID_STORAGE_ID;
  269. storageID[2] = XBX_INVALID_STORAGE_ID;
  270. storageID[3] = XBX_INVALID_STORAGE_ID;
  271. return;
  272. }
  273. #endif
  274. memcpy( storageID, m_Launch.header.nCtrlr2Storage, sizeof( m_Launch.header.nCtrlr2Storage ) );
  275. }
  276. void SetStorageID( int const storageID[4] )
  277. {
  278. #if defined( _DEMO )
  279. if ( m_Launch.header.id && m_Launch.header.id != VALVE_LAUNCH_ID )
  280. {
  281. return;
  282. }
  283. #endif
  284. memcpy( m_Launch.header.nCtrlr2Storage, storageID, sizeof( m_Launch.header.nCtrlr2Storage ) );
  285. }
  286. void GetSlotUsers( int &numGameUsers, char nSlot2Ctrlr[4], char nSlot2Guest[4] )
  287. {
  288. RestoreOrResetLaunchData();
  289. #if defined( _DEMO )
  290. if ( m_Launch.header.id && m_Launch.header.id != VALVE_LAUNCH_ID )
  291. {
  292. numGameUsers = 0;
  293. nSlot2Ctrlr[0] = 0;
  294. nSlot2Ctrlr[1] = 1;
  295. nSlot2Ctrlr[2] = 2;
  296. nSlot2Ctrlr[3] = 3;
  297. nSlot2Guest[0] = 0;
  298. nSlot2Guest[1] = 0;
  299. nSlot2Guest[2] = 0;
  300. nSlot2Guest[3] = 0;
  301. return;
  302. }
  303. #endif
  304. numGameUsers = m_Launch.header.numGameUsers;
  305. memcpy( nSlot2Ctrlr, m_Launch.header.nSlot2Ctrlr, sizeof( m_Launch.header.nSlot2Ctrlr ) );
  306. memcpy( nSlot2Guest, m_Launch.header.nSlot2Guest, sizeof( m_Launch.header.nSlot2Guest ) );
  307. }
  308. void SetSlotUsers( int numGameUsers, char const nSlot2Ctrlr[4], char const nSlot2Guest[4] )
  309. {
  310. #if defined( _DEMO )
  311. if ( m_Launch.header.id && m_Launch.header.id != VALVE_LAUNCH_ID )
  312. {
  313. return;
  314. }
  315. #endif
  316. m_Launch.header.numGameUsers = numGameUsers;
  317. memcpy( m_Launch.header.nSlot2Ctrlr, nSlot2Ctrlr, sizeof( m_Launch.header.nSlot2Ctrlr ) );
  318. memcpy( m_Launch.header.nSlot2Guest, nSlot2Guest, sizeof( m_Launch.header.nSlot2Guest ) );
  319. }
  320. int GetUserID( void )
  321. {
  322. RestoreOrResetLaunchData();
  323. #if defined( _DEMO )
  324. if ( m_Launch.header.id && m_Launch.header.id != VALVE_LAUNCH_ID )
  325. {
  326. return XBX_INVALID_USER_ID;
  327. }
  328. #endif
  329. return m_Launch.header.nUserID;
  330. }
  331. void SetUserID( int userID )
  332. {
  333. #if defined( _DEMO )
  334. if ( m_Launch.header.id && m_Launch.header.id != VALVE_LAUNCH_ID )
  335. {
  336. return;
  337. }
  338. #endif
  339. m_Launch.header.nUserID = userID;
  340. }
  341. bool GetForceEnglish( void )
  342. {
  343. RestoreOrResetLaunchData();
  344. #if defined( _DEMO )
  345. if ( m_Launch.header.id && m_Launch.header.id != VALVE_LAUNCH_ID )
  346. {
  347. return false;
  348. }
  349. #endif
  350. return m_Launch.header.bForceEnglish ? true : false;
  351. }
  352. void SetForceEnglish( bool bForceEnglish )
  353. {
  354. #if defined( _DEMO )
  355. if ( m_Launch.header.id && m_Launch.header.id != VALVE_LAUNCH_ID )
  356. {
  357. return;
  358. }
  359. #endif
  360. m_Launch.header.bForceEnglish = bForceEnglish;
  361. }
  362. DWORD GetAttractID( void )
  363. {
  364. RestoreOrResetLaunchData();
  365. #if defined( _DEMO )
  366. if ( m_Launch.header.id && m_Launch.header.id != VALVE_LAUNCH_ID )
  367. {
  368. return 0;
  369. }
  370. #endif
  371. return m_Launch.header.nAttractID;
  372. }
  373. void SetAttractID( DWORD nAttractID )
  374. {
  375. #if defined( _DEMO )
  376. if ( m_Launch.header.id && m_Launch.header.id != VALVE_LAUNCH_ID )
  377. {
  378. return;
  379. }
  380. #endif
  381. m_Launch.header.nAttractID = nAttractID;
  382. }
  383. void Launch( const char *pNewImageName = NULL )
  384. {
  385. if ( !pNewImageName )
  386. {
  387. #if defined( _DEMO )
  388. pNewImageName = XLAUNCH_KEYWORD_DEFAULT_APP;
  389. #else
  390. pNewImageName = "default.xex";
  391. #endif
  392. }
  393. XLaunchNewImage( pNewImageName, 0 );
  394. }
  395. private:
  396. xboxLaunchData_t m_Launch;
  397. DWORD m_LaunchDataSize;
  398. };
  399. #if defined( PLATFORM_H )
  400. // For applications that use tier0.dll
  401. PLATFORM_INTERFACE CXboxLaunch *XboxLaunch();
  402. #endif
  403. #endif