Skip to content
Permalink
Browse files

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).
  • Loading branch information
Pokechu22 committed Jun 28, 2019
1 parent 97f9f25 commit 547740984746cc77bdb142c61f65a4994235ad3b
@@ -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;
@@ -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<char*>(m_eeprom.data.data()), EEPROM_FREE_SIZE);
file.close();

m_eeprom_dirty = false;
}
m_eeprom = {};

// IR calibration:
std::array<u8, 11> 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<u8, 10> 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<u8, 24> 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<char*>(m_eeprom.data.data()), EEPROM_FREE_SIZE);
file.close();
}
else
{
// Load some default data.

// IR calibration:
std::array<u8, 11> 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<u8, 10> 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<u8, 24> 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<char*>(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);
}

@@ -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;

0 comments on commit 5477409

Please sign in to comment.
You can’t perform that action at this time.