Preliminary emulated Wiimote Extension support. It works in some games. The nunchuck controls are numpad 4, 5, 6, 8 for up down left right and C and Z for the c and z buttons. You have to select Extension connected from the settings to enable it.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1212 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
482cc819fb
commit
76ca6ac031
|
@ -942,9 +942,9 @@ namespace Core
|
||||||
{
|
{
|
||||||
void Callback_WiimoteInput(u16 _channelID, const void* _pData, u32 _Size)
|
void Callback_WiimoteInput(u16 _channelID, const void* _pData, u32 _Size)
|
||||||
{
|
{
|
||||||
LOGV(WII_IPC_WIIMOTE, 2, "=========================================================");
|
LOGV(WII_IPC_WIIMOTE, 3, "=========================================================");
|
||||||
const u8* pData = (const u8*)_pData;
|
const u8* pData = (const u8*)_pData;
|
||||||
LOGV(WII_IPC_WIIMOTE, 2, "Callback_WiimoteInput: 0x%x", _channelID);
|
LOGV(WII_IPC_WIIMOTE, 3, "Callback_WiimoteInput: 0x%x", _channelID);
|
||||||
std::string Temp;
|
std::string Temp;
|
||||||
for (u32 j=0; j<_Size; j++)
|
for (u32 j=0; j<_Size; j++)
|
||||||
{
|
{
|
||||||
|
@ -952,9 +952,9 @@ namespace Core
|
||||||
sprintf(Buffer, "%02x ", pData[j]);
|
sprintf(Buffer, "%02x ", pData[j]);
|
||||||
Temp.append(Buffer);
|
Temp.append(Buffer);
|
||||||
}
|
}
|
||||||
LOGV(WII_IPC_WIIMOTE, 2, " Data: %s", Temp.c_str());
|
LOGV(WII_IPC_WIIMOTE, 3, " Data: %s", Temp.c_str());
|
||||||
|
|
||||||
s_Usb->m_WiiMotes[0].SendL2capData(_channelID, _pData, _Size);
|
s_Usb->m_WiiMotes[0].SendL2capData(_channelID, _pData, _Size);
|
||||||
LOGV(WII_IPC_WIIMOTE, 2, "=========================================================");
|
LOGV(WII_IPC_WIIMOTE, 3, "=========================================================");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -536,6 +536,10 @@
|
||||||
<Filter
|
<Filter
|
||||||
Name="Emulated Wiimote"
|
Name="Emulated Wiimote"
|
||||||
>
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Src\DataReports.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Src\EmuDefinitions.cpp"
|
RelativePath=".\Src\EmuDefinitions.cpp"
|
||||||
>
|
>
|
||||||
|
@ -560,6 +564,14 @@
|
||||||
RelativePath=".\Src\EmuSubroutines.h"
|
RelativePath=".\Src\EmuSubroutines.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Src\Encryption.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Src\Encryption.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Src\FillReport.cpp"
|
RelativePath=".\Src\FillReport.cpp"
|
||||||
>
|
>
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "EmuSubroutines.h" // for WmRequestStatus_
|
#include "EmuSubroutines.h" // for WmRequestStatus_
|
||||||
|
|
||||||
//extern u16 WiiMoteEmu::g_channelID; // global id
|
|
||||||
|
|
||||||
BEGIN_EVENT_TABLE(ConfigDialog,wxDialog)
|
BEGIN_EVENT_TABLE(ConfigDialog,wxDialog)
|
||||||
EVT_CLOSE(ConfigDialog::OnClose)
|
EVT_CLOSE(ConfigDialog::OnClose)
|
||||||
|
@ -132,8 +131,9 @@ void ConfigDialog::GeneralSettingsChanged(wxCommandEvent& event)
|
||||||
g_Config.bExtensionConnected = m_ExtensionConnected->IsChecked();
|
g_Config.bExtensionConnected = m_ExtensionConnected->IsChecked();
|
||||||
|
|
||||||
// generate connect/disconnect status event
|
// generate connect/disconnect status event
|
||||||
if(WiiMoteEmu::g_channelID > 0)
|
if(WiiMoteEmu::g_ReportingChannel > 0)
|
||||||
WiiMoteEmu::WmRequestStatus_(WiiMoteEmu::g_channelID);
|
WiiMoteEmu::WmRequestStatus_(WiiMoteEmu::g_ReportingChannel,
|
||||||
|
g_Config.bExtensionConnected ? 1 : 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,225 @@
|
||||||
|
// Copyright (C) 2003-2008 Dolphin Project.
|
||||||
|
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
|
// Official SVN repository and contact information can be found at
|
||||||
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
|
|
||||||
|
#include "pluginspecs_wiimote.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include "Common.h"
|
||||||
|
#include "wiimote_hid.h"
|
||||||
|
#include "EmuSubroutines.h"
|
||||||
|
#include "EmuDefinitions.h"
|
||||||
|
#include "Encryption.h" // for extension encryption
|
||||||
|
#include "Console.h" // for startConsoleWin, wprintf, GetConsoleHwnd
|
||||||
|
#include "Config.h" // for g_Config
|
||||||
|
|
||||||
|
extern SWiimoteInitialize g_WiimoteInitialize;
|
||||||
|
//extern void __Log(int log, const char *format, ...);
|
||||||
|
//extern void __Log(int log, int v, const char *format, ...);
|
||||||
|
|
||||||
|
|
||||||
|
namespace WiiMoteEmu
|
||||||
|
{
|
||||||
|
|
||||||
|
//******************************************************************************
|
||||||
|
// Subroutines
|
||||||
|
//******************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
void WmDataReporting(u16 _channelID, wm_data_reporting* dr)
|
||||||
|
{
|
||||||
|
LOGV(WII_IPC_WIIMOTE, 0, "===========================================================");
|
||||||
|
LOG(WII_IPC_WIIMOTE, " Set Data reporting mode");
|
||||||
|
LOG(WII_IPC_WIIMOTE, " Rumble: %x", dr->rumble);
|
||||||
|
LOG(WII_IPC_WIIMOTE, " Continuous: %x", dr->continuous);
|
||||||
|
LOG(WII_IPC_WIIMOTE, " All The Time: %x (not only on data change)", dr->all_the_time);
|
||||||
|
LOG(WII_IPC_WIIMOTE, " Rumble: %x", dr->rumble);
|
||||||
|
LOG(WII_IPC_WIIMOTE, " Mode: 0x%02x", dr->mode);
|
||||||
|
//PanicAlert("Data reporting mode: 0x%02x", dr->mode);
|
||||||
|
wprintf("\nData reporting mode: 0x%02x", dr->mode);
|
||||||
|
wprintf("\nData reporting channel: 0x%04x\n", _channelID);
|
||||||
|
|
||||||
|
|
||||||
|
g_ReportingMode = dr->mode;
|
||||||
|
g_ReportingChannel = _channelID;
|
||||||
|
switch(dr->mode) { //see Wiimote_Update()
|
||||||
|
case WM_REPORT_CORE:
|
||||||
|
case WM_REPORT_CORE_ACCEL:
|
||||||
|
case WM_REPORT_CORE_ACCEL_IR12:
|
||||||
|
case WM_REPORT_CORE_ACCEL_EXT16:
|
||||||
|
case WM_REPORT_CORE_ACCEL_IR10_EXT6:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PanicAlert("Wiimote: Unknown reporting mode 0x%x", dr->mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
// WmSendAck(_channelID, WM_DATA_REPORTING);
|
||||||
|
|
||||||
|
LOGV(WII_IPC_WIIMOTE, 0, "===========================================================");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ===================================================
|
||||||
|
/* Case 0x30: Core Buttons */
|
||||||
|
// ----------------
|
||||||
|
void SendReportCore(u16 _channelID)
|
||||||
|
{
|
||||||
|
u8 DataFrame[1024];
|
||||||
|
u32 Offset = WriteWmReport(DataFrame, WM_REPORT_CORE);
|
||||||
|
|
||||||
|
wm_report_core* pReport = (wm_report_core*)(DataFrame + Offset);
|
||||||
|
Offset += sizeof(wm_report_core);
|
||||||
|
memset(pReport, 0, sizeof(wm_report_core));
|
||||||
|
|
||||||
|
FillReportInfo(pReport->c);
|
||||||
|
|
||||||
|
LOGV(WII_IPC_WIIMOTE, 2, " SendReportCore()");
|
||||||
|
|
||||||
|
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ===================================================
|
||||||
|
/* 0x31: Core Buttons and Accelerometer */
|
||||||
|
// ----------------
|
||||||
|
void SendReportCoreAccel(u16 _channelID)
|
||||||
|
{
|
||||||
|
u8 DataFrame[1024];
|
||||||
|
u32 Offset = WriteWmReport(DataFrame, WM_REPORT_CORE_ACCEL);
|
||||||
|
|
||||||
|
wm_report_core_accel* pReport = (wm_report_core_accel*)(DataFrame + Offset);
|
||||||
|
Offset += sizeof(wm_report_core_accel);
|
||||||
|
memset(pReport, 0, sizeof(wm_report_core_accel));
|
||||||
|
|
||||||
|
FillReportInfo(pReport->c);
|
||||||
|
FillReportAcc(pReport->a);
|
||||||
|
|
||||||
|
LOGV(WII_IPC_WIIMOTE, 2, " SendReportCoreAccel()");
|
||||||
|
|
||||||
|
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ===================================================
|
||||||
|
/* Case 0x33: Core Buttons and Accelerometer with 12 IR bytes */
|
||||||
|
// ----------------
|
||||||
|
void SendReportCoreAccelIr12(u16 _channelID) {
|
||||||
|
u8 DataFrame[1024];
|
||||||
|
u32 Offset = WriteWmReport(DataFrame, WM_REPORT_CORE_ACCEL_IR12);
|
||||||
|
|
||||||
|
wm_report_core_accel_ir12* pReport = (wm_report_core_accel_ir12*)(DataFrame + Offset);
|
||||||
|
Offset += sizeof(wm_report_core_accel_ir12);
|
||||||
|
memset(pReport, 0, sizeof(wm_report_core_accel_ir12));
|
||||||
|
|
||||||
|
FillReportInfo(pReport->c);
|
||||||
|
FillReportAcc(pReport->a);
|
||||||
|
FillReportIR(pReport->ir[0], pReport->ir[1]);
|
||||||
|
|
||||||
|
LOGV(WII_IPC_WIIMOTE, 2, " SendReportCoreAccelIr12()");
|
||||||
|
LOGV(WII_IPC_WIIMOTE, 2, " Offset: %08x", Offset);
|
||||||
|
|
||||||
|
// Debugging
|
||||||
|
/**/if(GetAsyncKeyState('V'))
|
||||||
|
{
|
||||||
|
wprintf("DataFrame: ");
|
||||||
|
for (int i = 0; i < Offset; i++)
|
||||||
|
{
|
||||||
|
wprintf("%02x ", DataFrame[i]);
|
||||||
|
if((i + 1) % 30 == 0) wprintf("\n");
|
||||||
|
}
|
||||||
|
wprintf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ===================================================
|
||||||
|
/* Case 0x35: Core Buttons and Accelerometer with 16 Extension Bytes */
|
||||||
|
// ----------------
|
||||||
|
void SendReportCoreAccelExt16(u16 _channelID)
|
||||||
|
{
|
||||||
|
u8 DataFrame[1024];
|
||||||
|
u32 Offset = WriteWmReport(DataFrame, WM_REPORT_CORE_ACCEL_EXT16);
|
||||||
|
|
||||||
|
wm_report_core_accel_ext16* pReport = (wm_report_core_accel_ext16*)(DataFrame + Offset);
|
||||||
|
Offset += sizeof(wm_report_core_accel_ext16);
|
||||||
|
memset(pReport, 0, sizeof(wm_report_core_accel_ext16));
|
||||||
|
|
||||||
|
FillReportInfo(pReport->c);
|
||||||
|
FillReportAcc(pReport->a);
|
||||||
|
//FillReportIRBasic(pReport->ir[0], pReport->ir[1]); // no IR here
|
||||||
|
FillReportExtension(pReport->ext);
|
||||||
|
|
||||||
|
LOGV(WII_IPC_WIIMOTE, 2, " SendReportCoreAccelExt16()");
|
||||||
|
|
||||||
|
// Debugging
|
||||||
|
/**/if(GetAsyncKeyState('V'))
|
||||||
|
{
|
||||||
|
wprintf("DataFrame: ");
|
||||||
|
for (int i = 0; i < Offset; i++)
|
||||||
|
{
|
||||||
|
wprintf("%02x ", DataFrame[i]);
|
||||||
|
if((i + 1) % 30 == 0) wprintf("\n");
|
||||||
|
}
|
||||||
|
wprintf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ===================================================
|
||||||
|
/* Case 0x37: Core Buttons and Accelerometer with 10 IR bytes and 6 Extension Bytes */
|
||||||
|
// ----------------
|
||||||
|
void SendReportCoreAccelIr10Ext(u16 _channelID)
|
||||||
|
{
|
||||||
|
u8 DataFrame[1024];
|
||||||
|
u32 Offset = WriteWmReport(DataFrame, WM_REPORT_CORE_ACCEL_IR10_EXT6);
|
||||||
|
|
||||||
|
wm_report_core_accel_ir10_ext6* pReport = (wm_report_core_accel_ir10_ext6*)(DataFrame + Offset);
|
||||||
|
Offset += sizeof(wm_report_core_accel_ir10_ext6);
|
||||||
|
memset(pReport, 0, sizeof(wm_report_core_accel_ir10_ext6));
|
||||||
|
|
||||||
|
FillReportInfo(pReport->c);
|
||||||
|
FillReportAcc(pReport->a);
|
||||||
|
FillReportIRBasic(pReport->ir[0], pReport->ir[1]);
|
||||||
|
FillReportExtension(pReport->ext);
|
||||||
|
|
||||||
|
LOGV(WII_IPC_WIIMOTE, 2, " SendReportCoreAccelIr10Ext()");
|
||||||
|
|
||||||
|
// Debugging
|
||||||
|
/**/if(GetAsyncKeyState('V'))
|
||||||
|
{
|
||||||
|
wprintf("DataFrame: ");
|
||||||
|
for (int i = 0; i < Offset; i++)
|
||||||
|
{
|
||||||
|
wprintf("%02x ", DataFrame[i]);
|
||||||
|
if((i + 1) % 30 == 0) wprintf("\n");
|
||||||
|
}
|
||||||
|
wprintf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // end of namespace
|
|
@ -25,6 +25,7 @@
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "wiimote_hid.h"
|
#include "wiimote_hid.h"
|
||||||
#include "EmuDefinitions.h"
|
#include "EmuDefinitions.h"
|
||||||
|
#include "Encryption.h"
|
||||||
#include "Console.h" // for startConsoleWin, wprintf, GetConsoleHwnd
|
#include "Console.h" // for startConsoleWin, wprintf, GetConsoleHwnd
|
||||||
|
|
||||||
extern SWiimoteInitialize g_WiimoteInitialize;
|
extern SWiimoteInitialize g_WiimoteInitialize;
|
||||||
|
@ -38,19 +39,20 @@ namespace WiiMoteEmu
|
||||||
// Definitions and variable declarations
|
// Definitions and variable declarations
|
||||||
//******************************************************************************
|
//******************************************************************************
|
||||||
|
|
||||||
u16 g_channelID;
|
|
||||||
|
|
||||||
u8 g_Leds = 0x1;
|
u8 g_Leds = 0x1;
|
||||||
|
|
||||||
u8 g_Eeprom[WIIMOTE_EEPROM_SIZE];
|
u8 g_Eeprom[WIIMOTE_EEPROM_SIZE];
|
||||||
|
|
||||||
u8 g_RegSpeaker[WIIMOTE_REG_SPEAKER_SIZE];
|
u8 g_RegSpeaker[WIIMOTE_REG_SPEAKER_SIZE];
|
||||||
u8 g_RegExt[WIIMOTE_REG_EXT_SIZE];
|
u8 g_RegExt[WIIMOTE_REG_EXT_SIZE];
|
||||||
|
u8 g_RegExtTmp[WIIMOTE_REG_EXT_SIZE];
|
||||||
|
u8 g_RegExtBlnk[WIIMOTE_REG_EXT_SIZE];
|
||||||
u8 g_RegIr[WIIMOTE_REG_IR_SIZE];
|
u8 g_RegIr[WIIMOTE_REG_IR_SIZE];
|
||||||
|
|
||||||
u8 g_ReportingMode;
|
u8 g_ReportingMode; // the reporting mode and channel id
|
||||||
u16 g_ReportingChannel;
|
u16 g_ReportingChannel;
|
||||||
|
|
||||||
|
wiimote_key g_ExtKey; // the extension encryption key
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace WiiMoteEmu
|
||||||
// Definitions and variable declarations
|
// Definitions and variable declarations
|
||||||
//******************************************************************************
|
//******************************************************************************
|
||||||
|
|
||||||
/* libogc bounding box, in smoothed IR coordinates: 232,284 792,704, however, it was
|
/* Libogc bounding box, in smoothed IR coordinates: 232,284 792,704, however, it was
|
||||||
possible for me to get a better calibration with these values, if they are not
|
possible for me to get a better calibration with these values, if they are not
|
||||||
universal for all PCs we have to make a setting for it. */
|
universal for all PCs we have to make a setting for it. */
|
||||||
#define LEFT 266
|
#define LEFT 266
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "wiimote_hid.h"
|
#include "wiimote_hid.h"
|
||||||
#include "EmuSubroutines.h"
|
#include "EmuSubroutines.h"
|
||||||
#include "EmuDefinitions.h"
|
#include "EmuDefinitions.h"
|
||||||
|
#include "Encryption.h" // for extension encryption
|
||||||
#include "Console.h" // for startConsoleWin, wprintf, GetConsoleHwnd
|
#include "Console.h" // for startConsoleWin, wprintf, GetConsoleHwnd
|
||||||
#include "Config.h" // for g_Config
|
#include "Config.h" // for g_Config
|
||||||
|
|
||||||
|
@ -42,8 +43,7 @@ namespace WiiMoteEmu
|
||||||
|
|
||||||
//wm_request_status global_struct;
|
//wm_request_status global_struct;
|
||||||
//extern wm_request_status global_struct;
|
//extern wm_request_status global_struct;
|
||||||
//extern u16 g_channelID;
|
|
||||||
//void ReadExt();
|
|
||||||
|
|
||||||
|
|
||||||
// ===================================================
|
// ===================================================
|
||||||
|
@ -61,35 +61,32 @@ void HidOutputReport(u16 _channelID, wm_report* sr) {
|
||||||
case 0x10:
|
case 0x10:
|
||||||
LOGV(WII_IPC_WIIMOTE, 0, "HidOutputReport: unknown sr->channel 0x10");
|
LOGV(WII_IPC_WIIMOTE, 0, "HidOutputReport: unknown sr->channel 0x10");
|
||||||
break;
|
break;
|
||||||
case WM_LEDS:
|
case WM_LEDS: // 0x11
|
||||||
WmLeds(_channelID, (wm_leds*)sr->data);
|
WmLeds(_channelID, (wm_leds*)sr->data);
|
||||||
break;
|
break;
|
||||||
case WM_READ_DATA:
|
case WM_DATA_REPORTING: // 0x12
|
||||||
WmReadData(_channelID, (wm_read_data*)sr->data);
|
WmDataReporting(_channelID, (wm_data_reporting*)sr->data);
|
||||||
break;
|
break;
|
||||||
case WM_REQUEST_STATUS:
|
case WM_REQUEST_STATUS: // 0x15
|
||||||
//global_struct = (wm_request_status*)sr->data;
|
//global_struct = (wm_request_status*)sr->data;
|
||||||
WmRequestStatus(_channelID, (wm_request_status*)sr->data);
|
WmRequestStatus(_channelID, (wm_request_status*)sr->data);
|
||||||
break;
|
break;
|
||||||
case WM_IR_PIXEL_CLOCK:
|
case WM_READ_DATA: // 0x17
|
||||||
case WM_IR_LOGIC:
|
WmReadData(_channelID, (wm_read_data*)sr->data);
|
||||||
|
break;
|
||||||
|
case WM_IR_PIXEL_CLOCK: // 0x13
|
||||||
|
case WM_IR_LOGIC: // 0x1a
|
||||||
LOGV(WII_IPC_WIIMOTE, 0, " IR Enable 0x%02x 0x%02x", sr->channel, sr->data[0]);
|
LOGV(WII_IPC_WIIMOTE, 0, " IR Enable 0x%02x 0x%02x", sr->channel, sr->data[0]);
|
||||||
break;
|
break;
|
||||||
case WM_WRITE_DATA:
|
case WM_WRITE_DATA: // 0x16
|
||||||
WmWriteData(_channelID, (wm_write_data*)sr->data);
|
WmWriteData(_channelID, (wm_write_data*)sr->data);
|
||||||
break;
|
break;
|
||||||
case WM_DATA_REPORTING:
|
|
||||||
WmDataReporting(_channelID, (wm_data_reporting*)sr->data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WM_SPEAKER_ENABLE:
|
case WM_SPEAKER_ENABLE:
|
||||||
LOGV(WII_IPC_WIIMOTE, 1, " WM Speaker Enable 0x%02x 0x%02x", sr->channel, sr->data[0]);
|
LOGV(WII_IPC_WIIMOTE, 1, " WM Speaker Enable 0x%02x 0x%02x", sr->channel, sr->data[0]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_SPEAKER_MUTE:
|
case WM_SPEAKER_MUTE:
|
||||||
LOGV(WII_IPC_WIIMOTE, 1, " WM Mute Enable 0x%02x 0x%02x", sr->channel, sr->data[0]);
|
LOGV(WII_IPC_WIIMOTE, 1, " WM Mute Enable 0x%02x 0x%02x", sr->channel, sr->data[0]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
PanicAlert("HidOutputReport: Unknown channel 0x%02x", sr->channel);
|
PanicAlert("HidOutputReport: Unknown channel 0x%02x", sr->channel);
|
||||||
return;
|
return;
|
||||||
|
@ -98,6 +95,9 @@ void HidOutputReport(u16 _channelID, wm_report* sr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ===================================================
|
||||||
|
/* LED (blue lights) report. */
|
||||||
|
// ----------------
|
||||||
void WmLeds(u16 _channelID, wm_leds* leds) {
|
void WmLeds(u16 _channelID, wm_leds* leds) {
|
||||||
LOGV(WII_IPC_WIIMOTE, 0, "===========================================================");
|
LOGV(WII_IPC_WIIMOTE, 0, "===========================================================");
|
||||||
|
|
||||||
|
@ -108,6 +108,8 @@ void WmLeds(u16 _channelID, wm_leds* leds) {
|
||||||
g_Leds = leds->leds;
|
g_Leds = leds->leds;
|
||||||
LOGV(WII_IPC_WIIMOTE, 0, "===========================================================");
|
LOGV(WII_IPC_WIIMOTE, 0, "===========================================================");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WmSendAck(u16 _channelID, u8 _reportID)
|
void WmSendAck(u16 _channelID, u8 _reportID)
|
||||||
{
|
{
|
||||||
u8 DataFrame[1024];
|
u8 DataFrame[1024];
|
||||||
|
@ -135,105 +137,9 @@ void WmSendAck(u16 _channelID, u8 _reportID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WmDataReporting(u16 _channelID, wm_data_reporting* dr)
|
// ===================================================
|
||||||
{
|
/* Read data from Wiimote and Extensions registers. */
|
||||||
LOGV(WII_IPC_WIIMOTE, 0, "===========================================================");
|
// ----------------
|
||||||
LOG(WII_IPC_WIIMOTE, " Set Data reporting mode");
|
|
||||||
LOG(WII_IPC_WIIMOTE, " Rumble: %x", dr->rumble);
|
|
||||||
LOG(WII_IPC_WIIMOTE, " Continuous: %x", dr->continuous);
|
|
||||||
LOG(WII_IPC_WIIMOTE, " All The Time: %x (not only on data change)", dr->all_the_time);
|
|
||||||
LOG(WII_IPC_WIIMOTE, " Rumble: %x", dr->rumble);
|
|
||||||
LOG(WII_IPC_WIIMOTE, " Mode: 0x%02x", dr->mode);
|
|
||||||
|
|
||||||
g_ReportingMode = dr->mode;
|
|
||||||
g_ReportingChannel = _channelID;
|
|
||||||
switch(dr->mode) { //see Wiimote_Update()
|
|
||||||
case WM_REPORT_CORE:
|
|
||||||
case WM_REPORT_CORE_ACCEL:
|
|
||||||
case WM_REPORT_CORE_ACCEL_IR12:
|
|
||||||
case WM_REPORT_CORE_ACCEL_IR10_EXT6:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
PanicAlert("Wiimote: Unknown reporting mode 0x%x", dr->mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
// WmSendAck(_channelID, WM_DATA_REPORTING);
|
|
||||||
|
|
||||||
LOGV(WII_IPC_WIIMOTE, 0, "===========================================================");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SendReportCore(u16 _channelID)
|
|
||||||
{
|
|
||||||
u8 DataFrame[1024];
|
|
||||||
u32 Offset = WriteWmReport(DataFrame, WM_REPORT_CORE);
|
|
||||||
|
|
||||||
wm_report_core* pReport = (wm_report_core*)(DataFrame + Offset);
|
|
||||||
Offset += sizeof(wm_report_core);
|
|
||||||
memset(pReport, 0, sizeof(wm_report_core));
|
|
||||||
|
|
||||||
FillReportInfo(pReport->c);
|
|
||||||
|
|
||||||
LOG(WII_IPC_WIIMOTE, " SendReportCore()");
|
|
||||||
|
|
||||||
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SendReportCoreAccelIr12(u16 _channelID) {
|
|
||||||
u8 DataFrame[1024];
|
|
||||||
u32 Offset = WriteWmReport(DataFrame, WM_REPORT_CORE_ACCEL_IR12);
|
|
||||||
|
|
||||||
wm_report_core_accel_ir12* pReport = (wm_report_core_accel_ir12*)(DataFrame + Offset);
|
|
||||||
Offset += sizeof(wm_report_core_accel_ir12);
|
|
||||||
memset(pReport, 0, sizeof(wm_report_core_accel_ir12));
|
|
||||||
|
|
||||||
FillReportInfo(pReport->c);
|
|
||||||
FillReportAcc(pReport->a);
|
|
||||||
FillReportIR(pReport->ir[0], pReport->ir[1]);
|
|
||||||
|
|
||||||
LOGV(WII_IPC_WIIMOTE, 2, " SendReportCoreAccelIr12()");
|
|
||||||
|
|
||||||
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SendReportCoreAccelIr10Ext(u16 _channelID)
|
|
||||||
{
|
|
||||||
u8 DataFrame[1024];
|
|
||||||
u32 Offset = WriteWmReport(DataFrame, WM_REPORT_CORE_ACCEL_IR10_EXT6);
|
|
||||||
|
|
||||||
wm_report_core_accel_ir10_ext6* pReport = (wm_report_core_accel_ir10_ext6*)(DataFrame + Offset);
|
|
||||||
Offset += sizeof(wm_report_core_accel_ir10_ext6);
|
|
||||||
memset(pReport, 0, sizeof(wm_report_core_accel_ir10_ext6));
|
|
||||||
|
|
||||||
FillReportInfo(pReport->c);
|
|
||||||
FillReportAcc(pReport->a);
|
|
||||||
FillReportIRBasic(pReport->ir[0], pReport->ir[1]);
|
|
||||||
|
|
||||||
LOG(WII_IPC_WIIMOTE, " SendReportCoreAccelIr10Ext()");
|
|
||||||
|
|
||||||
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SendReportCoreAccel(u16 _channelID)
|
|
||||||
{
|
|
||||||
u8 DataFrame[1024];
|
|
||||||
u32 Offset = WriteWmReport(DataFrame, WM_REPORT_CORE_ACCEL);
|
|
||||||
|
|
||||||
wm_report_core_accel* pReport = (wm_report_core_accel*)(DataFrame + Offset);
|
|
||||||
Offset += sizeof(wm_report_core_accel);
|
|
||||||
memset(pReport, 0, sizeof(wm_report_core_accel));
|
|
||||||
|
|
||||||
FillReportInfo(pReport->c);
|
|
||||||
FillReportAcc(pReport->a);
|
|
||||||
|
|
||||||
LOG(WII_IPC_WIIMOTE, " SendReportCoreAccel()");
|
|
||||||
|
|
||||||
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void WmReadData(u16 _channelID, wm_read_data* rd)
|
void WmReadData(u16 _channelID, wm_read_data* rd)
|
||||||
{
|
{
|
||||||
LOGV(WII_IPC_WIIMOTE, 0, "===========================================================");
|
LOGV(WII_IPC_WIIMOTE, 0, "===========================================================");
|
||||||
|
@ -260,42 +166,87 @@ void WmReadData(u16 _channelID, wm_read_data* rd)
|
||||||
u32 blockSize;
|
u32 blockSize;
|
||||||
switch((address >> 16) & 0xFE)
|
switch((address >> 16) & 0xFE)
|
||||||
{
|
{
|
||||||
/* case 0xA2:
|
/**/ case 0xA2:
|
||||||
block = g_RegSpeaker;
|
block = g_RegSpeaker;
|
||||||
blockSize = WIIMOTE_REG_SPEAKER_SIZE;
|
blockSize = WIIMOTE_REG_SPEAKER_SIZE;
|
||||||
break;*/
|
LOGV(WII_IPC_WIIMOTE, 0, "WmReadData: 0xB0 g_RegSpeaker");
|
||||||
|
break;
|
||||||
case 0xA4:
|
case 0xA4:
|
||||||
block = g_RegExt;
|
block = g_RegExt;
|
||||||
blockSize = WIIMOTE_REG_EXT_SIZE;
|
blockSize = WIIMOTE_REG_EXT_SIZE;
|
||||||
//PanicAlert("WmReadData: 0xA4 g_RegExt");
|
|
||||||
LOGV(WII_IPC_WIIMOTE, 0, " Case 0xA4: Read ExtReg ****************************");
|
LOGV(WII_IPC_WIIMOTE, 0, " Case 0xA4: Read ExtReg ****************************");
|
||||||
//wprintf("WmReadData\n"); ReadExt();
|
//wprintf("WmReadData\n"); ReadExt();
|
||||||
break;
|
break;
|
||||||
/* case 0xB0:
|
/**/ case 0xB0:
|
||||||
block = g_RegIr;
|
block = g_RegIr;
|
||||||
blockSize = WIIMOTE_REG_IR_SIZE;
|
blockSize = WIIMOTE_REG_IR_SIZE;
|
||||||
//PanicAlert("WmReadData: 0xB0 g_RegIr");
|
//PanicAlert("WmReadData: 0xB0 g_RegIr");
|
||||||
LOGV(WII_IPC_WIIMOTE, 0, "WmReadData: 0xB0 g_RegIr");
|
LOGV(WII_IPC_WIIMOTE, 0, "WmReadData: 0xB0 g_RegIr");
|
||||||
break;*/
|
break;
|
||||||
default:
|
default:
|
||||||
PanicAlert("WmWriteData: bad register block!");
|
PanicAlert("WmWriteData: bad register block!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -----------------------------------------
|
||||||
|
// Encrypt data that is read from the Wiimote Extension Register
|
||||||
|
// -------------
|
||||||
|
if(((address >> 16) & 0xfe) == 0xa4)
|
||||||
|
{
|
||||||
|
wprintf("\n\nWmReadData Address: %08x Offset: %08x Size: %i byte\n",
|
||||||
|
address, address & 0xffff, (u8)size);
|
||||||
|
|
||||||
|
// Debugging
|
||||||
|
u32 offset = address & 0xffff;
|
||||||
|
wprintf("Unencrypted data:\n");
|
||||||
|
for (int i = 0; i < (u8)size; i++)
|
||||||
|
{
|
||||||
|
wprintf("%02x ", g_RegExt[i + offset]);
|
||||||
|
if((i + 1) % 20 == 0) wprintf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if encrypted reads is on
|
||||||
|
if(g_RegExt[0xf0] == 0xaa)
|
||||||
|
{
|
||||||
|
// Copy g_RegExt to g_RegExtTmp
|
||||||
|
memcpy(g_RegExtTmp, g_RegExt, sizeof(g_RegExt));
|
||||||
|
|
||||||
|
// Copy the registry to a temporary space
|
||||||
|
memcpy(g_RegExtTmp, g_RegExt, sizeof(g_RegExt));
|
||||||
|
|
||||||
|
// Encrypt the read
|
||||||
|
wiimote_encrypt(&g_ExtKey, &g_RegExtTmp[address & 0xffff], (address & 0xffff), (u8)size);
|
||||||
|
|
||||||
|
// Debugging
|
||||||
|
wprintf("\nEncrypted data:\n");
|
||||||
|
for (int i = 0; i < (u8)size; i++)
|
||||||
|
{
|
||||||
|
wprintf("%02x ", g_RegExtTmp[i + offset]);
|
||||||
|
if((i + 1) % 20 == 0) wprintf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
//wprintf("\ng_RegExtTmp after: \n");
|
||||||
|
//ReadExtTmp();
|
||||||
|
//wprintf("\nFrom g_RegExt: \n");
|
||||||
|
//ReadExt();
|
||||||
|
|
||||||
|
// Update the block that SendReadDataReply will eventually send to the Wii
|
||||||
|
block = g_RegExtTmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
wprintf("\n\n\n");
|
||||||
|
}
|
||||||
|
//---------
|
||||||
|
|
||||||
|
|
||||||
address &= 0xFFFF;
|
address &= 0xFFFF;
|
||||||
if(address + size > blockSize) {
|
if(address + size > blockSize) {
|
||||||
PanicAlert("WmReadData: address + size out of bounds!");
|
PanicAlert("WmReadData: address + size out of bounds!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*// Debugging
|
|
||||||
wprintf("WmReadData %08x %i\n", address, (u8)size);
|
|
||||||
for (int i = 0; i < sizeof(block+address); i++)
|
|
||||||
{
|
|
||||||
wprintf("%02x ", g_RegExt[i]);
|
|
||||||
if((i + 1) % 25 == 0) wprintf("\n");
|
|
||||||
}
|
|
||||||
wprintf("\n\n");
|
|
||||||
//---------*/
|
|
||||||
|
|
||||||
SendReadDataReply(_channelID, block+address, address, (u8)size);
|
SendReadDataReply(_channelID, block+address, address, (u8)size);
|
||||||
}
|
}
|
||||||
|
@ -307,6 +258,10 @@ void WmReadData(u16 _channelID, wm_read_data* rd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ===================================================
|
||||||
|
/* Write data to Wiimote and Extensions registers. */
|
||||||
|
// ----------------
|
||||||
void WmWriteData(u16 _channelID, wm_write_data* wd)
|
void WmWriteData(u16 _channelID, wm_write_data* wd)
|
||||||
{
|
{
|
||||||
LOGV(WII_IPC_WIIMOTE, 0, "========================================================");
|
LOGV(WII_IPC_WIIMOTE, 0, "========================================================");
|
||||||
|
@ -342,9 +297,13 @@ void WmWriteData(u16 _channelID, wm_write_data* wd)
|
||||||
case 0xA4:
|
case 0xA4:
|
||||||
block = g_RegExt; // Extension Controller register
|
block = g_RegExt; // Extension Controller register
|
||||||
blockSize = WIIMOTE_REG_EXT_SIZE;
|
blockSize = WIIMOTE_REG_EXT_SIZE;
|
||||||
LOGV(WII_IPC_WIIMOTE, 0, " Case 0xA4: Write ExtReg *********************************");
|
LOGV(WII_IPC_WIIMOTE, 0, " *******************************************************");
|
||||||
//PanicAlert(" Case 0xA4: Write g_RegExt");
|
LOGV(WII_IPC_WIIMOTE, 0, "");
|
||||||
//wprintf("WmWriteData\n"); ReadExt();
|
LOGV(WII_IPC_WIIMOTE, 0, " Case 0xA4: Write ExtReg");
|
||||||
|
LOGV(WII_IPC_WIIMOTE, 0, "");
|
||||||
|
LOGV(WII_IPC_WIIMOTE, 0, " *******************************************************");
|
||||||
|
wprintf("\n\nWmWriteData Size: %i Address: %08x Offset: %08x \n",
|
||||||
|
wd->size, address, (address & 0xffff));
|
||||||
break;
|
break;
|
||||||
case 0xB0:
|
case 0xB0:
|
||||||
block = g_RegIr;
|
block = g_RegIr;
|
||||||
|
@ -354,29 +313,50 @@ void WmWriteData(u16 _channelID, wm_write_data* wd)
|
||||||
PanicAlert("WmWriteData: bad register block!");
|
PanicAlert("WmWriteData: bad register block!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Remove for example 0xa40000 from the address
|
||||||
address &= 0xFFFF;
|
address &= 0xFFFF;
|
||||||
|
|
||||||
|
// Check if the address is within bounds
|
||||||
if(address + wd->size > blockSize) {
|
if(address + wd->size > blockSize) {
|
||||||
PanicAlert("WmWriteData: address + size out of bounds!");
|
PanicAlert("WmWriteData: address + size out of bounds!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// finally write the registers to memory
|
|
||||||
|
|
||||||
|
// Finally write the registers to the right structure
|
||||||
|
memcpy(block + address, wd->data, wd->size);
|
||||||
|
|
||||||
/*// Debugging
|
// -----------------------------------------
|
||||||
if( ((address >> 16) & 0xFE) == 0xa4 )
|
// Generate key for the Wiimote Extension
|
||||||
|
// -------------
|
||||||
|
if(blockSize == WIIMOTE_REG_EXT_SIZE)
|
||||||
{
|
{
|
||||||
wprintf("WmWriteData %i\n", wd->size);
|
// Debugging
|
||||||
for (int i = 0; i < sizeof(wd->data); i++)
|
// Write the data
|
||||||
|
wprintf("Data: ");
|
||||||
|
for (int i = 0; i < wd->size; i++)
|
||||||
{
|
{
|
||||||
wprintf("%02x ", wd->data[i]);
|
wprintf("%02x ", wd->data[i]);
|
||||||
if((i + 1) % 25 == 0) wprintf("\n");
|
if((i + 1) % 25 == 0) wprintf("\n");
|
||||||
}
|
}
|
||||||
wprintf("\n\n");
|
wprintf("\n");
|
||||||
|
|
||||||
|
//wprintf("Current address: %08x\n", address);
|
||||||
|
|
||||||
|
//wprintf("g_RegExt:\n");
|
||||||
|
//ReadExt();
|
||||||
|
|
||||||
|
|
||||||
|
/* 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 */
|
||||||
|
//if(address >= 0xa40040 && address <= 0xa4004c)
|
||||||
|
if(address >= 0x40 && address <= 0x4c)
|
||||||
|
//if(address == 0x4c)
|
||||||
|
wiimote_gen_key(&g_ExtKey, &g_RegExt[0x40]);
|
||||||
}
|
}
|
||||||
//---------*/
|
// -------------
|
||||||
|
|
||||||
|
|
||||||
memcpy(wd->data, block + address, wd->size);
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -388,6 +368,10 @@ void WmWriteData(u16 _channelID, wm_write_data* wd)
|
||||||
LOGV(WII_IPC_WIIMOTE, 0, "==========================================================");
|
LOGV(WII_IPC_WIIMOTE, 0, "==========================================================");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ===================================================
|
||||||
|
/* Generate the right address for wm reports. */
|
||||||
|
// ----------------
|
||||||
int WriteWmReport(u8* dst, u8 channel) {
|
int WriteWmReport(u8* dst, u8 channel) {
|
||||||
u32 Offset = 0;
|
u32 Offset = 0;
|
||||||
hid_packet* pHidHeader = (hid_packet*)(dst + Offset);
|
hid_packet* pHidHeader = (hid_packet*)(dst + Offset);
|
||||||
|
@ -401,12 +385,9 @@ int WriteWmReport(u8* dst, u8 channel) {
|
||||||
return Offset;
|
return Offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===================================================
|
|
||||||
/* Here we produce status report to send to the Wii. We currently ignore the status
|
// Custom call version
|
||||||
request rs and all its eventual instructions it may include (for example turn off
|
void WmRequestStatus_(u16 _channelID, int a)
|
||||||
rumble or something else) and just send the status report. */
|
|
||||||
// ----------------
|
|
||||||
void WmRequestStatus_(u16 _channelID)
|
|
||||||
{
|
{
|
||||||
//PanicAlert("WmRequestStatus");
|
//PanicAlert("WmRequestStatus");
|
||||||
LOGV(WII_IPC_WIIMOTE, 0, "================================================");
|
LOGV(WII_IPC_WIIMOTE, 0, "================================================");
|
||||||
|
@ -420,15 +401,24 @@ void WmRequestStatus_(u16 _channelID)
|
||||||
wm_status_report* pStatus = (wm_status_report*)(DataFrame + Offset);
|
wm_status_report* pStatus = (wm_status_report*)(DataFrame + Offset);
|
||||||
Offset += sizeof(wm_status_report);
|
Offset += sizeof(wm_status_report);
|
||||||
memset(pStatus, 0, sizeof(wm_status_report)); // fill the status report with zeroes
|
memset(pStatus, 0, sizeof(wm_status_report)); // fill the status report with zeroes
|
||||||
|
|
||||||
|
// Status values
|
||||||
pStatus->leds = g_Leds;
|
pStatus->leds = g_Leds;
|
||||||
pStatus->ir = 1;
|
pStatus->ir = 1;
|
||||||
pStatus->battery = 0x4F; //arbitrary number
|
pStatus->battery = 0x4F; //arbitrary number
|
||||||
|
|
||||||
// this gets us passed the first error, but later brings up the disconnected error
|
|
||||||
if(g_Config.bExtensionConnected)
|
if(a == 1)
|
||||||
|
{
|
||||||
|
wprintf("pStatus->extension = 1\n");
|
||||||
pStatus->extension = 1;
|
pStatus->extension = 1;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
wprintf("pStatus->extension = 0\n");
|
||||||
pStatus->extension = 0;
|
pStatus->extension = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
LOGV(WII_IPC_WIIMOTE, 0, " Extension: %x", pStatus->extension);
|
LOGV(WII_IPC_WIIMOTE, 0, " Extension: %x", pStatus->extension);
|
||||||
LOGV(WII_IPC_WIIMOTE, 0, " SendStatusReport()");
|
LOGV(WII_IPC_WIIMOTE, 0, " SendStatusReport()");
|
||||||
|
@ -440,6 +430,11 @@ void WmRequestStatus_(u16 _channelID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ===================================================
|
||||||
|
/* Here we produce a status report to send to the Wii. We currently ignore the status
|
||||||
|
request rs and all its eventual instructions it may include (for example turn off
|
||||||
|
rumble or something else) and just send the status report. */
|
||||||
|
// ----------------
|
||||||
void WmRequestStatus(u16 _channelID, wm_request_status* rs)
|
void WmRequestStatus(u16 _channelID, wm_request_status* rs)
|
||||||
{
|
{
|
||||||
//PanicAlert("WmRequestStatus");
|
//PanicAlert("WmRequestStatus");
|
||||||
|
@ -455,11 +450,13 @@ void WmRequestStatus(u16 _channelID, wm_request_status* rs)
|
||||||
wm_status_report* pStatus = (wm_status_report*)(DataFrame + Offset);
|
wm_status_report* pStatus = (wm_status_report*)(DataFrame + Offset);
|
||||||
Offset += sizeof(wm_status_report);
|
Offset += sizeof(wm_status_report);
|
||||||
memset(pStatus, 0, sizeof(wm_status_report)); // fill the status report with zeroes
|
memset(pStatus, 0, sizeof(wm_status_report)); // fill the status report with zeroes
|
||||||
|
|
||||||
|
// Status values
|
||||||
pStatus->leds = g_Leds;
|
pStatus->leds = g_Leds;
|
||||||
pStatus->ir = 1;
|
pStatus->ir = 1;
|
||||||
pStatus->battery = 0x4F; //arbitrary number
|
pStatus->battery = 0x4F; //arbitrary number
|
||||||
|
|
||||||
// this gets us passed the first error, but later brings up the disconnected error
|
// Read config value for this one
|
||||||
if(g_Config.bExtensionConnected)
|
if(g_Config.bExtensionConnected)
|
||||||
pStatus->extension = 1;
|
pStatus->extension = 1;
|
||||||
else
|
else
|
||||||
|
@ -475,6 +472,10 @@ void WmRequestStatus(u16 _channelID, wm_request_status* rs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ===================================================
|
||||||
|
/* Here we produce the actual reply that we send to the Wii. The message is divided
|
||||||
|
into 16 bytes pieces and sent piece by piece. */
|
||||||
|
// ----------------
|
||||||
void SendReadDataReply(u16 _channelID, void* _Base, u16 _Address, u8 _Size)
|
void SendReadDataReply(u16 _channelID, void* _Base, u16 _Address, u8 _Size)
|
||||||
{
|
{
|
||||||
LOGV(WII_IPC_WIIMOTE, 0, "=========================================");
|
LOGV(WII_IPC_WIIMOTE, 0, "=========================================");
|
||||||
|
@ -498,15 +499,16 @@ void SendReadDataReply(u16 _channelID, void* _Base, u16 _Address, u8 _Size)
|
||||||
pReply->address = Common::swap16(_Address + dataOffset);
|
pReply->address = Common::swap16(_Address + dataOffset);
|
||||||
|
|
||||||
|
|
||||||
|
// Write a pice
|
||||||
memcpy(pReply->data + dataOffset, _Base, copySize);
|
memcpy(pReply->data + dataOffset, _Base, copySize);
|
||||||
|
|
||||||
|
if(copySize < 16) // check if we have less than 16 bytes left to send
|
||||||
if(copySize < 16)
|
|
||||||
{
|
{
|
||||||
memset(pReply->data + copySize, 0, 16 - copySize);
|
memset(pReply->data + copySize, 0, 16 - copySize);
|
||||||
}
|
}
|
||||||
dataOffset += copySize;
|
dataOffset += copySize;
|
||||||
|
|
||||||
|
|
||||||
LOG(WII_IPC_WIIMOTE, " SendReadDataReply()");
|
LOG(WII_IPC_WIIMOTE, " SendReadDataReply()");
|
||||||
LOG(WII_IPC_WIIMOTE, " Buttons: 0x%04x", pReply->buttons);
|
LOG(WII_IPC_WIIMOTE, " Buttons: 0x%04x", pReply->buttons);
|
||||||
LOG(WII_IPC_WIIMOTE, " Error: 0x%x", pReply->error);
|
LOG(WII_IPC_WIIMOTE, " Error: 0x%x", pReply->error);
|
||||||
|
@ -525,6 +527,7 @@ void SendReadDataReply(u16 _channelID, void* _Base, u16 _Address, u8 _Size)
|
||||||
*/
|
*/
|
||||||
//---------
|
//---------
|
||||||
|
|
||||||
|
// Send a piece
|
||||||
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
|
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
|
||||||
|
|
||||||
_Size -= copySize;
|
_Size -= copySize;
|
||||||
|
|
|
@ -30,7 +30,10 @@ void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size);
|
||||||
void ControlChannel(u16 _channelID, const void* _pData, u32 _Size) ;
|
void ControlChannel(u16 _channelID, const void* _pData, u32 _Size) ;
|
||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1);
|
//void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1);
|
||||||
|
|
||||||
|
void ReadExt(); // Debugging
|
||||||
|
void ReadExtTmp();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,10 @@ u16 convert16bit(const u8* src) {
|
||||||
return (src[0] << 8) | src[1];
|
return (src[0] << 8) | src[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ===================================================
|
||||||
|
/* Calibrate the mouse position to the emulation window. */
|
||||||
|
// ----------------
|
||||||
void GetMousePos(float& x, float& y)
|
void GetMousePos(float& x, float& y)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -69,6 +73,9 @@ void GetMousePos(float& x, float& y)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ===================================================
|
||||||
|
/* Homebrew encryption for 0x00000000 encryption keys. */
|
||||||
|
// ----------------
|
||||||
void CryptBuffer(u8* _buffer, u8 _size)
|
void CryptBuffer(u8* _buffer, u8 _size)
|
||||||
{
|
{
|
||||||
for (int i=0; i<_size; i++)
|
for (int i=0; i<_size; i++)
|
||||||
|
@ -85,7 +92,12 @@ void WriteCrypted16(u8* _baseBlock, u16 _address, u16 _value)
|
||||||
*(u16*)(_baseBlock + _address) = cryptedValue;
|
*(u16*)(_baseBlock + _address) = cryptedValue;
|
||||||
//PanicAlert("Converted %04x to %04x", _value, cryptedValue);
|
//PanicAlert("Converted %04x to %04x", _value, cryptedValue);
|
||||||
}
|
}
|
||||||
|
// ================
|
||||||
|
|
||||||
|
|
||||||
|
// ===================================================
|
||||||
|
/* Write initial values to Eeprom and registers. */
|
||||||
|
// ----------------
|
||||||
void Initialize()
|
void Initialize()
|
||||||
{
|
{
|
||||||
memset(g_Eeprom, 0, WIIMOTE_EEPROM_SIZE);
|
memset(g_Eeprom, 0, WIIMOTE_EEPROM_SIZE);
|
||||||
|
@ -95,23 +107,21 @@ void Initialize()
|
||||||
g_ReportingMode = 0;
|
g_ReportingMode = 0;
|
||||||
|
|
||||||
|
|
||||||
// Write 0x0000 in encrypted form (0xfefe) to 0xfe in the extension register
|
/* Extension data for homebrew applications that use the 0x00000000 key. This
|
||||||
WriteCrypted16(g_RegExt, 0xfe, 0x0000); // Fully inserted Nunchuk
|
writes 0x0000 in encrypted form (0xfefe) to 0xfe in the extension register. */
|
||||||
|
//WriteCrypted16(g_RegExt, 0xfe, 0x0000); // Fully inserted Nunchuk
|
||||||
|
|
||||||
|
|
||||||
|
// Copy nuncuck id and calibration to its register
|
||||||
|
memcpy(g_RegExt + 0x20, nunchuck_calibration, sizeof(nunchuck_calibration));
|
||||||
|
memcpy(g_RegExt + 0xfa, nunchuck_id, sizeof(nunchuck_id));
|
||||||
|
|
||||||
/*
|
|
||||||
g_RegExt[0xfa] = 0x00;
|
|
||||||
g_RegExt[0xfb] = 0x00;
|
|
||||||
g_RegExt[0xfc] = 0xa4;
|
|
||||||
g_RegExt[0xfd] = 0x20;
|
|
||||||
g_RegExt[0xfe] = 0x00;
|
|
||||||
g_RegExt[0xff] = 0x00;
|
|
||||||
*/
|
|
||||||
|
|
||||||
// g_RegExt[0xfd] = 0x1e;
|
// g_RegExt[0xfd] = 0x1e;
|
||||||
// g_RegExt[0xfc] = 0x9a;
|
// g_RegExt[0xfc] = 0x9a;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// ================
|
||||||
|
|
||||||
|
|
||||||
void DoState(void* ptr, int mode)
|
void DoState(void* ptr, int mode)
|
||||||
{
|
{
|
||||||
|
@ -129,8 +139,6 @@ void Shutdown(void)
|
||||||
// ----------------
|
// ----------------
|
||||||
void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size)
|
void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size)
|
||||||
{
|
{
|
||||||
g_channelID = _channelID; // store the channel id for manual use
|
|
||||||
|
|
||||||
LOGV(WII_IPC_WIIMOTE, 0, "=============================================================");
|
LOGV(WII_IPC_WIIMOTE, 0, "=============================================================");
|
||||||
const u8* data = (const u8*)_pData;
|
const u8* data = (const u8*)_pData;
|
||||||
|
|
||||||
|
@ -243,6 +251,7 @@ void Update()
|
||||||
case WM_REPORT_CORE: SendReportCore(g_ReportingChannel); break;
|
case WM_REPORT_CORE: SendReportCore(g_ReportingChannel); break;
|
||||||
case WM_REPORT_CORE_ACCEL: SendReportCoreAccel(g_ReportingChannel); break;
|
case WM_REPORT_CORE_ACCEL: SendReportCoreAccel(g_ReportingChannel); break;
|
||||||
case WM_REPORT_CORE_ACCEL_IR12: SendReportCoreAccelIr12(g_ReportingChannel);break;
|
case WM_REPORT_CORE_ACCEL_IR12: SendReportCoreAccelIr12(g_ReportingChannel);break;
|
||||||
|
case WM_REPORT_CORE_ACCEL_EXT16: SendReportCoreAccelExt16(g_ReportingChannel);break;
|
||||||
case WM_REPORT_CORE_ACCEL_IR10_EXT6: SendReportCoreAccelIr10Ext(g_ReportingChannel);break;
|
case WM_REPORT_CORE_ACCEL_IR10_EXT6: SendReportCoreAccelIr10Ext(g_ReportingChannel);break;
|
||||||
}
|
}
|
||||||
// g_ReportingMode = 0;
|
// g_ReportingMode = 0;
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "wiimote_hid.h"
|
#include "wiimote_hid.h"
|
||||||
#include "EmuDefinitions.h"
|
#include "EmuDefinitions.h"
|
||||||
|
#include "Encryption.h"
|
||||||
#include "Console.h" // for startConsoleWin, wprintf, GetConsoleHwnd
|
#include "Console.h" // for startConsoleWin, wprintf, GetConsoleHwnd
|
||||||
|
|
||||||
extern SWiimoteInitialize g_WiimoteInitialize;
|
extern SWiimoteInitialize g_WiimoteInitialize;
|
||||||
|
@ -38,7 +39,6 @@ namespace WiiMoteEmu
|
||||||
// Definitions and variable declarations
|
// Definitions and variable declarations
|
||||||
//******************************************************************************
|
//******************************************************************************
|
||||||
|
|
||||||
extern u16 g_channelID;
|
|
||||||
|
|
||||||
//extern u8 g_Leds = 0x1;
|
//extern u8 g_Leds = 0x1;
|
||||||
extern u8 g_Leds;
|
extern u8 g_Leds;
|
||||||
|
@ -47,11 +47,15 @@ extern u8 g_Eeprom[WIIMOTE_EEPROM_SIZE];
|
||||||
|
|
||||||
extern u8 g_RegSpeaker[WIIMOTE_REG_SPEAKER_SIZE];
|
extern u8 g_RegSpeaker[WIIMOTE_REG_SPEAKER_SIZE];
|
||||||
extern u8 g_RegExt[WIIMOTE_REG_EXT_SIZE];
|
extern u8 g_RegExt[WIIMOTE_REG_EXT_SIZE];
|
||||||
|
extern u8 g_RegExtTmp[WIIMOTE_REG_EXT_SIZE];
|
||||||
|
extern u8 g_RegExtBlnk[WIIMOTE_REG_EXT_SIZE];
|
||||||
|
|
||||||
extern u8 g_RegIr[WIIMOTE_REG_IR_SIZE];
|
extern u8 g_RegIr[WIIMOTE_REG_IR_SIZE];
|
||||||
|
|
||||||
extern u8 g_ReportingMode;
|
extern u8 g_ReportingMode;
|
||||||
extern u16 g_ReportingChannel;
|
extern u16 g_ReportingChannel;
|
||||||
|
|
||||||
|
extern wiimote_key g_ExtKey; // extension encryption key
|
||||||
|
|
||||||
static const u8 EepromData_0[] = {
|
static const u8 EepromData_0[] = {
|
||||||
0xA1, 0xAA, 0x8B, 0x99, 0xAE, 0x9E, 0x78, 0x30,
|
0xA1, 0xAA, 0x8B, 0x99, 0xAE, 0x9E, 0x78, 0x30,
|
||||||
|
@ -69,19 +73,40 @@ static const u8 EepromData_16D0[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Default calibration for the nunchuck. It should be written to 0x20 - 0x3f of the
|
||||||
|
extension register */
|
||||||
|
static const u8 nunchuck_calibration[] =
|
||||||
|
{
|
||||||
|
0x80,0x80,0x80,0x00, 0xb3,0xb3,0xb3,0x00,
|
||||||
|
0xe0,0x20,0x80,0xe0, 0x20,0x80,0xee,0x43,
|
||||||
|
0x80,0x80,0x80,0x00, 0xb3,0xb3,0xb3,0x00,
|
||||||
|
0xe0,0x20,0x80,0xe0, 0x20,0x80,0xee,0x43
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* The nunchuck id. It should be written to the last bytes of the
|
||||||
|
extension register */
|
||||||
|
static const u8 nunchuck_id[] =
|
||||||
|
{
|
||||||
|
0x00, 0x00, 0xa4, 0x20, 0x00, 0x00
|
||||||
|
//0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
void HidOutputReport(u16 _channelID, wm_report* sr);
|
void HidOutputReport(u16 _channelID, wm_report* sr);
|
||||||
|
|
||||||
void WmLeds(u16 _channelID, wm_leds* leds);
|
void WmLeds(u16 _channelID, wm_leds* leds);
|
||||||
void WmReadData(u16 _channelID, wm_read_data* rd);
|
void WmReadData(u16 _channelID, wm_read_data* rd);
|
||||||
void WmWriteData(u16 _channelID, wm_write_data* wd);
|
void WmWriteData(u16 _channelID, wm_write_data* wd);
|
||||||
void WmRequestStatus(u16 _channelID, wm_request_status* rs);
|
void WmRequestStatus(u16 _channelID, wm_request_status* rs);
|
||||||
void WmRequestStatus_(u16 _channelID);
|
void WmRequestStatus_(u16 _channelID, int a);
|
||||||
void WmDataReporting(u16 _channelID, wm_data_reporting* dr);
|
void WmDataReporting(u16 _channelID, wm_data_reporting* dr);
|
||||||
|
|
||||||
void SendReadDataReply(u16 _channelID, void* _Base, u16 _Address, u8 _Size);
|
void SendReadDataReply(u16 _channelID, void* _Base, u16 _Address, u8 _Size);
|
||||||
void SendReportCoreAccel(u16 _channelID);
|
void SendReportCoreAccel(u16 _channelID);
|
||||||
void SendReportCoreAccelIr12(u16 _channelID);
|
void SendReportCoreAccelIr12(u16 _channelID);
|
||||||
void SendReportCore(u16 _channelID);
|
void SendReportCore(u16 _channelID);
|
||||||
|
void SendReportCoreAccelExt16(u16 _channelID);
|
||||||
void SendReportCoreAccelIr10Ext(u16 _channelID);
|
void SendReportCoreAccelIr10Ext(u16 _channelID);
|
||||||
|
|
||||||
int WriteWmReport(u8* dst, u8 channel);
|
int WriteWmReport(u8* dst, u8 channel);
|
||||||
|
@ -92,6 +117,7 @@ void FillReportAcc(wm_accel& _acc);
|
||||||
void FillReportInfo(wm_core& _core);
|
void FillReportInfo(wm_core& _core);
|
||||||
void FillReportIR(wm_ir_extended& _ir0, wm_ir_extended& _ir1);
|
void FillReportIR(wm_ir_extended& _ir0, wm_ir_extended& _ir1);
|
||||||
void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1);
|
void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1);
|
||||||
|
void FillReportExtension(wm_extension& _ext);
|
||||||
|
|
||||||
|
|
||||||
u32 convert24bit(const u8* src);
|
u32 convert24bit(const u8* src);
|
||||||
|
|
|
@ -0,0 +1,297 @@
|
||||||
|
// Copyright (C) 2003-2008 Dolphin Project.
|
||||||
|
// Copyright (C) Hector Martin "marcan" (hector@marcansoft.com)
|
||||||
|
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
|
// Official SVN repository and contact information can be found at
|
||||||
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
|
|
||||||
|
#include "pluginspecs_wiimote.h"
|
||||||
|
#include "Common.h"
|
||||||
|
#include "Console.h" // for startConsoleWin, wprintf, GetConsoleHwnd
|
||||||
|
#include "Encryption.h"
|
||||||
|
|
||||||
|
|
||||||
|
u8 ans_tbl[7][6] = {
|
||||||
|
{0xA8,0x77,0xA6,0xE0,0xF7,0x43},
|
||||||
|
{0x5A,0x35,0x85,0xE2,0x72,0x97},
|
||||||
|
{0x8F,0xB7,0x1A,0x62,0x87,0x38},
|
||||||
|
{ 0xD,0x67,0xC7,0xBE,0x4F,0x3E},
|
||||||
|
{0x20,0x76,0x37,0x8F,0x68,0xB7},
|
||||||
|
{0xA9,0x26,0x3F,0x2B,0x10,0xE3},
|
||||||
|
{0x30,0x7E,0x90, 0xE,0x85, 0xA},
|
||||||
|
};
|
||||||
|
|
||||||
|
u8 tsbox[256] = {
|
||||||
|
0x70,0x51, 3,0x86,0x40, 0xD,0x4F,0xEB,0x3E,0xCC,0xD1,0x87,0x35,0xBD,0xF5, 0xB,
|
||||||
|
0x5E,0xD0,0xF8,0xF2,0xD5,0xE2,0x6C,0x31, 0xC,0xAD,0xFC,0x21,0xC3,0x78,0xC1, 6,
|
||||||
|
0xC2,0x4C,0x55,0xE6,0x4A,0x34,0x48,0x11,0x1E,0xDA,0xE7,0x1A,0x84,0xA0,0x96,0xA7,
|
||||||
|
0xE3,0x7F,0xAF,0x63,0x9C,0xFA,0x23,0x5B,0x79,0xC8,0x9E,0xBA,0xB2,0xC9,0x22,0x12,
|
||||||
|
0x4B,0xB3,0xA1,0xB6,0x32,0x49,0xA2,0xE1,0x89,0x39,0x10,0x66,0xC5, 7,0x8F,0x54,
|
||||||
|
0xEA,0x91,0xCA,0x3F,0xF9,0x19,0xF0,0xD7,0x46,0xBC,0x28,0x1B,0x61,0xE8,0x2F,0x6A,
|
||||||
|
0xAE,0x9D,0xF6,0x4E, 9,0x14,0x77,0x4D,0xDB,0x1F,0x2E,0x7B,0x7C,0xF1,0x43,0xA3,
|
||||||
|
0,0xB8,0x13,0x8C,0x85,0xB9,0x29,0x75,0x88,0xFD,0xD2,0x56,0x1C,0x50,0x97,0x41,
|
||||||
|
0xE5,0x3B,0x60,0xB5,0xC0,0x64,0xEE,0x98,0xD6,0x2D,0x25,0xA4,0xAA,0xCD,0x7D,0xA8,
|
||||||
|
0x83,0xC6,0xAB,0xBE,0x44,0x99,0x26,0x3C,0xCE,0x9F,0xBF,0xD3,0xCB,0x76,0x7A,0x7E,
|
||||||
|
0x82, 1,0x8A,0x9A,0x80,0x1D, 0xE,0xB0,0x5C,0xD4,0x38,0x62,0xF4,0x30,0xE0,0x8E,
|
||||||
|
0x53,0xB7, 2,0x57,0xAC,0xA6,0x52, 0xA,0x6D,0x92,0x65,0x17,0x24,0x33,0x45,0x72,
|
||||||
|
0x74,0xB1,0xB4,0xF7,0x5D,0xED,0x2C,0xFF,0x47,0x37,0x5A,0x90,0xBB,0xDF,0x2A,0x16,
|
||||||
|
0x59,0x95,0xD9,0xC4,0x27,0x67,0x73,0xC7,0x68,0xFE,0xA5,0xDD,0x6B,0x5F,0x93,0xD8,
|
||||||
|
0xEC, 5,0x3A,0x8D,0x6E,0xFB,0x3D,0xA9,0x69,0x36,0xF3,0x94,0xDE,0xEF,0x15,0x6F,
|
||||||
|
0x8B,0x9B, 8, 0xF,0xDC,0x81,0x18,0x20, 4,0xE4,0x71,0xCF,0xE9,0x2B,0x42,0x58,
|
||||||
|
};
|
||||||
|
|
||||||
|
u8 sboxes[8][256] = {
|
||||||
|
{
|
||||||
|
1,0xA0,0xA9,0x62,0xD6,0x3F,0x85,0xA7,0xB6,0xD4,0xFA,0x15,0x66,0x17, 9,0xBD,
|
||||||
|
0x5D,0x14,0x34,0x26,0x59,0x72,0x91,0x54, 6,0x4F,0xF8,0xB0,0x5B,0x74,0x93,0x99,
|
||||||
|
0x8C,0xF2,0x45,0xCD,0xEA,0x4E,0xAD,0x10,0x4A,0xE5,0xCA,0xEE,0xDF,0xC6,0x6F,0x9F,
|
||||||
|
0x88,0x8E, 2,0xCC, 8,0xA8,0x77,0x94,0x6D,0x21,0xB1,0x28,0xE4,0x39,0x79,0x96,
|
||||||
|
0x60,0x71,0x81,0x16,0x2E,0xE6,0x78,0xB9,0xC4,0x46,0x9A,0x42,0xAE,0xB7,0x7C,0x43,
|
||||||
|
0xB3,0x22,0x1A,0x86,0xC2,0x32,0x3D,0x2D,0x9C,0xD2,0x29,0xE9,0x63,0x9B,0xD1,0x31,
|
||||||
|
0x38,0x5E,0x1E,0x36,0x41,0xBB, 3,0x18,0x2B,0x3E,0xBF,0x68,0x61,0xFC,0x52,0xC0,
|
||||||
|
0xDE,0xE0, 0xA,0x58,0x13,0x5A, 0,0xBE,0x1C,0x90, 0xE,0x53,0x12,0xFD,0xE2,0x6E,
|
||||||
|
0xBA,0xCE,0x24,0x27,0x44,0x7F,0x87,0xA3,0xA1,0xD5,0x50,0x40,0xE3,0xF9,0x83,0xF7,
|
||||||
|
0xC7,0xA2,0x35,0xC8,0xDB,0x19,0xAB,0x2F,0x11,0x25,0xED,0x33,0x9E,0x55,0xE1,0x48,
|
||||||
|
0xAF,0x73,0x84,0xDA,0x2A,0xAA,0x51,0xEB,0x9D,0x95,0xB2,0xCB,0xE7,0x70,0x80,0xFE,
|
||||||
|
0x4C,0x65, 4,0xEF,0xC5,0xF1,0xC3,0x3A,0xB4,0xF5,0x5F,0x23,0x89,0xDD,0x30,0xA5,
|
||||||
|
0x8B,0xD3,0xF6,0xDC,0x4D,0x64,0xD7,0xF0,0x8F,0xEC,0x56,0x37,0x5C,0xA4, 0xD, 7,
|
||||||
|
0x76,0x8A,0x2C, 0xB,0xB5,0xD8,0xC1,0x1F,0xE8,0x3B,0xF4,0x4B,0x1B,0x47,0x6C,0x49,
|
||||||
|
0x67,0x7B,0x92,0xCF,0x75,0x7E,0x20,0xD9,0x7D,0x3C,0x97,0x7A,0xD0, 5,0x6B, 0xF,
|
||||||
|
0x1D,0xFB,0x82,0x98,0x57,0x8D,0xF3,0x6A,0xBC,0xAC,0xC9,0xA6,0xFF,0xB8,0x69, 0xC,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0x4C,0x4D,0x72, 7,0x5A,0x49,0x33,0x8D,0xA2,0xAB,0x46,0x3D,0x63, 0xD,0xA0,0x97,
|
||||||
|
0xFF,0xF0,0xF5,0xFA,0xC0,0xE9,0xDB,0x62,0xE4,0xE1,0x74,0x43,0xDC,0x86,0x18,0x29,
|
||||||
|
0x37,0xF4, 6,0xE2,0xED,0x6F,0x90,0x48,0x1E,0x2D,0x1D,0xEA,0x73,0x94,0x54,0xDF,
|
||||||
|
0x25,0xF6,0x47,0x27,0xD9,0x11,0x77,0xC9,0x84,0x1C,0x5B,0x5C,0x51,0x81,0xA6,0x22,
|
||||||
|
0x3E,0x24,0x96,0xC8,0x8A,0xEC,0x82,0x7C, 9,0xB8,0x45,0x4A,0x57,0xBB,0x2F,0x50,
|
||||||
|
0x75,0x8E,0x61,0x70,0x8C,0x6C,0xAF,0xD0,0xFD,0xB4,0x1B,0xAE,0xDE,0xFE,0x3B,0xB5,
|
||||||
|
0x36,0xBD,0x55, 1, 0xE,0x9C,0x41,0x56,0x5F,0xB3,0x26, 3,0x83,0xBA,0x13,0x4B,
|
||||||
|
0xCA,0xC5, 0xA,0xF8,0x60,0xA5,0xB9,0xC7,0xC3,0x98,0x32,0xFB,0x12,0xF9,0xA7,0x92,
|
||||||
|
0xAA,0x68,0xF3,0x78,0x7E, 5,0x20,0x21, 2,0xE8,0xBF,0xF2,0xB0,0x59,0x8F,0xD2,
|
||||||
|
0xCB,0x87,0x65,0x15,0xF1,0x1A,0xB2,0x30,0xAD,0xEE,0x58,0xA3,0x8B,0x66,0x1F,0x2C,
|
||||||
|
0xD7,0x5D,0x19,0x85,0xA8,0xE6,0xD3,0x6B,0xA1, 0xC,0x91,0x93,0x6A,0x5E, 0xB,0x79,
|
||||||
|
0xE3,0xDD, 0,0x4F,0x3C,0x89,0x6E,0x71,0x69,0xA9,0xAC,0x40,0xE5,0x99,0x28,0xC6,
|
||||||
|
0x31,0x4E,0x7A,0xCD, 8,0x9E,0x7D,0xEF,0x17,0xFC,0x88,0xD8,0xA4,0x6D,0x44,0x95,
|
||||||
|
0xD1,0xB7,0xD4,0x9B,0xBE,0x2A,0x34,0x64,0x2B,0xCF,0x2E,0xEB,0x38,0xCE,0x23,0xE0,
|
||||||
|
0x3A,0x3F,0xF7,0x7B,0x9F,0x10,0x53,0xBC,0x52,0x67,0x16,0xE7,0x80,0x76, 4,0xC4,
|
||||||
|
0xB6,0xC1,0xC2,0x7F,0x9A,0xDA,0xD5,0x39,0x42,0x14,0x9D,0xB1, 0xF,0x35,0xD6,0xCC,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0xB9,0xDA,0x38, 0xC,0xA2,0x9C, 9,0x1F, 6,0xB1,0xB6,0xFD,0x1A,0x69,0x23,0x30,
|
||||||
|
0xC4,0xDE, 1,0xD1,0xF4,0x58,0x29,0x37,0x1C,0x7D,0xD5,0xBF,0xFF,0xBD,0xC8,0xC9,
|
||||||
|
0xCF,0x65,0xBE,0x7B,0x78,0x97,0x98,0x67, 8,0xB3,0x26,0x57,0xF7,0xFA,0x40,0xAD,
|
||||||
|
0x8E,0x75,0xA6,0x7C,0xDB,0x91,0x8B,0x51,0x99,0xD4,0x17,0x7A,0x90,0x8D,0xCE,0x63,
|
||||||
|
0xCB,0x4E,0xA0,0xAB,0x18,0x3A,0x5B,0x50,0x7F,0x21,0x74,0xC1,0xBB,0xB8,0xB7,0xBA,
|
||||||
|
0xB,0x35,0x95,0x31,0x59,0x9A,0x4D, 4, 7,0x1E,0x5A,0x76,0x13,0xF3,0x71,0x83,
|
||||||
|
0xD0,0x86, 3,0xA8,0x39,0x42,0xAA,0x28,0xE6,0xE4,0xD8,0x5D,0xD3,0xD0,0x6E,0x6F,
|
||||||
|
0x96,0xFB,0x5E,0xBC,0x56,0xC2,0x5F,0x85,0x9B,0xE7,0xAF,0xD2,0x3B,0x84,0x6A,0xA7,
|
||||||
|
0x53,0xC5,0x44,0x49,0xA5,0xF9,0x36,0x72,0x3D,0x2C,0xD9,0x1B,0xA1,0xF5,0x4F,0x93,
|
||||||
|
0x9D,0x68,0x47,0x41,0x16,0xCA,0x2A,0x4C,0xA3,0x87,0xD6,0xE5,0x19,0x2E,0x77,0x15,
|
||||||
|
0x6D,0x70,0xC0,0xDF,0xB2, 0,0x46,0xED,0xC6,0x6C,0x43,0x60,0x92,0x2D,0xA9,0x22,
|
||||||
|
0x45,0x8F,0x34,0x55,0xAE,0xA4, 0xA,0x66,0x32,0xE0,0xDC, 2,0xAC,0xE8,0x20,0x8C,
|
||||||
|
0x89,0x62,0x4A,0xFE,0xEE,0xC3,0xE3,0x3C,0xF1,0x79, 5,0xE9,0xF6,0x27,0x33,0xCC,
|
||||||
|
0xF2,0x9E,0x11,0x81,0x7E,0x80,0x10,0x8A,0x82,0x9F,0x48, 0xD,0xD7,0xB4,0xFC,0x2F,
|
||||||
|
0xB5,0xC7,0xDD,0x88,0x14,0x6B,0x2B,0x54,0xEA,0x1D,0x94,0x5C,0xB0,0xEF,0x12,0x24,
|
||||||
|
0xCD,0xEB,0xE1,0xE2,0x64,0x73,0x3F, 0xE,0x52,0x61,0x25,0x3E,0xF8, 0xF,0x4B,0xEC,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0xC0, 0,0x30,0xF6, 2,0x49,0x3D,0x10,0x6E,0x20,0xC9,0xA6,0x2F,0xFE,0x2C,0x2B,
|
||||||
|
0x75,0x2E,0x45,0x26,0xAB,0x48,0xA9,0x80,0xFC, 4,0xCC,0xD3,0xB5,0xBA,0xA3,0x38,
|
||||||
|
0x31,0x7D, 1,0xD9,0xA7,0x7B,0x96,0xB6,0x63,0x69,0x4E,0xF7,0xDE,0xE0,0x78,0xCA,
|
||||||
|
0x50,0xAA,0x41,0x91,0x65,0x88,0xE4,0x21,0x85,0xDA,0x3A,0x27,0xBE,0x1C,0x3E,0x42,
|
||||||
|
0x5E,0x17,0x52,0x7F,0x1F,0x89,0x24,0x6F,0x8F,0x5C,0x67,0x74, 0xE,0x12,0x87,0x8D,
|
||||||
|
0xE9,0x34,0xED,0x73,0xC4,0xF8,0x61,0x5B, 5,0xDF,0x59,0x4C,0x97,0x79,0x83,0x18,
|
||||||
|
0xA4,0x55,0x95,0xEB,0xBD,0x53,0xF5,0xF1,0x57,0x66,0x46,0x9F,0xB2,0x81, 9,0x51,
|
||||||
|
0x86,0x22,0x16,0xDD,0x23,0x93,0x76,0x29,0xC2,0xD7,0x1D,0xD4,0xBF,0x36,0x3F,0xEA,
|
||||||
|
0x4B,0x11,0x32,0xB9,0x62,0x54,0x60,0xD6,0x6D,0x43,0x9A, 0xD,0x92,0x9C,0xB0,0xEF,
|
||||||
|
0x58,0x6C,0x9D,0x77,0x2D,0x70,0xFA,0xF3,0xB3, 0xB,0xE2,0x40,0x7E,0xF4,0x8A,0xE5,
|
||||||
|
0x8C,0x3C,0x56,0x71,0xD1,0x64,0xE1,0x82, 0xA,0xCB,0x13,0x15,0x90,0xEC, 3,0x99,
|
||||||
|
0xAF,0x14,0x5D, 0xF,0x33,0x4A,0x94,0xA5,0xA8,0x35,0x1B,0xE3,0x6A,0xC6,0x28,0xFF,
|
||||||
|
0x4D,0xE7,0x25,0x84,0xAC, 8,0xAE,0xC5,0xA2,0x2A,0xB8,0x37, 0xC,0x7A,0xA0,0xC3,
|
||||||
|
0xCE,0xAD, 6,0x1A,0x9E,0x8B,0xFB,0xD5,0xD0,0xC1,0x1E,0xD0,0xB4,0x9B,0xB1,0x44,
|
||||||
|
0xF2,0x47,0xC7,0x68,0xCF,0x72,0xBB,0x4F,0x5A,0xF9,0xDC,0x6B,0xDB,0xD2,0xE8,0x7C,
|
||||||
|
0xC8,0xEE,0x98,0xA1,0xE6,0xD8,0x39, 7,0x5F,0xFD,0x8E,0x19,0xB7,0x3B,0xBC,0xCD,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0x7C,0xE3,0x81,0x73,0xB2,0x11,0xBF,0x6F,0x20,0x98,0xFE,0x75,0x96,0xEF,0x6C,0xDA,
|
||||||
|
0x50,0xE1, 9,0x72,0x54,0x45,0xBA,0x34,0x80,0x5B,0xED,0x3E,0x53,0x2C,0x87,0xA4,
|
||||||
|
0x57,0xF3,0x33,0x3F,0x3C,0xB7,0x67,0xB4,0xA3,0x25,0x60,0x4F, 7,0x6B,0x1B,0x47,
|
||||||
|
0x15, 0xF,0xE4, 0xA,0xEA,0xD1,0x32,0x78,0x36,0x49,0x8D,0x4B,0xD2,0xBC,0xA5,0xDC,
|
||||||
|
0x1D, 0xD,0x4D,0xCD,0x9A,0x82,0x5F,0xFC,0x94,0x65,0xBE,0xE2,0xF4,0xC9,0x1E,0x44,
|
||||||
|
0xCB,0x9E, 0xC,0x64,0x71,0x26,0x63,0xB3,0x14,0xE8,0x40,0x70,0x8A, 0xE,0x19,0x42,
|
||||||
|
0x6D,0xAC,0x88,0x10,0x5C,0xDF,0x41,0xA9,0xAD,0xE5,0xFB,0x74,0xCC,0xD5, 6,0x8E,
|
||||||
|
0x59,0x86,0xCE,0x1F,0x3D,0x76,0xE0,0x8F,0xB9,0x77,0x27,0x7B,0xA6,0xD8,0x29,0xD3,
|
||||||
|
0xEC,0xB8,0x13,0xF7,0xFA,0xC3,0x51,0x6A,0xDE,0x4A,0x5A,0xEB,0xC2,0x8B,0x23,0x48,
|
||||||
|
0x92,0xCF,0x62,0xA8,0x99,0xF8,0xD0,0x2E,0x85,0x61,0x43,0xC8,0xBD,0xF0, 5,0x93,
|
||||||
|
0xCA,0x4E,0xF1,0x7D,0x30,0xFD,0xC4,0x69,0x66,0x2F, 8,0xB1,0x52,0xF9,0x21,0xE6,
|
||||||
|
0x7A,0x2B,0xDD,0x39,0x84,0xFF,0xC0,0x91,0xD6,0x37,0xD4,0x7F,0x2D,0x9B,0x5D,0xA1,
|
||||||
|
0x3B,0x6E,0xB5,0xC5,0x46, 4,0xF5,0x90,0xEE,0x7E,0x83,0x1C, 3,0x56,0xB6,0xAA,
|
||||||
|
0,0x17, 1,0x35,0x55,0x79, 0xB,0x12,0xBB,0x1A,0x31,0xE7, 2,0x28,0x16,0xC1,
|
||||||
|
0xF6,0xA2,0xDB,0x18,0x9C,0x89,0x68,0x38,0x97,0xAB,0xC7,0x2A,0xD7,0x3A,0xF2,0xC6,
|
||||||
|
0x24,0x4C,0xB0,0x58,0xA0,0x22,0x5E,0x9D,0xD9,0xA7,0xE9,0xAE,0xAF,0x8C,0x95,0x9F,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0x28,0xB7,0x20,0xD7,0xB0,0x30,0xC3, 9,0x19,0xC0,0x67,0xD6, 0,0x3C,0x7E,0xE7,
|
||||||
|
0xE9,0xF4, 8,0x5A,0xF8,0xB8,0x2E, 5,0xA6,0x25,0x9E,0x5C,0xD8,0x15, 0xD,0xE1,
|
||||||
|
0xF6,0x11,0x54,0x6B,0xCD,0x21,0x46,0x66,0x5E,0x84,0xAD, 6,0x38,0x29,0x44,0xC5,
|
||||||
|
0xA2,0xCE,0xF1,0xAA,0xC1,0x40,0x71,0x86,0xB5,0xEF,0xFC,0x36,0xA8,0xCB, 0xA,0x48,
|
||||||
|
0x27,0x45,0x64,0xA3,0xAF,0x8C,0xB2,0xC6,0x9F, 7,0x89,0xDC,0x17,0xD3,0x49,0x79,
|
||||||
|
0xFB,0xFE,0x1D,0xD0,0xB9,0x88,0x43,0x52,0xBC, 1,0x78,0x2B,0x7D,0x94,0xC7, 0xE,
|
||||||
|
0xDE,0xA5,0xD5,0x9B,0xCC,0xF7,0x61,0x7A,0xC2,0x74,0x81,0x39, 3,0xAB,0x96,0xA0,
|
||||||
|
0x37,0xBD,0x2D,0x72,0x75,0x3F,0xC9,0xD4,0x8E,0x6F,0xF9,0x8D,0xED,0x62,0xDB,0x1C,
|
||||||
|
0xDF, 4,0xAC,0x1B,0x6C,0x14,0x4B,0x63,0xD0,0xBF,0xB4,0x82,0xEC,0x7B,0x1A,0x59,
|
||||||
|
0x92,0xD2,0x10,0x60,0xB6,0x3D,0x5F,0xE6,0x80,0x6E,0x70,0xC4,0xF2,0x35,0xD9,0x7C,
|
||||||
|
0xEE,0xE5,0x41,0xA4,0x5B,0x50,0xDD,0xBB,0x4C,0xF3,0x1F,0x9D,0x5D,0x57,0x55,0x51,
|
||||||
|
0x97,0xE3,0x58,0x42,0x4D,0x9C,0x73,0xBA,0xC8,0x77,0x31,0x69,0x26,0xAE,0xEA,0x8A,
|
||||||
|
0xDA,0x22,0xB3,0x87,0x56,0xFA,0x93, 0xB,0x34,0x16,0x33,0xE8,0xE4,0x53,0xBE,0xA9,
|
||||||
|
0xB1,0x3A,0x3E,0xF5,0x90,0x6A,0xCF,0x3B,0x12,0xFD,0x8F,0x9A,0xA7,0x47,0x91,0x99,
|
||||||
|
0xEB, 0xF,0x24,0xFF,0x23,0x18,0x85,0x4E,0x7F, 0xC,0xE0,0xA1,0xD2,0xD1,0x2C,0x2A,
|
||||||
|
0x4A, 2,0x4F,0x1E,0x95,0x68,0x8B,0x98,0x83,0x6D,0x76,0xCA,0x65,0x32,0x13,0x2F,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0xC3,0x82,0x9A,0xA4,0xBA,0x81,0x60,0x37,0x34,0x35,0xFC,0x80,0xA8,0x51,0x65,0x67,
|
||||||
|
0xED,0x30,0x5F,0x10,0xD3,0x4A,0x27,0x2F,0x13,0xB9,0x2A,0xD2,0xCC,0xE1,0xEF,0xAE,
|
||||||
|
0xEB,0xBE,0xF4,0xBD,0xCF,0x43,0xB3,0xC5,0x88,0x84,0xB7,0xDD,0x39,0x40,0xCE,0x48,
|
||||||
|
0x6D,0x9B,0x72,0x61,0x7E,0xE7,0xA1,0x4E,0x53,0x2E,0x77,0x3B,0xE2,0xC9,0x36,0x22,
|
||||||
|
0x1B,0x6E,0x73,0xB1, 3,0xB2,0x4C,0x87,0xA9,0xD4,0x4D, 0xF,0xD8,0x15,0x6C,0xAA,
|
||||||
|
0x18,0xF6,0x49,0x57,0x5D,0xFB,0x7A,0x14,0x94,0x63,0xA0,0x11,0xB0,0x9E,0xDE, 5,
|
||||||
|
0x46,0xC8,0xEE,0x47,0xDB,0xDC,0x24,0x89,0x9C,0x91,0x97,0x29,0xE9,0x7B,0xC1, 7,
|
||||||
|
0x1E,0xB8,0xFD,0xFE,0xAC,0xC6,0x62,0x98,0x4F,0xF1,0x79,0xE0,0xE8,0x6B,0x78,0x56,
|
||||||
|
0xB6,0x8D, 4,0x50,0x86,0xCA,0x6F,0x20,0xE6,0xEA,0xE5,0x76,0x17,0x1C,0x74,0x7F,
|
||||||
|
0xBC, 0xD,0x2C,0x85,0xF7,0x66,0x96,0xE4,0x8B,0x75,0x3F,0x4B,0xD9,0x38,0xAF,0x7C,
|
||||||
|
0xDA, 0xB,0x83,0x2D,0x31,0x32,0xA2,0xF5,0x1D,0x59,0x41,0x45,0xBF,0x3C,0x1F,0xF8,
|
||||||
|
0xF9,0x8A,0xD0,0x16,0x25,0x69,0x12,0x99,0x9D,0x21,0x95,0xAB, 1,0xA6,0xD7,0xB5,
|
||||||
|
0xC0,0x7D,0xFF,0x58, 0xE,0x3A,0x92,0xD1,0x55,0xE3, 8,0x9F,0xD6,0x3E,0x52,0x8E,
|
||||||
|
0xFA,0xA3,0xC7, 2,0xCD,0xDF,0x8F,0x64,0x19,0x8C,0xF3,0xA7, 0xC,0x5E, 0xA,0x6A,
|
||||||
|
9,0xF0,0x93,0x5B,0x42,0xC2, 6,0x23,0xEC,0x71,0xAD,0xB4,0xCB,0xBB,0x70,0x28,
|
||||||
|
0xD5,0x1A,0x5C,0x33,0x68,0x5A, 0,0x44,0x90,0xA5,0xC4,0x26,0x3D,0x2B,0xF2,0x54,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0x96,0xAD,0xDA,0x1F,0xED,0x33,0xE1,0x81,0x69, 8, 0xD, 0xA,0xDB,0x35,0x77,0x9A,
|
||||||
|
0x64,0xD1,0xFC,0x78,0xAA,0x1B,0xD0,0x67,0xA0,0xDD,0xFA,0x6C,0x63,0x71, 5,0x84,
|
||||||
|
0x17,0x6A,0x89,0x4F,0x66,0x7F,0xC6,0x50,0x55,0x92,0x6F,0xBD,0xE7,0xD2,0x40,0x72,
|
||||||
|
0x8D,0xBB,0xEC, 6,0x42,0x8A,0xE4,0x88,0x9D,0x7E,0x7A,0x82,0x27,0x13,0x41,0x1A,
|
||||||
|
0xAF,0xC8,0xA4,0x76,0xB4,0xC2,0xFE,0x6D,0x1C,0xD9,0x61,0x30,0xB3,0x7C,0xEA,0xF7,
|
||||||
|
0x29, 0xF,0xF2,0x3B,0x51,0xC1,0xDE,0x5F,0xE5,0x2A,0x2F,0x99, 0xB,0x5D,0xA3,0x2B,
|
||||||
|
0x4A,0xAB,0x95,0xA5,0xD3,0x58,0x56,0xEE,0x28,0x31, 0,0xCC,0x15,0x46,0xCA,0xE6,
|
||||||
|
0x86,0x38,0x3C,0x65,0xF5,0xE3,0x9F,0xD6,0x5B, 9,0x49,0x83,0x70,0x2D,0x53,0xA9,
|
||||||
|
0x7D,0xE2,0xC4,0xAC,0x8E,0x5E,0xB8,0x25,0xF4,0xB9,0x57,0xF3,0xF1,0x68,0x47,0xB2,
|
||||||
|
0xA2,0x59,0x20,0xCE,0x34,0x79,0x5C,0x90, 0xE,0x1E,0xBE,0xD5,0x22,0x23,0xB1,0xC9,
|
||||||
|
0x18,0x62,0x16,0x2E,0x91,0x3E, 7,0x8F,0xD8,0x3F,0x93,0x3D,0xD4,0x9B,0xDF,0x85,
|
||||||
|
0x21,0xFB,0x11,0x74,0x97,0xC7,0xD7,0xDC,0x4C,0x19,0x45,0x98,0xE9,0x43, 2,0x4B,
|
||||||
|
0xBC,0xC3, 4,0x9C,0x6B,0xF0,0x75,0x52,0xA7,0x26,0xF6,0xC5,0xBA,0xCF,0xB0,0xB7,
|
||||||
|
0xAE,0x5A,0xA1,0xBF, 3,0x8B,0x80,0x12,0x6E, 0xC,0xEB,0xF9,0xC0,0x44,0x24,0xEF,
|
||||||
|
0x10,0xF8,0xA8,0x8C,0xE8,0x7B,0xFF,0x9E,0x2C,0xCD,0x60,0x36,0x87,0xB5,0x94,0xA6,
|
||||||
|
0x54,0x73,0x3A,0x14,0x4E, 1,0x1D,0xB6,0xFD,0x37,0x48,0x4D,0x39,0xCB,0xE0,0x32,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static inline u8 ror8(u8 a, u8 b) {
|
||||||
|
return (a>>b) | ((a<<(8-b))&0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void genkey(u8 *rand, u8 idx, u8 *key)
|
||||||
|
{
|
||||||
|
u8 *ans = ans_tbl[idx];
|
||||||
|
u8 t0[10];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i=0;i<10;i++)
|
||||||
|
t0[i] = tsbox[rand[i]];
|
||||||
|
|
||||||
|
key[0] = ((ror8((ans[0]^t0[5]),(t0[2]%8)) - t0[9]) ^ t0[4]);
|
||||||
|
key[1] = ((ror8((ans[1]^t0[1]),(t0[0]%8)) - t0[5]) ^ t0[7]);
|
||||||
|
key[2] = ((ror8((ans[2]^t0[6]),(t0[8]%8)) - t0[2]) ^ t0[0]);
|
||||||
|
key[3] = ((ror8((ans[3]^t0[4]),(t0[7]%8)) - t0[3]) ^ t0[2]);
|
||||||
|
key[4] = ((ror8((ans[4]^t0[1]),(t0[6]%8)) - t0[3]) ^ t0[4]);
|
||||||
|
key[5] = ((ror8((ans[5]^t0[7]),(t0[8]%8)) - t0[5]) ^ t0[9]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void gentabs(u8 *rand, u8 *key, u8 idx, u8 *ft, u8 *sb)
|
||||||
|
{
|
||||||
|
ft[0] = sboxes[idx][key[4]] ^ sboxes[(idx+1)%8][rand[3]];
|
||||||
|
ft[1] = sboxes[idx][key[2]] ^ sboxes[(idx+1)%8][rand[5]];
|
||||||
|
ft[2] = sboxes[idx][key[5]] ^ sboxes[(idx+1)%8][rand[7]];
|
||||||
|
ft[3] = sboxes[idx][key[0]] ^ sboxes[(idx+1)%8][rand[2]];
|
||||||
|
ft[4] = sboxes[idx][key[1]] ^ sboxes[(idx+1)%8][rand[4]];
|
||||||
|
ft[5] = sboxes[idx][key[3]] ^ sboxes[(idx+1)%8][rand[9]];
|
||||||
|
ft[6] = sboxes[idx][rand[0]] ^ sboxes[(idx+1)%8][rand[6]];
|
||||||
|
ft[7] = sboxes[idx][rand[1]] ^ sboxes[(idx+1)%8][rand[8]];
|
||||||
|
|
||||||
|
sb[0] = sboxes[idx][key[0]] ^ sboxes[(idx+1)%8][rand[1]];
|
||||||
|
sb[1] = sboxes[idx][key[5]] ^ sboxes[(idx+1)%8][rand[4]];
|
||||||
|
sb[2] = sboxes[idx][key[3]] ^ sboxes[(idx+1)%8][rand[0]];
|
||||||
|
sb[3] = sboxes[idx][key[2]] ^ sboxes[(idx+1)%8][rand[9]];
|
||||||
|
sb[4] = sboxes[idx][key[4]] ^ sboxes[(idx+1)%8][rand[7]];
|
||||||
|
sb[5] = sboxes[idx][key[1]] ^ sboxes[(idx+1)%8][rand[8]];
|
||||||
|
sb[6] = sboxes[idx][rand[3]] ^ sboxes[(idx+1)%8][rand[5]];
|
||||||
|
sb[7] = sboxes[idx][rand[2]] ^ sboxes[(idx+1)%8][rand[6]];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ===================================================
|
||||||
|
/* Generate key from the 0x40-0x4c data in g_RegExt */
|
||||||
|
// ----------------
|
||||||
|
void wiimote_gen_key(wiimote_key *key, u8 *keydata)
|
||||||
|
{
|
||||||
|
u8 rand[10];
|
||||||
|
u8 skey[6];
|
||||||
|
u8 testkey[6];
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
for(int i=0;i<10;i++)
|
||||||
|
rand[9-i] = keydata[i];
|
||||||
|
for(int i=0;i<6;i++)
|
||||||
|
skey[5-i] = keydata[i+10];
|
||||||
|
|
||||||
|
wprintf("rand: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", rand[0], rand[1], rand[2], rand[3], rand[4], rand[5], rand[6], rand[7], rand[8], rand[9]);
|
||||||
|
wprintf("key: %02x %02x %02x %02x %02x %02x\n", skey[0], skey[1], skey[2], skey[3], skey[4], skey[5]);
|
||||||
|
|
||||||
|
for(idx=0;idx<7;idx++)
|
||||||
|
{
|
||||||
|
genkey(rand, idx, testkey);
|
||||||
|
if(!memcmp(testkey,skey,6))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// default case is idx = 7 which is valid (homebrew uses it for the 0x17 case)
|
||||||
|
wprintf("idx: %d\n", idx);
|
||||||
|
|
||||||
|
gentabs(rand, skey, idx, key->ft, key->sb);
|
||||||
|
|
||||||
|
wprintf("ft: %02x %02x %02x %02x %02x %02x %02x %02x\n", key->ft[0], key->ft[1], key->ft[2], key->ft[3], key->ft[4], key->ft[5], key->ft[6], key->ft[7]);
|
||||||
|
wprintf("sb: %02x %02x %02x %02x %02x %02x %02x %02x\n", key->sb[0], key->sb[1], key->sb[2], key->sb[3], key->sb[4], key->sb[5], key->sb[6], key->sb[7]);
|
||||||
|
|
||||||
|
// for homebrew, ft and sb are all 0x97 which is equivalent to 0x17
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ===================================================
|
||||||
|
/* Encrypt data */
|
||||||
|
// ----------------
|
||||||
|
void wiimote_encrypt(wiimote_key *key, u8 *data, int addr, u8 len)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < len; i++, addr++)
|
||||||
|
{
|
||||||
|
//wprintf("data[%i] from %02x ", i, data[i]);
|
||||||
|
data[i] = (data[i] - key->ft[addr%8]) ^ key->sb[addr%8];
|
||||||
|
//wprintf("to %02x\n", data[i]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
// Copyright (C) 2003-2008 Dolphin Project.
|
||||||
|
// Copyright (C) Hector Martin "marcan" (hector@marcansoft.com)
|
||||||
|
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
|
// Official SVN repository and contact information can be found at
|
||||||
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef WIIMOTE_EXTENSION_ENCRYPTION_H
|
||||||
|
#define WIIMOTE_EXTENSION_ENCRYPTION_H
|
||||||
|
|
||||||
|
|
||||||
|
// ===================================================
|
||||||
|
/* They key structure to use with wiimote_gen_key() */
|
||||||
|
// ----------------
|
||||||
|
typedef struct {
|
||||||
|
u8 ft[8];
|
||||||
|
u8 sb[8];
|
||||||
|
} wiimote_key;
|
||||||
|
|
||||||
|
|
||||||
|
void wiimote_encrypt(wiimote_key *key, u8 *data, int addr, u8 len);
|
||||||
|
|
||||||
|
void wiimote_gen_key(wiimote_key *key, u8 *keydata);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -42,7 +42,8 @@ namespace WiiMoteEmu
|
||||||
//******************************************************************************
|
//******************************************************************************
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
/* Debugging. Read out the structs. */
|
||||||
void ReadExt()
|
void ReadExt()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < WIIMOTE_REG_EXT_SIZE; i++)
|
for (int i = 0; i < WIIMOTE_REG_EXT_SIZE; i++)
|
||||||
|
@ -53,12 +54,26 @@ void ReadExt()
|
||||||
}
|
}
|
||||||
wprintf("\n\n");
|
wprintf("\n\n");
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
//bool AllowReport = true;
|
void ReadExtTmp()
|
||||||
//int AllowCount = 0;
|
{
|
||||||
//bool toggleSideWays = false;
|
for (int i = 0; i < WIIMOTE_REG_EXT_SIZE; i++)
|
||||||
|
{
|
||||||
|
//wprintf("%i | (i % 16)
|
||||||
|
wprintf("%02x ", g_RegExtTmp[i]);
|
||||||
|
if((i + 1) % 20 == 0) wprintf("\n");
|
||||||
|
}
|
||||||
|
wprintf("\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* The extension status can be a little difficult, this lets's us change the extension
|
||||||
|
status back and forth */
|
||||||
|
bool AllowReport = true;
|
||||||
|
int AllowCount = 0;
|
||||||
|
|
||||||
|
|
||||||
void FillReportInfo(wm_core& _core)
|
void FillReportInfo(wm_core& _core)
|
||||||
{
|
{
|
||||||
|
@ -97,32 +112,79 @@ void FillReportInfo(wm_core& _core)
|
||||||
_core.down = GetAsyncKeyState(VK_DOWN) ? 1 : 0;
|
_core.down = GetAsyncKeyState(VK_DOWN) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**/
|
||||||
if(GetAsyncKeyState('M') && AllowReport)
|
// -----------------------
|
||||||
|
// Debugging. Send status report.
|
||||||
|
if(GetAsyncKeyState('I') && AllowReport)
|
||||||
{
|
{
|
||||||
|
//ClearScreen();
|
||||||
|
|
||||||
|
// Clear the register
|
||||||
|
//memcpy(g_RegExt, g_RegExtBlnk, sizeof(g_RegExt));
|
||||||
|
//g_RegExt[0xfc] = 0xa4;
|
||||||
|
//g_RegExt[0xfd] = 0x20;
|
||||||
|
|
||||||
|
// Clear the key part of the register
|
||||||
|
/**/
|
||||||
|
for(int i=0; i <= 16; i++)
|
||||||
|
{
|
||||||
|
g_RegExt[0x40 + i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
//wm_report sr;
|
//wm_report sr;
|
||||||
//wm_request_status *sr;
|
//wm_request_status *sr;
|
||||||
//WmRequestStatus(0x41, sr);
|
//WmRequestStatus(g_ReportingChannel, sr);
|
||||||
|
|
||||||
WmRequestStatus_(0x0041);
|
/**/
|
||||||
|
WmRequestStatus_(g_ReportingChannel, 1);
|
||||||
|
|
||||||
wprintf("Sent status report\n");
|
wprintf("Sent status report\n");
|
||||||
AllowReport = false;
|
AllowReport = false;
|
||||||
AllowCount = 0;
|
AllowCount = 0;
|
||||||
|
|
||||||
void ReadExt();
|
//void ReadExt();
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
if(AllowCount > 20)
|
/**/
|
||||||
|
if(GetAsyncKeyState('U') && AllowReport)
|
||||||
|
{
|
||||||
|
//ClearScreen();
|
||||||
|
//wm_report sr;
|
||||||
|
//wm_request_status *sr;
|
||||||
|
//WmRequestStatus(g_ReportingChannel, sr);
|
||||||
|
|
||||||
|
//memcpy(g_RegExt, g_RegExtBlnk, sizeof(g_RegExt));
|
||||||
|
//g_RegExt[0xfc] = 0xa4;
|
||||||
|
//g_RegExt[0xfd] = 0x20;
|
||||||
|
|
||||||
|
/**/
|
||||||
|
for(int i=0; i <= 16; i++)
|
||||||
|
{
|
||||||
|
g_RegExt[0x40 + i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* */
|
||||||
|
WmRequestStatus_(g_ReportingChannel, 0);
|
||||||
|
|
||||||
|
wprintf("Sent status report\n");
|
||||||
|
AllowReport = false;
|
||||||
|
AllowCount = 0;
|
||||||
|
|
||||||
|
//void ReadExt();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**/
|
||||||
|
if(AllowCount > 10)
|
||||||
{
|
{
|
||||||
AllowReport = true;
|
AllowReport = true;
|
||||||
AllowCount = 0;
|
AllowCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
AllowCount++;
|
AllowCount++;
|
||||||
*/
|
// ----------
|
||||||
|
|
||||||
#else
|
#else
|
||||||
// TODO: fill in
|
// TODO: fill in
|
||||||
|
@ -342,7 +404,7 @@ void FillReportAcc(wm_accel& _acc)
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
bool toggleWideScreen = false, toggleCursor = true;
|
//bool toggleWideScreen = false, toggleCursor = true;
|
||||||
|
|
||||||
|
|
||||||
void FillReportIR(wm_ir_extended& _ir0, wm_ir_extended& _ir1)
|
void FillReportIR(wm_ir_extended& _ir0, wm_ir_extended& _ir1)
|
||||||
|
@ -427,37 +489,148 @@ void FillReportIR(wm_ir_extended& _ir0, wm_ir_extended& _ir1)
|
||||||
|
|
||||||
void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1)
|
void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1)
|
||||||
{
|
{
|
||||||
|
/* See description above */
|
||||||
|
int Top, Left, Right, Bottom, SensorBarRadius;
|
||||||
|
if(g_Config.bWideScreen)
|
||||||
|
{
|
||||||
|
Top = wTOP; Left = wLEFT; Right = wRIGHT;
|
||||||
|
Bottom = wBOTTOM; SensorBarRadius = wSENSOR_BAR_RADIUS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Top = TOP; Left = LEFT; Right = RIGHT;
|
||||||
|
Bottom = BOTTOM; SensorBarRadius = SENSOR_BAR_RADIUS;
|
||||||
|
}
|
||||||
|
|
||||||
memset(&_ir0, 0xFF, sizeof(wm_ir_basic));
|
memset(&_ir0, 0xFF, sizeof(wm_ir_basic));
|
||||||
memset(&_ir1, 0xFF, sizeof(wm_ir_basic));
|
memset(&_ir1, 0xFF, sizeof(wm_ir_basic));
|
||||||
|
|
||||||
float MouseX, MouseY;
|
float MouseX, MouseY;
|
||||||
GetMousePos(MouseX, MouseY);
|
GetMousePos(MouseX, MouseY);
|
||||||
|
|
||||||
int y1 = TOP + (MouseY * (BOTTOM - TOP));
|
int y1 = Top + (MouseY * (Bottom - Top));
|
||||||
int y2 = TOP + (MouseY * (BOTTOM - TOP));
|
int y2 = Top + (MouseY * (Bottom - Top));
|
||||||
|
|
||||||
int x1 = LEFT + (MouseX * (RIGHT - LEFT)) - SENSOR_BAR_RADIUS;
|
int x1 = Left + (MouseX * (Right - Left)) - SensorBarRadius;
|
||||||
int x2 = LEFT + (MouseX * (RIGHT - LEFT)) + SENSOR_BAR_RADIUS;
|
int x2 = Left + (MouseX * (Right - Left)) + SensorBarRadius;
|
||||||
|
|
||||||
x1 = 1023 - x1;
|
x1 = 1023 - x1;
|
||||||
_ir0.x1 = x1 & 0xFF;
|
_ir0.x1 = x1 & 0xFF;
|
||||||
_ir0.y1 = y1 & 0xFF;
|
_ir0.y1 = y1 & 0xFF;
|
||||||
_ir0.x1High = (x1 >> 8) & 0x3;
|
_ir0.x1Hi = (x1 >> 8) & 0x3;
|
||||||
_ir0.y1High = (y1 >> 8) & 0x3;
|
_ir0.y1Hi = (y1 >> 8) & 0x3;
|
||||||
|
|
||||||
x2 = 1023 - x2;
|
x2 = 1023 - x2;
|
||||||
_ir1.x2 = x2 & 0xFF;
|
_ir1.x2 = x2 & 0xFF;
|
||||||
_ir1.y2 = y2 & 0xFF;
|
_ir1.y2 = y2 & 0xFF;
|
||||||
_ir1.x2High = (x2 >> 8) & 0x3;
|
_ir1.x2Hi = (x2 >> 8) & 0x3;
|
||||||
_ir1.y2High = (y2 >> 8) & 0x3;
|
_ir1.y2Hi = (y2 >> 8) & 0x3;
|
||||||
|
|
||||||
|
// ----------------------------
|
||||||
|
// Debugging for calibration
|
||||||
|
// ----------
|
||||||
|
/*
|
||||||
|
if(GetAsyncKeyState(VK_NUMPAD1))
|
||||||
|
Right +=1;
|
||||||
|
else if(GetAsyncKeyState(VK_NUMPAD2))
|
||||||
|
Right -=1;
|
||||||
|
if(GetAsyncKeyState(VK_NUMPAD4))
|
||||||
|
Left +=1;
|
||||||
|
else if(GetAsyncKeyState(VK_NUMPAD5))
|
||||||
|
Left -=1;
|
||||||
|
if(GetAsyncKeyState(VK_NUMPAD7))
|
||||||
|
Top += 1;
|
||||||
|
else if(GetAsyncKeyState(VK_NUMPAD8))
|
||||||
|
Top -= 1;
|
||||||
|
if(GetAsyncKeyState(VK_NUMPAD6))
|
||||||
|
Bottom += 1;
|
||||||
|
else if(GetAsyncKeyState(VK_NUMPAD3))
|
||||||
|
Bottom -= 1;
|
||||||
|
if(GetAsyncKeyState(VK_INSERT))
|
||||||
|
SensorBarRadius += 1;
|
||||||
|
else if(GetAsyncKeyState(VK_DELETE))
|
||||||
|
SensorBarRadius -= 1;
|
||||||
|
|
||||||
//ClearScreen();
|
//ClearScreen();
|
||||||
/*
|
//if(consoleDisplay == 1)
|
||||||
wprintf("x0:%03i | y0:%03i || x1:%03i | 0.y: %03i || 1.x: %03i | 1.y %03i\n", _ir0.x1, _ir0.y1,
|
wprintf("x1:%03i x2:%03i y1:%03i y2:%03i irx1:%03i y1:%03i x2:%03i y2:%03i | T:%i L:%i R:%i B:%i S:%i\n",
|
||||||
_ir1.x2, _ir1.y2
|
x1, x2, y1, y2, _ir0.x1, _ir0.y1, _ir1.x2, _ir1.y2, Top, Left, Right, Bottom, SensorBarRadius
|
||||||
);
|
);*/
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ===================================================
|
||||||
|
/* Generate the 6 byte extension report, encrypted. */
|
||||||
|
// ----------------
|
||||||
|
void FillReportExtension(wm_extension& _ext)
|
||||||
|
{
|
||||||
|
// JX JY AX AY AZ BT
|
||||||
|
|
||||||
|
// Make temporary values
|
||||||
|
|
||||||
|
_ext.ax = 0x80;
|
||||||
|
_ext.ay = 0x80;
|
||||||
|
_ext.az = 0xb3;
|
||||||
|
|
||||||
|
|
||||||
|
_ext.jx = 0x80; // these are the default values unless we don't use them
|
||||||
|
_ext.jy = 0x80;
|
||||||
|
_ext.bt = 0x03; // 0x03 means no button pressed, the button is zero active
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(GetAsyncKeyState(VK_NUMPAD4))
|
||||||
|
_ext.jx = 0x20;
|
||||||
|
|
||||||
|
if(GetAsyncKeyState(VK_NUMPAD8))
|
||||||
|
_ext.jy = 0x20;
|
||||||
|
|
||||||
|
if(GetAsyncKeyState(VK_NUMPAD6))
|
||||||
|
_ext.jx = 0xe0;
|
||||||
|
|
||||||
|
if(GetAsyncKeyState(VK_NUMPAD5))
|
||||||
|
_ext.jy = 0xe0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(GetAsyncKeyState('C'))
|
||||||
|
_ext.bt = 0x01;
|
||||||
|
|
||||||
|
if(GetAsyncKeyState('Z'))
|
||||||
|
_ext.bt = 0x02;
|
||||||
|
|
||||||
|
if(GetAsyncKeyState('C') && GetAsyncKeyState('Z'))
|
||||||
|
_ext.bt = 0x00;
|
||||||
|
|
||||||
|
|
||||||
|
// Clear g_RegExtTmp by copying g_RegExtBlnk to g_RegExtTmp
|
||||||
|
memcpy(g_RegExtTmp, g_RegExtBlnk, sizeof(g_RegExt));
|
||||||
|
|
||||||
|
// Write the nunchuck inputs to it
|
||||||
|
g_RegExtTmp[0x08] = _ext.jx;
|
||||||
|
g_RegExtTmp[0x09] = _ext.jy;
|
||||||
|
g_RegExtTmp[0x0a] = _ext.ax;
|
||||||
|
g_RegExtTmp[0x0b] = _ext.ay;
|
||||||
|
g_RegExtTmp[0x0c] = _ext.az;
|
||||||
|
g_RegExtTmp[0x0d] = _ext.bt;
|
||||||
|
|
||||||
|
// Encrypt it
|
||||||
|
wiimote_encrypt(&g_ExtKey, &g_RegExtTmp[0x08], 0x08, 0x06);
|
||||||
|
|
||||||
|
// Write it back
|
||||||
|
_ext.jx = g_RegExtTmp[0x08];
|
||||||
|
_ext.jy = g_RegExtTmp[0x09];
|
||||||
|
_ext.ax = g_RegExtTmp[0x0a];
|
||||||
|
_ext.ay = g_RegExtTmp[0x0b];
|
||||||
|
_ext.az = g_RegExtTmp[0x0c];
|
||||||
|
_ext.bt = g_RegExtTmp[0x0d];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // end of namespace
|
} // end of namespace
|
||||||
|
|
|
@ -129,8 +129,8 @@ extern "C" void Wiimote_Initialize(SWiimoteInitialize _WiimoteInitialize)
|
||||||
g_WiimoteInitialize = _WiimoteInitialize;
|
g_WiimoteInitialize = _WiimoteInitialize;
|
||||||
|
|
||||||
/* We will run WiiMoteReal::Initialize() even if we are not using a real wiimote,
|
/* We will run WiiMoteReal::Initialize() even if we are not using a real wiimote,
|
||||||
we will ini wiiuse.dll, but we will return before creating a new thread for
|
we will initiate wiiuse.dll, but we will return before creating a new thread
|
||||||
it, in that case */
|
for it in that case */
|
||||||
g_UseRealWiiMote = WiiMoteReal::Initialize() > 0;
|
g_UseRealWiiMote = WiiMoteReal::Initialize() > 0;
|
||||||
|
|
||||||
WiiMoteEmu::Initialize();
|
WiiMoteEmu::Initialize();
|
||||||
|
|
|
@ -159,14 +159,26 @@ struct wm_ir_basic
|
||||||
{
|
{
|
||||||
u8 x1;
|
u8 x1;
|
||||||
u8 y1;
|
u8 y1;
|
||||||
u8 x2High : 2;
|
u8 x2Hi : 2;
|
||||||
u8 y2High : 2;
|
u8 y2Hi : 2;
|
||||||
u8 x1High : 2;
|
u8 x1Hi : 2;
|
||||||
u8 y1High : 2;
|
u8 y1Hi : 2;
|
||||||
u8 x2;
|
u8 x2;
|
||||||
u8 y2;
|
u8 y2;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct wm_extension
|
||||||
|
{
|
||||||
|
u8 jx; // joystick x, y
|
||||||
|
u8 jy;
|
||||||
|
u8 ax; // accelerometer
|
||||||
|
u8 ay;
|
||||||
|
u8 az;
|
||||||
|
u8 bt; // buttons
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct wm_ir_extended
|
struct wm_ir_extended
|
||||||
{
|
{
|
||||||
u8 x;
|
u8 x;
|
||||||
|
@ -198,6 +210,16 @@ struct wm_report_core_accel_ir12 {
|
||||||
|
|
||||||
#define WM_REPORT_CORE_EXT19 0x34
|
#define WM_REPORT_CORE_EXT19 0x34
|
||||||
#define WM_REPORT_CORE_ACCEL_EXT16 0x35
|
#define WM_REPORT_CORE_ACCEL_EXT16 0x35
|
||||||
|
struct wm_report_core_accel_ext16
|
||||||
|
{
|
||||||
|
wm_core c;
|
||||||
|
wm_accel a;
|
||||||
|
wm_extension ext;
|
||||||
|
//wm_ir_basic ir[2];
|
||||||
|
u8 pad[10];
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
#define WM_REPORT_CORE_IR10_EXT9 0x36
|
#define WM_REPORT_CORE_IR10_EXT9 0x36
|
||||||
|
|
||||||
#define WM_REPORT_CORE_ACCEL_IR10_EXT6 0x37
|
#define WM_REPORT_CORE_ACCEL_IR10_EXT6 0x37
|
||||||
|
@ -206,10 +228,17 @@ struct wm_report_core_accel_ir10_ext6
|
||||||
wm_core c;
|
wm_core c;
|
||||||
wm_accel a;
|
wm_accel a;
|
||||||
wm_ir_basic ir[2];
|
wm_ir_basic ir[2];
|
||||||
u8 ext[6];
|
//u8 ext[6];
|
||||||
|
wm_extension ext;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define WM_REPORT_EXT21 0x3d // never used?
|
||||||
|
struct wm_report_ext21
|
||||||
|
{
|
||||||
|
u8 ext[21];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define WM_REPORT_EXT21 0x3d
|
|
||||||
#define WM_REPORT_INTERLEAVE1 0x3e
|
#define WM_REPORT_INTERLEAVE1 0x3e
|
||||||
#define WM_REPORT_INTERLEAVE2 0x3f
|
#define WM_REPORT_INTERLEAVE2 0x3f
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue