Skip to content

Commit

Permalink
Write the entirety of the Wiimote EEPROM, in a per-Wiimote file
Browse files Browse the repository at this point in the history
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 Nov 17, 2019
1 parent 97f9f25 commit 5477409
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 66 deletions.
25 changes: 1 addition & 24 deletions Source/Core/Core/HW/WiimoteEmu/EmuSubroutines.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
123 changes: 81 additions & 42 deletions Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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) |

This comment has been minimized.

Copy link
@lioncash

lioncash Jul 24, 2020

Member

This is pretty late (almost 13 months), but wouldn't this resolve down to:

0 | 0 | 0 | 3,

based off the constant values being anded, and is that intended if so?

This comment has been minimized.

Copy link
@Pokechu22

Pokechu22 Jul 24, 2020

Author Contributor

Yes; the points are (lowx, lowy), (lowx, highy), (highx, highy), (highx, lowy), with that line being the first 2 points. On actual remotes, the values vary a fair bit, though they won't usually end up being nonzero. I included them for completeness in case someone wants to mess with the offsets. Note also that they can appear in any order.

The original values (which are also given on wiibrew) were:

  • A1 AA 8B 99 AE 9E 78 30 A7 74 D3: (0A1, 2AA), (399, 28B), (39E, 078), (0A7, 030) (in this case, it's 30 instead of 03)

For context, the values with each of my wiimotes:

  • b4 b8 b8 a0 ad b6 66 30 a5 61 18: (3B4, 2B8), (0A0, 2B8), (3B6, 066), (0A5, 030)
  • 70 5e 03 7b 50 83 9b b8 7a a5 e6: (070, 05E), (37B, 003), (383, 29B), (07A, 2B8)
  • 83 9b 80 7e 50 8a 4c 3b 8d 98 f7: (083, 29B), (07E, 080), (38A, 04C), (38D, 23B)
  • 6f a9 8b 7d ae 78 5d 03 83 67 e5: (06F, 2A9), (37D, 28B), (078, 05D), (383, 003)

Note that this code was actually added in #8292 (7c892c0)

((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 = {};

Expand Down Expand Up @@ -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);
}

Expand Down
1 change: 1 addition & 0 deletions Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down

0 comments on commit 5477409

Please sign in to comment.