Team Fortress 2 Source Code as on 22/4/2020
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.

368 lines
11 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Xbox
  4. //
  5. //=====================================================================================//
  6. #include "pch_tier0.h"
  7. #include "xbox/xbox_console.h"
  8. #include "xbox/xbox_win32stubs.h"
  9. #include "xbox/xbox_launch.h"
  10. #include "tier0/memdbgon.h"
  11. #define XBX_MAX_EVENTS 32
  12. xevent_t g_xbx_eventQueue[XBX_MAX_EVENTS];
  13. int g_xbx_eventHead;
  14. int g_xbx_eventTail;
  15. DWORD g_iStorageDeviceId = XBX_INVALID_STORAGE_ID;
  16. DWORD g_iPrimaryUserId = XBX_INVALID_USER_ID;
  17. DWORD g_InvitedUserId = XBX_INVALID_USER_ID;
  18. HANDLE g_hListenHandle = INVALID_HANDLE_VALUE;
  19. ULONG64 g_ListenCategories = 0;
  20. XNKID g_InviteSessionId = { 0, 0, 0, 0, 0, 0, 0, 0 };
  21. //-----------------------------------------------------------------------------
  22. // Convert an Xbox notification to a custom windows message
  23. //-----------------------------------------------------------------------------
  24. static int NotificationToWindowsMessage( DWORD id )
  25. {
  26. switch( id )
  27. {
  28. case XN_SYS_UI: return WM_SYS_UI;
  29. case XN_SYS_SIGNINCHANGED: return WM_SYS_SIGNINCHANGED;
  30. case XN_SYS_STORAGEDEVICESCHANGED: return WM_SYS_STORAGEDEVICESCHANGED;
  31. case XN_SYS_PROFILESETTINGCHANGED: return WM_SYS_PROFILESETTINGCHANGED;
  32. case XN_SYS_MUTELISTCHANGED: return WM_SYS_MUTELISTCHANGED;
  33. case XN_SYS_INPUTDEVICESCHANGED: return WM_SYS_INPUTDEVICESCHANGED;
  34. case XN_SYS_INPUTDEVICECONFIGCHANGED: return WM_SYS_INPUTDEVICECONFIGCHANGED;
  35. case XN_LIVE_CONNECTIONCHANGED: return WM_LIVE_CONNECTIONCHANGED;
  36. case XN_LIVE_INVITE_ACCEPTED: return WM_LIVE_INVITE_ACCEPTED;
  37. case XN_LIVE_LINK_STATE_CHANGED: return WM_LIVE_LINK_STATE_CHANGED;
  38. case XN_LIVE_CONTENT_INSTALLED: return WM_LIVE_CONTENT_INSTALLED;
  39. case XN_LIVE_MEMBERSHIP_PURCHASED: return WM_LIVE_MEMBERSHIP_PURCHASED;
  40. case XN_LIVE_VOICECHAT_AWAY: return WM_LIVE_VOICECHAT_AWAY;
  41. case XN_LIVE_PRESENCE_CHANGED: return WM_LIVE_PRESENCE_CHANGED;
  42. case XN_FRIENDS_PRESENCE_CHANGED: return WM_FRIENDS_PRESENCE_CHANGED;
  43. case XN_FRIENDS_FRIEND_ADDED: return WM_FRIENDS_FRIEND_ADDED;
  44. case XN_FRIENDS_FRIEND_REMOVED: return WM_FRIENDS_FRIEND_REMOVED;
  45. //deprecated in Jun08 XDK: case XN_CUSTOM_GAMEBANNERPRESSED: return WM_CUSTOM_GAMEBANNERPRESSED;
  46. case XN_CUSTOM_ACTIONPRESSED: return WM_CUSTOM_ACTIONPRESSED;
  47. case XN_XMP_STATECHANGED: return WM_XMP_STATECHANGED;
  48. case XN_XMP_PLAYBACKBEHAVIORCHANGED: return WM_XMP_PLAYBACKBEHAVIORCHANGED;
  49. case XN_XMP_PLAYBACKCONTROLLERCHANGED: return WM_XMP_PLAYBACKCONTROLLERCHANGED;
  50. default:
  51. Warning( "Unrecognized notification id %d\n", id );
  52. return 0;
  53. }
  54. }
  55. //-----------------------------------------------------------------------------
  56. // XBX_Error
  57. //
  58. //-----------------------------------------------------------------------------
  59. void XBX_Error( const char* format, ... )
  60. {
  61. va_list args;
  62. char message[XBX_MAX_MESSAGE];
  63. va_start( args, format );
  64. _vsnprintf( message, sizeof( message ), format, args );
  65. va_end( args );
  66. message[sizeof( message )-1] = '\0';
  67. XBX_DebugString( XMAKECOLOR(255,0,0), message );
  68. XBX_FlushDebugOutput();
  69. DebugBreak();
  70. static volatile int doReturn;
  71. while ( !doReturn );
  72. }
  73. //-----------------------------------------------------------------------------
  74. // XBX_OutputDebugStringA
  75. //
  76. // Replaces 'OutputDebugString' to send through debugging channel
  77. //-----------------------------------------------------------------------------
  78. void XBX_OutputDebugStringA( LPCSTR lpOutputString )
  79. {
  80. XBX_DebugString( XMAKECOLOR(0,0,0), lpOutputString );
  81. }
  82. //-----------------------------------------------------------------------------
  83. // XBX_GetEvent
  84. //
  85. //-----------------------------------------------------------------------------
  86. static xevent_t* XBX_GetEvent(void)
  87. {
  88. xevent_t* evPtr;
  89. if ( g_xbx_eventHead == g_xbx_eventTail )
  90. {
  91. // empty
  92. return NULL;
  93. }
  94. evPtr = &g_xbx_eventQueue[g_xbx_eventHead & (XBX_MAX_EVENTS-1)];
  95. // advance to next event
  96. g_xbx_eventHead++;
  97. return evPtr;
  98. }
  99. //-----------------------------------------------------------------------------
  100. // XBX_FlushEvents
  101. //
  102. //-----------------------------------------------------------------------------
  103. static void XBX_FlushEvents(void)
  104. {
  105. g_xbx_eventHead = 0;
  106. g_xbx_eventTail = 0;
  107. }
  108. //-----------------------------------------------------------------------------
  109. // XBX_ProcessXCommand
  110. //
  111. //-----------------------------------------------------------------------------
  112. static void XBX_ProcessXCommand( const char *pCommand )
  113. {
  114. // remote command
  115. // pass it game via windows message
  116. HWND hWnd = GetFocus();
  117. WNDPROC windowProc = ( WNDPROC)GetWindowLong( hWnd, GWL_WNDPROC );
  118. if ( windowProc )
  119. {
  120. windowProc( hWnd, WM_XREMOTECOMMAND, 0, (LPARAM)pCommand );
  121. }
  122. }
  123. //-----------------------------------------------------------------------------
  124. // XBX_ProcessListenerNotification
  125. //
  126. //-----------------------------------------------------------------------------
  127. static void XBX_ProcessListenerNotification( int notification, int parameter )
  128. {
  129. // pass it game via windows message
  130. HWND hWnd = GetFocus();
  131. WNDPROC windowProc = ( WNDPROC)GetWindowLong( hWnd, GWL_WNDPROC );
  132. if ( windowProc )
  133. {
  134. windowProc( hWnd, notification, 0, (LPARAM)parameter );
  135. }
  136. }
  137. //-----------------------------------------------------------------------------
  138. // XBX_QueueEvent
  139. //
  140. //-----------------------------------------------------------------------------
  141. void XBX_QueueEvent(xevent_e event, int arg1, int arg2, int arg3)
  142. {
  143. xevent_t* evPtr;
  144. evPtr = &g_xbx_eventQueue[g_xbx_eventTail & (XBX_MAX_EVENTS-1)];
  145. evPtr->event = event;
  146. evPtr->arg1 = arg1;
  147. evPtr->arg2 = arg2;
  148. evPtr->arg3 = arg3;
  149. // next slot, queue never fills just overwrite older events
  150. g_xbx_eventTail++;
  151. }
  152. //-----------------------------------------------------------------------------
  153. // XBX_ProcessEvents
  154. //
  155. // Assumed one per frame only!
  156. //-----------------------------------------------------------------------------
  157. void XBX_ProcessEvents(void)
  158. {
  159. xevent_t *evPtr;
  160. DWORD id;
  161. ULONG parameter;
  162. while ( XNotifyGetNext( g_hListenHandle, 0, &id, &parameter ) )
  163. {
  164. // Special handling
  165. switch( id )
  166. {
  167. case XN_SYS_STORAGEDEVICESCHANGED:
  168. {
  169. // Have we selected a storage device?
  170. DWORD storageID = XBX_GetStorageDeviceId();
  171. if ( storageID == XBX_INVALID_STORAGE_ID || storageID == XBX_STORAGE_DECLINED )
  172. break;
  173. // Validate the selected storage device
  174. XDEVICE_DATA deviceData;
  175. DWORD ret = XContentGetDeviceData( storageID, &deviceData );
  176. if ( ret != ERROR_SUCCESS )
  177. {
  178. // Device was removed
  179. XBX_SetStorageDeviceId( XBX_INVALID_STORAGE_ID );
  180. XBX_QueueEvent( XEV_LISTENER_NOTIFICATION, NotificationToWindowsMessage( id ), 0, 0 );
  181. }
  182. break;
  183. }
  184. default:
  185. XBX_QueueEvent( XEV_LISTENER_NOTIFICATION, NotificationToWindowsMessage( id ), parameter, 0 );
  186. break;
  187. }
  188. }
  189. // pump event queue
  190. while ( 1 )
  191. {
  192. evPtr = XBX_GetEvent();
  193. if ( !evPtr )
  194. break;
  195. switch ( evPtr->event )
  196. {
  197. case XEV_REMOTECMD:
  198. XBX_ProcessXCommand( (char *)evPtr->arg1 );
  199. // clear to mark as absorbed
  200. ((char *)evPtr->arg1)[0] = '\0';
  201. break;
  202. case XEV_LISTENER_NOTIFICATION:
  203. XBX_ProcessListenerNotification( evPtr->arg1, evPtr->arg2 );
  204. break;
  205. }
  206. }
  207. }
  208. //-----------------------------------------------------------------------------
  209. // XBX_NotifyCreateListener
  210. //
  211. // Add notification categories to the listener object
  212. //-----------------------------------------------------------------------------
  213. bool XBX_NotifyCreateListener( ULONG64 categories )
  214. {
  215. if ( categories != 0 )
  216. {
  217. categories |= g_ListenCategories;
  218. }
  219. g_hListenHandle = XNotifyCreateListener( categories );
  220. if ( g_hListenHandle == NULL || g_hListenHandle == INVALID_HANDLE_VALUE )
  221. {
  222. return false;
  223. }
  224. g_ListenCategories = categories;
  225. return true;
  226. }
  227. //-----------------------------------------------------------------------------
  228. // XBX_GetLanguageString
  229. //
  230. // Returns the xbox language setting as a string
  231. //-----------------------------------------------------------------------------
  232. const char* XBX_GetLanguageString( void )
  233. {
  234. switch( XGetLanguage() )
  235. {
  236. case XC_LANGUAGE_FRENCH:
  237. return "french";
  238. case XC_LANGUAGE_GERMAN:
  239. return "german";
  240. }
  241. return "english";
  242. }
  243. bool XBX_IsLocalized( void )
  244. {
  245. switch( XGetLanguage() )
  246. {
  247. case XC_LANGUAGE_FRENCH:
  248. case XC_LANGUAGE_GERMAN:
  249. return true;
  250. }
  251. return false;
  252. }
  253. //-----------------------------------------------------------------------------
  254. // XBX_GetStorageDeviceId
  255. //
  256. // Returns the xbox storage device ID
  257. //-----------------------------------------------------------------------------
  258. DWORD XBX_GetStorageDeviceId( void )
  259. {
  260. return g_iStorageDeviceId;
  261. }
  262. //-----------------------------------------------------------------------------
  263. // XBX_SetStorageDeviceId
  264. //
  265. // Sets the xbox storage device ID
  266. //-----------------------------------------------------------------------------
  267. void XBX_SetStorageDeviceId( DWORD id )
  268. {
  269. g_iStorageDeviceId = id;
  270. }
  271. //-----------------------------------------------------------------------------
  272. // XBX_GetPrimaryUserId
  273. //
  274. // Returns the active user ID
  275. //-----------------------------------------------------------------------------
  276. DWORD XBX_GetPrimaryUserId( void )
  277. {
  278. return g_iPrimaryUserId;
  279. }
  280. //-----------------------------------------------------------------------------
  281. // XBX_SetPrimaryUserId
  282. //
  283. // Sets the active user ID
  284. //-----------------------------------------------------------------------------
  285. void XBX_SetPrimaryUserId( DWORD idx )
  286. {
  287. g_iPrimaryUserId = idx;
  288. }
  289. //-----------------------------------------------------------------------------
  290. // Purpose: Returns the stored session ID for a cross-game invite
  291. //-----------------------------------------------------------------------------
  292. XNKID XBX_GetInviteSessionId( void )
  293. {
  294. return g_InviteSessionId;
  295. }
  296. //-----------------------------------------------------------------------------
  297. // Purpose: Store a session ID for an invitation
  298. //-----------------------------------------------------------------------------
  299. void XBX_SetInviteSessionId( XNKID nSessionId )
  300. {
  301. g_InviteSessionId = nSessionId;
  302. }
  303. //-----------------------------------------------------------------------------
  304. // Purpose: Get the Id of the user who received an invite
  305. //-----------------------------------------------------------------------------
  306. DWORD XBX_GetInvitedUserId( void )
  307. {
  308. return g_InvitedUserId;
  309. }
  310. //-----------------------------------------------------------------------------
  311. // Purpose: Set the Id of the user who received an invite
  312. //-----------------------------------------------------------------------------
  313. void XBX_SetInvitedUserId( DWORD nUserId )
  314. {
  315. g_InvitedUserId = nUserId;
  316. }
  317. static CXboxLaunch g_XBoxLaunch;
  318. CXboxLaunch *XboxLaunch()
  319. {
  320. return &g_XBoxLaunch;
  321. }