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
This commit is contained in:
Jake.Stine 2009-12-21 16:14:28 +00:00
parent 500c1dbfeb
commit 0430e4dd9f
7 changed files with 81 additions and 69 deletions

View File

@ -370,9 +370,6 @@ void SysMtgsThread::ExecuteTaskInThread()
GSvsync(tag.data[0]); GSvsync(tag.data[0]);
gsFrameSkip(); gsFrameSkip();
if( PADupdate != NULL )
PADupdate(0);
StateCheckInThread(); StateCheckInThread();
} }
break; break;

View File

@ -332,9 +332,7 @@ void SysCoreThread::CpuInitializeMess()
sbcoe.Success(); sbcoe.Success();
} }
// Called by the VsyncInThread() if a valid keyEvent is pending and is unhandled by other void SysCoreThread::PostVsyncToUI()
// PS2 core plugins.
void SysCoreThread::DispatchKeyEventToUI( const keyEvent& evt )
{ {
} }
@ -349,17 +347,7 @@ void SysCoreThread::DispatchKeyEventToUI( const keyEvent& evt )
// //
void SysCoreThread::VsyncInThread() void SysCoreThread::VsyncInThread()
{ {
if( !pxAssert(g_plugins!=NULL) ) return; PostVsyncToUI();
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 );
}
if (EmuConfig.EnablePatches) ApplyPatch(); if (EmuConfig.EnablePatches) ApplyPatch();
} }

View File

@ -204,7 +204,7 @@ public:
bool HasPendingStateChangeRequest() const; bool HasPendingStateChangeRequest() const;
virtual void StateCheckInThread(); virtual void StateCheckInThread();
virtual void VsyncInThread(); virtual void VsyncInThread();
virtual void DispatchKeyEventToUI( const keyEvent& evt ); virtual void PostVsyncToUI()=0;
virtual const wxString& GetElfOverride() const { return m_elf_override; } virtual const wxString& GetElfOverride() const { return m_elf_override; }
virtual void SetElfOverride( const wxString& elf ); virtual void SetElfOverride( const wxString& elf );

View File

@ -40,6 +40,7 @@ BEGIN_DECLARE_EVENT_TYPES()
DECLARE_EVENT_TYPE( pxEVT_CoreThreadStatus, -1 ) DECLARE_EVENT_TYPE( pxEVT_CoreThreadStatus, -1 )
DECLARE_EVENT_TYPE( pxEVT_FreezeThreadFinished, -1 ) DECLARE_EVENT_TYPE( pxEVT_FreezeThreadFinished, -1 )
DECLARE_EVENT_TYPE( pxEVT_Ping, -1 ) DECLARE_EVENT_TYPE( pxEVT_Ping, -1 )
DECLARE_EVENT_TYPE( pxEVT_LogicalVsync, -1 )
END_DECLARE_EVENT_TYPES() END_DECLARE_EVENT_TYPES()
// This is used when the GS plugin is handling its own window. Messages from the PAD // This is used when the GS plugin is handling its own window. Messages from the PAD
@ -368,6 +369,7 @@ protected:
ConsoleLogFrame* m_ProgramLogBox; ConsoleLogFrame* m_ProgramLogBox;
std::vector<Semaphore*> m_PingWhenIdle; std::vector<Semaphore*> m_PingWhenIdle;
wxKeyEvent m_kevt;
public: public:
Pcsx2App(); Pcsx2App();
@ -446,6 +448,7 @@ protected:
void CleanupMess(); void CleanupMess();
void OpenWizardConsole(); void OpenWizardConsole();
void PingDispatch( const char* action ); 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) const;
void HandleEvent(wxEvtHandler* handler, wxEventFunction func, wxEvent& event); void HandleEvent(wxEvtHandler* handler, wxEventFunction func, wxEvent& event);
@ -455,11 +458,11 @@ protected:
void OnLoadPluginsComplete( wxCommandEvent& evt ); void OnLoadPluginsComplete( wxCommandEvent& evt );
void OnOpenModalDialog( wxCommandEvent& evt ); void OnOpenModalDialog( wxCommandEvent& evt );
void OnCoreThreadStatus( wxCommandEvent& evt ); void OnCoreThreadStatus( wxCommandEvent& evt );
void OnFreezeThreadFinished( wxCommandEvent& evt ); void OnFreezeThreadFinished( wxCommandEvent& evt );
void OnMessageBox( pxMessageBoxEvent& evt ); void OnMessageBox( pxMessageBoxEvent& evt );
void OnEmuKeyDown( wxKeyEvent& evt ); void OnEmuKeyDown( wxKeyEvent& evt );
void OnLogicalVsync( wxCommandEvent& evt );
void OnIdleEvent( wxIdleEvent& evt ); void OnIdleEvent( wxIdleEvent& evt );
void OnPingEvent( pxPingEvent& evt ); void OnPingEvent( pxPingEvent& evt );
@ -497,9 +500,6 @@ class AppCoreThread : public SysCoreThread
{ {
typedef SysCoreThread _parent; typedef SysCoreThread _parent;
protected:
wxKeyEvent m_kevt;
public: public:
AppCoreThread(); AppCoreThread();
virtual ~AppCoreThread() throw(); virtual ~AppCoreThread() throw();
@ -519,7 +519,7 @@ protected:
virtual void OnSuspendInThread(); virtual void OnSuspendInThread();
virtual void OnCleanupInThread(); virtual void OnCleanupInThread();
//virtual void VsyncInThread(); //virtual void VsyncInThread();
virtual void DispatchKeyEventToUI( const keyEvent& ev ); virtual void PostVsyncToUI();
virtual void ExecuteTaskInThread(); virtual void ExecuteTaskInThread();
}; };

View File

@ -59,13 +59,6 @@ bool AppCoreThread::Suspend( bool isBlocking )
if( !retval || isBlocking ) if( !retval || isBlocking )
ScopedBusyCursor::SetDefault( Cursor_NotBusy ); 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; return retval;
} }
@ -169,34 +162,10 @@ void AppCoreThread::OnCleanupInThread()
_parent::OnCleanupInThread(); _parent::OnCleanupInThread();
} }
#ifdef __WXGTK__ void AppCoreThread::PostVsyncToUI()
extern int TranslateGDKtoWXK( u32 keysym );
#endif
void AppCoreThread::DispatchKeyEventToUI( const keyEvent& ev )
{ {
m_kevt.SetEventType( ( ev.evt == KEYPRESS ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ); wxCommandEvent evt( pxEVT_LogicalVsync );
const bool isDown = (ev.evt == KEYPRESS); wxGetApp().AddPendingEvent( evt );
#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 );
} }
void AppCoreThread::StateCheckInThread() void AppCoreThread::StateCheckInThread()

View File

@ -288,15 +288,16 @@ bool Pcsx2App::OnInit()
m_StderrRedirHandle = NewPipeRedir(stderr); m_StderrRedirHandle = NewPipeRedir(stderr);
wxLocale::AddCatalogLookupPathPrefix( wxGetCwd() ); wxLocale::AddCatalogLookupPathPrefix( wxGetCwd() );
Connect( pxEVT_ReloadPlugins, wxCommandEventHandler( Pcsx2App::OnReloadPlugins ) ); Connect( pxEVT_ReloadPlugins, wxCommandEventHandler (Pcsx2App::OnReloadPlugins) );
Connect( pxEVT_SysExecute, wxCommandEventHandler( Pcsx2App::OnSysExecute ) ); Connect( pxEVT_SysExecute, wxCommandEventHandler (Pcsx2App::OnSysExecute) );
Connect( pxEVT_LoadPluginsComplete, wxCommandEventHandler( Pcsx2App::OnLoadPluginsComplete ) ); Connect( pxEVT_LoadPluginsComplete, wxCommandEventHandler (Pcsx2App::OnLoadPluginsComplete) );
Connect( pxEVT_CoreThreadStatus, wxCommandEventHandler( Pcsx2App::OnCoreThreadStatus ) ); Connect( pxEVT_CoreThreadStatus, wxCommandEventHandler (Pcsx2App::OnCoreThreadStatus) );
Connect( pxEVT_FreezeThreadFinished, wxCommandEventHandler( Pcsx2App::OnFreezeThreadFinished ) ); Connect( pxEVT_FreezeThreadFinished, wxCommandEventHandler (Pcsx2App::OnFreezeThreadFinished) );
Connect( pxEVT_LogicalVsync, wxCommandEventHandler (Pcsx2App::OnLogicalVsync) );
Connect( pxEVT_Ping, pxPingEventHandler( Pcsx2App::OnPingEvent ) ); Connect( pxEVT_Ping, pxPingEventHandler (Pcsx2App::OnPingEvent) );
Connect( wxEVT_IDLE, wxIdleEventHandler( Pcsx2App::OnIdleEvent ) ); Connect( wxEVT_IDLE, wxIdleEventHandler (Pcsx2App::OnIdleEvent) );
Connect( pxID_PadHandler_Keydown, wxEVT_KEY_DOWN, wxKeyEventHandler( Pcsx2App::OnEmuKeyDown ) ); Connect( pxID_PadHandler_Keydown, wxEVT_KEY_DOWN, wxKeyEventHandler( Pcsx2App::OnEmuKeyDown ) );

View File

@ -39,6 +39,7 @@ DEFINE_EVENT_TYPE( pxEVT_LoadPluginsComplete );
DEFINE_EVENT_TYPE( pxEVT_CoreThreadStatus ); DEFINE_EVENT_TYPE( pxEVT_CoreThreadStatus );
DEFINE_EVENT_TYPE( pxEVT_FreezeThreadFinished ); DEFINE_EVENT_TYPE( pxEVT_FreezeThreadFinished );
DEFINE_EVENT_TYPE( pxEVT_Ping ); DEFINE_EVENT_TYPE( pxEVT_Ping );
DEFINE_EVENT_TYPE( pxEVT_LogicalVsync );
#include "Utilities/EventSource.inl" #include "Utilities/EventSource.inl"
EventSource_ImplementType( IniInterface ); EventSource_ImplementType( IniInterface );
@ -152,21 +153,70 @@ void Pcsx2App::Ping()
sema.WaitNoCancel(); 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 // 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 // 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. // only if *either* the GS or PAD plugins are in legacy mode.
if( m_gsFrame == NULL || (PADopen != NULL) ) if( m_gsFrame == NULL || (PADopen != NULL) )
{ {
evt.SetId( pxID_PadHandler_Keydown ); if( m_kevt.GetEventType() == wxEVT_KEY_DOWN )
wxGetApp().AddPendingEvent( evt ); {
m_kevt.SetId( pxID_PadHandler_Keydown );
wxGetApp().ProcessEvent( m_kevt );
}
} }
else else
{ {
evt.SetId( m_gsFrame->GetViewport()->GetId() ); m_kevt.SetId( m_gsFrame->GetViewport()->GetId() );
m_gsFrame->AddPendingEvent( evt ); 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. // polling of the CoreThread rather than the belated status.
void Pcsx2App::OnCoreThreadStatus( wxCommandEvent& evt ) 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 ); m_evtsrc_CoreThreadStatus.Dispatch( evt );
ScopedBusyCursor::SetDefault( Cursor_NotBusy ); ScopedBusyCursor::SetDefault( Cursor_NotBusy );
CoreThread.RethrowException(); CoreThread.RethrowException();