summaryrefslogtreecommitdiff
path: root/tier0/xbox
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /tier0/xbox
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'tier0/xbox')
-rw-r--r--tier0/xbox/xbox_console.cpp31
-rw-r--r--tier0/xbox/xbox_profile.cpp9
-rw-r--r--tier0/xbox/xbox_system.cpp368
-rw-r--r--tier0/xbox/xbox_win32stubs.cpp617
4 files changed, 1025 insertions, 0 deletions
diff --git a/tier0/xbox/xbox_console.cpp b/tier0/xbox/xbox_console.cpp
new file mode 100644
index 0000000..7e9532c
--- /dev/null
+++ b/tier0/xbox/xbox_console.cpp
@@ -0,0 +1,31 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Xbox console link
+//
+//=====================================================================================//
+
+#include "pch_tier0.h"
+#include "xbox/xbox_console.h"
+#include "tier0/memdbgon.h"
+
+IXboxConsole *g_pXboxConsole;
+
+typedef IXboxConsole * (WINAPI *CONSOLEINTERFACEFUNC)( void );
+
+void XboxConsoleInit()
+{
+ g_pXboxConsole = NULL;
+
+ HMODULE hDLL = ::LoadLibrary( "vxbdm_360.dll" );
+ if ( !hDLL )
+ {
+ return;
+ }
+
+ CONSOLEINTERFACEFUNC fpnGetConsoleInterface = (CONSOLEINTERFACEFUNC) ::GetProcAddress( hDLL, "GetConsoleInterface" );
+
+ if ( fpnGetConsoleInterface )
+ {
+ g_pXboxConsole = fpnGetConsoleInterface();
+ }
+}
diff --git a/tier0/xbox/xbox_profile.cpp b/tier0/xbox/xbox_profile.cpp
new file mode 100644
index 0000000..db0ac3a
--- /dev/null
+++ b/tier0/xbox/xbox_profile.cpp
@@ -0,0 +1,9 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Xbox profiling
+//
+//=====================================================================================//
+
+#include "pch_tier0.h"
+#include "tier0/memdbgon.h"
+
diff --git a/tier0/xbox/xbox_system.cpp b/tier0/xbox/xbox_system.cpp
new file mode 100644
index 0000000..2edfb47
--- /dev/null
+++ b/tier0/xbox/xbox_system.cpp
@@ -0,0 +1,368 @@
+//========= 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, &parameter ) )
+ {
+ // 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;
+}
diff --git a/tier0/xbox/xbox_win32stubs.cpp b/tier0/xbox/xbox_win32stubs.cpp
new file mode 100644
index 0000000..95d0b53
--- /dev/null
+++ b/tier0/xbox/xbox_win32stubs.cpp
@@ -0,0 +1,617 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: XBox win32 replacements - Mocks trivial windows flow
+//
+//=============================================================================//
+
+#include "pch_tier0.h"
+#include "xbox/xbox_win32stubs.h"
+#include "tier0/memdbgon.h"
+
+// On the 360, threads can run on any of 6 logical processors
+DWORD g_dwProcessAffinityMask = 0x3F;
+
+#define HWND_MAGIC 0x12345678
+
+struct xWndClass_t
+{
+ char* pClassName;
+ WNDPROC wndProc;
+ xWndClass_t* pNext;
+};
+
+struct xWnd_t
+{
+ xWndClass_t* pWndClass;
+ int x;
+ int y;
+ int w;
+ int h;
+ long windowLongs[GWL_MAX];
+ int show;
+ int nMagic;
+ xWnd_t* pNext;
+};
+
+static xWndClass_t* g_pWndClasses;
+static xWnd_t* g_pWnds;
+static HWND g_focusWindow;
+
+inline bool IsWndValid( HWND hWnd )
+{
+ if ( !hWnd || ((xWnd_t*)hWnd)->nMagic != HWND_MAGIC )
+ return false;
+ return true;
+}
+
+int MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
+{
+ XBX_Error( lpText );
+ Assert( 0 );
+
+ return (0);
+}
+
+LONG GetWindowLong(HWND hWnd, int nIndex)
+{
+ LONG oldLong;
+
+ if ( !IsWndValid( hWnd ) )
+ return 0;
+
+ switch (nIndex)
+ {
+ case GWL_WNDPROC:
+ case GWL_USERDATA:
+ case GWL_STYLE:
+ case GWL_EXSTYLE:
+ oldLong = ((xWnd_t*)hWnd)->windowLongs[nIndex];
+ break;
+ default:
+ // not implemented
+ Assert( 0 );
+ return 0;
+ }
+
+ return oldLong;
+}
+
+LONG_PTR GetWindowLongPtr(HWND hWnd, int nIndex)
+{
+ UINT idx;
+
+ switch ( nIndex )
+ {
+ case GWLP_WNDPROC:
+ idx = GWL_WNDPROC;
+ break;
+ case GWLP_USERDATA:
+ idx = GWL_USERDATA;
+ break;
+ default:
+ // not implemented
+ Assert(0);
+ return 0;
+ }
+
+ return GetWindowLong( hWnd, idx );
+}
+
+LONG_PTR GetWindowLongPtrW(HWND hWnd, int nIndex)
+{
+ AssertMsg( false, "GetWindowLongPtrW does not exist on Xbox 360." );
+ return GetWindowLongPtr( hWnd, nIndex );
+}
+
+
+LONG SetWindowLong(HWND hWnd, int nIndex, LONG dwNewLong)
+{
+ LONG oldLong;
+
+ if ( !IsWndValid( hWnd ) )
+ return 0;
+
+ switch ( nIndex )
+ {
+ case GWL_WNDPROC:
+ case GWL_USERDATA:
+ case GWL_STYLE:
+ oldLong = ((xWnd_t*)hWnd)->windowLongs[nIndex];
+ ((xWnd_t*)hWnd)->windowLongs[nIndex] = dwNewLong;
+ break;
+ default:
+ // not implemented
+ Assert( 0 );
+ return 0;
+ }
+
+ return oldLong;
+}
+
+LONG_PTR SetWindowLongPtr(HWND hWnd, int nIndex, LONG_PTR dwNewLong)
+{
+ UINT idx;
+
+ switch ( nIndex )
+ {
+ case GWLP_WNDPROC:
+ idx = GWL_WNDPROC;
+ break;
+ case GWLP_USERDATA:
+ idx = GWL_USERDATA;
+ break;
+ default:
+ // not implemented
+ Assert( 0 );
+ return 0;
+ }
+
+ return SetWindowLong( hWnd, idx, dwNewLong );
+}
+
+LONG_PTR SetWindowLongPtrW(HWND hWnd, int nIndex, LONG_PTR dwNewLong)
+{
+ AssertMsg( false, "SetWindowLongPtrW does not exist on Xbox 360." );
+ return SetWindowLongPtr( hWnd, nIndex, dwNewLong );
+}
+
+HWND CreateWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)
+{
+ // find classname
+ xWndClass_t* pWndClass = g_pWndClasses;
+ while ( pWndClass )
+ {
+ if ( !stricmp( lpClassName, pWndClass->pClassName ) )
+ break;
+ pWndClass = pWndClass->pNext;
+ }
+ if ( !pWndClass )
+ {
+ // no such class
+ return (HWND)NULL;
+ }
+
+ // allocate and setup
+ xWnd_t* pWnd = new xWnd_t;
+ memset( pWnd, 0, sizeof(xWnd_t) );
+ pWnd->pWndClass = pWndClass;
+ pWnd->windowLongs[GWL_WNDPROC] = (LONG)pWndClass->wndProc;
+ pWnd->windowLongs[GWL_STYLE] = dwStyle;
+ pWnd->x = x;
+ pWnd->y = y;
+ pWnd->w = nWidth;
+ pWnd->h = nHeight;
+ pWnd->nMagic = HWND_MAGIC;
+
+ // link into list
+ pWnd->pNext = g_pWnds;
+ g_pWnds = pWnd;
+
+ // force the focus
+ g_focusWindow = (HWND)pWnd;
+
+ // send the expected message sequence
+ SendMessage( (HWND)pWnd, WM_CREATE, 0, 0 );
+ SendMessage( (HWND)pWnd, WM_ACTIVATEAPP, TRUE, 0 );
+
+ return (HWND)pWnd;
+}
+
+HWND CreateWindowEx(DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)
+{
+ return CreateWindow( lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam );
+}
+
+BOOL DestroyWindow( HWND hWnd )
+{
+ if ( !IsWndValid( hWnd ) )
+ return FALSE;
+
+ xWnd_t* pPrev = g_pWnds;
+ xWnd_t* pCur = g_pWnds;
+
+ while ( pCur )
+ {
+ if ( pCur == (xWnd_t*)hWnd )
+ {
+ if ( pPrev == g_pWnds )
+ {
+ // at head of list, fixup
+ g_pWnds = pCur->pNext;
+ }
+ else
+ {
+ // remove from chain
+ pPrev->pNext = pCur->pNext;
+ }
+ pCur->nMagic = 0;
+ delete pCur;
+ break;
+ }
+
+ // advance through list
+ pPrev = pCur;
+ pCur = pCur->pNext;
+ }
+
+ return TRUE;
+}
+
+ATOM RegisterClassEx(CONST WNDCLASSEX *lpwcx)
+{
+ // create
+ xWndClass_t* pWndClass = new xWndClass_t;
+ memset(pWndClass, 0, sizeof(xWndClass_t));
+ pWndClass->pClassName = new char[strlen(lpwcx->lpszClassName)+1];
+ strcpy(pWndClass->pClassName, lpwcx->lpszClassName);
+ pWndClass->wndProc = lpwcx->lpfnWndProc;
+
+ // insert into list
+ pWndClass->pNext = g_pWndClasses;
+ g_pWndClasses = pWndClass;
+
+ return (ATOM)pWndClass;
+}
+
+ATOM RegisterClass(CONST WNDCLASS *lpwc)
+{
+ // create
+ xWndClass_t* pWndClass = new xWndClass_t;
+ memset(pWndClass, 0, sizeof(xWndClass_t));
+ pWndClass->pClassName = new char[strlen(lpwc->lpszClassName)+1];
+ strcpy(pWndClass->pClassName, lpwc->lpszClassName);
+ pWndClass->wndProc = lpwc->lpfnWndProc;
+
+ // insert into list
+ pWndClass->pNext = g_pWndClasses;
+ g_pWndClasses = pWndClass;
+
+ return (ATOM)pWndClass;
+}
+
+HWND GetFocus(VOID)
+{
+ if ( !IsWndValid( g_focusWindow ) )
+ return NULL;
+
+ return g_focusWindow;
+}
+
+HWND SetFocus( HWND hWnd )
+{
+ HWND hOldFocus = g_focusWindow;
+
+ if ( IsWndValid( hWnd ) )
+ {
+ g_focusWindow = hWnd;
+ }
+
+ return hOldFocus;
+}
+
+
+LRESULT CallWindowProc(WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
+{
+ return (lpPrevWndFunc(hWnd, Msg, wParam, lParam));
+}
+
+int GetSystemMetrics(int nIndex)
+{
+ XVIDEO_MODE videoMode;
+ XGetVideoMode( &videoMode );
+ // default to having the backbuffer the same as the mode resolution.
+ int nFrameBufferWidth, nFrameBufferHeight;
+ nFrameBufferWidth = videoMode.dwDisplayWidth;
+ nFrameBufferHeight = videoMode.dwDisplayHeight;
+
+ // override for cases where we need to have a different backbuffer either for memory reasons
+ // or for dealing with anamorphic modes.
+ if ( !videoMode.fIsWideScreen && videoMode.dwDisplayWidth == 640 && videoMode.dwDisplayHeight == 576 )
+ {
+ // PAL normal
+ nFrameBufferWidth = 640;
+ nFrameBufferHeight = 480;
+ }
+ else if ( videoMode.fIsWideScreen && videoMode.dwDisplayWidth == 640 && videoMode.dwDisplayHeight == 576 )
+ {
+ // PAL widescreen
+ nFrameBufferWidth = 848;
+ nFrameBufferHeight = 480;
+ }
+ else if ( videoMode.fIsWideScreen && videoMode.dwDisplayWidth == 640 && videoMode.dwDisplayHeight == 480 )
+ {
+ // anamorphic
+ nFrameBufferWidth = 848;
+ nFrameBufferHeight = 480;
+ }
+ else if ( videoMode.fIsWideScreen && videoMode.dwDisplayWidth == 1024 && videoMode.dwDisplayHeight == 768 )
+ {
+ // anamorphic
+ nFrameBufferWidth = 1280;
+ nFrameBufferHeight = 720;
+ }
+ else if ( videoMode.dwDisplayWidth == 1280 && videoMode.dwDisplayHeight == 760 )
+ {
+ nFrameBufferWidth = 1280;
+ nFrameBufferHeight = 720;
+ }
+ else if ( videoMode.dwDisplayWidth == 1280 && videoMode.dwDisplayHeight == 768 )
+ {
+ nFrameBufferWidth = 1280;
+ nFrameBufferHeight = 720;
+ }
+ else if ( !videoMode.fIsWideScreen && videoMode.dwDisplayWidth == 1280 && videoMode.dwDisplayHeight == 1024 )
+ {
+ nFrameBufferWidth = 1024;
+ nFrameBufferHeight = 768;
+ }
+ else if ( videoMode.fIsWideScreen && videoMode.dwDisplayWidth == 1280 && videoMode.dwDisplayHeight == 1024 )
+ {
+ // anamorphic
+ nFrameBufferWidth = 1280;
+ nFrameBufferHeight = 720;
+ }
+ else if ( videoMode.dwDisplayWidth == 1360 && videoMode.dwDisplayHeight == 768 )
+ {
+ nFrameBufferWidth = 1280;
+ nFrameBufferHeight = 720;
+ }
+ else if ( videoMode.dwDisplayWidth == 1920 && videoMode.dwDisplayHeight == 1080 )
+ {
+ nFrameBufferWidth = 1280;
+ nFrameBufferHeight = 720;
+ }
+
+ switch ( nIndex )
+ {
+ case SM_CXFIXEDFRAME:
+ case SM_CYFIXEDFRAME:
+ case SM_CYSIZE:
+ return 0;
+ case SM_CXSCREEN:
+ return nFrameBufferWidth;
+ case SM_CYSCREEN:
+ return nFrameBufferHeight;
+ }
+
+ // not implemented
+ Assert( 0 );
+ return 0;
+}
+
+BOOL ShowWindow(HWND hWnd, int nCmdShow)
+{
+ if ( !IsWndValid( hWnd ) )
+ return FALSE;
+
+ ((xWnd_t*)hWnd)->show = nCmdShow;
+
+ if ((nCmdShow == SW_SHOWDEFAULT) || (nCmdShow == SW_SHOWNORMAL) || (nCmdShow == SW_SHOW))
+ g_focusWindow = hWnd;
+
+ return TRUE;
+}
+
+LRESULT SendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
+{
+ if ( !IsWndValid( hWnd ) )
+ return 0L;
+
+ xWnd_t* pWnd = (xWnd_t*)hWnd;
+ WNDPROC wndProc = (WNDPROC)pWnd->windowLongs[GWL_WNDPROC];
+ Assert( wndProc );
+ LRESULT result = wndProc(hWnd, Msg, wParam, lParam);
+
+ return result;
+}
+
+LRESULT SendMessageTimeout( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, UINT fuFlags, UINT uTimeout, PDWORD_PTR lpdwResult )
+{
+ *lpdwResult = SendMessage( hWnd, Msg, wParam, lParam );
+
+ return -1;
+}
+
+BOOL GetClientRect(HWND hWnd, LPRECT lpRect)
+{
+ if ( !IsWndValid( hWnd ) )
+ return FALSE;
+
+ xWnd_t* pWnd = (xWnd_t*)hWnd;
+ lpRect->left = 0;
+ lpRect->top = 0;
+ lpRect->right = pWnd->w;
+ lpRect->bottom = pWnd->h;
+
+ return TRUE;
+}
+
+int GetDeviceCaps(HDC hdc, int nIndex)
+{
+ switch (nIndex)
+ {
+ case HORZRES:
+ return GetSystemMetrics( SM_CXSCREEN );
+ case VERTRES:
+ return GetSystemMetrics( SM_CYSCREEN );
+ case VREFRESH:
+ return 60;
+ }
+
+ Assert( 0 );
+ return 0;
+}
+
+BOOL SetWindowPos( HWND hWnd, HWND hWndInsertAfter, int x, int y, int cx, int cy, UINT uFlags )
+{
+ if ( !IsWndValid( hWnd ) )
+ return FALSE;
+
+ xWnd_t* pWnd = (xWnd_t*)hWnd;
+
+ if ( !( uFlags & SWP_NOMOVE ) )
+ {
+ pWnd->x = x;
+ pWnd->y = y;
+ }
+
+ if ( !( uFlags & SWP_NOSIZE ) )
+ {
+ pWnd->w = cx;
+ pWnd->h = cy;
+ }
+
+ return TRUE;
+}
+
+int XBX_unlink( const char* filename )
+{
+ bool bSuccess = DeleteFile( filename ) != 0;
+ if ( !bSuccess )
+ {
+ if ( GetLastError() == ERROR_FILE_NOT_FOUND )
+ {
+ // not a real failure
+ return 0;
+ }
+ }
+ // 0 = sucess, -1 = failure
+ return bSuccess ? 0 : -1;
+}
+
+int XBX_mkdir( const char *pszDir )
+{
+ char dirPath[MAX_PATH];
+ char* ptr;
+ BOOL bSuccess;
+
+ // prime and skip to first seperator after the drive path
+ // must create directory one path at a time
+ bSuccess = false;
+ strcpy( dirPath, pszDir );
+ ptr = strchr( dirPath, '\\' );
+ while ( ptr )
+ {
+ ptr = strchr( ptr+1, '\\' );
+ if ( ptr )
+ {
+ *ptr = '\0';
+ bSuccess = CreateDirectory( dirPath, XBOX_DONTCARE );
+ if ( !bSuccess && GetLastError() == ERROR_ALREADY_EXISTS )
+ {
+ // not a real error
+ bSuccess = true;
+ }
+ *ptr = '\\';
+ }
+ }
+
+ return ( bSuccess ? 0 : -1 );
+}
+
+char *XBX_getcwd( char *buf, size_t size )
+{
+ if ( !buf )
+ {
+ buf = (char*)malloc( 4 );
+ }
+ strncpy( buf, "D:", size );
+ return buf;
+}
+
+int XBX_access( const char *path, int mode )
+{
+ if ( !path )
+ {
+ return -1;
+ }
+
+ // get the fatx attributes
+ DWORD dwAttr = GetFileAttributes( path );
+ if ( dwAttr == (DWORD)-1 )
+ {
+ return -1;
+ }
+
+ if ( mode == 0 )
+ {
+ // is file exist?
+ return 0;
+ }
+ else if ( mode == 2 )
+ {
+ // is file write only?
+ return -1;
+ }
+ else if ( mode == 4 )
+ {
+ // is file read only?
+ if ( dwAttr & FILE_ATTRIBUTE_READONLY )
+ return 0;
+ else
+ return -1;
+ }
+ else if ( mode == 6 )
+ {
+ // is file read and write?
+ if ( !( dwAttr & FILE_ATTRIBUTE_READONLY ) )
+ return 0;
+ else
+ return -1;
+ }
+
+ return -1;
+}
+
+DWORD XBX_GetCurrentDirectory( DWORD nBufferLength, LPTSTR lpBuffer )
+{
+ XBX_getcwd( lpBuffer, nBufferLength );
+ return strlen( lpBuffer );
+}
+
+DWORD XBX_GetModuleFileName( HMODULE hModule, LPTSTR lpFilename, DWORD nSize )
+{
+ int len;
+ char *pStr;
+ char *pEnd;
+ char xexName[MAX_PATH];
+
+ if ( hModule == GetModuleHandle( NULL ) )
+ {
+ // isolate xex of command line
+ pStr = GetCommandLine();
+ if ( pStr )
+ {
+ // cull possible quotes around xex
+ if ( pStr[0] == '\"' )
+ {
+ pStr++;
+ pEnd = strchr( pStr, '\"' );
+ if ( !pEnd )
+ {
+ // no ending matching quote
+ return 0;
+ }
+ }
+ else
+ {
+ // find possible first argument
+ pEnd = strchr( lpFilename, ' ' );
+ if ( !pEnd )
+ {
+ pEnd = pStr+strlen( pStr );
+ }
+ }
+ len = pEnd-pStr;
+ memcpy( xexName, pStr, len );
+ xexName[len] = '\0';
+
+ len = _snprintf( lpFilename, nSize, "D:\\%s", xexName );
+ if ( len == -1 )
+ lpFilename[nSize-1] = '\0';
+
+ return strlen( lpFilename );
+ }
+ }
+ return 0;
+}