1 /******************************************************************************
2
3 @File PVRShellOS.cpp
4
5 @Title Windows/PVRShellOS
6
7 @Version
8
9 @Copyright Copyright (c) Imagination Technologies Limited.
10
11 @Platform WinCE/Windows
12
13 @Description Makes programming for 3D APIs easier by wrapping window creation
14 and other functions for use by a demo.
15
16 ******************************************************************************/
17
18 /****************************************************************************
19 ** INCLUDES **
20 ****************************************************************************/
21 #include <windows.h>
22 #include <TCHAR.H>
23 #include <stdio.h>
24
25 #include "PVRShell.h"
26 #include "PVRShellAPI.h"
27 #include "PVRShellOS.h"
28 #include "PVRShellImpl.h"
29
30 // No Doxygen for CPP files, due to documentation duplication
31 /// @cond NO_DOXYGEN
32
33 #if !(WINVER >= 0x0500)
34 #define COMPILE_MULTIMON_STUBS
35 #include <multimon.h>
36 #endif
37
38 /****************************************************************************
39 Defines
40 *****************************************************************************/
41 /*! The class name for the window */
42 #define WINDOW_CLASS _T("PVRShellClass")
43
44 /*! Maximum size to create string array for determining the read/write paths */
45 #define DIR_BUFFER_LEN (10240)
46
47 /*! X dimension of the window that is created */
48 #define SHELL_DISPLAY_DIM_X 800
49 /*! Y dimension of the window that is created */
50 #define SHELL_DISPLAY_DIM_Y 600
51
52 /*****************************************************************************
53 Declarations
54 *****************************************************************************/
55 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
56
57 /*!***************************************************************************
58 Class: PVRShellInit
59 *****************************************************************************/
60
61 /*!***********************************************************************
62 @Function PVRShellOutputDebug
63 @Input format printf style format followed by arguments it requires
64 @Description Writes the resultant string to the debug output (e.g. using
65 printf(), OutputDebugString(), ...). Check the SDK release notes for
66 details on how the string is output.
67 *************************************************************************/
PVRShellOutputDebug(char const * const format,...) const68 void PVRShell::PVRShellOutputDebug(char const * const format, ...) const
69 {
70 va_list arg;
71 char buf[1024];
72
73 va_start(arg, format);
74 vsnprintf(buf, 1024, format, arg);
75 va_end(arg);
76
77 // Passes the data to a platform dependant function
78 m_pShellInit->OsDisplayDebugString(buf);
79 }
80
81 /*!***********************************************************************
82 @Function OsInit
83 @description Initialisation for OS-specific code.
84 *************************************************************************/
OsInit()85 void PVRShellInit::OsInit()
86 {
87 m_hAccelTable = 0;
88
89 m_pShell->m_pShellData->nShellDimX = SHELL_DISPLAY_DIM_X;
90 m_pShell->m_pShellData->nShellDimY = SHELL_DISPLAY_DIM_Y;
91
92 m_hDC = 0;
93 m_hWnd = 0;
94
95 // Pixmap support: init variables to 0
96 m_hBmPixmap = 0;
97 m_hBmPixmapOld = 0;
98 m_hDcPixmap = 0;
99
100 /*
101 Construct the binary path for GetReadPath() and GetWritePath()
102 */
103 {
104 /* Allocate memory for strings and return 0 if allocation failed */
105 TCHAR* exeNameTCHAR = new TCHAR[DIR_BUFFER_LEN];
106 char* exeName = new char[DIR_BUFFER_LEN];
107 if(exeNameTCHAR && exeName)
108 {
109 DWORD retSize;
110
111 /*
112 Get the data path and a default application name
113 */
114
115 // Get full path of executable
116 retSize = GetModuleFileName(NULL, exeNameTCHAR, DIR_BUFFER_LEN);
117
118 if (DIR_BUFFER_LEN > (int)retSize)
119 {
120 /* Get string length in char */
121 retSize = (DWORD)_tcslen(exeNameTCHAR);
122
123 /* Convert TChar to char */
124 for (DWORD i = 0; i <= retSize; i++)
125 {
126 exeName[i] = (char)exeNameTCHAR[i];
127 }
128
129 SetAppName(exeName);
130 SetReadPath(exeName);
131 SetWritePath(exeName);
132 }
133 }
134
135 delete [] exeName;
136 delete [] exeNameTCHAR;
137 }
138
139 m_u32ButtonState = 0; // clear mouse button state at startup
140 }
141
142 /*!***********************************************************************
143 @Function OsInitOS
144 @description Saves instance handle and creates main window
145 In this function, we save the instance handle in a global variable and
146 create and display the main program window.
147 *************************************************************************/
OsInitOS()148 bool PVRShellInit::OsInitOS()
149 {
150 MONITORINFO sMInfo;
151 TCHAR *appName;
152 RECT winRect;
153 POINT p;
154
155 MyRegisterClass();
156
157 /*
158 Build the window title
159 */
160 {
161 const char *pszName, *pszSeparator, *pszVersion;
162 size_t len;
163 unsigned int out, in;
164
165 pszName = (const char*)m_pShell->PVRShellGet(prefAppName);
166 pszSeparator = STR_WNDTITLE;
167 pszVersion = (const char*)m_pShell->PVRShellGet(prefVersion);
168
169 len = strlen(pszName)+strlen(pszSeparator)+strlen(pszVersion)+1;
170 appName = new TCHAR[len];
171
172 for(out = 0; (appName[out] = pszName[out]) != 0; ++out);
173 for(in = 0; (appName[out] = pszSeparator[in]) != 0; ++in, ++out);
174 for(in = 0; (appName[out] = pszVersion[in]) != 0; ++in, ++out);
175 _ASSERT(out == len-1);
176 }
177
178 /*
179 Retrieve the monitor information.
180
181 MonitorFromWindow() doesn't work, because the window hasn't been
182 created yet.
183 */
184 {
185 HMONITOR hMonitor;
186 BOOL bRet;
187
188 p.x = m_pShell->m_pShellData->nShellPosX;
189 p.y = m_pShell->m_pShellData->nShellPosY;
190 hMonitor = MonitorFromPoint(p, MONITOR_DEFAULTTOPRIMARY);
191 sMInfo.cbSize = sizeof(sMInfo);
192 bRet = GetMonitorInfo(hMonitor, &sMInfo);
193 _ASSERT(bRet);
194 }
195
196 /*
197 Reduce the window size until it fits on screen
198 */
199 while(
200 (m_pShell->m_pShellData->nShellDimX > (sMInfo.rcMonitor.right - sMInfo.rcMonitor.left)) ||
201 (m_pShell->m_pShellData->nShellDimY > (sMInfo.rcMonitor.bottom - sMInfo.rcMonitor.top)))
202 {
203 m_pShell->m_pShellData->nShellDimX >>= 1;
204 m_pShell->m_pShellData->nShellDimY >>= 1;
205 }
206
207
208 /*
209 Create the window
210 */
211
212 if(m_pShell->m_pShellData->bFullScreen)
213 {
214 m_hWnd = CreateWindow(WINDOW_CLASS, appName, WS_VISIBLE | WS_SYSMENU,CW_USEDEFAULT, CW_USEDEFAULT, m_pShell->m_pShellData->nShellDimX, m_pShell->m_pShellData->nShellDimY,
215 NULL, NULL, m_hInstance, this);
216
217 SetWindowLong(m_hWnd,GWL_STYLE,GetWindowLong(m_hWnd,GWL_STYLE) &~ WS_CAPTION);
218 SetWindowPos(m_hWnd,HWND_NOTOPMOST,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
219 }
220 else
221 {
222 int x, y;
223
224 SetRect(&winRect,
225 m_pShell->m_pShellData->nShellPosX,
226 m_pShell->m_pShellData->nShellPosY,
227 m_pShell->m_pShellData->nShellPosX+m_pShell->m_pShellData->nShellDimX,
228 m_pShell->m_pShellData->nShellPosY+m_pShell->m_pShellData->nShellDimY);
229 AdjustWindowRectEx(&winRect, WS_CAPTION|WS_SYSMENU, false, 0);
230
231 x = m_pShell->m_pShellData->nShellPosX - winRect.left;
232 winRect.left += x;
233 winRect.right += x;
234
235 y = m_pShell->m_pShellData->nShellPosY - winRect.top;
236 winRect.top += y;
237 winRect.bottom += y;
238
239 if(m_pShell->m_pShellData->bShellPosWasDefault)
240 {
241 x = CW_USEDEFAULT;
242 y = CW_USEDEFAULT;
243 }
244 else
245 {
246 x = winRect.left;
247 y = winRect.top;
248 }
249
250 m_hWnd = CreateWindow(WINDOW_CLASS, appName, WS_VISIBLE|WS_CAPTION|WS_SYSMENU,
251 x, y, winRect.right-winRect.left, winRect.bottom-winRect.top, NULL, NULL, m_hInstance, this);
252
253 }
254
255 if(!m_hWnd)
256 return false;
257
258 if(m_pShell->m_pShellData->bFullScreen)
259 {
260 m_pShell->m_pShellData->nShellDimX = sMInfo.rcMonitor.right;
261 m_pShell->m_pShellData->nShellDimY = sMInfo.rcMonitor.bottom;
262 SetWindowPos(m_hWnd,HWND_TOPMOST,0,0,m_pShell->m_pShellData->nShellDimX,m_pShell->m_pShellData->nShellDimY,0);
263 }
264
265 m_hDC = GetDC(m_hWnd);
266 ShowWindow(m_hWnd, m_nCmdShow);
267 UpdateWindow(m_hWnd);
268
269 delete [] appName;
270 return true;
271 }
272
273 /*!***********************************************************************
274 @Function OsReleaseOS
275 @description Destroys main window
276 *************************************************************************/
OsReleaseOS()277 void PVRShellInit::OsReleaseOS()
278 {
279 ReleaseDC(m_hWnd, m_hDC);
280 DestroyWindow(m_hWnd);
281 }
282
283 /*!***********************************************************************
284 @Function OsExit
285 @description Destroys main window
286 *************************************************************************/
OsExit()287 void PVRShellInit::OsExit()
288 {
289 const char *szText;
290
291 /*
292 Show the exit message to the user
293 */
294 szText = (const char*)m_pShell->PVRShellGet(prefExitMessage);
295
296 int i, nT, nC;
297 const char *szCaption;
298 TCHAR *tzText, *tzCaption;
299
300 szCaption = (const char*)m_pShell->PVRShellGet(prefAppName);
301
302 if(!szText || !szCaption)
303 return;
304
305 nT = (int)strlen(szText) + 1;
306 nC = (int)strlen(szCaption) + 1;
307
308 tzText = (TCHAR*)malloc(nT * sizeof(*tzText));
309 tzCaption = (TCHAR*)malloc(nC * sizeof(*tzCaption));
310
311 for(i = 0; (tzText[i] = szText[i]) != 0; ++i);
312 for(i = 0; (tzCaption[i] = szCaption[i]) != 0; ++i);
313
314 MessageBox(NULL, tzText, tzCaption, MB_OK | MB_ICONINFORMATION | MB_SETFOREGROUND);
315
316 FREE(tzText);
317 FREE(tzCaption);
318 }
319
320 /*!***********************************************************************
321 @Function OsDoInitAPI
322 @Return true on success
323 @description Perform API initialisation and bring up window / fullscreen
324 *************************************************************************/
OsDoInitAPI()325 bool PVRShellInit::OsDoInitAPI()
326 {
327
328 // Pixmap support: create the pixmap
329 if(m_pShell->m_pShellData->bNeedPixmap)
330 {
331 m_hDcPixmap = CreateCompatibleDC(m_hDC);
332 m_hBmPixmap = CreateCompatibleBitmap(m_hDC, 640, 480);
333 }
334
335 if(!ApiInitAPI())
336 {
337 return false;
338 }
339
340 // Pixmap support: select the pixmap into a device context (DC) ready for blitting
341 if(m_pShell->m_pShellData->bNeedPixmap)
342 {
343 m_hBmPixmapOld = (HBITMAP)SelectObject(m_hDcPixmap, m_hBmPixmap);
344 }
345
346 SetForegroundWindow(m_hWnd);
347
348 /* No problem occured */
349 return true;
350 }
351
352 /*!***********************************************************************
353 @Function OsDoReleaseAPI
354 @description Clean up after we're done
355 *************************************************************************/
OsDoReleaseAPI()356 void PVRShellInit::OsDoReleaseAPI()
357 {
358 ApiReleaseAPI();
359
360 if(m_pShell->m_pShellData->bNeedPixmap)
361 {
362 // Pixmap support: free the pixmap
363 SelectObject(m_hDcPixmap, m_hBmPixmapOld);
364 DeleteDC(m_hDcPixmap);
365 DeleteObject(m_hBmPixmap);
366 }
367 }
368
369 /*!***********************************************************************
370 @Function OsRenderComplete
371 @Returns false when the app should quit
372 @description Main message loop / render loop
373 *************************************************************************/
OsRenderComplete()374 void PVRShellInit::OsRenderComplete()
375 {
376 MSG msg;
377
378 /*
379 Process the message queue
380 */
381 while(PeekMessage(&msg, m_hWnd, 0, 0, PM_REMOVE))
382 {
383 if (!TranslateAccelerator(msg.hwnd, m_hAccelTable, &msg))
384 {
385 TranslateMessage(&msg);
386 DispatchMessage(&msg);
387 }
388 }
389
390 }
391
392 /*!***********************************************************************
393 @Function OsPixmapCopy
394 @Return true if the copy succeeded
395 @description When using pixmaps, copy the render to the display
396 *************************************************************************/
OsPixmapCopy()397 bool PVRShellInit::OsPixmapCopy()
398 {
399 return (BitBlt(m_hDC, 0, 0, 640, 480, m_hDcPixmap, 0, 0, SRCCOPY) == TRUE);
400 }
401
402 /*!***********************************************************************
403 @Function OsGetNativeDisplayType
404 @Return The 'NativeDisplayType' for EGL
405 @description Called from InitAPI() to get the NativeDisplayType
406 *************************************************************************/
OsGetNativeDisplayType()407 void *PVRShellInit::OsGetNativeDisplayType()
408 {
409 return m_hDC;
410 }
411
412 /*!***********************************************************************
413 @Function OsGetNativePixmapType
414 @Return The 'NativePixmapType' for EGL
415 @description Called from InitAPI() to get the NativePixmapType
416 *************************************************************************/
OsGetNativePixmapType()417 void *PVRShellInit::OsGetNativePixmapType()
418 {
419 // Pixmap support: return the pixmap
420 return m_hBmPixmap;
421 }
422
423 /*!***********************************************************************
424 @Function OsGetNativeWindowType
425 @Return The 'NativeWindowType' for EGL
426 @description Called from InitAPI() to get the NativeWindowType
427 *************************************************************************/
OsGetNativeWindowType()428 void *PVRShellInit::OsGetNativeWindowType()
429 {
430 return m_hWnd;
431 }
432
433 /*!***********************************************************************
434 @Function OsGet
435 @Input prefName Name of value to get
436 @Modified pn A pointer set to the value asked for
437 @Returns true on success
438 @Description Retrieves OS-specific data
439 *************************************************************************/
OsGet(const prefNameIntEnum prefName,int * pn)440 bool PVRShellInit::OsGet(const prefNameIntEnum prefName, int *pn)
441 {
442 switch(prefName)
443 {
444 case prefButtonState:
445 *pn = m_u32ButtonState;
446 return true;
447 };
448 return false;
449 }
450
451 /*!***********************************************************************
452 @Function OsSet
453 @Input prefName Name of preference to set to value
454 @Input value Value
455 @Return true for success
456 @Description Sets OS-specific data
457 *************************************************************************/
OsSet(const prefNameBoolEnum prefName,const bool value)458 bool PVRShellInit::OsSet(const prefNameBoolEnum prefName, const bool value)
459 {
460 switch(prefName)
461 {
462 case prefShowCursor:
463 ShowCursor(value ? TRUE : FALSE);
464 return true;
465 }
466
467 return false;
468 }
469
470 /*!***********************************************************************
471 @Function OsSet
472 @Input prefName Name of value to set
473 @Input i32Value The value to set our named value to
474 @Returns true on success
475 @Description Sets OS-specific data
476 *************************************************************************/
OsSet(const prefNameIntEnum prefName,const int i32Value)477 bool PVRShellInit::OsSet(const prefNameIntEnum prefName, const int i32Value)
478 {
479 PVRSHELL_UNREFERENCED_PARAMETER(prefName);
480 PVRSHELL_UNREFERENCED_PARAMETER(i32Value);
481 return false;
482 }
483
484 /*!***********************************************************************
485 @Function OsGet
486 @Input prefName Name of value to get
487 @Modified pp A pointer set to the value asked for
488 @Returns true on success
489 @Description Retrieves OS-specific data
490 *************************************************************************/
OsGet(const prefNamePtrEnum prefName,void ** pp)491 bool PVRShellInit::OsGet(const prefNamePtrEnum prefName, void **pp)
492 {
493 switch(prefName)
494 {
495 case prefHINSTANCE:
496 *pp = m_hInstance;
497 return true;
498 default:
499 return false;
500 }
501 }
502
503 /*!***********************************************************************
504 @Function OsDisplayDebugString
505 @Input str string to output
506 @Description Prints a debug string
507 *************************************************************************/
OsDisplayDebugString(char const * const str)508 void PVRShellInit::OsDisplayDebugString(char const * const str)
509 {
510 if(str)
511 {
512 #if defined(UNICODE)
513 wchar_t strc[1024];
514 int i;
515
516 for(i = 0; (str[i] != '\0') && (i < (sizeof(strc) / sizeof(*strc))); ++i)
517 {
518 strc[i] = (wchar_t)str[i];
519 }
520
521 strc[i] = '\0';
522
523 OutputDebugString(strc);
524 #else
525 OutputDebugString(str);
526 #endif
527 }
528 }
529
530 /*!***********************************************************************
531 @Function OsGetTime
532 @Return An incrementing time value measured in milliseconds
533 @Description Returns an incrementing time value measured in milliseconds
534 *************************************************************************/
OsGetTime()535 unsigned long PVRShellInit::OsGetTime()
536 {
537 return (unsigned long)GetTickCount();
538 }
539
540 /*****************************************************************************
541 Class: PVRShellInitOS
542 *****************************************************************************/
543
544 /*!******************************************************************************************
545 @function MyRegisterClass()
546 @description Registers the window class.
547 This function and its usage is only necessary if you want this code
548 to be compatible with Win32 systems prior to the 'RegisterClassEx'
549 function that was added to Windows 95. It is important to call this function
550 so that the application will get 'well formed' small icons associated
551 with it.
552 **********************************************************************************************/
MyRegisterClass()553 ATOM PVRShellInitOS::MyRegisterClass()
554 {
555 WNDCLASS wc;
556
557 wc.style = CS_HREDRAW | CS_VREDRAW;
558 wc.lpfnWndProc = (WNDPROC)WndProc;
559 wc.cbClsExtra = 0;
560 wc.cbWndExtra = 0;
561 wc.hInstance = m_hInstance;
562 wc.hIcon = LoadIcon(m_hInstance, _T("ICON"));
563 wc.hCursor = 0;
564 wc.lpszMenuName = 0;
565 wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
566 wc.lpszClassName = WINDOW_CLASS;
567
568 return RegisterClass(&wc);
569 }
570
571 /*****************************************************************************
572 Global code
573 *****************************************************************************/
doButtonDown(HWND hWnd,PVRShellInit * pData,EPVRShellButtonState eButton,LPARAM lParam)574 void doButtonDown(HWND hWnd, PVRShellInit *pData, EPVRShellButtonState eButton, LPARAM lParam)
575 {
576 RECT rcWinDimensions;
577 GetClientRect(hWnd,&rcWinDimensions);
578 float vec2TouchPosition[2] = { (float)(short)LOWORD(lParam)/(float)(rcWinDimensions.right), (float)(short)HIWORD(lParam)/(float)(rcWinDimensions.bottom) };
579 pData->TouchBegan(vec2TouchPosition);
580 SetCapture(hWnd); // must be within window so capture
581 pData->m_u32ButtonState |= eButton;
582 }
583
doButtonUp(HWND hWnd,PVRShellInit * pData,EPVRShellButtonState eButton,LPARAM lParam)584 bool doButtonUp(HWND hWnd, PVRShellInit *pData, EPVRShellButtonState eButton, LPARAM lParam)
585 {
586 RECT rcWinDimensions;
587 GetClientRect(hWnd,&rcWinDimensions);
588 float vec2TouchPosition[2] = { (float)(short)LOWORD(lParam)/(float)(rcWinDimensions.right), (float)(short)HIWORD(lParam)/(float)(rcWinDimensions.bottom) };
589 pData->TouchEnded(vec2TouchPosition);
590 pData->m_u32ButtonState &= (~eButton);
591
592 if(vec2TouchPosition[0] < 0.f || vec2TouchPosition[0] > 1.f || vec2TouchPosition[1] < 0.f || vec2TouchPosition[1] > 1.f)
593 { // pointer has left window
594 if(pData->m_u32ButtonState==0)
595 { // only release capture if mouse buttons have been released
596 ReleaseCapture();
597 }
598
599 return false;
600 }
601 return true;
602 }
603
604 /*!***************************************************************************
605 @function WndProc
606 @input hWnd Handle to the window
607 @input message Specifies the message
608 @input wParam Additional message information
609 @input lParam Additional message information
610 @returns result code to OS
611 @description Processes messages for the main window.
612 *****************************************************************************/
WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)613 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
614 {
615 PVRShellInit *pData = (PVRShellInit*) GetWindowLongPtr(hWnd, GWLP_USERDATA);
616
617 switch (message)
618 {
619 case WM_CREATE:
620 {
621 CREATESTRUCT *pCreate = (CREATESTRUCT*)lParam;
622 SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)pCreate->lpCreateParams);
623 break;
624 }
625 case WM_PAINT:
626 break;
627 case WM_DESTROY:
628 return 0;
629 case WM_CLOSE:
630 pData->gShellDone = true;
631 return 0;
632 case WM_QUIT:
633 return 0;
634 case WM_MOVE:
635 pData->m_pShell->PVRShellSet(prefPositionX, (int)LOWORD(lParam));
636 pData->m_pShell->PVRShellSet(prefPositionY, (int)HIWORD(lParam));
637 break;
638 case WM_LBUTTONDOWN:
639 {
640 doButtonDown(hWnd,pData,ePVRShellButtonLeft,lParam);
641 break;
642 }
643 case WM_LBUTTONUP:
644 {
645 if(!doButtonUp(hWnd,pData,ePVRShellButtonLeft,lParam))
646 return false;
647 break;
648 }
649 case WM_RBUTTONDOWN:
650 {
651 doButtonDown(hWnd,pData,ePVRShellButtonRight,lParam);
652 break;
653 }
654 case WM_RBUTTONUP:
655 {
656 if(!doButtonUp(hWnd,pData,ePVRShellButtonRight,lParam))
657 return false;
658 break;
659 }
660 case WM_MBUTTONDOWN:
661 {
662 doButtonDown(hWnd,pData,ePVRShellButtonMiddle,lParam);
663 break;
664 }
665 case WM_MBUTTONUP:
666 {
667 if(!doButtonUp(hWnd,pData,ePVRShellButtonMiddle,lParam))
668 return false;
669 break;
670 }
671 case WM_MOUSEMOVE:
672 {
673 RECT rcWinDimensions;
674 GetClientRect(hWnd,&rcWinDimensions);
675 float vec2TouchPosition[2] = { (float)(short)LOWORD(lParam)/(float)(rcWinDimensions.right), (float)(short)HIWORD(lParam)/(float)(rcWinDimensions.bottom) };
676
677 if(vec2TouchPosition[0] < 0.f || vec2TouchPosition[0] > 1.f || vec2TouchPosition[1] < 0.f || vec2TouchPosition[1] > 1.f)
678 {
679 // pointer has left window
680 if(pData->m_u32ButtonState==0)
681 { // only release capture if mouse buttons have been released
682 ReleaseCapture();
683 }
684
685 pData->TouchEnded(vec2TouchPosition);
686 return false;
687 }
688 else
689 { // pointer is inside window
690 pData->TouchMoved(vec2TouchPosition);
691 }
692 break;
693 }
694 case WM_SETFOCUS:
695 pData->m_bHaveFocus = true;
696 return 0;
697 case WM_KILLFOCUS:
698 pData->m_bHaveFocus = false;
699 return 0;
700 case WM_KEYDOWN:
701 {
702 switch(wParam)
703 {
704 case VK_ESCAPE:
705 case 0xC1:
706 pData->KeyPressed(PVRShellKeyNameQUIT);
707 break;
708 case VK_UP:
709 case 0x35:
710 pData->KeyPressed(pData->m_eKeyMapUP);
711 break;
712 case VK_DOWN:
713 case 0x30:
714 pData->KeyPressed(pData->m_eKeyMapDOWN);
715 break;
716 case VK_LEFT:
717 case 0x37:
718 pData->KeyPressed(pData->m_eKeyMapLEFT);
719 break;
720 case VK_RIGHT:
721 case 0x39:
722 pData->KeyPressed(pData->m_eKeyMapRIGHT);
723 break;
724 case VK_SPACE:
725 case 0x38:
726 pData->KeyPressed(PVRShellKeyNameSELECT);
727 break;
728 case '1':
729 case 0x34:
730 pData->KeyPressed(PVRShellKeyNameACTION1);
731 break;
732 case '2':
733 case 0x36:
734 pData->KeyPressed(PVRShellKeyNameACTION2);
735 break;
736 case VK_F11:
737 case 0xC2:
738 pData->KeyPressed(PVRShellKeyNameScreenshot);
739 break;
740 }
741 }
742 default:
743 break;
744 }
745
746 return DefWindowProc(hWnd, message, wParam, lParam);
747 }
748
749 /*!***************************************************************************
750 @function WinMain
751 @input hInstance Application instance from OS
752 @input hPrevInstance Always NULL
753 @input lpCmdLine command line from OS
754 @input nCmdShow Specifies how the window is to be shown
755 @returns result code to OS
756 @description Main function of the program
757 *****************************************************************************/
WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,TCHAR * lpCmdLine,int nCmdShow)758 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, TCHAR *lpCmdLine, int nCmdShow)
759 {
760 size_t i;
761 char *pszCmdLine;
762 PVRShellInit init;
763
764 PVRSHELL_UNREFERENCED_PARAMETER(hPrevInstance);
765
766 #if defined(_WIN32)
767 // Enable memory-leak reports
768 _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG));
769 #endif
770
771 // Get a char-array command line as the input may be UNICODE
772 i = _tcslen(lpCmdLine) + 1;
773 pszCmdLine = new char[i];
774
775 while(i)
776 {
777 --i;
778 pszCmdLine[i] = (char)lpCmdLine[i];
779 }
780
781 // Init the demo, process the command line, create the OS initialiser.
782 if(!init.Init())
783 {
784 delete[] pszCmdLine;
785 return EXIT_ERR_CODE;
786 }
787
788 init.CommandLine(pszCmdLine);
789 init.m_hInstance = hInstance;
790 init.m_nCmdShow = nCmdShow;
791
792 // Initialise/run/shutdown
793 while(init.Run());
794
795 delete[] pszCmdLine;
796
797 return EXIT_NOERR_CODE;
798 }
799
800 /// @endcond
801
802 /*****************************************************************************
803 End of file (PVRShellOS.cpp)
804 *****************************************************************************/
805
806