From 547740984746cc77bdb142c61f65a4994235ad3b Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Fri, 28 Jun 2019 13:24:01 -0700 Subject: [PATCH] Write the entirety of the Wiimote EEPROM, in a per-Wiimote file Previously, only Mii data was written. Additionally, the file containing mii data was shared for all Wiimotes, which made it a lot less useful. Additionally, the file was read/written on each Wiimote read, even though the whole EEPROM was kept in memory. This was bad for performance and not particularly necessary (it did enforce that the data was properly shared between all Wiimotes, but that's not something I want). --- .../Core/HW/WiimoteEmu/EmuSubroutines.cpp | 25 +--- Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp | 123 ++++++++++++------ Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h | 1 + 3 files changed, 83 insertions(+), 66 deletions(-) diff --git a/Source/Core/Core/HW/WiimoteEmu/EmuSubroutines.cpp b/Source/Core/Core/HW/WiimoteEmu/EmuSubroutines.cpp index 76d5848336b8..8e1c6945c105 100644 --- a/Source/Core/Core/HW/WiimoteEmu/EmuSubroutines.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/EmuSubroutines.cpp @@ -291,18 +291,7 @@ void Wiimote::HandleWriteData(const OutputReportWriteData& wd) else { std::copy_n(wd.data, wd.size, m_eeprom.data.data() + address); - - // Write mii data to file - if (address >= 0x0FCA && address < 0x12C0) - { - // TODO: Only write parts of the Mii block. - // TODO: Use different files for different wiimote numbers. - std::ofstream file; - File::OpenFStream(file, File::GetUserPath(D_SESSION_WIIROOT_IDX) + "/mii.bin", - std::ios::binary | std::ios::out); - file.write((char*)m_eeprom.data.data() + 0x0FCA, 0x02f0); - file.close(); - } + m_eeprom_dirty = true; } } break; @@ -486,18 +475,6 @@ bool Wiimote::ProcessReadDataRequest() } else { - // Mii block handling: - // TODO: different filename for each wiimote? - if (m_read_request.address >= 0x0FCA && m_read_request.address < 0x12C0) - { - // TODO: Only read the Mii block parts required - std::ifstream file; - File::OpenFStream(file, (File::GetUserPath(D_SESSION_WIIROOT_IDX) + "/mii.bin").c_str(), - std::ios::binary | std::ios::in); - file.read((char*)m_eeprom.data.data() + 0x0FCA, 0x02f0); - file.close(); - } - // Read memory to be sent to Wii std::copy_n(m_eeprom.data.data() + m_read_request.address, bytes_to_read, reply.data); reply.size_minus_one = bytes_to_read - 1; diff --git a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp index fcfbdb71c3dd..9c7e12e48599 100644 --- a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp @@ -12,6 +12,7 @@ #include "Common/CommonTypes.h" #include "Common/Config/Config.h" +#include "Common/FileUtil.h" #include "Common/Logging/Log.h" #include "Common/MathUtil.h" #include "Common/MsgHandler.h" @@ -77,50 +78,86 @@ void Wiimote::Reset() m_speaker_mute = false; // EEPROM + std::string eeprom_file = (File::GetUserPath(D_SESSION_WIIROOT_IDX) + "/" + GetName() + ".bin"); + if (m_eeprom_dirty) + { + // Write out existing EEPROM + INFO_LOG(WIIMOTE, "Wrote EEPROM for %s", GetName().c_str()); + std::ofstream file; + File::OpenFStream(file, eeprom_file, std::ios::binary | std::ios::out); + file.write(reinterpret_cast(m_eeprom.data.data()), EEPROM_FREE_SIZE); + file.close(); + + m_eeprom_dirty = false; + } m_eeprom = {}; - // IR calibration: - std::array ir_calibration = { - // Point 1 - IR_LOW_X & 0xFF, - IR_LOW_Y & 0xFF, - // Mix - ((IR_LOW_Y & 0x300) >> 2) | ((IR_LOW_X & 0x300) >> 4) | ((IR_LOW_Y & 0x300) >> 6) | - ((IR_HIGH_X & 0x300) >> 8), - // Point 2 - IR_HIGH_X & 0xFF, - IR_LOW_Y & 0xFF, - // Point 3 - IR_HIGH_X & 0xFF, - IR_HIGH_Y & 0xFF, - // Mix - ((IR_HIGH_Y & 0x300) >> 2) | ((IR_HIGH_X & 0x300) >> 4) | ((IR_HIGH_Y & 0x300) >> 6) | - ((IR_LOW_X & 0x300) >> 8), - // Point 4 - IR_LOW_X & 0xFF, - IR_HIGH_Y & 0xFF, - // Checksum - 0x00, - }; - UpdateCalibrationDataChecksum(ir_calibration, 1); - m_eeprom.ir_calibration_1 = ir_calibration; - m_eeprom.ir_calibration_2 = ir_calibration; - - // Accel calibration: - // Last byte is a checksum. - std::array accel_calibration = { - ACCEL_ZERO_G, ACCEL_ZERO_G, ACCEL_ZERO_G, 0, ACCEL_ONE_G, ACCEL_ONE_G, ACCEL_ONE_G, 0, 0, 0, - }; - UpdateCalibrationDataChecksum(accel_calibration, 1); - m_eeprom.accel_calibration_1 = accel_calibration; - m_eeprom.accel_calibration_2 = accel_calibration; - - // TODO: Is this needed? - // Data of unknown purpose: - constexpr std::array EEPROM_DATA_16D0 = {0x00, 0x00, 0x00, 0xFF, 0x11, 0xEE, 0x00, 0x00, - 0x33, 0xCC, 0x44, 0xBB, 0x00, 0x00, 0x66, 0x99, - 0x77, 0x88, 0x00, 0x00, 0x2B, 0x01, 0xE8, 0x13}; - m_eeprom.unk_2 = EEPROM_DATA_16D0; + if (File::Exists(eeprom_file)) + { + // Read existing EEPROM + std::ifstream file; + File::OpenFStream(file, eeprom_file, std::ios::binary | std::ios::in); + file.read(reinterpret_cast(m_eeprom.data.data()), EEPROM_FREE_SIZE); + file.close(); + } + else + { + // Load some default data. + + // IR calibration: + std::array ir_calibration = { + // Point 1 + IR_LOW_X & 0xFF, + IR_LOW_Y & 0xFF, + // Mix + ((IR_LOW_Y & 0x300) >> 2) | ((IR_LOW_X & 0x300) >> 4) | ((IR_LOW_Y & 0x300) >> 6) | + ((IR_HIGH_X & 0x300) >> 8), + // Point 2 + IR_HIGH_X & 0xFF, + IR_LOW_Y & 0xFF, + // Point 3 + IR_HIGH_X & 0xFF, + IR_HIGH_Y & 0xFF, + // Mix + ((IR_HIGH_Y & 0x300) >> 2) | ((IR_HIGH_X & 0x300) >> 4) | ((IR_HIGH_Y & 0x300) >> 6) | + ((IR_LOW_X & 0x300) >> 8), + // Point 4 + IR_LOW_X & 0xFF, + IR_HIGH_Y & 0xFF, + // Checksum + 0x00, + }; + UpdateCalibrationDataChecksum(ir_calibration, 1); + m_eeprom.ir_calibration_1 = ir_calibration; + m_eeprom.ir_calibration_2 = ir_calibration; + + // Accel calibration: + // Last byte is a checksum. + std::array accel_calibration = { + ACCEL_ZERO_G, ACCEL_ZERO_G, ACCEL_ZERO_G, 0, ACCEL_ONE_G, ACCEL_ONE_G, ACCEL_ONE_G, 0, 0, 0, + }; + UpdateCalibrationDataChecksum(accel_calibration, 1); + m_eeprom.accel_calibration_1 = accel_calibration; + m_eeprom.accel_calibration_2 = accel_calibration; + + // TODO: Is this needed? + // Data of unknown purpose: + constexpr std::array EEPROM_DATA_16D0 = { + 0x00, 0x00, 0x00, 0xFF, 0x11, 0xEE, 0x00, 0x00, 0x33, 0xCC, 0x44, 0xBB, + 0x00, 0x00, 0x66, 0x99, 0x77, 0x88, 0x00, 0x00, 0x2B, 0x01, 0xE8, 0x13}; + m_eeprom.unk_2 = EEPROM_DATA_16D0; + + std::string mii_file = File::GetUserPath(D_SESSION_WIIROOT_IDX) + "/mii.bin"; + if (File::Exists(mii_file)) + { + // Import from the existing mii.bin file, if present + std::ifstream file; + File::OpenFStream(file, mii_file, std::ios::binary | std::ios::in); + file.read(reinterpret_cast(m_eeprom.mii_data_1.data()), m_eeprom.mii_data_1.size()); + m_eeprom.mii_data_2 = m_eeprom.mii_data_1; + file.close(); + } + } m_read_request = {}; @@ -245,6 +282,8 @@ Wiimote::Wiimote(const unsigned int index) : m_index(index) std::string Wiimote::GetName() const { + if (m_index == WIIMOTE_BALANCE_BOARD) + return "BalanceBoard"; return fmt::format("Wiimote{}", 1 + m_index); } diff --git a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h index 0f627e619e6a..1f13d29d2e8a 100644 --- a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h +++ b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h @@ -291,6 +291,7 @@ class Wiimote : public ControllerEmu::EmulatedController bool m_is_motion_plus_attached; + bool m_eeprom_dirty = false; ReadRequest m_read_request; UsableEEPROMData m_eeprom;