forked from dolphin-emu/dolphin
		
	
		
			
				
	
	
		
			203 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			203 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// Copyright 2013 Dolphin Emulator Project
 | 
						|
// Licensed under GPLv2
 | 
						|
// Refer to the license.txt file included.
 | 
						|
 | 
						|
#include "Core/Host.h"
 | 
						|
 | 
						|
#include "DolphinWX/GLInterface/GLInterface.h"
 | 
						|
 | 
						|
#include "VideoCommon/EmuWindow.h"
 | 
						|
#include "VideoCommon/RenderBase.h"
 | 
						|
#include "VideoCommon/VertexShaderManager.h"
 | 
						|
#include "VideoCommon/VideoConfig.h"
 | 
						|
 | 
						|
static HDC hDC = nullptr;       // Private GDI Device Context
 | 
						|
static HGLRC hRC = nullptr;     // Permanent Rendering Context
 | 
						|
static HINSTANCE dllHandle = nullptr; // Handle to OpenGL32.dll
 | 
						|
 | 
						|
// typedef from wglext.h
 | 
						|
typedef BOOL(WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
 | 
						|
static PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = nullptr;
 | 
						|
 | 
						|
void cInterfaceWGL::SwapInterval(int Interval)
 | 
						|
{
 | 
						|
	if (wglSwapIntervalEXT)
 | 
						|
		wglSwapIntervalEXT(Interval);
 | 
						|
	else
 | 
						|
		ERROR_LOG(VIDEO, "No support for SwapInterval (framerate clamped to monitor refresh rate).");
 | 
						|
}
 | 
						|
void cInterfaceWGL::Swap()
 | 
						|
{
 | 
						|
	SwapBuffers(hDC);
 | 
						|
}
 | 
						|
 | 
						|
void* cInterfaceWGL::GetFuncAddress(std::string name)
 | 
						|
{
 | 
						|
	void* func = (void*)wglGetProcAddress((LPCSTR)name.c_str());
 | 
						|
	if (func == nullptr)
 | 
						|
		func = (void*)GetProcAddress(dllHandle, (LPCSTR)name.c_str());
 | 
						|
	return func;
 | 
						|
}
 | 
						|
 | 
						|
// Draw messages on top of the screen
 | 
						|
bool cInterfaceWGL::PeekMessages()
 | 
						|
{
 | 
						|
	// TODO: peekmessage
 | 
						|
	MSG msg;
 | 
						|
	while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
 | 
						|
	{
 | 
						|
		if (msg.message == WM_QUIT)
 | 
						|
			return FALSE;
 | 
						|
		TranslateMessage(&msg);
 | 
						|
		DispatchMessage(&msg);
 | 
						|
	}
 | 
						|
	return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
// Show the current FPS
 | 
						|
void cInterfaceWGL::UpdateFPSDisplay(const char *text)
 | 
						|
{
 | 
						|
	TCHAR temp[512];
 | 
						|
	swprintf_s(temp, sizeof(temp)/sizeof(TCHAR), _T("%hs"), text);
 | 
						|
	EmuWindow::SetWindowText(temp);
 | 
						|
}
 | 
						|
 | 
						|
// Create rendering window.
 | 
						|
// Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize()
 | 
						|
bool cInterfaceWGL::Create(void *&window_handle)
 | 
						|
{
 | 
						|
	int _tx, _ty, _twidth, _theight;
 | 
						|
	Host_GetRenderWindowSize(_tx, _ty, _twidth, _theight);
 | 
						|
 | 
						|
	// Control window size and picture scaling
 | 
						|
	s_backbuffer_width = _twidth;
 | 
						|
	s_backbuffer_height = _theight;
 | 
						|
 | 
						|
#ifdef _WIN32
 | 
						|
	dllHandle = LoadLibrary(TEXT("OpenGL32.dll"));
 | 
						|
#endif
 | 
						|
 | 
						|
	window_handle = (void*)EmuWindow::Create((HWND)window_handle, GetModuleHandle(0), _T("Please wait..."));
 | 
						|
	if (window_handle == nullptr)
 | 
						|
	{
 | 
						|
		Host_SysMessage("failed to create window");
 | 
						|
		return false;
 | 
						|
	}
 | 
						|
 | 
						|
	// Show the window
 | 
						|
	EmuWindow::Show();
 | 
						|
 | 
						|
	PIXELFORMATDESCRIPTOR pfd =         // pfd Tells Windows How We Want Things To Be
 | 
						|
	{
 | 
						|
		sizeof(PIXELFORMATDESCRIPTOR),  // Size Of This Pixel Format Descriptor
 | 
						|
		1,                              // Version Number
 | 
						|
		PFD_DRAW_TO_WINDOW |            // Format Must Support Window
 | 
						|
			PFD_SUPPORT_OPENGL |        // Format Must Support OpenGL
 | 
						|
			PFD_DOUBLEBUFFER,           // Must Support Double Buffering
 | 
						|
		PFD_TYPE_RGBA,                  // Request An RGBA Format
 | 
						|
		32,                             // Select Our Color Depth
 | 
						|
		0, 0, 0, 0, 0, 0,               // Color Bits Ignored
 | 
						|
		0,                              // 8bit Alpha Buffer
 | 
						|
		0,                              // Shift Bit Ignored
 | 
						|
		0,                              // No Accumulation Buffer
 | 
						|
		0, 0, 0, 0,                     // Accumulation Bits Ignored
 | 
						|
		0,                              // 0Bit Z-Buffer (Depth Buffer)
 | 
						|
		0,                              // 0bit Stencil Buffer
 | 
						|
		0,                              // No Auxiliary Buffer
 | 
						|
		PFD_MAIN_PLANE,                 // Main Drawing Layer
 | 
						|
		0,                              // Reserved
 | 
						|
		0, 0, 0                         // Layer Masks Ignored
 | 
						|
	};
 | 
						|
 | 
						|
	int      PixelFormat;               // Holds The Results After Searching For A Match
 | 
						|
 | 
						|
	if (!(hDC=GetDC(EmuWindow::GetWnd()))) {
 | 
						|
		PanicAlert("(1) Can't create an OpenGL Device context. Fail.");
 | 
						|
		return false;
 | 
						|
	}
 | 
						|
	if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd))) {
 | 
						|
		PanicAlert("(2) Can't find a suitable PixelFormat.");
 | 
						|
		return false;
 | 
						|
	}
 | 
						|
	if (!SetPixelFormat(hDC, PixelFormat, &pfd)) {
 | 
						|
		PanicAlert("(3) Can't set the PixelFormat.");
 | 
						|
		return false;
 | 
						|
	}
 | 
						|
	if (!(hRC = wglCreateContext(hDC))) {
 | 
						|
		PanicAlert("(4) Can't create an OpenGL rendering context.");
 | 
						|
		return false;
 | 
						|
	}
 | 
						|
 | 
						|
	return true;
 | 
						|
}
 | 
						|
 | 
						|
bool cInterfaceWGL::MakeCurrent()
 | 
						|
{
 | 
						|
	return wglMakeCurrent(hDC, hRC) ? true : false;
 | 
						|
}
 | 
						|
 | 
						|
bool cInterfaceWGL::ClearCurrent()
 | 
						|
{
 | 
						|
	bool success = wglMakeCurrent(hDC, nullptr) ? true : false;
 | 
						|
	if (success)
 | 
						|
	{
 | 
						|
		// Grab the swap interval function pointer
 | 
						|
		wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)GLInterface->GetFuncAddress("wglSwapIntervalEXT");
 | 
						|
	}
 | 
						|
	return success;
 | 
						|
}
 | 
						|
 | 
						|
// Update window width, size and etc. Called from Render.cpp
 | 
						|
void cInterfaceWGL::Update()
 | 
						|
{
 | 
						|
	RECT rcWindow;
 | 
						|
	if (!EmuWindow::GetParentWnd())
 | 
						|
	{
 | 
						|
		// We are not rendering to a child window - use client size.
 | 
						|
		GetClientRect(EmuWindow::GetWnd(), &rcWindow);
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		// We are rendering to a child window - use parent size.
 | 
						|
		GetWindowRect(EmuWindow::GetParentWnd(), &rcWindow);
 | 
						|
	}
 | 
						|
 | 
						|
	// Get the new window width and height
 | 
						|
	// See below for documentation
 | 
						|
	int width = rcWindow.right - rcWindow.left;
 | 
						|
	int height = rcWindow.bottom - rcWindow.top;
 | 
						|
 | 
						|
	// If we are rendering to a child window
 | 
						|
	if (EmuWindow::GetParentWnd() != 0 &&
 | 
						|
			(s_backbuffer_width != width || s_backbuffer_height != height) &&
 | 
						|
			width >= 4 && height >= 4)
 | 
						|
	{
 | 
						|
		::MoveWindow(EmuWindow::GetWnd(), 0, 0, width, height, FALSE);
 | 
						|
		s_backbuffer_width = width;
 | 
						|
		s_backbuffer_height = height;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// Close backend
 | 
						|
void cInterfaceWGL::Shutdown()
 | 
						|
{
 | 
						|
	if (hRC)
 | 
						|
	{
 | 
						|
		if (!wglMakeCurrent(nullptr, nullptr))
 | 
						|
			NOTICE_LOG(VIDEO, "Could not release drawing context.");
 | 
						|
 | 
						|
		if (!wglDeleteContext(hRC))
 | 
						|
			ERROR_LOG(VIDEO, "Attempt to release rendering context failed.");
 | 
						|
 | 
						|
		hRC = nullptr;
 | 
						|
	}
 | 
						|
 | 
						|
	if (hDC && !ReleaseDC(EmuWindow::GetWnd(), hDC))
 | 
						|
	{
 | 
						|
		ERROR_LOG(VIDEO, "Attempt to release device context failed.");
 | 
						|
		hDC = nullptr;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
 |