From 8912bb3ff4c60c4629539829a983885d44583585 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sun, 2 Oct 2016 16:59:41 +0200 Subject: [PATCH] Back up part of SYSCONF when switching to emulated BT This fixes an issue where the Bluetooth info section could be fully filled up by syncing 5 Wiimotes in passthrough mode then switching to emulated Bluetooth; emulated Wiimotes were then unable to be used. The "real" SYSCONF section is now backed up before being replaced with a blank section that the emulated BT adapter can always fill with 5 Wiimotes without issues. This backup is restored by the passthrough code, instead of during the Bluetooth mode switch because this should be done regardless of the user interface, and even without UI (if the config file is edited manually). --- Source/Core/Common/CommonPaths.h | 1 + Source/Core/Core/BootManager.cpp | 3 ++ .../WII_IPC_HLE_Device_usb_bt_base.cpp | 44 ++++++++++++++++++- .../IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.h | 3 ++ .../IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.cpp | 27 ++++-------- 5 files changed, 59 insertions(+), 19 deletions(-) diff --git a/Source/Core/Common/CommonPaths.h b/Source/Core/Common/CommonPaths.h index 24152773df..c6cc3e2acf 100644 --- a/Source/Core/Common/CommonPaths.h +++ b/Source/Core/Common/CommonPaths.h @@ -120,6 +120,7 @@ #define WII_STATE "state.dat" #define WII_SDCARD "sd.raw" +#define WII_BTDINF_BACKUP "btdinf.bak" #define WII_SETTING "setting.txt" diff --git a/Source/Core/Core/BootManager.cpp b/Source/Core/Core/BootManager.cpp index 6758c25b48..732955cf5e 100644 --- a/Source/Core/Core/BootManager.cpp +++ b/Source/Core/Core/BootManager.cpp @@ -35,6 +35,7 @@ #include "Core/HW/Sram.h" #include "Core/HW/WiimoteReal/WiimoteReal.h" #include "Core/Host.h" +#include "Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.h" #include "Core/Movie.h" #include "Core/NetPlayProto.h" #include "VideoCommon/VideoBackendBase.h" @@ -399,6 +400,8 @@ bool BootCore(const std::string& _rFilename) // TODO: remove this if and once Dolphin supports WC24 standby mode. SConfig::GetInstance().m_SYSCONF->SetData("IPL.IDL", 0x00); NOTICE_LOG(BOOT, "Disabling WC24 'standby' (shutdown to idle) to avoid hanging on shutdown"); + + RestoreBTInfoSection(); } // Run the game diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.cpp index 85e2095fa3..67884c7b8d 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.cpp @@ -2,14 +2,56 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. -#include "Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.h" +#include +#include + #include "Common/Assert.h" #include "Common/CommonFuncs.h" +#include "Common/CommonPaths.h" #include "Common/CommonTypes.h" +#include "Common/FileUtil.h" #include "Common/Logging/Log.h" #include "Core/ConfigManager.h" #include "Core/Core.h" #include "Core/HW/Memmap.h" +#include "Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.h" + +constexpr u16 BT_INFO_SECTION_LENGTH = 0x460; + +void BackUpBTInfoSection() +{ + const std::string filename = File::GetUserPath(D_SESSION_WIIROOT_IDX) + DIR_SEP WII_BTDINF_BACKUP; + if (File::Exists(filename)) + return; + File::IOFile backup(filename, "wb"); + std::vector section(BT_INFO_SECTION_LENGTH); + if (!SConfig::GetInstance().m_SYSCONF->GetArrayData("BT.DINF", section.data(), + static_cast(section.size()))) + { + ERROR_LOG(WII_IPC_WIIMOTE, "Failed to read source BT.DINF section"); + return; + } + if (!backup.WriteBytes(section.data(), section.size())) + ERROR_LOG(WII_IPC_WIIMOTE, "Failed to back up BT.DINF section"); +} + +void RestoreBTInfoSection() +{ + const std::string filename = File::GetUserPath(D_SESSION_WIIROOT_IDX) + DIR_SEP WII_BTDINF_BACKUP; + if (!File::Exists(filename)) + return; + File::IOFile backup(filename, "rb"); + std::vector section(BT_INFO_SECTION_LENGTH); + if (!backup.ReadBytes(section.data(), section.size())) + { + ERROR_LOG(WII_IPC_WIIMOTE, "Failed to read backed up BT.DINF section"); + return; + } + SConfig::GetInstance().m_SYSCONF->SetArrayData("BT.DINF", section.data(), + static_cast(section.size())); + SConfig::GetInstance().m_SYSCONF->Save(); + File::Delete(filename); +} IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_base::IOCtl(u32 command_address) { diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.h index dee774905b..ea28ad17b9 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_base.h @@ -7,6 +7,9 @@ #include "Core/IPC_HLE/WII_IPC_HLE.h" #include "Core/IPC_HLE/WII_IPC_HLE_Device.h" +void BackUpBTInfoSection(); +void RestoreBTInfoSection(); + class CWII_IPC_HLE_Device_usb_oh1_57e_305_base : public IWII_IPC_HLE_Device { public: diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.cpp index 58772cde85..d672464cf4 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.cpp @@ -46,6 +46,7 @@ CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::CWII_IPC_HLE_Device_usb_oh1_57e_305_emu else { sysconf = SConfig::GetInstance().m_SYSCONF; + BackUpBTInfoSection(); } // Activate only first Wiimote by default @@ -62,24 +63,13 @@ CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::CWII_IPC_HLE_Device_usb_oh1_57e_305_emu u8 i = 0; while (i < MAX_BBMOTES) { - if (i < BT_DINF.num_registered) - { - tmpBD.b[5] = BT_DINF.active[i].bdaddr[0] = BT_DINF.registered[i].bdaddr[0]; - tmpBD.b[4] = BT_DINF.active[i].bdaddr[1] = BT_DINF.registered[i].bdaddr[1]; - tmpBD.b[3] = BT_DINF.active[i].bdaddr[2] = BT_DINF.registered[i].bdaddr[2]; - tmpBD.b[2] = BT_DINF.active[i].bdaddr[3] = BT_DINF.registered[i].bdaddr[3]; - tmpBD.b[1] = BT_DINF.active[i].bdaddr[4] = BT_DINF.registered[i].bdaddr[4]; - tmpBD.b[0] = BT_DINF.active[i].bdaddr[5] = BT_DINF.registered[i].bdaddr[5]; - } - else - { - tmpBD.b[5] = BT_DINF.active[i].bdaddr[0] = BT_DINF.registered[i].bdaddr[0] = i; - tmpBD.b[4] = BT_DINF.active[i].bdaddr[1] = BT_DINF.registered[i].bdaddr[1] = 0; - tmpBD.b[3] = BT_DINF.active[i].bdaddr[2] = BT_DINF.registered[i].bdaddr[2] = 0x79; - tmpBD.b[2] = BT_DINF.active[i].bdaddr[3] = BT_DINF.registered[i].bdaddr[3] = 0x19; - tmpBD.b[1] = BT_DINF.active[i].bdaddr[4] = BT_DINF.registered[i].bdaddr[4] = 2; - tmpBD.b[0] = BT_DINF.active[i].bdaddr[5] = BT_DINF.registered[i].bdaddr[5] = 0x11; - } + // Previous records can be safely overwritten, since they are backed up + tmpBD.b[5] = BT_DINF.active[i].bdaddr[0] = BT_DINF.registered[i].bdaddr[0] = i; + tmpBD.b[4] = BT_DINF.active[i].bdaddr[1] = BT_DINF.registered[i].bdaddr[1] = 0; + tmpBD.b[3] = BT_DINF.active[i].bdaddr[2] = BT_DINF.registered[i].bdaddr[2] = 0x79; + tmpBD.b[2] = BT_DINF.active[i].bdaddr[3] = BT_DINF.registered[i].bdaddr[3] = 0x19; + tmpBD.b[1] = BT_DINF.active[i].bdaddr[4] = BT_DINF.registered[i].bdaddr[4] = 2; + tmpBD.b[0] = BT_DINF.active[i].bdaddr[5] = BT_DINF.registered[i].bdaddr[5] = 0x11; const char* wmName; if (i == WIIMOTE_BALANCE_BOARD) @@ -95,6 +85,7 @@ CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::CWII_IPC_HLE_Device_usb_oh1_57e_305_emu i++; } + BT_DINF.num_registered = MAX_BBMOTES; // save now so that when games load sysconf file it includes the new Wiimotes // and the correct order for connected Wiimotes if (!sysconf->SetArrayData("BT.DINF", (u8*)&BT_DINF, sizeof(_conf_pads)) || !sysconf->Save())