Merge pull request #8224 from Pokechu22/wiimote-eeprom
Write the entirety of the Wiimote EEPROM, in a per-Wiimote file
This commit is contained in:
commit
a9cf8670e0
|
@ -290,6 +290,7 @@ void Stop() // - Hammertime!
|
|||
g_video_backend->Video_ExitLoop();
|
||||
}
|
||||
|
||||
Wiimote::ResetAllWiimotes();
|
||||
ResetRumble();
|
||||
|
||||
#ifdef USE_MEMORYWATCHER
|
||||
|
|
|
@ -63,6 +63,8 @@ enum class InitializeMode
|
|||
|
||||
// The Real Wii Remote sends report every ~5ms (200 Hz).
|
||||
constexpr int UPDATE_FREQ = 200;
|
||||
// Custom channel ID used in ControlChannel to indicate disconnects
|
||||
constexpr int DOLPHIN_DISCONNET_CONTROL_CHANNEL = 99;
|
||||
|
||||
void Shutdown();
|
||||
void Initialize(InitializeMode init_mode);
|
||||
|
|
|
@ -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;
|
||||
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.
|
||||
|
||||
// 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;
|
||||
// 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;
|
||||
|
||||
// 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;
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
@ -533,7 +572,7 @@ void Wiimote::SendDataReport()
|
|||
void Wiimote::ControlChannel(const u16 channel_id, const void* data, u32 size)
|
||||
{
|
||||
// Check for custom communication
|
||||
if (99 == channel_id)
|
||||
if (channel_id == ::Wiimote::DOLPHIN_DISCONNET_CONTROL_CHANNEL)
|
||||
{
|
||||
// Wii Remote disconnected.
|
||||
Reset();
|
||||
|
|
|
@ -291,6 +291,7 @@ private:
|
|||
|
||||
bool m_is_motion_plus_attached;
|
||||
|
||||
bool m_eeprom_dirty = false;
|
||||
ReadRequest m_read_request;
|
||||
UsableEEPROMData m_eeprom;
|
||||
|
||||
|
|
|
@ -143,7 +143,7 @@ void Wiimote::ClearReadQueue()
|
|||
void Wiimote::ControlChannel(const u16 channel, const void* const data, const u32 size)
|
||||
{
|
||||
// Check for custom communication
|
||||
if (channel == 99)
|
||||
if (channel == ::Wiimote::DOLPHIN_DISCONNET_CONTROL_CHANNEL)
|
||||
{
|
||||
if (m_really_disconnect)
|
||||
{
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "Core/HW/DVD/DVDInterface.h"
|
||||
#include "Core/HW/Memmap.h"
|
||||
#include "Core/HW/SystemTimers.h"
|
||||
#include "Core/HW/Wiimote.h"
|
||||
#include "Core/Host.h"
|
||||
#include "Core/PowerPC/PPCSymbolDB.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
|
@ -35,6 +36,7 @@ static void ReinitHardware()
|
|||
// MIOS appears to only reset the DI and the PPC.
|
||||
DVDInterface::Reset();
|
||||
PowerPC::Reset();
|
||||
Wiimote::ResetAllWiimotes();
|
||||
// Note: this is specific to Dolphin and is required because we initialised it in Wii mode.
|
||||
DSP::Reinit(SConfig::GetInstance().bDSPHLE);
|
||||
DSP::GetDSPEmulator()->Initialize(SConfig::GetInstance().bWii, SConfig::GetInstance().bDSPThread);
|
||||
|
|
|
@ -218,7 +218,8 @@ void WiimoteDevice::EventConnectionAccepted()
|
|||
void WiimoteDevice::EventDisconnect()
|
||||
{
|
||||
// Send disconnect message to plugin
|
||||
Wiimote::ControlChannel(m_connection_handle & 0xFF, 99, nullptr, 0);
|
||||
Wiimote::ControlChannel(m_connection_handle & 0xFF, Wiimote::DOLPHIN_DISCONNET_CONTROL_CHANNEL,
|
||||
nullptr, 0);
|
||||
|
||||
m_connection_state = ConnectionState::Inactive;
|
||||
|
||||
|
|
Loading…
Reference in New Issue