An attempt to fix Issue 1919 (Multi-Wiimote Freezing)

Please test.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4787 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
ayuanx 2010-01-05 17:39:06 +00:00
parent 6500db254f
commit 516f7a4ca1
11 changed files with 137 additions and 135 deletions

View File

@ -42,6 +42,7 @@ CWII_IPC_HLE_Device_usb_oh1_57e_305::CWII_IPC_HLE_Device_usb_oh1_57e_305(u32 _De
, m_ACLBuffer(NULL)
, m_ACLPool(0)
, m_LastCmd(0)
, m_FreqDividerMote(0)
, m_FreqDividerSync(0)
{
// Activate only first Wiimote by default
@ -65,7 +66,6 @@ CWII_IPC_HLE_Device_usb_oh1_57e_305::CWII_IPC_HLE_Device_usb_oh1_57e_305(u32 _De
memset(m_LocalName, 0, HCI_UNIT_NAME_SIZE);
memset(m_PacketCount, 0, sizeof(m_PacketCount));
memset(m_FreqDividerMote, 0, sizeof(m_FreqDividerMote));
Host_SetWiiMoteConnectionState(0);
}
@ -85,11 +85,11 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::DoState(PointerWrap &p)
p.Do(m_ACLBuffer);
p.Do(m_ACLPool);
p.Do(m_FreqDividerSync);
p.Do(m_FreqDividerMote);
for (int i = 0; i < 4; i++)
{
p.Do(m_PacketCount[i]);
p.Do(m_FreqDividerMote[i]);
}
for (unsigned int i = 0; i < m_WiiMotes.size(); i++)
@ -105,6 +105,25 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::RemoteDisconnect(u16 _connectionHandle
// Open
bool CWII_IPC_HLE_Device_usb_oh1_57e_305::Open(u32 _CommandAddress, u32 _Mode)
{
m_PINType = 0;
m_ScanEnable = 0;
m_EventFilterType = 0;
m_EventFilterCondition = 0;
m_HostMaxACLSize = 0;
m_HostMaxSCOSize = 0;
m_HostNumACLPackets = 0;
m_HostNumSCOPackets = 0;
m_LastCmd = 0;
m_FreqDividerSync = 0;
m_FreqDividerMote = 0;
memset(m_PacketCount, 0, sizeof(m_PacketCount));
m_HCIBuffer.m_address = 0;
m_HCIPool.m_number = 0;
m_ACLBuffer.m_address = 0;
m_ACLPool.m_number = 0;
Memory::Write_U32(GetDeviceID(), _CommandAddress+4);
m_Active = true;
return true;
@ -125,7 +144,7 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::Close(u32 _CommandAddress, bool _bForc
m_LastCmd = 0;
m_FreqDividerSync = 0;
memset(m_FreqDividerMote, 0, sizeof(m_FreqDividerMote));
m_FreqDividerMote = 0;
memset(m_PacketCount, 0, sizeof(m_PacketCount));
m_HCIBuffer.m_address = 0;
@ -469,12 +488,6 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update()
}
}
// AyuanX: Actually we don't need to link channels so early
// We can wait until HCI command: CommandReadRemoteFeatures is finished
// Because at this moment, CPU is busy handling HCI commands
// and have no time to respond ACL requests shortly
// But ... whatever, either way works
//
// Link channels when connected
if (m_ACLBuffer.m_address && !m_LastCmd && !WII_IPCInterface::GetAddress())
{
@ -490,12 +503,12 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update()
// Calculation: 15000Hz (IPC_HLE) / 100Hz (WiiMote) = 150
if (m_ACLBuffer.m_address && !m_LastCmd)
{
if (++m_FreqDividerMote > 150)
m_FreqDividerMote = 0;
for (unsigned int i = 0; i < m_WiiMotes.size(); i++)
{
m_FreqDividerMote[i]++;
if (m_WiiMotes[i].IsConnected() == 3 && m_FreqDividerMote[i] >= 150)
if (m_WiiMotes[i].IsConnected() == 3 && m_FreqDividerMote == 150 / (i + 1))
{
m_FreqDividerMote[i] = 0;
CPluginManager::GetInstance().GetWiimote(0)->Wiimote_Update(i);
return true;
}
@ -508,17 +521,15 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update()
// TODO: Figure out the correct frequency to send this thing
if (m_HCIBuffer.m_address && !WII_IPCInterface::GetAddress())
{
m_FreqDividerSync++;
if (m_FreqDividerSync >= 500) // Feel free to tweak it
{
if (++m_FreqDividerSync > 500)
m_FreqDividerSync = 0;
for (unsigned int i = 0; i < m_WiiMotes.size(); i++)
for (unsigned int i = 0; i < m_WiiMotes.size(); i++)
{
if (m_WiiMotes[i].IsConnected() == 3 && m_FreqDividerSync == 500 / (i + 1))
{
if (m_WiiMotes[i].IsConnected() == 3)
{
SendEventNumberOfCompletedPackets();
return true;
}
SendEventNumberOfCompletedPackets(m_WiiMotes[i].GetConnectionHandle(), m_PacketCount[i]);
m_PacketCount[i] = 0;
return true;
}
}
}
@ -971,38 +982,29 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventRoleChange(bdaddr_t _bd, bool
return true;
}
bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventNumberOfCompletedPackets()
bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventNumberOfCompletedPackets(u16 _connectionHandle, u16 _count)
{
int Num = 0;
for (unsigned int i = 0; i < m_WiiMotes.size(); i++)
CWII_IPC_HLE_WiiMote* pWiiMote = AccessWiiMote(_connectionHandle);
if (pWiiMote == NULL)
{
if (m_WiiMotes[i].IsConnected() == 3)
Num++;
ERROR_LOG(WII_IPC_WIIMOTE, "SendEventNumberOfCompletedPackets: Cant find WiiMote by connection handle %02x", _connectionHandle);
PanicAlert("SendEventNumberOfCompletedPackets: Cant find WiiMote by connection handle %02x", _connectionHandle);
return false;
}
if (Num == 0)
return false;
SQueuedEvent Event(sizeof(SHCIEventNumberOfCompletedPackets) + Num * 4, 0);
SQueuedEvent Event(sizeof(SHCIEventNumberOfCompletedPackets), 0); // zero, so this packet isnt counted
SHCIEventNumberOfCompletedPackets* pNumberOfCompletedPackets = (SHCIEventNumberOfCompletedPackets*)Event.m_buffer;
pNumberOfCompletedPackets->EventType = HCI_EVENT_NUM_COMPL_PKTS;
pNumberOfCompletedPackets->PayloadLength = sizeof(SHCIEventNumberOfCompletedPackets) + Num * 4 - 2;
pNumberOfCompletedPackets->NumberOfHandles = Num;
u16 *pData = (u16 *)(Event.m_buffer + sizeof(SHCIEventNumberOfCompletedPackets));
for (unsigned int i = 0; i < m_WiiMotes.size(); i++)
{
if (m_WiiMotes[i].IsConnected() != 3) continue;
pData[0] = m_WiiMotes[i].GetConnectionHandle();
pData[Num] = m_PacketCount[i];
m_PacketCount[i] = 0;
pData++;
}
pNumberOfCompletedPackets->EventType = 0x13;
pNumberOfCompletedPackets->PayloadLength = sizeof(SHCIEventNumberOfCompletedPackets) - 2;
pNumberOfCompletedPackets->NumberOfHandles = 1;
pNumberOfCompletedPackets->Connection_Handle = _connectionHandle;
pNumberOfCompletedPackets->Number_Of_Completed_Packets = _count;
// Log
INFO_LOG(WII_IPC_WIIMOTE, "Event: SendEventNumberOfCompletedPackets");
DEBUG_LOG(WII_IPC_WIIMOTE, " NumberOfConnectionHandle: 0x%04x", pNumberOfCompletedPackets->NumberOfHandles);
DEBUG_LOG(WII_IPC_WIIMOTE, " Connection_Handle: 0x%04x", pNumberOfCompletedPackets->Connection_Handle);
DEBUG_LOG(WII_IPC_WIIMOTE, " Number_Of_Completed_Packets: %i", pNumberOfCompletedPackets->Number_Of_Completed_Packets);
AddEventToQueue(Event);

View File

@ -163,7 +163,7 @@ private:
{
if(_Address == 0)
{
m_buffer = NULL;
m_buffer = 0;
}
else
{
@ -197,7 +197,7 @@ private:
ACLPool m_ACLPool;
u32 m_LastCmd;
u32 m_PacketCount[4];
u32 m_FreqDividerMote[4];
u32 m_FreqDividerMote;
u32 m_FreqDividerSync;
// Events
@ -214,7 +214,7 @@ private:
bool SendEventReadRemoteVerInfo(u16 _connectionHandle);
bool SendEventReadRemoteFeatures(u16 _connectionHandle);
bool SendEventRoleChange(bdaddr_t _bd, bool _master);
bool SendEventNumberOfCompletedPackets();
bool SendEventNumberOfCompletedPackets(u16 _connectionHandle, u16 _count);
bool SendEventAuthenticationCompleted(u16 _connectionHandle);
bool SendEventModeChange(u16 _connectionHandle, u8 _mode, u16 _value);
bool SendEventDisconnect(u16 _connectionHandle, u8 _Reason);

View File

@ -2507,6 +2507,8 @@ struct SHCIEventNumberOfCompletedPackets
u8 EventType;
u8 PayloadLength;
u8 NumberOfHandles;
u16 Connection_Handle;
u16 Number_Of_Completed_Packets;
};
struct SHCIEventAuthenticationCompleted

View File

@ -17,9 +17,6 @@
// Based off of tachtig http://git.infradead.org/?p=users/segher/wii.git
#ifdef _WIN32
#include "stdafx.h"
#endif
#include "WiiSaveCrypted.h"
#include "FileUtil.h"

View File

@ -73,13 +73,18 @@ void WmReportMode(u16 _channelID, wm_report_mode* dr)
INFO_LOG(WIIMOTE, "Set data report mode");
DEBUG_LOG(WIIMOTE, " Rumble: %x", dr->rumble);
DEBUG_LOG(WIIMOTE, " Continuous: %x", dr->continuous);
DEBUG_LOG(WIIMOTE, " All The Time: %x (not only on data change)", dr->all_the_time);
DEBUG_LOG(WIIMOTE, " All The Time: %x", dr->all_the_time);
DEBUG_LOG(WIIMOTE, " Mode: 0x%02x", dr->mode);
g_ReportingAuto[g_ID] = dr->all_the_time;
g_ReportingMode[g_ID] = dr->mode;
g_ReportingChannel[g_ID] = _channelID;
if (dr->all_the_time == 0)
{
PanicAlert("Wiimote: Reporting Always is set to OFF!");
}
// Validation check
switch(dr->mode)
{

View File

@ -35,19 +35,18 @@ namespace WiiMoteEmu
//******************************************************************************
// Definitions and variable declarations
//******************************************************************************
u8 g_IR[4];
u8 g_Leds[4];
u8 g_Speaker;
u8 g_SpeakerVoice;
u8 g_Eeprom[MAX_WIIMOTES][WIIMOTE_EEPROM_SIZE];
u8 g_RegExt[MAX_WIIMOTES][WIIMOTE_REG_EXT_SIZE];
u8 g_RegMotionPlus[MAX_WIIMOTES][WIIMOTE_REG_EXT_SIZE];
u8 g_RegSpeaker[MAX_WIIMOTES][WIIMOTE_REG_SPEAKER_SIZE];
u8 g_RegIr[MAX_WIIMOTES][WIIMOTE_REG_IR_SIZE];
u8 g_IRClock[MAX_WIIMOTES];
u8 g_IR[MAX_WIIMOTES];
u8 g_Leds[MAX_WIIMOTES];
u8 g_Speaker[MAX_WIIMOTES];
u8 g_SpeakerMute[MAX_WIIMOTES];
u8 g_Eeprom[WIIMOTE_EEPROM_SIZE];
u8 g_RegSpeaker[WIIMOTE_REG_SPEAKER_SIZE];
u8 g_RegMotionPlus[WIIMOTE_REG_EXT_SIZE];
u8 g_RegExtTmp[WIIMOTE_REG_EXT_SIZE];
u8 g_RegIr[WIIMOTE_REG_IR_SIZE];
int g_ID; // Current refreshing Wiimote
bool g_ReportingAuto[MAX_WIIMOTES]; // Auto report or passive report

View File

@ -68,18 +68,18 @@ extern double g_RecordingCurrentTime[3];
#define WIIMOTE_REG_EXT_SIZE 0x100
#define WIIMOTE_REG_IR_SIZE 0x34
extern u8 g_IR[4];
extern u8 g_Leds[4];
extern u8 g_Speaker;
extern u8 g_SpeakerVoice;
extern u8 g_Eeprom[MAX_WIIMOTES][WIIMOTE_EEPROM_SIZE];
extern u8 g_RegExt[MAX_WIIMOTES][WIIMOTE_REG_EXT_SIZE];
extern u8 g_RegMotionPlus[MAX_WIIMOTES][WIIMOTE_REG_EXT_SIZE];
extern u8 g_RegSpeaker[MAX_WIIMOTES][WIIMOTE_REG_SPEAKER_SIZE];
extern u8 g_RegIr[MAX_WIIMOTES][WIIMOTE_REG_IR_SIZE];
extern u8 g_IRClock[MAX_WIIMOTES];
extern u8 g_IR[MAX_WIIMOTES];
extern u8 g_Leds[MAX_WIIMOTES];
extern u8 g_Speaker[MAX_WIIMOTES];
extern u8 g_SpeakerMute[MAX_WIIMOTES];
extern u8 g_Eeprom[WIIMOTE_EEPROM_SIZE];
extern u8 g_RegSpeaker[WIIMOTE_REG_SPEAKER_SIZE];
extern u8 g_RegMotionPlus[WIIMOTE_REG_EXT_SIZE];
extern u8 g_RegExtTmp[WIIMOTE_REG_EXT_SIZE];
extern u8 g_RegIr[WIIMOTE_REG_IR_SIZE];
extern int g_ID;
extern bool g_ReportingAuto[MAX_WIIMOTES];

View File

@ -333,16 +333,18 @@ void Initialize()
g_SearchDeviceDone = true;
}
// Write default Eeprom data to g_Eeprom[], this may be overwritten by
// WiiMoteReal::Initialize() after this function.
memset(g_Eeprom, 0, WIIMOTE_EEPROM_SIZE);
memcpy(g_Eeprom, EepromData_0, sizeof(EepromData_0));
memcpy(g_Eeprom + 0x16D0, EepromData_16D0, sizeof(EepromData_16D0));
InitCalibration();
// Copy extension id and calibration to its register, g_Config.Load() is needed before this
for (int i = 0; i < MAX_WIIMOTES; i++)
{
// Write default Eeprom data to g_Eeprom[], this may be overwritten by
// WiiMoteReal::Initialize() after this function.
memset(g_Eeprom[i], 0, WIIMOTE_EEPROM_SIZE);
memcpy(g_Eeprom[i], EepromData_0, sizeof(EepromData_0));
memcpy(g_Eeprom[i] + 0x16D0, EepromData_16D0, sizeof(EepromData_16D0));
// Copy extension id and calibration to its register, g_Config.Load() is needed before this
UpdateExtRegisterBlocks(i);
}
// The emulated Wiimote is initialized
g_EmulatedWiiMoteInitialized = true;
@ -397,12 +399,12 @@ void ResetVariables()
// Initiate the accelerometer neutral values
void InitCalibration()
{
g_wm.cal_zero.x = g_Eeprom[22];
g_wm.cal_zero.y = g_Eeprom[23];
g_wm.cal_zero.z = g_Eeprom[24];
g_wm.cal_g.x = g_Eeprom[26] - g_Eeprom[22];
g_wm.cal_g.y = g_Eeprom[27] - g_Eeprom[23];
g_wm.cal_g.z = g_Eeprom[28] - g_Eeprom[24];
g_wm.cal_zero.x = EepromData_0[22];
g_wm.cal_zero.y = EepromData_0[23];
g_wm.cal_zero.z = EepromData_0[24];
g_wm.cal_g.x = EepromData_0[26] - EepromData_0[22];
g_wm.cal_g.y = EepromData_0[27] - EepromData_0[23];
g_wm.cal_g.z = EepromData_0[28] - EepromData_0[24];
g_nu.cal_zero.x = nunchuck_calibration[0x00];
g_nu.cal_zero.y = nunchuck_calibration[0x01];
@ -474,14 +476,12 @@ void UpdateExtRegisterBlocks(int Slot)
void DoState(PointerWrap &p)
{
// TODO: Shorten the list
p.Do(g_Speaker);
p.Do(g_SpeakerVoice);
p.DoArray(g_Eeprom, WIIMOTE_EEPROM_SIZE);
p.DoArray(g_RegSpeaker, WIIMOTE_REG_SPEAKER_SIZE);
p.DoArray(&g_Eeprom[0][0], WIIMOTE_EEPROM_SIZE * MAX_WIIMOTES);
p.DoArray(&g_RegExt[0][0], WIIMOTE_REG_EXT_SIZE * MAX_WIIMOTES);
p.DoArray(g_RegMotionPlus, WIIMOTE_REG_EXT_SIZE);
p.DoArray(g_RegExtTmp, WIIMOTE_REG_EXT_SIZE);
p.DoArray(g_RegIr, WIIMOTE_REG_IR_SIZE);
p.DoArray(&g_RegMotionPlus[0][0], WIIMOTE_REG_EXT_SIZE * MAX_WIIMOTES);
p.DoArray(&g_RegSpeaker[0][0], WIIMOTE_REG_SPEAKER_SIZE * MAX_WIIMOTES);
p.DoArray(&g_RegIr[0][0], WIIMOTE_REG_IR_SIZE * MAX_WIIMOTES);
//p.DoArray(g_RegExtTmp, WIIMOTE_REG_EXT_SIZE);
p.Do(g_Encryption);
@ -499,8 +499,11 @@ void DoState(PointerWrap &p)
p.Do(g_ReportingAuto[i]);
p.Do(g_ReportingMode[i]);
p.Do(g_ReportingChannel[i]);
//p.Do(g_IR[i]);
//p.Do(g_IRClock[i]);
p.Do(g_IR[i]);
p.Do(g_Leds[i]);
p.Do(g_Speaker[i]);
//p.Do(g_SpeakerMute[i]);
p.Do(g_ExtKey[i]);
}
return;

View File

@ -58,22 +58,23 @@ extern void PAD_Rumble(u8 _numPAD, unsigned int _uType);
1. Wiimote_InterruptChannel > InterruptChannel > HidOutputReport
2. Wiimote_ControlChannel > ControlChannel > HidOutputReport
The IR lights and speaker enable/disable and mute/unmute values are
0x2 = Disable
0x6 = Enable
The IR enable/disable and speaker enable/disable and mute/unmute values are
bit2: 0 = Disable (0x02), 1 = Enable (0x06)
*/
void HidOutputReport(u16 _channelID, wm_report* sr)
{
INFO_LOG(WIIMOTE, "HidOutputReport (cid: 0x%02x, wm: 0x%02x)", _channelID, sr->wm);
INFO_LOG(WIIMOTE, "HidOutputReport (page: %i, cid: 0x%02x, wm: 0x%02x)", g_ID, _channelID, sr->wm);
switch(sr->wm)
{
case WM_RUMBLE: // 0x10
PAD_Rumble(g_ID, sr->data[0]);
if (WiiMapping[g_ID].Rumble && WiiMapping[g_ID].ID < NumGoodPads)
PAD_Rumble(g_ID, sr->data[0]);
break;
case WM_LEDS: // 0x11
WmLeds(_channelID, (wm_leds*)sr->data);
INFO_LOG(WIIMOTE, "Set LEDs: 0x%02x", sr->data[0]);
g_Leds[g_ID] = sr->data[0] >> 4;
break;
case WM_REPORT_MODE: // 0x12
@ -81,18 +82,13 @@ void HidOutputReport(u16 _channelID, wm_report* sr)
break;
case WM_IR_PIXEL_CLOCK: // 0x13
case WM_IR_LOGIC: // 0x1a
// This enables or disables the IR lights, we update the global variable g_IR
// so that WmRequestStatus() knows about it
INFO_LOG(WIIMOTE, "WM IR Enable: 0x%02x", sr->data[0]);
if(sr->data[0] == 0x02) g_IR[g_ID] = 0;
else if(sr->data[0] == 0x06) g_IR[g_ID] = 1;
INFO_LOG(WIIMOTE, "WM IR Clock: 0x%02x", sr->data[0]);
//g_IRClock[g_ID] = (sr->data[0] & 0x04) ? 1 : 0;
break;
case WM_SPEAKER_ENABLE: // 0x14
INFO_LOG(WIIMOTE, "WM Speaker Enable: 0x%02x", sr->data[0]);
if(sr->data[0] == 0x02) g_Speaker = 0;
else if(sr->data[0] == 0x06) g_Speaker = 1;
g_Speaker[g_ID] = (sr->data[0] & 0x04) ? 1 : 0;
break;
case WM_REQUEST_STATUS: // 0x15
@ -112,9 +108,15 @@ void HidOutputReport(u16 _channelID, wm_report* sr)
break;
case WM_SPEAKER_MUTE: // 0x19
INFO_LOG(WIIMOTE, "WM Mute Enable: 0x%02x", sr->data[0]);
if(sr->data[0] == 0x02) g_SpeakerVoice = 0; // g_SpeakerVoice
else if(sr->data[0] == 0x06) g_SpeakerVoice = 1;
INFO_LOG(WIIMOTE, "WM Speaker Mute: 0x%02x", sr->data[0]);
//g_SpeakerMute[g_ID] = (sr->data[0] & 0x04) ? 1 : 0;
break;
case WM_IR_LOGIC: // 0x1a
// This enables or disables the IR lights, we update the global variable g_IR
// so that WmRequestStatus() knows about it
INFO_LOG(WIIMOTE, "WM IR Enable: 0x%02x", sr->data[0]);
g_IR[g_ID] = (sr->data[0] & 0x04) ? 1 : 0;
break;
default:
@ -155,15 +157,6 @@ int WriteWmReportHdr(u8* dst, u8 wm)
return Offset;
}
/* LED (blue lights) report. */
void WmLeds(u16 _channelID, wm_leds* leds)
{
INFO_LOG(WIIMOTE, "Set LEDs: %x, Rumble: %x", leds->leds, leds->rumble);
g_Leds[g_ID] = leds->leds;
}
/* This will generate the 0x22 acknowledgement for most Input reports.
It has the form of "a1 22 00 00 _reportID 00".
The first two bytes are the core buttons data,
@ -213,7 +206,7 @@ void WmReadData(u16 _channelID, wm_read_data* rd)
PanicAlert("WmReadData: address + size out of bounds");
return;
}
SendReadDataReply(_channelID, g_Eeprom + address, address, (int)size);
SendReadDataReply(_channelID, g_Eeprom[g_ID] + address, address, (int)size);
/*DEBUG_LOG(WIIMOTE, "Read RegEeprom: Size: %i, Address: %08x, Offset: %08x",
size, address, (address & 0xffff));*/
}
@ -224,10 +217,11 @@ void WmReadData(u16 _channelID, wm_read_data* rd)
switch((address >> 16) & 0xFE)
{
case 0xA2:
block = g_RegSpeaker;
block = g_RegSpeaker[g_ID];
blockSize = WIIMOTE_REG_SPEAKER_SIZE;
DEBUG_LOG(WIIMOTE, " Case 0xa2: g_RegSpeaker");
break;
case 0xA4:
block = g_RegExt[g_ID];
blockSize = WIIMOTE_REG_EXT_SIZE;
@ -236,7 +230,7 @@ void WmReadData(u16 _channelID, wm_read_data* rd)
// MotionPlus is pretty much just a dummy atm :p
case 0xA6:
block = g_RegMotionPlus;
block = g_RegMotionPlus[g_ID];
block[0xFC] = 0xA6;
block[0xFD] = 0x20;
block[0xFE] = 0x00;
@ -246,13 +240,14 @@ void WmReadData(u16 _channelID, wm_read_data* rd)
break;
case 0xB0:
block = g_RegIr;
block = g_RegIr[g_ID];
blockSize = WIIMOTE_REG_IR_SIZE;
DEBUG_LOG(WIIMOTE, " Case 0xb0: g_RegIr");
break;
default:
ERROR_LOG(WIIMOTE, "WmReadData: bad register block!");
PanicAlert("WmReadData: bad register block!");
return;
}
@ -389,7 +384,7 @@ void WmWriteData(u16 _channelID, wm_write_data* wd)
PanicAlert("WmWriteData: address + size out of bounds!");
return;
}
memcpy(g_Eeprom + address, wd->data, wd->size);
memcpy(g_Eeprom[g_ID] + address, wd->data, wd->size);
}
// Write to registers
else if(wd->size <= 16 && (wd->space == WM_SPACE_REGS1 || wd->space == WM_SPACE_REGS2))
@ -399,10 +394,11 @@ void WmWriteData(u16 _channelID, wm_write_data* wd)
switch((address >> 16) & 0xFE)
{
case 0xA2:
block = g_RegSpeaker;
block = g_RegSpeaker[g_ID];
blockSize = WIIMOTE_REG_SPEAKER_SIZE;
DEBUG_LOG(WIIMOTE, " Case 0xa2: RegSpeaker");
break;
case 0xA4:
block = g_RegExt[g_ID]; // Extension Controller register
blockSize = WIIMOTE_REG_EXT_SIZE;
@ -410,13 +406,13 @@ void WmWriteData(u16 _channelID, wm_write_data* wd)
break;
case 0xA6:
block = g_RegMotionPlus;
block = g_RegMotionPlus[g_ID];
blockSize = WIIMOTE_REG_EXT_SIZE;
DEBUG_LOG(WIIMOTE, " Case 0xa6: MotionPlusReg [%x]", address);
break;
case 0xB0:
block = g_RegIr;
block = g_RegIr[g_ID];
blockSize = WIIMOTE_REG_IR_SIZE;
INFO_LOG(WIIMOTE, " Case 0xb0: RegIr");
break;
@ -426,21 +422,18 @@ void WmWriteData(u16 _channelID, wm_write_data* wd)
PanicAlert("WmWriteData: bad register block!");
return;
}
// Remove for example 0xa40000 from the address
address &= 0xFFFF;
// Check if the address is within bounds
if(address + wd->size > blockSize) {
if((address & 0xFFFF) + wd->size > blockSize) {
PanicAlert("WmWriteData: address + size out of bounds!");
return;
}
// Finally write the registers to the right structure
memcpy(block + address, wd->data, wd->size);
memcpy(block + (address & 0xFFFF), wd->data, wd->size);
// Generate key for the Wiimote Extension
if(blockSize == WIIMOTE_REG_EXT_SIZE)
if(((address >> 16) & 0xfe) == 0xa4)
{
/* 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
@ -480,7 +473,7 @@ void WmRequestStatus(u16 _channelID, wm_request_status* rs, int Extension)
#endif
pStatus->leds = g_Leds[g_ID]; // leds are 4 bit
pStatus->ir = g_IR[g_ID]; // 1 bit
pStatus->speaker = g_Speaker; // 1 bit
pStatus->speaker = g_Speaker[g_ID]; // 1 bit
pStatus->battery_low = 0; // battery is okay
pStatus->battery = 0x5f; // fully charged
/* Battery levels in voltage
@ -501,8 +494,11 @@ void WmRequestStatus(u16 _channelID, wm_request_status* rs, int Extension)
}
INFO_LOG(WIIMOTE, "Request Status");
DEBUG_LOG(WIIMOTE, " Extension: %x", pStatus->extension);
DEBUG_LOG(WIIMOTE, " Buttons: 0x%04x", pStatus->buttons);
DEBUG_LOG(WIIMOTE, " Extension: %x", pStatus->extension);
DEBUG_LOG(WIIMOTE, " Speaker: %x", pStatus->speaker);
DEBUG_LOG(WIIMOTE, " IR: %x", pStatus->ir);
DEBUG_LOG(WIIMOTE, " LEDs: %x", pStatus->leds);
g_WiimoteInitialize.pWiimoteInput(g_ID, _channelID, DataFrame, Offset);

View File

@ -37,7 +37,6 @@ namespace WiiMoteEmu
void HidOutputReport(u16 _channelID, wm_report* sr);
void WmLeds(u16 _channelID, wm_leds* leds);
void WmReadData(u16 _channelID, wm_read_data* rd);
void WmWriteData(u16 _channelID, wm_write_data* wd);
void WmRequestStatus(u16 _channelID, wm_request_status* rs, int Extension = -1);

View File

@ -323,9 +323,8 @@ void ReadWiimote()
&& g_WiiMotesFromWiiUse[i]->read_req->addr == 0)
{
Temp = ArrayToString(g_WiiMotesFromWiiUse[i]->read_req->buf, sizeof(WiiMoteEmu::EepromData_0), 0, 30);
memcpy(WiiMoteEmu::g_Eeprom, g_WiiMotesFromWiiUse[i]->read_req->buf, sizeof(WiiMoteEmu::EepromData_0));
//memcpy(WiiMoteEmu::g_Eeprom[i], g_WiiMotesFromWiiUse[i]->read_req->buf, sizeof(WiiMoteEmu::EepromData_0));
DEBUG_LOG(WIIMOTE, "EEPROM: %s", Temp.c_str());
WiiMoteEmu::InitCalibration();
g_RunTemporary = false;
}
break;