diff --git a/plugins/GSdx/GS.cpp b/plugins/GSdx/GS.cpp index ec0c53f555..d0d92153b6 100644 --- a/plugins/GSdx/GS.cpp +++ b/plugins/GSdx/GS.cpp @@ -78,17 +78,24 @@ EXPORT_C_(INT32) GSinit() return -1; } +#ifdef _WINDOWS + + s_hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED); + + if(!GSUtil::CheckDirectX()) + { + return -1; + } + +#endif + return 0; } EXPORT_C GSshutdown() -{ -} - -EXPORT_C GSclose() { delete s_gs; - + s_gs = NULL; #ifdef _WINDOWS @@ -103,61 +110,103 @@ EXPORT_C GSclose() #endif } +EXPORT_C GSclose() +{ + if( !s_gs ) return; + + s_gs->ResetDevice(); + + if( s_gs->m_dev ) + s_gs->m_dev->Reset(1, 1, GSDevice::Windowed); + + delete s_gs->m_dev; + s_gs->m_dev = NULL; + + s_gs->m_wnd.Detach(); +} + static INT32 GSopen(void* dsp, char* title, int mt, int renderer) { GSclose(); -#ifdef _WINDOWS - - s_hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED); - - if(!GSUtil::CheckDirectX()) - { - return -1; - } - -#endif + GSDevice* dev = NULL; switch(renderer) { default: - case 0: s_gs = new GSRendererDX9(s_basemem, !!mt, s_irq); break; - case 1: s_gs = new GSRendererSW(s_basemem, !!mt, s_irq, new GSDevice9()); break; - case 2: s_gs = new GSRendererNull(s_basemem, !!mt, s_irq, new GSDevice9()); break; - case 3: s_gs = new GSRendererDX10(s_basemem, !!mt, s_irq); break; - case 4: s_gs = new GSRendererSW(s_basemem, !!mt, s_irq, new GSDevice10()); break; - case 5: s_gs = new GSRendererNull(s_basemem, !!mt, s_irq, new GSDevice10()); break; - case 6: s_gs = new GSRendererDX11(s_basemem, !!mt, s_irq); break; - case 7: s_gs = new GSRendererSW(s_basemem, !!mt, s_irq, new GSDevice11()); break; - case 8: s_gs = new GSRendererNull(s_basemem, !!mt, s_irq, new GSDevice11()); break; - #if 0 - case 9: s_gs = new GSRendererOGL(s_basemem, !!mt, s_irq); break; - case 10: s_gs = new GSRendererSW(s_basemem, !!mt, s_irq, new GSDeviceOGL()); break; - case 11: s_gs = new GSRendererNull(s_basemem, !!mt, s_irq, new GSDeviceOGL()); break; - #endif - case 12: s_gs = new GSRendererSW(s_basemem, !!mt, s_irq, new GSDeviceNull()); break; - case 13: s_gs = new GSRendererNull(s_basemem, !!mt, s_irq, new GSDeviceNull()); break; + case 0: case 1: case 2: dev = new GSDevice9(); break; + case 3: case 4: case 5: dev = new GSDevice10(); break; + case 6: case 7: case 8: dev = new GSDevice11(); break; +#if 0 + case 9: case 10: case 11: dev = new GSDeviceOGL(); break; +#endif + case 12: case 13: new GSDeviceNull(); break; } - int w = theApp.GetConfig("ModeWidth", 0); - int h = theApp.GetConfig("ModeHeight", 0); + if( !dev ) return -1; - if(!s_gs->Create(title, w, h)) + if( !s_gs ) + { + switch(renderer) + { + default: + case 0: s_gs = new GSRendererDX9(s_basemem, !!mt, s_irq); break; + case 3: s_gs = new GSRendererDX10(s_basemem, !!mt, s_irq); break; + case 6: s_gs = new GSRendererDX11(s_basemem, !!mt, s_irq); break; +#if 0 + case 9: s_gs = new GSRendererOGL(s_basemem, !!mt, s_irq); break; +#endif + case 2: case 5: case 8: case 11: case 13: + s_gs = new GSRendererNull(s_basemem, !!mt, s_irq); break; + + case 1: case 4: case 7: case 10: case 12: + s_gs = new GSRendererSW(s_basemem, !!mt, s_irq); break; + } + } + + if( *(HWND*)dsp == NULL ) + { + // old-style API expects us to create and manage our own window: + + int w = theApp.GetConfig("ModeWidth", 0); + int h = theApp.GetConfig("ModeHeight", 0); + + if(!s_gs->CreateWnd(title, w, h)) + { + GSclose(); + return -1; + } + + s_gs->m_wnd.Show(); + *(HWND*)dsp = (HWND)s_gs->m_wnd.GetHandle(); + } + else + { + s_gs->m_wnd.Attach( *(HWND*)dsp, false ); + } + + if( !s_gs->CreateDevice(dev) ) { GSclose(); - return -1; } - s_gs->m_wnd.Show(); - - *(HWND*)dsp = (HWND)s_gs->m_wnd.GetHandle(); - // if(mt) _mm_setcsr(MXCSR); return 0; } +EXPORT_C_(INT32) GSopen2(void* dsp, INT32 forceSoftware ) +{ + int renderer = theApp.GetConfig("renderer", 0); + if( forceSoftware ) + { + renderer = 1; + } + + return GSopen( dsp, NULL, true, renderer ); +} + EXPORT_C_(INT32) GSopen(void* dsp, char* title, int mt) { int renderer; @@ -174,6 +223,7 @@ EXPORT_C_(INT32) GSopen(void* dsp, char* title, int mt) renderer = theApp.GetConfig("renderer", 0); } + *(HWND*)dsp = NULL; return GSopen(dsp, title, mt, renderer); } diff --git a/plugins/GSdx/GSDevice.cpp b/plugins/GSdx/GSDevice.cpp index 8d1dd4007a..799c07f711 100644 --- a/plugins/GSdx/GSDevice.cpp +++ b/plugins/GSdx/GSDevice.cpp @@ -79,7 +79,7 @@ bool GSDevice::Reset(int w, int h, int mode) m_current = NULL; // current is special, points to other textures, no need to delete - return true; + return m_wnd != NULL; } void GSDevice::Present(const GSVector4i& r, int shader, bool limit) diff --git a/plugins/GSdx/GSRenderer.cpp b/plugins/GSdx/GSRenderer.cpp index 9191041263..b37a1d549d 100644 --- a/plugins/GSdx/GSRenderer.cpp +++ b/plugins/GSdx/GSRenderer.cpp @@ -22,9 +22,9 @@ #include "StdAfx.h" #include "GSRenderer.h" -GSRenderer::GSRenderer(uint8* base, bool mt, void (*irq)(), GSDevice* dev) +GSRenderer::GSRenderer(uint8* base, bool mt, void (*irq)()) : GSState(base, mt, irq) - , m_dev(dev) + , m_dev(NULL) , m_shader(0) , m_vt(this) { @@ -55,21 +55,26 @@ GSRenderer::~GSRenderer() delete m_dev; } -bool GSRenderer::Create(const string& title, int w, int h) +bool GSRenderer::CreateWnd(const string& title, int w, int h) { if(!m_wnd.Create(title.c_str(), w, h)) { return false; } + return true; +} - ASSERT(m_dev); +bool GSRenderer::CreateDevice(GSDevice* dev) +{ + ASSERT(dev); + ASSERT(!m_dev); - if(!m_dev->Create(&m_wnd, m_vsync)) + if(!dev->Create(&m_wnd, m_vsync)) { return false; } - Reset(); + m_dev = dev; return true; } @@ -316,7 +321,11 @@ void GSRenderer::VSync(int field) s += " | Recording..."; } - m_wnd.SetWindowText(s.c_str()); + if( !m_wnd.SetWindowText(s.c_str()) ) + { + // We don't have window title rights, or the window has no title, + // so let's use actual OSD! + } } if(m_frameskip) diff --git a/plugins/GSdx/GSRenderer.h b/plugins/GSdx/GSRenderer.h index 378ab45afb..6383bfdea6 100644 --- a/plugins/GSdx/GSRenderer.h +++ b/plugins/GSdx/GSRenderer.h @@ -46,7 +46,6 @@ protected: bool m_aa1; bool m_blur; - virtual void ResetDevice() {} virtual GSTexture* GetOutput(int i) = 0; GSVertexTrace m_vt; @@ -70,10 +69,12 @@ public: int s_saven; public: - GSRenderer(uint8* base, bool mt, void (*irq)(), GSDevice* dev); + GSRenderer(uint8* base, bool mt, void (*irq)()); virtual ~GSRenderer(); - virtual bool Create(const string& title, int w, int h); + virtual bool CreateWnd(const string& title, int w, int h); + virtual bool CreateDevice(GSDevice* dev); + virtual void ResetDevice() {} virtual void VSync(int field); virtual bool MakeSnapshot(const string& path); virtual void KeyEvent(GSKeyEventData* e, int param = 0); @@ -212,8 +213,8 @@ protected: virtual void Draw() = 0; public: - GSRendererT(uint8* base, bool mt, void (*irq)(), GSDevice* dev) - : GSRenderer(base, mt, irq, dev) + GSRendererT(uint8* base, bool mt, void (*irq)()) + : GSRenderer(base, mt, irq) , m_vertices(NULL) , m_count(0) , m_maxcount(0) diff --git a/plugins/GSdx/GSRendererDX.h b/plugins/GSdx/GSRendererDX.h index 8afeb2f9a1..204b00a07a 100644 --- a/plugins/GSdx/GSRendererDX.h +++ b/plugins/GSdx/GSRendererDX.h @@ -41,8 +41,8 @@ protected: virtual void UpdateFBA(GSTexture* rt) {} public: - GSRendererDX(uint8* base, bool mt, void (*irq)(), GSDevice* dev, GSTextureCache* tc, GSTextureFX* tfx, const GSVector2& pixelcenter = GSVector2(0, 0)) - : GSRendererHW(base, mt, irq, dev, tc) + GSRendererDX(uint8* base, bool mt, void (*irq)(), GSTextureCache* tc, GSTextureFX* tfx, const GSVector2& pixelcenter = GSVector2(0, 0)) + : GSRendererHW(base, mt, irq, tc) , m_tfx(tfx) , m_pixelcenter(pixelcenter) , m_topology(-1) @@ -58,9 +58,9 @@ public: delete m_tfx; } - bool Create(const string& title, int w, int h) + bool CreateDevice(GSDevice* dev) { - if(!__super::Create(title, w, h)) + if(!__super::CreateDevice(dev)) return false; if(!m_tfx->Create(m_dev)) diff --git a/plugins/GSdx/GSRendererDX10.cpp b/plugins/GSdx/GSRendererDX10.cpp index 3f44ea790f..dc93ade76b 100644 --- a/plugins/GSdx/GSRendererDX10.cpp +++ b/plugins/GSdx/GSRendererDX10.cpp @@ -25,14 +25,14 @@ #include "resource.h" GSRendererDX10::GSRendererDX10(uint8* base, bool mt, void (*irq)()) - : GSRendererDX(base, mt, irq, new GSDevice10(), new GSTextureCache10(this), new GSTextureFX10(), GSVector2(-0.5f, -0.5f)) + : GSRendererDX(base, mt, irq, new GSTextureCache10(this), new GSTextureFX10(), GSVector2(-0.5f, -0.5f)) { InitVertexKick(); } -bool GSRendererDX10::Create(const string& title, int w, int h) +bool GSRendererDX10::CreateDevice(GSDevice* dev) { - if(!__super::Create(title, w, h)) + if(!__super::CreateDevice(dev)) return false; // diff --git a/plugins/GSdx/GSRendererDX10.h b/plugins/GSdx/GSRendererDX10.h index 7e08538891..3dc8557661 100644 --- a/plugins/GSdx/GSRendererDX10.h +++ b/plugins/GSdx/GSRendererDX10.h @@ -41,7 +41,7 @@ protected: public: GSRendererDX10(uint8* base, bool mt, void (*irq)()); - bool Create(const string& title, int w, int h); + bool CreateDevice(GSDevice* dev); template void VertexKick(bool skip); }; \ No newline at end of file diff --git a/plugins/GSdx/GSRendererDX11.cpp b/plugins/GSdx/GSRendererDX11.cpp index 55930cdef2..89761f6fab 100644 --- a/plugins/GSdx/GSRendererDX11.cpp +++ b/plugins/GSdx/GSRendererDX11.cpp @@ -25,14 +25,14 @@ #include "resource.h" GSRendererDX11::GSRendererDX11(uint8* base, bool mt, void (*irq)()) - : GSRendererDX(base, mt, irq, new GSDevice11(), new GSTextureCache11(this), new GSTextureFX11(), GSVector2(-0.5f, -0.5f)) + : GSRendererDX(base, mt, irq, new GSTextureCache11(this), new GSTextureFX11(), GSVector2(-0.5f, -0.5f)) { InitVertexKick(); } -bool GSRendererDX11::Create(const string& title, int w, int h) +bool GSRendererDX11::CreateDevice(GSDevice* dev) { - if(!__super::Create(title, w, h)) + if(!__super::CreateDevice(dev)) return false; // diff --git a/plugins/GSdx/GSRendererDX11.h b/plugins/GSdx/GSRendererDX11.h index 1e26df8863..c24ac00c81 100644 --- a/plugins/GSdx/GSRendererDX11.h +++ b/plugins/GSdx/GSRendererDX11.h @@ -42,7 +42,7 @@ protected: public: GSRendererDX11(uint8* base, bool mt, void (*irq)()); - bool Create(const string& title, int w, int h); + bool CreateDevice(GSDevice* dev); template void VertexKick(bool skip); }; \ No newline at end of file diff --git a/plugins/GSdx/GSRendererDX9.cpp b/plugins/GSdx/GSRendererDX9.cpp index 6e3774bdc5..e89472f935 100644 --- a/plugins/GSdx/GSRendererDX9.cpp +++ b/plugins/GSdx/GSRendererDX9.cpp @@ -25,14 +25,14 @@ #include "resource.h" GSRendererDX9::GSRendererDX9(uint8* base, bool mt, void (*irq)()) - : GSRendererDX(base, mt, irq, new GSDevice9(), new GSTextureCache9(this), new GSTextureFX9()) + : GSRendererDX(base, mt, irq, new GSTextureCache9(this), new GSTextureFX9()) { InitVertexKick(); } -bool GSRendererDX9::Create(const string& title, int w, int h) +bool GSRendererDX9::CreateDevice(GSDevice* dev) { - if(!__super::Create(title, w, h)) + if(!__super::CreateDevice(dev)) return false; // diff --git a/plugins/GSdx/GSRendererDX9.h b/plugins/GSdx/GSRendererDX9.h index 5111d942f9..8d4d6d55fe 100644 --- a/plugins/GSdx/GSRendererDX9.h +++ b/plugins/GSdx/GSRendererDX9.h @@ -48,7 +48,7 @@ protected: public: GSRendererDX9(uint8* base, bool mt, void (*irq)()); - bool Create(const string& title, int w, int h); + bool CreateDevice(GSDevice* dev); template void VertexKick(bool skip); }; diff --git a/plugins/GSdx/GSRendererHW.h b/plugins/GSdx/GSRendererHW.h index 5bdd74f0bf..49b6c906b9 100644 --- a/plugins/GSdx/GSRendererHW.h +++ b/plugins/GSdx/GSRendererHW.h @@ -703,8 +703,8 @@ protected: } public: - GSRendererHW(uint8* base, bool mt, void (*irq)(), GSDevice* dev, GSTextureCache* tc) - : GSRendererT(base, mt, irq, dev) + GSRendererHW(uint8* base, bool mt, void (*irq)(), GSTextureCache* tc) + : GSRendererT(base, mt, irq) , m_tc(tc) , m_width(1024) , m_height(1024) diff --git a/plugins/GSdx/GSRendererNull.h b/plugins/GSdx/GSRendererNull.h index 285cdc4d2f..7cceae0562 100644 --- a/plugins/GSdx/GSRendererNull.h +++ b/plugins/GSdx/GSRendererNull.h @@ -37,8 +37,8 @@ protected: } public: - GSRendererNull(uint8* base, bool mt, void (*irq)(), GSDevice* dev) - : GSRendererT(base, mt, irq, dev) + GSRendererNull(uint8* base, bool mt, void (*irq)()) + : GSRendererT(base, mt, irq) { InitVertexKick(); } diff --git a/plugins/GSdx/GSRendererOGL.cpp b/plugins/GSdx/GSRendererOGL.cpp index 6ccaffa838..08ab965ac5 100644 --- a/plugins/GSdx/GSRendererOGL.cpp +++ b/plugins/GSdx/GSRendererOGL.cpp @@ -25,14 +25,14 @@ #include "resource.h" GSRendererOGL::GSRendererOGL(uint8* base, bool mt, void (*irq)()) - : GSRendererHW(base, mt, irq, new GSDeviceOGL(), new GSTextureCacheOGL(this)) + : GSRendererHW(base, mt, irq, new GSTextureCacheOGL(this)) { InitVertexKick(); } -bool GSRendererOGL::Create(const string& title, int w, int h) +bool GSRendererOGL::CreateDevice(GSDevice* dev) { - if(!__super::Create(title, w, h)) + if(!__super::CreateDevice(dev)) return false; // TODO diff --git a/plugins/GSdx/GSRendererOGL.h b/plugins/GSdx/GSRendererOGL.h index 14c6b84c21..b39f6132f8 100644 --- a/plugins/GSdx/GSRendererOGL.h +++ b/plugins/GSdx/GSRendererOGL.h @@ -34,7 +34,7 @@ protected: public: GSRendererOGL(uint8* base, bool mt, void (*irq)()); - bool Create(const string& title, int w, int h); + bool CreateDevice(GSDevice* dev); template void VertexKick(bool skip); }; \ No newline at end of file diff --git a/plugins/GSdx/GSRendererSW.cpp b/plugins/GSdx/GSRendererSW.cpp index 9c1d6ceb27..7eeb636b33 100644 --- a/plugins/GSdx/GSRendererSW.cpp +++ b/plugins/GSdx/GSRendererSW.cpp @@ -24,8 +24,8 @@ const GSVector4 g_pos_scale(1.0f / 16, 1.0f / 16, 1.0f, 128.0f); -GSRendererSW::GSRendererSW(uint8* base, bool mt, void (*irq)(), GSDevice* dev) - : GSRendererT(base, mt, irq, dev) +GSRendererSW::GSRendererSW(uint8* base, bool mt, void (*irq)()) + : GSRendererT(base, mt, irq) { m_tc = new GSTextureCacheSW(this); diff --git a/plugins/GSdx/GSRendererSW.h b/plugins/GSdx/GSRendererSW.h index 542e53e6b3..652735efff 100644 --- a/plugins/GSdx/GSRendererSW.h +++ b/plugins/GSdx/GSRendererSW.h @@ -44,7 +44,7 @@ protected: void GetScanlineParam(GSScanlineParam& p, GS_PRIM_CLASS primclass); public: - GSRendererSW(uint8* base, bool mt, void (*irq)(), GSDevice* dev); + GSRendererSW(uint8* base, bool mt, void (*irq)()); virtual ~GSRendererSW(); template diff --git a/plugins/GSdx/GSWnd.cpp b/plugins/GSdx/GSWnd.cpp index c86edc1408..160f2fc1ff 100644 --- a/plugins/GSdx/GSWnd.cpp +++ b/plugins/GSdx/GSWnd.cpp @@ -25,6 +25,8 @@ GSWnd::GSWnd() : m_hWnd(NULL) + , m_IsManaged(true) + , m_HasFrame(true) { } @@ -77,6 +79,8 @@ LRESULT GSWnd::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) bool GSWnd::Create(const string& title, int w, int h) { + if(m_hWnd) return true; + WNDCLASS wc; memset(&wc, 0, sizeof(wc)); @@ -134,15 +138,22 @@ bool GSWnd::Create(const string& title, int w, int h) return true; } -bool GSWnd::Attach(HWND hWnd) +bool GSWnd::Attach(HWND hWnd, bool isManaged) { // TODO: subclass m_hWnd = hWnd; + m_IsManaged = isManaged; return true; } +void GSWnd::Detach() +{ + m_hWnd = NULL; + m_IsManaged = true; +} + GSVector4i GSWnd::GetClientRect() { GSVector4i r; @@ -152,13 +163,21 @@ GSVector4i GSWnd::GetClientRect() return r; } -void GSWnd::SetWindowText(const char* title) +// Returns FALSE if the window has no title, or if th window title is under the strict +// management of the emulator. +bool GSWnd::SetWindowText(const char* title) { + if( !m_IsManaged ) return false; + ::SetWindowText(m_hWnd, title); + + return m_HasFrame; } void GSWnd::Show() { + if( !m_IsManaged ) return; + //SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); SetForegroundWindow(m_hWnd); @@ -170,14 +189,20 @@ void GSWnd::Show() void GSWnd::Hide() { + if( !m_IsManaged ) return; + ShowWindow(m_hWnd, SW_HIDE); } void GSWnd::HideFrame() { + if( !m_IsManaged ) return; + SetWindowLong(m_hWnd, GWL_STYLE, GetWindowLong(m_hWnd, GWL_STYLE) & ~(WS_CAPTION|WS_THICKFRAME)); SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); SetMenu(m_hWnd, NULL); + + m_HasFrame = false; } diff --git a/plugins/GSdx/GSWnd.h b/plugins/GSdx/GSWnd.h index 8f0a72a0d4..9671131116 100644 --- a/plugins/GSdx/GSWnd.h +++ b/plugins/GSdx/GSWnd.h @@ -26,6 +26,8 @@ class GSWnd { HWND m_hWnd; + bool m_IsManaged; // set true when we're attached to a 3rdparty window that's amanged by the emulator + bool m_HasFrame; static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); virtual LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam); @@ -35,13 +37,14 @@ public: virtual ~GSWnd(); bool Create(const string& title, int w, int h); - bool Attach(HWND hWnd); + bool Attach(HWND hWnd, bool isManaged=true); + void Detach(); void* GetHandle() {return m_hWnd;} GSVector4i GetClientRect(); - void SetWindowText(const char* title); + bool SetWindowText(const char* title); void Show(); void Hide(); diff --git a/plugins/GSdx/GSdx.def b/plugins/GSdx/GSdx.def index b08d67fa63..1a7c5cdc2a 100644 --- a/plugins/GSdx/GSdx.def +++ b/plugins/GSdx/GSdx.def @@ -11,7 +11,8 @@ EXPORTS GSsetBaseMem GSinit GSshutdown - GSopen + GSopen + GSopen2 GSclose GSreset GSwriteCSR diff --git a/plugins/GSdx/GSdx_vs2008.vcproj b/plugins/GSdx/GSdx_vs2008.vcproj index ea6b64a505..185a30352d 100644 --- a/plugins/GSdx/GSdx_vs2008.vcproj +++ b/plugins/GSdx/GSdx_vs2008.vcproj @@ -1197,10 +1197,6 @@ /> - - @@ -1977,6 +1973,10 @@ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" > + +