Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //===========================================================================
- // EVideo.h
- //
- // Video subsystem. Responsible for enumerating possible display modes,
- // creating the window, and processing window events.
- //===========================================================================
- #pragma once
- #include "utils/PsMem.h"
- //===========================================================================
- // 'VidMode' - describes video settings.
- //===========================================================================
- class VidMode : public EngineMemalloc
- {
- public:
- inline VidMode();
- physx::PxU32 width;
- physx::PxU32 height;
- physx::PxU32 screenWidth;
- physx::PxU32 screenHeight;
- bool fullscreen;
- };
- //---------------------------------------------------------------------------
- VidMode::VidMode()
- : width( 0 )
- , height( 0 )
- , screenWidth( 0 )
- , screenHeight( 0 )
- , fullscreen( 0 )
- {
- }
- extern void VidMode_Init( VidMode* p,
- physx::PxU32 width, physx::PxU32 height,
- bool fullscreen );
- //===========================================================================
- // 'VidContext' - represents a window instance.
- //===========================================================================
- class VidContext;
- // TODO
- //extern bool Vid_EnumModes( VidMode& outMode );
- // creates a window and applies the specified video mode.
- // (For OpenGL rendering, set 'createGLContext' to true.)
- extern VidContext* Vid_Startup( VidMode* mode, bool createGLContext, void* wndProc );
- extern void Vid_Shutdown( VidContext* ctx );
- // returns whether the window is focused.
- extern bool Vid_HasFocus( VidContext* ctx );
- // processes the window events.
- extern bool Vid_DoEvents( VidContext* ctx );
- extern bool Vid_SwapBuffers( VidContext* ctx );
- // returns the video mode associated with the window.
- extern const VidMode* Vid_GetCurrentMode( VidContext* ctx );
- extern PxU32 Vid_GetScreenWidth( VidContext* ctx );
- extern PxU32 Vid_GetScreenHeight( VidContext* ctx );
- // sets the title of the window.
- extern void Vid_SetWindowTitle( VidContext* ctx, const char* title );
- // brings the window to the front.
- extern void Vid_Focus( VidContext* ctx );
- //===========================================================================
- // EVideo_win.cpp
- //
- // Win32 implementation.
- //===========================================================================
- //===========================================================================
- // vid_win.cpp
- //
- // Windows implementation of the Video subsystem.
- //===========================================================================
- #include "Common/common_afx.h"
- #include "Engine/EVideo.h"
- #include "Engine/EConsole.h"
- #include "Engine/ECvar.h"
- // Unicode headers.
- #include "Common/UUnicode.h"
- // Windows headers.
- #define WIN32_LEAN_AND_MEAN
- #include <windows.h>
- // standard headers.
- #include <stdlib.h> // itoa()
- // GL libraries.
- #pragma comment( lib, "OpenGL32.lib" )
- // file-local globals.
- static HGLRC _currentRC;
- // constants.
- typedef WCHAR USECHAR;
- static const USECHAR WINDOW_CLASS_BASE_NAME[] = TEXT( "GLWindow" );
- EXTERN_CVAR_BOOL( vid_enabled );
- //===========================================================================
- // VidMode
- //===========================================================================
- //---------------------------------------------------------------------------
- void
- VidMode_Init( VidMode* p,
- physx::PxU32 width, physx::PxU32 height,
- bool fullscreen )
- {
- MemZero( p, sizeof( VidMode ) );
- p->width = width;
- p->height = height;
- p->screenWidth = width;
- p->screenHeight = height;
- p->fullscreen = fullscreen;
- }
- //===========================================================================
- // VidContext
- //===========================================================================
- class VidContext : public EngineMemalloc
- {
- public:
- VidContext();
- VidMode mMode;
- HINSTANCE mInstance;
- HWND mWindow;
- HDC mWindowDC;
- HGLRC mWindowRC;
- WNDPROC mWindowProc;
- USECHAR* mWindowClass;
- bool mHasFocus;
- };
- //---------------------------------------------------------------------------
- VidContext::VidContext()
- : mInstance( NULL )
- , mWindow( NULL )
- , mWindowDC( NULL )
- , mWindowRC( NULL )
- , mWindowProc( NULL )
- , mWindowClass( L"Duatiu" )
- , mHasFocus( false )
- {
- }
- //---------------------------------------------------------------------------
- VidContext*
- Vid_Startup( VidMode* mode, bool createGLContext, void* wndProc )
- {
- // validate inputs.
- PX_ASSERT( mode != NULL );
- PX_ASSERT( wndProc != NULL );
- if ( wndProc == NULL )
- return NULL;
- // get the handle to the program instance.
- HINSTANCE hInstance = GetModuleHandle( NULL );
- HWND hWnd = NULL;
- PxU32 windowWidth = 0;
- PxU32 windowHeight = 1;
- HDC hDC = NULL;
- HGLRC hRC = NULL;
- USECHAR wndClassName[ 512 ] = { '\0' };
- if ( vid_enabled )
- {
- // generate a window class name.
- {
- size_t len = wcslen( WINDOW_CLASS_BASE_NAME );
- PX_ASSERT( len < (512 - 32) );
- // copy the base class name.
- wcscpy_s( wndClassName, 512, WINDOW_CLASS_BASE_NAME );
- // append an incrementing number.
- static physx::PxI32 kCurCount = 0;
- ++kCurCount;
- _itow_s( kCurCount, wndClassName + len, 511 - len, 10 );
- }
- PX_ASSERT( wndClassName != NULL );
- char wndClassNameA[ 512 ];
- Uni_Wide2ASCII( wndClassNameA, wndClassName, 512 );
- Console.Std << "Video Startup:"
- << Newl << "\tPlatform: Win32"
- << Newl << "\tResolution: " << mode->width << "x" << mode->height
- << Newl << "\tFullscreen: " << mode->fullscreen
- << Newl;
- // register the window class.
- {
- WNDCLASS wc;
- wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
- wc.lpfnWndProc = (WNDPROC)wndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = hInstance;
- wc.hIcon = LoadIcon( NULL, IDI_WINLOGO );
- wc.hCursor = LoadCursor( NULL, IDC_ARROW );
- wc.hbrBackground = NULL;
- wc.lpszMenuName = NULL;
- wc.lpszClassName = wndClassName;
- if ( !RegisterClass( &wc ) )
- {
- Console.Gfx.Err << "Failed to register window class" << Newl;
- return NULL;
- }
- }
- if ( mode->fullscreen )
- {
- // switch to fullscreen.
- DEVMODE dm;
- memset( &dm, 0, sizeof( dm ) );
- dm.dmSize = sizeof( dm );
- dm.dmPelsWidth = mode->width;
- dm.dmPelsHeight = mode->height;
- dm.dmBitsPerPel = 32;
- dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
- if ( DISP_CHANGE_SUCCESSFUL != ChangeDisplaySettings( &dm, CDS_FULLSCREEN ) )
- {
- Console.Gfx.Err << "Failed to switch to fullscreen mode" << Newl;
- return NULL;
- }
- }
- // select desired window characteristics.
- DWORD dwStyle;
- if ( !mode->fullscreen )
- {
- // non-fullscreen window style:
- // - has title bar.
- // - has minimize / maximize buttons.
- // - no system menu.
- // - no resizing.
- dwStyle = WS_OVERLAPPEDWINDOW & ~WS_OVERLAPPED & ~WS_THICKFRAME;
- }
- else
- {
- // fullscreen window style:
- // - no elements.
- dwStyle = WS_POPUP;
- }
- // calculate the window dimensions such that that the number of rendered pixels
- // is exactly (width * height).
- RECT windowRect;
- windowRect.left = 0;
- windowRect.top = 0;
- windowRect.right = mode->width;
- windowRect.bottom = mode->height;
- AdjustWindowRect( &windowRect, dwStyle, FALSE );
- windowWidth = windowRect.right - windowRect.left;
- windowHeight = windowRect.bottom - windowRect.top;
- // create the window.
- const physx::PxI32 kWindowX = 0, kWindowY = 0;
- hWnd = CreateWindow(
- wndClassName,
- TEXT( "" ),
- dwStyle | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
- kWindowX, kWindowY,
- windowWidth, windowHeight,
- NULL, // parent.
- NULL, // menu.
- hInstance,
- NULL );
- if ( !hWnd )
- {
- Console.Gfx.Err << "Window creation failed" << Newl;
- if ( mode->fullscreen )
- ChangeDisplaySettings( NULL, 0 );
- return NULL;
- }
- // get the device context.
- hDC = GetDC( hWnd );
- if ( !hDC )
- {
- Console.Gfx.Err << "GetDC failed" << Newl;
- DestroyWindow( hWnd );
- if ( mode->fullscreen )
- ChangeDisplaySettings( NULL, 0 );
- return NULL;
- }
- // create the GL rendering context, if necessary.
- if ( createGLContext )
- {
- // choose the pixel format.
- PIXELFORMATDESCRIPTOR pfd =
- {
- sizeof( PIXELFORMATDESCRIPTOR ),
- 1,
- PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
- PFD_TYPE_RGBA,
- 32,
- 0, 0, 0, 0, 0, 0,
- 0,
- 0,
- 0,
- 0, 0, 0, 0,
- 24,
- 0,
- 0,
- PFD_MAIN_PLANE,
- 0,
- 0, 0, 0
- };
- physx::PxI32 pixelFormat = ChoosePixelFormat( hDC, &pfd );
- if ( !pixelFormat )
- {
- Console.Gfx.Err << "ChoosePixelFormat failed" << Newl;
- ReleaseDC( hWnd, hDC );
- DestroyWindow( hWnd );
- if ( mode->fullscreen )
- ChangeDisplaySettings( NULL, 0 );
- return NULL;
- }
- if ( !SetPixelFormat( hDC, pixelFormat, &pfd ) )
- {
- Console.Gfx.Err << "SetPixelFormat failed" << Newl;
- ReleaseDC( hWnd, hDC );
- DestroyWindow( hWnd );
- if ( mode->fullscreen )
- ChangeDisplaySettings( NULL, 0 );
- return NULL;
- }
- // create a new GL rendering context for the window.
- hRC = wglCreateContext( hDC );
- if ( !hRC )
- {
- Console.Gfx.Err << "wglCreateContext failed" << Newl;
- ReleaseDC( hWnd, hDC );
- DestroyWindow( hWnd );
- if ( mode->fullscreen )
- ChangeDisplaySettings( NULL, 0 );
- return NULL;
- }
- // begin rendering to that window.
- if ( !wglMakeCurrent( hDC, hRC ) )
- {
- Console.Gfx.Err << "wglMakeCurrent failed" << Newl;
- wglDeleteContext( hRC );
- ReleaseDC( hWnd, hDC );
- DestroyWindow( hWnd );
- if ( mode->fullscreen )
- ChangeDisplaySettings( NULL, 0 );
- return NULL;
- }
- _currentRC = hRC;
- }
- // show the window.
- ShowWindow( hWnd, SW_SHOW );
- }
- // store the specified window width and height.
- mode->screenWidth = windowWidth;
- mode->screenHeight = windowHeight;
- VidContext* ret = PS_NEW( VidContext );
- ret->mInstance = hInstance;
- ret->mMode = *mode;
- ret->mWindow = hWnd;
- ret->mWindowDC = hDC;
- ret->mWindowRC = hRC;
- ret->mWindowProc = (WNDPROC)wndProc;
- ret->mWindowClass = (USECHAR *)PS_ALLOC_ENGINE( sizeof(USECHAR)* 512,"WindowClass" );
- ret->mHasFocus = true;
- wcscpy_s( ret->mWindowClass, 512, wndClassName );
- return ret;
- }
- //---------------------------------------------------------------------------
- void
- Vid_Shutdown( VidContext* ctx )
- {
- if ( ctx == NULL )
- return;
- if ( vid_enabled )
- {
- if ( ctx->mMode.fullscreen )
- {
- // exit fullscreen.
- ChangeDisplaySettings( NULL, 0 );
- }
- // destroy the GL context.
- if ( ctx->mWindowRC )
- {
- if ( _currentRC == ctx->mWindowRC )
- {
- wglMakeCurrent( NULL, NULL );
- _currentRC = NULL;
- }
- wglDeleteContext( ctx->mWindowRC );
- ctx->mWindowRC = NULL;
- }
- // destroy the device context.
- if ( ctx->mWindowDC )
- {
- ReleaseDC( ctx->mWindow, ctx->mWindowDC );
- ctx->mWindowDC = NULL;
- }
- // destroy the window.
- if ( ctx->mWindow )
- {
- DestroyWindow( ctx->mWindow );
- ctx->mWindow = NULL;
- }
- // unregister the window class.
- {
- UnregisterClass( ctx->mWindowClass, ctx->mInstance );
- PS_FREE_ENGINE( ctx->mWindowClass );
- }
- }
- delete ctx;
- }
- //---------------------------------------------------------------------------
- extern bool
- Vid_HasFocus( VidContext* ctx )
- {
- return ctx->mHasFocus;
- }
- //---------------------------------------------------------------------------
- bool
- Vid_DoEvents( VidContext* ctx )
- {
- if ( !ctx )
- return false;
- if ( vid_enabled )
- {
- PX_ASSERT( ctx->mWindow );
- if ( !ctx->mWindow )
- return false;
- MSG msg;
- // process each pending window message.
- while ( PeekMessage( &msg, ctx->mWindow, 0, 0, PM_NOREMOVE ) )
- {
- // if we've just processed a quit message, abort.
- if ( GetMessage( &msg, ctx->mWindow, 0, 0 ) )
- {
- TranslateMessage( &msg );
- DispatchMessage( &msg );
- }
- else
- {
- break;
- }
- }
- if ( GetActiveWindow() == ctx->mWindow )
- ctx->mHasFocus = true;
- else
- ctx->mHasFocus = false;
- }
- return true;
- }
- //---------------------------------------------------------------------------
- bool
- Vid_SwapBuffers( VidContext* ctx )
- {
- if ( !ctx )
- return false;
- if ( vid_enabled )
- {
- PX_ASSERT( ctx->mWindowDC );
- if ( !ctx->mWindowDC )
- return false;
- if ( !SwapBuffers( ctx->mWindowDC ) )
- {
- Console.Gfx.Err << "SwapBuffers failed" << Newl;
- return false;
- }
- }
- return true;
- }
- //---------------------------------------------------------------------------
- const VidMode*
- Vid_GetCurrentMode( VidContext* ctx )
- {
- PX_ASSERT( ctx != NULL );
- return &(ctx->mMode);
- }
- //---------------------------------------------------------------------------
- PxU32
- Vid_GetScreenWidth( VidContext* ctx )
- {
- PX_ASSERT( ctx != NULL );
- return ctx->mMode.screenWidth;
- }
- //---------------------------------------------------------------------------
- PxU32
- Vid_GetScreenHeight( VidContext* ctx )
- {
- PX_ASSERT( ctx != NULL );
- if ( !ctx )
- return 0;
- return ctx->mMode.screenHeight;
- }
- //---------------------------------------------------------------------------
- void
- Vid_SetWindowTitle( VidContext* ctx, const char* title )
- {
- if ( !ctx )
- return;
- if ( vid_enabled )
- {
- PX_ASSERT( ctx->mWindow );
- SetWindowTextA( ctx->mWindow, title );
- }
- }
- //---------------------------------------------------------------------------
- void
- Vid_Focus( VidContext* ctx )
- {
- if ( !ctx )
- return;
- if ( vid_enabled )
- {
- PX_ASSERT( ctx->mWindow );
- SetFocus( ctx->mWindow );
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement