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
368 lines
11 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: Xbox |
|
// |
|
//=====================================================================================// |
|
|
|
#include "pch_tier0.h" |
|
#include "xbox/xbox_console.h" |
|
#include "xbox/xbox_win32stubs.h" |
|
#include "xbox/xbox_launch.h" |
|
#include "tier0/memdbgon.h" |
|
|
|
#define XBX_MAX_EVENTS 32 |
|
|
|
xevent_t g_xbx_eventQueue[XBX_MAX_EVENTS]; |
|
int g_xbx_eventHead; |
|
int g_xbx_eventTail; |
|
DWORD g_iStorageDeviceId = XBX_INVALID_STORAGE_ID; |
|
DWORD g_iPrimaryUserId = XBX_INVALID_USER_ID; |
|
DWORD g_InvitedUserId = XBX_INVALID_USER_ID; |
|
HANDLE g_hListenHandle = INVALID_HANDLE_VALUE; |
|
ULONG64 g_ListenCategories = 0; |
|
XNKID g_InviteSessionId = { 0, 0, 0, 0, 0, 0, 0, 0 }; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Convert an Xbox notification to a custom windows message |
|
//----------------------------------------------------------------------------- |
|
static int NotificationToWindowsMessage( DWORD id ) |
|
{ |
|
switch( id ) |
|
{ |
|
case XN_SYS_UI: return WM_SYS_UI; |
|
case XN_SYS_SIGNINCHANGED: return WM_SYS_SIGNINCHANGED; |
|
case XN_SYS_STORAGEDEVICESCHANGED: return WM_SYS_STORAGEDEVICESCHANGED; |
|
case XN_SYS_PROFILESETTINGCHANGED: return WM_SYS_PROFILESETTINGCHANGED; |
|
case XN_SYS_MUTELISTCHANGED: return WM_SYS_MUTELISTCHANGED; |
|
case XN_SYS_INPUTDEVICESCHANGED: return WM_SYS_INPUTDEVICESCHANGED; |
|
case XN_SYS_INPUTDEVICECONFIGCHANGED: return WM_SYS_INPUTDEVICECONFIGCHANGED; |
|
case XN_LIVE_CONNECTIONCHANGED: return WM_LIVE_CONNECTIONCHANGED; |
|
case XN_LIVE_INVITE_ACCEPTED: return WM_LIVE_INVITE_ACCEPTED; |
|
case XN_LIVE_LINK_STATE_CHANGED: return WM_LIVE_LINK_STATE_CHANGED; |
|
case XN_LIVE_CONTENT_INSTALLED: return WM_LIVE_CONTENT_INSTALLED; |
|
case XN_LIVE_MEMBERSHIP_PURCHASED: return WM_LIVE_MEMBERSHIP_PURCHASED; |
|
case XN_LIVE_VOICECHAT_AWAY: return WM_LIVE_VOICECHAT_AWAY; |
|
case XN_LIVE_PRESENCE_CHANGED: return WM_LIVE_PRESENCE_CHANGED; |
|
case XN_FRIENDS_PRESENCE_CHANGED: return WM_FRIENDS_PRESENCE_CHANGED; |
|
case XN_FRIENDS_FRIEND_ADDED: return WM_FRIENDS_FRIEND_ADDED; |
|
case XN_FRIENDS_FRIEND_REMOVED: return WM_FRIENDS_FRIEND_REMOVED; |
|
//deprecated in Jun08 XDK: case XN_CUSTOM_GAMEBANNERPRESSED: return WM_CUSTOM_GAMEBANNERPRESSED; |
|
case XN_CUSTOM_ACTIONPRESSED: return WM_CUSTOM_ACTIONPRESSED; |
|
case XN_XMP_STATECHANGED: return WM_XMP_STATECHANGED; |
|
case XN_XMP_PLAYBACKBEHAVIORCHANGED: return WM_XMP_PLAYBACKBEHAVIORCHANGED; |
|
case XN_XMP_PLAYBACKCONTROLLERCHANGED: return WM_XMP_PLAYBACKCONTROLLERCHANGED; |
|
default: |
|
Warning( "Unrecognized notification id %d\n", id ); |
|
return 0; |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// XBX_Error |
|
// |
|
//----------------------------------------------------------------------------- |
|
void XBX_Error( const char* format, ... ) |
|
{ |
|
va_list args; |
|
char message[XBX_MAX_MESSAGE]; |
|
|
|
va_start( args, format ); |
|
_vsnprintf( message, sizeof( message ), format, args ); |
|
va_end( args ); |
|
|
|
message[sizeof( message )-1] = '\0'; |
|
|
|
XBX_DebugString( XMAKECOLOR(255,0,0), message ); |
|
XBX_FlushDebugOutput(); |
|
|
|
DebugBreak(); |
|
|
|
static volatile int doReturn; |
|
|
|
while ( !doReturn ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// XBX_OutputDebugStringA |
|
// |
|
// Replaces 'OutputDebugString' to send through debugging channel |
|
//----------------------------------------------------------------------------- |
|
void XBX_OutputDebugStringA( LPCSTR lpOutputString ) |
|
{ |
|
XBX_DebugString( XMAKECOLOR(0,0,0), lpOutputString ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// XBX_GetEvent |
|
// |
|
//----------------------------------------------------------------------------- |
|
static xevent_t* XBX_GetEvent(void) |
|
{ |
|
xevent_t* evPtr; |
|
|
|
if ( g_xbx_eventHead == g_xbx_eventTail ) |
|
{ |
|
// empty |
|
return NULL; |
|
} |
|
|
|
evPtr = &g_xbx_eventQueue[g_xbx_eventHead & (XBX_MAX_EVENTS-1)]; |
|
|
|
// advance to next event |
|
g_xbx_eventHead++; |
|
|
|
return evPtr; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// XBX_FlushEvents |
|
// |
|
//----------------------------------------------------------------------------- |
|
static void XBX_FlushEvents(void) |
|
{ |
|
g_xbx_eventHead = 0; |
|
g_xbx_eventTail = 0; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// XBX_ProcessXCommand |
|
// |
|
//----------------------------------------------------------------------------- |
|
static void XBX_ProcessXCommand( const char *pCommand ) |
|
{ |
|
// remote command |
|
// pass it game via windows message |
|
HWND hWnd = GetFocus(); |
|
WNDPROC windowProc = ( WNDPROC)GetWindowLong( hWnd, GWL_WNDPROC ); |
|
if ( windowProc ) |
|
{ |
|
windowProc( hWnd, WM_XREMOTECOMMAND, 0, (LPARAM)pCommand ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// XBX_ProcessListenerNotification |
|
// |
|
//----------------------------------------------------------------------------- |
|
static void XBX_ProcessListenerNotification( int notification, int parameter ) |
|
{ |
|
// pass it game via windows message |
|
HWND hWnd = GetFocus(); |
|
WNDPROC windowProc = ( WNDPROC)GetWindowLong( hWnd, GWL_WNDPROC ); |
|
if ( windowProc ) |
|
{ |
|
windowProc( hWnd, notification, 0, (LPARAM)parameter ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// XBX_QueueEvent |
|
// |
|
//----------------------------------------------------------------------------- |
|
void XBX_QueueEvent(xevent_e event, int arg1, int arg2, int arg3) |
|
{ |
|
xevent_t* evPtr; |
|
|
|
evPtr = &g_xbx_eventQueue[g_xbx_eventTail & (XBX_MAX_EVENTS-1)]; |
|
evPtr->event = event; |
|
evPtr->arg1 = arg1; |
|
evPtr->arg2 = arg2; |
|
evPtr->arg3 = arg3; |
|
|
|
// next slot, queue never fills just overwrite older events |
|
g_xbx_eventTail++; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// XBX_ProcessEvents |
|
// |
|
// Assumed one per frame only! |
|
//----------------------------------------------------------------------------- |
|
void XBX_ProcessEvents(void) |
|
{ |
|
xevent_t *evPtr; |
|
|
|
DWORD id; |
|
ULONG parameter; |
|
while ( XNotifyGetNext( g_hListenHandle, 0, &id, ¶meter ) ) |
|
{ |
|
// Special handling |
|
switch( id ) |
|
{ |
|
case XN_SYS_STORAGEDEVICESCHANGED: |
|
{ |
|
// Have we selected a storage device? |
|
DWORD storageID = XBX_GetStorageDeviceId(); |
|
if ( storageID == XBX_INVALID_STORAGE_ID || storageID == XBX_STORAGE_DECLINED ) |
|
break; |
|
|
|
// Validate the selected storage device |
|
XDEVICE_DATA deviceData; |
|
DWORD ret = XContentGetDeviceData( storageID, &deviceData ); |
|
if ( ret != ERROR_SUCCESS ) |
|
{ |
|
// Device was removed |
|
XBX_SetStorageDeviceId( XBX_INVALID_STORAGE_ID ); |
|
XBX_QueueEvent( XEV_LISTENER_NOTIFICATION, NotificationToWindowsMessage( id ), 0, 0 ); |
|
} |
|
break; |
|
} |
|
|
|
default: |
|
XBX_QueueEvent( XEV_LISTENER_NOTIFICATION, NotificationToWindowsMessage( id ), parameter, 0 ); |
|
break; |
|
} |
|
} |
|
|
|
// pump event queue |
|
while ( 1 ) |
|
{ |
|
evPtr = XBX_GetEvent(); |
|
if ( !evPtr ) |
|
break; |
|
|
|
switch ( evPtr->event ) |
|
{ |
|
case XEV_REMOTECMD: |
|
XBX_ProcessXCommand( (char *)evPtr->arg1 ); |
|
// clear to mark as absorbed |
|
((char *)evPtr->arg1)[0] = '\0'; |
|
break; |
|
|
|
case XEV_LISTENER_NOTIFICATION: |
|
XBX_ProcessListenerNotification( evPtr->arg1, evPtr->arg2 ); |
|
break; |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// XBX_NotifyCreateListener |
|
// |
|
// Add notification categories to the listener object |
|
//----------------------------------------------------------------------------- |
|
bool XBX_NotifyCreateListener( ULONG64 categories ) |
|
{ |
|
if ( categories != 0 ) |
|
{ |
|
categories |= g_ListenCategories; |
|
} |
|
|
|
g_hListenHandle = XNotifyCreateListener( categories ); |
|
if ( g_hListenHandle == NULL || g_hListenHandle == INVALID_HANDLE_VALUE ) |
|
{ |
|
return false; |
|
} |
|
|
|
g_ListenCategories = categories; |
|
return true; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// XBX_GetLanguageString |
|
// |
|
// Returns the xbox language setting as a string |
|
//----------------------------------------------------------------------------- |
|
const char* XBX_GetLanguageString( void ) |
|
{ |
|
switch( XGetLanguage() ) |
|
{ |
|
case XC_LANGUAGE_FRENCH: |
|
return "french"; |
|
case XC_LANGUAGE_GERMAN: |
|
return "german"; |
|
} |
|
|
|
return "english"; |
|
} |
|
|
|
bool XBX_IsLocalized( void ) |
|
{ |
|
switch( XGetLanguage() ) |
|
{ |
|
case XC_LANGUAGE_FRENCH: |
|
case XC_LANGUAGE_GERMAN: |
|
return true; |
|
} |
|
|
|
return false; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// XBX_GetStorageDeviceId |
|
// |
|
// Returns the xbox storage device ID |
|
//----------------------------------------------------------------------------- |
|
DWORD XBX_GetStorageDeviceId( void ) |
|
{ |
|
return g_iStorageDeviceId; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// XBX_SetStorageDeviceId |
|
// |
|
// Sets the xbox storage device ID |
|
//----------------------------------------------------------------------------- |
|
void XBX_SetStorageDeviceId( DWORD id ) |
|
{ |
|
g_iStorageDeviceId = id; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// XBX_GetPrimaryUserId |
|
// |
|
// Returns the active user ID |
|
//----------------------------------------------------------------------------- |
|
DWORD XBX_GetPrimaryUserId( void ) |
|
{ |
|
return g_iPrimaryUserId; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// XBX_SetPrimaryUserId |
|
// |
|
// Sets the active user ID |
|
//----------------------------------------------------------------------------- |
|
void XBX_SetPrimaryUserId( DWORD idx ) |
|
{ |
|
g_iPrimaryUserId = idx; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Returns the stored session ID for a cross-game invite |
|
//----------------------------------------------------------------------------- |
|
XNKID XBX_GetInviteSessionId( void ) |
|
{ |
|
return g_InviteSessionId; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Store a session ID for an invitation |
|
//----------------------------------------------------------------------------- |
|
void XBX_SetInviteSessionId( XNKID nSessionId ) |
|
{ |
|
g_InviteSessionId = nSessionId; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Get the Id of the user who received an invite |
|
//----------------------------------------------------------------------------- |
|
|
|
DWORD XBX_GetInvitedUserId( void ) |
|
{ |
|
return g_InvitedUserId; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Set the Id of the user who received an invite |
|
//----------------------------------------------------------------------------- |
|
void XBX_SetInvitedUserId( DWORD nUserId ) |
|
{ |
|
g_InvitedUserId = nUserId; |
|
} |
|
|
|
static CXboxLaunch g_XBoxLaunch; |
|
CXboxLaunch *XboxLaunch() |
|
{ |
|
return &g_XBoxLaunch; |
|
}
|
|
|