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.

606 lines
12 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: XBox win32 replacements - Mocks trivial windows flow
  4. //
  5. //=============================================================================//
  6. #include "../pch_tier0.h"
  7. #include "xbox/xbox_win32stubs.h"
  8. #include "tier0/memdbgon.h"
  9. // On the 360, threads can run on any of 6 logical processors
  10. DWORD g_dwProcessAffinityMask = 0x3F;
  11. #define HWND_MAGIC 0x12345678
  12. struct xWndClass_t
  13. {
  14. char* pClassName;
  15. WNDPROC wndProc;
  16. xWndClass_t* pNext;
  17. };
  18. struct xWnd_t
  19. {
  20. xWndClass_t* pWndClass;
  21. int x;
  22. int y;
  23. int w;
  24. int h;
  25. long windowLongs[GWL_MAX];
  26. int show;
  27. int nMagic;
  28. xWnd_t* pNext;
  29. };
  30. static xWndClass_t* g_pWndClasses;
  31. static xWnd_t* g_pWnds;
  32. static HWND g_focusWindow;
  33. inline bool IsWndValid( HWND hWnd )
  34. {
  35. if ( !hWnd || ((xWnd_t*)hWnd)->nMagic != HWND_MAGIC )
  36. return false;
  37. return true;
  38. }
  39. int MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
  40. {
  41. XBX_Error( lpText );
  42. Assert( 0 );
  43. return (0);
  44. }
  45. LONG GetWindowLong(HWND hWnd, int nIndex)
  46. {
  47. LONG oldLong;
  48. if ( !IsWndValid( hWnd ) )
  49. return 0;
  50. switch (nIndex)
  51. {
  52. case GWL_WNDPROC:
  53. case GWL_USERDATA:
  54. case GWL_STYLE:
  55. case GWL_EXSTYLE:
  56. oldLong = ((xWnd_t*)hWnd)->windowLongs[nIndex];
  57. break;
  58. default:
  59. // not implemented
  60. Assert( 0 );
  61. return 0;
  62. }
  63. return oldLong;
  64. }
  65. LONG_PTR GetWindowLongPtr(HWND hWnd, int nIndex)
  66. {
  67. UINT idx;
  68. switch ( nIndex )
  69. {
  70. case GWLP_WNDPROC:
  71. idx = GWL_WNDPROC;
  72. break;
  73. case GWLP_USERDATA:
  74. idx = GWL_USERDATA;
  75. break;
  76. default:
  77. // not implemented
  78. Assert(0);
  79. return 0;
  80. }
  81. return GetWindowLong( hWnd, idx );
  82. }
  83. LONG_PTR GetWindowLongPtrW(HWND hWnd, int nIndex)
  84. {
  85. AssertMsg( false, "GetWindowLongPtrW does not exist on Xbox 360." );
  86. return GetWindowLongPtr( hWnd, nIndex );
  87. }
  88. LONG SetWindowLong(HWND hWnd, int nIndex, LONG dwNewLong)
  89. {
  90. LONG oldLong;
  91. if ( !IsWndValid( hWnd ) )
  92. return 0;
  93. switch ( nIndex )
  94. {
  95. case GWL_WNDPROC:
  96. case GWL_USERDATA:
  97. case GWL_STYLE:
  98. oldLong = ((xWnd_t*)hWnd)->windowLongs[nIndex];
  99. ((xWnd_t*)hWnd)->windowLongs[nIndex] = dwNewLong;
  100. break;
  101. default:
  102. // not implemented
  103. Assert( 0 );
  104. return 0;
  105. }
  106. return oldLong;
  107. }
  108. LONG_PTR SetWindowLongPtr(HWND hWnd, int nIndex, LONG_PTR dwNewLong)
  109. {
  110. UINT idx;
  111. switch ( nIndex )
  112. {
  113. case GWLP_WNDPROC:
  114. idx = GWL_WNDPROC;
  115. break;
  116. case GWLP_USERDATA:
  117. idx = GWL_USERDATA;
  118. break;
  119. default:
  120. // not implemented
  121. Assert( 0 );
  122. return 0;
  123. }
  124. return SetWindowLong( hWnd, idx, dwNewLong );
  125. }
  126. LONG_PTR SetWindowLongPtrW(HWND hWnd, int nIndex, LONG_PTR dwNewLong)
  127. {
  128. AssertMsg( false, "SetWindowLongPtrW does not exist on Xbox 360." );
  129. return SetWindowLongPtr( hWnd, nIndex, dwNewLong );
  130. }
  131. HWND CreateWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)
  132. {
  133. // find classname
  134. xWndClass_t* pWndClass = g_pWndClasses;
  135. while ( pWndClass )
  136. {
  137. if ( !V_tier0_stricmp( lpClassName, pWndClass->pClassName ) )
  138. break;
  139. pWndClass = pWndClass->pNext;
  140. }
  141. if ( !pWndClass )
  142. {
  143. // no such class
  144. return (HWND)NULL;
  145. }
  146. // allocate and setup
  147. xWnd_t* pWnd = new xWnd_t;
  148. memset( pWnd, 0, sizeof(xWnd_t) );
  149. pWnd->pWndClass = pWndClass;
  150. pWnd->windowLongs[GWL_WNDPROC] = (LONG)pWndClass->wndProc;
  151. pWnd->windowLongs[GWL_STYLE] = dwStyle;
  152. pWnd->x = x;
  153. pWnd->y = y;
  154. pWnd->w = nWidth;
  155. pWnd->h = nHeight;
  156. pWnd->nMagic = HWND_MAGIC;
  157. // link into list
  158. pWnd->pNext = g_pWnds;
  159. g_pWnds = pWnd;
  160. // force the focus
  161. g_focusWindow = (HWND)pWnd;
  162. // send the expected message sequence
  163. SendMessage( (HWND)pWnd, WM_CREATE, 0, 0 );
  164. SendMessage( (HWND)pWnd, WM_ACTIVATEAPP, TRUE, 0 );
  165. return (HWND)pWnd;
  166. }
  167. 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)
  168. {
  169. return CreateWindow( lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam );
  170. }
  171. BOOL DestroyWindow( HWND hWnd )
  172. {
  173. if ( !IsWndValid( hWnd ) )
  174. return FALSE;
  175. xWnd_t* pPrev = g_pWnds;
  176. xWnd_t* pCur = g_pWnds;
  177. while ( pCur )
  178. {
  179. if ( pCur == (xWnd_t*)hWnd )
  180. {
  181. if ( pPrev == g_pWnds )
  182. {
  183. // at head of list, fixup
  184. g_pWnds = pCur->pNext;
  185. }
  186. else
  187. {
  188. // remove from chain
  189. pPrev->pNext = pCur->pNext;
  190. }
  191. pCur->nMagic = 0;
  192. delete pCur;
  193. break;
  194. }
  195. // advance through list
  196. pPrev = pCur;
  197. pCur = pCur->pNext;
  198. }
  199. return TRUE;
  200. }
  201. ATOM RegisterClassEx(CONST WNDCLASSEX *lpwcx)
  202. {
  203. // create
  204. xWndClass_t* pWndClass = new xWndClass_t;
  205. memset(pWndClass, 0, sizeof(xWndClass_t));
  206. pWndClass->pClassName = new char[strlen(lpwcx->lpszClassName)+1];
  207. strcpy(pWndClass->pClassName, lpwcx->lpszClassName);
  208. pWndClass->wndProc = lpwcx->lpfnWndProc;
  209. // insert into list
  210. pWndClass->pNext = g_pWndClasses;
  211. g_pWndClasses = pWndClass;
  212. return (ATOM)pWndClass;
  213. }
  214. ATOM RegisterClass(CONST WNDCLASS *lpwc)
  215. {
  216. // create
  217. xWndClass_t* pWndClass = new xWndClass_t;
  218. memset(pWndClass, 0, sizeof(xWndClass_t));
  219. pWndClass->pClassName = new char[strlen(lpwc->lpszClassName)+1];
  220. strcpy(pWndClass->pClassName, lpwc->lpszClassName);
  221. pWndClass->wndProc = lpwc->lpfnWndProc;
  222. // insert into list
  223. pWndClass->pNext = g_pWndClasses;
  224. g_pWndClasses = pWndClass;
  225. return (ATOM)pWndClass;
  226. }
  227. HWND GetFocus(VOID)
  228. {
  229. if ( !IsWndValid( g_focusWindow ) )
  230. return NULL;
  231. return g_focusWindow;
  232. }
  233. HWND SetFocus( HWND hWnd )
  234. {
  235. HWND hOldFocus = g_focusWindow;
  236. if ( IsWndValid( hWnd ) )
  237. {
  238. g_focusWindow = hWnd;
  239. }
  240. return hOldFocus;
  241. }
  242. LRESULT CallWindowProc(WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  243. {
  244. return (lpPrevWndFunc(hWnd, Msg, wParam, lParam));
  245. }
  246. LRESULT CallWindowProcW(WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  247. {
  248. AssertMsg( false, "CallWindowProcW does not exist on Xbox 360." );
  249. return CallWindowProc( lpPrevWndFunc, hWnd, Msg, wParam, lParam );
  250. }
  251. int GetSystemMetrics(int nIndex)
  252. {
  253. XVIDEO_MODE videoMode;
  254. XGetVideoMode( &videoMode );
  255. // default to having the backbuffer the same as the mode resolution.
  256. int nFrameBufferWidth, nFrameBufferHeight;
  257. nFrameBufferWidth = videoMode.dwDisplayWidth;
  258. nFrameBufferHeight = videoMode.dwDisplayHeight;
  259. // override for cases where we need to have a different backbuffer either for memory reasons
  260. // or for dealing with anamorphic modes.
  261. if ( !videoMode.fIsWideScreen && videoMode.dwDisplayWidth == 640 && videoMode.dwDisplayHeight == 576 )
  262. {
  263. // PAL normal
  264. nFrameBufferWidth = 640;
  265. nFrameBufferHeight = 480;
  266. }
  267. else if ( videoMode.fIsWideScreen && videoMode.dwDisplayWidth == 640 && videoMode.dwDisplayHeight == 576 )
  268. {
  269. // PAL widescreen
  270. nFrameBufferWidth = 848;
  271. nFrameBufferHeight = 480;
  272. }
  273. else if ( videoMode.fIsWideScreen && videoMode.dwDisplayWidth == 640 && videoMode.dwDisplayHeight == 480 )
  274. {
  275. // anamorphic
  276. nFrameBufferWidth = 848;
  277. nFrameBufferHeight = 480;
  278. }
  279. else if ( videoMode.fIsWideScreen && videoMode.dwDisplayWidth == 1024 && videoMode.dwDisplayHeight == 768 )
  280. {
  281. // anamorphic
  282. nFrameBufferWidth = 1280;
  283. nFrameBufferHeight = 720;
  284. }
  285. else if ( videoMode.dwDisplayWidth == 1280 && videoMode.dwDisplayHeight == 760 )
  286. {
  287. nFrameBufferWidth = 1280;
  288. nFrameBufferHeight = 720;
  289. }
  290. else if ( videoMode.dwDisplayWidth == 1280 && videoMode.dwDisplayHeight == 768 )
  291. {
  292. nFrameBufferWidth = 1280;
  293. nFrameBufferHeight = 720;
  294. }
  295. else if ( !videoMode.fIsWideScreen && videoMode.dwDisplayWidth == 1280 && videoMode.dwDisplayHeight == 1024 )
  296. {
  297. nFrameBufferWidth = 1024;
  298. nFrameBufferHeight = 768;
  299. }
  300. else if ( videoMode.fIsWideScreen && videoMode.dwDisplayWidth == 1280 && videoMode.dwDisplayHeight == 1024 )
  301. {
  302. // anamorphic
  303. nFrameBufferWidth = 1280;
  304. nFrameBufferHeight = 720;
  305. }
  306. else if ( videoMode.dwDisplayWidth == 1360 && videoMode.dwDisplayHeight == 768 )
  307. {
  308. nFrameBufferWidth = 1280;
  309. nFrameBufferHeight = 720;
  310. }
  311. else if ( videoMode.dwDisplayWidth == 1920 && videoMode.dwDisplayHeight == 1080 )
  312. {
  313. nFrameBufferWidth = 1280;
  314. nFrameBufferHeight = 720;
  315. }
  316. switch ( nIndex )
  317. {
  318. case SM_CXFIXEDFRAME:
  319. case SM_CYFIXEDFRAME:
  320. case SM_CYSIZE:
  321. return 0;
  322. case SM_CXSCREEN:
  323. return nFrameBufferWidth;
  324. case SM_CYSCREEN:
  325. return nFrameBufferHeight;
  326. }
  327. // not implemented
  328. Assert( 0 );
  329. return 0;
  330. }
  331. BOOL ShowWindow(HWND hWnd, int nCmdShow)
  332. {
  333. if ( !IsWndValid( hWnd ) )
  334. return FALSE;
  335. ((xWnd_t*)hWnd)->show = nCmdShow;
  336. if ((nCmdShow == SW_SHOWDEFAULT) || (nCmdShow == SW_SHOWNORMAL) || (nCmdShow == SW_SHOW))
  337. g_focusWindow = hWnd;
  338. return TRUE;
  339. }
  340. LRESULT SendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
  341. {
  342. if ( !IsWndValid( hWnd ) )
  343. return 0L;
  344. xWnd_t* pWnd = (xWnd_t*)hWnd;
  345. WNDPROC wndProc = (WNDPROC)pWnd->windowLongs[GWL_WNDPROC];
  346. Assert( wndProc );
  347. LRESULT result = wndProc(hWnd, Msg, wParam, lParam);
  348. return result;
  349. }
  350. LRESULT SendMessageTimeout( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, UINT fuFlags, UINT uTimeout, PDWORD_PTR lpdwResult )
  351. {
  352. *lpdwResult = SendMessage( hWnd, Msg, wParam, lParam );
  353. return -1;
  354. }
  355. BOOL GetClientRect(HWND hWnd, LPRECT lpRect)
  356. {
  357. if ( !IsWndValid( hWnd ) )
  358. return FALSE;
  359. xWnd_t* pWnd = (xWnd_t*)hWnd;
  360. lpRect->left = 0;
  361. lpRect->top = 0;
  362. lpRect->right = pWnd->w;
  363. lpRect->bottom = pWnd->h;
  364. return TRUE;
  365. }
  366. int GetDeviceCaps(HDC hdc, int nIndex)
  367. {
  368. switch (nIndex)
  369. {
  370. case HORZRES:
  371. return GetSystemMetrics( SM_CXSCREEN );
  372. case VERTRES:
  373. return GetSystemMetrics( SM_CYSCREEN );
  374. case VREFRESH:
  375. return 60;
  376. }
  377. Assert( 0 );
  378. return 0;
  379. }
  380. BOOL SetWindowPos( HWND hWnd, HWND hWndInsertAfter, int x, int y, int cx, int cy, UINT uFlags )
  381. {
  382. if ( !IsWndValid( hWnd ) )
  383. return FALSE;
  384. xWnd_t* pWnd = (xWnd_t*)hWnd;
  385. if ( !( uFlags & SWP_NOMOVE ) )
  386. {
  387. pWnd->x = x;
  388. pWnd->y = y;
  389. }
  390. if ( !( uFlags & SWP_NOSIZE ) )
  391. {
  392. pWnd->w = cx;
  393. pWnd->h = cy;
  394. }
  395. return TRUE;
  396. }
  397. int XBX_unlink( const char* filename )
  398. {
  399. bool bSuccess = DeleteFile( filename ) != 0;
  400. if ( !bSuccess && GetLastError() == ERROR_FILE_NOT_FOUND )
  401. {
  402. // not a real error
  403. bSuccess = true;
  404. }
  405. // 0 = sucess, -1 = failure
  406. return bSuccess ? 0 : -1;
  407. }
  408. //-----------------------------------------------------------------------------
  409. // Purpose: Xbox low level replacement for _mkdir().
  410. // Expects to be driven by a higher level path iterator.
  411. //-----------------------------------------------------------------------------
  412. int XBX_mkdir( const char *pszDir )
  413. {
  414. bool bSuccess = CreateDirectory( pszDir, XBOX_DONTCARE ) != 0;
  415. if ( !bSuccess && GetLastError() == ERROR_ALREADY_EXISTS )
  416. {
  417. // not a real error
  418. bSuccess = true;
  419. }
  420. // 0 = sucess, -1 = failure
  421. return ( bSuccess ? 0 : -1 );
  422. }
  423. char *XBX_getcwd( char *buf, size_t size )
  424. {
  425. if ( !buf )
  426. {
  427. buf = (char*)malloc( 4 );
  428. }
  429. strncpy( buf, "D:", size );
  430. return buf;
  431. }
  432. int XBX_access( const char *path, int mode )
  433. {
  434. if ( !path )
  435. {
  436. return -1;
  437. }
  438. // get the fatx attributes
  439. DWORD dwAttr = GetFileAttributes( path );
  440. if ( dwAttr == (DWORD)-1 )
  441. {
  442. return -1;
  443. }
  444. if ( mode == 0 )
  445. {
  446. // is file exist?
  447. return 0;
  448. }
  449. else if ( mode == 2 )
  450. {
  451. // is file write only?
  452. return -1;
  453. }
  454. else if ( mode == 4 )
  455. {
  456. // is file read only?
  457. if ( dwAttr & FILE_ATTRIBUTE_READONLY )
  458. return 0;
  459. else
  460. return -1;
  461. }
  462. else if ( mode == 6 )
  463. {
  464. // is file read and write?
  465. if ( !( dwAttr & FILE_ATTRIBUTE_READONLY ) )
  466. return 0;
  467. else
  468. return -1;
  469. }
  470. return -1;
  471. }
  472. DWORD XBX_GetCurrentDirectory( DWORD nBufferLength, LPTSTR lpBuffer )
  473. {
  474. XBX_getcwd( lpBuffer, nBufferLength );
  475. return strlen( lpBuffer );
  476. }
  477. DWORD XBX_GetModuleFileName( HMODULE hModule, LPTSTR lpFilename, DWORD nSize )
  478. {
  479. int len;
  480. char *pStr;
  481. char *pEnd;
  482. char xexName[MAX_PATH];
  483. if ( hModule == GetModuleHandle( NULL ) )
  484. {
  485. // isolate xex of command line
  486. pStr = GetCommandLine();
  487. if ( pStr )
  488. {
  489. // cull possible quotes around xex
  490. if ( pStr[0] == '\"' )
  491. {
  492. pStr++;
  493. pEnd = strchr( pStr, '\"' );
  494. if ( !pEnd )
  495. {
  496. // no ending matching quote
  497. return 0;
  498. }
  499. }
  500. else
  501. {
  502. // find possible first argument
  503. pEnd = strchr( lpFilename, ' ' );
  504. if ( !pEnd )
  505. {
  506. pEnd = pStr+strlen( pStr );
  507. }
  508. }
  509. len = pEnd-pStr;
  510. memcpy( xexName, pStr, len );
  511. xexName[len] = '\0';
  512. len = _snprintf( lpFilename, nSize, "D:\\%s", xexName );
  513. if ( len == -1 )
  514. lpFilename[nSize-1] = '\0';
  515. return strlen( lpFilename );
  516. }
  517. }
  518. return 0;
  519. }