1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-07-02 09:03:37 +00:00

Add DisplayWindow class to replace OGLVideo

This commit is contained in:
Sergey Lipskiy 2017-01-09 17:21:41 +07:00
parent 07fae53ed4
commit 3bbb871fc6
6 changed files with 759 additions and 0 deletions

View File

@ -279,6 +279,7 @@
<ClCompile Include="..\..\src\DepthBuffer.cpp" />
<ClCompile Include="..\..\src\DepthBufferRender\ClipPolygon.cpp" />
<ClCompile Include="..\..\src\DepthBufferRender\DepthBufferRender.cpp" />
<ClCompile Include="..\..\src\DisplayWindow.cpp" />
<ClCompile Include="..\..\src\F3DEX2CBFD.cpp" />
<ClCompile Include="..\..\src\F3DEX2MM.cpp" />
<ClCompile Include="..\..\src\F3DGOLDEN.cpp" />
@ -300,6 +301,10 @@
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_ShaderStorage.cpp" />
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_SpecialShadersFactory.cpp" />
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_Utils.cpp" />
<ClCompile Include="..\..\src\Graphics\OpenGLContext\mupen64plus\mupen64plus_DisplayWindow.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\Graphics\OpenGLContext\opengl_Attributes.cpp" />
<ClCompile Include="..\..\src\Graphics\OpenGLContext\opengl_BufferManipulationObjectFactory.cpp" />
<ClCompile Include="..\..\src\Graphics\OpenGLContext\opengl_CachedFunctions.cpp" />
@ -308,6 +313,11 @@
<ClCompile Include="..\..\src\Graphics\OpenGLContext\opengl_Parameters.cpp" />
<ClCompile Include="..\..\src\Graphics\OpenGLContext\opengl_TextureManipulationObjectFactory.cpp" />
<ClCompile Include="..\..\src\Graphics\OpenGLContext\opengl_Utils.cpp" />
<ClCompile Include="..\..\src\Graphics\OpenGLContext\windows\windows_DisplayWindow.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_mupenplus|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_mupenplus|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_mupenplus_uniformset|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\gSP.cpp" />
<ClCompile Include="..\..\src\Keys.cpp" />
<ClCompile Include="..\..\src\Log.cpp" />
@ -408,6 +418,7 @@
<ClInclude Include="..\..\src\DepthBuffer.h" />
<ClInclude Include="..\..\src\DepthBufferRender\ClipPolygon.h" />
<ClInclude Include="..\..\src\DepthBufferRender\DepthBufferRender.h" />
<ClInclude Include="..\..\src\DisplayWindow.h" />
<ClInclude Include="..\..\src\F3DEX2CBFD.h" />
<ClInclude Include="..\..\src\F3DEX2MM.h" />
<ClInclude Include="..\..\src\F3DGOLDEN.h" />

View File

@ -63,6 +63,15 @@
<Filter Include="Source Files\Graphics\OpenGL\GLSL">
<UniqueIdentifier>{e67eafa1-5cea-4267-bc12-715e06c744db}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Graphics\OpenGL\windows">
<UniqueIdentifier>{dfff6885-c7e7-4b77-863e-7eeea6753d5a}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Graphics\OpenGL\windows">
<UniqueIdentifier>{e8b5c80f-51ec-45c2-bcdb-5e18868073df}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Graphics\OpenGL\mupen64plus">
<UniqueIdentifier>{77259791-9942-4601-a63f-5a0468e69e49}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\Combiner.cpp">
@ -323,6 +332,15 @@
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_ShaderStorage.cpp">
<Filter>Source Files\Graphics\OpenGL\GLSL</Filter>
</ClCompile>
<ClCompile Include="..\..\src\DisplayWindow.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\src\Graphics\OpenGLContext\windows\windows_DisplayWindow.cpp">
<Filter>Source Files\Graphics\OpenGL\windows</Filter>
</ClCompile>
<ClCompile Include="..\..\src\Graphics\OpenGLContext\mupen64plus\mupen64plus_DisplayWindow.cpp">
<Filter>Source Files\Graphics\OpenGL\mupen64plus</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\3DMath.h">
@ -601,5 +619,8 @@
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_ShaderStorage.h">
<Filter>Header Files\Graphics\OpenGL\GLSL</Filter>
</ClInclude>
<ClInclude Include="..\..\src\DisplayWindow.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

164
src/DisplayWindow.cpp Normal file
View File

@ -0,0 +1,164 @@
#include <assert.h>
#include "Config.h"
#include "VI.h"
#include "DisplayWindow.h"
#include "Graphics/Context.h"
void DisplayWindow::start()
{
_start(); // TODO: process initialization error
gfxContext.init();
// m_render._initData();
m_buffersSwapCount = 0;
}
void DisplayWindow::stop()
{
// m_render._destroyData();
gfxContext.destroy();
_stop();
}
void DisplayWindow::restart()
{
m_bResizeWindow = true;
}
void DisplayWindow::swapBuffers()
{
// m_render.drawOSD();
_swapBuffers();
gDP.otherMode.l = 0;
if ((config.generalEmulation.hacks & hack_doNotResetTLUTmode) == 0)
gDPSetTextureLUT(G_TT_NONE);
++m_buffersSwapCount;
}
void DisplayWindow::setCaptureScreen(const char * const _strDirectory)
{
::mbstowcs(m_strScreenDirectory, _strDirectory, PLUGIN_PATH_SIZE - 1);
m_bCaptureScreen = true;
}
void DisplayWindow::saveScreenshot()
{
if (!m_bCaptureScreen)
return;
_saveScreenshot();
m_bCaptureScreen = false;
}
bool DisplayWindow::changeWindow()
{
if (!m_bToggleFullscreen)
return false;
// m_render._destroyData();
_changeWindow();
updateScale();
// m_render._initData();
m_bToggleFullscreen = false;
return true;
}
void DisplayWindow::setWindowSize(u32 _width, u32 _height)
{
if (m_width != _width || m_height != _height) {
m_resizeWidth = _width;
m_resizeHeight = _height;
m_bResizeWindow = true;
}
}
bool DisplayWindow::resizeWindow()
{
if (!m_bResizeWindow)
return false;
// m_render._destroyData();
if (!_resizeWindow())
_start();
updateScale();
// m_render._initData();
m_bResizeWindow = false;
return true;
}
void DisplayWindow::updateScale()
{
if (VI.width == 0 || VI.height == 0)
return;
m_scaleX = m_width / (float)VI.width;
m_scaleY = m_height / (float)VI.height;
}
void DisplayWindow::_setBufferSize()
{
m_bAdjustScreen = false;
if (config.frameBufferEmulation.enable) {
switch (config.frameBufferEmulation.aspect) {
case Config::aStretch: // stretch
m_width = m_screenWidth;
m_height = m_screenHeight;
break;
case Config::a43: // force 4/3
if (m_screenWidth * 3 / 4 > m_screenHeight) {
m_height = m_screenHeight;
m_width = m_screenHeight * 4 / 3;
}
else if (m_screenHeight * 4 / 3 > m_screenWidth) {
m_width = m_screenWidth;
m_height = m_screenWidth * 3 / 4;
}
else {
m_width = m_screenWidth;
m_height = m_screenHeight;
}
break;
case Config::a169: // force 16/9
if (m_screenWidth * 9 / 16 > m_screenHeight) {
m_height = m_screenHeight;
m_width = m_screenHeight * 16 / 9;
}
else if (m_screenHeight * 16 / 9 > m_screenWidth) {
m_width = m_screenWidth;
m_height = m_screenWidth * 9 / 16;
}
else {
m_width = m_screenWidth;
m_height = m_screenHeight;
}
break;
case Config::aAdjust: // adjust
m_width = m_screenWidth;
m_height = m_screenHeight;
if (m_screenWidth * 3 / 4 > m_screenHeight) {
f32 width43 = m_screenHeight * 4.0f / 3.0f;
m_adjustScale = width43 / m_screenWidth;
m_bAdjustScreen = true;
}
break;
default:
assert(false && "Unknown aspect ratio");
m_width = m_screenWidth;
m_height = m_screenHeight;
}
}
else {
m_width = m_screenWidth;
m_height = m_screenHeight;
if (config.frameBufferEmulation.aspect == Config::aAdjust && (m_screenWidth * 3 / 4 > m_screenHeight)) {
f32 width43 = m_screenHeight * 4.0f / 3.0f;
m_adjustScale = width43 / m_screenWidth;
m_bAdjustScreen = true;
}
}
}
void DisplayWindow::readScreen(void **_pDest, long *_pWidth, long *_pHeight)
{
_readScreen(_pDest, _pWidth, _pHeight);
}
void DisplayWindow::readScreen2(void * _dest, int * _width, int * _height, int _front)
{
_readScreen2(_dest, _width, _height, _front);
}

78
src/DisplayWindow.h Normal file
View File

@ -0,0 +1,78 @@
#pragma once
#include "Types.h"
namespace graphics {
class VideoImpl;
}
class DisplayWindow
{
public:
virtual ~DisplayWindow() {}
void start();
void stop();
void restart();
void swapBuffers();
void saveScreenshot();
bool changeWindow();
bool resizeWindow();
void setWindowSize(u32 _width, u32 _height);
void setCaptureScreen(const char * const _strDirectory);
void setToggleFullscreen() { m_bToggleFullscreen = true; }
void readScreen(void **_pDest, long *_pWidth, long *_pHeight);
void readScreen2(void * _dest, int * _width, int * _height, int _front);
void updateScale();
f32 getScaleX() const { return m_scaleX; }
f32 getScaleY() const { return m_scaleY; }
f32 getAdjustScale() const { return m_adjustScale; }
u32 getBuffersSwapCount() const { return m_buffersSwapCount; }
u32 getWidth() const { return m_width; }
u32 getHeight() const { return m_height; }
u32 getScreenWidth() const { return m_screenWidth; }
u32 getScreenHeight() const { return m_screenHeight; }
u32 getHeightOffset() const { return m_heightOffset; }
bool isFullscreen() const { return m_bFullscreen; }
bool isAdjustScreen() const { return m_bAdjustScreen; }
bool isResizeWindow() const { return m_bResizeWindow; }
static DisplayWindow & get();
protected:
DisplayWindow() = default;
void _setBufferSize();
bool m_bCaptureScreen = false;
bool m_bToggleFullscreen = false;
bool m_bResizeWindow = false;
bool m_bFullscreen = false;
bool m_bAdjustScreen = false;
u32 m_buffersSwapCount = 0;
u32 m_width = 0;
u32 m_height = 0;
u32 m_heightOffset = 0;
u32 m_screenWidth = 0;
u32 m_screenHeight = 0;
u32 m_resizeWidth = 0;
u32 m_resizeHeight = 0;
f32 m_scaleX = 0;
f32 m_scaleY = 0;
f32 m_adjustScale = 0;
wchar_t m_strScreenDirectory[PLUGIN_PATH_SIZE];
private:
// OGLRender m_render;
virtual bool _start() = 0;
virtual void _stop() = 0;
virtual void _swapBuffers() = 0;
virtual void _saveScreenshot() = 0;
virtual void _changeWindow() = 0;
virtual bool _resizeWindow() = 0;
virtual void _readScreen(void **_pDest, long *_pWidth, long *_pHeight) = 0;
virtual void _readScreen2(void * _dest, int * _width, int * _height, int _front) = 0;
};

View File

@ -0,0 +1,225 @@
#include <stdio.h>
#include <Graphics/OpenGLContext/GLFunctions.h>
#include <Graphics/OpenGLContext/opengl_Utils.h>
#include <mupenplus/GLideN64_mupenplus.h>
#include <GLideN64.h>
#include <Config.h>
#include <N64.h>
#include <gSP.h>
#include <Log.h>
#include <Revision.h>
#include <FrameBuffer.h>
#include <GLideNUI/GLideNUI.h>
#include <DisplayWindow.h>
#ifdef VC
#include <bcm_host.h>
#endif
class DisplayWindowMupen64plus : public DisplayWindow
{
public:
DisplayWindowMupen64plus() {}
private:
void _setAttributes();
void _getDisplaySize();
bool _start() override;
void _stop() override;
void _swapBuffers() override;
void _saveScreenshot() override;
bool _resizeWindow() override;
void _changeWindow() override;
void _readScreen(void **_pDest, long *_pWidth, long *_pHeight) override {}
void _readScreen2(void * _dest, int * _width, int * _height, int _front) override;
};
DisplayWindow & DisplayWindow::get()
{
static DisplayWindowMupen64plus video;
return video;
}
void DisplayWindowMupen64plus::_setAttributes()
{
#ifdef GLES2
CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_MAJOR_VERSION, 2);
CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_MINOR_VERSION, 0);
LOG(LOG_VERBOSE, "[gles2GlideN64]: _setAttributes\n");
#elif defined(GLES3)
CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_MAJOR_VERSION, 3);
CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_MINOR_VERSION, 0);
#elif defined(GLES3_1)
CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_MAJOR_VERSION, 3);
CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_MINOR_VERSION, 1);
#elif defined(OS_MAC_OS_X)
CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_MAJOR_VERSION, 3);
CoreVideo_GL_SetAttribute(M64P_GL_CONTEXT_MINOR_VERSION, 2);
#else
// Do nothing
#endif
#ifndef GLES2
CoreVideo_GL_SetAttribute(M64P_GL_RED_SIZE, 8);
CoreVideo_GL_SetAttribute(M64P_GL_GREEN_SIZE, 8);
CoreVideo_GL_SetAttribute(M64P_GL_BLUE_SIZE, 8);
CoreVideo_GL_SetAttribute(M64P_GL_ALPHA_SIZE, 8);
#endif
CoreVideo_GL_SetAttribute(M64P_GL_DOUBLEBUFFER, 1);
CoreVideo_GL_SetAttribute(M64P_GL_SWAP_CONTROL, config.video.verticalSync);
CoreVideo_GL_SetAttribute(M64P_GL_BUFFER_SIZE, 32);
CoreVideo_GL_SetAttribute(M64P_GL_DEPTH_SIZE, 16);
if (config.video.multisampling > 0 && config.frameBufferEmulation.enable == 0) {
CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLEBUFFERS, 1);
if (config.video.multisampling <= 2)
CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 2);
else if (config.video.multisampling <= 4)
CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 4);
else if (config.video.multisampling <= 8)
CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 8);
else
CoreVideo_GL_SetAttribute(M64P_GL_MULTISAMPLESAMPLES, 16);
}
}
bool DisplayWindowMupen64plus::_start()
{
CoreVideo_Init();
_setAttributes();
m_bFullscreen = config.video.fullscreen > 0;
m_screenWidth = config.video.windowedWidth;
m_screenHeight = config.video.windowedHeight;
_getDisplaySize();
_setBufferSize();
printf("(II) Setting video mode %dx%d...\n", m_screenWidth, m_screenHeight);
const m64p_video_flags flags = M64VIDEOFLAG_SUPPORT_RESIZING;
if (CoreVideo_SetVideoMode(m_screenWidth, m_screenHeight, 0, m_bFullscreen ? M64VIDEO_FULLSCREEN : M64VIDEO_WINDOWED, flags) != M64ERR_SUCCESS) {
//printf("(EE) Error setting videomode %dx%d\n", m_screenWidth, m_screenHeight);
LOG(LOG_ERROR, "[gles2GlideN64]: Error setting videomode %dx%d\n", m_screenWidth, m_screenHeight);
CoreVideo_Quit();
return false;
}
LOG(LOG_VERBOSE, "[gles2GlideN64]: Create setting videomode %dx%d\n", m_screenWidth, m_screenHeight);
char caption[128];
# ifdef _DEBUG
sprintf(caption, "%s debug. Revision %s", pluginName, PLUGIN_REVISION);
# else // _DEBUG
sprintf(caption, "%s. Revision %s", pluginName, PLUGIN_REVISION);
# endif // _DEBUG
CoreVideo_SetCaption(caption);
return true;
}
void DisplayWindowMupen64plus::_stop()
{
CoreVideo_Quit();
}
void DisplayWindowMupen64plus::_swapBuffers()
{
// if emulator defined a render callback function, call it before buffer swap
if (renderCallback != nullptr) {
glUseProgram(0);
if (config.frameBufferEmulation.N64DepthCompare == 0) {
glViewport(0, getHeightOffset(), getScreenWidth(), getScreenHeight());
gSP.changed |= CHANGED_VIEWPORT;
}
gDP.changed |= CHANGED_COMBINE;
(*renderCallback)((gDP.changed&CHANGED_CPU_FB_WRITE) == 0 ? 1 : 0);
}
CoreVideo_GL_SwapBuffers();
}
void DisplayWindowMupen64plus::_saveScreenshot()
{
}
bool DisplayWindowMupen64plus::_resizeWindow()
{
_setAttributes();
m_bFullscreen = false;
m_width = m_screenWidth = m_resizeWidth;
m_height = m_screenHeight = m_resizeHeight;
if (CoreVideo_ResizeWindow(m_screenWidth, m_screenHeight) != M64ERR_SUCCESS) {
printf("(EE) Error setting videomode %dx%d\n", m_screenWidth, m_screenHeight);
m_width = m_screenWidth = config.video.windowedWidth;
m_height = m_screenHeight = config.video.windowedHeight;
CoreVideo_Quit();
return false;
}
_setBufferSize();
opengl::Utils::isGLError(); // reset GL error.
return true;
}
void DisplayWindowMupen64plus::_changeWindow()
{
CoreVideo_ToggleFullScreen();
}
void DisplayWindowMupen64plus::_getDisplaySize()
{
#ifdef VC
if( m_bFullscreen ) {
// Use VC get_display_size function to get the current screen resolution
u32 fb_width;
u32 fb_height;
if (graphics_get_display_size(0 /* LCD */, &fb_width, &fb_height) < 0)
printf("ERROR: Failed to get display size\n");
else {
m_screenWidth = fb_width;
m_screenHeight = fb_height;
}
}
#endif
}
void DisplayWindowMupen64plus::_readScreen2(void * _dest, int * _width, int * _height, int _front)
{
if (_width == nullptr || _height == nullptr)
return;
*_width = m_screenWidth;
*_height = m_screenHeight;
if (_dest == nullptr)
return;
u8 *pBufferData = (u8*)malloc((*_width)*(*_height) * 4);
u8 *pDest = (u8*)_dest;
#ifndef GLES2
GLint oldMode;
glGetIntegerv(GL_READ_BUFFER, &oldMode);
if (_front != 0)
glReadBuffer(GL_FRONT);
else
glReadBuffer(GL_BACK);
glReadPixels(0, m_heightOffset, m_screenWidth, m_screenHeight, GL_RGBA, GL_UNSIGNED_BYTE, pBufferData);
glReadBuffer(oldMode);
#else
glReadPixels(0, m_heightOffset, m_screenWidth, m_screenHeight, GL_RGBA, GL_UNSIGNED_BYTE, pBufferData);
#endif
//Convert RGBA to RGB
for (u32 y = 0; y < *_height; ++y) {
u8 *ptr = pBufferData + ((*_width) * 4 * y);
for (u32 x = 0; x < *_width; ++x) {
pDest[x * 3] = ptr[0]; // red
pDest[x * 3 + 1] = ptr[1]; // green
pDest[x * 3 + 2] = ptr[2]; // blue
ptr += 4;
}
pDest += (*_width) * 3;
}
free(pBufferData);
}

View File

@ -0,0 +1,260 @@
#include <stdio.h>
#include <Graphics/OpenGLContext/GLFunctions.h>
#include <windows/GLideN64_Windows.h>
#include <GLideN64.h>
#include <Config.h>
#include <N64.h>
#include <RSP.h>
#include <FrameBuffer.h>
#include <GLideNUI/GLideNUI.h>
#include <DisplayWindow.h>
class DisplayWindowWindows : public DisplayWindow
{
public:
DisplayWindowWindows() : hRC(NULL), hDC(NULL) {}
private:
bool _start() override;
void _stop() override;
void _swapBuffers() override;
void _saveScreenshot() override;
bool _resizeWindow() override;
void _changeWindow() override;
void _readScreen(void **_pDest, long *_pWidth, long *_pHeight) override;
void _readScreen2(void * _dest, int * _width, int * _height, int _front) override {}
HGLRC hRC;
HDC hDC;
};
DisplayWindow & DisplayWindow::get()
{
static DisplayWindowWindows video;
return video;
}
bool DisplayWindowWindows::_start()
{
int pixelFormat;
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
1, // version number
PFD_DRAW_TO_WINDOW | // support window
PFD_SUPPORT_OPENGL | // support OpenGL
PFD_DOUBLEBUFFER, // double buffered
PFD_TYPE_RGBA, // RGBA type
32, // color depth
0, 0, 0, 0, 0, 0, // color bits ignored
0, // no alpha buffer
0, // shift bit ignored
0, // no accumulation buffer
0, 0, 0, 0, // accum bits ignored
32, // z-buffer
0, // no stencil buffer
0, // no auxiliary buffer
PFD_MAIN_PLANE, // main layer
0, // reserved
0, 0, 0 // layer masks ignored
};
if (hWnd == NULL)
hWnd = GetActiveWindow();
if ((hDC = GetDC( hWnd )) == NULL) {
MessageBox( hWnd, L"Error while getting a device context!", pluginNameW, MB_ICONERROR | MB_OK );
return false;
}
if ((pixelFormat = ChoosePixelFormat(hDC, &pfd )) == 0) {
MessageBox( hWnd, L"Unable to find a suitable pixel format!", pluginNameW, MB_ICONERROR | MB_OK );
_stop();
return false;
}
if ((SetPixelFormat(hDC, pixelFormat, &pfd )) == FALSE) {
MessageBox( hWnd, L"Error while setting pixel format!", pluginNameW, MB_ICONERROR | MB_OK );
_stop();
return false;
}
if ((hRC = wglCreateContext(hDC)) == NULL) {
MessageBox( hWnd, L"Error while creating OpenGL context!", pluginNameW, MB_ICONERROR | MB_OK );
_stop();
return false;
}
if ((wglMakeCurrent(hDC, hRC)) == FALSE) {
MessageBox( hWnd, L"Error while making OpenGL context current!", pluginNameW, MB_ICONERROR | MB_OK );
_stop();
return false;
}
return _resizeWindow();
}
void DisplayWindowWindows::_stop()
{
wglMakeCurrent( NULL, NULL );
if (hRC != NULL) {
wglDeleteContext(hRC);
hRC = NULL;
}
if (hDC != NULL) {
ReleaseDC(hWnd, hDC);
hDC = NULL;
}
}
void DisplayWindowWindows::_swapBuffers()
{
if (hDC == NULL)
SwapBuffers( wglGetCurrentDC() );
else
SwapBuffers( hDC );
}
void DisplayWindowWindows::_saveScreenshot()
{
unsigned char * pixelData = NULL;
FrameBuffer * pBuffer = frameBufferList().findBuffer(*REG.VI_ORIGIN);
if (pBuffer == nullptr) {
GLint oldMode;
glGetIntegerv(GL_READ_BUFFER, &oldMode);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glReadBuffer(GL_FRONT);
pixelData = (unsigned char*)malloc(m_screenWidth * m_screenHeight * 3);
glReadPixels(0, m_heightOffset, m_screenWidth, m_screenHeight, GL_RGB, GL_UNSIGNED_BYTE, pixelData);
glReadBuffer(oldMode);
SaveScreenshot(m_strScreenDirectory, RSP.romname, m_screenWidth, m_screenHeight, pixelData);
}
else {
if (config.video.multisampling != 0) {
pBuffer->resolveMultisampledTexture();
glBindFramebuffer(GL_READ_FRAMEBUFFER, pBuffer->m_resolveFBO);
} else
glBindFramebuffer(GL_READ_FRAMEBUFFER, pBuffer->m_FBO);
pixelData = (unsigned char*)malloc(pBuffer->m_pTexture->realWidth * pBuffer->m_pTexture->realHeight * 3);
glReadPixels(0, 0, pBuffer->m_pTexture->realWidth, pBuffer->m_pTexture->realHeight, GL_RGB, GL_UNSIGNED_BYTE, pixelData);
SaveScreenshot(m_strScreenDirectory, RSP.romname, pBuffer->m_pTexture->realWidth, pBuffer->m_pTexture->realHeight, pixelData);
}
free( pixelData );
}
void DisplayWindowWindows::_changeWindow()
{
static LONG windowedStyle;
static LONG windowedExStyle;
static RECT windowedRect;
static HMENU windowedMenu;
if (!m_bFullscreen) {
DEVMODE fullscreenMode;
memset( &fullscreenMode, 0, sizeof(DEVMODE) );
fullscreenMode.dmSize = sizeof(DEVMODE);
fullscreenMode.dmPelsWidth = config.video.fullscreenWidth;
fullscreenMode.dmPelsHeight = config.video.fullscreenHeight;
fullscreenMode.dmBitsPerPel = 32;
fullscreenMode.dmDisplayFrequency = config.video.fullscreenRefresh;
fullscreenMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
if (ChangeDisplaySettings( &fullscreenMode, CDS_FULLSCREEN ) != DISP_CHANGE_SUCCESSFUL) {
MessageBox( NULL, L"Failed to change display mode", pluginNameW, MB_ICONERROR | MB_OK );
return;
}
ShowCursor( FALSE );
windowedMenu = GetMenu( hWnd );
if (windowedMenu)
SetMenu( hWnd, NULL );
if (hStatusBar)
ShowWindow( hStatusBar, SW_HIDE );
windowedExStyle = GetWindowLong( hWnd, GWL_EXSTYLE );
windowedStyle = GetWindowLong( hWnd, GWL_STYLE );
SetWindowLong( hWnd, GWL_EXSTYLE, WS_EX_APPWINDOW | WS_EX_TOPMOST );
SetWindowLong( hWnd, GWL_STYLE, WS_POPUP );
GetWindowRect( hWnd, &windowedRect );
m_bFullscreen = true;
_resizeWindow();
} else {
ChangeDisplaySettings( NULL, 0 );
ShowCursor( TRUE );
if (windowedMenu)
SetMenu( hWnd, windowedMenu );
if (hStatusBar)
ShowWindow( hStatusBar, SW_SHOW );
SetWindowLong( hWnd, GWL_STYLE, windowedStyle );
SetWindowLong( hWnd, GWL_EXSTYLE, windowedExStyle );
SetWindowPos( hWnd, NULL, windowedRect.left, windowedRect.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE );
m_bFullscreen = false;
_resizeWindow();
}
}
bool DisplayWindowWindows::_resizeWindow()
{
RECT windowRect, statusRect, toolRect;
if (m_bFullscreen) {
m_screenWidth = config.video.fullscreenWidth;
m_screenHeight = config.video.fullscreenHeight;
m_heightOffset = 0;
_setBufferSize();
return (SetWindowPos(hWnd, NULL, 0, 0, m_screenWidth, m_screenHeight, SWP_NOACTIVATE | SWP_NOZORDER | SWP_SHOWWINDOW) == TRUE);
} else {
m_screenWidth = m_width = config.video.windowedWidth;
m_screenHeight = config.video.windowedHeight;
_setBufferSize();
GetClientRect( hWnd, &windowRect );
GetWindowRect( hStatusBar, &statusRect );
if (hToolBar)
GetWindowRect( hToolBar, &toolRect );
else
toolRect.bottom = toolRect.top = 0;
m_heightOffset = (statusRect.bottom - statusRect.top);
windowRect.right = windowRect.left + config.video.windowedWidth - 1;
windowRect.bottom = windowRect.top + config.video.windowedHeight - 1 + m_heightOffset;
AdjustWindowRect( &windowRect, GetWindowLong( hWnd, GWL_STYLE ), GetMenu( hWnd ) != NULL );
return (SetWindowPos( hWnd, NULL, 0, 0, windowRect.right - windowRect.left + 1,
windowRect.bottom - windowRect.top + 1 + toolRect.bottom - toolRect.top + 1, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE ) == TRUE);
}
}
void DisplayWindowWindows::_readScreen(void **_pDest, long *_pWidth, long *_pHeight)
{
*_pWidth = m_width;
*_pHeight = m_height;
*_pDest = malloc(m_height * m_width * 3);
if (*_pDest == nullptr)
return;
#ifndef GLESX
const GLenum format = GL_BGR_EXT;
glReadBuffer(GL_FRONT);
#else
const GLenum format = GL_RGB;
#endif
glReadPixels(0, m_heightOffset, m_width, m_height, format, GL_UNSIGNED_BYTE, *_pDest);
}