mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-15 05:47:56 -07:00
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:
parent
6500db254f
commit
516f7a4ca1
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -2507,6 +2507,8 @@ struct SHCIEventNumberOfCompletedPackets
|
||||
u8 EventType;
|
||||
u8 PayloadLength;
|
||||
u8 NumberOfHandles;
|
||||
u16 Connection_Handle;
|
||||
u16 Number_Of_Completed_Packets;
|
||||
};
|
||||
|
||||
struct SHCIEventAuthenticationCompleted
|
||||
|
@ -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"
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user