diff --git a/pcsx2_suite_2008.sln b/pcsx2_suite_2008.sln index d3fb09b8a8..a073580361 100644 --- a/pcsx2_suite_2008.sln +++ b/pcsx2_suite_2008.sln @@ -521,8 +521,8 @@ Global {067D7863-393B-494F-B296-4A8853EB3D1D}.Debug|Win32.ActiveCfg = Debug|Win32 {067D7863-393B-494F-B296-4A8853EB3D1D}.Debug|Win32.Build.0 = Debug|Win32 {067D7863-393B-494F-B296-4A8853EB3D1D}.Debug|x64.ActiveCfg = Debug|Win32 - {067D7863-393B-494F-B296-4A8853EB3D1D}.Devel|Win32.ActiveCfg = Devel|Win32 - {067D7863-393B-494F-B296-4A8853EB3D1D}.Devel|Win32.Build.0 = Devel|Win32 + {067D7863-393B-494F-B296-4A8853EB3D1D}.Devel|Win32.ActiveCfg = Release|Win32 + {067D7863-393B-494F-B296-4A8853EB3D1D}.Devel|Win32.Build.0 = Release|Win32 {067D7863-393B-494F-B296-4A8853EB3D1D}.Devel|x64.ActiveCfg = Devel|Win32 {067D7863-393B-494F-B296-4A8853EB3D1D}.Release SSE2|Win32.ActiveCfg = Release|Win32 {067D7863-393B-494F-B296-4A8853EB3D1D}.Release SSE2|Win32.Build.0 = Release|Win32 diff --git a/plugins/GSdx/GS.cpp b/plugins/GSdx/GS.cpp index f4a12f1ccd..8b0f9a4b4d 100644 --- a/plugins/GSdx/GS.cpp +++ b/plugins/GSdx/GS.cpp @@ -38,6 +38,7 @@ static HRESULT s_hr = E_FAIL; static GSRenderer* s_gs = NULL; static void (*s_irq)() = NULL; static uint8* s_basemem = NULL; +static int s_renderer = -1; EXPORT_C_(uint32) PS2EgetLibType() { @@ -101,6 +102,7 @@ EXPORT_C GSshutdown() delete s_gs; s_gs = NULL; + s_renderer = -1; #ifdef _WINDOWS @@ -134,6 +136,31 @@ static INT32 _GSopen(void* dsp, char* title, int renderer) try { + GSFreezeData tempsave = { 0, NULL }; + + if(s_gs && (s_renderer != renderer)) + { + // This isn't a "normal" suspend resume case -- We need to swap renderers, but + // we have to preserve the GSState at the same time, so quick-save it to the + // tempsave, and then recover below after the new GSRenderer is in place. + + s_gs->Freeze(&tempsave, true); + + tempsave.data = (uint8*)_aligned_malloc( tempsave.size, 16 ); + + if(!tempsave.data) + { + throw std::bad_alloc("Failed allocating buffer for device-change savestate."); + } + + s_gs->Freeze( &tempsave, false ); + + delete s_gs; + + s_gs = NULL; + s_renderer = -1; + } + switch(renderer) { default: @@ -165,6 +192,13 @@ static INT32 _GSopen(void* dsp, char* title, int renderer) case 1: case 4: case 7: case 10: case 12: s_gs = new GSRendererSW(); break; } + + s_renderer = renderer; + } + + if(tempsave.data) + { + s_gs->Defrost(&tempsave); } } catch( std::exception& ex ) @@ -344,7 +378,14 @@ EXPORT_C_(int) GSfreeze(int mode, GSFreezeData* data) EXPORT_C GSconfigure() { - GSSettingsDlg().DoModal(); + if( GSSettingsDlg().DoModal() == IDOK ) + { + if( s_gs != NULL && s_gs->m_wnd.IsManaged() ) + { + // Legacy apps like gsdxgui expect this... + GSshutdown(); + } + } } EXPORT_C_(INT32) GStest() diff --git a/plugins/GSdx/GSState.h b/plugins/GSdx/GSState.h index b752b752c6..6fd0fbc1a5 100644 --- a/plugins/GSdx/GSState.h +++ b/plugins/GSdx/GSState.h @@ -250,8 +250,8 @@ public: virtual void SetGameCRC(uint32 crc, int options); void SetFrameSkip(int skip); void SetFrameLimit(bool limit); - void SetRegsMem( uint8* basemem ); + void SetRegsMem(uint8* basemem); void SetIrqCallback(void (*irq)()); - void SetMultithreaded( bool isMT=true ); + void SetMultithreaded(bool isMT=true); }; diff --git a/plugins/GSdx/GSWnd.cpp b/plugins/GSdx/GSWnd.cpp index b8a8bdd0de..7ccad2b0de 100644 --- a/plugins/GSdx/GSWnd.cpp +++ b/plugins/GSdx/GSWnd.cpp @@ -68,6 +68,9 @@ LRESULT GSWnd::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) // DestroyWindow(m_hWnd); return 0; case WM_DESTROY: + // This kills the emulator when GS is closed, which *really* isn't desired behavior, + // especially in STGS mode (worked in MTGS mode since it only quit the thread, but even + // that wasn't needed). //PostQuitMessage(0); return 0; default: diff --git a/plugins/GSdx/GSWnd.h b/plugins/GSdx/GSWnd.h index 9671131116..1ad4cd26ff 100644 --- a/plugins/GSdx/GSWnd.h +++ b/plugins/GSdx/GSWnd.h @@ -39,6 +39,7 @@ public: bool Create(const string& title, int w, int h); bool Attach(HWND hWnd, bool isManaged=true); void Detach(); + bool IsManaged() const { return m_IsManaged; } void* GetHandle() {return m_hWnd;}