Advertisement
Guest User

Untitled

a guest
Sep 22nd, 2017
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.71 KB | None | 0 0
  1. //===========================================================================
  2. // EVideo.h
  3. //
  4. //  Video subsystem.  Responsible for enumerating possible display modes,
  5. //  creating the window, and processing window events.
  6. //===========================================================================
  7. #pragma once
  8.  
  9. #include "utils/PsMem.h"
  10. //===========================================================================
  11. // 'VidMode' - describes video settings.
  12. //===========================================================================
  13. class VidMode : public EngineMemalloc
  14. {
  15. public:
  16.     inline VidMode();
  17.  
  18.     physx::PxU32    width;
  19.     physx::PxU32    height;
  20.     physx::PxU32    screenWidth;
  21.     physx::PxU32    screenHeight;
  22.     bool            fullscreen;
  23. };
  24.  
  25. //---------------------------------------------------------------------------
  26. VidMode::VidMode()
  27. : width( 0 )
  28. , height( 0 )
  29. , screenWidth( 0 )
  30. , screenHeight( 0 )
  31. , fullscreen( 0 )
  32. {
  33. }
  34.  
  35. extern void     VidMode_Init( VidMode* p,
  36.                              physx::PxU32 width, physx::PxU32 height,
  37.                              bool fullscreen );
  38.  
  39. //===========================================================================
  40. // 'VidContext' - represents a window instance.
  41. //===========================================================================
  42. class VidContext;
  43.  
  44. // TODO
  45. //extern bool               Vid_EnumModes( VidMode& outMode );
  46.  
  47. // creates a window and applies the specified video mode.
  48. // (For OpenGL rendering, set 'createGLContext' to true.)
  49. extern VidContext*          Vid_Startup( VidMode* mode, bool createGLContext, void* wndProc );
  50. extern void                 Vid_Shutdown( VidContext* ctx );
  51.  
  52. // returns whether the window is focused.
  53. extern bool                 Vid_HasFocus( VidContext* ctx );
  54.  
  55. // processes the window events.
  56. extern bool                 Vid_DoEvents( VidContext* ctx );
  57.  
  58. extern bool                 Vid_SwapBuffers( VidContext* ctx );
  59.  
  60. // returns the video mode associated with the window.
  61. extern const VidMode*       Vid_GetCurrentMode( VidContext* ctx );
  62. extern PxU32                Vid_GetScreenWidth( VidContext* ctx );
  63. extern PxU32                Vid_GetScreenHeight( VidContext* ctx );
  64.  
  65. // sets the title of the window.
  66. extern void                 Vid_SetWindowTitle( VidContext* ctx, const char* title );
  67.  
  68. // brings the window to the front.
  69. extern void                 Vid_Focus( VidContext* ctx );
  70.  
  71.  
  72.  
  73.  
  74.  
  75.  
  76. //===========================================================================
  77. // EVideo_win.cpp
  78. //
  79. //  Win32 implementation.
  80. //===========================================================================
  81. //===========================================================================
  82. // vid_win.cpp
  83. //
  84. //  Windows implementation of the Video subsystem.
  85. //===========================================================================
  86. #include "Common/common_afx.h"
  87. #include "Engine/EVideo.h"
  88. #include "Engine/EConsole.h"
  89. #include "Engine/ECvar.h"
  90.  
  91. // Unicode headers.
  92. #include "Common/UUnicode.h"
  93.  
  94. // Windows headers.
  95. #define WIN32_LEAN_AND_MEAN
  96. #include <windows.h>
  97.  
  98. // standard headers.
  99. #include <stdlib.h> // itoa()
  100.  
  101. // GL libraries.
  102. #pragma comment( lib, "OpenGL32.lib" )
  103.  
  104. // file-local globals.
  105. static HGLRC    _currentRC;
  106.  
  107. // constants.
  108. typedef WCHAR           USECHAR;
  109. static const USECHAR    WINDOW_CLASS_BASE_NAME[] = TEXT( "GLWindow" );
  110.  
  111. EXTERN_CVAR_BOOL( vid_enabled );
  112.  
  113. //===========================================================================
  114. // VidMode
  115. //===========================================================================
  116.  
  117. //---------------------------------------------------------------------------
  118. void
  119. VidMode_Init( VidMode* p,
  120.              physx::PxU32 width, physx::PxU32 height,
  121.              bool fullscreen )
  122. {
  123.     MemZero( p, sizeof( VidMode ) );
  124.     p->width            = width;
  125.     p->height           = height;
  126.     p->screenWidth      = width;
  127.     p->screenHeight     = height;
  128.     p->fullscreen       = fullscreen;
  129. }
  130.  
  131. //===========================================================================
  132. // VidContext
  133. //===========================================================================
  134. class VidContext : public EngineMemalloc
  135. {
  136. public:
  137.     VidContext();
  138.  
  139.     VidMode     mMode;
  140.  
  141.     HINSTANCE   mInstance;
  142.  
  143.     HWND        mWindow;
  144.     HDC         mWindowDC;
  145.     HGLRC       mWindowRC;
  146.     WNDPROC     mWindowProc;
  147.     USECHAR*    mWindowClass;
  148.  
  149.     bool        mHasFocus;
  150. };
  151.  
  152. //---------------------------------------------------------------------------
  153. VidContext::VidContext()
  154. : mInstance( NULL )
  155. , mWindow( NULL )
  156. , mWindowDC( NULL )
  157. , mWindowRC( NULL )
  158. , mWindowProc( NULL )
  159. , mWindowClass( L"Duatiu" )
  160. , mHasFocus( false )
  161. {
  162. }
  163.  
  164. //---------------------------------------------------------------------------
  165. VidContext*
  166. Vid_Startup( VidMode* mode, bool createGLContext, void* wndProc )
  167. {
  168.     // validate inputs.
  169.     PX_ASSERT( mode != NULL );
  170.     PX_ASSERT( wndProc != NULL );
  171.     if ( wndProc == NULL )
  172.         return NULL;
  173.  
  174.     // get the handle to the program instance.
  175.     HINSTANCE hInstance = GetModuleHandle( NULL );
  176.     HWND hWnd = NULL;
  177.     PxU32 windowWidth = 0;
  178.     PxU32 windowHeight = 1;
  179.     HDC hDC = NULL;
  180.     HGLRC hRC = NULL;
  181.     USECHAR wndClassName[ 512 ] = { '\0' };
  182.  
  183.     if ( vid_enabled )
  184.     {
  185.         // generate a window class name.
  186.         {
  187.             size_t len = wcslen( WINDOW_CLASS_BASE_NAME );
  188.             PX_ASSERT( len < (512 - 32) );
  189.  
  190.             // copy the base class name.
  191.             wcscpy_s( wndClassName, 512, WINDOW_CLASS_BASE_NAME );
  192.  
  193.             // append an incrementing number.
  194.             static physx::PxI32 kCurCount = 0;
  195.             ++kCurCount;
  196.             _itow_s( kCurCount, wndClassName + len, 511 - len, 10 );
  197.         }
  198.         PX_ASSERT( wndClassName != NULL );
  199.  
  200.         char wndClassNameA[ 512 ];
  201.         Uni_Wide2ASCII( wndClassNameA, wndClassName, 512 );
  202.         Console.Std << "Video Startup:"
  203.             << Newl << "\tPlatform: Win32"
  204.             << Newl << "\tResolution: " << mode->width << "x" << mode->height
  205.             << Newl << "\tFullscreen: " << mode->fullscreen
  206.             << Newl;
  207.  
  208.         // register the window class.
  209.         {
  210.             WNDCLASS wc;
  211.             wc.style            = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
  212.             wc.lpfnWndProc      = (WNDPROC)wndProc;
  213.             wc.cbClsExtra       = 0;
  214.             wc.cbWndExtra       = 0;
  215.             wc.hInstance        = hInstance;
  216.             wc.hIcon            = LoadIcon( NULL, IDI_WINLOGO );
  217.             wc.hCursor          = LoadCursor( NULL, IDC_ARROW );
  218.             wc.hbrBackground    = NULL;
  219.             wc.lpszMenuName     = NULL;
  220.             wc.lpszClassName    = wndClassName;
  221.             if ( !RegisterClass( &wc ) )
  222.             {
  223.                 Console.Gfx.Err << "Failed to register window class" << Newl;
  224.                 return NULL;
  225.             }
  226.         }
  227.  
  228.         if ( mode->fullscreen )
  229.         {
  230.             // switch to fullscreen.
  231.             DEVMODE dm;
  232.             memset( &dm, 0, sizeof( dm ) );
  233.             dm.dmSize           = sizeof( dm );
  234.             dm.dmPelsWidth      = mode->width;
  235.             dm.dmPelsHeight     = mode->height;
  236.             dm.dmBitsPerPel     = 32;
  237.             dm.dmFields         = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
  238.             if ( DISP_CHANGE_SUCCESSFUL != ChangeDisplaySettings( &dm, CDS_FULLSCREEN ) )
  239.             {
  240.                 Console.Gfx.Err << "Failed to switch to fullscreen mode" << Newl;
  241.                 return NULL;
  242.             }
  243.         }
  244.  
  245.         // select desired window characteristics.
  246.         DWORD dwStyle;
  247.         if ( !mode->fullscreen )
  248.         {
  249.             // non-fullscreen window style:
  250.             // - has title bar.
  251.             // - has minimize / maximize buttons.
  252.             // - no system menu.
  253.             // - no resizing.
  254.             dwStyle = WS_OVERLAPPEDWINDOW & ~WS_OVERLAPPED & ~WS_THICKFRAME;
  255.         }
  256.         else
  257.         {
  258.             // fullscreen window style:
  259.             // - no elements.
  260.             dwStyle = WS_POPUP;
  261.         }
  262.  
  263.         // calculate the window dimensions such that that the number of rendered pixels
  264.         // is exactly (width * height).
  265.         RECT windowRect;
  266.         windowRect.left     = 0;
  267.         windowRect.top      = 0;
  268.         windowRect.right    = mode->width;
  269.         windowRect.bottom   = mode->height;
  270.         AdjustWindowRect( &windowRect, dwStyle, FALSE );
  271.         windowWidth         = windowRect.right - windowRect.left;
  272.         windowHeight        = windowRect.bottom - windowRect.top;
  273.  
  274.         // create the window.
  275.         const physx::PxI32 kWindowX = 0, kWindowY = 0;
  276.  
  277.         hWnd = CreateWindow(
  278.             wndClassName,
  279.             TEXT( "" ),
  280.             dwStyle | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
  281.             kWindowX, kWindowY,
  282.             windowWidth, windowHeight,
  283.             NULL,   // parent.
  284.             NULL,   // menu.
  285.             hInstance,
  286.             NULL );
  287.         if ( !hWnd )
  288.         {
  289.             Console.Gfx.Err << "Window creation failed" << Newl;
  290.             if ( mode->fullscreen )
  291.                 ChangeDisplaySettings( NULL, 0 );
  292.             return NULL;
  293.         }
  294.  
  295.         // get the device context.
  296.         hDC = GetDC( hWnd );
  297.         if ( !hDC )
  298.         {
  299.             Console.Gfx.Err << "GetDC failed" << Newl;
  300.             DestroyWindow( hWnd );
  301.             if ( mode->fullscreen )
  302.                 ChangeDisplaySettings( NULL, 0 );
  303.             return NULL;
  304.         }
  305.  
  306.         // create the GL rendering context, if necessary.
  307.         if ( createGLContext )
  308.         {
  309.             // choose the pixel format.
  310.             PIXELFORMATDESCRIPTOR pfd =
  311.             {
  312.                 sizeof( PIXELFORMATDESCRIPTOR ),
  313.                 1,
  314.                 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
  315.                 PFD_TYPE_RGBA,
  316.                 32,
  317.                 0, 0, 0, 0, 0, 0,
  318.                 0,
  319.                 0,
  320.                 0,
  321.                 0, 0, 0, 0,
  322.                 24,
  323.                 0,
  324.                 0,
  325.                 PFD_MAIN_PLANE,
  326.                 0,
  327.                 0, 0, 0
  328.             };
  329.             physx::PxI32 pixelFormat = ChoosePixelFormat( hDC, &pfd );
  330.             if ( !pixelFormat )
  331.             {
  332.                 Console.Gfx.Err << "ChoosePixelFormat failed" << Newl;
  333.                 ReleaseDC( hWnd, hDC );
  334.                 DestroyWindow( hWnd );
  335.                 if ( mode->fullscreen )
  336.                     ChangeDisplaySettings( NULL, 0 );
  337.                 return NULL;
  338.             }
  339.             if ( !SetPixelFormat( hDC, pixelFormat, &pfd ) )
  340.             {
  341.                 Console.Gfx.Err << "SetPixelFormat failed" << Newl;
  342.                 ReleaseDC( hWnd, hDC );
  343.                 DestroyWindow( hWnd );
  344.                 if ( mode->fullscreen )
  345.                     ChangeDisplaySettings( NULL, 0 );
  346.                 return NULL;
  347.             }
  348.  
  349.             // create a new GL rendering context for the window.
  350.             hRC = wglCreateContext( hDC );
  351.             if ( !hRC )
  352.             {
  353.                 Console.Gfx.Err << "wglCreateContext failed" << Newl;
  354.                 ReleaseDC( hWnd, hDC );
  355.                 DestroyWindow( hWnd );
  356.                 if ( mode->fullscreen )
  357.                     ChangeDisplaySettings( NULL, 0 );
  358.                 return NULL;
  359.             }
  360.  
  361.             // begin rendering to that window.
  362.             if ( !wglMakeCurrent( hDC, hRC ) )
  363.             {
  364.                 Console.Gfx.Err << "wglMakeCurrent failed" << Newl;
  365.                 wglDeleteContext( hRC );
  366.                 ReleaseDC( hWnd, hDC );
  367.                 DestroyWindow( hWnd );
  368.                 if ( mode->fullscreen )
  369.                     ChangeDisplaySettings( NULL, 0 );
  370.                 return NULL;
  371.             }
  372.             _currentRC = hRC;
  373.         }
  374.  
  375.         // show the window.
  376.         ShowWindow( hWnd, SW_SHOW );
  377.     }
  378.  
  379.     // store the specified window width and height.
  380.     mode->screenWidth = windowWidth;
  381.     mode->screenHeight = windowHeight;
  382.  
  383.     VidContext* ret = PS_NEW( VidContext );
  384.     ret->mInstance      = hInstance;
  385.     ret->mMode          = *mode;
  386.     ret->mWindow        = hWnd;
  387.     ret->mWindowDC      = hDC;
  388.     ret->mWindowRC      = hRC;
  389.     ret->mWindowProc    = (WNDPROC)wndProc;
  390.     ret->mWindowClass   = (USECHAR *)PS_ALLOC_ENGINE( sizeof(USECHAR)* 512,"WindowClass" );
  391.     ret->mHasFocus      = true;
  392.     wcscpy_s( ret->mWindowClass, 512, wndClassName );
  393.     return ret;
  394. }
  395.  
  396. //---------------------------------------------------------------------------
  397. void
  398. Vid_Shutdown( VidContext* ctx )
  399. {
  400.     if ( ctx == NULL )
  401.         return;
  402.  
  403.     if ( vid_enabled )
  404.     {
  405.         if ( ctx->mMode.fullscreen )
  406.         {
  407.             // exit fullscreen.
  408.             ChangeDisplaySettings( NULL, 0 );
  409.         }
  410.  
  411.         // destroy the GL context.
  412.         if ( ctx->mWindowRC )
  413.         {
  414.             if ( _currentRC == ctx->mWindowRC )
  415.             {
  416.                 wglMakeCurrent( NULL, NULL );
  417.                 _currentRC = NULL;
  418.             }
  419.  
  420.             wglDeleteContext( ctx->mWindowRC );
  421.             ctx->mWindowRC = NULL;
  422.         }
  423.  
  424.         // destroy the device context.
  425.         if ( ctx->mWindowDC )
  426.         {
  427.             ReleaseDC( ctx->mWindow, ctx->mWindowDC );
  428.             ctx->mWindowDC = NULL;
  429.         }
  430.  
  431.         // destroy the window.
  432.         if ( ctx->mWindow )
  433.         {
  434.             DestroyWindow( ctx->mWindow );
  435.             ctx->mWindow = NULL;
  436.         }
  437.  
  438.         // unregister the window class.
  439.         {
  440.             UnregisterClass( ctx->mWindowClass, ctx->mInstance );
  441.             PS_FREE_ENGINE( ctx->mWindowClass );
  442.         }
  443.     }
  444.  
  445.     delete ctx;
  446. }
  447.  
  448. //---------------------------------------------------------------------------
  449. extern bool
  450. Vid_HasFocus( VidContext* ctx )
  451. {
  452.     return ctx->mHasFocus;
  453. }
  454.  
  455. //---------------------------------------------------------------------------
  456. bool
  457. Vid_DoEvents( VidContext* ctx )
  458. {
  459.     if ( !ctx )
  460.         return false;
  461.  
  462.     if ( vid_enabled )
  463.     {
  464.         PX_ASSERT( ctx->mWindow );
  465.         if ( !ctx->mWindow )
  466.             return false;
  467.  
  468.         MSG msg;
  469.         // process each pending window message.
  470.         while ( PeekMessage( &msg, ctx->mWindow, 0, 0, PM_NOREMOVE ) )
  471.         {
  472.             // if we've just processed a quit message, abort.
  473.             if ( GetMessage( &msg, ctx->mWindow, 0, 0 ) )
  474.             {
  475.                 TranslateMessage( &msg );
  476.                 DispatchMessage( &msg );
  477.             }
  478.             else
  479.             {
  480.                 break;
  481.             }
  482.         }
  483.  
  484.         if ( GetActiveWindow() == ctx->mWindow )
  485.             ctx->mHasFocus = true;
  486.         else
  487.             ctx->mHasFocus = false;
  488.     }
  489.  
  490.     return true;
  491. }
  492.  
  493. //---------------------------------------------------------------------------
  494. bool
  495. Vid_SwapBuffers( VidContext* ctx )
  496. {
  497.     if ( !ctx )
  498.         return false;
  499.  
  500.     if ( vid_enabled )
  501.     {
  502.         PX_ASSERT( ctx->mWindowDC );
  503.         if ( !ctx->mWindowDC )
  504.             return false;
  505.  
  506.         if ( !SwapBuffers( ctx->mWindowDC ) )
  507.         {
  508.             Console.Gfx.Err << "SwapBuffers failed" << Newl;
  509.             return false;
  510.         }
  511.     }
  512.     return true;
  513. }
  514.  
  515. //---------------------------------------------------------------------------
  516. const VidMode*
  517. Vid_GetCurrentMode( VidContext* ctx )
  518. {
  519.     PX_ASSERT( ctx != NULL );
  520.     return &(ctx->mMode);
  521. }
  522.  
  523. //---------------------------------------------------------------------------
  524. PxU32
  525. Vid_GetScreenWidth( VidContext* ctx )
  526. {
  527.     PX_ASSERT( ctx != NULL );
  528.     return ctx->mMode.screenWidth;
  529. }
  530.  
  531. //---------------------------------------------------------------------------
  532. PxU32
  533. Vid_GetScreenHeight( VidContext* ctx )
  534. {
  535.     PX_ASSERT( ctx != NULL );
  536.     if ( !ctx )
  537.         return 0;
  538.  
  539.     return ctx->mMode.screenHeight;
  540. }
  541.  
  542. //---------------------------------------------------------------------------
  543. void
  544. Vid_SetWindowTitle( VidContext* ctx, const char* title )
  545. {
  546.     if ( !ctx )
  547.         return;
  548.  
  549.     if ( vid_enabled )
  550.     {
  551.         PX_ASSERT( ctx->mWindow );
  552.         SetWindowTextA( ctx->mWindow, title );
  553.     }
  554. }
  555.  
  556. //---------------------------------------------------------------------------
  557. void
  558. Vid_Focus( VidContext* ctx )
  559. {
  560.     if ( !ctx )
  561.         return;
  562.  
  563.     if ( vid_enabled )
  564.     {
  565.         PX_ASSERT( ctx->mWindow );
  566.         SetFocus( ctx->mWindow );
  567.     }
  568. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement