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.

560 lines
10 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. // TerrainBlend.cpp : Defines the entry point for the application.
  9. //
  10. #include "stdafx.h"
  11. #include "resource.h"
  12. #include "mathlib/mathlib.h"
  13. #include "tier0/dbg.h"
  14. #include "tier0/icommandline.h"
  15. #include "tier1/strtools.h"
  16. #define MAX_LOADSTRING 100
  17. // Global Variables:
  18. HINSTANCE hInst; // current instance
  19. TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
  20. TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text
  21. HWND g_hWnd;
  22. // Foward declarations of functions included in this code module:
  23. ATOM MyRegisterClass(HINSTANCE hInstance);
  24. BOOL InitInstance(HINSTANCE, int);
  25. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  26. LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
  27. int g_nCapture = 0;
  28. bool g_bFocus = false;
  29. int g_ScreenWidth, g_ScreenHeight;
  30. D3DPRESENT_PARAMETERS d3dpp;
  31. IDirect3D8 *g_pDirect3D;
  32. IDirect3DDevice8 *g_pDevice;
  33. POINT GetWindowCenter()
  34. {
  35. RECT rc;
  36. GetWindowRect(g_hWnd, &rc);
  37. POINT ret;
  38. ret.x = (rc.left + rc.right) / 2;
  39. ret.y = (rc.top + rc.bottom) / 2;
  40. return ret;
  41. }
  42. void CallAppRender( bool bInvalidRect )
  43. {
  44. static DWORD lastTime = 0;
  45. static POINT lastMousePos = {0xFFFF, 0xFFFF};
  46. // Sample time and mouse position and tell the app to render.
  47. DWORD curTime = GetTickCount();
  48. float frametime = (curTime - lastTime) / 1000.0f;
  49. if( frametime > 0.1f )
  50. frametime = 0.1f;
  51. lastTime = curTime;
  52. // Get the cursor delta.
  53. POINT curMousePos;
  54. GetCursorPos(&curMousePos);
  55. int deltaX, deltaY;
  56. if( lastMousePos.x == 0xFFFF )
  57. {
  58. deltaX = deltaY = 0;
  59. }
  60. else
  61. {
  62. deltaX = curMousePos.x - lastMousePos.x;
  63. deltaY = curMousePos.y - lastMousePos.y;
  64. }
  65. // Recenter the cursor.
  66. if( g_nCapture )
  67. {
  68. lastMousePos = GetWindowCenter();
  69. SetCursorPos( lastMousePos.x, lastMousePos.y );
  70. }
  71. else
  72. {
  73. lastMousePos = curMousePos;
  74. }
  75. AppRender( frametime, (float)deltaX, (float)deltaY, bInvalidRect );
  76. }
  77. SpewRetval_t D3DAppSpewFunc( SpewType_t spewType, char const *pMsg )
  78. {
  79. switch (spewType)
  80. {
  81. case SPEW_ERROR:
  82. MessageBox(NULL, pMsg, "FATAL ERROR", MB_OK);
  83. return SPEW_ABORT;
  84. default:
  85. OutputDebugString(pMsg);
  86. #ifdef _DEBUG
  87. return spewType == SPEW_ASSERT ? SPEW_DEBUGGER : SPEW_CONTINUE;
  88. #else
  89. return SPEW_CONTINUE;
  90. #endif
  91. }
  92. }
  93. int APIENTRY WinMain(HINSTANCE hInstance,
  94. HINSTANCE hPrevInstance,
  95. LPSTR lpCmdLine,
  96. int nCmdShow)
  97. {
  98. CommandLine()->CreateCmdLine( Plat_GetCommandLine() );
  99. // TODO: Place code here.
  100. SpewOutputFunc( D3DAppSpewFunc );
  101. MathLib_Init( true, true, true, 2.2f, 2.2f, 0.0f, 2.0f );
  102. MSG msg;
  103. HACCEL hAccelTable;
  104. // Initialize global strings
  105. LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
  106. strcpy( szWindowClass, "d3dapp" );
  107. MyRegisterClass(hInstance);
  108. // Perform application initialization:
  109. if (!InitInstance (hInstance, nCmdShow))
  110. {
  111. return FALSE;
  112. }
  113. hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_TERRAINBLEND);
  114. InvalidateRect( g_hWnd, NULL, FALSE );
  115. // Main message loop:
  116. while(1)
  117. {
  118. while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  119. {
  120. if(msg.message == WM_QUIT)
  121. break;
  122. if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
  123. {
  124. TranslateMessage(&msg);
  125. DispatchMessage(&msg);
  126. }
  127. }
  128. if(msg.message == WM_QUIT)
  129. break;
  130. CallAppRender( false );
  131. }
  132. AppExit();
  133. return msg.wParam;
  134. }
  135. //
  136. // FUNCTION: MyRegisterClass()
  137. //
  138. // PURPOSE: Registers the window class.
  139. //
  140. // COMMENTS:
  141. //
  142. // This function and its usage is only necessary if you want this code
  143. // to be compatible with Win32 systems prior to the 'RegisterClassEx'
  144. // function that was added to Windows 95. It is important to call this function
  145. // so that the application will get 'well formed' small icons associated
  146. // with it.
  147. //
  148. ATOM MyRegisterClass(HINSTANCE hInstance)
  149. {
  150. WNDCLASSEX wcex;
  151. wcex.cbSize = sizeof(WNDCLASSEX);
  152. wcex.style = CS_HREDRAW | CS_VREDRAW;
  153. wcex.lpfnWndProc = (WNDPROC)WndProc;
  154. wcex.cbClsExtra = 0;
  155. wcex.cbWndExtra = 0;
  156. wcex.hInstance = hInstance;
  157. wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_TERRAINBLEND);
  158. wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
  159. wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  160. wcex.lpszMenuName = NULL;
  161. wcex.lpszClassName = szWindowClass;
  162. wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
  163. return RegisterClassEx(&wcex);
  164. }
  165. void ShutdownD3D()
  166. {
  167. if( g_pDevice )
  168. {
  169. g_pDevice->Release();
  170. g_pDevice = NULL;
  171. }
  172. if( g_pDirect3D )
  173. {
  174. g_pDirect3D->Release();
  175. g_pDirect3D = NULL;
  176. }
  177. }
  178. void InitD3D()
  179. {
  180. ShutdownD3D();
  181. RECT rcClient;
  182. GetClientRect( g_hWnd, &rcClient );
  183. g_ScreenWidth = rcClient.right - rcClient.left;
  184. g_ScreenHeight = rcClient.bottom - rcClient.top;
  185. // Initialize D3D.
  186. g_pDirect3D = Direct3DCreate8( D3D_SDK_VERSION );
  187. // Get the current desktop display mode, so we can set up a back
  188. // buffer of the same format
  189. D3DDISPLAYMODE d3ddm;
  190. g_pDirect3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm );
  191. // Set up the structure used to create the D3DDevice
  192. ZeroMemory( &d3dpp, sizeof(d3dpp) );
  193. d3dpp.Windowed = TRUE;
  194. d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
  195. d3dpp.BackBufferFormat = d3ddm.Format;
  196. d3dpp.EnableAutoDepthStencil = TRUE;
  197. d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
  198. d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
  199. HRESULT hr = g_pDirect3D->CreateDevice(
  200. D3DADAPTER_DEFAULT,
  201. D3DDEVTYPE_HAL,
  202. g_hWnd,
  203. D3DCREATE_SOFTWARE_VERTEXPROCESSING,
  204. &d3dpp,
  205. &g_pDevice);
  206. if( FAILED(hr) )
  207. {
  208. Sys_Error( "CreateDevice failed (%s)", DXGetErrorString8(hr) );
  209. }
  210. g_pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
  211. g_pDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
  212. }
  213. void DoResize()
  214. {
  215. AppPreResize();
  216. InitD3D();
  217. AppPostResize();
  218. CallAppRender( true );
  219. }
  220. //
  221. // FUNCTION: InitInstance(HANDLE, int)
  222. //
  223. // PURPOSE: Saves instance handle and creates main window
  224. //
  225. // COMMENTS:
  226. //
  227. // In this function, we save the instance handle in a global variable and
  228. // create and display the main program window.
  229. //
  230. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
  231. {
  232. hInst = hInstance; // Store instance handle in our global variable
  233. int x = Sys_FindArgInt( "-x", 0 );
  234. int y = Sys_FindArgInt( "-y", 0 );
  235. int w = Sys_FindArgInt( "-width", CW_USEDEFAULT );
  236. int h = Sys_FindArgInt( "-height", CW_USEDEFAULT );
  237. DWORD dwFlags = WS_OVERLAPPEDWINDOW;
  238. // Get the 'work area' so we don't overlap the taskbar on the top or left.
  239. RECT rcWorkArea;
  240. SystemParametersInfo( SPI_GETWORKAREA, 0, &rcWorkArea, 0 );
  241. // If they don't specify anything, maximize the window.
  242. if( x == 0 && y == 0 && w == CW_USEDEFAULT && h == CW_USEDEFAULT )
  243. {
  244. x = rcWorkArea.left;
  245. y = rcWorkArea.top;
  246. w = rcWorkArea.right - rcWorkArea.left;
  247. h = rcWorkArea.bottom - rcWorkArea.top;
  248. dwFlags |= WS_MAXIMIZE;
  249. }
  250. else
  251. {
  252. x += rcWorkArea.left;
  253. y += rcWorkArea.top;
  254. }
  255. g_hWnd = CreateWindow(
  256. szWindowClass,
  257. szTitle,
  258. dwFlags, // window style
  259. x, // x
  260. y, // y
  261. w, // width
  262. h, // height
  263. NULL,
  264. NULL,
  265. hInstance,
  266. NULL);
  267. if (!g_hWnd)
  268. {
  269. return FALSE;
  270. }
  271. ShowWindow(g_hWnd, nCmdShow);
  272. UpdateWindow(g_hWnd);
  273. InitD3D();
  274. AppInit();
  275. // Reinitialize D3D. For some reason, D3D point primitives are way too large
  276. // unless we do this.
  277. DoResize();
  278. return TRUE;
  279. }
  280. //
  281. // FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
  282. //
  283. // PURPOSE: Processes messages for the main window.
  284. //
  285. // WM_COMMAND - process the application menu
  286. // WM_PAINT - Paint the main window
  287. // WM_DESTROY - post a quit message and return
  288. //
  289. //
  290. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  291. {
  292. switch (message)
  293. {
  294. case WM_PAINT:
  295. {
  296. PAINTSTRUCT ps;
  297. BeginPaint( hWnd, &ps );
  298. EndPaint( hWnd, &ps );
  299. if( g_pDevice )
  300. CallAppRender( true );
  301. }
  302. break;
  303. case WM_KEYDOWN:
  304. {
  305. AppKey( (int)wParam, lParam&0xFFFF );
  306. }
  307. break;
  308. case WM_KEYUP:
  309. {
  310. AppKey( (int)wParam, 0 );
  311. }
  312. break;
  313. case WM_CHAR:
  314. {
  315. AppChar( (int)wParam );
  316. }
  317. break;
  318. case WM_DESTROY:
  319. PostQuitMessage(0);
  320. break;
  321. case WM_LBUTTONDOWN:
  322. {
  323. ShowCursor( FALSE );
  324. SetCapture( g_hWnd );
  325. g_nCapture++;
  326. }
  327. break;
  328. case WM_LBUTTONUP:
  329. {
  330. ShowCursor( TRUE );
  331. ReleaseCapture( );
  332. g_nCapture--;
  333. }
  334. break;
  335. case WM_RBUTTONDOWN:
  336. {
  337. ShowCursor( FALSE );
  338. SetCapture( g_hWnd );
  339. g_nCapture++;
  340. }
  341. break;
  342. case WM_RBUTTONUP:
  343. {
  344. ShowCursor( TRUE );
  345. ReleaseCapture( );
  346. g_nCapture--;
  347. }
  348. break;
  349. case WM_SIZE:
  350. {
  351. if( g_pDevice )
  352. DoResize();
  353. }
  354. break;
  355. case WM_SETFOCUS:
  356. {
  357. g_bFocus = true;
  358. }
  359. break;
  360. case WM_KILLFOCUS:
  361. {
  362. g_bFocus = false;
  363. }
  364. break;
  365. default:
  366. return DefWindowProc(hWnd, message, wParam, lParam);
  367. }
  368. return 0;
  369. }
  370. bool Sys_Error(const char *pMsg, ...)
  371. {
  372. char msg[4096];
  373. va_list marker;
  374. va_start( marker, pMsg );
  375. V_vsprintf_safe( msg, pMsg, marker );
  376. va_end( marker );
  377. MessageBox( NULL, msg, "Error!", MB_OK );
  378. exit(1);
  379. return true;
  380. }
  381. void Sys_Quit()
  382. {
  383. PostQuitMessage( 0 );
  384. }
  385. void Sys_SetWindowText( char const *pMsg, ... )
  386. {
  387. va_list marker;
  388. char msg[4096];
  389. va_start(marker, pMsg);
  390. V_vsprintf_safe(msg, pMsg, marker);
  391. va_end(marker);
  392. SetWindowText( g_hWnd, msg );
  393. }
  394. bool Sys_GetKeyState( int key )
  395. {
  396. int keyTranslations[][2] =
  397. {
  398. {APPKEY_LBUTTON, VK_LBUTTON},
  399. {APPKEY_RBUTTON, VK_RBUTTON},
  400. {APPKEY_SPACE, VK_SPACE}
  401. };
  402. int nKeyTranslations = sizeof(keyTranslations) / sizeof(keyTranslations[0]);
  403. for( int i=0; i < nKeyTranslations; i++ )
  404. {
  405. if( key == keyTranslations[i][0] )
  406. {
  407. key = keyTranslations[i][1];
  408. break;
  409. }
  410. }
  411. return !!( GetAsyncKeyState( key ) & 0x8000 );
  412. }
  413. void Sys_Sleep( int ms )
  414. {
  415. Sleep( (DWORD)ms );
  416. }
  417. bool Sys_HasFocus()
  418. {
  419. return g_bFocus;
  420. }
  421. char const* Sys_FindArg( char const *pArg, char const *pDefault )
  422. {
  423. for( int i=0; i < __argc; i++ )
  424. {
  425. if( stricmp( __argv[i], pArg ) == 0 )
  426. return (i+1) < __argc ? __argv[i+1] : "";
  427. }
  428. return pDefault;
  429. }
  430. int Sys_FindArgInt( char const *pArg, int defaultVal )
  431. {
  432. char const *pVal = Sys_FindArg( pArg, NULL );
  433. if( pVal )
  434. return atoi( pVal );
  435. else
  436. return defaultVal;
  437. }
  438. int Sys_ScreenWidth()
  439. {
  440. return g_ScreenWidth;
  441. }
  442. int Sys_ScreenHeight()
  443. {
  444. return g_ScreenHeight;
  445. }