diff --git a/Source/Core/Core/HW/WiimoteCommon/WiimoteConstants.h b/Source/Core/Core/HW/WiimoteCommon/WiimoteConstants.h index 2203eb3df2..99cf0e04e7 100644 --- a/Source/Core/Core/HW/WiimoteCommon/WiimoteConstants.h +++ b/Source/Core/Core/HW/WiimoteCommon/WiimoteConstants.h @@ -10,10 +10,6 @@ namespace WiimoteCommon { constexpr u8 MAX_PAYLOAD = 23; -// Based on testing, old WiiLi.org docs, and WiiUse library: -// Max battery level seems to be 0xc8 (decimal 200) -constexpr u8 MAX_BATTERY_LEVEL = 0xc8; - enum class InputReportID : u8 { Status = 0x20, diff --git a/Source/Core/Core/HW/WiimoteCommon/WiimoteReport.h b/Source/Core/Core/HW/WiimoteCommon/WiimoteReport.h index 35c81518bb..39f4c5705a 100644 --- a/Source/Core/Core/HW/WiimoteCommon/WiimoteReport.h +++ b/Source/Core/Core/HW/WiimoteCommon/WiimoteReport.h @@ -207,6 +207,22 @@ struct InputReportStatus u8 leds : 4; u8 padding2[2]; u8 battery; + + constexpr float GetEstimatedCharge() const + { + return battery * BATTERY_LEVEL_M / BATTERY_MAX + BATTERY_LEVEL_B; + } + void SetEstimatedCharge(float charge) + { + battery = u8(std::lround((charge - BATTERY_LEVEL_B) / BATTERY_LEVEL_M * BATTERY_MAX)); + } + +private: + static constexpr auto BATTERY_MAX = std::numeric_limits::max(); + + // Linear fit of battery level mid-point for charge bars in home menu. + static constexpr float BATTERY_LEVEL_M = 2.46f; + static constexpr float BATTERY_LEVEL_B = -0.013f; }; static_assert(sizeof(InputReportStatus) == 6, "Wrong size"); diff --git a/Source/Core/Core/HW/WiimoteEmu/EmuSubroutines.cpp b/Source/Core/Core/HW/WiimoteEmu/EmuSubroutines.cpp index 8d98a93d59..5100ae74fc 100644 --- a/Source/Core/Core/HW/WiimoteEmu/EmuSubroutines.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/EmuSubroutines.cpp @@ -235,13 +235,12 @@ void Wiimote::HandleRequestStatus(const OutputReportRequestStatus&) // Update status struct m_status.extension = m_extension_port.IsDeviceConnected(); - - m_status.battery = u8(std::lround(m_battery_setting.GetValue() / 100 * MAX_BATTERY_LEVEL)); + m_status.SetEstimatedCharge(m_battery_setting.GetValue() / ciface::BATTERY_INPUT_MAX_VALUE); if (Core::WantsDeterminism()) { // One less thing to break determinism: - m_status.battery = MAX_BATTERY_LEVEL; + m_status.SetEstimatedCharge(1.f); } // Less than 0x20 triggers the low-battery flag: diff --git a/Source/Core/InputCommon/ControllerInterface/Wiimote/Wiimote.cpp b/Source/Core/InputCommon/ControllerInterface/Wiimote/Wiimote.cpp index 059138e52a..3ff61621d8 100644 --- a/Source/Core/InputCommon/ControllerInterface/Wiimote/Wiimote.cpp +++ b/Source/Core/InputCommon/ControllerInterface/Wiimote/Wiimote.cpp @@ -288,8 +288,7 @@ Device::Device(std::unique_ptr wiimote) : m_wiimote(std::m AddInput(new AnalogInput(&m_classic_state.triggers[1], classic_prefix + "R-Analog", 1.f)); // Specialty inputs: - AddInput(new UndetectableAnalogInput( - &m_battery, "Battery", WiimoteCommon::MAX_BATTERY_LEVEL / ciface::BATTERY_INPUT_MAX_VALUE)); + AddInput(new UndetectableAnalogInput(&m_battery, "Battery", 1.f)); AddInput(new UndetectableAnalogInput( &m_extension_number_input, "Attached Extension", WiimoteEmu::ExtensionNumber(1))); AddInput(new UndetectableAnalogInput(&m_mplus_attached_input, "Attached MotionPlus", 1)); @@ -1550,7 +1549,7 @@ void Device::ProcessStatusReport(const InputReportStatus& status) // Update status periodically to keep battery level value up to date. m_status_outdated_time = Clock::now() + std::chrono::seconds(10); - m_battery = status.battery; + m_battery = status.GetEstimatedCharge() * BATTERY_INPUT_MAX_VALUE; m_leds = status.leds; if (!status.ir) diff --git a/Source/Core/InputCommon/ControllerInterface/Wiimote/Wiimote.h b/Source/Core/InputCommon/ControllerInterface/Wiimote/Wiimote.h index 75296c65b1..87165faff4 100644 --- a/Source/Core/InputCommon/ControllerInterface/Wiimote/Wiimote.h +++ b/Source/Core/InputCommon/ControllerInterface/Wiimote/Wiimote.h @@ -233,7 +233,7 @@ private: // Status report is requested every so often to update the battery level. Clock::time_point m_status_outdated_time = Clock::now(); - u8 m_battery = 0; + float m_battery = 0; u8 m_leds = 0; bool m_speaker_configured = false;