From 0430e4dd9fc565e43dcd59aad565af6535c287e5 Mon Sep 17 00:00:00 2001 From: "Jake.Stine" Date: Mon, 21 Dec 2009 16:14:28 +0000 Subject: [PATCH] Moved PADupdate() from MTGS thread to the GUI thread, and moved PADkeyEvent from EEcore thread to GUI thread. Rationale: I realized finally the point and purpose of PADupdate was to give the PAD plugin a callback that's on the same thread as the GS window, and which is (mostly) updated in regular sync to the refresh rate (50/60hz). So that's what it does now, finally. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2377 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/MTGS.cpp | 3 -- pcsx2/System/SysCoreThread.cpp | 16 +------- pcsx2/System/SysThreads.h | 2 +- pcsx2/gui/App.h | 10 ++--- pcsx2/gui/AppCoreThread.cpp | 37 ++----------------- pcsx2/gui/AppInit.cpp | 15 ++++---- pcsx2/gui/AppMain.cpp | 67 +++++++++++++++++++++++++++++++--- 7 files changed, 81 insertions(+), 69 deletions(-) diff --git a/pcsx2/MTGS.cpp b/pcsx2/MTGS.cpp index fea88bb927..f30e297913 100644 --- a/pcsx2/MTGS.cpp +++ b/pcsx2/MTGS.cpp @@ -370,9 +370,6 @@ void SysMtgsThread::ExecuteTaskInThread() GSvsync(tag.data[0]); gsFrameSkip(); - if( PADupdate != NULL ) - PADupdate(0); - StateCheckInThread(); } break; diff --git a/pcsx2/System/SysCoreThread.cpp b/pcsx2/System/SysCoreThread.cpp index 23d995fe7f..6c5857640f 100644 --- a/pcsx2/System/SysCoreThread.cpp +++ b/pcsx2/System/SysCoreThread.cpp @@ -332,9 +332,7 @@ void SysCoreThread::CpuInitializeMess() sbcoe.Success(); } -// Called by the VsyncInThread() if a valid keyEvent is pending and is unhandled by other -// PS2 core plugins. -void SysCoreThread::DispatchKeyEventToUI( const keyEvent& evt ) +void SysCoreThread::PostVsyncToUI() { } @@ -349,17 +347,7 @@ void SysCoreThread::DispatchKeyEventToUI( const keyEvent& evt ) // void SysCoreThread::VsyncInThread() { - if( !pxAssert(g_plugins!=NULL) ) return; - const keyEvent* ev = PADkeyEvent(); - if( ev != NULL && (ev->key != 0) ) - { - // Give plugins first try to handle keys. If none of them handles the key, it will - // be passed to the main user interface. - - if( !g_plugins->KeyEvent( *ev ) ) - DispatchKeyEventToUI( *ev ); - } - + PostVsyncToUI(); if (EmuConfig.EnablePatches) ApplyPatch(); } diff --git a/pcsx2/System/SysThreads.h b/pcsx2/System/SysThreads.h index 1e625e82c0..8d934659ea 100644 --- a/pcsx2/System/SysThreads.h +++ b/pcsx2/System/SysThreads.h @@ -204,7 +204,7 @@ public: bool HasPendingStateChangeRequest() const; virtual void StateCheckInThread(); virtual void VsyncInThread(); - virtual void DispatchKeyEventToUI( const keyEvent& evt ); + virtual void PostVsyncToUI()=0; virtual const wxString& GetElfOverride() const { return m_elf_override; } virtual void SetElfOverride( const wxString& elf ); diff --git a/pcsx2/gui/App.h b/pcsx2/gui/App.h index 939e3a22cd..6004b0757d 100644 --- a/pcsx2/gui/App.h +++ b/pcsx2/gui/App.h @@ -40,6 +40,7 @@ BEGIN_DECLARE_EVENT_TYPES() DECLARE_EVENT_TYPE( pxEVT_CoreThreadStatus, -1 ) DECLARE_EVENT_TYPE( pxEVT_FreezeThreadFinished, -1 ) DECLARE_EVENT_TYPE( pxEVT_Ping, -1 ) + DECLARE_EVENT_TYPE( pxEVT_LogicalVsync, -1 ) END_DECLARE_EVENT_TYPES() // This is used when the GS plugin is handling its own window. Messages from the PAD @@ -368,6 +369,7 @@ protected: ConsoleLogFrame* m_ProgramLogBox; std::vector m_PingWhenIdle; + wxKeyEvent m_kevt; public: Pcsx2App(); @@ -446,6 +448,7 @@ protected: void CleanupMess(); void OpenWizardConsole(); void PingDispatch( const char* action ); + void PadKeyDispatch( const keyEvent& ev ); void HandleEvent(wxEvtHandler* handler, wxEventFunction func, wxEvent& event) const; void HandleEvent(wxEvtHandler* handler, wxEventFunction func, wxEvent& event); @@ -455,11 +458,11 @@ protected: void OnLoadPluginsComplete( wxCommandEvent& evt ); void OnOpenModalDialog( wxCommandEvent& evt ); void OnCoreThreadStatus( wxCommandEvent& evt ); - void OnFreezeThreadFinished( wxCommandEvent& evt ); void OnMessageBox( pxMessageBoxEvent& evt ); void OnEmuKeyDown( wxKeyEvent& evt ); + void OnLogicalVsync( wxCommandEvent& evt ); void OnIdleEvent( wxIdleEvent& evt ); void OnPingEvent( pxPingEvent& evt ); @@ -497,9 +500,6 @@ class AppCoreThread : public SysCoreThread { typedef SysCoreThread _parent; -protected: - wxKeyEvent m_kevt; - public: AppCoreThread(); virtual ~AppCoreThread() throw(); @@ -519,7 +519,7 @@ protected: virtual void OnSuspendInThread(); virtual void OnCleanupInThread(); //virtual void VsyncInThread(); - virtual void DispatchKeyEventToUI( const keyEvent& ev ); + virtual void PostVsyncToUI(); virtual void ExecuteTaskInThread(); }; diff --git a/pcsx2/gui/AppCoreThread.cpp b/pcsx2/gui/AppCoreThread.cpp index 1855bff585..ec1c152eb0 100644 --- a/pcsx2/gui/AppCoreThread.cpp +++ b/pcsx2/gui/AppCoreThread.cpp @@ -59,13 +59,6 @@ bool AppCoreThread::Suspend( bool isBlocking ) if( !retval || isBlocking ) ScopedBusyCursor::SetDefault( Cursor_NotBusy ); - // Clear the sticky key statuses, because hell knows what'll change while the PAD - // plugin is suspended. - - m_kevt.m_shiftDown = false; - m_kevt.m_controlDown = false; - m_kevt.m_altDown = false; - return retval; } @@ -169,34 +162,10 @@ void AppCoreThread::OnCleanupInThread() _parent::OnCleanupInThread(); } -#ifdef __WXGTK__ - extern int TranslateGDKtoWXK( u32 keysym ); -#endif - -void AppCoreThread::DispatchKeyEventToUI( const keyEvent& ev ) +void AppCoreThread::PostVsyncToUI() { - m_kevt.SetEventType( ( ev.evt == KEYPRESS ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ); - const bool isDown = (ev.evt == KEYPRESS); - - #ifdef __WXMSW__ - const int vkey = wxCharCodeMSWToWX( ev.key ); - #elif defined( __WXGTK__ ) - const int vkey = TranslateGDKtoWXK( ev.key ); - #else - # error Unsupported Target Platform. - #endif - - switch (vkey) - { - case WXK_SHIFT: m_kevt.m_shiftDown = isDown; return; - case WXK_CONTROL: m_kevt.m_controlDown = isDown; return; - - case WXK_ALT: // ALT/MENU are usually the same key? I'm confused. - case WXK_MENU: m_kevt.m_altDown = isDown; return; - } - - m_kevt.m_keyCode = vkey; - wxGetApp().PostPadKey( m_kevt ); + wxCommandEvent evt( pxEVT_LogicalVsync ); + wxGetApp().AddPendingEvent( evt ); } void AppCoreThread::StateCheckInThread() diff --git a/pcsx2/gui/AppInit.cpp b/pcsx2/gui/AppInit.cpp index 7247a4ae4d..3a7009b9a2 100644 --- a/pcsx2/gui/AppInit.cpp +++ b/pcsx2/gui/AppInit.cpp @@ -288,15 +288,16 @@ bool Pcsx2App::OnInit() m_StderrRedirHandle = NewPipeRedir(stderr); wxLocale::AddCatalogLookupPathPrefix( wxGetCwd() ); - Connect( pxEVT_ReloadPlugins, wxCommandEventHandler( Pcsx2App::OnReloadPlugins ) ); - Connect( pxEVT_SysExecute, wxCommandEventHandler( Pcsx2App::OnSysExecute ) ); + Connect( pxEVT_ReloadPlugins, wxCommandEventHandler (Pcsx2App::OnReloadPlugins) ); + Connect( pxEVT_SysExecute, wxCommandEventHandler (Pcsx2App::OnSysExecute) ); - Connect( pxEVT_LoadPluginsComplete, wxCommandEventHandler( Pcsx2App::OnLoadPluginsComplete ) ); - Connect( pxEVT_CoreThreadStatus, wxCommandEventHandler( Pcsx2App::OnCoreThreadStatus ) ); - Connect( pxEVT_FreezeThreadFinished, wxCommandEventHandler( Pcsx2App::OnFreezeThreadFinished ) ); + Connect( pxEVT_LoadPluginsComplete, wxCommandEventHandler (Pcsx2App::OnLoadPluginsComplete) ); + Connect( pxEVT_CoreThreadStatus, wxCommandEventHandler (Pcsx2App::OnCoreThreadStatus) ); + Connect( pxEVT_FreezeThreadFinished, wxCommandEventHandler (Pcsx2App::OnFreezeThreadFinished) ); + Connect( pxEVT_LogicalVsync, wxCommandEventHandler (Pcsx2App::OnLogicalVsync) ); - Connect( pxEVT_Ping, pxPingEventHandler( Pcsx2App::OnPingEvent ) ); - Connect( wxEVT_IDLE, wxIdleEventHandler( Pcsx2App::OnIdleEvent ) ); + Connect( pxEVT_Ping, pxPingEventHandler (Pcsx2App::OnPingEvent) ); + Connect( wxEVT_IDLE, wxIdleEventHandler (Pcsx2App::OnIdleEvent) ); Connect( pxID_PadHandler_Keydown, wxEVT_KEY_DOWN, wxKeyEventHandler( Pcsx2App::OnEmuKeyDown ) ); diff --git a/pcsx2/gui/AppMain.cpp b/pcsx2/gui/AppMain.cpp index 34b2006fe1..23cbf7612e 100644 --- a/pcsx2/gui/AppMain.cpp +++ b/pcsx2/gui/AppMain.cpp @@ -39,6 +39,7 @@ DEFINE_EVENT_TYPE( pxEVT_LoadPluginsComplete ); DEFINE_EVENT_TYPE( pxEVT_CoreThreadStatus ); DEFINE_EVENT_TYPE( pxEVT_FreezeThreadFinished ); DEFINE_EVENT_TYPE( pxEVT_Ping ); +DEFINE_EVENT_TYPE( pxEVT_LogicalVsync ); #include "Utilities/EventSource.inl" EventSource_ImplementType( IniInterface ); @@ -152,21 +153,70 @@ void Pcsx2App::Ping() sema.WaitNoCancel(); } -void Pcsx2App::PostPadKey( wxKeyEvent& evt ) +#ifdef __WXGTK__ +extern int TranslateGDKtoWXK( u32 keysym ); +#endif + +void Pcsx2App::PadKeyDispatch( const keyEvent& ev ) { + m_kevt.SetEventType( ( ev.evt == KEYPRESS ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ); + const bool isDown = (ev.evt == KEYPRESS); + +#ifdef __WXMSW__ + const int vkey = wxCharCodeMSWToWX( ev.key ); +#elif defined( __WXGTK__ ) + const int vkey = TranslateGDKtoWXK( ev.key ); +#else +# error Unsupported Target Platform. +#endif + + switch (vkey) + { + case WXK_SHIFT: m_kevt.m_shiftDown = isDown; return; + case WXK_CONTROL: m_kevt.m_controlDown = isDown; return; + + case WXK_ALT: // ALT/MENU are usually the same key? I'm confused. + case WXK_MENU: m_kevt.m_altDown = isDown; return; + } + + m_kevt.m_keyCode = vkey; + // HACK: Legacy PAD plugins expect PCSX2 to ignore keyboard messages on the // GS window while the PAD plugin is open, so send messages to the APP handler // only if *either* the GS or PAD plugins are in legacy mode. if( m_gsFrame == NULL || (PADopen != NULL) ) { - evt.SetId( pxID_PadHandler_Keydown ); - wxGetApp().AddPendingEvent( evt ); + if( m_kevt.GetEventType() == wxEVT_KEY_DOWN ) + { + m_kevt.SetId( pxID_PadHandler_Keydown ); + wxGetApp().ProcessEvent( m_kevt ); + } } else { - evt.SetId( m_gsFrame->GetViewport()->GetId() ); - m_gsFrame->AddPendingEvent( evt ); + m_kevt.SetId( m_gsFrame->GetViewport()->GetId() ); + m_gsFrame->ProcessEvent( m_kevt ); + } +} + +// OnLogicalVsync - Event received from the AppCoreThread (EEcore) for each vsync, +// roughly 50/60 times a second when frame limiting is enabled, and up to 10,000 +// times a second if not (ok, not quite, but you get the idea... I hope.) +void Pcsx2App::OnLogicalVsync( wxCommandEvent& evt ) +{ + if( !SysHasValidState() || g_plugins == NULL ) return; + + if( PADupdate != NULL ) PADupdate(0); + const keyEvent* ev = PADkeyEvent(); + + if( (ev != NULL) && (ev->key != 0) ) + { + // Give plugins first try to handle keys. If none of them handles the key, it will + // be passed to the main user interface. + + if( !g_plugins->KeyEvent( *ev ) ) + PadKeyDispatch( *ev ); } } @@ -180,6 +230,13 @@ void Pcsx2App::PostPadKey( wxKeyEvent& evt ) // polling of the CoreThread rather than the belated status. void Pcsx2App::OnCoreThreadStatus( wxCommandEvent& evt ) { + // Clear the sticky key statuses, because hell knows what'll change while the PAD + // plugin is suspended. + + m_kevt.m_shiftDown = false; + m_kevt.m_controlDown = false; + m_kevt.m_altDown = false; + m_evtsrc_CoreThreadStatus.Dispatch( evt ); ScopedBusyCursor::SetDefault( Cursor_NotBusy ); CoreThread.RethrowException();