diff --git a/Source/Core/Core/Src/BootManager.cpp b/Source/Core/Core/Src/BootManager.cpp index b867052381..1e9e612fe0 100644 --- a/Source/Core/Core/Src/BootManager.cpp +++ b/Source/Core/Core/Src/BootManager.cpp @@ -55,7 +55,7 @@ namespace BootManager struct ConfigCache { bool valid, bCPUThread, bSkipIdle, bEnableFPRF, bMMU, bDCBZOFF, - bVBeam, bFastDiscSpeed, bMergeBlocks, bDSPHLE, bDisableWiimoteSpeaker, bHLE_BS2; + bVBeam, bFastDiscSpeed, bMergeBlocks, bDSPHLE, bHLE_BS2; int iTLBHack, iCPUCore; std::string strBackend; }; @@ -98,7 +98,6 @@ bool BootCore(const std::string& _rFilename) config_cache.bFastDiscSpeed = StartUp.bFastDiscSpeed; config_cache.bMergeBlocks = StartUp.bMergeBlocks; config_cache.bDSPHLE = StartUp.bDSPHLE; - config_cache.bDisableWiimoteSpeaker = StartUp.bDisableWiimoteSpeaker; config_cache.strBackend = StartUp.m_strVideoBackend; config_cache.bHLE_BS2 = StartUp.bHLE_BS2; @@ -113,7 +112,6 @@ bool BootCore(const std::string& _rFilename) game_ini.Get("Core", "FastDiscSpeed", &StartUp.bFastDiscSpeed, StartUp.bFastDiscSpeed); game_ini.Get("Core", "BlockMerging", &StartUp.bMergeBlocks, StartUp.bMergeBlocks); game_ini.Get("Core", "DSPHLE", &StartUp.bDSPHLE, StartUp.bDSPHLE); - game_ini.Get("Wii", "DisableWiimoteSpeaker",&StartUp.bDisableWiimoteSpeaker, StartUp.bDisableWiimoteSpeaker); game_ini.Get("Core", "GFXBackend", &StartUp.m_strVideoBackend, StartUp.m_strVideoBackend.c_str()); game_ini.Get("Core", "CPUCore", &StartUp.iCPUCore, StartUp.iCPUCore); game_ini.Get("Core", "HLE_BS2", &StartUp.bHLE_BS2, StartUp.bHLE_BS2); @@ -173,7 +171,6 @@ void Stop() StartUp.bFastDiscSpeed = config_cache.bFastDiscSpeed; StartUp.bMergeBlocks = config_cache.bMergeBlocks; StartUp.bDSPHLE = config_cache.bDSPHLE; - StartUp.bDisableWiimoteSpeaker = config_cache.bDisableWiimoteSpeaker; StartUp.m_strVideoBackend = config_cache.strBackend; VideoBackend::ActivateBackend(StartUp.m_strVideoBackend); StartUp.bHLE_BS2 = config_cache.bHLE_BS2; diff --git a/Source/Core/Core/Src/CoreParameter.cpp b/Source/Core/Core/Src/CoreParameter.cpp index 7f019bcf59..a7a44be5ea 100644 --- a/Source/Core/Core/Src/CoreParameter.cpp +++ b/Source/Core/Core/Src/CoreParameter.cpp @@ -51,8 +51,8 @@ SCoreStartupParameter::SCoreStartupParameter() bRunCompareServer(false), bRunCompareClient(false), bMMU(false), bDCBZOFF(false), iTLBHack(0), bVBeam(false), bFastDiscSpeed(false), - SelectedLanguage(0), bWii(false), bDisableWiimoteSpeaker(false), - bConfirmStop(false), bHideCursor(false), + SelectedLanguage(0), bWii(false), + bConfirmStop(false), bHideCursor(false), bAutoHideCursor(false), bUsePanicHandlers(true), bOnScreenDisplayMessages(true), iRenderWindowXPos(-1), iRenderWindowYPos(-1), iRenderWindowWidth(640), iRenderWindowHeight(480), @@ -99,8 +99,6 @@ void SCoreStartupParameter::LoadDefaults() bJITPairedOff = false; bJITSystemRegistersOff = false; - bDisableWiimoteSpeaker = false; - m_strName = "NONE"; m_strUniqueID = "00000000"; } diff --git a/Source/Core/Core/Src/CoreParameter.h b/Source/Core/Core/Src/CoreParameter.h index e2e5eb6f1b..55d20b7b1b 100644 --- a/Source/Core/Core/Src/CoreParameter.h +++ b/Source/Core/Core/Src/CoreParameter.h @@ -121,7 +121,6 @@ struct SCoreStartupParameter int SelectedLanguage; bool bWii; - bool bDisableWiimoteSpeaker; // Interface settings bool bConfirmStop, bHideCursor, bAutoHideCursor, bUsePanicHandlers, bOnScreenDisplayMessages; diff --git a/Source/Core/Core/Src/HW/SystemTimers.cpp b/Source/Core/Core/Src/HW/SystemTimers.cpp index b9f9fe0107..318b1213af 100644 --- a/Source/Core/Core/Src/HW/SystemTimers.cpp +++ b/Source/Core/Core/Src/HW/SystemTimers.cpp @@ -248,15 +248,13 @@ void Init() DSP_PERIOD = (int)(GetTicksPerSecond() * 0.003f); // AyuanX: TO BE TWEAKED - // Now the 1500 is a pure assumption + // Now the 1500 is (was) a pure assumption // We need to figure out the real frequency though - // FIXME: does Wiimote Speaker support really require a different interval? (issue 4608) - const int interval = SConfig::GetInstance().m_LocalCoreStartupParameter. - bDisableWiimoteSpeaker ? 15000 : 4000; + const int freq = 8000; const int fields = SConfig::GetInstance().m_LocalCoreStartupParameter. bVBeam ? 2 : 1; - IPC_HLE_PERIOD = GetTicksPerSecond() / (interval * fields); + IPC_HLE_PERIOD = GetTicksPerSecond() / (freq * fields); } else { diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp index bb939f4a06..4aee5cb045 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp @@ -58,6 +58,8 @@ They will also generate a true or false return for UpdateInterrupts() in WII_IPC #include "../HW/WII_IPC.h" #include "../Debugger/Debugger_SymbolMap.h" #include "../PowerPC/PowerPC.h" +#include "../HW/SystemTimers.h" +#include "CoreTiming.h" namespace WII_IPC_HLE_Interface @@ -80,8 +82,17 @@ typedef std::deque ipc_msg_queue; static ipc_msg_queue request_queue; // ppc -> arm static ipc_msg_queue reply_queue; // arm -> ppc +static int enque_reply; + +void EnqueReplyCallback(u64 userdata, int) +{ + reply_queue.push_back(userdata); +} + void Init() { + enque_reply = CoreTiming::RegisterEvent("IPCReply", EnqueReplyCallback); + _dbg_assert_msg_(WII_IPC_HLE, g_DeviceMap.empty(), "DeviceMap isnt empty on init"); CWII_IPC_HLE_Device_es::m_ContentFile = ""; u32 i; @@ -504,7 +515,7 @@ void ExecuteCommand(u32 _Address) if (CmdSuccess) { // Generate a reply to the IPC command - EnqReply(_Address); + EnqReply(_Address, SystemTimers::GetTicksPerSecond() / 150); } else { @@ -526,9 +537,9 @@ void EnqRequest(u32 _Address) } // Called when IOS module has some reply -void EnqReply(u32 _Address) +void EnqReply(u32 _Address, int cycles_in_future) { - reply_queue.push_back(_Address); + CoreTiming::ScheduleEvent(cycles_in_future, enque_reply, _Address); } // This is called every IPC_HLE_PERIOD from SystemTimers.cpp diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.h index 2e056b5bec..65244836cc 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.h @@ -62,7 +62,7 @@ void UpdateDevices(); void ExecuteCommand(u32 _Address); void EnqRequest(u32 _Address); -void EnqReply(u32 _Address); +void EnqReply(u32 _Address, int cycles_in_future = 0); enum ECommandType { diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp index 33474af8c7..e3c0247b46 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp @@ -336,23 +336,23 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendToDevice(u16 _ConnectionHandle, u8 pWiiMote->ExecuteL2capCmd(_pData, _Size); } -// Here we send ACL packets to CPU. They will consist of header + data. -// The header is for example 07 00 41 00 which means size 0x0007 and channel 0x0041. -// --------------------------------------------------- -// AyuanX: Basically, our WII_IPC_HLE is efficient enough to send the packet immediately -// rather than enqueue it to some other memory -// But...the only exception comes from the Wiimote_Plugin void CWII_IPC_HLE_Device_usb_oh1_57e_305::IncDataPacket(u16 _ConnectionHandle) { m_PacketCount[_ConnectionHandle & 0xff]++; + // I don't think this makes sense or should be necessary + // m_PacketCount refers to "completed" packets and is not related to some buffer size, yes? +#if 0 if (m_PacketCount[_ConnectionHandle & 0xff] > (unsigned int)m_acl_pkts_num) { DEBUG_LOG(WII_IPC_WIIMOTE, "ACL buffer overflow"); m_PacketCount[_ConnectionHandle & 0xff] = m_acl_pkts_num; } +#endif } +// Here we send ACL packets to CPU. They will consist of header + data. +// The header is for example 07 00 41 00 which means size 0x0007 and channel 0x0041. void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendACLPacket(u16 _ConnectionHandle, u8* _pData, u32 _Size) { DEBUG_LOG(WII_IPC_WIIMOTE, "ACL packet from %x ready to send to stack...", _ConnectionHandle); @@ -374,8 +374,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendACLPacket(u16 _ConnectionHandle, u } else { - DEBUG_LOG(WII_IPC_WIIMOTE, "ACL endpoint not currently valid, " - "queueing(%d)...", m_acl_pool.GetWritePos()); + DEBUG_LOG(WII_IPC_WIIMOTE, "ACL endpoint not currently valid, queueing..."); m_acl_pool.Store(_pData, _Size, _ConnectionHandle); } } @@ -486,18 +485,8 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update() } } - // The Real Wiimote sends report every ~6.66ms (150 Hz). - // However, we don't actually reach here at dependable intervals, so we - // instead just timeslice in such a way that makes the stack think we have - // perfect "radio quality" (WPADGetRadioSensitivity) and yet still have some - // idle time. - // Somehow, Dolphin's Wiimote Speaker support requires using an update interval - // of 5ms (200 Hz) for its output to work. This increased frequency tends to - // fill the ACL queue (even) quicker than it can be processed by Dolphin, - // especially during simultaneous requests involving many (emulated) Wiimotes... - // Thus, we only use that interval when the option is enabled. See issue 4608. - const u64 interval = SystemTimers::GetTicksPerSecond() / (SConfig::GetInstance(). - m_LocalCoreStartupParameter.bDisableWiimoteSpeaker ? 150 : 200); + // The Real Wiimote sends report every ~5ms (200 Hz). + const u64 interval = SystemTimers::GetTicksPerSecond() / 200; const u64 each_wiimote_interval = interval / m_WiiMotes.size(); const u64 now = CoreTiming::GetTicks(); @@ -518,25 +507,47 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update() return packet_transferred; } +void CWII_IPC_HLE_Device_usb_oh1_57e_305::ACLPool::Store(const u8* data, const u16 size, const u16 conn_handle) +{ + if (m_queue.size() >= 100) + { + // Many simultaneous exchanges of ACL packets tend to cause the queue to fill up. + ERROR_LOG(WII_IPC_WIIMOTE, "ACL queue size reached 100 - current packet will be dropped!"); + return; + } + + _dbg_assert_msg_(WII_IPC_WIIMOTE, + size < m_acl_pkt_size, "acl packet too large for pool"); + + m_queue.push_back(Packet()); + auto& packet = m_queue.back(); + + std::copy(data, data + size, packet.data); + packet.size = size; + packet.conn_handle = conn_handle; +} + void CWII_IPC_HLE_Device_usb_oh1_57e_305::ACLPool::WriteToEndpoint(CtrlBuffer& endpoint) { - const u8 *data = m_pool + m_acl_pkt_size * m_read_ptr; - const u16 size = m_info[m_read_ptr].size; - const u16 conn_handle = m_info[m_read_ptr].conn_handle; + auto& packet = m_queue.front(); + + const u8* const data = packet.data; + const u16 size = packet.size; + const u16 conn_handle = packet.conn_handle; DEBUG_LOG(WII_IPC_WIIMOTE, "ACL packet being written from " - "queue(%d) to %08x", GetReadPos(), endpoint.m_address); + "queue to %08x", endpoint.m_address); hci_acldata_hdr_t* pHeader = (hci_acldata_hdr_t*)Memory::GetPointer(endpoint.m_buffer); pHeader->con_handle = HCI_MK_CON_HANDLE(conn_handle, HCI_PACKET_START, HCI_POINT2POINT); pHeader->length = size; // Write the packet to the buffer - memcpy((u8*)pHeader + sizeof(hci_acldata_hdr_t), data, pHeader->length); + std::copy(data, data + size, (u8*)pHeader + sizeof(hci_acldata_hdr_t)); endpoint.SetRetVal(sizeof(hci_acldata_hdr_t) + size); - m_read_ptr = (m_read_ptr + 1) % m_acl_pkts_num; + m_queue.pop_front(); WII_IPC_HLE_Interface::EnqReply(endpoint.m_address); endpoint.Invalidate(); diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.h index 61c439a7ec..eb091b1ff9 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.h @@ -17,9 +17,11 @@ #pragma once -#include "hci.h" +#include #include #include + +#include "hci.h" #include "WII_IPC_HLE.h" #include "WII_IPC_HLE_Device.h" #include "WII_IPC_HLE_WiiMote.h" @@ -168,70 +170,33 @@ private: class ACLPool { - u8 m_pool[m_acl_pkt_size * m_acl_pkts_num]; - int m_read_ptr; - int m_write_ptr; - - struct + struct Packet { + u8 data[m_acl_pkt_size]; u16 size; u16 conn_handle; - } m_info[m_acl_pkts_num]; + }; + + std::deque m_queue; public: ACLPool() - : m_read_ptr(0) - , m_write_ptr(0) + : m_queue() {} - void Store(const u8* data, const u16 size, const u16 conn_handle) - { - _dbg_assert_msg_(WII_IPC_WIIMOTE, - size < m_acl_pkt_size, "acl packet too large for pool"); - - const int next_write_ptr = (m_write_ptr + 1) % m_acl_pkts_num; - if (next_write_ptr == m_read_ptr) - { - // Many simultaneous exchanges of ACL packets tend to cause the - // 10-packet limit to be exceeded. Typically, this occurs when - // many emulated Wiimotes are requesting connections at once. - // See issue 4608 for more info. - ERROR_LOG(WII_IPC_WIIMOTE, "ACL queue is full - current packet will be " - "dropped! (m_write_ptr(%d) was about to overlap m_read_ptr(%d))", - m_write_ptr, m_read_ptr); - return; - } - - memcpy(m_pool + m_acl_pkt_size * m_write_ptr, data, size); - m_info[m_write_ptr].size = size; - m_info[m_write_ptr].conn_handle = conn_handle; - m_write_ptr = next_write_ptr; - } + void Store(const u8* data, const u16 size, const u16 conn_handle); void WriteToEndpoint(CtrlBuffer& endpoint); bool IsEmpty() const { - return m_write_ptr == m_read_ptr; - } - - int GetWritePos() const - { - return m_write_ptr; - } - - int GetReadPos() const - { - return m_read_ptr; + return m_queue.empty(); } // For SaveStates void DoState(PointerWrap &p) { - p.Do(m_write_ptr); - p.Do(m_read_ptr); - p.DoArray((u8 *)m_pool, sizeof(m_pool)); - p.DoArray((u8 *)m_info, sizeof(m_info)); + p.Do(m_queue); } } m_acl_pool; diff --git a/Source/Core/Core/Src/State.cpp b/Source/Core/Core/Src/State.cpp index a532ace217..a9d56cc16a 100644 --- a/Source/Core/Core/Src/State.cpp +++ b/Source/Core/Core/Src/State.cpp @@ -70,8 +70,8 @@ static Common::Event g_compressAndDumpStateSyncEvent; static std::thread g_save_thread; -// Don't forget to increase this after doing changes on the savestate system -static const u32 STATE_VERSION = 10; +// Don't forget to increase this after doing changes on the savestate system +static const u32 STATE_VERSION = 11; struct StateHeader { diff --git a/Source/Core/DolphinWX/Src/ISOProperties.cpp b/Source/Core/DolphinWX/Src/ISOProperties.cpp index 6a673b95d1..c44aad5d5b 100644 --- a/Source/Core/DolphinWX/Src/ISOProperties.cpp +++ b/Source/Core/DolphinWX/Src/ISOProperties.cpp @@ -328,8 +328,6 @@ void CISOProperties::CreateGUIControls(bool IsWad) // Wii Console EnableWideScreen = new wxCheckBox(m_GameConfig, ID_ENABLEWIDESCREEN, _("Enable WideScreen"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator); - DisableWiimoteSpeaker = new wxCheckBox(m_GameConfig, ID_DISABLEWIIMOTESPEAKER, _("Alternate Wiimote Timing"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator); - DisableWiimoteSpeaker->SetToolTip(_("Mutes the Wiimote speaker. Fixes random disconnections on real wiimotes. No effect on emulated wiimotes.")); // Video UseBBox = new wxCheckBox(m_GameConfig, ID_USE_BBOX, _("Enable Bounding Box Calculation"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER); @@ -377,10 +375,8 @@ void CISOProperties::CreateGUIControls(bool IsWad) { sbWiiOverrides->ShowItems(false); EnableWideScreen->Hide(); - DisableWiimoteSpeaker->Hide(); } sbWiiOverrides->Add(EnableWideScreen, 0, wxLEFT, 5); - sbWiiOverrides->Add(DisableWiimoteSpeaker, 0, wxLEFT, 5); wxStaticBoxSizer * const sbVideoOverrides = new wxStaticBoxSizer(wxVERTICAL, m_GameConfig, _("Video")); @@ -966,11 +962,6 @@ void CISOProperties::LoadGameConfig() else EnableWideScreen->Set3StateValue(wxCHK_UNDETERMINED); - if (GameIni.Get("Wii", "DisableWiimoteSpeaker", &bTemp)) - DisableWiimoteSpeaker->Set3StateValue((wxCheckBoxState)bTemp); - else - DisableWiimoteSpeaker->Set3StateValue(wxCHK_UNDETERMINED); - if (GameIni.Get("Video", "UseBBox", &bTemp)) UseBBox->Set3StateValue((wxCheckBoxState)bTemp); else @@ -1059,11 +1050,6 @@ bool CISOProperties::SaveGameConfig() else GameIni.Set("Wii", "Widescreen", EnableWideScreen->Get3StateValue()); - if (DisableWiimoteSpeaker->Get3StateValue() == wxCHK_UNDETERMINED) - GameIni.DeleteKey("Wii", "DisableWiimoteSpeaker"); - else - GameIni.Set("Wii", "DisableWiimoteSpeaker", DisableWiimoteSpeaker->Get3StateValue()); - if (UseBBox->Get3StateValue() == wxCHK_UNDETERMINED) GameIni.DeleteKey("Video", "UseBBox"); else diff --git a/Source/Core/DolphinWX/Src/ISOProperties.h b/Source/Core/DolphinWX/Src/ISOProperties.h index 4f03130ba7..499b242516 100644 --- a/Source/Core/DolphinWX/Src/ISOProperties.h +++ b/Source/Core/DolphinWX/Src/ISOProperties.h @@ -72,7 +72,7 @@ private: wxCheckBox *CPUThread, *SkipIdle, *MMU, *DCBZOFF, *TLBHack; wxCheckBox *VBeam, *FastDiscSpeed, *BlockMerging, *DSPHLE; // Wii - wxCheckBox *EnableWideScreen, *DisableWiimoteSpeaker; + wxCheckBox *EnableWideScreen; // Video wxCheckBox *UseZTPSpeedupHack, *PHackEnable, *UseBBox; wxButton *PHSettings; @@ -139,7 +139,6 @@ private: ID_PHSETTINGS, ID_ENABLEPROGRESSIVESCAN, ID_ENABLEWIDESCREEN, - ID_DISABLEWIIMOTESPEAKER, ID_EDITCONFIG, ID_EMUSTATE, ID_EMU_ISSUES,