From cd658ac755914930fbe97e552326ac5535067dd6 Mon Sep 17 00:00:00 2001 From: "XTra.KrazzY" Date: Thu, 29 Jan 2009 23:35:31 +0000 Subject: [PATCH] More WIP OGL EventHandler work by shuffle2 and myself. Wiimote isn't implemented yet and OGL window is too small (should take window borders into account when creating window). Not committing VideoOGL.vcproj so that project compiles with old OGL video window. In order to test just replace main.cpp/GLUtil.cpp/GLUtil.h with nmain.cpp/nGLUtil.cpp/nGLUtil.h in the project. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2038 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/InputCommon/Src/EventHandler.cpp | 6 +- .../Plugin_PadSimple/Src/PadSimple.cpp | 3 +- .../Plugin_PadSimpleEvnt.vcproj | 9 +- .../Plugin_PadSimpleEvnt/Src/PadSimple.cpp | 60 +- Source/Plugins/Plugin_VideoOGL/Src/GLWindow.h | 171 +-- .../Src/NativeVertexFormat.cpp | 2 +- .../Plugin_VideoOGL/Src/PixelShaderCache.cpp | 2 +- Source/Plugins/Plugin_VideoOGL/Src/Render.cpp | 28 +- .../Plugins/Plugin_VideoOGL/Src/SDLWindow.cpp | 104 +- .../Plugins/Plugin_VideoOGL/Src/SDLWindow.h | 20 +- .../Plugin_VideoOGL/Src/TextureConverter.cpp | 2 +- .../Plugin_VideoOGL/Src/TextureConverter.h | 2 +- .../Plugins/Plugin_VideoOGL/Src/TextureMngr.h | 2 +- .../Plugin_VideoOGL/Src/VertexShaderCache.cpp | 2 +- .../Plugin_VideoOGL/Src/Win32Window.cpp | 1166 +++++++++++------ .../Plugins/Plugin_VideoOGL/Src/Win32Window.h | 67 +- .../Plugins/Plugin_VideoOGL/Src/X11Window.cpp | 2 +- Source/Plugins/Plugin_VideoOGL/Src/XFB.cpp | 2 +- .../Plugins/Plugin_VideoOGL/Src/nGLUtil.cpp | 86 +- Source/Plugins/Plugin_VideoOGL/Src/nGLUtil.h | 1 + Source/Plugins/Plugin_VideoOGL/Src/nmain.cpp | 71 +- 21 files changed, 1158 insertions(+), 650 deletions(-) diff --git a/Source/Core/InputCommon/Src/EventHandler.cpp b/Source/Core/InputCommon/Src/EventHandler.cpp index 9795740ec4..1d4e42ea17 100644 --- a/Source/Core/InputCommon/Src/EventHandler.cpp +++ b/Source/Core/InputCommon/Src/EventHandler.cpp @@ -271,7 +271,7 @@ void EventHandler::SFKeyToString(sf::Key::Code keycode, char *keyStr) { case sf::Key::Divide: sprintf(keyStr, "/"); break; case sf::Key::Left: sprintf(keyStr, "Left"); break; case sf::Key::Right: sprintf(keyStr, "Right"); break; - case sf::Key::Up: sprintf(keyStr, "UP"); break; + case sf::Key::Up: sprintf(keyStr, "Up"); break; case sf::Key::Down: sprintf(keyStr, "Down"); break; case sf::Key::Numpad0: sprintf(keyStr, "NP 0"); break; case sf::Key::Numpad1: sprintf(keyStr, "NP 1"); break; @@ -298,12 +298,12 @@ void EventHandler::SFKeyToString(sf::Key::Code keycode, char *keyStr) { case sf::Key::F13: sprintf(keyStr, "F13"); break; case sf::Key::F14: sprintf(keyStr, "F14"); break; case sf::Key::F15: sprintf(keyStr, "F15"); break; - case sf::Key::Pause: sprintf(keyStr, "Paues"); break; + case sf::Key::Pause: sprintf(keyStr, "Pause"); break; default: if (keycode > sf::Key::Escape) sprintf(keyStr, "Invalid Key"); else - sprintf(keyStr, "%c", keycode); + sprintf(keyStr, "%c", toupper(keycode)); break; } } diff --git a/Source/Plugins/Plugin_PadSimple/Src/PadSimple.cpp b/Source/Plugins/Plugin_PadSimple/Src/PadSimple.cpp index 3b4b0cd9d1..35f77b3646 100644 --- a/Source/Plugins/Plugin_PadSimple/Src/PadSimple.cpp +++ b/Source/Plugins/Plugin_PadSimple/Src/PadSimple.cpp @@ -587,7 +587,8 @@ void cocoa_Read(int _numPAD, SPADStatus* _pPADStatus) #endif // Set buttons status from wxWidgets in the main application // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻ -void PAD_Input(u16 _Key, u8 _UpDown) {} +void PAD_Input(u16 _Key, u8 _UpDown) { +} void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) diff --git a/Source/Plugins/Plugin_PadSimpleEvnt/Plugin_PadSimpleEvnt.vcproj b/Source/Plugins/Plugin_PadSimpleEvnt/Plugin_PadSimpleEvnt.vcproj index c81ddfdfc6..13ebddc46d 100644 --- a/Source/Plugins/Plugin_PadSimpleEvnt/Plugin_PadSimpleEvnt.vcproj +++ b/Source/Plugins/Plugin_PadSimpleEvnt/Plugin_PadSimpleEvnt.vcproj @@ -163,7 +163,7 @@ EnableFunctionLevelLinking="true" EnableEnhancedInstructionSet="0" FloatingPointModel="0" - UsePrecompiledHeader="0" + UsePrecompiledHeader="1" PrecompiledHeaderThrough="stdafx.h" PrecompiledHeaderFile="$(IntDir)\$(TargetName).pch" AssemblerListingLocation="$(IntDir)\" @@ -187,12 +187,13 @@ /> + + diff --git a/Source/Plugins/Plugin_PadSimpleEvnt/Src/PadSimple.cpp b/Source/Plugins/Plugin_PadSimpleEvnt/Src/PadSimple.cpp index 16ff010d77..f7f69d2a8b 100644 --- a/Source/Plugins/Plugin_PadSimpleEvnt/Src/PadSimple.cpp +++ b/Source/Plugins/Plugin_PadSimpleEvnt/Src/PadSimple.cpp @@ -20,6 +20,7 @@ #include "Common.h" +#include "pluginspecs_pad.h" #include "PadSimple.h" #include "IniFile.h" @@ -99,32 +100,32 @@ bool registerKey(int nPad, int id, sf::Key::Code code, int mods) { key.mods = mods; if (!eventHandler) { - PanicAlert("Can't get event handler"); - return false; + PanicAlert("Can't get event handler"); + return false; } - - if (!eventHandler->RegisterEventListener(ParseKeyEvent, key)) { - char codestr[100]; - eventHandler->SFKeyToString(code, codestr); - PanicAlert("Failed to register %s, might be already in use", codestr); - return false; - } - - - // FIXME: unregister old event + + // We need to handle mod change // and double registers if (pad[nPad].keyForControl[id] != 0) { - oldKey.inputType = KeyboardInput; - oldKey.keyCode = pad[nPad].keyForControl[id]; - oldKey.mods = mods; + oldKey.inputType = KeyboardInput; + oldKey.keyCode = pad[nPad].keyForControl[id]; + oldKey.mods = mods; - // Might be not be registered yet + // Might be not be registered yet eventHandler->RemoveEventListener(oldKey); } + if (!eventHandler->RegisterEventListener(ParseKeyEvent, key)) { + char codestr[100]; + eventHandler->SFKeyToString(code, codestr); + PanicAlert("Failed to register %s, might be already in use", codestr); + return false; + } + + pad[nPad].keyForControl[id] = code; return true; @@ -253,17 +254,19 @@ bool ParseKeyEvent(sf::Event ev) { fprintf(stderr, "parsing type %d code %d\n", ev.Type, ev.Key.Code); // FIXME: should we support more than one control? - for (int i = 0; i < NUMCONTROLS; i++) { - if (ev.Key.Code == pad[0].keyForControl[i]) { - KeyStatus[i] = (ev.Type == sf::Event::KeyPressed); - break; + for (int i = 0; i < NUMCONTROLS; i++) { + if (ev.Key.Code == pad[0].keyForControl[i]) { + KeyStatus[i] = (ev.Type == sf::Event::KeyPressed); + break; + } } - } return true; } +void PAD_Input(u16 _Key, u8 _UpDown) { +} void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) { @@ -342,9 +345,6 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) #endif } -void PAD_Input(u8 _Key, u8 _UpDown) { -} - void PAD_Rumble(u8 _numPAD, unsigned int _uType, unsigned int _uStrength) { } @@ -404,12 +404,12 @@ void LoadConfig() file.Get(SectionName, "Attached", &pad[i].bAttached, i==0); file.Get(SectionName, "DisableOnBackground", &pad[i].bDisable, false); for (int x = 0; x < NUMCONTROLS; x++) { - int key; - file.Get(SectionName, controlNames[x], - &key, (i==0)?defaultKeyForControl[x]:0); - - if (i == g_PADInitialize.padNumber && pad[i].bAttached) - registerKey(i, x, (sf::Key::Code)key); + int key; + file.Get(SectionName, controlNames[x], + &key, (i==0)?defaultKeyForControl[x]:0); + + if (i == g_PADInitialize.padNumber && pad[i].bAttached) + registerKey(i, x, (sf::Key::Code)key); } } } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GLWindow.h b/Source/Plugins/Plugin_VideoOGL/Src/GLWindow.h index 713d3227fd..89d6c70db2 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GLWindow.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/GLWindow.h @@ -9,7 +9,12 @@ #include "pluginspecs_video.h" #ifdef _WIN32 +#define GLEW_STATIC + #include +#include +#include +#include #else #include #endif @@ -20,118 +25,118 @@ #include #endif enum OGL_Props { - OGL_FULLSCREEN, - OGL_KEEPRATIO, - OGL_HIDECURSOR, - OGL_PROP_COUNT + OGL_FULLSCREEN, + OGL_KEEPRATIO, + OGL_HIDECURSOR, + OGL_PROP_COUNT }; struct res { - u32 x; - u32 y; + u32 x; + u32 y; }; class GLWindow { - private: +private: - // TODO: what is xmax and ymax? do we need [xy]render? - u32 xWin, yWin; // windows size - int xOffset, yOffset; // offset in window - float xMax, yMax; // ??? - u32 xRender, yRender; // render area + // TODO: what is xmax and ymax? do we need [xy]render? + u32 xWin, yWin; // Windows' size + int xOffset, yOffset; // Offset in window + float xMax, yMax; // ??? + u32 xRender, yRender; // Render area - bool properties[OGL_PROP_COUNT]; + bool properties[OGL_PROP_COUNT]; protected: - EventHandler* eventHandler; - res origRes, currFullRes, currWinRes; - static std::vector fullResolutions; - virtual void SetRender(u32 x, u32 y) { - xRender = x; - yRender = y; - } + EventHandler* eventHandler; + res origRes, currFullRes, currWinRes; + static std::vector fullResolutions; + virtual void SetRender(u32 x, u32 y) { + xRender = x; + yRender = y; + } - static const std::vector& getFsResolutions() { - return fullResolutions; - } - - static void addFSResolution(res fsr) { - fullResolutions.push_back(fsr); - } + static const std::vector& getFsResolutions() { + return fullResolutions; + } + + static void addFSResolution(res fsr) { + fullResolutions.push_back(fsr); + } public: - virtual void SwapBuffers() {}; - virtual void SetWindowText(const char *text) {}; - virtual bool PeekMessages() {return false;}; - virtual void Update() {}; - virtual bool MakeCurrent() {return false;}; + virtual void SwapBuffers() {}; + virtual void SetWindowText(const char *text) {}; + virtual bool PeekMessages() {return false;}; + virtual void Update() {}; + virtual bool MakeCurrent() {return false;}; - virtual void updateDim() { - if (GetProperty(OGL_FULLSCREEN)) - SetWinSize(currFullRes.x, currFullRes.y); - else - SetWinSize(currWinRes.x, currWinRes.y); - - float FactorX = 640.0f / (float)GetXwin(); - float FactorY = 480.0f / (float)GetYwin(); - // float Max = (FactorX < FactorY) ? FactorX : FactorY; + virtual void updateDim() { + if (GetProperty(OGL_FULLSCREEN)) + SetWinSize(currFullRes.x, currFullRes.y); + else + SetWinSize(currWinRes.x, currWinRes.y); - SetMax(1.0f / FactorX, 1.0f / FactorY); - SetOffset(0,0); - } - - void SetEventHandler(EventHandler *eh) { eventHandler = eh;} - bool GetProperty(OGL_Props prop) {return properties[prop];} - virtual bool SetProperty(OGL_Props prop, bool value) - {return properties[prop] = value;} + float FactorX = 640.0f / (float)GetXwin(); + float FactorY = 480.0f / (float)GetYwin(); + //float Max = (FactorX < FactorY) ? FactorX : FactorY; - u32 GetXrender() {return xRender;} - u32 GetYrender() {return yRender;} + SetMax(1.0f / FactorX, 1.0f / FactorY); + SetOffset(0,0); + } - u32 GetXwin() {return xWin;} - u32 GetYwin() {return yWin;} - void SetWinSize(u32 x, u32 y) { - xWin = x; - yWin = y; - } + void SetEventHandler(EventHandler *eh) { eventHandler = eh;} + bool GetProperty(OGL_Props prop) {return properties[prop];} + virtual bool SetProperty(OGL_Props prop, bool value) + {return properties[prop] = value;} - int GetYoff() {return yOffset;} - int GetXoff() {return xOffset;} - void SetOffset(int x, int y) { - yOffset = y; - xOffset = x; - } + u32 GetXrender() {return xRender;} + u32 GetYrender() {return yRender;} - void SetMax(float x, float y) { - yMax = y; - xMax = x; - } + u32 GetXwin() {return xWin;} + u32 GetYwin() {return yWin;} + void SetWinSize(u32 x, u32 y) { + xWin = x; + yWin = y; + } - float GetXmax() {return xMax;} - float GetYmax() {return yMax;} + int GetYoff() {return yOffset;} + int GetXoff() {return xOffset;} + void SetOffset(int x, int y) { + yOffset = y; + xOffset = x; + } - static bool valid() { return false;} + void SetMax(float x, float y) { + yMax = y; + xMax = x; + } - GLWindow() { + float GetXmax() {return xMax;} + float GetYmax() {return yMax;} - // Load defaults - sscanf(g_Config.iFSResolution, "%dx%d", - &currFullRes.x, &currFullRes.y); + static bool valid() { return false;} - sscanf(g_Config.iWindowedRes, "%dx%d", - &currWinRes.x, &currWinRes.y); + GLWindow() { - SetProperty(OGL_FULLSCREEN, g_Config.bFullscreen); - SetProperty(OGL_KEEPRATIO, g_Config.bKeepAR); - SetProperty(OGL_HIDECURSOR, g_Config.bHideCursor); + // Load defaults + sscanf(g_Config.iFSResolution, "%dx%d", + &currFullRes.x, &currFullRes.y); - updateDim(); - } + sscanf(g_Config.iWindowedRes, "%dx%d", + &currWinRes.x, &currWinRes.y); + + SetProperty(OGL_FULLSCREEN, g_Config.bFullscreen); + SetProperty(OGL_KEEPRATIO, g_Config.bKeepAR); + SetProperty(OGL_HIDECURSOR, g_Config.bHideCursor); + + updateDim(); + } - // setResolution - // resolution iter + // setResolution + // resolution iter }; #endif diff --git a/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp b/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp index e1b10b298c..48c1cc880f 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp @@ -15,7 +15,7 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ -#include "GLUtil.h" +#include "nGLUtil.h" #include "Profiler.h" #include "x64Emitter.h" #include "ABI.h" diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp index 0035a5c54d..dcbbfa2068 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp @@ -18,7 +18,7 @@ #include "Globals.h" #include "Profiler.h" -#include "GLUtil.h" +#include "nGLUtil.h" #include #include diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index 981008e946..0e2406cfd0 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -24,7 +24,7 @@ #include #include -#include "GLUtil.h" +#include "nGLUtil.h" #include #include @@ -56,7 +56,7 @@ #endif #ifdef _WIN32 - #include "OS/Win32.h" + #include "Win32Window.h" // warning: crapcode #else #endif ///////////////////////////// @@ -494,19 +494,19 @@ void Renderer::ReinitView(int nNewWidth, int nNewHeight) if (oldscreen && !g_Config.bFullscreen) { // if transitioning from full screen #ifdef _WIN32 - RECT rc; - rc.left = 0; rc.top = 0; - rc.right = nNewWidth; rc.bottom = nNewHeight; - AdjustWindowRect(&rc, EmuWindow::g_winstyle, FALSE); + //RECT rc; + //rc.left = 0; rc.top = 0; + //rc.right = nNewWidth; rc.bottom = nNewHeight; + //AdjustWindowRect(&rc, EmuWindow::g_winstyle, FALSE); - RECT rcdesktop; - GetWindowRect(GetDesktopWindow(), &rcdesktop); + //RECT rcdesktop; + //GetWindowRect(GetDesktopWindow(), &rcdesktop); - SetWindowLong(EmuWindow::GetWnd(), GWL_STYLE, EmuWindow::g_winstyle); - SetWindowPos(EmuWindow::GetWnd(), HWND_TOP, ((rcdesktop.right-rcdesktop.left)-(rc.right-rc.left))/2, - ((rcdesktop.bottom-rcdesktop.top)-(rc.bottom-rc.top))/2, - rc.right-rc.left, rc.bottom-rc.top, SWP_SHOWWINDOW); - UpdateWindow(EmuWindow::GetWnd()); + //SetWindowLong(EmuWindow::GetWnd(), GWL_STYLE, EmuWindow::g_winstyle); + //SetWindowPos(EmuWindow:GetWnd(), HWND_TOP, ((rcdesktop.right-rcdesktop.left)-(rc.right-rc.left))/2, + // ((rcdesktop.bottom-rcdesktop.top)-(rc.bottom-rc.top))/2, + // rc.right-rc.left, rc.bottom-rc.top, SWP_SHOWWINDOW); + //UpdateWindow(EmuWindow::GetWnd()); #else // linux #endif } @@ -1216,4 +1216,4 @@ void UpdateViewport() } glDepthRange((xfregs.rawViewport[5]- xfregs.rawViewport[2])/16777215.0f, xfregs.rawViewport[5]/16777215.0f); -} \ No newline at end of file +} diff --git a/Source/Plugins/Plugin_VideoOGL/Src/SDLWindow.cpp b/Source/Plugins/Plugin_VideoOGL/Src/SDLWindow.cpp index f1123409d8..d6b709df5d 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/SDLWindow.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/SDLWindow.cpp @@ -1,77 +1,77 @@ #include "SDLWindow.h" void SDLWindow::SwapBuffers() { - SDL_GL_SwapBuffers(); + SDL_GL_SwapBuffers(); } void SDLWindow::SetWindowText(const char *text) { - SDL_WM_SetCaption(text, NULL); + SDL_WM_SetCaption(text, NULL); } bool SDLWindow::PeekMessages() { - // TODO implement - return false; + // TODO implement + return false; } void SDLWindow::Update() { - SDL_Surface *surface = SDL_GetVideoSurface(); - if (!surface) { - PanicAlert("Can't ge t surface to update"); - return; - } - - // SetSize(surface->w, surface->h); - updateDim(); - + SDL_Surface *surface = SDL_GetVideoSurface(); + if (!surface) { + PanicAlert("Can't get surface to update"); + return; + } + + //SetSize(surface->w, surface->h); + updateDim(); + } bool SDLWindow::MakeCurrent() { - /* Note: The reason for having the call to SDL_SetVideoMode in here instead - of in OpenGL_Create() is that "make current" is part of the video - mode setting and is not available as a separate call in SDL. We - have to do "make current" here because this method runs in the CPU - thread while OpenGL_Create() runs in a diferent thread and "make - current" has to be done in the same thread that will be making - calls to OpenGL. */ - - // Fetch video info. - const SDL_VideoInfo *videoInfo = SDL_GetVideoInfo(); - if (!videoInfo) { - PanicAlert("Couldn't get video info"); - SDL_Quit(); - return false; - } - // Compute video mode flags. - const int videoFlags = SDL_OPENGL - | ( videoInfo->hw_available ? SDL_HWSURFACE : SDL_SWSURFACE ) - | ( g_Config.bFullscreen ? SDL_FULLSCREEN : 0); - // Set vide mode. - // TODO: Can we use this field or is a separate field needed? - SDL_Surface *screen = SDL_SetVideoMode(GetXwin(), GetYwin(), - 0, videoFlags); - if (!screen) { - PanicAlert("Couldn't set video mode"); - SDL_Quit(); - return false; - } + /* Note: The reason for having the call to SDL_SetVideoMode in here instead + of in OpenGL_Create() is that "make current" is part of the video + mode setting and is not available as a separate call in SDL. We + have to do "make current" here because this method runs in the CPU + thread while OpenGL_Create() runs in a diferent thread and "make + current" has to be done in the same thread that will be making + calls to OpenGL. */ - return true; + // Fetch video info. + const SDL_VideoInfo *videoInfo = SDL_GetVideoInfo(); + if (!videoInfo) { + PanicAlert("Couldn't get video info"); + SDL_Quit(); + return false; + } + // Compute video mode flags. + const int videoFlags = SDL_OPENGL + | ( videoInfo->hw_available ? SDL_HWSURFACE : SDL_SWSURFACE ) + | ( g_Config.bFullscreen ? SDL_FULLSCREEN : 0); + // Set vide mode. + // TODO: Can we use this field or is a separate field needed? + SDL_Surface *screen = SDL_SetVideoMode(GetXwin(), GetYwin(), + 0, videoFlags); + if (!screen) { + PanicAlert("Couldn't set video mode"); + SDL_Quit(); + return false; + } + + return true; } SDLWindow::~SDLWindow() { - SDL_Quit(); + SDL_Quit(); } SDLWindow::SDLWindow() : GLWindow() { - //init sdl video - if (SDL_Init(SDL_INIT_VIDEO) < 0) { - PanicAlert("Failed to init SDL: %s", SDL_GetError()); - SDL_Quit(); - // return NULL; - } - - //setup ogl to use double buffering - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + //init sdl video + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + PanicAlert("Failed to init SDL: %s", SDL_GetError()); + SDL_Quit(); + //return NULL; + } + + // Setup ogl to use double buffering + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/SDLWindow.h b/Source/Plugins/Plugin_VideoOGL/Src/SDLWindow.h index 8cea3a6ab4..f53f921b4b 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/SDLWindow.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/SDLWindow.h @@ -8,22 +8,22 @@ class SDLWindow : public GLWindow { public: - virtual void SwapBuffers(); - virtual void SetWindowText(const char *text); - virtual bool PeekMessages(); - virtual void Update(); - virtual bool MakeCurrent(); + virtual void SwapBuffers(); + virtual void SetWindowText(const char *text); + virtual bool PeekMessages(); + virtual void Update(); + virtual bool MakeCurrent(); - static bool valid() { return true; } - ~SDLWindow(); - SDLWindow(); + static bool valid() { return true; } + ~SDLWindow(); + SDLWindow(); }; #else class SDLWindow : public GLWindow { - public: - SDLWindow() {} +public: + SDLWindow() {} }; #endif #endif diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp index 42f27833ee..974d4556c7 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp @@ -22,7 +22,7 @@ #include "Globals.h" #include "Config.h" #include "ImageWrite.h" -#include "GLUtil.h" +#include "nGLUtil.h" #include "Render.h" namespace TextureConverter diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.h b/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.h index 43e23c2364..79085dff01 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.h @@ -19,7 +19,7 @@ #define _TEXTURECONVERTER_H #include "VideoCommon.h" -#include "GLUtil.h" +#include "nGLUtil.h" // Converts textures between formats // TODO: support multiple texture formats diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.h b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.h index 273a720901..6ea6395557 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.h @@ -21,7 +21,7 @@ #include #include "VideoCommon.h" -#include "GLUtil.h" +#include "nGLUtil.h" #include "BPStructs.h" class TextureMngr diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp index 9c0313aa54..ec6c35ab3b 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp @@ -22,7 +22,7 @@ #include "Config.h" #include "Statistics.h" -#include "GLUtil.h" +#include "nGLUtil.h" #include #include diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Win32Window.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Win32Window.cpp index 84d33999f3..cec96f8a59 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Win32Window.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Win32Window.cpp @@ -1,393 +1,803 @@ +#include "Win32Window.h" + +// Static member data +unsigned int Win32Window::ourWindowCount = 0; +const char* Win32Window::ourClassName = _T("DolphinEmuWnd"); +Win32Window* Win32Window::ourFullscreenWindow = NULL; + + +Win32Window::Win32Window() : GLWindow(), +myHandle (NULL), +myCallback (0), +myCursor (NULL), +myIcon (NULL), +myKeyRepeatEnabled (true), +myIsCursorIn (false) +{ + // Register the window class at first call + if (ourWindowCount == 0) + RegisterWindowClass(); + + // Use small dimensions + //SetWinSize(1, 1); + + // Create the rendering window + if (!(myHandle = CreateWindow(ourClassName, _T(""), WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, + GetXwin(), GetYwin(), NULL, NULL, myhInstance, this))) { + PanicAlert("Error creating GL Window"); + } + + ShowWindow(myHandle, SW_SHOW); + + // Create the rendering context + if (myHandle) + { + VideoMode Mode; + Mode.Width = GetXwin(); + Mode.Height = GetYwin(); + Mode.BitsPerPixel = 32; + Mode.DepthBits = 24; + Mode.StencilBits = 8; + Mode.AntialiasingLevel = 0; + CreateContext(Mode); + + // Don't activate by default + //SetNotActive(); + } +} + +Win32Window::~Win32Window() +{ + // Destroy the custom icon, if any + if (myIcon) + DestroyIcon(myIcon); + + if (!myCallback) + { + // Destroy the window + if (myHandle) + DestroyWindow(myHandle); + + // Decrement the window count + ourWindowCount--; + + // Unregister window class if we were the last window + if (ourWindowCount == 0) + UnregisterClass(ourClassName, GetModuleHandle(NULL)); + } + else + { + // The window is external : remove the hook on its message callback + SetWindowLongPtr(myHandle, GWLP_WNDPROC, myCallback); + } +} + +void Win32Window::SwapBuffers() +{ + if (myDeviceContext && myGLContext) + ::SwapBuffers(myDeviceContext); +} + +void Win32Window::SetWindowText(const char *text) +{ + ::SetWindowText(GetWnd(), text); +} + +void Win32Window::ShowMouseCursor(bool Show) +{ + if (Show) + myCursor = LoadCursor(NULL, IDC_ARROW); + else + myCursor = NULL; + + SetCursor(myCursor); +} + +bool Win32Window::PeekMessages() +{ + // We update the window only if we own it + if (!myCallback) + { + MSG Message; + while (PeekMessage(&Message, myHandle, 0, 0, PM_REMOVE)) + { + TranslateMessage(&Message); + DispatchMessage(&Message); + } + } + return true; // I don't know why this is bool... +} + +void Win32Window::Update() +{ + // We just check all of our events here + // TODO + PeekMessages(); + eventHandler->Update(); + updateDim(); +} + +bool Win32Window::MakeCurrent() +{ + if (myDeviceContext && myGLContext && (wglGetCurrentContext() != myGLContext)) + { + wglMakeCurrent(myDeviceContext, myGLContext); + return true; + } + else + return false; +} + +void Win32Window::RegisterWindowClass() +{ + WNDCLASS WindowClass; + myhInstance = GetModuleHandle(NULL); + WindowClass.style = CS_OWNDC; + WindowClass.lpfnWndProc = &Win32Window::GlobalOnEvent; + WindowClass.cbClsExtra = 0; + WindowClass.cbWndExtra = 0; + WindowClass.hInstance = myhInstance; + WindowClass.hIcon = NULL; + WindowClass.hCursor = 0; + WindowClass.hbrBackground = 0; + WindowClass.lpszMenuName = NULL; + WindowClass.lpszClassName = ourClassName; + if (!RegisterClass(&WindowClass)) + ERROR_LOG("Failed To Register The Window Class\n"); +} + +void Win32Window::SwitchToFullscreen(const VideoMode& Mode) +{ + DEVMODE DevMode; + DevMode.dmSize = sizeof(DEVMODE); + DevMode.dmPelsWidth = Mode.Width; + DevMode.dmPelsHeight = Mode.Height; + DevMode.dmBitsPerPel = Mode.BitsPerPixel; + DevMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL; + + // Apply fullscreen mode + if (ChangeDisplaySettings(&DevMode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) + { + ERROR_LOG("Failed to change display mode for fullscreen\n"); + return; + } + + // Change window style (no border, no titlebar, ...) + SetWindowLong(myHandle, GWL_STYLE, WS_POPUP); + SetWindowLong(myHandle, GWL_EXSTYLE, WS_EX_APPWINDOW); + + // And resize it so that it fits the entire screen + SetWindowPos(myHandle, HWND_TOP, 0, 0, Mode.Width, Mode.Height, SWP_FRAMECHANGED); + ShowWindow(myHandle, SW_SHOW); + + // Set "this" as the current fullscreen window + ourFullscreenWindow = this; + + // SetPixelFormat can fail (really ?) if window style doesn't contain these flags + long Style = GetWindowLong(myHandle, GWL_STYLE); + SetWindowLong(myHandle, GWL_STYLE, Style | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); +} + +//VideoMode Win32Window::GetSupportedVideoModes(std::vector& Modes) +//{ +// // First, clear array to fill +// Modes.clear(); +// +// // Enumerate all available video modes for primary display adapter +// DEVMODE Win32Mode; +// Win32Mode.dmSize = sizeof(DEVMODE); +// for (int Count = 0; EnumDisplaySettings(NULL, Count, &Win32Mode); ++Count) +// { +// // Convert to sfVideoMode +// VideoMode Mode(Win32Mode.dmPelsWidth, Win32Mode.dmPelsHeight, Win32Mode.dmBitsPerPel); +// +// // Add it only if it is not already in the array +// if (std::find(Modes.begin(), Modes.end(), Mode) == Modes.end()) +// Modes.push_back(Mode); +// } +//} + +void Win32Window::CreateContext(VideoMode& Mode) +{ + // TESTING + Mode.DepthBits = 24; + Mode.StencilBits = 8; + //Mode.AntialiasingLevel = 4; + + // Get the device context attached to the window + myDeviceContext = GetDC(myHandle); + if (myDeviceContext == NULL) + { + ERROR_LOG("Failed to get device context of window -- cannot create OpenGL context\n"); + return; + } + + // Let's find a suitable pixel format -- first try with antialiasing + int BestFormat = 0; + if (Mode.AntialiasingLevel > 0) + { + // Get the wglChoosePixelFormatARB function (it is an extension) + PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = reinterpret_cast(wglGetProcAddress("wglChoosePixelFormatARB")); + + // Define the basic attributes we want for our window + int IntAttributes[] = + { + WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, + WGL_SUPPORT_OPENGL_ARB, GL_TRUE, + WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB, + WGL_DOUBLE_BUFFER_ARB, GL_TRUE, + WGL_SAMPLE_BUFFERS_ARB, (Mode.AntialiasingLevel ? GL_TRUE : GL_FALSE), + WGL_SAMPLES_ARB, Mode.AntialiasingLevel, + 0, 0 + }; + + // Let's check how many formats are supporting our requirements + int Formats[128]; + UINT NbFormats; + float FloatAttributes[] = {0, 0}; + bool IsValid = wglChoosePixelFormatARB(myDeviceContext, IntAttributes, FloatAttributes, sizeof(Formats) / sizeof(*Formats), Formats, &NbFormats) != 0; + if (!IsValid || (NbFormats == 0)) + { + if (Mode.AntialiasingLevel > 2) + { + // No format matching our needs : reduce the multisampling level + char errMsg[256]; + sprintf(errMsg, "Failed to find a pixel format supporting %u antialiasing levels ; trying with 2 levels\n", Mode.AntialiasingLevel); + ERROR_LOG(errMsg); + + Mode.AntialiasingLevel = IntAttributes[1] = 2; + IsValid = wglChoosePixelFormatARB(myDeviceContext, IntAttributes, FloatAttributes, sizeof(Formats) / sizeof(*Formats), Formats, &NbFormats) != 0; + } + + if (!IsValid || (NbFormats == 0)) + { + // Cannot find any pixel format supporting multisampling ; disabling antialiasing + ERROR_LOG("Failed to find a pixel format supporting antialiasing ; antialiasing will be disabled\n"); + Mode.AntialiasingLevel = 0; + } + } + + // Get the best format among the returned ones + if (IsValid && (NbFormats > 0)) + { + int BestScore = 0xFFFF; + for (UINT i = 0; i < NbFormats; ++i) + { + // Get the current format's attributes + PIXELFORMATDESCRIPTOR Attribs; + Attribs.nSize = sizeof(PIXELFORMATDESCRIPTOR); + Attribs.nVersion = 1; + DescribePixelFormat(myDeviceContext, Formats[i], sizeof(PIXELFORMATDESCRIPTOR), &Attribs); + + // Evaluate the current configuration + int Color = Attribs.cRedBits + Attribs.cGreenBits + Attribs.cBlueBits + Attribs.cAlphaBits; + int Score = abs(static_cast(Mode.BitsPerPixel - Color)) + // The EvaluateConfig function + abs(static_cast(Mode.DepthBits - Attribs.cDepthBits)) + + abs(static_cast(Mode.StencilBits - Attribs.cStencilBits)); + + // Keep it if it's better than the current best + if (Score < BestScore) + { + BestScore = Score; + BestFormat = Formats[i]; + } + } + } + } + + // Find a pixel format with no antialiasing, if not needed or not supported + if (BestFormat == 0) + { + // Setup a pixel format descriptor from the rendering settings + PIXELFORMATDESCRIPTOR PixelDescriptor; + ZeroMemory(&PixelDescriptor, sizeof(PIXELFORMATDESCRIPTOR)); + PixelDescriptor.nSize = sizeof(PIXELFORMATDESCRIPTOR); + PixelDescriptor.nVersion = 1; + PixelDescriptor.iLayerType = PFD_MAIN_PLANE; + PixelDescriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; + PixelDescriptor.iPixelType = PFD_TYPE_RGBA; + PixelDescriptor.cColorBits = static_cast(Mode.BitsPerPixel); + PixelDescriptor.cDepthBits = static_cast(Mode.DepthBits); + PixelDescriptor.cStencilBits = static_cast(Mode.StencilBits); + + // Get the pixel format that best matches our requirements + BestFormat = ChoosePixelFormat(myDeviceContext, &PixelDescriptor); + if (BestFormat == 0) + { + ERROR_LOG("Failed to find a suitable pixel format for device context -- cannot create OpenGL context\n"); + return; + } + } + + // Extract the depth and stencil bits from the chosen format + PIXELFORMATDESCRIPTOR ActualFormat; + ActualFormat.nSize = sizeof(PIXELFORMATDESCRIPTOR); + ActualFormat.nVersion = 1; + DescribePixelFormat(myDeviceContext, BestFormat, sizeof(PIXELFORMATDESCRIPTOR), &ActualFormat); + Mode.DepthBits = ActualFormat.cDepthBits; + Mode.StencilBits = ActualFormat.cStencilBits; + + // Set the chosen pixel format + if (!SetPixelFormat(myDeviceContext, BestFormat, &ActualFormat)) + { + ERROR_LOG("Failed to set pixel format for device context -- cannot create OpenGL context\n"); + return; + } + + // Create the OpenGL context from the device context + myGLContext = wglCreateContext(myDeviceContext); + if (myGLContext == NULL) + { + ERROR_LOG("Failed to create an OpenGL context for this window\n"); + return; + } + + // Share display lists with other contexts + HGLRC CurrentContext = wglGetCurrentContext(); + if (CurrentContext) + wglShareLists(CurrentContext, myGLContext); + + // Activate the context + MakeCurrent(); + + // Enable multisampling + if (Mode.AntialiasingLevel > 0) + glEnable(GL_MULTISAMPLE_ARB); +} + +void Win32Window::Cleanup() +{ + // Restore the previous video mode (in case we were running in fullscreen) + if (ourFullscreenWindow == this) + { + ChangeDisplaySettings(NULL, 0); + ourFullscreenWindow = NULL; + } + + // Unhide the mouse cursor (in case it was hidden) + ShowMouseCursor(true); + //GetProperty(OGL_HIDECURSOR) + + // Destroy the OpenGL context + if (myGLContext) + { + // Unbind the context before destroying it + //SetNotActive(); + + wglDeleteContext(myGLContext); + myGLContext = NULL; + } + if (myDeviceContext) + { + ReleaseDC(myHandle, myDeviceContext); + myDeviceContext = NULL; + } +} + +//////////////////////////////////////////////////////////// +/// Process a Win32 Event +//////////////////////////////////////////////////////////// +void Win32Window::ProcessEvent(UINT Message, WPARAM WParam, LPARAM LParam) +{ + // Don't process any message until window is created + if (myHandle == NULL) + return; + + switch (Message) + { + // Destroy Event + case WM_DESTROY : + { + // Here we must cleanup resources ! + Cleanup(); + break; + } + + // Set cursor Event + case WM_SETCURSOR : + { + // The mouse has moved, if the cursor is in our window we must refresh the cursor + if (LOWORD(LParam) == HTCLIENT) + SetCursor(myCursor); + break; + } + case WM_CLOSE : + { + sf::Event Evt; + Evt.Type = sf::Event::Closed; + eventHandler->addEvent(&Evt); + break; + } + + // Resize Event + case WM_SIZE : + { + // Update window size + RECT Rect; + GetClientRect(myHandle, &Rect); + SetWinSize(Rect.right - Rect.left, Rect.bottom - Rect.top); + + sf::Event Evt; + Evt.Type = sf::Event::Resized; + Evt.Size.Width = GetXwin(); + Evt.Size.Height = GetYwin(); + eventHandler->addEvent(&Evt); + break; + } + // Gain focus Event + case WM_SETFOCUS : + { + sf::Event Evt; + Evt.Type = sf::Event::GainedFocus; + eventHandler->addEvent(&Evt); + break; + } + + // Lost focus Event + case WM_KILLFOCUS : + { + sf::Event Evt; + Evt.Type = sf::Event::LostFocus; + eventHandler->addEvent(&Evt); + break; + } + + // Text Event + case WM_CHAR : + { + sf::Event Evt; + Evt.Type = sf::Event::TextEntered; + Evt.Text.Unicode = static_cast(WParam); + eventHandler->addEvent(&Evt); + break; + } + // Keydown Event + case WM_KEYDOWN : + case WM_SYSKEYDOWN : + { + if (myKeyRepeatEnabled || ((LParam & (1 << 30)) == 0)) + { + sf::Event Evt; + Evt.Type = sf::Event::KeyPressed; + Evt.Key.Code = (WParam == VK_SHIFT) ? GetShiftState(true) : VirtualKeyCodeToSF(WParam, LParam); + Evt.Key.Alt = HIWORD(GetAsyncKeyState(VK_MENU)) != 0; + Evt.Key.Control = HIWORD(GetAsyncKeyState(VK_CONTROL)) != 0; + Evt.Key.Shift = HIWORD(GetAsyncKeyState(VK_SHIFT)) != 0; + eventHandler->addEvent(&Evt); + } + break; + } + + // Keyup Event + case WM_KEYUP : + case WM_SYSKEYUP : + { + sf::Event Evt; + Evt.Type = sf::Event::KeyReleased; + Evt.Key.Code = (WParam == VK_SHIFT) ? GetShiftState(false) : VirtualKeyCodeToSF(WParam, LParam); + Evt.Key.Alt = HIWORD(GetAsyncKeyState(VK_MENU)) != 0; + Evt.Key.Control = HIWORD(GetAsyncKeyState(VK_CONTROL)) != 0; + Evt.Key.Shift = HIWORD(GetAsyncKeyState(VK_SHIFT)) != 0; + eventHandler->addEvent(&Evt); + break; + } + + // Mouse wheel Event + case WM_MOUSEWHEEL : + { + sf::Event Evt; + Evt.Type = sf::Event::MouseWheelMoved; + Evt.MouseWheel.Delta = static_cast(HIWORD(WParam)) / 120; + eventHandler->addEvent(&Evt); + break; + } + + // Mouse left button down Event + case WM_LBUTTONDOWN : + { + sf::Event Evt; + Evt.Type = sf::Event::MouseButtonPressed; + Evt.MouseButton.Button = sf::Mouse::Left; + Evt.MouseButton.X = LOWORD(LParam); + Evt.MouseButton.Y = HIWORD(LParam); + eventHandler->addEvent(&Evt); + break; + } + + // Mouse left button up Event + case WM_LBUTTONUP : + { + sf::Event Evt; + Evt.Type = sf::Event::MouseButtonReleased; + Evt.MouseButton.Button = sf::Mouse::Left; + Evt.MouseButton.X = LOWORD(LParam); + Evt.MouseButton.Y = HIWORD(LParam); + eventHandler->addEvent(&Evt); + break; + } + + // Mouse right button down Event + case WM_RBUTTONDOWN : + { + sf::Event Evt; + Evt.Type = sf::Event::MouseButtonPressed; + Evt.MouseButton.Button = sf::Mouse::Right; + Evt.MouseButton.X = LOWORD(LParam); + Evt.MouseButton.Y = HIWORD(LParam); + eventHandler->addEvent(&Evt); + break; + } + + // Mouse right button up Event + case WM_RBUTTONUP : + { + sf::Event Evt; + Evt.Type = sf::Event::MouseButtonReleased; + Evt.MouseButton.Button = sf::Mouse::Right; + Evt.MouseButton.X = LOWORD(LParam); + Evt.MouseButton.Y = HIWORD(LParam); + eventHandler->addEvent(&Evt); + break; + } + + // Mouse wheel button down Event + case WM_MBUTTONDOWN : + { + sf::Event Evt; + Evt.Type = sf::Event::MouseButtonPressed; + Evt.MouseButton.Button = sf::Mouse::Middle; + Evt.MouseButton.X = LOWORD(LParam); + Evt.MouseButton.Y = HIWORD(LParam); + eventHandler->addEvent(&Evt); + break; + } + + // Mouse wheel button up Event + case WM_MBUTTONUP : + { + sf::Event Evt; + Evt.Type = sf::Event::MouseButtonReleased; + Evt.MouseButton.Button = sf::Mouse::Middle; + Evt.MouseButton.X = LOWORD(LParam); + Evt.MouseButton.Y = HIWORD(LParam); + eventHandler->addEvent(&Evt); + break; + } + + // Mouse X button down Event + case WM_XBUTTONDOWN : + { + sf::Event Evt; + Evt.Type = sf::Event::MouseButtonPressed; + Evt.MouseButton.Button = HIWORD(WParam) == XBUTTON1 ? sf::Mouse::XButton1 : sf::Mouse::XButton2; + Evt.MouseButton.X = LOWORD(LParam); + Evt.MouseButton.Y = HIWORD(LParam); + eventHandler->addEvent(&Evt); + break; + } + + // Mouse X button up Event + case WM_XBUTTONUP : + { + sf::Event Evt; + Evt.Type = sf::Event::MouseButtonReleased; + Evt.MouseButton.Button = HIWORD(WParam) == XBUTTON1 ? sf::Mouse::XButton1 : sf::Mouse::XButton2; + Evt.MouseButton.X = LOWORD(LParam); + eventHandler->addEvent(&Evt); + break; + } + + // Mouse move Event + case WM_MOUSEMOVE : + { + // Check if we need to generate a MouseEntered Event + if (!myIsCursorIn) + { + TRACKMOUSEEVENT MouseEvent; + MouseEvent.cbSize = sizeof(TRACKMOUSEEVENT); + MouseEvent.hwndTrack = myHandle; + MouseEvent.dwFlags = TME_LEAVE; + TrackMouseEvent(&MouseEvent); + + myIsCursorIn = true; + + sf::Event Evt; + Evt.Type = sf::Event::MouseEntered; + eventHandler->addEvent(&Evt); + } + + sf::Event Evt; + Evt.Type = sf::Event::MouseMoved; + Evt.MouseMove.X = LOWORD(LParam); + Evt.MouseMove.Y = HIWORD(LParam); // (shuffle2) Added this, check to see if it's good + eventHandler->addEvent(&Evt); + break; + } + + // Mouse leave Event + case WM_MOUSELEAVE : + { + myIsCursorIn = false; + + sf::Event Evt; + Evt.Type = sf::Event::MouseLeft; + eventHandler->addEvent(&Evt); + break; + } + } +} + +/////////////////////////////////////////////////////////// +/// Check the state of the shift keys on a key sf::Event, +/// and return the corresponding SF key code +//////////////////////////////////////////////////////////// +sf::Key::Code Win32Window::GetShiftState(bool KeyDown) +{ + static bool LShiftPrevDown = false; + static bool RShiftPrevDown = false; + + bool LShiftDown = (HIWORD(GetAsyncKeyState(VK_LSHIFT)) != 0); + bool RShiftDown = (HIWORD(GetAsyncKeyState(VK_RSHIFT)) != 0); + + sf::Key::Code Code = sf::Key::Code(0); + if (KeyDown) + { + if (!LShiftPrevDown && LShiftDown) Code = sf::Key::LShift; + else if (!RShiftPrevDown && RShiftDown) Code = sf::Key::RShift; + } + else + { + if (LShiftPrevDown && !LShiftDown) Code = sf::Key::LShift; + else if (RShiftPrevDown && !RShiftDown) Code = sf::Key::RShift; + } + + LShiftPrevDown = LShiftDown; + RShiftPrevDown = RShiftDown; + + return Code; +} + /////////////////////////////////////////////////////////// /// Convert a Win32 virtual key code to a SFML key code //////////////////////////////////////////////////////////// -Key::Code VirtualKeyCodeToSF(WPARAM VirtualKey, LPARAM Flags) +sf::Key::Code Win32Window::VirtualKeyCodeToSF(WPARAM VirtualKey, LPARAM Flags) { - switch (VirtualKey) - { - // VK_SHIFT is handled by the GetShiftState function - case VK_MENU : return (Flags & (1 << 24)) ? Key::RAlt : Key::LAlt; - case VK_CONTROL : return (Flags & (1 << 24)) ? Key::RControl : Key::LControl; - case VK_LWIN : return Key::LSystem; - case VK_RWIN : return Key::RSystem; - case VK_APPS : return Key::Menu; - case VK_OEM_1 : return Key::SemiColon; - case VK_OEM_2 : return Key::Slash; - case VK_OEM_PLUS : return Key::Equal; - case VK_OEM_MINUS : return Key::Dash; - case VK_OEM_4 : return Key::LBracket; - case VK_OEM_6 : return Key::RBracket; - case VK_OEM_COMMA : return Key::Comma; - case VK_OEM_PERIOD : return Key::Period; - case VK_OEM_7 : return Key::Quote; - case VK_OEM_5 : return Key::BackSlash; - case VK_OEM_3 : return Key::Tilde; - case VK_ESCAPE : return Key::Escape; - case VK_SPACE : return Key::Space; - case VK_RETURN : return Key::Return; - case VK_BACK : return Key::Back; - case VK_TAB : return Key::Tab; - case VK_PRIOR : return Key::PageUp; - case VK_NEXT : return Key::PageDown; - case VK_END : return Key::End; - case VK_HOME : return Key::Home; - case VK_INSERT : return Key::Insert; - case VK_DELETE : return Key::Delete; - case VK_ADD : return Key::Add; - case VK_SUBTRACT : return Key::Subtract; - case VK_MULTIPLY : return Key::Multiply; - case VK_DIVIDE : return Key::Divide; - case VK_PAUSE : return Key::Pause; - case VK_F1 : return Key::F1; - case VK_F2 : return Key::F2; - case VK_F3 : return Key::F3; - case VK_F4 : return Key::F4; - case VK_F5 : return Key::F5; - case VK_F6 : return Key::F6; - case VK_F7 : return Key::F7; - case VK_F8 : return Key::F8; - case VK_F9 : return Key::F9; - case VK_F10 : return Key::F10; - case VK_F11 : return Key::F11; - case VK_F12 : return Key::F12; - case VK_F13 : return Key::F13; - case VK_F14 : return Key::F14; - case VK_F15 : return Key::F15; - case VK_RIGHT : return Key::Right; - case VK_UP : return Key::Up; - case VK_DOWN : return Key::Down; - case VK_NUMPAD0 : return Key::Numpad0; - case VK_NUMPAD1 : return Key::Numpad1; - case VK_NUMPAD2 : return Key::Numpad2; - case VK_NUMPAD3 : return Key::Numpad3; - case VK_NUMPAD4 : return Key::Numpad4; - case VK_NUMPAD5 : return Key::Numpad5; - case VK_NUMPAD6 : return Key::Numpad6; - case VK_NUMPAD7 : return Key::Numpad7; - case VK_NUMPAD8 : return Key::Numpad8; - case VK_NUMPAD9 : return Key::Numpad9; - case 'A' : return Key::A; - case 'Z' : return Key::Z; - case 'E' : return Key::E; - case 'R' : return Key::R; - case 'T' : return Key::T; - case 'Y' : return Key::Y; - case 'U' : return Key::U; - case 'I' : return Key::I; - case 'O' : return Key::O; - case 'P' : return Key::P; - case 'Q' : return Key::Q; - case 'S' : return Key::S; - case 'D' : return Key::D; - case 'F' : return Key::F; - case 'G' : return Key::G; - case 'H' : return Key::H; - case 'J' : return Key::J; - case 'K' : return Key::K; - case 'L' : return Key::L; - case 'M' : return Key::M; - case 'W' : return Key::W; - case 'X' : return Key::X; - case 'C' : return Key::C; - case 'V' : return Key::V; - case 'B' : return Key::B; - case 'N' : return Key::N; - case '0' : return Key::Num0; - case '1' : return Key::Num1; - case '2' : return Key::Num2; - case '3' : return Key::Num3; - case '4' : return Key::Num4; - case '5' : return Key::Num5; - case '6' : return Key::Num6; - case '7' : return Key::Num7; - case '8' : return Key::Num8; - case '9' : return Key::Num9; - } + switch (VirtualKey) + { + // VK_SHIFT is handled by the GetShiftState function + case VK_MENU : return (Flags & (1 << 24)) ? sf::Key::RAlt : sf::Key::LAlt; + case VK_CONTROL : return (Flags & (1 << 24)) ? sf::Key::RControl : sf::Key::LControl; + case VK_LWIN : return sf::Key::LSystem; + case VK_RWIN : return sf::Key::RSystem; + case VK_APPS : return sf::Key::Menu; + case VK_OEM_1 : return sf::Key::SemiColon; + case VK_OEM_2 : return sf::Key::Slash; + case VK_OEM_PLUS : return sf::Key::Equal; + case VK_OEM_MINUS : return sf::Key::Dash; + case VK_OEM_4 : return sf::Key::LBracket; + case VK_OEM_6 : return sf::Key::RBracket; + case VK_OEM_COMMA : return sf::Key::Comma; + case VK_OEM_PERIOD : return sf::Key::Period; + case VK_OEM_7 : return sf::Key::Quote; + case VK_OEM_5 : return sf::Key::BackSlash; + case VK_OEM_3 : return sf::Key::Tilde; + case VK_ESCAPE : return sf::Key::Escape; + case VK_SPACE : return sf::Key::Space; + case VK_RETURN : return sf::Key::Return; + case VK_BACK : return sf::Key::Back; + case VK_TAB : return sf::Key::Tab; + case VK_PRIOR : return sf::Key::PageUp; + case VK_NEXT : return sf::Key::PageDown; + case VK_END : return sf::Key::End; + case VK_HOME : return sf::Key::Home; + case VK_INSERT : return sf::Key::Insert; + case VK_DELETE : return sf::Key::Delete; + case VK_ADD : return sf::Key::Add; + case VK_SUBTRACT : return sf::Key::Subtract; + case VK_MULTIPLY : return sf::Key::Multiply; + case VK_DIVIDE : return sf::Key::Divide; + case VK_PAUSE : return sf::Key::Pause; + case VK_F1 : return sf::Key::F1; + case VK_F2 : return sf::Key::F2; + case VK_F3 : return sf::Key::F3; + case VK_F4 : return sf::Key::F4; + case VK_F5 : return sf::Key::F5; + case VK_F6 : return sf::Key::F6; + case VK_F7 : return sf::Key::F7; + case VK_F8 : return sf::Key::F8; + case VK_F9 : return sf::Key::F9; + case VK_F10 : return sf::Key::F10; + case VK_F11 : return sf::Key::F11; + case VK_F12 : return sf::Key::F12; + case VK_F13 : return sf::Key::F13; + case VK_F14 : return sf::Key::F14; + case VK_F15 : return sf::Key::F15; + case VK_LEFT : return sf::Key::Left; + case VK_RIGHT : return sf::Key::Right; + case VK_UP : return sf::Key::Up; + case VK_DOWN : return sf::Key::Down; + case VK_NUMPAD0 : return sf::Key::Numpad0; + case VK_NUMPAD1 : return sf::Key::Numpad1; + case VK_NUMPAD2 : return sf::Key::Numpad2; + case VK_NUMPAD3 : return sf::Key::Numpad3; + case VK_NUMPAD4 : return sf::Key::Numpad4; + case VK_NUMPAD5 : return sf::Key::Numpad5; + case VK_NUMPAD6 : return sf::Key::Numpad6; + case VK_NUMPAD7 : return sf::Key::Numpad7; + case VK_NUMPAD8 : return sf::Key::Numpad8; + case VK_NUMPAD9 : return sf::Key::Numpad9; + case 'A' : return sf::Key::A; + case 'Z' : return sf::Key::Z; + case 'E' : return sf::Key::E; + case 'R' : return sf::Key::R; + case 'T' : return sf::Key::T; + case 'Y' : return sf::Key::Y; + case 'U' : return sf::Key::U; + case 'I' : return sf::Key::I; + case 'O' : return sf::Key::O; + case 'P' : return sf::Key::P; + case 'Q' : return sf::Key::Q; + case 'S' : return sf::Key::S; + case 'D' : return sf::Key::D; + case 'F' : return sf::Key::F; + case 'G' : return sf::Key::G; + case 'H' : return sf::Key::H; + case 'J' : return sf::Key::J; + case 'K' : return sf::Key::K; + case 'L' : return sf::Key::L; + case 'M' : return sf::Key::M; + case 'W' : return sf::Key::W; + case 'X' : return sf::Key::X; + case 'C' : return sf::Key::C; + case 'V' : return sf::Key::V; + case 'B' : return sf::Key::B; + case 'N' : return sf::Key::N; + case '0' : return sf::Key::Num0; + case '1' : return sf::Key::Num1; + case '2' : return sf::Key::Num2; + case '3' : return sf::Key::Num3; + case '4' : return sf::Key::Num4; + case '5' : return sf::Key::Num5; + case '6' : return sf::Key::Num6; + case '7' : return sf::Key::Num7; + case '8' : return sf::Key::Num8; + case '9' : return sf::Key::Num9; + } - return Key::Code(0); + return sf::Key::Code(0); } -//////////////////////////////////////////////////////////// -/// Process a Win32 event -//////////////////////////////////////////////////////////// -void ProcessEvent(UINT Message, WPARAM WParam, LPARAM LParam) -{ - // Don't process any message until window is created - if (myHandle == NULL) - return; - - switch (Message) - { - // Destroy event - case WM_DESTROY : - { - // Here we must cleanup resources ! - Cleanup(); - break; - } - - // Set cursor event - case WM_SETCURSOR : - { - // The mouse has moved, if the cursor is in our window we must refresh the cursor - if (LOWORD(LParam) == HTCLIENT) - SetCursor(myCursor); - - break; - } - case WM_CLOSE : - { - Event Evt; - Evt.Type = Event::Closed; - SendEvent(Evt); - break; - } - - // Resize event - case WM_SIZE : - { - // Update window size - RECT Rect; - GetClientRect(myHandle, &Rect); - myWidth = Rect.right - Rect.left; - myHeight = Rect.bottom - Rect.top; - - Event Evt; - Evt.Type = Event::Resized; - Evt.Size.Width = myWidth; - Evt.Size.Height = myHeight; - SendEvent(Evt); - break; - } - // Gain focus event - case WM_SETFOCUS : - { - Event Evt; - Evt.Type = Event::GainedFocus; - SendEvent(Evt); - break; - } - - // Lost focus event - case WM_KILLFOCUS : - { - Event Evt; - Evt.Type = Event::LostFocus; - SendEvent(Evt); - break; - } - - // Text event - case WM_CHAR : - { - Event Evt; - Evt.Type = Event::TextEntered; - Evt.Text.Unicode = static_cast(WParam); - SendEvent(Evt); - break; - } - // Keydown event - case WM_KEYDOWN : - case WM_SYSKEYDOWN : - { - if (myKeyRepeatEnabled || ((LParam & (1 << 30)) == 0)) - { - Event Evt; - Evt.Type = Event::KeyPressed; - Evt.Key.Code = (WParam == VK_SHIFT) ? GetShiftState(true) : VirtualKeyCodeToSF(WParam, LParam); - Evt.Key.Alt = HIWORD(GetAsyncKeyState(VK_MENU)) != 0; - Evt.Key.Control = HIWORD(GetAsyncKeyState(VK_CONTROL)) != 0; - Evt.Key.Shift = HIWORD(GetAsyncKeyState(VK_SHIFT)) != 0; - SendEvent(Evt); - } - break; - } - - // Keyup event - case WM_KEYUP : - case WM_SYSKEYUP : - { - Event Evt; - Evt.Type = Event::KeyReleased; - Evt.Key.Code = (WParam == VK_SHIFT) ? GetShiftState(false) : VirtualKeyCodeToSF(WParam, LParam); - Evt.Key.Alt = HIWORD(GetAsyncKeyState(VK_MENU)) != 0; - Evt.Key.Control = HIWORD(GetAsyncKeyState(VK_CONTROL)) != 0; - Evt.Key.Shift = HIWORD(GetAsyncKeyState(VK_SHIFT)) != 0; - SendEvent(Evt); - break; - } - - // Mouse wheel event - case WM_MOUSEWHEEL : - { - Event Evt; - Evt.Type = Event::MouseWheelMoved; - Evt.MouseWheel.Delta = static_cast(HIWORD(WParam)) / 120; - SendEvent(Evt); - break; - } - - // Mouse left button down event - case WM_LBUTTONDOWN : - { - Event Evt; - Evt.Type = Event::MouseButtonPressed; - Evt.MouseButton.Button = Mouse::Left; - Evt.MouseButton.X = LOWORD(LParam); - Evt.MouseButton.Y = HIWORD(LParam); - SendEvent(Evt); - break; - } - - // Mouse left button up event - case WM_LBUTTONUP : - { - Event Evt; - Evt.Type = Event::MouseButtonReleased; - Evt.MouseButton.Button = Mouse::Left; - Evt.MouseButton.X = LOWORD(LParam); - Evt.MouseButton.Y = HIWORD(LParam); - SendEvent(Evt); - break; - } - - // Mouse right button down event - case WM_RBUTTONDOWN : - { - Event Evt; - Evt.Type = Event::MouseButtonPressed; - Evt.MouseButton.Button = Mouse::Right; - Evt.MouseButton.X = LOWORD(LParam); - Evt.MouseButton.Y = HIWORD(LParam); - SendEvent(Evt); - break; - } - - // Mouse right button up event - case WM_RBUTTONUP : - { - Event Evt; - Evt.Type = Event::MouseButtonReleased; - Evt.MouseButton.Button = Mouse::Right; - Evt.MouseButton.X = LOWORD(LParam); - Evt.MouseButton.Y = HIWORD(LParam); - SendEvent(Evt); - break; - } - - // Mouse wheel button down event - case WM_MBUTTONDOWN : - { - Event Evt; - Evt.Type = Event::MouseButtonPressed; - Evt.MouseButton.Button = Mouse::Middle; - Evt.MouseButton.X = LOWORD(LParam); - Evt.MouseButton.Y = HIWORD(LParam); - SendEvent(Evt); - break; - } - - // Mouse wheel button up event - case WM_MBUTTONUP : - { - Event Evt; - Evt.Type = Event::MouseButtonReleased; - Evt.MouseButton.Button = Mouse::Middle; - Evt.MouseButton.X = LOWORD(LParam); - Evt.MouseButton.Y = HIWORD(LParam); - SendEvent(Evt); - break; - } - - // Mouse X button down event - case WM_XBUTTONDOWN : - { - Event Evt; - Evt.Type = Event::MouseButtonPressed; - Evt.MouseButton.Button = HIWORD(WParam) == XBUTTON1 ? Mouse::XButton1 : Mouse::XButton2; - Evt.MouseButton.X = LOWORD(LParam); - Evt.MouseButton.Y = HIWORD(LParam); - SendEvent(Evt); - break; - } - - // Mouse X button up event - case WM_XBUTTONUP : - { - Event Evt; - Evt.Type = Event::MouseButtonReleased; - Evt.MouseButton.Button = HIWORD(WParam) == XBUTTON1 ? Mouse::XButton1 : Mouse::XButton2; - Evt.MouseButton.X = LOWORD(LParam); - SendEvent(Evt); - break; - } - - // Mouse move event - case WM_MOUSEMOVE : - { - // Check if we need to generate a MouseEntered event - if (!myIsCursorIn) - { - TRACKMOUSEEVENT MouseEvent; - MouseEvent.cbSize = sizeof(TRACKMOUSEEVENT); - MouseEvent.hwndTrack = myHandle; - MouseEvent.dwFlags = TME_LEAVE; - TrackMouseEvent(&MouseEvent); - - myIsCursorIn = true; - - Event Evt; - Evt.Type = Event::MouseEntered; - SendEvent(Evt); - } - - Event Evt; - Evt.Type = Event::MouseMoved; - Evt.MouseMove.X = LOWORD(LParam); - SendEvent(Evt); - break; - } - - // Mouse leave event - case WM_MOUSELEAVE : - { - myIsCursorIn = false; - - Event Evt; - Evt.Type = Event::MouseLeft; - SendEvent(Evt); - break; - } - } -} - - /////////////////////////////////////////////////////////// -/// Check the state of the shift keys on a key event, -/// and return the corresponding SF key code +/// Win32 Callback for the window class //////////////////////////////////////////////////////////// -Key::Code WindowImplWin32::GetShiftState(bool KeyDown) +LRESULT CALLBACK Win32Window::GlobalOnEvent(HWND Handle, UINT Message, WPARAM WParam, LPARAM LParam) { - static bool LShiftPrevDown = false; - static bool RShiftPrevDown = false; + // Associate handle and Window instance when the creation message is received + if (Message == WM_CREATE) + { + // Get Win32Window instance (it was passed as the last argument of CreateWindow) + long This = reinterpret_cast(reinterpret_cast(LParam)->lpCreateParams); - bool LShiftDown = (HIWORD(GetAsyncKeyState(VK_LSHIFT)) != 0); - bool RShiftDown = (HIWORD(GetAsyncKeyState(VK_RSHIFT)) != 0); + // Set as the "user data" parameter of the window + SetWindowLongPtr(Handle, GWLP_USERDATA, This); + } - Key::Code Code = Key::Code(0); - if (KeyDown) - { - if (!LShiftPrevDown && LShiftDown) Code = Key::LShift; - else if (!RShiftPrevDown && RShiftDown) Code = Key::RShift; - } - else - { - if (LShiftPrevDown && !LShiftDown) Code = Key::LShift; - else if (RShiftPrevDown && !RShiftDown) Code = Key::RShift; - } + // Get the GLWindow instance corresponding to the window handle + Win32Window* Window = reinterpret_cast(GetWindowLongPtr(Handle, GWLP_USERDATA)); - LShiftPrevDown = LShiftDown; - RShiftPrevDown = RShiftDown; + // Forward the event to the appropriate function + if (Window) + { + Window->ProcessEvent(Message, WParam, LParam); - return Code; + if (Window->myCallback) + return CallWindowProc(reinterpret_cast(Window->myCallback), Handle, Message, WParam, LParam); + } + + // We don't forward the WM_CLOSE message to prevent the OS from automatically destroying the window + if (Message == WM_CLOSE) + return 0; + + return DefWindowProc(Handle, Message, WParam, LParam); } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Win32Window.h b/Source/Plugins/Plugin_VideoOGL/Src/Win32Window.h index da7de1e906..4e1ae5f4ce 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Win32Window.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/Win32Window.h @@ -6,24 +6,65 @@ #ifdef _WIN32 class Win32Window : public GLWindow { - virtual void SwapBuffers(); - virtual void SetWindowText(const char *text); - virtual bool PeekMessages(); - virtual void Update(); - virtual bool MakeCurrent(); - - static bool valid() { return true; } - ~Win32Window(); - Win32Window(); - static sf::Key::Code KeysymToSF(KeySym Sym); +public: + virtual void SwapBuffers(); + virtual void SetWindowText(const char *text); + virtual bool PeekMessages(); + virtual void Update(); + virtual bool MakeCurrent(); + HWND GetWnd(){return myHandle;}; + HWND GetParentWnd(){return myParent;}; + + static bool valid() { return true; } + ~Win32Window(); + Win32Window(); + static sf::Key::Code VirtualKeyCodeToSF(WPARAM VirtualKey, LPARAM Flags); + static sf::Key::Code GetShiftState(bool KeyDown); + +private: + struct VideoMode + { + unsigned int Width; + unsigned int Height; + unsigned int BitsPerPixel; + unsigned int DepthBits; + unsigned int StencilBits; + unsigned int AntialiasingLevel; + }; + + virtual void ShowMouseCursor(bool Show); + void RegisterWindowClass(); + void SwitchToFullscreen(const VideoMode& Mode); + void CreateContext(VideoMode& Mode); + void Cleanup(); + void ProcessEvent(UINT Message, WPARAM WParam, LPARAM LParam); + static LRESULT CALLBACK GlobalOnEvent(HWND Handle, UINT Message, WPARAM WParam, LPARAM LParam); + + // Static member data + static unsigned int ourWindowCount; + static const char* ourClassName; + static Win32Window* ourFullscreenWindow; + + // Member data + HWND myHandle; + HINSTANCE myhInstance; + HWND myParent; // Possibly not wanted here + long myCallback; + HCURSOR myCursor; + HICON myIcon; + bool myKeyRepeatEnabled; + bool myIsCursorIn; + HDC myDeviceContext; + HGLRC myGLContext; }; #else class Win32Window : public GLWindow { - public: - Win32Window {} +public: + Win32Window {} }; -#endif +#endif //_WIN32 +#endif //_WIN32WINDOW_H diff --git a/Source/Plugins/Plugin_VideoOGL/Src/X11Window.cpp b/Source/Plugins/Plugin_VideoOGL/Src/X11Window.cpp index bbe3fd5287..ed0cf32904 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/X11Window.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/X11Window.cpp @@ -351,7 +351,7 @@ sf::Key::Code X11Window::KeysymToSF(KeySym Sym) { case XK_KP_6 : return sf::Key::Numpad6; case XK_KP_7 : return sf::Key::Numpad7; case XK_KP_8 : return sf::Key::Numpad8; - case XK_Z : return sf::Key::Z; + case XK_Z : return sf::Key::Z; case XK_E : return sf::Key::E; case XK_R : return sf::Key::R; case XK_T : return sf::Key::T; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/XFB.cpp b/Source/Plugins/Plugin_VideoOGL/Src/XFB.cpp index 2342216848..56a8821159 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/XFB.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/XFB.cpp @@ -19,7 +19,7 @@ // Preliminary non-working code. #include "Globals.h" -#include "GLUtil.h" +#include "nGLUtil.h" #include "MemoryUtil.h" #include "Render.h" #include "TextureMngr.h" diff --git a/Source/Plugins/Plugin_VideoOGL/Src/nGLUtil.cpp b/Source/Plugins/Plugin_VideoOGL/Src/nGLUtil.cpp index 7d526e9035..6fe774f892 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/nGLUtil.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/nGLUtil.cpp @@ -26,112 +26,114 @@ GLWindow *glWin = NULL; void OpenGL_SwapBuffers() { - glWin->SwapBuffers(); + glWin->SwapBuffers(); } void OpenGL_SetWindowText(const char *text) { - glWin->SetWindowText(text); + glWin->SetWindowText(text); } unsigned int Callback_PeekMessages() { - return glWin->PeekMessages(); + return glWin->PeekMessages(); } void UpdateFPSDisplay(const char *text) { - char temp[512]; - sprintf(temp, "SVN R%s: GL: %s", SVN_REV_STR, text); - OpenGL_SetWindowText(temp); + char temp[512]; + sprintf(temp, "SVN R%s: GL: %s", SVN_REV_STR, text); + OpenGL_SetWindowText(temp); } // ======================================================================================= // Create window. Called from main.cpp -bool OpenGL_Create(SVideoInitialize &_VideoInitialize, - int width, int height) +bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int width, int height) { - g_VideoInitialize.pPeekMessages = &Callback_PeekMessages; - g_VideoInitialize.pUpdateFPSDisplay = &UpdateFPSDisplay; + g_VideoInitialize.pPeekMessages = &Callback_PeekMessages; + g_VideoInitialize.pUpdateFPSDisplay = &UpdateFPSDisplay; - if (strncasecmp(g_Config.iBackend, "sdl", 10) == 0) - glWin = new SDLWindow(); - else if (strncasecmp(g_Config.iBackend, "x11", 10) == 0) - glWin = new X11Window(); - else if (strncasecmp(g_Config.iBackend, "wxgl", 10) == 0) - glWin = new WXGLWindow(); - else - PanicAlert("Invalid backend %s", g_Config.iBackend); - - if (! glWin) - return false; + if (strncasecmp(g_Config.iBackend, "sdl", 10) == 0) + glWin = new SDLWindow(); + else if (strncasecmp(g_Config.iBackend, "x11", 10) == 0) + glWin = new X11Window(); + else if (strncasecmp(g_Config.iBackend, "wxgl", 10) == 0) + glWin = new WXGLWindow(); + else if (strncasecmp(g_Config.iBackend, "windows", 10) == 0) + glWin = new Win32Window(); + else + PanicAlert("Invalid backend %s", g_Config.iBackend); - glWin->SetEventHandler((EventHandler *)globals->eventHandler); - return true; + if (! glWin) + return false; + + glWin->SetEventHandler((EventHandler *)globals->eventHandler); + return true; } bool OpenGL_MakeCurrent() { - return glWin->MakeCurrent(); + return glWin->MakeCurrent(); } // ======================================================================================= -// Update window width, size and etc. Called from Render.cpp +// Update window width, size and etc. Called from Render.cpp and XFB.cpp // ---------------- void OpenGL_Update() { - glWin->Update(); + glWin->Update(); } - // ======================================================================================= // Close plugin // ---------------- void OpenGL_Shutdown() { - delete glWin; + delete glWin; } u32 OpenGL_GetWidth() { - return glWin->GetXwin(); + return glWin->GetXwin(); } u32 OpenGL_GetHeight() { - return glWin->GetYwin(); + return glWin->GetYwin(); } void OpenGL_SetSize(u32 width, u32 height) { - glWin->SetWinSize(width, height); + glWin->SetWinSize(width, height); } int OpenGL_GetXoff() { - return glWin->GetXoff(); + return glWin->GetXoff(); } int OpenGL_GetYoff() { - return glWin->GetYoff(); + return glWin->GetYoff(); } float OpenGL_GetXmax() { - return glWin->GetXmax(); + return glWin->GetXmax(); } float OpenGL_GetYmax() { - return glWin->GetYmax(); + return glWin->GetYmax(); } void OpenGL_AddBackends(ConfigDialog *frame) { - if(SDLWindow::valid()) - frame->AddRenderBackend("SDL"); - if(X11Window::valid()) - frame->AddRenderBackend("X11"); - if(WXGLWindow::valid()) - frame->AddRenderBackend("WXGL"); + if(SDLWindow::valid()) + frame->AddRenderBackend("SDL"); + if(X11Window::valid()) + frame->AddRenderBackend("X11"); + if(WXGLWindow::valid()) + frame->AddRenderBackend("WXGL"); + if(Win32Window::valid()) + frame->AddRenderBackend("Windows"); // Not "Win32" because retarded people will ask where "win64" is... } void OpenGL_AddResolutions(ConfigDialog *frame) { - // TODO get resolution iter + // TODO get resolution iter } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/nGLUtil.h b/Source/Plugins/Plugin_VideoOGL/Src/nGLUtil.h index 44cbb6850a..17a55dd53c 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/nGLUtil.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/nGLUtil.h @@ -26,6 +26,7 @@ #include "SDLWindow.h" #include "X11Window.h" #include "WXGLWindow.h" +#include "Win32Window.h" #ifndef GL_DEPTH24_STENCIL8_EXT // allows FBOs to support stencils #define GL_DEPTH_STENCIL_EXT 0x84F9 diff --git a/Source/Plugins/Plugin_VideoOGL/Src/nmain.cpp b/Source/Plugins/Plugin_VideoOGL/Src/nmain.cpp index a3d819c816..cef6119df4 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/nmain.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/nmain.cpp @@ -26,7 +26,7 @@ #include "LookUpTables.h" #include "ImageWrite.h" #include "Render.h" -#include "GLUtil.h" +#include "nGLUtil.h" #include "Fifo.h" #include "OpcodeDecoding.h" #include "TextureMngr.h" @@ -47,6 +47,53 @@ SVideoInitialize g_VideoInitialize; PLUGIN_GLOBALS* globals; +////////////////////////////////////////////////////////////////////////// +// Nasty stuff which win32 needs for wxw +////////////////////////////////////////////////////////////////////////// +#if defined(_WIN32) && defined(HAVE_WX) && HAVE_WX +HINSTANCE g_hInstance; + +class wxDLLApp : public wxApp +{ + bool OnInit() + { + return true; + } +}; +IMPLEMENT_APP_NO_MAIN(wxDLLApp) + +WXDLLIMPEXP_BASE void wxSetInstance(HINSTANCE hInst); + +BOOL APIENTRY DllMain(HINSTANCE hinstDLL, // DLL module handle + DWORD dwReason, // reason called + LPVOID lpvReserved) // reserved +{ + switch (dwReason) + { + case DLL_PROCESS_ATTACH: + { // Use wxInitialize() if you don't want GUI instead of the following 12 lines + wxSetInstance((HINSTANCE)hinstDLL); + int argc = 0; + char **argv = NULL; + wxEntryStart(argc, argv); + if ( !wxTheApp || !wxTheApp->CallOnInit() ) + return FALSE; + } + break; + + case DLL_PROCESS_DETACH: + wxEntryCleanup(); // Use wxUninitialize() if you don't want GUI + break; + default: + break; + } + + g_hInstance = hinstDLL; + return TRUE; +} +#endif +////////////////////////////////////////////////////////////////////////// + /* Create debugging window. There's currently a strange crash that occurs whe a game is loaded if the OpenGL plugin was loaded before. I'll try to fix that. Currently you may have to clsoe the window if it has auto started, and then restart it after the dll has loaded @@ -102,11 +149,15 @@ void SetDllGlobals(PLUGIN_GLOBALS* _pPluginGlobals) { void DllConfig(HWND _hParent) { - ConfigDialog frame(NULL); - g_Config.Load(); - OpenGL_AddBackends(&frame); - OpenGL_AddResolutions(&frame); - frame.ShowModal(); + wxWindow * win = new wxWindow(); + win->SetHWND((WXHWND)_hParent); + win->AdoptAttributesFromHWND(); + //win->Reparent(wxGetApp().GetTopWindow()); + ConfigDialog *frame = new ConfigDialog(win); + g_Config.Load(); + OpenGL_AddBackends(frame); + OpenGL_AddResolutions(frame); + frame->ShowModal(); } void Initialize(void *init) @@ -242,14 +293,6 @@ unsigned int Video_Screenshot(TCHAR* _szFilename) return FALSE; } -void Video_UpdateXFB(u8* _pXFB, u32 _dwWidth, u32 _dwHeight, s32 _dwYOffset) -{ - if(g_Config.bUseXFB) - { - XFB_Draw(_pXFB, _dwWidth, _dwHeight, _dwYOffset); - } -} - void Video_AddMessage(const char* pstr, u32 milliseconds) { Renderer::AddMessage(pstr,milliseconds);