From 3cb5dffbc932cf0d9cde8ba9cf922eff17676cba Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Mon, 17 Dec 2012 15:01:52 -0600 Subject: [PATCH] Missed the video interface files. --- Source/Core/DolphinWX/Src/GLVideoInterface.h | 75 ++++ .../Core/DolphinWX/Src/VideoInterface/AGL.cpp | 123 ++++++ .../Core/DolphinWX/Src/VideoInterface/AGL.h | 37 ++ .../Core/DolphinWX/Src/VideoInterface/EGL.cpp | 383 ++++++++++++++++++ .../Core/DolphinWX/Src/VideoInterface/EGL.h | 43 ++ .../Core/DolphinWX/Src/VideoInterface/GLX.cpp | 342 ++++++++++++++++ .../Core/DolphinWX/Src/VideoInterface/GLX.h | 41 ++ .../Src/VideoInterface/InterfaceBase.h | 36 ++ .../Core/DolphinWX/Src/VideoInterface/WGL.cpp | 179 ++++++++ .../Core/DolphinWX/Src/VideoInterface/WGL.h | 41 ++ .../Core/DolphinWX/Src/VideoInterface/WX.cpp | 82 ++++ Source/Core/DolphinWX/Src/VideoInterface/WX.h | 41 ++ 12 files changed, 1423 insertions(+) create mode 100644 Source/Core/DolphinWX/Src/GLVideoInterface.h create mode 100644 Source/Core/DolphinWX/Src/VideoInterface/AGL.cpp create mode 100644 Source/Core/DolphinWX/Src/VideoInterface/AGL.h create mode 100644 Source/Core/DolphinWX/Src/VideoInterface/EGL.cpp create mode 100644 Source/Core/DolphinWX/Src/VideoInterface/EGL.h create mode 100644 Source/Core/DolphinWX/Src/VideoInterface/GLX.cpp create mode 100644 Source/Core/DolphinWX/Src/VideoInterface/GLX.h create mode 100644 Source/Core/DolphinWX/Src/VideoInterface/InterfaceBase.h create mode 100644 Source/Core/DolphinWX/Src/VideoInterface/WGL.cpp create mode 100644 Source/Core/DolphinWX/Src/VideoInterface/WGL.h create mode 100644 Source/Core/DolphinWX/Src/VideoInterface/WX.cpp create mode 100644 Source/Core/DolphinWX/Src/VideoInterface/WX.h diff --git a/Source/Core/DolphinWX/Src/GLVideoInterface.h b/Source/Core/DolphinWX/Src/GLVideoInterface.h new file mode 100644 index 0000000000..3469b1d3c1 --- /dev/null +++ b/Source/Core/DolphinWX/Src/GLVideoInterface.h @@ -0,0 +1,75 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ +#ifndef _VIDEOINTERFACE_H_ +#define _VIDEOINTERFACE_H_ + +#include "Thread.h" + +#if defined(USE_EGL) && USE_EGL +#include "VideoInterface/EGL.h" +#elif defined(USE_WX) && USE_WX +#include "VideoInterface/WX.h" +#elif defined(__APPLE__) +#include "VideoInterface/AGL.h" +#elif defined(_WIN32) +#include "VideoInterface/GLW.h" +#elif defined(HAVE_X11) && HAVE_X11 +#include "VideoInterface/GLX.h" +#endif + +typedef struct { +#if defined(USE_EGL) && USE_EGL // This is currently a X11/EGL implementation for desktop + int screen; + Display *x_dpy; + Display *x_evdpy; + Window win; + Window parent; + EGLSurface egl_surf; + EGLContext egl_ctx; + EGLDisplay egl_dpy; + XVisualInfo *vi; + XSetWindowAttributes attr; + std::thread xEventThread; + int x, y; + unsigned int width, height; +#elif defined(USE_WX) && USE_WX + wxGLCanvas *glCanvas; + wxGLContext *glCtxt; + wxPanel *panel; +#elif defined(__APPLE__) + NSWindow *cocoaWin; + NSOpenGLContext *cocoaCtx; +#elif defined(HAVE_X11) && HAVE_X11 + int screen; + Window win; + Window parent; + // dpy used for glx stuff, evdpy for window events etc. + // evdpy is to be used by XEventThread only + Display *dpy, *evdpy; + XVisualInfo *vi; + GLXContext ctx; + XSetWindowAttributes attr; + std::thread xEventThread; + int x, y; + unsigned int width, height; +#endif +} GLWindow; + +extern cInterfaceBase *GLInterface; +extern GLWindow GLWin; + +#endif diff --git a/Source/Core/DolphinWX/Src/VideoInterface/AGL.cpp b/Source/Core/DolphinWX/Src/VideoInterface/AGL.cpp new file mode 100644 index 0000000000..465f77c972 --- /dev/null +++ b/Source/Core/DolphinWX/Src/VideoInterface/AGL.cpp @@ -0,0 +1,123 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "VideoConfig.h" +#include "Host.h" +#include "RenderBase.h" + +#include "VertexShaderManager.h" +#include "../GLVideoInterface.h" +#include "AGL.h" + +void cInterfaceAGL::SwapBuffers() +{ + [GLWin.cocoaCtx flushBuffer]; +} + +// Show the current FPS +void cInterfaceAGL::UpdateFPSDisplay(const char *text) +{ + [GLWin.cocoaWin setTitle: [NSString stringWithUTF8String: text]]; +} + +// Create rendering window. +// Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize() +bool cInterfaceAGL::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; + + NSRect size; + NSUInteger style = NSMiniaturizableWindowMask; + NSOpenGLPixelFormatAttribute attr[2] = { NSOpenGLPFADoubleBuffer, 0 }; + NSOpenGLPixelFormat *fmt = [[NSOpenGLPixelFormat alloc] + initWithAttributes: attr]; + if (fmt == nil) { + ERROR_LOG(VIDEO, "failed to create pixel format"); + return NULL; + } + + GLWin.cocoaCtx = [[NSOpenGLContext alloc] + initWithFormat: fmt shareContext: nil]; + [fmt release]; + if (GLWin.cocoaCtx == nil) { + ERROR_LOG(VIDEO, "failed to create context"); + return NULL; + } + + if (SConfig::GetInstance().m_LocalCoreStartupParameter.bFullscreen) { + size = [[NSScreen mainScreen] frame]; + style |= NSBorderlessWindowMask; + } else { + size = NSMakeRect(_tx, _ty, _twidth, _theight); + style |= NSResizableWindowMask | NSTitledWindowMask; + } + + GLWin.cocoaWin = [[NSWindow alloc] initWithContentRect: size + styleMask: style backing: NSBackingStoreBuffered defer: NO]; + if (GLWin.cocoaWin == nil) { + ERROR_LOG(VIDEO, "failed to create window"); + return NULL; + } + + if (SConfig::GetInstance().m_LocalCoreStartupParameter.bFullscreen) { + CGDisplayCapture(CGMainDisplayID()); + [GLWin.cocoaWin setLevel: CGShieldingWindowLevel()]; + } + + [GLWin.cocoaCtx setView: [GLWin.cocoaWin contentView]]; + [GLWin.cocoaWin makeKeyAndOrderFront: nil]; + + return true; +} + +bool cInterfaceAGL::MakeCurrent() +{ + [GLWin.cocoaCtx makeCurrentContext]; + return true; +} + +// Update window width, size and etc. Called from Render.cpp +void cInterfaceAGL::Update() +{ + int width, height; + + width = [[GLWin.cocoaWin contentView] frame].size.width; + height = [[GLWin.cocoaWin contentView] frame].size.height; + if (width == s_backbuffer_width && height == s_backbuffer_height) + return; + + [GLWin.cocoaCtx setView: [GLWin.cocoaWin contentView]]; + [GLWin.cocoaCtx update]; + [GLWin.cocoaCtx makeCurrentContext]; + s_backbuffer_width = width; + s_backbuffer_height = height; +} + +// Close backend +void cInterfaceAGL::Shutdown() +{ + [GLWin.cocoaWin close]; + [GLWin.cocoaCtx clearDrawable]; + [GLWin.cocoaCtx release]; +} + + diff --git a/Source/Core/DolphinWX/Src/VideoInterface/AGL.h b/Source/Core/DolphinWX/Src/VideoInterface/AGL.h new file mode 100644 index 0000000000..1e73f3c6b8 --- /dev/null +++ b/Source/Core/DolphinWX/Src/VideoInterface/AGL.h @@ -0,0 +1,37 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ +#ifndef _INTERFACEAGL_H_ +#define _INTERFACEAGL_H_ + +#ifdef __APPLE__ +#include +#import +#endif + +#include "InterfaceBase.h" + +class cInterfaceAGL : public cInterfaceBase +{ +public: + void SwapBuffers(); + void UpdateFPSDisplay(const char *Text); + bool CreateWindow(void *&window_handle); + bool MakeCurrent(); + void Shutdown(); +}; +#endif + diff --git a/Source/Core/DolphinWX/Src/VideoInterface/EGL.cpp b/Source/Core/DolphinWX/Src/VideoInterface/EGL.cpp new file mode 100644 index 0000000000..bcf7acaff5 --- /dev/null +++ b/Source/Core/DolphinWX/Src/VideoInterface/EGL.cpp @@ -0,0 +1,383 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "VideoConfig.h" +#include "Host.h" +#include "RenderBase.h" + +#include "VertexShaderManager.h" +#include "../GLVideoInterface.h" +#include "EGL.h" + +void cInterfaceEGL::CreateXWindow(void) +{ + Atom wmProtocols[1]; + + // Setup window attributes + GLWin.attr.colormap = XCreateColormap(GLWin.x_evdpy, + GLWin.parent, GLWin.vi->visual, AllocNone); + GLWin.attr.event_mask = KeyPressMask | StructureNotifyMask | FocusChangeMask; + GLWin.attr.background_pixel = BlackPixel(GLWin.x_evdpy, GLWin.screen); + GLWin.attr.border_pixel = 0; + + // Create the window + GLWin.win = XCreateWindow(GLWin.x_evdpy, GLWin.parent, + GLWin.x, GLWin.y, GLWin.width, GLWin.height, 0, + GLWin.vi->depth, InputOutput, GLWin.vi->visual, + CWBorderPixel | CWBackPixel | CWColormap | CWEventMask, &GLWin.attr); + wmProtocols[0] = XInternAtom(GLWin.x_evdpy, "WM_DELETE_WINDOW", True); + XSetWMProtocols(GLWin.x_evdpy, GLWin.win, wmProtocols, 1); + XSetStandardProperties(GLWin.x_evdpy, GLWin.win, "GPU", "GPU", None, NULL, 0, NULL); + XMapRaised(GLWin.x_evdpy, GLWin.win); + XSync(GLWin.x_evdpy, True); + + GLWin.xEventThread = std::thread(&cInterfaceEGL::XEventThread, this); +} + +void cInterfaceEGL::DestroyXWindow(void) +{ + XUnmapWindow(GLWin.x_dpy, GLWin.win); + GLWin.win = 0; + if (GLWin.xEventThread.joinable()) + GLWin.xEventThread.join(); + XFreeColormap(GLWin.x_dpy, GLWin.attr.colormap); +} + +void cInterfaceEGL::XEventThread() +{ + // Free look variables + static bool mouseLookEnabled = false; + static bool mouseMoveEnabled = false; + static float lastMouse[2]; + while (GLWin.win) + { + XEvent event; + KeySym key; + for (int num_events = XPending(GLWin.x_evdpy); num_events > 0; num_events--) + { + XNextEvent(GLWin.x_evdpy, &event); + switch(event.type) { + case KeyPress: + key = XLookupKeysym((XKeyEvent*)&event, 0); + switch (key) + { + case XK_3: + OSDChoice = 1; + // Toggle native resolution + g_Config.iEFBScale = g_Config.iEFBScale + 1; + if (g_Config.iEFBScale > 7) g_Config.iEFBScale = 0; + break; + case XK_4: + OSDChoice = 2; + // Toggle aspect ratio + g_Config.iAspectRatio = (g_Config.iAspectRatio + 1) & 3; + break; + case XK_5: + OSDChoice = 3; + // Toggle EFB copy + if (!g_Config.bEFBCopyEnable || g_Config.bCopyEFBToTexture) + { + g_Config.bEFBCopyEnable ^= true; + g_Config.bCopyEFBToTexture = false; + } + else + { + g_Config.bCopyEFBToTexture = !g_Config.bCopyEFBToTexture; + } + break; + case XK_6: + OSDChoice = 4; + g_Config.bDisableFog = !g_Config.bDisableFog; + break; + default: + break; + } + if (g_Config.bFreeLook) + { + static float debugSpeed = 1.0f; + switch (key) + { + case XK_parenleft: + debugSpeed /= 2.0f; + break; + case XK_parenright: + debugSpeed *= 2.0f; + break; + case XK_w: + VertexShaderManager::TranslateView(0.0f, debugSpeed); + break; + case XK_s: + VertexShaderManager::TranslateView(0.0f, -debugSpeed); + break; + case XK_a: + VertexShaderManager::TranslateView(debugSpeed, 0.0f); + break; + case XK_d: + VertexShaderManager::TranslateView(-debugSpeed, 0.0f); + break; + case XK_r: + VertexShaderManager::ResetView(); + break; + } + } + break; + case ButtonPress: + if (g_Config.bFreeLook) + { + switch (event.xbutton.button) + { + case 2: // Middle button + lastMouse[0] = event.xbutton.x; + lastMouse[1] = event.xbutton.y; + mouseMoveEnabled = true; + break; + case 3: // Right button + lastMouse[0] = event.xbutton.x; + lastMouse[1] = event.xbutton.y; + mouseLookEnabled = true; + break; + } + } + break; + case ButtonRelease: + if (g_Config.bFreeLook) + { + switch (event.xbutton.button) + { + case 2: // Middle button + mouseMoveEnabled = false; + break; + case 3: // Right button + mouseLookEnabled = false; + break; + } + } + break; + case MotionNotify: + if (g_Config.bFreeLook) + { + if (mouseLookEnabled) + { + VertexShaderManager::RotateView((event.xmotion.x - lastMouse[0]) / 200.0f, + (event.xmotion.y - lastMouse[1]) / 200.0f); + lastMouse[0] = event.xmotion.x; + lastMouse[1] = event.xmotion.y; + } + + if (mouseMoveEnabled) + { + VertexShaderManager::TranslateView((event.xmotion.x - lastMouse[0]) / 50.0f, + (event.xmotion.y - lastMouse[1]) / 50.0f); + lastMouse[0] = event.xmotion.x; + lastMouse[1] = event.xmotion.y; + } + } + break; + case ConfigureNotify: + Window winDummy; + unsigned int borderDummy, depthDummy; + XGetGeometry(GLWin.x_dpy, GLWin.win, &winDummy, &GLWin.x, &GLWin.y, + &GLWin.width, &GLWin.height, &borderDummy, &depthDummy); + s_backbuffer_width = GLWin.width; + s_backbuffer_height = GLWin.height; + break; + case ClientMessage: + if ((unsigned long) event.xclient.data.l[0] == + XInternAtom(GLWin.x_dpy, "WM_DELETE_WINDOW", False)) + Host_Message(WM_USER_STOP); + if ((unsigned long) event.xclient.data.l[0] == + XInternAtom(GLWin.x_dpy, "RESIZE", False)) + XMoveResizeWindow(GLWin.x_dpy, GLWin.win, + event.xclient.data.l[1], event.xclient.data.l[2], + event.xclient.data.l[3], event.xclient.data.l[4]); + break; + default: + break; + } + } + Common::SleepCurrentThread(20); + } +} + +// Show the current FPS +void cInterfaceEGL::UpdateFPSDisplay(const char *text) +{ + XStoreName(GLWin.x_dpy, GLWin.win, text); +} +void cInterfaceEGL::SwapBuffers() +{ + eglSwapBuffers(GLWin.egl_dpy, GLWin.egl_surf); +} + +// Create rendering window. +// Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize() +bool cInterfaceEGL::CreateWindow(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; + + const char *s; + EGLint egl_major, egl_minor; + + GLWin.x_dpy = XOpenDisplay(NULL); + + if (!GLWin.x_dpy) { + printf("Error: couldn't open display\n"); + return false; + } + + GLWin.egl_dpy = eglGetDisplay(GLWin.x_dpy); + if (!GLWin.egl_dpy) { + printf("Error: eglGetDisplay() failed\n"); + return false; + } + + if (!eglInitialize(GLWin.egl_dpy, &egl_major, &egl_minor)) { + printf("Error: eglInitialize() failed\n"); + return false; + } + + s = eglQueryString(GLWin.egl_dpy, EGL_VERSION); + printf("EGL_VERSION = %s\n", s); + + s = eglQueryString(GLWin.egl_dpy, EGL_VENDOR); + printf("EGL_VENDOR = %s\n", s); + + s = eglQueryString(GLWin.egl_dpy, EGL_EXTENSIONS); + printf("EGL_EXTENSIONS = %s\n", s); + + s = eglQueryString(GLWin.egl_dpy, EGL_CLIENT_APIS); + printf("EGL_CLIENT_APIS = %s\n", s); + + // attributes for a visual in RGBA format with at least + // 8 bits per color and a 24 bit depth buffer + int attribs[] = { + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_DEPTH_SIZE, 24, +#ifdef USE_GLES + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, +#else + EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, +#endif + EGL_NONE }; + + static const EGLint ctx_attribs[] = { +#ifdef USE_GLES + EGL_CONTEXT_CLIENT_VERSION, 2, +#endif + EGL_NONE + }; + + GLWin.x_evdpy = XOpenDisplay(NULL); + GLWin.parent = (Window)window_handle; + GLWin.screen = DefaultScreen(GLWin.x_dpy); + if (GLWin.parent == 0) + GLWin.parent = RootWindow(GLWin.x_dpy, GLWin.screen); + + unsigned long mask; + XVisualInfo visTemplate; + int num_visuals; + EGLConfig config; + EGLint num_configs; + EGLint vid; + + if (!eglChooseConfig( GLWin.egl_dpy, attribs, &config, 1, &num_configs)) { + printf("Error: couldn't get an EGL visual config\n"); + exit(1); + } + + if (!eglGetConfigAttrib(GLWin.egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) { + printf("Error: eglGetConfigAttrib() failed\n"); + exit(1); + } + + /* The X window visual must match the EGL config */ + visTemplate.visualid = vid; + GLWin.vi = XGetVisualInfo(GLWin.x_dpy, VisualIDMask, &visTemplate, &num_visuals); + if (!GLWin.vi) { + printf("Error: couldn't get X visual\n"); + exit(1); + } + + GLWin.x = _tx; + GLWin.y = _ty; + GLWin.width = _twidth; + GLWin.height = _theight; + + CreateXWindow(); +#ifdef USE_GLES + eglBindAPI(EGL_OPENGL_ES_API); +#else + eglBindAPI(EGL_OPENGL_API); +#endif + GLWin.egl_ctx = eglCreateContext(GLWin.egl_dpy, config, EGL_NO_CONTEXT, ctx_attribs ); + if (!GLWin.egl_ctx) { + printf("Error: eglCreateContext failed\n"); + exit(1); + } + + GLWin.egl_surf = eglCreateWindowSurface(GLWin.egl_dpy, config, GLWin.win, NULL); + if (!GLWin.egl_surf) { + printf("Error: eglCreateWindowSurface failed\n"); + exit(1); + } + + if (!eglMakeCurrent(GLWin.egl_dpy, GLWin.egl_surf, GLWin.egl_surf, GLWin.egl_ctx)) { + + printf("Error: eglMakeCurrent() failed\n"); + return false; + } + + + printf("GL_VENDOR: %s\n", glGetString(GL_VENDOR)); + printf("GL_RENDERER: %s\n", glGetString(GL_RENDERER)); + printf("GL_VERSION: %s\n", glGetString(GL_VERSION)); + printf("GL_EXTENSIONS: %s\n", glGetString(GL_EXTENSIONS)); + /* Set initial projection/viewing transformation. + * We can't be sure we'll get a ConfigureNotify event when the window + * first appears. + */ + glViewport(0, 0, (GLint) _twidth, (GLint) _theight); + window_handle = (void *)GLWin.win; + return true; +} + +bool cInterfaceEGL::MakeCurrent() +{ + return eglMakeCurrent(GLWin.egl_dpy, GLWin.egl_surf, GLWin.egl_surf, GLWin.egl_ctx); +} +// Close backend +void cInterfaceEGL::Shutdown() +{ + DestroyXWindow(); + if (GLWin.egl_ctx && !eglMakeCurrent(GLWin.egl_dpy, GLWin.egl_surf, GLWin.egl_surf, GLWin.egl_ctx)) + NOTICE_LOG(VIDEO, "Could not release drawing context."); + if (GLWin.egl_ctx) + { + eglDestroyContext(GLWin.egl_dpy, GLWin.egl_ctx); + eglDestroySurface(GLWin.egl_dpy, GLWin.egl_surf); + eglTerminate(GLWin.egl_dpy); + GLWin.egl_ctx = NULL; + } +} + diff --git a/Source/Core/DolphinWX/Src/VideoInterface/EGL.h b/Source/Core/DolphinWX/Src/VideoInterface/EGL.h new file mode 100644 index 0000000000..afb57b2ac2 --- /dev/null +++ b/Source/Core/DolphinWX/Src/VideoInterface/EGL.h @@ -0,0 +1,43 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ +#ifndef _INTERFACEGLX_H_ +#define _INTERFACEGLX_H_ + +#include +#ifdef USE_GLES +#include +#else +#include +#include +#endif +#include "InterfaceBase.h" + +class cInterfaceEGL : public cInterfaceBase +{ +private: + void CreateXWindow(); + void DestroyXWindow(); + void XEventThread(); +public: + void SwapBuffers(); + void UpdateFPSDisplay(const char *Text); + bool CreateWindow(void *&window_handle); + bool MakeCurrent(); + void Shutdown(); +}; +#endif + diff --git a/Source/Core/DolphinWX/Src/VideoInterface/GLX.cpp b/Source/Core/DolphinWX/Src/VideoInterface/GLX.cpp new file mode 100644 index 0000000000..63458f7a4d --- /dev/null +++ b/Source/Core/DolphinWX/Src/VideoInterface/GLX.cpp @@ -0,0 +1,342 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "VideoConfig.h" +#include "Host.h" +#include "RenderBase.h" + +#include "VertexShaderManager.h" +#include "../GLVideoInterface.h" +#include "GLX.h" + +void cInterfaceGLX::CreateXWindow(void) +{ + Atom wmProtocols[1]; + + // Setup window attributes + GLWin.attr.colormap = XCreateColormap(GLWin.evdpy, + GLWin.parent, GLWin.vi->visual, AllocNone); + GLWin.attr.event_mask = KeyPressMask | StructureNotifyMask | FocusChangeMask; + GLWin.attr.background_pixel = BlackPixel(GLWin.evdpy, GLWin.screen); + GLWin.attr.border_pixel = 0; + + // Create the window + GLWin.win = XCreateWindow(GLWin.evdpy, GLWin.parent, + GLWin.x, GLWin.y, GLWin.width, GLWin.height, 0, + GLWin.vi->depth, InputOutput, GLWin.vi->visual, + CWBorderPixel | CWBackPixel | CWColormap | CWEventMask, &GLWin.attr); + wmProtocols[0] = XInternAtom(GLWin.evdpy, "WM_DELETE_WINDOW", True); + XSetWMProtocols(GLWin.evdpy, GLWin.win, wmProtocols, 1); + XSetStandardProperties(GLWin.evdpy, GLWin.win, "GPU", "GPU", None, NULL, 0, NULL); + XMapRaised(GLWin.evdpy, GLWin.win); + XSync(GLWin.evdpy, True); + + GLWin.xEventThread = std::thread(&cInterfaceGLX::XEventThread, this); +} + +void cInterfaceGLX::DestroyXWindow(void) +{ + XUnmapWindow(GLWin.dpy, GLWin.win); + GLWin.win = 0; + if (GLWin.xEventThread.joinable()) + GLWin.xEventThread.join(); + XFreeColormap(GLWin.evdpy, GLWin.attr.colormap); +} + +void cInterfaceGLX::XEventThread() +{ + // Free look variables + static bool mouseLookEnabled = false; + static bool mouseMoveEnabled = false; + static float lastMouse[2]; + while (GLWin.win) + { + XEvent event; + KeySym key; + for (int num_events = XPending(GLWin.evdpy); num_events > 0; num_events--) + { + XNextEvent(GLWin.evdpy, &event); + switch(event.type) { + case KeyPress: + key = XLookupKeysym((XKeyEvent*)&event, 0); + switch (key) + { + case XK_3: + OSDChoice = 1; + // Toggle native resolution + g_Config.iEFBScale = g_Config.iEFBScale + 1; + if (g_Config.iEFBScale > 7) g_Config.iEFBScale = 0; + break; + case XK_4: + OSDChoice = 2; + // Toggle aspect ratio + g_Config.iAspectRatio = (g_Config.iAspectRatio + 1) & 3; + break; + case XK_5: + OSDChoice = 3; + // Toggle EFB copy + if (!g_Config.bEFBCopyEnable || g_Config.bCopyEFBToTexture) + { + g_Config.bEFBCopyEnable ^= true; + g_Config.bCopyEFBToTexture = false; + } + else + { + g_Config.bCopyEFBToTexture = !g_Config.bCopyEFBToTexture; + } + break; + case XK_6: + OSDChoice = 4; + g_Config.bDisableFog = !g_Config.bDisableFog; + break; + default: + break; + } + if (g_Config.bFreeLook) + { + static float debugSpeed = 1.0f; + switch (key) + { + case XK_parenleft: + debugSpeed /= 2.0f; + break; + case XK_parenright: + debugSpeed *= 2.0f; + break; + case XK_w: + VertexShaderManager::TranslateView(0.0f, debugSpeed); + break; + case XK_s: + VertexShaderManager::TranslateView(0.0f, -debugSpeed); + break; + case XK_a: + VertexShaderManager::TranslateView(debugSpeed, 0.0f); + break; + case XK_d: + VertexShaderManager::TranslateView(-debugSpeed, 0.0f); + break; + case XK_r: + VertexShaderManager::ResetView(); + break; + } + } + break; + case ButtonPress: + if (g_Config.bFreeLook) + { + switch (event.xbutton.button) + { + case 2: // Middle button + lastMouse[0] = event.xbutton.x; + lastMouse[1] = event.xbutton.y; + mouseMoveEnabled = true; + break; + case 3: // Right button + lastMouse[0] = event.xbutton.x; + lastMouse[1] = event.xbutton.y; + mouseLookEnabled = true; + break; + } + } + break; + case ButtonRelease: + if (g_Config.bFreeLook) + { + switch (event.xbutton.button) + { + case 2: // Middle button + mouseMoveEnabled = false; + break; + case 3: // Right button + mouseLookEnabled = false; + break; + } + } + break; + case MotionNotify: + if (g_Config.bFreeLook) + { + if (mouseLookEnabled) + { + VertexShaderManager::RotateView((event.xmotion.x - lastMouse[0]) / 200.0f, + (event.xmotion.y - lastMouse[1]) / 200.0f); + lastMouse[0] = event.xmotion.x; + lastMouse[1] = event.xmotion.y; + } + + if (mouseMoveEnabled) + { + VertexShaderManager::TranslateView((event.xmotion.x - lastMouse[0]) / 50.0f, + (event.xmotion.y - lastMouse[1]) / 50.0f); + lastMouse[0] = event.xmotion.x; + lastMouse[1] = event.xmotion.y; + } + } + break; + case ConfigureNotify: + Window winDummy; + unsigned int borderDummy, depthDummy; + XGetGeometry(GLWin.evdpy, GLWin.win, &winDummy, &GLWin.x, &GLWin.y, + &GLWin.width, &GLWin.height, &borderDummy, &depthDummy); + s_backbuffer_width = GLWin.width; + s_backbuffer_height = GLWin.height; + break; + case ClientMessage: + if ((unsigned long) event.xclient.data.l[0] == + XInternAtom(GLWin.evdpy, "WM_DELETE_WINDOW", False)) + Host_Message(WM_USER_STOP); + if ((unsigned long) event.xclient.data.l[0] == + XInternAtom(GLWin.evdpy, "RESIZE", False)) + XMoveResizeWindow(GLWin.evdpy, GLWin.win, + event.xclient.data.l[1], event.xclient.data.l[2], + event.xclient.data.l[3], event.xclient.data.l[4]); + break; + default: + break; + } + } + Common::SleepCurrentThread(20); + } +} + +// Show the current FPS +void cInterfaceGLX::UpdateFPSDisplay(const char *text) +{ + XStoreName(GLWin.dpy, GLWin.win, text); +} +void cInterfaceGLX::SwapBuffers() +{ + glXSwapBuffers(GLWin.dpy, GLWin.win); +} + +// Create rendering window. +// Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize() +bool cInterfaceGLX::CreateWindow(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; + + int glxMajorVersion, glxMinorVersion; + + // attributes for a single buffered visual in RGBA format with at least + // 8 bits per color and a 24 bit depth buffer + int attrListSgl[] = {GLX_RGBA, GLX_RED_SIZE, 8, + GLX_GREEN_SIZE, 8, + GLX_BLUE_SIZE, 8, + GLX_DEPTH_SIZE, 24, + None}; + + // attributes for a double buffered visual in RGBA format with at least + // 8 bits per color and a 24 bit depth buffer + int attrListDbl[] = {GLX_RGBA, GLX_DOUBLEBUFFER, + GLX_RED_SIZE, 8, + GLX_GREEN_SIZE, 8, + GLX_BLUE_SIZE, 8, + GLX_DEPTH_SIZE, 24, + GLX_SAMPLE_BUFFERS_ARB, g_Config.iMultisampleMode != MULTISAMPLE_OFF?1:0, + GLX_SAMPLES_ARB, g_Config.iMultisampleMode != MULTISAMPLE_OFF?1:0, + None }; + + int attrListDefault[] = { + GLX_RGBA, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + GLX_DOUBLEBUFFER, + GLX_DEPTH_SIZE, 1, + None }; + + GLWin.dpy = XOpenDisplay(0); + GLWin.evdpy = XOpenDisplay(0); + GLWin.parent = (Window)window_handle; + GLWin.screen = DefaultScreen(GLWin.dpy); + if (GLWin.parent == 0) + GLWin.parent = RootWindow(GLWin.dpy, GLWin.screen); + + glXQueryVersion(GLWin.dpy, &glxMajorVersion, &glxMinorVersion); + NOTICE_LOG(VIDEO, "glX-Version %d.%d", glxMajorVersion, glxMinorVersion); + + // Get an appropriate visual + GLWin.vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListDbl); + if (GLWin.vi == NULL) + { + GLWin.vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListSgl); + if (GLWin.vi != NULL) + { + ERROR_LOG(VIDEO, "Only single buffered visual!"); + } + else + { + GLWin.vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListDefault); + if (GLWin.vi == NULL) + { + ERROR_LOG(VIDEO, "Could not choose visual (glXChooseVisual)"); + return false; + } + } + } + else + NOTICE_LOG(VIDEO, "Got double buffered visual!"); + + // Create a GLX context. + GLWin.ctx = glXCreateContext(GLWin.dpy, GLWin.vi, 0, GL_TRUE); + if (!GLWin.ctx) + { + PanicAlert("Unable to create GLX context."); + return false; + } + + GLWin.x = _tx; + GLWin.y = _ty; + GLWin.width = _twidth; + GLWin.height = _theight; + + CreateXWindow(); + window_handle = (void *)GLWin.win; + return true; +} + +bool cInterfaceGLX::MakeCurrent() +{ + // connect the glx-context to the window + #if defined(HAVE_WX) && (HAVE_WX) + Host_GetRenderWindowSize(GLWin.x, GLWin.y, + (int&)GLWin.width, (int&)GLWin.height); + XMoveResizeWindow(GLWin.dpy, GLWin.win, GLWin.x, GLWin.y, + GLWin.width, GLWin.height); + #endif + return glXMakeCurrent(GLWin.dpy, GLWin.win, GLWin.ctx); +} +// Close backend +void cInterfaceGLX::Shutdown() +{ + DestroyXWindow(); + if (GLWin.ctx && !glXMakeCurrent(GLWin.dpy, None, NULL)) + NOTICE_LOG(VIDEO, "Could not release drawing context."); + if (GLWin.ctx) + { + glXDestroyContext(GLWin.dpy, GLWin.ctx); + XCloseDisplay(GLWin.dpy); + XCloseDisplay(GLWin.evdpy); + GLWin.ctx = NULL; + } +} + diff --git a/Source/Core/DolphinWX/Src/VideoInterface/GLX.h b/Source/Core/DolphinWX/Src/VideoInterface/GLX.h new file mode 100644 index 0000000000..bea58cb862 --- /dev/null +++ b/Source/Core/DolphinWX/Src/VideoInterface/GLX.h @@ -0,0 +1,41 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ +#ifndef _INTERFACEGLX_H_ +#define _INTERFACEGLX_H_ + +#include +#include +#include +#include + +#include "InterfaceBase.h" + +class cInterfaceGLX : public cInterfaceBase +{ +private: + void CreateXWindow(); + void DestroyXWindow(); + void XEventThread(); +public: + void SwapBuffers(); + void UpdateFPSDisplay(const char *Text); + bool CreateWindow(void *&window_handle); + bool MakeCurrent(); + void Shutdown(); +}; +#endif + diff --git a/Source/Core/DolphinWX/Src/VideoInterface/InterfaceBase.h b/Source/Core/DolphinWX/Src/VideoInterface/InterfaceBase.h new file mode 100644 index 0000000000..8fa4cc1b12 --- /dev/null +++ b/Source/Core/DolphinWX/Src/VideoInterface/InterfaceBase.h @@ -0,0 +1,36 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +class cInterfaceBase +{ +protected: + // Window dimensions. + u32 s_backbuffer_width; + u32 s_backbuffer_height; +public: + virtual void SwapBuffers() = 0; + virtual void UpdateFPSDisplay(const char *Text) = 0; + virtual bool CreateWindow(void *&window_handle) = 0; + virtual bool MakeCurrent() = 0; + virtual void Shutdown() = 0; + + virtual u32 GetBackBufferWidth() { return s_backbuffer_width; } + virtual u32 GetBackBufferHeight() { return s_backbuffer_height; } + virtual void Update() { } + virtual bool PeekMessages() { return false; } +}; + diff --git a/Source/Core/DolphinWX/Src/VideoInterface/WGL.cpp b/Source/Core/DolphinWX/Src/VideoInterface/WGL.cpp new file mode 100644 index 0000000000..9abcd52fc6 --- /dev/null +++ b/Source/Core/DolphinWX/Src/VideoInterface/WGL.cpp @@ -0,0 +1,179 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "VideoConfig.h" +#include "Host.h" +#include "RenderBase.h" + +#include "VertexShaderManager.h" +#include "../GLVideoInterface.h" +#include "WGL.h" + +#include "EmuWindow.h" +static HDC hDC = NULL; // Private GDI Device Context +static HGLRC hRC = NULL; // Permanent Rendering Context + +void cInterfaceWGL::SwapBuffers() +{ + SwapBuffers(hDC); +} + +// 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::CreateWindow(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; + + window_handle = (void*)EmuWindow::Create((HWND)window_handle, GetModuleHandle(0), _T("Please wait...")); + if (window_handle == NULL) + { + 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 + 24, // 24Bit Z-Buffer (Depth Buffer) + 8, // 8bit Stencil Buffer + 0, // No Auxiliary Buffer + PFD_MAIN_PLANE, // Main Drawing Layer + 0, // Reserved + 0, 0, 0 // Layer Masks Ignored + }; + + GLuint 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; +} + +// 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(NULL, NULL)) + NOTICE_LOG(VIDEO, "Could not release drawing context."); + + if (!wglDeleteContext(hRC)) + ERROR_LOG(VIDEO, "Release Rendering Context Failed."); + + hRC = NULL; + } + + if (hDC && !ReleaseDC(EmuWindow::GetWnd(), hDC)) + { + ERROR_LOG(VIDEO, "Release Device Context Failed."); + hDC = NULL; + } +} + + diff --git a/Source/Core/DolphinWX/Src/VideoInterface/WGL.h b/Source/Core/DolphinWX/Src/VideoInterface/WGL.h new file mode 100644 index 0000000000..4ef6943623 --- /dev/null +++ b/Source/Core/DolphinWX/Src/VideoInterface/WGL.h @@ -0,0 +1,41 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ +#ifndef _INTERFACEWGL_H_ +#define _INTERFACEWGL_H_ + +#ifdef _WIN32 +#define GLEW_STATIC +#include +#include +#endif + +#include "InterfaceBase.h" + +class cInterfaceWGL : public cInterfaceBase +{ +public: + void SwapBuffers(); + void UpdateFPSDisplay(const char *Text); + bool CreateWindow(void *&window_handle); + bool MakeCurrent(); + void Shutdown(); + + void Update(); + bool PeekMessages(); +}; +#endif + diff --git a/Source/Core/DolphinWX/Src/VideoInterface/WX.cpp b/Source/Core/DolphinWX/Src/VideoInterface/WX.cpp new file mode 100644 index 0000000000..7126ccb8ba --- /dev/null +++ b/Source/Core/DolphinWX/Src/VideoInterface/WX.cpp @@ -0,0 +1,82 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "VideoConfig.h" +#include "Host.h" +#include "RenderBase.h" + +#include "VertexShaderManager.h" +#include "../GLVideoInterface.h" +#include "WX.h" + +void cInterfaceWX::SwapBuffers() +{ + GLWin.glCanvas->SwapBuffers(); +} + +void cInterfaceWX::UpdateFPSDisplay(const char *text) +{ + // Handled by Host_UpdateTitle() +} + +// Create rendering window. +// Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize() +bool cInterfaceWX::CreateCreate(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; + + GLWin.panel = (wxPanel *)window_handle; + GLWin.glCanvas = new wxGLCanvas(GLWin.panel, wxID_ANY, NULL, + wxPoint(0, 0), wxSize(_twidth, _theight)); + GLWin.glCanvas->Show(true); + if (GLWin.glCtxt == NULL) // XXX dirty hack + GLWin.glCtxt = new wxGLContext(GLWin.glCanvas); +} + +bool cInterfaceWX::MakeCurrent() +{ + return GLWin.glCanvas->SetCurrent(*GLWin.glCtxt); +} + +// Update window width, size and etc. Called from Render.cpp +void cInterfaceWX::Update() +{ + int width, height; + + GLWin.panel->GetSize(&width, &height); + if (width == s_backbuffer_width && height == s_backbuffer_height) + return; + + GLWin.glCanvas->SetFocus(); + GLWin.glCanvas->SetSize(0, 0, width, height); + GLWin.glCtxt->SetCurrent(*GLWin.glCanvas); + s_backbuffer_width = width; + s_backbuffer_height = height; +} + +// Close backend +void cInterfaceWX::Shutdown() +{ + GLWin.glCanvas->Hide(); +} + + diff --git a/Source/Core/DolphinWX/Src/VideoInterface/WX.h b/Source/Core/DolphinWX/Src/VideoInterface/WX.h new file mode 100644 index 0000000000..290b0262ed --- /dev/null +++ b/Source/Core/DolphinWX/Src/VideoInterface/WX.h @@ -0,0 +1,41 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ +#ifndef _INTERFACEWX_H_ +#define _INTERFACEWX_H_ + +#include +#include +#if defined USE_WX && USE_WX +#include "wx/wx.h" +#include "wx/glcanvas.h" +#endif + +#include "InterfaceBase.h" + +class cInterfaceWX : public cInterfaceBase +{ +public: + void SwapBuffers(); + void UpdateFPSDisplay(const char *Text); + bool CreateWindow(void *&window_handle); + bool MakeCurrent(); + void Shutdown(); + + void Update(); +}; +#endif +