diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /tier0/xbox | |
| download | archived-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.cpp | 31 | ||||
| -rw-r--r-- | tier0/xbox/xbox_profile.cpp | 9 | ||||
| -rw-r--r-- | tier0/xbox/xbox_system.cpp | 368 | ||||
| -rw-r--r-- | tier0/xbox/xbox_win32stubs.cpp | 617 |
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, ¶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; +} 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; +} |