system.cpp
上传用户:jnfxsk
上传日期:2022-06-16
资源大小:3675k
文件大小:20k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. /*
  2. ** Haaf's Game Engine 1.8
  3. ** Copyright (C) 2003-2007, Relish Games
  4. ** hge.relishgames.com
  5. **
  6. ** Core system functions
  7. */
  8. #include "hge_impl.h"
  9. #define LOWORDINT(n) ((int)((signed short)(LOWORD(n))))
  10. #define HIWORDINT(n) ((int)((signed short)(HIWORD(n))))
  11. const char *WINDOW_CLASS_NAME = "HGE__WNDCLASS";
  12. LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
  13. int nRef=0;
  14. HGE_Impl* pHGE=0;
  15. BOOL APIENTRY DllMain(HANDLE, DWORD, LPVOID)
  16. {
  17.     return TRUE;
  18. }
  19. HGE* CALL hgeCreate(int ver)
  20. {
  21. if(ver==HGE_VERSION)
  22. return (HGE*)HGE_Impl::_Interface_Get();
  23. else
  24. return 0;
  25. }
  26. HGE_Impl* HGE_Impl::_Interface_Get()
  27. {
  28. if(!pHGE) pHGE=new HGE_Impl();
  29. nRef++;
  30. return pHGE;
  31. }
  32. void CALL HGE_Impl::Release()
  33. {
  34. nRef--;
  35. if(!nRef)
  36. {
  37. if(pHGE->hwnd) pHGE->System_Shutdown();
  38. Resource_RemoveAllPacks();
  39. delete pHGE;
  40. pHGE=0;
  41. }
  42. }
  43. bool CALL HGE_Impl::System_Initiate()
  44. {
  45. OSVERSIONINFO os_ver;
  46. SYSTEMTIME tm;
  47. MEMORYSTATUS mem_st;
  48. WNDCLASS winclass;
  49. int width, height;
  50. // Log system info
  51. System_Log("HGE Started..n");
  52. System_Log("HGE version: %X.%X", HGE_VERSION>>8, HGE_VERSION & 0xFF);
  53. GetLocalTime(&tm);
  54. System_Log("Date: %02d.%02d.%d, %02d:%02d:%02dn", tm.wDay, tm.wMonth, tm.wYear, tm.wHour, tm.wMinute, tm.wSecond);
  55. System_Log("Application: %s",szWinTitle);
  56. os_ver.dwOSVersionInfoSize=sizeof(os_ver);
  57. GetVersionEx(&os_ver);
  58. System_Log("OS: Windows %ld.%ld.%ld",os_ver.dwMajorVersion,os_ver.dwMinorVersion,os_ver.dwBuildNumber);
  59. GlobalMemoryStatus(&mem_st);
  60. System_Log("Memory: %ldK total, %ldK freen",mem_st.dwTotalPhys/1024L,mem_st.dwAvailPhys/1024L);
  61. // Register window class
  62. winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
  63. winclass.lpfnWndProc = WindowProc;
  64. winclass.cbClsExtra = 0;
  65. winclass.cbWndExtra = 0;
  66. winclass.hInstance = hInstance;
  67. winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  68. winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
  69. winclass.lpszMenuName = NULL; 
  70. winclass.lpszClassName = WINDOW_CLASS_NAME;
  71. if(szIcon) winclass.hIcon = LoadIcon(hInstance, szIcon);
  72. else winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  73. if (!RegisterClass(&winclass)) {
  74. _PostError("Can't register window class");
  75. return false;
  76. }
  77. // Create window
  78. width=nScreenWidth + GetSystemMetrics(SM_CXFIXEDFRAME)*2;
  79. height=nScreenHeight + GetSystemMetrics(SM_CYFIXEDFRAME)*2 + GetSystemMetrics(SM_CYCAPTION);
  80. rectW.left=(GetSystemMetrics(SM_CXSCREEN)-width)/2;
  81. rectW.top=(GetSystemMetrics(SM_CYSCREEN)-height)/2;
  82. rectW.right=rectW.left+width;
  83. rectW.bottom=rectW.top+height;
  84. styleW=WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_VISIBLE; //WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX;
  85. rectFS.left=0;
  86. rectFS.top=0;
  87. rectFS.right=nScreenWidth;
  88. rectFS.bottom=nScreenHeight;
  89. styleFS=WS_POPUP|WS_VISIBLE; //WS_POPUP
  90. if(hwndParent)
  91. {
  92. rectW.left=0;
  93. rectW.top=0;
  94. rectW.right=nScreenWidth;
  95. rectW.bottom=nScreenHeight;
  96. styleW=WS_CHILD|WS_VISIBLE; 
  97. bWindowed=true;
  98. }
  99. if(bWindowed)
  100. hwnd = CreateWindowEx(0, WINDOW_CLASS_NAME, szWinTitle, styleW,
  101. rectW.left, rectW.top, rectW.right-rectW.left, rectW.bottom-rectW.top,
  102. hwndParent, NULL, hInstance, NULL);
  103. else
  104. hwnd = CreateWindowEx(WS_EX_TOPMOST, WINDOW_CLASS_NAME, szWinTitle, styleFS,
  105. 0, 0, 0, 0,
  106. NULL, NULL, hInstance, NULL);
  107. if (!hwnd)
  108. {
  109. _PostError("Can't create window");
  110. return false;
  111. }
  112. ShowWindow(hwnd, SW_SHOW);
  113. // Init subsystems
  114. timeBeginPeriod(1);
  115. Random_Seed();
  116. _InitPowerStatus();
  117. _InputInit();
  118. if(!_GfxInit()) { System_Shutdown(); return false; }
  119. if(!_SoundInit()) { System_Shutdown(); return false; }
  120. System_Log("Init done.n");
  121. fTime=0.0f;
  122. t0=t0fps=timeGetTime();
  123. dt=cfps=0;
  124. nFPS=0;
  125. // Show splash
  126. #ifdef DEMO
  127. bool (*func)();
  128. bool (*rfunc)();
  129. HWND hwndTmp;
  130. if(pHGE->bDMO)
  131. {
  132. Sleep(200);
  133. func=(bool(*)())pHGE->System_GetStateFunc(HGE_FRAMEFUNC);
  134. rfunc=(bool(*)())pHGE->System_GetStateFunc(HGE_RENDERFUNC);
  135. hwndTmp=hwndParent; hwndParent=0;
  136. pHGE->System_SetStateFunc(HGE_FRAMEFUNC, DFrame);
  137. pHGE->System_SetStateFunc(HGE_RENDERFUNC, 0);
  138. DInit();
  139. pHGE->System_Start();
  140. DDone();
  141. hwndParent=hwndTmp;
  142. pHGE->System_SetStateFunc(HGE_FRAMEFUNC, func);
  143. pHGE->System_SetStateFunc(HGE_RENDERFUNC, rfunc);
  144. }
  145. #endif
  146. // Done
  147. return true;
  148. }
  149. void CALL HGE_Impl::System_Shutdown()
  150. {
  151. System_Log("nFinishing..");
  152. timeEndPeriod(1);
  153. if(hSearch) { FindClose(hSearch); hSearch=0; }
  154. _ClearQueue();
  155. _SoundDone();
  156. _GfxDone();
  157. _DonePowerStatus();
  158. if(hwnd)
  159. {
  160. //ShowWindow(hwnd, SW_HIDE);
  161. //SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_TOOLWINDOW);
  162. //ShowWindow(hwnd, SW_SHOW);
  163. DestroyWindow(hwnd);
  164. hwnd=0;
  165. }
  166. if(hInstance) UnregisterClass(WINDOW_CLASS_NAME, hInstance);
  167. System_Log("The End.");
  168. }
  169. bool CALL HGE_Impl::System_Start()
  170. {
  171. MSG msg;
  172. if(!hwnd)
  173. {
  174. _PostError("System_Start: System_Initiate wasn't called");
  175. return false;
  176. }
  177. if(!procFrameFunc) {
  178. _PostError("System_Start: No frame function defined");
  179. return false;
  180. }
  181. bActive=true;
  182. // MAIN LOOP
  183. for(;;)
  184. {
  185. // Process window messages if not in "child mode"
  186. // (if in "child mode" the parent application will do this for us)
  187. if(!hwndParent)
  188. {
  189. if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
  190. if (msg.message == WM_QUIT) break;
  191. // TranslateMessage(&msg);
  192. DispatchMessage(&msg);
  193. continue;
  194. }
  195. }
  196. // Check if mouse is over HGE window for Input_IsMouseOver
  197. _UpdateMouse();
  198. // If HGE window is focused or we have the "don't suspend" state - process the main loop
  199. if(bActive || bDontSuspend)
  200. {
  201. // Ensure we have at least 1ms time step
  202. // to not confuse user's code with 0
  203. do { dt=timeGetTime() - t0; } while(dt < 1);
  204. // If we reached the time for the next frame
  205. // or we just run in unlimited FPS mode, then
  206. // do the stuff
  207. if(dt >= nFixedDelta)
  208. {
  209. // fDeltaTime = time step in seconds returned by Timer_GetDelta
  210. fDeltaTime=dt/1000.0f;
  211. // Cap too large time steps usually caused by lost focus to avoid jerks
  212. if(fDeltaTime > 0.2f)
  213. {
  214. fDeltaTime = nFixedDelta ? nFixedDelta/1000.0f : 0.01f;
  215. }
  216. // Update time counter returned Timer_GetTime
  217. fTime += fDeltaTime;
  218. // Store current time for the next frame
  219. // and count FPS
  220. t0=timeGetTime();
  221. if(t0-t0fps <= 1000) cfps++;
  222. else
  223. {
  224. nFPS=cfps; cfps=0; t0fps=t0;
  225. _UpdatePowerStatus();
  226. }
  227. // Do user's stuff
  228. if(procFrameFunc()) break;
  229. if(procRenderFunc) procRenderFunc();
  230. // If if "child mode" - return after processing single frame
  231. if(hwndParent) break;
  232. // Clean up input events that were generated by
  233. // WindowProc and weren't handled by user's code
  234. _ClearQueue();
  235. // If we use VSYNC - we could afford a little
  236. // sleep to lower CPU usage
  237. // if(!bWindowed && nHGEFPS==HGEFPS_VSYNC) Sleep(1);
  238. }
  239. // If we have a fixed frame rate and the time
  240. // for the next frame isn't too close, sleep a bit
  241. else
  242. {
  243. if(nFixedDelta && dt+3 < nFixedDelta) Sleep(1);
  244. }
  245. }
  246. // If main loop is suspended - just sleep a bit
  247. // (though not too much to allow instant window
  248. // redraw if requested by OS)
  249. else Sleep(1);
  250. }
  251. _ClearQueue();
  252. bActive=false;
  253. return true;
  254. }
  255. void CALL HGE_Impl::System_SetStateBool(hgeBoolState state, bool value)
  256. {
  257. switch(state)
  258. {
  259. case HGE_WINDOWED: if(VertArray || hwndParent) break;
  260. if(pD3DDevice && bWindowed != value)
  261. {
  262. if(d3dppW.BackBufferFormat==D3DFMT_UNKNOWN || d3dppFS.BackBufferFormat==D3DFMT_UNKNOWN) break;
  263. if(bWindowed) GetWindowRect(hwnd, &rectW);
  264. bWindowed=value;
  265. if(bWindowed) d3dpp=&d3dppW;
  266. else d3dpp=&d3dppFS;
  267. if(_format_id(d3dpp->BackBufferFormat) < 4) nScreenBPP=16;
  268. else nScreenBPP=32;
  269. _GfxRestore();
  270. _AdjustWindow();
  271. }
  272. else bWindowed=value;
  273. break;
  274. case HGE_ZBUFFER: if(!pD3DDevice) bZBuffer=value;
  275. break;
  276. case HGE_TEXTUREFILTER: bTextureFilter=value;
  277. if(pD3DDevice)
  278. {
  279. _render_batch();
  280. if(bTextureFilter)
  281. {
  282. pD3DDevice->SetTextureStageState(0,D3DTSS_MAGFILTER,D3DTEXF_LINEAR);
  283. pD3DDevice->SetTextureStageState(0,D3DTSS_MINFILTER,D3DTEXF_LINEAR);
  284. }
  285. else
  286. {
  287. pD3DDevice->SetTextureStageState(0,D3DTSS_MAGFILTER,D3DTEXF_POINT);
  288. pD3DDevice->SetTextureStageState(0,D3DTSS_MINFILTER,D3DTEXF_POINT);
  289. }
  290. }
  291. break;
  292. case HGE_USESOUND: if(bUseSound!=value)
  293. {
  294. bUseSound=value;
  295. if(bUseSound && hwnd) _SoundInit();
  296. if(!bUseSound && hwnd) _SoundDone();
  297. }
  298. break;
  299. case HGE_HIDEMOUSE: bHideMouse=value; break;
  300. case HGE_DONTSUSPEND: bDontSuspend=value; break;
  301. #ifdef DEMO
  302. case HGE_SHOWSPLASH: bDMO=value; break;
  303. #endif
  304. }
  305. }
  306. void CALL HGE_Impl::System_SetStateFunc(hgeFuncState state, hgeCallback value)
  307. {
  308. switch(state)
  309. {
  310. case HGE_FRAMEFUNC:  procFrameFunc=value; break;
  311. case HGE_RENDERFUNC:  procRenderFunc=value; break;
  312. case HGE_FOCUSLOSTFUNC:  procFocusLostFunc=value; break;
  313. case HGE_FOCUSGAINFUNC:  procFocusGainFunc=value; break;
  314. case HGE_GFXRESTOREFUNC: procGfxRestoreFunc=value; break;
  315. case HGE_EXITFUNC:  procExitFunc=value; break;
  316. }
  317. }
  318. void CALL HGE_Impl::System_SetStateHwnd(hgeHwndState state, HWND value)
  319. {
  320. switch(state)
  321. {
  322. case HGE_HWNDPARENT: if(!hwnd) hwndParent=value; break;
  323. }
  324. }
  325. void CALL HGE_Impl::System_SetStateInt(hgeIntState state, int value)
  326. {
  327. switch(state)
  328. {
  329. case HGE_SCREENWIDTH: if(!pD3DDevice) nScreenWidth=value; break;
  330. case HGE_SCREENHEIGHT: if(!pD3DDevice) nScreenHeight=value; break;
  331. case HGE_SCREENBPP: if(!pD3DDevice) nScreenBPP=value; break;
  332. case HGE_SAMPLERATE: if(!hBass) nSampleRate=value;
  333. break;
  334. case HGE_FXVOLUME: nFXVolume=value;
  335. _SetFXVolume(nFXVolume);
  336. break;
  337. case HGE_MUSVOLUME: nMusVolume=value;
  338. _SetMusVolume(nMusVolume);
  339. break;
  340. case HGE_STREAMVOLUME: nStreamVolume=value;
  341. _SetStreamVolume(nStreamVolume);
  342. break;
  343. case HGE_FPS: if(VertArray) break;
  344. if(pD3DDevice)
  345. {
  346. if((nHGEFPS>=0 && value <0) || (nHGEFPS<0 && value>=0))
  347. {
  348. if(value==HGEFPS_VSYNC)
  349. {
  350. d3dppW.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC;
  351. d3dppFS.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE;
  352. }
  353. else
  354. {
  355. d3dppW.SwapEffect = D3DSWAPEFFECT_COPY;
  356. d3dppFS.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
  357. }
  358. //if(procFocusLostFunc) procFocusLostFunc();
  359. _GfxRestore();
  360. //if(procFocusGainFunc) procFocusGainFunc();
  361. }
  362. }
  363. nHGEFPS=value;
  364. if(nHGEFPS>0) nFixedDelta=int(1000.0f/value);
  365. else nFixedDelta=0;
  366. break;
  367. }
  368. }
  369. void CALL HGE_Impl::System_SetStateString(hgeStringState state, const char *value)
  370. {
  371. FILE *hf;
  372. switch(state)
  373. {
  374. case HGE_ICON: szIcon=value;
  375. if(pHGE->hwnd) SetClassLong(pHGE->hwnd, GCL_HICON, (LONG)LoadIcon(pHGE->hInstance, szIcon));
  376. break;
  377. case HGE_TITLE: strcpy(szWinTitle,value);
  378. if(pHGE->hwnd) SetWindowText(pHGE->hwnd, szWinTitle);
  379. break;
  380. case HGE_INIFILE: if(value) strcpy(szIniFile,Resource_MakePath(value));
  381. else szIniFile[0]=0;
  382. break;
  383. case HGE_LOGFILE: if(value)
  384. {
  385. strcpy(szLogFile,Resource_MakePath(value));
  386. hf=fopen(szLogFile, "w");
  387. if(!hf) szLogFile[0]=0;
  388. else fclose(hf);
  389. }
  390. else szLogFile[0]=0;
  391. break;
  392. }
  393. }
  394. bool CALL HGE_Impl::System_GetStateBool(hgeBoolState state)
  395. {
  396. switch(state)
  397. {
  398. case HGE_WINDOWED: return bWindowed;
  399. case HGE_ZBUFFER: return bZBuffer;
  400. case HGE_TEXTUREFILTER: return bTextureFilter;
  401. case HGE_USESOUND: return bUseSound;
  402. case HGE_DONTSUSPEND: return bDontSuspend;
  403. case HGE_HIDEMOUSE: return bHideMouse;
  404. #ifdef DEMO
  405. case HGE_SHOWSPLASH: return bDMO;
  406. #endif
  407. }
  408. return false;
  409. }
  410. hgeCallback CALL HGE_Impl::System_GetStateFunc(hgeFuncState state)
  411. {
  412. switch(state)
  413. {
  414. case HGE_FRAMEFUNC: return procFrameFunc;
  415. case HGE_RENDERFUNC: return procRenderFunc;
  416. case HGE_FOCUSLOSTFUNC: return procFocusLostFunc;
  417. case HGE_FOCUSGAINFUNC: return procFocusGainFunc;
  418. case HGE_EXITFUNC: return procExitFunc;
  419. }
  420. return NULL;
  421. }
  422. HWND CALL HGE_Impl::System_GetStateHwnd(hgeHwndState state)
  423. {
  424. switch(state)
  425. {
  426. case HGE_HWND: return hwnd;
  427. case HGE_HWNDPARENT: return hwndParent;
  428. }
  429. return 0;
  430. }
  431. int CALL HGE_Impl::System_GetStateInt(hgeIntState state)
  432. {
  433. switch(state)
  434. {
  435. case HGE_SCREENWIDTH: return nScreenWidth;
  436. case HGE_SCREENHEIGHT: return nScreenHeight;
  437. case HGE_SCREENBPP: return nScreenBPP;
  438. case HGE_SAMPLERATE: return nSampleRate;
  439. case HGE_FXVOLUME: return nFXVolume;
  440. case HGE_MUSVOLUME: return nMusVolume;
  441. case HGE_STREAMVOLUME: return nStreamVolume;
  442. case HGE_FPS: return nHGEFPS;
  443. case HGE_POWERSTATUS: return nPowerStatus;
  444. }
  445. return 0;
  446. }
  447. const char* CALL HGE_Impl::System_GetStateString(hgeStringState state) {
  448. switch(state) {
  449. case HGE_ICON: return szIcon;
  450. case HGE_TITLE: return szWinTitle;
  451. case HGE_INIFILE: if(szIniFile[0]) return szIniFile;
  452. else return 0;
  453. case HGE_LOGFILE: if(szLogFile[0]) return szLogFile;
  454. else return 0;
  455. }
  456. return NULL;
  457. }
  458. char* CALL HGE_Impl::System_GetErrorMessage()
  459. {
  460. return szError;
  461. }
  462. void CALL HGE_Impl::System_Log(const char *szFormat, ...)
  463. {
  464. FILE *hf = NULL;
  465. va_list ap;
  466. if(!szLogFile[0]) return;
  467. hf = fopen(szLogFile, "a");
  468. if(!hf) return;
  469. va_start(ap, szFormat);
  470. vfprintf(hf, szFormat, ap);
  471. va_end(ap);
  472. fprintf(hf, "n");
  473. fclose(hf);
  474. }
  475. bool CALL HGE_Impl::System_Launch(const char *url)
  476. {
  477. if((DWORD)ShellExecute(pHGE->hwnd, NULL, url, NULL, NULL, SW_SHOWMAXIMIZED)>32) return true;
  478. else return false;
  479. }
  480. void CALL HGE_Impl::System_Snapshot(const char *filename)
  481. {
  482. LPDIRECT3DSURFACE8 pSurf;
  483. char *shotname, tempname[_MAX_PATH];
  484. int i;
  485. if(!filename)
  486. {
  487. i=0;
  488. shotname=Resource_EnumFiles("shot???.bmp");
  489. while(shotname)
  490. {
  491. i++;
  492. shotname=Resource_EnumFiles();
  493. }
  494. sprintf(tempname, "shot%03d.bmp", i);
  495. filename=Resource_MakePath(tempname);
  496. }
  497. if(pD3DDevice)
  498. {
  499. pD3DDevice->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pSurf);
  500. D3DXSaveSurfaceToFile(filename, D3DXIFF_BMP, pSurf, NULL, NULL);
  501. pSurf->Release();
  502. }
  503. }
  504. //////// Implementation ////////
  505. HGE_Impl::HGE_Impl()
  506. {
  507. hInstance=GetModuleHandle(0);
  508. hwnd=0;
  509. bActive=false;
  510. szError[0]=0;
  511. pD3D=0;
  512. pD3DDevice=0;
  513. d3dpp=0;
  514. pTargets=0;
  515. pCurTarget=0;
  516. pScreenSurf=0;
  517. pScreenDepth=0;
  518. pVB=0;
  519. pIB=0;
  520. VertArray=0;
  521. textures=0;
  522. hBass=0;
  523. bSilent=false;
  524. streams=0;
  525. hSearch=0;
  526. res=0;
  527. queue=0;
  528. Char=VKey=Zpos=0;
  529. Xpos=Ypos=0.0f;
  530. bMouseOver=false;
  531. bCaptured=false;
  532. nHGEFPS=HGEFPS_UNLIMITED;
  533. fTime=0.0f;
  534. fDeltaTime=0.0f;
  535. nFPS=0;
  536. procFrameFunc=0;
  537. procRenderFunc=0;
  538. procFocusLostFunc=0;
  539. procFocusGainFunc=0;
  540. procGfxRestoreFunc=0;
  541. procExitFunc=0;
  542. szIcon=0;
  543. strcpy(szWinTitle,"HGE");
  544. nScreenWidth=800;
  545. nScreenHeight=600;
  546. nScreenBPP=32;
  547. bWindowed=false;
  548. bZBuffer=false;
  549. bTextureFilter=true;
  550. szLogFile[0]=0;
  551. szIniFile[0]=0;
  552. bUseSound=true;
  553. nSampleRate=44100;
  554. nFXVolume=100;
  555. nMusVolume=100;
  556. nStreamVolume=100;
  557. nFixedDelta=0;
  558. bHideMouse=true;
  559. bDontSuspend=false;
  560. hwndParent=0;
  561. nPowerStatus=HGEPWR_UNSUPPORTED;
  562. hKrnl32 = NULL;
  563. lpfnGetSystemPowerStatus = NULL;
  564. #ifdef DEMO
  565. bDMO=true;
  566. #endif
  567. GetModuleFileName(GetModuleHandle(NULL), szAppPath, sizeof(szAppPath));
  568. int i;
  569. for(i=strlen(szAppPath)-1; i>0; i--) if(szAppPath[i]=='\') break;
  570. szAppPath[i+1]=0;
  571. }
  572. void HGE_Impl::_PostError(char *error)
  573. {
  574. System_Log(error);
  575. strcpy(szError,error);
  576. }
  577. void HGE_Impl::_FocusChange(bool bAct)
  578. {
  579. bActive=bAct;
  580. if(bActive)
  581. {
  582. if(procFocusGainFunc) procFocusGainFunc();
  583. }
  584. else
  585. {
  586. if(procFocusLostFunc) procFocusLostFunc();
  587. }
  588. }
  589. LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
  590. {
  591. bool bActivating;
  592. switch(msg)
  593. {
  594. case WM_CREATE: 
  595. return FALSE;
  596. case WM_PAINT:
  597. if(pHGE->pD3D && pHGE->procRenderFunc && pHGE->bWindowed) pHGE->procRenderFunc();
  598. break;
  599. case WM_DESTROY:
  600. PostQuitMessage(0);
  601. return FALSE;
  602. /*
  603. case WM_ACTIVATEAPP:
  604. bActivating = (wparam == TRUE);
  605. if(pHGE->pD3D && pHGE->bActive != bActivating) pHGE->_FocusChange(bActivating);
  606. return FALSE;
  607. */
  608. case WM_ACTIVATE:
  609. // tricky: we should catch WA_ACTIVE and WA_CLICKACTIVE,
  610. // but only if HIWORD(wParam) (fMinimized) == FALSE (0)
  611. bActivating = (LOWORD(wparam) != WA_INACTIVE) && (HIWORD(wparam) == 0);
  612. if(pHGE->pD3D && pHGE->bActive != bActivating) pHGE->_FocusChange(bActivating);
  613. return FALSE;
  614. case WM_SETCURSOR:
  615. if(pHGE->bActive && LOWORD(lparam)==HTCLIENT && pHGE->bHideMouse) SetCursor(NULL);
  616. else SetCursor(LoadCursor(NULL, IDC_ARROW));
  617. return FALSE;
  618. case WM_SYSKEYDOWN:
  619. if(wparam == VK_F4)
  620. {
  621. if(pHGE->procExitFunc && !pHGE->procExitFunc()) return FALSE;
  622. return DefWindowProc(hwnd, msg, wparam, lparam);
  623. }
  624. else if(wparam == VK_RETURN)
  625. {
  626. pHGE->System_SetState(HGE_WINDOWED, !pHGE->System_GetState(HGE_WINDOWED));
  627. return FALSE;
  628. }
  629. else
  630. {
  631. pHGE->_BuildEvent(INPUT_KEYDOWN, wparam, HIWORD(lparam) & 0xFF, (lparam & 0x40000000) ? HGEINP_REPEAT:0, -1, -1);
  632. return FALSE;
  633. }
  634. case WM_KEYDOWN:
  635. pHGE->_BuildEvent(INPUT_KEYDOWN, wparam, HIWORD(lparam) & 0xFF, (lparam & 0x40000000) ? HGEINP_REPEAT:0, -1, -1);
  636. return FALSE;
  637. case WM_SYSKEYUP:
  638. pHGE->_BuildEvent(INPUT_KEYUP, wparam, HIWORD(lparam) & 0xFF, 0, -1, -1);
  639. return FALSE;
  640. case WM_KEYUP:
  641. pHGE->_BuildEvent(INPUT_KEYUP, wparam, HIWORD(lparam) & 0xFF, 0, -1, -1);
  642. return FALSE;
  643. case WM_LBUTTONDOWN:
  644. SetFocus(hwnd);
  645. pHGE->_BuildEvent(INPUT_MBUTTONDOWN, HGEK_LBUTTON, 0, 0, LOWORDINT(lparam), HIWORDINT(lparam));
  646. return FALSE;
  647. case WM_MBUTTONDOWN:
  648. SetFocus(hwnd);
  649. pHGE->_BuildEvent(INPUT_MBUTTONDOWN, HGEK_MBUTTON, 0, 0, LOWORDINT(lparam), HIWORDINT(lparam));
  650. return FALSE;
  651. case WM_RBUTTONDOWN:
  652. SetFocus(hwnd);
  653. pHGE->_BuildEvent(INPUT_MBUTTONDOWN, HGEK_RBUTTON, 0, 0, LOWORDINT(lparam), HIWORDINT(lparam));
  654. return FALSE;
  655. case WM_LBUTTONDBLCLK:
  656. pHGE->_BuildEvent(INPUT_MBUTTONDOWN, HGEK_LBUTTON, 0, HGEINP_REPEAT, LOWORDINT(lparam), HIWORDINT(lparam));
  657. return FALSE;
  658. case WM_MBUTTONDBLCLK:
  659. pHGE->_BuildEvent(INPUT_MBUTTONDOWN, HGEK_MBUTTON, 0, HGEINP_REPEAT, LOWORDINT(lparam), HIWORDINT(lparam));
  660. return FALSE;
  661. case WM_RBUTTONDBLCLK:
  662. pHGE->_BuildEvent(INPUT_MBUTTONDOWN, HGEK_RBUTTON, 0, HGEINP_REPEAT, LOWORDINT(lparam), HIWORDINT(lparam));
  663. return FALSE;
  664. case WM_LBUTTONUP:
  665. pHGE->_BuildEvent(INPUT_MBUTTONUP, HGEK_LBUTTON, 0, 0, LOWORDINT(lparam), HIWORDINT(lparam));
  666. return FALSE;
  667. case WM_MBUTTONUP:
  668. pHGE->_BuildEvent(INPUT_MBUTTONUP, HGEK_MBUTTON, 0, 0, LOWORDINT(lparam), HIWORDINT(lparam));
  669. return FALSE;
  670. case WM_RBUTTONUP:
  671. pHGE->_BuildEvent(INPUT_MBUTTONUP, HGEK_RBUTTON, 0, 0, LOWORDINT(lparam), HIWORDINT(lparam));
  672. return FALSE;
  673. case WM_MOUSEMOVE:
  674. pHGE->_BuildEvent(INPUT_MOUSEMOVE, 0, 0, 0, LOWORDINT(lparam), HIWORDINT(lparam));
  675. return FALSE;
  676. case 0x020A: // WM_MOUSEWHEEL, GET_WHEEL_DELTA_WPARAM(wparam);
  677. pHGE->_BuildEvent(INPUT_MOUSEWHEEL, short(HIWORD(wparam))/120, 0, 0, LOWORDINT(lparam), HIWORDINT(lparam));
  678. return FALSE;
  679. case WM_SIZE:
  680. if(pHGE->pD3D && wparam==SIZE_RESTORED) pHGE->_Resize(LOWORD(lparam), HIWORD(lparam));
  681. //return FALSE;
  682. break;
  683. case WM_SYSCOMMAND:
  684. if(wparam==SC_CLOSE)
  685. {
  686. if(pHGE->procExitFunc && !pHGE->procExitFunc()) return FALSE;
  687. pHGE->bActive=false;
  688. return DefWindowProc(hwnd, msg, wparam, lparam);
  689. }
  690. break;
  691. }
  692. return DefWindowProc(hwnd, msg, wparam, lparam);
  693. }