diff --git a/Source/Core/Core/Src/Core.cpp b/Source/Core/Core/Src/Core.cpp index a748ae8eb1..aa2e9616f9 100644 --- a/Source/Core/Core/Src/Core.cpp +++ b/Source/Core/Core/Src/Core.cpp @@ -184,7 +184,7 @@ void Stop() // - Hammertime! #ifdef _WIN32 PostMessage((HWND)g_pWindowHandle, WM_QUIT, 0, 0); #else - // TODO(ector) : post message exit + PluginVideo::Video_Stop(); #endif delete g_pThread; //Wait for emuthread to close diff --git a/Source/Core/Core/Src/Plugins/Plugin_Video.cpp b/Source/Core/Core/Src/Plugins/Plugin_Video.cpp index 08252de8d5..6a74212f3c 100644 --- a/Source/Core/Core/Src/Plugins/Plugin_Video.cpp +++ b/Source/Core/Core/Src/Plugins/Plugin_Video.cpp @@ -35,7 +35,8 @@ TVideo_Screenshot Video_Screenshot = 0; TVideo_EnterLoop Video_EnterLoop = 0; TVideo_AddMessage Video_AddMessage = 0; TVideo_DoState Video_DoState = 0; - +TVideo_Stop Video_Stop = 0; + // Library Instance DynamicLibrary plugin; @@ -57,6 +58,7 @@ void UnloadPlugin() Video_UpdateXFB = 0; Video_AddMessage = 0; Video_DoState = 0; + Video_Stop = 0; plugin.Unload(); } @@ -77,6 +79,7 @@ bool LoadPlugin(const char *_Filename) Video_EnterLoop = reinterpret_cast (plugin.Get("Video_EnterLoop")); Video_AddMessage = reinterpret_cast (plugin.Get("Video_AddMessage")); Video_DoState = reinterpret_cast (plugin.Get("Video_DoState")); + Video_Stop = reinterpret_cast (plugin.Get("Video_Stop")); if ((GetDllInfo != 0) && (DllAbout != 0) && (DllConfig != 0) && @@ -88,7 +91,8 @@ bool LoadPlugin(const char *_Filename) (Video_EnterLoop != 0) && (Video_Screenshot != 0) && (Video_AddMessage != 0) && - (Video_DoState != 0) ) + (Video_DoState != 0) && + (Video_Stop != 0)) { return true; } diff --git a/Source/Core/Core/Src/Plugins/Plugin_Video.h b/Source/Core/Core/Src/Plugins/Plugin_Video.h index 59067ecd1c..9db0a5996d 100644 --- a/Source/Core/Core/Src/Plugins/Plugin_Video.h +++ b/Source/Core/Core/Src/Plugins/Plugin_Video.h @@ -43,7 +43,8 @@ typedef BOOL (__cdecl* TVideo_Screenshot)(TCHAR*); typedef void (__cdecl* TVideo_EnterLoop)(); typedef void (__cdecl* TVideo_AddMessage)(const char* pstr, unsigned int milliseconds); typedef void (__cdecl* TVideo_DoState)(unsigned char **ptr, int mode); - +typedef void (__cdecl* TVideo_Stop)(); + // Function Pointers extern TGetDllInfo GetDllInfo; extern TDllAbout DllAbout; @@ -57,6 +58,7 @@ extern TVideo_Screenshot Video_Screenshot; extern TVideo_EnterLoop Video_EnterLoop; extern TVideo_AddMessage Video_AddMessage; extern TVideo_DoState Video_DoState; +extern TVideo_Stop Video_Stop; } // end of namespace PluginVideo diff --git a/Source/Core/VideoCommon/Src/Fifo.cpp b/Source/Core/VideoCommon/Src/Fifo.cpp index af2405ff28..ae7efe3c26 100644 --- a/Source/Core/VideoCommon/Src/Fifo.cpp +++ b/Source/Core/VideoCommon/Src/Fifo.cpp @@ -29,6 +29,8 @@ extern u32 g_pVideoData; FifoReader fifo; #endif +bool fifoStateRun = true; + // STATE_TO_SAVE static u8 *videoBuffer; static int size = 0; @@ -46,11 +48,17 @@ void Fifo_Init() #ifndef DATAREADER_INLINE fifo.Init(videoBuffer, videoBuffer); //zero length. there is no data yet. #endif + fifoStateRun = true; } void Fifo_Shutdown() { FreeMemoryPages(videoBuffer, FIFO_SIZE); + fifoStateRun = false; +} + +void Fifo_Stop() { + fifoStateRun = false; } u32 FAKE_GetFifoStartPtr() @@ -161,7 +169,7 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize) #endif // TODO(ector): Don't peek so often! - while (video_initialize.pPeekMessages()) + while (fifoStateRun || video_initialize.pPeekMessages()) { #if defined(THREAD_VIDEO_WAKEUP_ONIDLE) && defined(_WIN32) if (MsgWaitForMultipleObjects(1, &hEventOnIdle, FALSE, 1L, QS_ALLEVENTS) == WAIT_ABANDONED) diff --git a/Source/Core/VideoCommon/Src/Fifo.h b/Source/Core/VideoCommon/Src/Fifo.h index 68bc0eed96..e3d480b9ff 100644 --- a/Source/Core/VideoCommon/Src/Fifo.h +++ b/Source/Core/VideoCommon/Src/Fifo.h @@ -71,6 +71,7 @@ void Fifo_Init(); void Fifo_Shutdown(); void Fifo_EnterLoop(const SVideoInitialize &video_initialize); void Fifo_DoState(PointerWrap &f); +void Fifo_Stop(); #endif diff --git a/Source/PluginSpecs/pluginspecs_video.h b/Source/PluginSpecs/pluginspecs_video.h index c9233d7df1..fb5b0f2afb 100644 --- a/Source/PluginSpecs/pluginspecs_video.h +++ b/Source/PluginSpecs/pluginspecs_video.h @@ -182,5 +182,13 @@ EXPORT void CALL Video_AddMessage(const char* pstr, unsigned int milliseconds); // EXPORT void CALL Video_DoState(unsigned char **ptr, int mode); +// __________________________________________________________________________________________________ +// Function: Video_Stop +// Purpose: Stop the video plugin before shutdown +// input/output: +// input: +// +EXPORT void CALL Video_Stop(); + #include "ExportEpilog.h" #endif diff --git a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp index 18a055a76b..a40eb5a61c 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp @@ -192,6 +192,7 @@ void Video_DoState(unsigned char **ptr, int mode) { //PanicAlert("Saving/Loading state from DirectX9"); } + void Video_EnterLoop() { Fifo_EnterLoop(g_VideoInitialize); @@ -219,6 +220,10 @@ void Video_Shutdown(void) DeInit(); } +void Video_Stop(void) +{ +} + void Video_UpdateXFB(u8* /*_pXFB*/, u32 /*_dwWidth*/, u32 /*_dwHeight*/) { /* diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GLInit.cpp b/Source/Plugins/Plugin_VideoOGL/Src/GLInit.cpp index 7d7cb4b666..3f61e2f04c 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GLInit.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/GLInit.cpp @@ -76,10 +76,10 @@ void OpenGL_SetWindowText(const char *text) BOOL Callback_PeekMessages() { #if USE_SDL - // TODO: There is no documentation of this function and the calling code - // ignores the return value, so I have no idea what would be the + // TODO: There is no documentation of this function and the calling code + // ignores the return value, so I have no idea what would be the // proper value to return. - return TRUE; + return FALSE; #elif defined(_WIN32) //TODO: peekmessage MSG msg; @@ -94,7 +94,7 @@ BOOL Callback_PeekMessages() #else // GLX // This is called from Outside of our video thread, from EmuThread // The calls are NOT thread safe, so it breaks everything - return TRUE; + return FALSE; #endif } @@ -427,8 +427,8 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight return true; } -bool OpenGL_MakeCurrent() -{ +bool OpenGL_MakeCurrent() +{ #if USE_SDL // 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 @@ -504,70 +504,70 @@ void OpenGL_Update() nBackbufferWidth = width; nBackbufferHeight = height; -#else // GLX - // We just check all of our events here - XEvent event; - KeySym key; - static bool ShiftPressed = false; - static bool ControlPressed = false; - static int FKeyPressed = -1; - int num_events; - for (num_events = XPending(GLWin.dpy);num_events > 0;num_events--) { - XNextEvent(GLWin.dpy, &event); - switch(event.type) { - case KeyRelease: - key = XLookupKeysym((XKeyEvent*)&event, 0); - if(key >= XK_F1 && key <= XK_F9) { - g_VideoInitialize.pKeyPress(FKeyPressed, ShiftPressed, ControlPressed); - FKeyPressed = -1; - } else { - if(key == XK_Shift_L || key == XK_Shift_R) - ShiftPressed = false; - else if(key == XK_Control_L || key == XK_Control_R) - ControlPressed = false; - else - XPutBackEvent(GLWin.dpy, &event); - } - break; - case KeyPress: - key = XLookupKeysym((XKeyEvent*)&event, 0); - if(key >= XK_F1 && key <= XK_F9) - FKeyPressed = key - 0xff4e; - else { - if(key == XK_Shift_L || key == XK_Shift_R) - ShiftPressed = true; - else if(key == XK_Control_L || key == XK_Control_R) - ControlPressed = true; - else - XPutBackEvent(GLWin.dpy, &event); - } - break; - case ButtonPress: - case ButtonRelease: - XPutBackEvent(GLWin.dpy, &event); - break; - case ConfigureNotify: - Window winDummy; - unsigned int borderDummy; - XGetGeometry(GLWin.dpy, GLWin.win, &winDummy, &GLWin.x, &GLWin.y, - &GLWin.width, &GLWin.height, &borderDummy, &GLWin.depth); - nBackbufferWidth = GLWin.width; - nBackbufferHeight = GLWin.height; - break; - case ClientMessage: //TODO: We aren't reading this correctly, It could be anything, highest change is that it's a close event though - Video_Shutdown(); // Calling from here since returning false does nothing - return; - break; - default: - //TODO: Should we put the event back if we don't handle it? - // I think we handle all the needed ones, the rest shouldn't matter - // But to be safe, let's but them back anyway - //XPutBackEvent(GLWin.dpy, &event); - break; - } - } - return; -#endif +#else // GLX + // We just check all of our events here + XEvent event; + KeySym key; + static bool ShiftPressed = false; + static bool ControlPressed = false; + static int FKeyPressed = -1; + int num_events; + for (num_events = XPending(GLWin.dpy);num_events > 0;num_events--) { + XNextEvent(GLWin.dpy, &event); + switch(event.type) { + case KeyRelease: + key = XLookupKeysym((XKeyEvent*)&event, 0); + if(key >= XK_F1 && key <= XK_F9) { + g_VideoInitialize.pKeyPress(FKeyPressed, ShiftPressed, ControlPressed); + FKeyPressed = -1; + } else { + if(key == XK_Shift_L || key == XK_Shift_R) + ShiftPressed = false; + else if(key == XK_Control_L || key == XK_Control_R) + ControlPressed = false; + else + XPutBackEvent(GLWin.dpy, &event); + } + break; + case KeyPress: + key = XLookupKeysym((XKeyEvent*)&event, 0); + if(key >= XK_F1 && key <= XK_F9) + FKeyPressed = key - 0xff4e; + else { + if(key == XK_Shift_L || key == XK_Shift_R) + ShiftPressed = true; + else if(key == XK_Control_L || key == XK_Control_R) + ControlPressed = true; + else + XPutBackEvent(GLWin.dpy, &event); + } + break; + case ButtonPress: + case ButtonRelease: + XPutBackEvent(GLWin.dpy, &event); + break; + case ConfigureNotify: + Window winDummy; + unsigned int borderDummy; + XGetGeometry(GLWin.dpy, GLWin.win, &winDummy, &GLWin.x, &GLWin.y, + &GLWin.width, &GLWin.height, &borderDummy, &GLWin.depth); + nBackbufferWidth = GLWin.width; + nBackbufferHeight = GLWin.height; + break; + case ClientMessage: //TODO: We aren't reading this correctly, It could be anything, highest change is that it's a close event though + Video_Shutdown(); // Calling from here since returning false does nothing + return; + break; + default: + //TODO: Should we put the event back if we don't handle it? + // I think we handle all the needed ones, the rest shouldn't matter + // But to be safe, let's but them back anyway + //XPutBackEvent(GLWin.dpy, &event); + break; + } + } + return; +#endif float FactorW = 640.0f / (float)nBackbufferWidth; float FactorH = 480.0f / (float)nBackbufferHeight; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp index 28a84beb27..923c19dd6f 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp @@ -218,9 +218,13 @@ void Video_Shutdown(void) TextureMngr::Shutdown(); OpcodeDecoder_Shutdown(); Renderer::Shutdown(); - OpenGL_Shutdown(); + OpenGL_Shutdown(); } +void Video_Stop(void) +{ + Fifo_Stop(); +} void Video_EnterLoop() {