diff --git a/common/include/PS2Edefs.h b/common/include/PS2Edefs.h index 9ece1307fa..76c0fc17e5 100644 --- a/common/include/PS2Edefs.h +++ b/common/include/PS2Edefs.h @@ -532,6 +532,7 @@ typedef void (CALLBACK* _GSprintf)(int timeout, char *fmt, ...); typedef void (CALLBACK* _GSsetBaseMem)(void*); typedef void (CALLBACK* _GSsetGameCRC)(int, int); typedef void (CALLBACK* _GSsetFrameSkip)(int frameskip); +typedef void (CALLBACK* _GSsetFrameLimit)(int); typedef int (CALLBACK* _GSsetupRecording)(int, void*); typedef void (CALLBACK* _GSreset)(); typedef void (CALLBACK* _GSwriteCSR)(u32 value); @@ -725,6 +726,7 @@ extern _GSprintf GSprintf; extern _GSsetBaseMem GSsetBaseMem; extern _GSsetGameCRC GSsetGameCRC; extern _GSsetFrameSkip GSsetFrameSkip; +extern _GSsetFrameLimit GSsetFrameLimit; extern _GSsetupRecording GSsetupRecording; extern _GSreset GSreset; extern _GSwriteCSR GSwriteCSR; diff --git a/pcsx2/GS.cpp b/pcsx2/GS.cpp index abb171d06e..66e7398e7e 100644 --- a/pcsx2/GS.cpp +++ b/pcsx2/GS.cpp @@ -175,6 +175,7 @@ void gsInit() // Opens the gsRingbuffer thread. s32 gsOpen() { + u32 curFrameLimit = Config.Options & PCSX2_FRAMELIMIT_MASK; if( m_gsOpened ) return 0; //video @@ -200,6 +201,23 @@ s32 gsOpen() UpdateVSyncRate() ); }*/ + + if(GSsetFrameLimit == NULL) + { + DevCon::Notice("Notice: GS Plugin does not implement GSsetFrameLimit."); + } + else + { + if(curFrameLimit == PCSX2_FRAMELIMIT_NORMAL) + { + GSsetFrameLimit(0); + } + else + { + GSsetFrameLimit(1); + } + } + return !m_gsOpened; } diff --git a/pcsx2/Misc.cpp b/pcsx2/Misc.cpp index f10e4815fe..18c3c3dfba 100644 --- a/pcsx2/Misc.cpp +++ b/pcsx2/Misc.cpp @@ -499,6 +499,23 @@ void CycleFrameLimit(int dir) newOptions = (Config.Options & ~PCSX2_FRAMELIMIT_MASK) | newFrameLimit; gsResetFrameSkip(); + + // Allows sync to vblank only when framelimit is on, if GS can. + if(GSsetFrameLimit == NULL) + { + DevCon::Notice("Notice: GS Plugin does not implement GSsetFrameLimit."); + } + else + { + if(newFrameLimit) + { + GSsetFrameLimit(1); + } + else + { + GSsetFrameLimit(0); + } + } switch(newFrameLimit) { case PCSX2_FRAMELIMIT_NORMAL: diff --git a/pcsx2/Plugins.cpp b/pcsx2/Plugins.cpp index a4964e376a..9734d535c7 100644 --- a/pcsx2/Plugins.cpp +++ b/pcsx2/Plugins.cpp @@ -46,6 +46,7 @@ _GSprintf GSprintf; _GSsetBaseMem GSsetBaseMem; _GSsetGameCRC GSsetGameCRC; _GSsetFrameSkip GSsetFrameSkip; +_GSsetFrameLimit GSsetFrameLimit; _GSsetupRecording GSsetupRecording; _GSreset GSreset; _GSwriteCSR GSwriteCSR; @@ -341,6 +342,7 @@ int LoadGSplugin(const string& filename) MapSymbol(GSgetDriverInfo); MapSymbol(GSsetFrameSkip); + MapSymbol(GSsetFrameLimit); MapSymbol(GSsetupRecording); #ifdef _WIN32 diff --git a/plugins/GSdx/GS.cpp b/plugins/GSdx/GS.cpp index f7751d5d33..2f90e72415 100644 --- a/plugins/GSdx/GS.cpp +++ b/plugins/GSdx/GS.cpp @@ -291,7 +291,7 @@ EXPORT_C GSsetGameCRC(uint32 crc, int options) s_gs->SetGameCRC(crc, options); } -EXPORT_C GSgetLastTag(uint32* tag) +EXPORT_C GSgetLastTag(uint32* tag) { s_gs->GetLastTag(tag); } @@ -301,6 +301,18 @@ EXPORT_C GSsetFrameSkip(int frameskip) s_gs->SetFrameSkip(frameskip); } +EXPORT_C GSsetFrameLimit(int limit) +{ + if(limit) + { + s_gs->SetFrameLimit(1); + } + else + { + s_gs->SetFrameLimit(0); + } +} + #ifdef _WINDOWS EXPORT_C GSReplay(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) diff --git a/plugins/GSdx/GSDevice.cpp b/plugins/GSdx/GSDevice.cpp index 38de81de65..ba7a450e55 100644 --- a/plugins/GSdx/GSDevice.cpp +++ b/plugins/GSdx/GSDevice.cpp @@ -251,3 +251,8 @@ bool GSDevice::ResizeTexture(GSTexture** t, int w, int h) return t2 != NULL; } + +void GSDevice::SetVSync(bool vsync) +{ + m_vsync = vsync; +} diff --git a/plugins/GSdx/GSDevice.h b/plugins/GSdx/GSDevice.h index 00540b907d..7db5480390 100644 --- a/plugins/GSdx/GSDevice.h +++ b/plugins/GSdx/GSDevice.h @@ -103,6 +103,8 @@ public: virtual void StretchRect(GSTexture* st, GSTexture* dt, const GSVector4& dr, int shader = 0, bool linear = true); virtual void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader = 0, bool linear = true) {} + virtual void SetVSync(bool vsync); + GSTexture* GetCurrent(); void Merge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, const GSVector2i& fs, bool slbg, bool mmod, const GSVector4& c); diff --git a/plugins/GSdx/GSRenderer.cpp b/plugins/GSdx/GSRenderer.cpp index c263ba922e..c6ef736eb0 100644 --- a/plugins/GSdx/GSRenderer.cpp +++ b/plugins/GSdx/GSRenderer.cpp @@ -435,6 +435,12 @@ void GSRenderer::KeyEvent(GSKeyEventData* e) } } + +void GSRenderer::SetFrameLimit(bool limit) +{ + m_dev->SetVSync(m_vsync && limit); +} + void GSRenderer::GetTextureMinMax(GSVector4i& r, bool linear) { const GSDrawingContext* context = m_context; diff --git a/plugins/GSdx/GSRenderer.h b/plugins/GSdx/GSRenderer.h index e78f762e2b..e74508a4f4 100644 --- a/plugins/GSdx/GSRenderer.h +++ b/plugins/GSdx/GSRenderer.h @@ -77,6 +77,7 @@ public: virtual void VSync(int field); virtual bool MakeSnapshot(const string& path); virtual void KeyEvent(GSKeyEventData* e); + virtual void SetFrameLimit(bool limit); virtual bool CanUpscale() { diff --git a/plugins/GSdx/GSdx.def b/plugins/GSdx/GSdx.def index fd1bf9dbb5..ec872b0b12 100644 --- a/plugins/GSdx/GSdx.def +++ b/plugins/GSdx/GSdx.def @@ -30,7 +30,8 @@ EXPORTS GSreadFIFO2 GSirqCallback GSsetGameCRC - GSsetFrameSkip + GSsetFrameSkip + GSsetFrameLimit GSgetLastTag GSReplay GSBenchmark