diff --git a/Source/Core/Common/Src/Plugin.cpp b/Source/Core/Common/Src/Plugin.cpp index 36283be7a6..8cadbdbad6 100644 --- a/Source/Core/Common/Src/Plugin.cpp +++ b/Source/Core/Common/Src/Plugin.cpp @@ -40,6 +40,7 @@ CPlugin::CPlugin(const char* _szName) : valid(false) m_Initialize = NULL; m_Shutdown = NULL; m_DoState = NULL; + m_EmuStateChange = NULL; if (m_hInstLib.Load(_szName)) { @@ -57,6 +58,8 @@ CPlugin::CPlugin(const char* _szName) : valid(false) (m_hInstLib.Get("Shutdown")); m_DoState = reinterpret_cast (m_hInstLib.Get("DoState")); + m_EmuStateChange = reinterpret_cast + (m_hInstLib.Get("EmuStateChange")); // Check if the plugin has all the functions it shold have if (m_GetDllInfo != 0 && @@ -65,7 +68,8 @@ CPlugin::CPlugin(const char* _szName) : valid(false) m_SetDllGlobals != 0 && m_Initialize != 0 && m_Shutdown != 0 && - m_DoState != 0) + m_DoState != 0 && + m_EmuStateChange != 0) valid = true; } @@ -112,6 +116,11 @@ void CPlugin::DoState(unsigned char **ptr, int mode) { m_DoState(ptr, mode); } +void CPlugin::EmuStateChange(PLUGIN_EMUSTATE newState) { + if (m_EmuStateChange != NULL) + m_EmuStateChange(newState); +} + void CPlugin::Initialize(void *init) { if (m_Initialize != NULL) diff --git a/Source/Core/Common/Src/Plugin.h b/Source/Core/Common/Src/Plugin.h index 59f0d08b7f..5d91bb0c49 100644 --- a/Source/Core/Common/Src/Plugin.h +++ b/Source/Core/Common/Src/Plugin.h @@ -31,6 +31,7 @@ namespace Common typedef void (__cdecl * TInitialize)(void *); typedef void (__cdecl * TShutdown)(); typedef void (__cdecl * TDoState)(unsigned char**, int); + typedef void (__cdecl * TEmuStateChange)(PLUGIN_EMUSTATE); class CPlugin { @@ -50,6 +51,7 @@ public: void About(HWND _hwnd); void Debug(HWND _hwnd, bool Show); void DoState(unsigned char **ptr, int mode); + void EmuStateChange(PLUGIN_EMUSTATE newState); void Initialize(void *init); void Shutdown(); @@ -66,6 +68,7 @@ private: TInitialize m_Initialize; TShutdown m_Shutdown; TDoState m_DoState; + TEmuStateChange m_EmuStateChange; }; } // Namespace diff --git a/Source/Core/Core/Src/Core.cpp b/Source/Core/Core/Src/Core.cpp index 3a0bac0d6d..ad9f91390b 100644 --- a/Source/Core/Core/Src/Core.cpp +++ b/Source/Core/Core/Src/Core.cpp @@ -196,6 +196,7 @@ void Stop() // - Hammertime! { const SCoreStartupParameter& _CoreParameter = SConfig::GetInstance().m_LocalCoreStartupParameter; g_bStopping = true; + CPluginManager::GetInstance().EmuStateChange(PLUGIN_EMUSTATE_STOP); WARN_LOG(CONSOLE, "Stop [Main Thread]\t\t---- Shutting down ----"); @@ -531,10 +532,12 @@ void SetState(EState _State) case CORE_PAUSE: CCPU::EnableStepping(true); // Break CPluginManager::GetInstance().GetDSP()->DSP_ClearAudioBuffer(); + CPluginManager::GetInstance().EmuStateChange(PLUGIN_EMUSTATE_PAUSE); break; case CORE_RUN: CCPU::EnableStepping(false); CPluginManager::GetInstance().GetDSP()->DSP_ClearAudioBuffer(); + CPluginManager::GetInstance().EmuStateChange(PLUGIN_EMUSTATE_PLAY); break; default: PanicAlert("Invalid state"); diff --git a/Source/Core/Core/Src/PluginManager.cpp b/Source/Core/Core/Src/PluginManager.cpp index 8bbc72b226..35a5e5e930 100644 --- a/Source/Core/Core/Src/PluginManager.cpp +++ b/Source/Core/Core/Src/PluginManager.cpp @@ -462,6 +462,17 @@ void CPluginManager::FreeWiimote(u32 Wiimote) } } +void CPluginManager::EmuStateChange(PLUGIN_EMUSTATE newState) +{ + GetVideo()->EmuStateChange(newState); + GetDSP()->EmuStateChange(newState); + //TODO: OpenConfig below only uses GetXxx(0) aswell + // Would we need to call all plugins? + // If yes, how would one check if the plugin was not + // just created by GetXxx(idx) because there was none? + GetPad(0)->EmuStateChange(newState); + GetWiimote(0)->EmuStateChange(newState); +} diff --git a/Source/Core/Core/Src/PluginManager.h b/Source/Core/Core/Src/PluginManager.h index 1d2fac10c2..de478c6b60 100644 --- a/Source/Core/Core/Src/PluginManager.h +++ b/Source/Core/Core/Src/PluginManager.h @@ -57,6 +57,8 @@ public: void FreePad(u32 Pad); void FreeWiimote(u32 Wiimote); + void EmuStateChange(PLUGIN_EMUSTATE newState); + bool InitPlugins(); void ShutdownPlugins(); void ShutdownVideoPlugin(); diff --git a/Source/PluginSpecs/PluginSpecs.h b/Source/PluginSpecs/PluginSpecs.h index 1ab57a19d6..6f486816c1 100644 --- a/Source/PluginSpecs/PluginSpecs.h +++ b/Source/PluginSpecs/PluginSpecs.h @@ -83,6 +83,12 @@ enum PLUGIN_TYPE { #define STATE_MODE_WRITE 2 #define STATE_MODE_MEASURE 3 +// used for notification on emulation state +enum PLUGIN_EMUSTATE { + PLUGIN_EMUSTATE_PLAY = 1, + PLUGIN_EMUSTATE_PAUSE, + PLUGIN_EMUSTATE_STOP, +}; // Export structs // ------------ @@ -169,6 +175,13 @@ EXPORT void CALL Shutdown(void); // EXPORT void CALL DoState(unsigned char **ptr, int mode); +// ___________________________________________________________________________ +// Function: EmuStateChange +// Purpose: Notifies the plugin of a change in emulation state +// input: newState +// output: none +// +EXPORT void CALL EmuStateChange(PLUGIN_EMUSTATE newState); #if defined(__cplusplus) diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/main.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/main.cpp index edc9aee5b6..f6e2679fb7 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Src/main.cpp +++ b/Source/Plugins/Plugin_DSP_HLE/Src/main.cpp @@ -243,6 +243,9 @@ void DoState(unsigned char **ptr, int mode) CDSPHandler::GetInstance().GetUCode()->DoState(p); } +void EmuStateChange(PLUGIN_EMUSTATE newState) +{ +} // Mailbox fuctions unsigned short DSP_ReadMailboxHigh(bool _CPUMailbox) diff --git a/Source/Plugins/Plugin_DSP_LLE/Src/main.cpp b/Source/Plugins/Plugin_DSP_LLE/Src/main.cpp index e6b62c46a3..0aaa4a0b35 100644 --- a/Source/Plugins/Plugin_DSP_LLE/Src/main.cpp +++ b/Source/Plugins/Plugin_DSP_LLE/Src/main.cpp @@ -170,6 +170,10 @@ void DoState(unsigned char **ptr, int mode) p.Do(g_InitMixer); } +void EmuStateChange(PLUGIN_EMUSTATE newState) +{ +} + void DllDebugger(HWND _hParent, bool Show) { #if defined(HAVE_WX) && HAVE_WX diff --git a/Source/Plugins/Plugin_PadSimple/Src/PadSimple.cpp b/Source/Plugins/Plugin_PadSimple/Src/PadSimple.cpp index c18e7da6d8..0ba14dbf62 100644 --- a/Source/Plugins/Plugin_PadSimple/Src/PadSimple.cpp +++ b/Source/Plugins/Plugin_PadSimple/Src/PadSimple.cpp @@ -700,6 +700,10 @@ void DoState(unsigned char **ptr, int mode) #endif } +void EmuStateChange(PLUGIN_EMUSTATE newState) +{ +} + void Shutdown() { // Save the recording and reset the counter diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp b/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp index 2d3a78aa99..401b1814a8 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp @@ -121,8 +121,8 @@ void InitPP(int adapter, int f, int aa_mode, D3DPRESENT_PARAMETERS *pp) pp->SwapEffect = D3DSWAPEFFECT_DISCARD; pp->Windowed = FALSE; //if(g_Config.bHideCursor) - if(!g_Config.RenderToMainframe) - ShowCursor(FALSE); + //if(!g_Config.RenderToMainframe) + ShowCursor(FALSE); } else { diff --git a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp index 533d6bdbe8..654ed86b94 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp @@ -310,6 +310,10 @@ void DoState(unsigned char **ptr, int mode) { VideoCommon_DoState(p); } +void EmuStateChange(PLUGIN_EMUSTATE newState) +{ +} + void Video_EnterLoop() { Fifo_EnterLoop(g_VideoInitialize); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp index f32ceff9e6..df386efdbc 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp @@ -377,6 +377,10 @@ void DoState(unsigned char **ptr, int mode) { } } +void EmuStateChange(PLUGIN_EMUSTATE newState) +{ +} + // This is called after Video_Initialize() from the Core void Video_Prepare(void) { diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/main.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/main.cpp index e3378377dc..c832c6270b 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/main.cpp @@ -92,6 +92,10 @@ void DoState(unsigned char **ptr, int mode) { } +void EmuStateChange(PLUGIN_EMUSTATE newState) +{ +} + void Shutdown(void) { } diff --git a/Source/Plugins/Plugin_Wiimote/Src/ConfigBasicDlg.cpp b/Source/Plugins/Plugin_Wiimote/Src/ConfigBasicDlg.cpp index 04cd94a8ae..68c1e8fd5a 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/ConfigBasicDlg.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/ConfigBasicDlg.cpp @@ -112,7 +112,7 @@ void WiimoteBasicConfigDialog::ButtonClick(wxCommandEvent& event) break; #ifdef WIN32 case ID_BUTTONPAIRUP: - if(!g_EmulatorRunning) { + if (g_EmulatorState != PLUGIN_EMUSTATE_PLAY) { m_ButtonPairUp->Enable(false); if (WiiMoteReal::WiimotePairUp() > 0) { //Only temporay solution TODO: 2nd step: threaded. // sleep would be required (but not best way to solve that cuz 3000ms~ would be needed, which is not convenient),cuz BT device is not ready yet when calling DoRefreshReal() @@ -151,6 +151,7 @@ void WiimoteBasicConfigDialog::CreateGUIControls() // Basic Settings m_InputSource[i] = new wxChoice(m_Controller[i], IDC_INPUT_SOURCE, wxDefaultPosition, wxDefaultSize, arrayStringFor_source, 0, wxDefaultValidator); + m_InputSource[i]->SetToolTip(wxT("This can only be changed when the emulator is paused or stopped.")); // Emulated Wiimote m_SidewaysWiimote[i] = new wxCheckBox(m_Controller[i], IDC_SIDEWAYSWIIMOTE, wxT("Sideways Wiimote")); @@ -164,10 +165,10 @@ void WiimoteBasicConfigDialog::CreateGUIControls() m_Extension[i] = new wxChoice(m_Controller[i], IDC_EXTCONNECTED, wxDefaultPosition, wxDefaultSize, arrayStringFor_extension, 0, wxDefaultValidator); m_ConnectRealWiimote[i] = new wxCheckBox(m_Controller[i], IDC_CONNECT_REAL, wxT("Connect Real Wiimote")); - m_ConnectRealWiimote[i]->SetToolTip(wxT("Connected to the Real WiiMote(s). This can not be changed during gameplay.")); + m_ConnectRealWiimote[i]->SetToolTip(wxT("Connected to the Real WiiMote(s).\nThis can only be changed when the emulator is paused or stopped.")); m_FoundWiimote[i] = new wxStaticText(m_Controller[i], ID_FOUND_REAL, wxT("Found 0 WiiMotes")); m_RefreshRealWiiMote[i] = new wxButton(m_Controller[i], ID_REFRESH_REAL, wxT("Refresh Real WiiMotes")); - m_RefreshRealWiiMote[i]->SetToolTip(wxT("Reconnect to all Real WiiMotes. This is useful if you recently connected another one.")); + m_RefreshRealWiiMote[i]->SetToolTip(wxT("Reconnect to all Real WiiMotes.\nThis is useful if you recently connected another one.\nThis can only be done when the emulator is paused or stopped.")); //IR Pointer m_TextScreenWidth[i] = new wxStaticText(m_Controller[i], wxID_ANY, wxT("Width: 000")); @@ -301,7 +302,7 @@ void WiimoteBasicConfigDialog::UpdateOnce(wxTimerEvent& event) void WiimoteBasicConfigDialog::DoConnectReal() { - if(g_Config.bConnectRealWiimote) + if (g_Config.bConnectRealWiimote) { if (!g_RealWiiMoteInitialized) { @@ -320,15 +321,14 @@ void WiimoteBasicConfigDialog::DoConnectReal() void WiimoteBasicConfigDialog::DoRefreshReal() { - if(!g_Config.bConnectRealWiimote || g_EmulatorRunning) - return; - if (g_RealWiiMoteInitialized) - WiiMoteReal::Shutdown(); - if (!g_RealWiiMoteInitialized) + if (g_Config.bConnectRealWiimote && g_EmulatorState != PLUGIN_EMUSTATE_PLAY) { - WiiMoteReal::Initialize(); - UpdateGUI();; + if (g_RealWiiMoteInitialized) + WiiMoteReal::Shutdown(); + if (!g_RealWiiMoteInitialized) + WiiMoteReal::Initialize(); } + UpdateGUI(); } void WiimoteBasicConfigDialog::DoUseReal() @@ -351,7 +351,7 @@ void WiimoteBasicConfigDialog::DoUseReal() DEBUG_LOG(WIIMOTE, "DoUseReal() Connect extension: %i", !UsingExtension); DoExtensionConnectedDisconnected(UsingExtension ? 1 : 0); - if (g_EmulatorRunning) + if (g_EmulatorState == PLUGIN_EMUSTATE_PLAY) { // Disable the checkbox for a moment SetCursor(wxCursor(wxCURSOR_WAIT)); @@ -400,28 +400,30 @@ void WiimoteBasicConfigDialog::GeneralSettingsChanged(wxCommandEvent& event) switch (event.GetId()) { case IDC_CONNECT_REAL: - if(!g_EmulatorRunning) + // If the config dialog was open when the user click on Play/Pause, the GUI was not updated, so this could crash everything! + if (g_EmulatorState != PLUGIN_EMUSTATE_PLAY) { g_Config.bConnectRealWiimote = m_ConnectRealWiimote[m_Page]->IsChecked(); DoConnectReal(); } break; case IDC_INPUT_SOURCE: - if (m_InputSource[m_Page]->GetSelection() == 2) + // If the config dialog was open when the user click on Play/Pause, the GUI was not updated, so this could crash everything! + if (g_EmulatorState == PLUGIN_EMUSTATE_PLAY) { - if(!g_EmulatorRunning) + PanicAlert("This can only be changed when the emulator is paused or stopped!"); + WiiMoteEmu::WiiMapping[m_Page].Source = 0; + } + else + { + if (m_InputSource[m_Page]->GetSelection() == 2) { WiiMoteEmu::WiiMapping[m_Page].Source = 2; DoUseReal(); } else - { - PanicAlert("You can't change to Real WiiMote when a game is running!"); - WiiMoteEmu::WiiMapping[m_Page].Source = 0; - } + WiiMoteEmu::WiiMapping[m_Page].Source = m_InputSource[m_Page]->GetSelection(); } - else - WiiMoteEmu::WiiMapping[m_Page].Source = m_InputSource[m_Page]->GetSelection(); break; case IDC_SIDEWAYSWIIMOTE: WiiMoteEmu::WiiMapping[m_Page].bSideways = m_SidewaysWiimote[m_Page]->IsChecked(); @@ -437,7 +439,7 @@ void WiimoteBasicConfigDialog::GeneralSettingsChanged(wxCommandEvent& event) DoExtensionConnectedDisconnected(WiiMoteEmu::EXT_NONE); // It doesn't seem to be needed but shouldn't it at least take 25 ms to // reconnect an extension after we disconnected another? - if(g_EmulatorRunning) + if (g_EmulatorRunning) SLEEP(25); // Update status WiiMoteEmu::WiiMapping[m_Page].iExtensionConnected = m_Extension[m_Page]->GetSelection(); @@ -477,12 +479,13 @@ void WiimoteBasicConfigDialog::UpdateGUI() mean that the wiimote must be sent the current reporting mode and the channel ID after it has been initialized. Functions for that are basically already in place so these two options could possibly be simplified to one option. */ + m_InputSource[m_Page]->Enable(g_EmulatorState != PLUGIN_EMUSTATE_PLAY); m_ConnectRealWiimote[m_Page]->SetValue(g_Config.bConnectRealWiimote); - m_ConnectRealWiimote[m_Page]->Enable(!g_EmulatorRunning); - m_RefreshRealWiiMote[m_Page]->Enable(!g_EmulatorRunning && g_Config.bConnectRealWiimote); - m_ButtonPairUp->Enable(!g_EmulatorRunning); + m_ConnectRealWiimote[m_Page]->Enable(g_EmulatorState != PLUGIN_EMUSTATE_PLAY); + m_RefreshRealWiiMote[m_Page]->Enable(g_EmulatorState != PLUGIN_EMUSTATE_PLAY && g_Config.bConnectRealWiimote); + m_ButtonPairUp->Enable(g_EmulatorState != PLUGIN_EMUSTATE_PLAY); wxString Found; - if(g_Config.bConnectRealWiimote) + if (g_Config.bConnectRealWiimote) Found.Printf(wxT("Connected to %i Real WiiMote(s)"), WiiMoteReal::g_NumberOfWiiMotes); else Found.Printf(wxT("Not connected to Real WiiMotes")); diff --git a/Source/Plugins/Plugin_Wiimote/Src/main.cpp b/Source/Plugins/Plugin_Wiimote/Src/main.cpp index 542d757510..848f5289d8 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/main.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/main.cpp @@ -78,7 +78,9 @@ int g_UpdateWriteScreen = 0; std::vector g_UpdateTimeList (5, 0); // Movement recording -std::vector VRecording(RECORDING_ROWS); +std::vector VRecording(RECORDING_ROWS); + +PLUGIN_EMUSTATE g_EmulatorState = PLUGIN_EMUSTATE_STOP; // Standard crap to make wxWidgets happy #ifdef _WIN32 @@ -185,6 +187,8 @@ void DllConfig(HWND _hParent) m_BasicConfigFrame = new WiimoteBasicConfigDialog(GetParentedWxWindow(_hParent)); else if (!m_BasicConfigFrame->GetParent()->IsShown()) m_BasicConfigFrame->Close(true); + // Update the GUI (because it was not updated when it had been already open before...) + m_BasicConfigFrame->UpdateGUI(); // Only allow one open at a time if (!m_BasicConfigFrame->IsShown()) { @@ -294,7 +298,10 @@ void DoState(unsigned char **ptr, int mode) return; } - +void EmuStateChange(PLUGIN_EMUSTATE newState) +{ + g_EmulatorState = newState; +} /* This function produce Wiimote Input (reports from the Wiimote) in response to Output from the Wii. It's called from WII_IPC_HLE_WiiMote.cpp. diff --git a/Source/Plugins/Plugin_Wiimote/Src/main.h b/Source/Plugins/Plugin_Wiimote/Src/main.h index 86fe6dca00..133fba289c 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/main.h +++ b/Source/Plugins/Plugin_Wiimote/Src/main.h @@ -22,6 +22,7 @@ #include #include "CommonTypes.h" +#include "pluginspecs_wiimote.h" #if defined(HAVE_X11) && HAVE_X11 #include #include @@ -89,6 +90,9 @@ struct SRecordingAll // Movement recording extern std::vector VRecording; + + extern PLUGIN_EMUSTATE g_EmulatorState; + #endif diff --git a/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.cpp b/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.cpp index 857159c0df..67231bed75 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.cpp @@ -315,7 +315,7 @@ int Initialize() g_RealWiiMotePresent = false; g_RealWiiMoteAllocated = false; - if(g_Config.bConnectRealWiimote) + if (g_Config.bConnectRealWiimote) { // Call Wiiuse.dll g_WiiMotesFromWiiUse = wiiuse_init(MAX_WIIMOTES); @@ -356,7 +356,7 @@ int Initialize() #endif // If we are connecting from the config window without a game running we set the LEDs - if (!g_EmulatorRunning && g_RealWiiMotePresent) + if (g_EmulatorState != PLUGIN_EMUSTATE_PLAY && g_RealWiiMotePresent) FlashLights(true); // Create a new thread and start listening for Wiimote data @@ -389,7 +389,7 @@ int Initialize() // Allocate each Real WiiMote found to a WiiMote slot with Source set to "WiiMote Real" void Allocate() { - if(!g_RealWiiMoteInitialized) + if (!g_RealWiiMoteInitialized) Initialize(); // Clear the wiimote classes @@ -419,9 +419,8 @@ void Allocate() } } // If we found a valid slot for this WiiMote... - if(current_number < MAX_WIIMOTES) + if (current_number < MAX_WIIMOTES) { - g_WiiMotes[current_number] = new CWiiMote(current_number, g_WiiMotesFromWiiUse[i]); g_WiimoteInUse[current_number] = true; switch (current_number) @@ -490,7 +489,7 @@ void Shutdown(void) } // Flash flights - if (!g_EmulatorRunning && g_RealWiiMotePresent) + if (g_EmulatorState != PLUGIN_EMUSTATE_PLAY && g_RealWiiMotePresent) FlashLights(false); // Clean up wiiuse diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp b/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp index f89c6a5fbb..2327fc3524 100644 --- a/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp +++ b/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp @@ -294,6 +294,9 @@ void DoState(unsigned char **ptr, int mode) #endif } +void EmuStateChange(PLUGIN_EMUSTATE newState) +{ +} // Set PAD status // --------------