diff --git a/Source/Core/Common/Src/PluginVideo.cpp b/Source/Core/Common/Src/PluginVideo.cpp index 08174fefcb..394d21d5ee 100644 --- a/Source/Core/Common/Src/PluginVideo.cpp +++ b/Source/Core/Common/Src/PluginVideo.cpp @@ -39,6 +39,7 @@ PluginVideo::PluginVideo(const char *_Filename) : CPlugin(_Filename), validVideo Video_GatherPipeBursted = 0; Video_WaitForFrameFinish = 0; Video_IsFifoBusy = 0; + Video_AbortFrame = 0; Video_Prepare = reinterpret_cast (LoadSymbol("Video_Prepare")); @@ -74,6 +75,8 @@ PluginVideo::PluginVideo(const char *_Filename) : CPlugin(_Filename), validVideo (LoadSymbol("Video_WaitForFrameFinish")); Video_IsFifoBusy = reinterpret_cast (LoadSymbol("Video_IsFifoBusy")); + Video_AbortFrame = reinterpret_cast + (LoadSymbol("Video_AbortFrame")); if ((Video_Prepare != 0) && (Video_BeginField != 0) && (Video_EndField != 0) && @@ -91,7 +94,8 @@ PluginVideo::PluginVideo(const char *_Filename) : CPlugin(_Filename), validVideo (Video_PixelEngineWrite32 != 0) && (Video_GatherPipeBursted != 0) && (Video_WaitForFrameFinish != 0) && - (Video_IsFifoBusy != 0)) + (Video_IsFifoBusy != 0) && + (Video_AbortFrame != 0)) validVideo = true; } diff --git a/Source/Core/Common/Src/PluginVideo.h b/Source/Core/Common/Src/PluginVideo.h index 04a69aec92..43e4dc00fc 100644 --- a/Source/Core/Common/Src/PluginVideo.h +++ b/Source/Core/Common/Src/PluginVideo.h @@ -40,6 +40,7 @@ typedef void (__cdecl* TVideo_Write32)(const u32 _Data, const u32 _Address); typedef void (__cdecl* TVideo_GatherPipeBursted)(); typedef void (__cdecl* TVideo_WaitForFrameFinish)(); typedef bool (__cdecl* TVideo_IsFifoBusy)(); +typedef void (__cdecl* TVideo_AbortFrame)(); class PluginVideo : public CPlugin { @@ -68,6 +69,7 @@ public: TVideo_GatherPipeBursted Video_GatherPipeBursted; TVideo_WaitForFrameFinish Video_WaitForFrameFinish; TVideo_IsFifoBusy Video_IsFifoBusy; + TVideo_AbortFrame Video_AbortFrame; private: bool validVideo; }; diff --git a/Source/Core/Core/Src/HW/ProcessorInterface.cpp b/Source/Core/Core/Src/HW/ProcessorInterface.cpp index 97efc1245e..f3fa5b72d6 100644 --- a/Source/Core/Core/Src/HW/ProcessorInterface.cpp +++ b/Source/Core/Core/Src/HW/ProcessorInterface.cpp @@ -24,7 +24,7 @@ #include "../CoreTiming.h" #include "ProcessorInterface.h" #include "GPFifo.h" - +#include "../PluginManager.h" namespace ProcessorInterface { @@ -181,6 +181,8 @@ void Write32(const u32 _uValue, const u32 _iAddress) break; case PI_FIFO_RESET: + //Abort the actual frame + CPluginManager::GetInstance().GetVideo()->Video_AbortFrame(); //Fifo_CPUWritePointer = Fifo_CPUBase; ?? //PanicAlert("Unknown write to PI_FIFO_RESET (%08x)", _uValue); WARN_LOG(PROCESSORINTERFACE, "Fifo reset (%08x)", _uValue); diff --git a/Source/Core/VideoCommon/Src/CommandProcessor.cpp b/Source/Core/VideoCommon/Src/CommandProcessor.cpp index 0bc11714b5..d3394c4840 100644 --- a/Source/Core/VideoCommon/Src/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/Src/CommandProcessor.cpp @@ -701,4 +701,18 @@ void SetFifoIdleFromVideoPlugin() s_fifoIdleEvent.Set(); } +// This is called by the ProcessorInterface when PI_FIFO_RESET is writed, +// the general idea is abort all commands in the FIFO. +// This prevent Negative fifo.CPReadWriteDistance because when PI_FIFO_RESET happens +// the fifo.CPReadWriteDistance is writed to 0 +void AbortFrame() +{ + Fifo_SetRendering(false); + while(!fifo.CPCmdIdle) + Common::YieldCPU(); + Fifo_SetRendering(true); + PixelEngine::ResetSetToken(); + PixelEngine::ResetSetFinish(); +} + } // end of namespace CommandProcessor diff --git a/Source/Core/VideoCommon/Src/CommandProcessor.h b/Source/Core/VideoCommon/Src/CommandProcessor.h index 4c29d46ca6..d84c1866fe 100644 --- a/Source/Core/VideoCommon/Src/CommandProcessor.h +++ b/Source/Core/VideoCommon/Src/CommandProcessor.h @@ -162,6 +162,7 @@ void WaitForFrameFinish(); void FifoCriticalEnter(); void FifoCriticalLeave(); +void AbortFrame(); } // namespace CommandProcessor #endif // _COMMANDPROCESSOR_H diff --git a/Source/Core/VideoCommon/Src/PixelEngine.cpp b/Source/Core/VideoCommon/Src/PixelEngine.cpp index 12f353f7e7..06ceeef88e 100644 --- a/Source/Core/VideoCommon/Src/PixelEngine.cpp +++ b/Source/Core/VideoCommon/Src/PixelEngine.cpp @@ -393,4 +393,16 @@ void ResetSetFinish() } } +void ResetSetToken() +{ + if (g_bSignalTokenInterrupt) + { + g_VideoInitialize.pSetInterrupt(INT_CAUSE_PE_TOKEN, false); + g_bSignalTokenInterrupt = false; + + }else + { + g_VideoInitialize.pRemoveEvent(et_SetTokenOnMainThread); + } +} } // end of namespace PixelEngine diff --git a/Source/Core/VideoCommon/Src/PixelEngine.h b/Source/Core/VideoCommon/Src/PixelEngine.h index 6124c7b6e3..5b773c6c9b 100644 --- a/Source/Core/VideoCommon/Src/PixelEngine.h +++ b/Source/Core/VideoCommon/Src/PixelEngine.h @@ -68,6 +68,7 @@ void Write32(const u32 _iValue, const u32 _iAddress); void SetToken(const u16 _token, const int _bSetTokenAcknowledge); void SetFinish(void); void ResetSetFinish(void); +void ResetSetToken(void); bool AllowIdleSkipping(); // Bounding box functionality. Paper Mario (both) are a couple of the few games that use it. diff --git a/Source/PluginSpecs/pluginspecs_video.h b/Source/PluginSpecs/pluginspecs_video.h index 6388db13a0..7fde0e43fa 100644 --- a/Source/PluginSpecs/pluginspecs_video.h +++ b/Source/PluginSpecs/pluginspecs_video.h @@ -189,5 +189,7 @@ EXPORT void CALL Video_WaitForFrameFinish(void); // EXPORT bool CALL Video_IsFifoBusy(void); +EXPORT void CALL Video_AbortFrame(void); + #include "ExportEpilog.h" #endif diff --git a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp index c6585b3909..ab61173daf 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp @@ -453,3 +453,8 @@ bool Video_IsFifoBusy(void) { return CommandProcessor::isFifoBusy; } + +void Video_AbortFrame(void) +{ + CommandProcessor::AbortFrame(); +} \ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp index e745bd4e56..93c78d542a 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp @@ -479,3 +479,8 @@ bool Video_IsFifoBusy(void) { return CommandProcessor::isFifoBusy; } + +void Video_AbortFrame(void) +{ + CommandProcessor::AbortFrame(); +} diff --git a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp index 10cc1a283b..f886e1111b 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp @@ -510,3 +510,8 @@ bool Video_IsFifoBusy(void) { return CommandProcessor::isFifoBusy; } + +void Video_AbortFrame(void) +{ + CommandProcessor::AbortFrame(); +} \ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/main.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/main.cpp index 9a6d84bab3..9cd89d1787 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/main.cpp @@ -220,3 +220,7 @@ bool Video_IsFifoBusy(void) { return false; } + +void Video_AbortFrame(void) +{ +} \ No newline at end of file