Merge branch 'JP-wiimote-savestate-fixes'

This commit is contained in:
Rachel Bryk 2013-06-25 09:32:01 -04:00
commit a619135ab4
16 changed files with 827 additions and 74 deletions

View File

@ -162,6 +162,7 @@ const char* GetLastErrorMsg();
namespace Common namespace Common
{ {
inline u8 swap8(u8 _data) {return _data;} inline u8 swap8(u8 _data) {return _data;}
inline u32 swap24(const u8* _data) {return (_data[0] << 16) | (_data[1] << 8) | _data[2];}
#ifdef _WIN32 #ifdef _WIN32
inline u16 swap16(u16 _data) {return _byteswap_ushort(_data);} inline u16 swap16(u16 _data) {return _byteswap_ushort(_data);}

View File

@ -243,7 +243,6 @@ void SConfig::SaveSettings()
ini.Set("Core", "WiiSDCard", m_WiiSDCard); ini.Set("Core", "WiiSDCard", m_WiiSDCard);
ini.Set("Core", "WiiKeyboard", m_WiiKeyboard); ini.Set("Core", "WiiKeyboard", m_WiiKeyboard);
ini.Set("Core", "WiimoteReconnectOnLoad", m_WiimoteReconnectOnLoad);
ini.Set("Core", "WiimoteContinuousScanning", m_WiimoteContinuousScanning); ini.Set("Core", "WiimoteContinuousScanning", m_WiimoteContinuousScanning);
ini.Set("Core", "WiimoteEnableSpeaker", m_WiimoteEnableSpeaker); ini.Set("Core", "WiimoteEnableSpeaker", m_WiimoteEnableSpeaker);
ini.Set("Core", "RunCompareServer", m_LocalCoreStartupParameter.bRunCompareServer); ini.Set("Core", "RunCompareServer", m_LocalCoreStartupParameter.bRunCompareServer);
@ -400,7 +399,6 @@ void SConfig::LoadSettings()
ini.Get("Core", "WiiSDCard", &m_WiiSDCard, false); ini.Get("Core", "WiiSDCard", &m_WiiSDCard, false);
ini.Get("Core", "WiiKeyboard", &m_WiiKeyboard, false); ini.Get("Core", "WiiKeyboard", &m_WiiKeyboard, false);
ini.Get("Core", "WiimoteReconnectOnLoad", &m_WiimoteReconnectOnLoad, true);
ini.Get("Core", "WiimoteContinuousScanning", &m_WiimoteContinuousScanning, false); ini.Get("Core", "WiimoteContinuousScanning", &m_WiimoteContinuousScanning, false);
ini.Get("Core", "WiimoteEnableSpeaker", &m_WiimoteEnableSpeaker, true); ini.Get("Core", "WiimoteEnableSpeaker", &m_WiimoteEnableSpeaker, true);
ini.Get("Core", "RunCompareServer", &m_LocalCoreStartupParameter.bRunCompareServer, false); ini.Get("Core", "RunCompareServer", &m_LocalCoreStartupParameter.bRunCompareServer, false);

View File

@ -28,7 +28,6 @@ struct SConfig : NonCopyable
// Wii Devices // Wii Devices
bool m_WiiSDCard; bool m_WiiSDCard;
bool m_WiiKeyboard; bool m_WiiKeyboard;
bool m_WiimoteReconnectOnLoad;
bool m_WiimoteContinuousScanning; bool m_WiimoteContinuousScanning;
bool m_WiimoteEnableSpeaker; bool m_WiimoteEnableSpeaker;

View File

@ -504,9 +504,11 @@ void SetState(EState _State)
break; break;
case CORE_PAUSE: case CORE_PAUSE:
CCPU::EnableStepping(true); // Break CCPU::EnableStepping(true); // Break
Wiimote::Pause();
break; break;
case CORE_RUN: case CORE_RUN:
CCPU::EnableStepping(false); CCPU::EnableStepping(false);
Wiimote::Resume();
break; break;
default: default:
PanicAlertT("Invalid state"); PanicAlertT("Invalid state");

View File

@ -32,8 +32,7 @@ void Shutdown()
delete *i; delete *i;
g_plugin.controllers.clear(); g_plugin.controllers.clear();
// WiimoteReal is shutdown on app exit WiimoteReal::Shutdown();
//WiimoteReal::Shutdown();
g_controller_interface.Shutdown(); g_controller_interface.Shutdown();
} }
@ -58,6 +57,17 @@ void Initialize(void* const hwnd)
Movie::ChangeWiiPads(); Movie::ChangeWiiPads();
} }
void Resume()
{
WiimoteReal::Resume();
}
void Pause()
{
WiimoteReal::Pause();
}
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// Function: ControlChannel // Function: ControlChannel
// Purpose: An L2CAP packet is passed from the Core to the Wiimote, // Purpose: An L2CAP packet is passed from the Core to the Wiimote,
@ -72,11 +82,8 @@ void Initialize(void* const hwnd)
// //
void ControlChannel(int _number, u16 _channelID, const void* _pData, u32 _Size) void ControlChannel(int _number, u16 _channelID, const void* _pData, u32 _Size)
{ {
if (WIIMOTE_SRC_EMU & g_wiimote_sources[_number]) if (WIIMOTE_SRC_HYBRID & g_wiimote_sources[_number])
((WiimoteEmu::Wiimote*)g_plugin.controllers[_number])->ControlChannel(_channelID, _pData, _Size); ((WiimoteEmu::Wiimote*)g_plugin.controllers[_number])->ControlChannel(_channelID, _pData, _Size);
if (WIIMOTE_SRC_REAL & g_wiimote_sources[_number])
WiimoteReal::ControlChannel(_number, _channelID, _pData, _Size);
} }
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
@ -93,10 +100,8 @@ void ControlChannel(int _number, u16 _channelID, const void* _pData, u32 _Size)
// //
void InterruptChannel(int _number, u16 _channelID, const void* _pData, u32 _Size) void InterruptChannel(int _number, u16 _channelID, const void* _pData, u32 _Size)
{ {
if (WIIMOTE_SRC_EMU & g_wiimote_sources[_number]) if (WIIMOTE_SRC_HYBRID & g_wiimote_sources[_number])
((WiimoteEmu::Wiimote*)g_plugin.controllers[_number])->InterruptChannel(_channelID, _pData, _Size); ((WiimoteEmu::Wiimote*)g_plugin.controllers[_number])->InterruptChannel(_channelID, _pData, _Size);
else
WiimoteReal::InterruptChannel(_number, _channelID, _pData, _Size);
} }
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________

View File

@ -36,6 +36,8 @@ namespace Wiimote
void Shutdown(); void Shutdown();
void Initialize(void* const hwnd); void Initialize(void* const hwnd);
void Resume();
void Pause();
unsigned int GetAttached(); unsigned int GetAttached();
void DoState(u8 **ptr, PointerWrap::Mode mode); void DoState(u8 **ptr, PointerWrap::Mode mode);
@ -53,6 +55,8 @@ namespace WiimoteReal
void Initialize(); void Initialize();
void Shutdown(); void Shutdown();
void Resume();
void Pause();
void Refresh(); void Refresh();
void LoadSettings(); void LoadSettings();

View File

@ -29,15 +29,662 @@
#include "Attachment/Attachment.h" #include "Attachment/Attachment.h"
/* Bit shift conversions */
static u32 swap24(const u8* src)
{
return (src[0] << 16) | (src[1] << 8) | src[2];
}
namespace WiimoteEmu namespace WiimoteEmu
{ {
void Spy(Wiimote* wm_, const void* data_, int size_)
{
#if 0
// enable log
bool logCom = true;
bool logData = true;
bool logMP = false;
bool logAudio = false;
std::string Name, TmpData;
static int c;
int size;
u16 SampleValue;
bool AudioData = false;
bool DataReport = false;
static std::queue<u32> dataRep;
static u8 dataReply[3] = {0};
bool emu = wm_;
static Wiimote* wm = 0;
// a container for f.e. the extension encryption key
if (!wm_ && !wm)
wm = new Wiimote(0);
else
wm = wm_;
// ignore emulated Wiimote data
if (emu) return;
const hid_packet* const hidp = (hid_packet*)data_;
const wm_report* const sr = (wm_report*)hidp->data;
// use a non-pointer array because that makes read syntax shorter
u8 data[32] = {};
memcpy(data, data_, size_);
switch(data[1])
{
case WM_RUMBLE:
size = 1;
if (logCom) Name.append("WM_RUMBLE");
break;
case WM_LEDS:
size = sizeof(wm_leds);
if (logCom) Name.append("WM_LEDS");
break;
case WM_REPORT_MODE:
size = sizeof(wm_report_mode);
if (logCom) Name.append("WM_REPORT_MODE");
ERROR_LOG(CONSOLE, "WM_REPORT_MODE: 0x%02x", data[3]);
break;
case WM_IR_PIXEL_CLOCK:
if (logCom) Name.append("WM_IR_PIXEL_CLOCK");
break;
case WM_SPEAKER_ENABLE:
if (logCom) Name.append("WM_SPEAKER_ENABLE");
NOTICE_LOG(CONSOLE, "Speaker on: %d", sr->enable);
break;
case WM_REQUEST_STATUS:
size = sizeof(wm_request_status);
if (logCom) Name.append("WM_REQUEST_STATUS");
NOTICE_LOG(CONSOLE, "WM_REQUEST_STATUS: %s", ArrayToString(data, size+2, 0).c_str());
break;
case WM_WRITE_DATA:
{
if (logCom) Name.append("W 0x16");
size = sizeof(wm_write_data);
wm_write_data* wd = (wm_write_data*)sr->data;
u32 address = Common::swap24(wd->address);
address &= ~0x010000;
switch(data[2] >> 0x01)
{
case WM_SPACE_EEPROM:
if (logCom) Name.append(" REG_EEPROM"); break;
case WM_SPACE_REGS1:
case WM_SPACE_REGS2: {
const u8 region_offset = (u8)address;
void *region_ptr = NULL;
int region_size = 0;
switch(data[3])
{
case 0xa2:
if (logCom)
{
Name.append(" REG_SPEAKER");
if(data[6] == 7)
{
//INFO_LOG(CONSOLE, "Sound configuration:");
if(data[8] == 0x00)
{
//memcpy(&SampleValue, &data[9], 2);
//NOTICE_LOG(CONSOLE, " Data format: 4-bit ADPCM (%i Hz)", 6000000 / SampleValue);
//NOTICE_LOG(CONSOLE, " Volume: %02i%%", (data[11] / 0x40) * 100);
}
else if (data[8] == 0x40)
{
//memcpy(&SampleValue, &data[9], 2);
//NOTICE_LOG(CONSOLE, " Data format: 8-bit PCM (%i Hz)", 12000000 / SampleValue);
//NOTICE_LOG(CONSOLE, " Volume: %02i%%", (data[11] / 0xff) * 100);
}
}
}
break;
case 0xa4:
if (logCom) Name.append(" REG_EXT");
// Update the encryption mode
if (data[5] == 0xf0) {
if (!emu)
wm->m_reg_ext.encryption = wd->data[0];
//NOTICE_LOG(CONSOLE, "Extension encryption: %u", wm->m_reg_ext.encryption);
}
region_ptr = &wm->m_reg_ext;
break;
case 0xa6 :
if (logCom) Name.append(" REG_M+");
// update the encryption mode
if (data[5] == 0xf0) {
if (!emu)
wm->m_reg_motion_plus.activated = wd->data[0];
//NOTICE_LOG(CONSOLE, "Extension enryption: %u", wm->m_reg_ext.encryption);
}
region_ptr = &wm->m_reg_motion_plus;
break;
case 0xb0:
if (logCom) Name.append(" REG_IR"); break;
}
// save register
if (!emu && region_ptr)
memcpy((u8*)region_ptr + region_offset, wd->data, wd->size);
// save key
if (region_offset >= 0x40 && region_offset <= 0x4c) {
if(!emu)
wiimote_gen_key(&wm->m_ext_key, wm->m_reg_ext.encryption_key);
INFO_LOG(CONSOLE, "Writing key: %s", ArrayToString((u8*)&wm->m_ext_key, sizeof(wm->m_ext_key), 0, 30).c_str());
}
if (data[3] == 0xa4 || data[3] == 0xa6) {
//DEBUG_LOG(CONSOLE, "M+: %s", ArrayToString((u8*)&wm->m_reg_motion_plus, sizeof(wm->m_reg_motion_plus), 0, 30).c_str());
//DEBUG_LOG(CONSOLE, "M+: %s", ArrayToString((u8*)&wm->m_reg_motion_plus.ext_identifier, sizeof(wm->m_reg_motion_plus.ext_identifier), 0, 30).c_str());
NOTICE_LOG(CONSOLE, "W[0x%02x 0x%02x|%d]: %s", data[3], region_offset, wd->size, ArrayToString(wd->data, wd->size, 0).c_str());
}
break;
}
}
break;
}
case WM_READ_DATA:
{
if (logCom) Name.append("R");
size = sizeof(wm_read_data);
wm_read_data* rd = (wm_read_data*)sr->data;
u32 address = Common::swap24(rd->address);
u8 addressLO = address & 0xFFFF;
address &= 0xFEFFFF;
u16 size = Common::swap16(rd->size);
u8 *const block = new u8[size];
void *region_ptr = NULL;
dataRep.push(((data[2]>>1)<<16) + ((data[3])<<8) + addressLO);
switch(data[2]>>1)
{
case WM_SPACE_EEPROM:
if (logCom) Name.append(" REG_EEPROM");
if (!emu)
memcpy(block, wm->m_eeprom + address, size);
break;
case WM_SPACE_REGS1:
case WM_SPACE_REGS2:
// ignore second byte for extension area
if (address>>16 == 0xA4) address &= 0xFF00FF;
const u8 region_offset = (u8)address;
switch(data[3])
{
case 0xa2:
if (logCom) Name.append(" REG_SPEAKER");
region_ptr = &wm->m_reg_speaker;
break;
case 0xa4:
if (logCom) Name.append(" REG_EXT");
region_ptr = &wm->m_reg_motion_plus;
break;
case 0xa6:
if (logCom) Name.append(" REG_M+");
region_ptr = &wm->m_reg_motion_plus;
break;
case 0xb0:
if (logCom) Name.append(" REG_IR");
region_ptr = &wm->m_reg_ir;
break;
}
//if (!emu && region_ptr)
//memcpy(block, (u8*)region_ptr + region_offset, size);
//WARN_LOG(CONSOLE, "READING[0x%02x 0x%02x|%d]: %s", data[3], region_offset, size, ArrayToString(block, size, 0, 30).c_str());
break;
}
break;
}
case WM_WRITE_SPEAKER_DATA:
if (logCom) Name.append("WM_SPEAKER_DATA");
size = 21;
break;
case WM_SPEAKER_MUTE:
if (logCom) Name.append("WM_SPEAKER");
size = 1;
NOTICE_LOG(CONSOLE, "Speaker mute: %d", sr->enable);
break;
case WM_IR_LOGIC:
if (logCom) Name.append("WM_IR");
size = 1;
break;
case WM_STATUS_REPORT:
size = sizeof(wm_status_report);
Name = "WM_STATUS_REPORT";
//INFO_LOG(CONSOLE, "WM_STATUS_REPORT: %s", ArrayToString(data, size+2, 0).c_str());
{
wm_status_report* pStatus = (wm_status_report*)(data + 2);
ERROR_LOG(CONSOLE, ""
"Statusreport extension: %i",
//"Speaker enabled: %i"
//"IR camera enabled: %i"
//"LED 1: %i\n"
//"LED 2: %i\n"
//"LED 3: %i\n"
//"LED 4: %i\n"
//"Battery low: %i\n"
//"Battery level: %i",
pStatus->extension
//pStatus->speaker,
//pStatus->ir,
//(pStatus->leds >> 0),
//(pStatus->leds >> 1),
//(pStatus->leds >> 2),
//(pStatus->leds >> 3),
//pStatus->battery_low,
//pStatus->battery
);
}
break;
case WM_READ_DATA_REPLY:
{
size = sizeof(wm_read_data_reply);
Name = "R_REPLY";
u8 data2[32];
memset(data2, 0, sizeof(data2));
memcpy(data2, data, size_);
wm_read_data_reply* const rdr = (wm_read_data_reply*)(data2 + 2);
bool decrypted = false;
if(!dataRep.empty())
{
dataReply[0] = (dataRep.front()>>16)&0x00FF;
dataReply[1] = (dataRep.front()>>8)&0x00FF;
dataReply[2] = dataRep.front()&0x00FF;
dataRep.pop();
}
switch(dataReply[0])
{
case WM_SPACE_EEPROM:
if (logCom)
Name.append(" REG_EEPROM");
// Wiimote calibration
if(data[4] == 0xf0 && data[5] == 0x00 && data[6] == 0x10) {
if(data[6] == 0x10) {
accel_cal* calib = (accel_cal*)&rdr->data[6];
ERROR_LOG(CONSOLE, "Wiimote calibration:");
//SERROR_LOG(CONSOLE, "%s", ArrayToString(rdr->data, rdr->size).c_str());
ERROR_LOG(CONSOLE, "Cal_zero.x: %i", calib->zero_g.x);
ERROR_LOG(CONSOLE, "Cal_zero.y: %i", calib->zero_g.y);
ERROR_LOG(CONSOLE, "Cal_zero.z: %i", calib->zero_g.z);
ERROR_LOG(CONSOLE, "Cal_g.x: %i", calib->one_g.x);
ERROR_LOG(CONSOLE, "Cal_g.y: %i", calib->one_g.y);
ERROR_LOG(CONSOLE, "Cal_g.z: %i", calib->one_g.z);
// save
if (!emu)
memcpy(wm->m_eeprom + 0x16, rdr->data + 6, rdr->size);
}
}
break;
case WM_SPACE_REGS1:
case WM_SPACE_REGS2:
switch(dataReply[1])
{
case 0xa2: if (logCom) Name.append(" REG_SPEAKER"); break;
case 0xa4: if (logCom) Name.append(" REG_EXT"); break;
case 0xa6: if (logCom) Name.append(" REG_M+"); break;
case 0xb0: if (logCom) Name.append(" REG_IR"); break;
}
}
// save key
if (!emu && rdr->address>>8 == 0x40)
{
memcpy(((u8*)&wm->m_reg_ext.encryption_key), rdr->data, rdr->size+1);
wiimote_gen_key(&wm->m_ext_key, wm->m_reg_ext.encryption_key);
NOTICE_LOG(CONSOLE, "Reading key: %s", ArrayToString(((u8*)&wm->m_ext_key), sizeof(wm->m_ext_key), 0, 30).c_str());
}
// select decryption
//if(((!wm->GetMotionPlusActive() && ((u8*)&wm->m_reg_ext)[0xf0] == 0xaa) || (wm->GetMotionPlusActive() && ((u8*)&wm->m_reg_motion_plus)[0xf0] == 0xaa)) && rdr->address>>8 < 0xf0) {
//if(((((u8*)&wm->m_reg_ext)[0xf0] == 0xaa) || ((u8*)&wm->m_reg_motion_plus)[0xf0] == 0xaa) && rdr->address>>8 < 0xf0) {
//if(!wm->GetMotionPlusActive() && ((u8*)&wm->m_reg_ext)[0xf0] == 0xaa && rdr->address>>8 < 0xf0) {
//if(!wm->GetMotionPlusActive() && ((u8*)&wm->m_reg_ext)[0xf0] == 0xaa) {
// SWARN_LOG(CONSOLE, "key %s", ArrayToString(((u8*)&wm->m_ext_key), sizeof(wm->m_ext_key), 0, 30).c_str());
// SWARN_LOG(CONSOLE, "decrypt %s", ArrayToString(rdr->data, rdr->size+1, 0, 30).c_str());
// wiimote_decrypt(&wm->m_ext_key, rdr->data, dataReply[2]&0xffff, rdr->size+1);
// SWARN_LOG(CONSOLE, "decrypt %s", ArrayToString(rdr->data, rdr->size+1, 0, 30).c_str());
// decrypted = true;
//}
// save data
if (!emu && !rdr->error)
{
//if (dataReply[1] == 0xa4 && wm->GetMotionPlusActive())
//memcpy(&((u8*)&wm->m_reg_motion_plus)[rdr->address>>8], rdr->data, rdr->size+1);
//if (dataReply[1] == 0xa4 && !wm->GetMotionPlusActive())
//if (dataReply[1] == 0xa4)
// memcpy(&((u8*)&wm->m_reg_ext)[rdr->address>>8], rdr->data, rdr->size+1);
//if (!wm->GetMotionPlusActive() && wm->GetMotionPlusAttached())
//if (dataReply[1] == 0xa6)
// memcpy(&((u8*)&wm->m_reg_motion_plus)[rdr->address>>8], rdr->data, rdr->size+1);
//INFO_LOG(CONSOLE, "Saving[0x%2x:0x%2x]: %s", dataReply[1], rdr->address>>8, ArrayToString(rdr->data, rdr->size+1).c_str());
}
if (!rdr->error && rdr->address>>8 >= 0xf0 && rdr->address>>8 <= 0xff)
{
//INFO_LOG(CONSOLE, "Extension ID: %s", ArrayToString(rdr->data, rdr->size+1).c_str());
}
// Nunchuck calibration
if(data[4] == 0xf0 && data[5] == 0x00 && (data[6] == 0x20 || data[6] == 0x30))
{
// log
//TmpData = StringFromFormat("Read[%s] (enc): %s", (Emu ? "Emu" : "Real"), ArrayToString(data, size + 2).c_str());
// decrypt
//if(((u8*)&wm->m_reg_ext)[0xf0] == 0xaa) {
// wiimote_decrypt(&wm->m_ext_key, &data[0x07], 0x00, (data[4] >> 0x04) + 1);
//if (wm->m_extension->name == "NUNCHUCK") {
// INFO_LOG(CONSOLE, "\nGame got the Nunchuck calibration:\n");
// INFO_LOG(CONSOLE, "Cal_zero.x: %i\n", data[7 + 0]);
// INFO_LOG(CONSOLE, "Cal_zero.y: %i\n", data[7 + 1]);
// INFO_LOG(CONSOLE, "Cal_zero.z: %i\n", data[7 + 2]);
// INFO_LOG(CONSOLE, "Cal_g.x: %i\n", data[7 + 4]);
// INFO_LOG(CONSOLE, "Cal_g.y: %i\n", data[7 + 5]);
// INFO_LOG(CONSOLE, "Cal_g.z: %i\n", data[7 + 6]);
// INFO_LOG(CONSOLE, "Js.Max.x: %i\n", data[7 + 8]);
// INFO_LOG(CONSOLE, "Js.Min.x: %i\n", data[7 + 9]);
// INFO_LOG(CONSOLE, "Js.Center.x: %i\n", data[7 + 10]);
// INFO_LOG(CONSOLE, "Js.Max.y: %i\n", data[7 + 11]);
// INFO_LOG(CONSOLE, "Js.Min.y: %i\n", data[7 + 12]);
// INFO_LOG(CONSOLE, "JS.Center.y: %i\n\n", data[7 + 13]);
//}
//else // g_Config.bClassicControllerConnected {
// INFO_LOG(CONSOLE, "\nGame got the Classic Controller calibration:\n");
// INFO_LOG(CONSOLE, "Lx.Max: %i\n", data[7 + 0]);
// INFO_LOG(CONSOLE, "Lx.Min: %i\n", data[7 + 1]);
// INFO_LOG(CONSOLE, "Lx.Center: %i\n", data[7 + 2]);
// INFO_LOG(CONSOLE, "Ly.Max: %i\n", data[7 + 3]);
// INFO_LOG(CONSOLE, "Ly.Min: %i\n", data[7 + 4]);
// INFO_LOG(CONSOLE, "Ly.Center: %i\n", data[7 + 5]);
// INFO_LOG(CONSOLE, "Rx.Max.x: %i\n", data[7 + 6]);
// INFO_LOG(CONSOLE, "Rx.Min.x: %i\n", data[7 + 7]);
// INFO_LOG(CONSOLE, "Rx.Center.x: %i\n", data[7 + 8]);
// INFO_LOG(CONSOLE, "Ry.Max.y: %i\n", data[7 + 9]);
// INFO_LOG(CONSOLE, "Ry.Min: %i\n", data[7 + 10]);
// INFO_LOG(CONSOLE, "Ry.Center: %i\n\n", data[7 + 11]);
// INFO_LOG(CONSOLE, "Lt.Neutral: %i\n", data[7 + 12]);
// INFO_LOG(CONSOLE, "Rt.Neutral %i\n\n", data[7 + 13]);
//}
// save values
if (!emu)
{
// Save to registry
if(data[7 + 0] != 0xff)
{
//memcpy((u8*)&wm->m_reg_ext.calibration, &data[7], 0x10);
//memcpy((u8*)&wm->m_reg_ext.unknown3, &data[7], 0x10);
}
// Save the default values that should work with Wireless Nunchucks
else
{
//WiimoteEmu::SetDefaultExtensionRegistry();
}
//WiimoteEmu::UpdateEeprom();
}
// third party Nunchuck
else if(data[7] == 0xff)
{
//memcpy(wm->m_reg_ext + 0x20, WiimoteEmu::wireless_nunchuck_calibration, sizeof(WiimoteEmu::wireless_nunchuck_calibration));
//memcpy(wm->m_reg_ext + 0x30, WiimoteEmu::wireless_nunchuck_calibration, sizeof(WiimoteEmu::wireless_nunchuck_calibration));
}
// print encrypted data
//INFO_LOG(CONSOLE, "WM_READ_DATA_REPLY: Extension calibration: %s", TmpData.c_str());
}
if (dataReply[1] == 0xa4 || dataReply[1] == 0xa6)
{
if(rdr->error == 7 || rdr->error == 8)
{
WARN_LOG(CONSOLE, "R%s[0x%02x 0x%02x]: e-%d", decrypted?"*":"", dataReply[1], rdr->address>>8, rdr->error);
}
else
{
WARN_LOG(CONSOLE, "R%s[0x%02x 0x%02x|%d]: %s", decrypted?"*":"", dataReply[1], rdr->address>>8, rdr->size+1, ArrayToString(rdr->data, rdr->size+1, 0).c_str());
}
}
break;
}
case WM_ACK_DATA:
size = sizeof(wm_acknowledge);
Name = "WM_ACK_DATA";
//INFO_LOG(CONSOLE, "ACK 0x%02x", data[4]);
break;
case WM_REPORT_CORE:
size = sizeof(wm_report_core);
DataReport = true;
break;
case WM_REPORT_CORE_ACCEL:
size = sizeof(wm_report_core_accel);
DataReport = true;
break;
case WM_REPORT_CORE_EXT8:
size = sizeof(wm_report_core_accel_ir12);
DataReport = true;
break;
case WM_REPORT_CORE_ACCEL_IR12:
size = sizeof(wm_report_core_accel_ir12);
DataReport = true;
break;
case WM_REPORT_CORE_EXT19:
size = sizeof(wm_report_core_accel_ext16);
DataReport = true;
break;
case WM_REPORT_CORE_ACCEL_EXT16:
size = sizeof(wm_report_core_accel_ext16);
DataReport = true;
break;
case WM_REPORT_CORE_IR10_EXT9:
size = sizeof(wm_report_core_accel_ir10_ext6);
DataReport = true;
break;
case WM_REPORT_CORE_ACCEL_IR10_EXT6:
size = sizeof(wm_report_core_accel_ir10_ext6);
DataReport = true;
break;
default:
size = 15;
NOTICE_LOG(CONSOLE, "Debugging[%s]: Unknown channel 0x%02x", (emu ? "E" : "R"), data[1]);
break;
}
//if (DataReport && wm->GetMotionPlusActive())
//{
// if (data[1] == WM_REPORT_CORE_ACCEL_IR10_EXT6)
// static bool extension = false;
// if (extension != (bool)(data[17+4]&1))
// ERROR_LOG(CONSOLE, "Datareport extension %d", data[17+4]&1);
// extension = data[17+4]&1;
//}
if (!DataReport && logCom && size <= 30)
{
ERROR_LOG_S(CONSOLE, "Com[%s] %s: %s", (emu ? "E" : "R"), Name.c_str(), ArrayToString(data, size + 2, 0).c_str());
}
if (logAudio && AudioData)
{
//DEBUG_LOG(CONSOLE, "%s: %s\n", Name.c_str(), ArrayToString(data, std::min(10,size), 0, 30).c_str());
}
if (DataReport && (logData || logMP))
{
// decrypt extension data
//if (data[1] == 0x37 && !wm->GetMotionPlusActive())
//if (data[1] == 0x37)
// wiimote_decrypt(&wm->m_ext_key, &data[17], 0x00, 0x06);
//if (data[1] == 0x35)
// wiimote_decrypt(&wm->m_ext_key, &data[7], 0x00, 0x06);
//if (data[1] == 0x35 || data[1] == 0x37)
//{
// if (!g_DebugMP && mp->is_mp_data) return;
// if (!g_DebugData && !mp->is_mp_data) return;
//}
std::string SCore = "", SAcc = "", SIR = "", SExt = "", SExtID = "";
wm_core* core = (wm_core*)sr->data;
accel_cal* calib = (accel_cal*)&wm->m_eeprom[0x16];
wm_accel* accel = (wm_accel*)&data[4];
//SCore = StringFromFormat(
// "%d %d %d %d ",
// core->xL,
// core->yL,
// core->zL,
// core->unknown);
SAcc = StringFromFormat(
//"%3d %3d %3d"
//" | %3d %3d %3d"
//" | %3d %3d %3d"
"| %5.2f %5.2f %5.2f"
//, calib->zero_g.x, calib->zero_g.y, calib->zero_g.z
//, (calib->zero_g.x<<2) + calib->zero_g.xL, (calib->zero_g.y<<2) + calib->zero_g.yL, (calib->zero_g.z<<2) + calib->zero_g.zL
//, calib->one_g.x, calib->one_g.y, calib->one_g.z
//, (calib->one_g.x<<2) + calib->one_g.xL, (calib->one_g.y<<2) + calib->one_g.yL, (calib->one_g.z<<2) + calib->one_g.zL
//, accel->x, accel->y, accel->z
//, (accel->x<<2) + core->xL, (accel->y<<2) + core->yL, (accel->z<<2) + core->zL
, (accel->x - calib->zero_g.x) / float(calib->one_g.x-calib->zero_g.x), (accel->y - calib->zero_g.y) / float(calib->one_g.y-calib->zero_g.y), (accel->z - calib->zero_g.z) / float(calib->one_g.z-calib->zero_g.z));
NOTICE_LOG(CONSOLE, "%d", size);
if (data[1] == WM_REPORT_CORE_ACCEL_IR12)
{
wm_ir_extended *ir = (wm_ir_extended*)&data[7];
SIR = StringFromFormat(
"%4u %4u | %u"
, ir->x | ir->xhi << 8
, ir->y | ir->yhi << 8
, ir->size);
}
if (data[1] == WM_REPORT_CORE_ACCEL_EXT16)
{
wm_extension *nc = (wm_extension*)&data[7];
SExt = StringFromFormat(
"%02x %02x | %02x %02x %02x | %02x"
, nc->jx, nc->jy
, nc->ax, nc->ay, nc->az
, nc->bt);
}
if (data[1] == WM_REPORT_CORE_ACCEL_IR10_EXT6)
{
wm_ir_basic *ir = (wm_ir_basic*)&data[7];
SIR = StringFromFormat(
"%4u %4u %4u %4u"
, ir->x1 | ir->x1hi << 8
, ir->y1 | ir->y1hi << 8
, ir->x2 | ir->x2hi << 8
, ir->y2 | ir->y1hi << 8);
/*
wm_motionplus *mp = (wm_motionplus*)&data[17];
wm_nc_mp *nc_mp = (wm_nc_mp *)&data[17];
if (mp->is_mp_data)
{
SExt = StringFromFormat(""
//"%02x %02x %02x %02x %02x %02x"
//"| %04x %04x %04x
" %5.2f %5.2f %5.2f"
" %s%s%s"
//, mp->roll1, mp->roll2
//, mp->pitch1, mp->pitch2
//, mp->yaw1, mp->yaw2
//, mp->pitch2<<8 | mp->pitch1
//, mp->roll2<<8 | mp->roll1
//, mp->yaw2<<8 | mp->yaw1
//, mp->pitch2<<8 | mp->pitch1
//, mp->roll2<<8 | mp->roll1
//, mp->yaw2<<8 | mp->yaw1
, float((mp->pitch2<<8 | mp->pitch1) - 0x1f7f) / float(0x1fff)
, float((mp->roll2<<8 | mp->roll1) - 0x1f7f) / float(0x1fff)
, float((mp->yaw2<<8 | mp->yaw1) - 0x1f7f) / float(0x1fff)
, mp->pitch_slow?"*":" ", mp->roll_slow?"*":" ", mp->yaw_slow?"*":" ");
}
else
{
SExt = StringFromFormat(
"%02x %02x | %02x %02x | %02x %02x %02x | %02x %02x %02x",
nc_mp->bz, nc_mp->bc,
nc_mp->jx, nc_mp->jy,
nc_mp->ax+nc_mp->axL, nc_mp->ay+nc_mp->ayL, (nc_mp->az<<1)+nc_mp->azL);
}
SExtID = StringFromFormat(
"[%s|%d|%d]"
, mp->is_mp_data ? "+" : "e"
, mp->is_mp_data ? mp->extension_connected : nc_mp->extension_connected
, wm->m_extension->active_extension);
*/
//DEBUG_LOG_S(CONSOLE, "M+ %d Extension %d %d %s", mp->is_mp_data, mp->is_mp_data ?
// mp->extension_connected : ((wm_nc_mp*)&data[17])->extension_connected, wm->m_extension->active_extension,
// ArrayToString(((u8*)&wm->m_reg_motion_plus.ext_identifier), sizeof(wm->m_reg_motion_plus.ext_identifier), 0).c_str());
}
// select log data
WARN_LOG_S(CONSOLE, "Data"
"[%s]"
" | id %s"
" | %s"
" | c %s"
" | a %s"
" | ir %s"
" | ext %s"
//" | %s"
//" | %s"
//" | %s"
, (emu ? "E" : "R")
, SExtID.c_str()
, ArrayToString(data, 2, 0).c_str()
, SCore.c_str()
, SAcc.c_str()
, SIR.c_str()
, SExt.c_str()
//, ArrayToString(&data[4], 3, 0).c_str()
//, (accel->x - 0x7f) / float(0xff), (accel->y - 0x7f) / float(0xff), (accel->z - 0x7f) / float(0xff)
//, ArrayToString(&data[17], 6, 0).c_str(),
);
}
#endif
}
void Wiimote::ReportMode(const wm_report_mode* const dr) void Wiimote::ReportMode(const wm_report_mode* const dr)
{ {
//INFO_LOG(WIIMOTE, "Set data report mode"); //INFO_LOG(WIIMOTE, "Set data report mode");
@ -64,7 +711,7 @@ void Wiimote::ReportMode(const wm_report_mode* const dr)
an Input Report back to the Wii. Input and Output is from the Wii's an Input Report back to the Wii. Input and Output is from the Wii's
perspective, Output means data to the Wiimote (from the Wii), Input means perspective, Output means data to the Wiimote (from the Wii), Input means
data from the Wiimote. data from the Wiimote.
The call browser: The call browser:
1. Wiimote_InterruptChannel > InterruptChannel > HidOutputReport 1. Wiimote_InterruptChannel > InterruptChannel > HidOutputReport
@ -231,7 +878,7 @@ void Wiimote::RequestStatus(const wm_request_status* const rs)
*(wm_status_report*)(data + 2) = m_status; *(wm_status_report*)(data + 2) = m_status;
// hybrid wiimote stuff // hybrid wiimote stuff
if (WIIMOTE_SRC_HYBRID == g_wiimote_sources[m_index] && (m_extension->switch_extension <= 0)) if (WIIMOTE_SRC_REAL & g_wiimote_sources[m_index] && (m_extension->switch_extension <= 0))
{ {
using namespace WiimoteReal; using namespace WiimoteReal;
@ -253,7 +900,7 @@ void Wiimote::RequestStatus(const wm_request_status* const rs)
/* Write data to Wiimote and Extensions registers. */ /* Write data to Wiimote and Extensions registers. */
void Wiimote::WriteData(const wm_write_data* const wd) void Wiimote::WriteData(const wm_write_data* const wd)
{ {
u32 address = swap24(wd->address); u32 address = Common::swap24(wd->address);
// ignore the 0x010000 bit // ignore the 0x010000 bit
address &= ~0x010000; address &= ~0x010000;
@ -290,7 +937,7 @@ void Wiimote::WriteData(const wm_write_data* const wd)
} }
} }
break; break;
case WM_SPACE_REGS1 : case WM_SPACE_REGS1 :
case WM_SPACE_REGS2 : case WM_SPACE_REGS2 :
{ {
@ -354,7 +1001,7 @@ void Wiimote::WriteData(const wm_write_data* const wd)
if (&m_reg_ext == region_ptr) if (&m_reg_ext == region_ptr)
{ {
// Run the key generation on all writes in the key area, it doesn't matter // Run the key generation on all writes in the key area, it doesn't matter
// that we send it parts of a key, only the last full key will have an effect // that we send it parts of a key, only the last full key will have an effect
if (address >= 0xa40040 && address <= 0xa4004c) if (address >= 0xa40040 && address <= 0xa4004c)
wiimote_gen_key(&m_ext_key, m_reg_ext.encryption_key); wiimote_gen_key(&m_ext_key, m_reg_ext.encryption_key);
@ -381,9 +1028,9 @@ void Wiimote::WriteData(const wm_write_data* const wd)
} }
/* Read data from Wiimote and Extensions registers. */ /* Read data from Wiimote and Extensions registers. */
void Wiimote::ReadData(const wm_read_data* const rd) void Wiimote::ReadData(const wm_read_data* const rd)
{ {
u32 address = swap24(rd->address); u32 address = Common::swap24(rd->address);
u16 size = Common::swap16(rd->size); u16 size = Common::swap16(rd->size);
// ignore the 0x010000 bit // ignore the 0x010000 bit
@ -391,10 +1038,10 @@ void Wiimote::ReadData(const wm_read_data* const rd)
// hybrid wiimote stuff // hybrid wiimote stuff
// relay the read data request to real-wiimote // relay the read data request to real-wiimote
if (WIIMOTE_SRC_HYBRID == g_wiimote_sources[m_index] && ((0xA4 != (address >> 16)) || (m_extension->switch_extension <= 0))) if (WIIMOTE_SRC_REAL & g_wiimote_sources[m_index] && ((0xA4 != (address >> 16)) || (m_extension->switch_extension <= 0)))
{ {
WiimoteReal::InterruptChannel(m_index, m_reporting_channel, ((u8*)rd) - 2, sizeof(wm_read_data) + 2); // hacky WiimoteReal::InterruptChannel(m_index, m_reporting_channel, ((u8*)rd) - 2, sizeof(wm_read_data) + 2); // hacky
// don't want emu-wiimote to send reply // don't want emu-wiimote to send reply
return; return;
} }
@ -408,9 +1055,9 @@ void Wiimote::ReadData(const wm_read_data* const rd)
{ {
//PanicAlert("ReadData: reading from EEPROM: address: 0x%x size: 0x%x", address, size); //PanicAlert("ReadData: reading from EEPROM: address: 0x%x size: 0x%x", address, size);
// Read from EEPROM // Read from EEPROM
if (address + size >= WIIMOTE_EEPROM_FREE_SIZE) if (address + size >= WIIMOTE_EEPROM_FREE_SIZE)
{ {
if (address + size > WIIMOTE_EEPROM_SIZE) if (address + size > WIIMOTE_EEPROM_SIZE)
{ {
PanicAlert("ReadData: address + size out of bounds"); PanicAlert("ReadData: address + size out of bounds");
delete [] block; delete [] block;
@ -503,7 +1150,7 @@ void Wiimote::ReadData(const wm_read_data* const rd)
} }
// want the requested address, not the above modified one // want the requested address, not the above modified one
rr.address = swap24(rd->address); rr.address = Common::swap24(rd->address);
rr.size = size; rr.size = size;
//rr.channel = _channelID; //rr.channel = _channelID;
rr.position = 0; rr.position = 0;
@ -643,6 +1290,21 @@ void Wiimote::DoState(PointerWrap& p)
} }
} }
p.DoMarker("Wiimote"); p.DoMarker("Wiimote");
if (p.GetMode() == PointerWrap::MODE_READ)
RealState();
}
// load real Wiimote state
void Wiimote::RealState()
{
using namespace WiimoteReal;
if (g_wiimotes[m_index])
{
g_wiimotes[m_index]->SetChannel(m_reporting_channel);
g_wiimotes[m_index]->EnableDataReporting(m_reporting_mode);
}
} }
} }

View File

@ -781,7 +781,10 @@ void Wiimote::Update()
// send data report // send data report
if (rptf_size) if (rptf_size)
{
WiimoteEmu::Spy(this, data, rptf_size);
Core::Callback_WiimoteInterruptChannel(m_index, m_reporting_channel, data, rptf_size); Core::Callback_WiimoteInterruptChannel(m_index, m_reporting_channel, data, rptf_size);
}
} }
void Wiimote::ControlChannel(const u16 _channelID, const void* _pData, u32 _Size) void Wiimote::ControlChannel(const u16 _channelID, const void* _pData, u32 _Size)
@ -853,7 +856,7 @@ void Wiimote::InterruptChannel(const u16 _channelID, const void* _pData, u32 _Si
{ {
const wm_report* const sr = (wm_report*)hidp->data; const wm_report* const sr = (wm_report*)hidp->data;
if (WIIMOTE_SRC_HYBRID == g_wiimote_sources[m_index]) if (WIIMOTE_SRC_REAL & g_wiimote_sources[m_index])
{ {
switch (sr->wm) switch (sr->wm)
{ {

View File

@ -24,6 +24,11 @@
#define WIIMOTE_REG_EXT_SIZE 0x100 #define WIIMOTE_REG_EXT_SIZE 0x100
#define WIIMOTE_REG_IR_SIZE 0x34 #define WIIMOTE_REG_IR_SIZE 0x34
namespace WiimoteReal
{
class Wiimote;
}
namespace WiimoteEmu namespace WiimoteEmu
{ {
@ -66,6 +71,8 @@ inline double trim(double a)
class Wiimote : public ControllerEmu class Wiimote : public ControllerEmu
{ {
friend class WiimoteReal::Wiimote;
friend void Spy(Wiimote* wm_, const void* data_, int size_);
public: public:
enum enum
@ -92,6 +99,7 @@ public:
void ControlChannel(const u16 _channelID, const void* _pData, u32 _Size); void ControlChannel(const u16 _channelID, const void* _pData, u32 _Size);
void DoState(PointerWrap& p); void DoState(PointerWrap& p);
void RealState();
void LoadDefaults(const ControllerInterface& ciface); void LoadDefaults(const ControllerInterface& ciface);
@ -235,6 +243,8 @@ private:
} m_reg_speaker; } m_reg_speaker;
}; };
void Spy(Wiimote* wm_, const void* data_, int size_);
} }
#endif #endif

View File

@ -597,6 +597,8 @@ int _IORead(HANDLE &dev_handle, OVERLAPPED &hid_overlap_read, u8* buf, int index
} }
} }
WiimoteEmu::Spy(NULL, buf, bytes + 1);
return bytes + 1; return bytes + 1;
} }
@ -611,6 +613,8 @@ int Wiimote::IORead(u8* buf)
int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stack_t &stack, const u8* buf, int len) int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stack_t &stack, const u8* buf, int len)
{ {
WiimoteEmu::Spy(NULL, buf, len);
switch (stack) switch (stack)
{ {
case MSBT_STACK_UNKNOWN: case MSBT_STACK_UNKNOWN:

View File

@ -110,6 +110,22 @@ void Wiimote::DisableDataReporting()
QueueReport(WM_REPORT_MODE, &rpt, sizeof(rpt)); QueueReport(WM_REPORT_MODE, &rpt, sizeof(rpt));
} }
void Wiimote::EnableDataReporting(u8 mode)
{
m_last_input_report.clear();
wm_report_mode rpt = {};
rpt.mode = mode;
rpt.all_the_time = 1;
rpt.continuous = 1;
QueueReport(WM_REPORT_MODE, &rpt, sizeof(rpt));
}
void Wiimote::SetChannel(u16 channel)
{
m_channel = channel;
}
void Wiimote::ClearReadQueue() void Wiimote::ClearReadQueue()
{ {
Report rpt; Report rpt;
@ -152,6 +168,7 @@ void Wiimote::InterruptChannel(const u16 channel, const void* const _data, const
auto const data = static_cast<const u8*>(_data); auto const data = static_cast<const u8*>(_data);
Report rpt(data, data + size); Report rpt(data, data + size);
WiimoteEmu::Wiimote *const wm = (WiimoteEmu::Wiimote*)::Wiimote::GetPlugin()->controllers[index];
// Convert output DATA packets to SET_REPORT packets. // Convert output DATA packets to SET_REPORT packets.
// Nintendo Wiimotes work without this translation, but 3rd // Nintendo Wiimotes work without this translation, but 3rd
@ -173,7 +190,8 @@ void Wiimote::InterruptChannel(const u16 channel, const void* const _data, const
} }
} }
else if (rpt[1] == WM_WRITE_SPEAKER_DATA else if (rpt[1] == WM_WRITE_SPEAKER_DATA
&& !SConfig::GetInstance().m_WiimoteEnableSpeaker) && (!SConfig::GetInstance().m_WiimoteEnableSpeaker
|| (!wm->m_status.speaker || wm->m_speaker_mute)))
{ {
// Translate speaker data reports into rumble reports. // Translate speaker data reports into rumble reports.
rpt[1] = WM_RUMBLE; rpt[1] = WM_RUMBLE;
@ -314,6 +332,44 @@ void Wiimote::EmuStop()
NOTICE_LOG(WIIMOTE, "Stopping Wiimote data reporting."); NOTICE_LOG(WIIMOTE, "Stopping Wiimote data reporting.");
} }
void Wiimote::EmuResume()
{
WiimoteEmu::Wiimote *const wm = (WiimoteEmu::Wiimote*)::Wiimote::GetPlugin()->controllers[index];
m_last_input_report.clear();
wm_report_mode rpt = {};
rpt.mode = wm->m_reporting_mode;
rpt.all_the_time = 1;
rpt.continuous = 1;
QueueReport(WM_REPORT_MODE, &rpt, sizeof(rpt));
NOTICE_LOG(WIIMOTE, "Resuming Wiimote data reporting.");
}
void Wiimote::EmuPause()
{
m_last_input_report.clear();
wm_report_mode rpt = {};
rpt.mode = WM_REPORT_CORE;
rpt.all_the_time = 0;
rpt.continuous = 0;
QueueReport(WM_REPORT_MODE, &rpt, sizeof(rpt));
NOTICE_LOG(WIIMOTE, "Pausing Wiimote data reporting.");
}
unsigned int CalculateConnectedWiimotes()
{
unsigned int connected_wiimotes = 0;
for (unsigned int i = 0; i < MAX_WIIMOTES; ++i)
if (g_wiimotes[i])
++connected_wiimotes;
return connected_wiimotes;
}
unsigned int CalculateWantedWiimotes() unsigned int CalculateWantedWiimotes()
{ {
// Figure out how many real Wiimotes are required // Figure out how many real Wiimotes are required
@ -470,12 +526,26 @@ void Initialize()
g_wiimote_scanner.StartScanning(); g_wiimote_scanner.StartScanning();
else else
g_wiimote_scanner.StopScanning(); g_wiimote_scanner.StopScanning();
std::lock_guard<std::recursive_mutex> lk(g_refresh_lock); std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes()); g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes());
g_wiimote_scanner.WantBB(0 != CalculateWantedBB()); g_wiimote_scanner.WantBB(0 != CalculateWantedBB());
// wait for connection because it should exist before state load
int timeout = 100;
std::vector<Wiimote*> found_wiimotes;
Wiimote* found_board = NULL;
g_wiimote_scanner.FindWiimotes(found_wiimotes, found_board);
if (SConfig::GetInstance().m_WiimoteContinuousScanning)
{
while(CalculateWantedWiimotes() && CalculateConnectedWiimotes() < found_wiimotes.size() && timeout)
{
Common::SleepCurrentThread(100);
timeout--;
}
}
if (g_real_wiimotes_initialized) if (g_real_wiimotes_initialized)
return; return;
@ -485,7 +555,14 @@ void Initialize()
} }
void Shutdown(void) void Shutdown(void)
{ {
for (unsigned int i = 0; i < MAX_BBMOTES; ++i)
if (g_wiimotes[i] && g_wiimotes[i]->IsConnected())
g_wiimotes[i]->EmuStop();
// WiimoteReal is shutdown on app exit
return;
g_wiimote_scanner.StopScanning(); g_wiimote_scanner.StopScanning();
std::lock_guard<std::recursive_mutex> lk(g_refresh_lock); std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
@ -501,6 +578,20 @@ void Shutdown(void)
HandleWiimoteDisconnect(i); HandleWiimoteDisconnect(i);
} }
void Resume()
{
for (unsigned int i = 0; i < MAX_BBMOTES; ++i)
if (g_wiimotes[i] && g_wiimotes[i]->IsConnected())
g_wiimotes[i]->EmuResume();
}
void Pause()
{
for (unsigned int i = 0; i < MAX_BBMOTES; ++i)
if (g_wiimotes[i] && g_wiimotes[i]->IsConnected())
g_wiimotes[i]->EmuPause();
}
void ChangeWiimoteSource(unsigned int index, int source) void ChangeWiimoteSource(unsigned int index, int source)
{ {
{ {

View File

@ -47,6 +47,8 @@ public:
// "handshake" / stop packets // "handshake" / stop packets
void EmuStart(); void EmuStart();
void EmuStop(); void EmuStop();
void EmuResume();
void EmuPause();
// connecting and disconnecting from physical devices // connecting and disconnecting from physical devices
// (using address inserted by FindWiimotes) // (using address inserted by FindWiimotes)
@ -59,6 +61,8 @@ public:
bool Prepare(int index); bool Prepare(int index);
void DisableDataReporting(); void DisableDataReporting();
void EnableDataReporting(u8 mode);
void SetChannel(u16 channel);
void QueueReport(u8 rpt_id, const void* data, unsigned int size); void QueueReport(u8 rpt_id, const void* data, unsigned int size);

View File

@ -138,27 +138,6 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::DoState(PointerWrap &p)
for (unsigned int i = 0; i < MAX_BBMOTES; i++) for (unsigned int i = 0; i < MAX_BBMOTES; i++)
m_WiiMotes[i].DoState(p); m_WiiMotes[i].DoState(p);
// Reset the connection of real and hybrid wiimotes
if (p.GetMode() == PointerWrap::MODE_READ && SConfig::GetInstance().m_WiimoteReconnectOnLoad)
{
for (unsigned int i = 0; i < MAX_BBMOTES; i++)
{
if (WIIMOTE_SRC_EMU == g_wiimote_sources[i] || WIIMOTE_SRC_NONE == g_wiimote_sources[i])
continue;
// TODO: Selectively clear real wiimote messages if possible. Or create a real wiimote channel and reporting mode pre-setup to vacate the need for m_WiimoteReconnectOnLoad.
m_EventQueue.clear();
if (!m_WiiMotes[i].IsInactive())
{
m_WiiMotes[i].Activate(false);
m_WiiMotes[i].Activate(true);
}
else
{
m_WiiMotes[i].Activate(false);
}
}
}
} }
bool CWII_IPC_HLE_Device_usb_oh1_57e_305::RemoteDisconnect(u16 _connectionHandle) bool CWII_IPC_HLE_Device_usb_oh1_57e_305::RemoteDisconnect(u16 _connectionHandle)
@ -508,18 +487,16 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update()
// The Real Wiimote sends report every ~5ms (200 Hz). // The Real Wiimote sends report every ~5ms (200 Hz).
const u64 interval = SystemTimers::GetTicksPerSecond() / 200; const u64 interval = SystemTimers::GetTicksPerSecond() / 200;
const u64 each_wiimote_interval = interval / m_WiiMotes.size();
const u64 now = CoreTiming::GetTicks(); const u64 now = CoreTiming::GetTicks();
if (now - m_last_ticks > each_wiimote_interval) if (now - m_last_ticks > interval)
{ {
static int wiimote_to_update = 0; for (unsigned int i = 0; i < m_WiiMotes.size(); i++)
if (m_WiiMotes[wiimote_to_update].IsConnected()) if (m_WiiMotes[i].IsConnected())
{ {
NetPlay_WiimoteUpdate(wiimote_to_update); NetPlay_WiimoteUpdate(i);
Wiimote::Update(wiimote_to_update); Wiimote::Update(i);
} }
wiimote_to_update = (wiimote_to_update + 1) % m_WiiMotes.size();
m_last_ticks = now; m_last_ticks = now;
} }

View File

@ -658,6 +658,8 @@ void Host_SetWiiMoteConnectionState(int _State)
// Update field 1 or 2 // Update field 1 or 2
event.SetInt(1); event.SetInt(1);
NOTICE_LOG(WIIMOTE, event.GetString().c_str());
main_frame->GetEventHandler()->AddPendingEvent(event); main_frame->GetEventHandler()->AddPendingEvent(event);
} }

View File

@ -106,7 +106,6 @@ WiimoteConfigDiag::WiimoteConfigDiag(wxWindow* const parent, InputPlugin& plugin
wxSlider* const WiiSensBarSens = new wxSlider(this, wxID_ANY, 0, 0, 4, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL); wxSlider* const WiiSensBarSens = new wxSlider(this, wxID_ANY, 0, 0, 4, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL);
wxSlider* const WiimoteSpkVolume = new wxSlider(this, wxID_ANY, 0, 0, 127); wxSlider* const WiimoteSpkVolume = new wxSlider(this, wxID_ANY, 0, 0, 127);
wxCheckBox* const WiimoteMotor = new wxCheckBox(this, wxID_ANY, _("Wiimote Motor")); wxCheckBox* const WiimoteMotor = new wxCheckBox(this, wxID_ANY, _("Wiimote Motor"));
wxCheckBox* const WiimoteReconnectOnLoad = new wxCheckBox(this, wxID_ANY, _("Reconnect Wiimote on State Loading"));
wxStaticText* const WiiSensBarPosText = new wxStaticText(this, wxID_ANY, _("Sensor Bar Position:")); wxStaticText* const WiiSensBarPosText = new wxStaticText(this, wxID_ANY, _("Sensor Bar Position:"));
wxStaticText* const WiiSensBarSensText = new wxStaticText(this, wxID_ANY, _("IR Sensitivity:")); wxStaticText* const WiiSensBarSensText = new wxStaticText(this, wxID_ANY, _("IR Sensitivity:"));
@ -143,13 +142,11 @@ WiimoteConfigDiag::WiimoteConfigDiag(wxWindow* const parent, InputPlugin& plugin
WiiSensBarSens->SetValue(SConfig::GetInstance().m_SYSCONF->GetData<u32>("BT.SENS")); WiiSensBarSens->SetValue(SConfig::GetInstance().m_SYSCONF->GetData<u32>("BT.SENS"));
WiimoteSpkVolume->SetValue(SConfig::GetInstance().m_SYSCONF->GetData<u8>("BT.SPKV")); WiimoteSpkVolume->SetValue(SConfig::GetInstance().m_SYSCONF->GetData<u8>("BT.SPKV"));
WiimoteMotor->SetValue(SConfig::GetInstance().m_SYSCONF->GetData<bool>("BT.MOT")); WiimoteMotor->SetValue(SConfig::GetInstance().m_SYSCONF->GetData<bool>("BT.MOT"));
WiimoteReconnectOnLoad->SetValue(SConfig::GetInstance().m_WiimoteReconnectOnLoad);
WiiSensBarPos->Bind(wxEVT_COMMAND_CHOICE_SELECTED, &WiimoteConfigDiag::OnSensorBarPos, this); WiiSensBarPos->Bind(wxEVT_COMMAND_CHOICE_SELECTED, &WiimoteConfigDiag::OnSensorBarPos, this);
WiiSensBarSens->Bind(wxEVT_COMMAND_SLIDER_UPDATED, &WiimoteConfigDiag::OnSensorBarSensitivity, this); WiiSensBarSens->Bind(wxEVT_COMMAND_SLIDER_UPDATED, &WiimoteConfigDiag::OnSensorBarSensitivity, this);
WiimoteSpkVolume->Bind(wxEVT_COMMAND_SLIDER_UPDATED, &WiimoteConfigDiag::OnSpeakerVolume, this); WiimoteSpkVolume->Bind(wxEVT_COMMAND_SLIDER_UPDATED, &WiimoteConfigDiag::OnSpeakerVolume, this);
WiimoteMotor->Bind(wxEVT_COMMAND_CHECKBOX_CLICKED, &WiimoteConfigDiag::OnMotor, this); WiimoteMotor->Bind(wxEVT_COMMAND_CHECKBOX_CLICKED, &WiimoteConfigDiag::OnMotor, this);
WiimoteReconnectOnLoad->Bind(wxEVT_COMMAND_CHECKBOX_CLICKED, &WiimoteConfigDiag::OnReconnectOnLoad, this);
// "General Settings" layout // "General Settings" layout
@ -175,7 +172,6 @@ WiimoteConfigDiag::WiimoteConfigDiag(wxWindow* const parent, InputPlugin& plugin
wxGridSizer* const general_wiimote_sizer = new wxGridSizer(1, 5, 5); wxGridSizer* const general_wiimote_sizer = new wxGridSizer(1, 5, 5);
general_wiimote_sizer->Add(WiimoteMotor); general_wiimote_sizer->Add(WiimoteMotor);
general_wiimote_sizer->Add(WiimoteReconnectOnLoad);
general_sizer->Add(choice_sizer); general_sizer->Add(choice_sizer);
general_sizer->Add(general_wiimote_sizer); general_sizer->Add(general_wiimote_sizer);

View File

@ -52,11 +52,6 @@ public:
SConfig::GetInstance().m_SYSCONF->SetData("BT.MOT", event.GetInt()); SConfig::GetInstance().m_SYSCONF->SetData("BT.MOT", event.GetInt());
event.Skip(); event.Skip();
} }
void OnReconnectOnLoad(wxCommandEvent& event)
{
SConfig::GetInstance().m_WiimoteReconnectOnLoad = event.IsChecked();
event.Skip();
}
void OnContinuousScanning(wxCommandEvent& event) void OnContinuousScanning(wxCommandEvent& event)
{ {
SConfig::GetInstance().m_WiimoteContinuousScanning = event.IsChecked(); SConfig::GetInstance().m_WiimoteContinuousScanning = event.IsChecked();