Wiimote plugin cleanup & linux build fix

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3677 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
LPFaint99 2009-07-05 05:59:03 +00:00
parent c921fe1c13
commit 52438f1dc7
16 changed files with 332 additions and 683 deletions

View File

@ -29,10 +29,10 @@
#include "EmuDefinitions.h" // for joyinfo
// Change Joystick
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
/* Function: When changing the joystick we save and load the settings and update the PadMapping
and PadState array. PadState[].joy is the gamepad handle that is used to access the pad throughout
the plugin. Joyinfo[].joy is only used the first time the pads are checked. */
/* Function: When changing the joystick we save and load the settings and
update the PadMapping and PadState array. PadState[].joy is the gamepad
handle that is used to access the pad throughout the plugin. Joyinfo[].joy
is only used the first time the pads are checked. */
void WiimotePadConfigDialog::DoChangeJoystick()
{
// Close the current pad, unless it's used by another slot
@ -61,10 +61,10 @@ void WiimotePadConfigDialog::PadOpen(int Open) // Open for slot 1, 2, 3 or 4
INFO_LOG(CONSOLE, "Update the Slot %i handle to Id %i\n", Page, WiiMoteEmu::PadMapping[Open].ID);
WiiMoteEmu::PadState[Open].joy = SDL_JoystickOpen(WiiMoteEmu::PadMapping[Open].ID);
}
void WiimotePadConfigDialog::PadClose(int Close) // Close for slot 1, 2, 3 or 4
void WiimotePadConfigDialog::PadClose(int _Close) // Close for slot 1, 2, 3 or 4
{
if (SDL_JoystickOpened(WiiMoteEmu::PadMapping[Close].ID)) SDL_JoystickClose(WiiMoteEmu::PadState[Close].joy);
WiiMoteEmu::PadState[Close].joy = NULL;
if (SDL_JoystickOpened(WiiMoteEmu::PadMapping[_Close].ID)) SDL_JoystickClose(WiiMoteEmu::PadState[_Close].joy);
WiiMoteEmu::PadState[_Close].joy = NULL;
}
void WiimotePadConfigDialog::DoChangeDeadZone(bool Left)
@ -88,12 +88,9 @@ void WiimotePadConfigDialog::DoChangeDeadZone(bool Left)
m_bmpDeadZoneRightIn[Page]->Refresh();
}
}
//////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
// Change settings
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
// Set the button text for all four Wiimotes
void WiimotePadConfigDialog::SetButtonTextAll(int id, char text[128])
@ -120,7 +117,6 @@ void WiimotePadConfigDialog::SaveButtonMappingAll(int Slot)
}
// Set dialog items from saved values
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
void WiimotePadConfigDialog::UpdateGUIButtonMapping(int controller)
{
// Temporary storage
@ -206,7 +202,7 @@ void WiimotePadConfigDialog::UpdateGUIButtonMapping(int controller)
/* Populate the PadMapping array with the dialog items settings (for example
selected joystick, enabled or disabled status and so on) */
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
void WiimotePadConfigDialog::SaveButtonMapping(int controller, bool DontChangeId, int FromSlot)
{
// Temporary storage
@ -314,18 +310,18 @@ void WiimotePadConfigDialog::SaveKeyboardMapping(int Controller, int Id, int Key
}
// Replace the harder to understand -1 with "" for the sake of user friendliness
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
void WiimotePadConfigDialog::ToBlank(bool ToBlank)
void WiimotePadConfigDialog::ToBlank(bool _ToBlank)
{
if (!ControlsCreated) return;
for (int j = 0; j < 1; j++)
{
if(ToBlank)
if(_ToBlank)
{
for(int i = IDB_ANALOG_LEFT_X; i <= IDB_TRIGGER_R; i++)
#ifndef _WIN32
if(GetButtonText(i, j).ToAscii() == "-1") SetButtonText(i, "", j);
if(GetButtonText(i, j).ToAscii() == "-1")
SetButtonText(i, (char *)"", j);
#else
if(GetButtonText(i, j) == "-1") SetButtonText(i, "", j);
#endif
@ -333,11 +329,11 @@ void WiimotePadConfigDialog::ToBlank(bool ToBlank)
else
{
for(int i = IDB_ANALOG_LEFT_X; i <= IDB_TRIGGER_R; i++)
if(GetButtonText(i, j).IsEmpty()) SetButtonText(i, "-1", j);
if(GetButtonText(i, j).IsEmpty())
SetButtonText(i, (char *)"-1", j);
}
}
}
//////////////////////////////////////
@ -441,25 +437,24 @@ wxString WiimotePadConfigDialog::GetButtonText(int id, int _Page)
}
//////////////////////////////////////////////////////////////////////////////////////////
// Configure button mapping
// ¯¯¯¯¯¯¯¯¯¯
// Wait for button press
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
/* Loop or timer: There are basically two ways to do this. With a while() or for() loop, or with a
timer. The downside with the while() or for() loop is that there is no way to stop it if the user
should select to configure another button while we are still in an old loop. What will happen then
is that we start another parallel loop (at least in Windows) that blocks the old loop. And our only
option to wait for the old loop to finish is with a new loop, and that will block the old loop for as
long as it's going on. Therefore a timer is easier to control. */
/* Loop or timer: There are basically two ways to do this. With a while() or
for() loop, or with a timer. The downside with the while() or for() loop is
that there is no way to stop it if the user should select to configure
another button while we are still in an old loop. What will happen then is
that we start another parallel loop (at least in Windows) that blocks the
old loop. And our only option to wait for the old loop to finish is with a
new loop, and that will block the old loop for as long as it's going
on. Therefore a timer is easier to control. */
void WiimotePadConfigDialog::GetButtons(wxCommandEvent& event)
{
DoGetButtons(event.GetId());
}
void WiimotePadConfigDialog::DoGetButtons(int GetId)
void WiimotePadConfigDialog::DoGetButtons(int _GetId)
{
// =============================================
// Collect the starting values
@ -473,11 +468,11 @@ void WiimotePadConfigDialog::DoGetButtons(int GetId)
int TriggerType = WiiMoteEmu::PadMapping[Controller].triggertype;
// Collect the accepted buttons for this slot
bool LeftRight = (GetId == IDB_TRIGGER_L || GetId == IDB_TRIGGER_R);
bool LeftRight = (_GetId == IDB_TRIGGER_L || _GetId == IDB_TRIGGER_R);
bool Axis = (GetId >= IDB_ANALOG_LEFT_X && GetId <= IDB_TRIGGER_R)
bool Axis = (_GetId >= IDB_ANALOG_LEFT_X && _GetId <= IDB_TRIGGER_R)
// Don't allow SDL axis input for the shoulder buttons if XInput is selected
&& !(TriggerType == InputCommon::CTL_TRIGGER_XINPUT && (GetId == IDB_TRIGGER_L || GetId == IDB_TRIGGER_R) );
&& !(TriggerType == InputCommon::CTL_TRIGGER_XINPUT && (_GetId == IDB_TRIGGER_L || _GetId == IDB_TRIGGER_R) );
bool XInput = (TriggerType == InputCommon::CTL_TRIGGER_XINPUT);
@ -501,10 +496,10 @@ void WiimotePadConfigDialog::DoGetButtons(int GetId)
// =======================
//INFO_LOG(CONSOLE, "Before (%i) Id:%i %i IsRunning:%i\n",
// GetButtonWaitingTimer, GetButtonWaitingID, GetId, m_ButtonMappingTimer->IsRunning());
// GetButtonWaitingTimer, GetButtonWaitingID, _GetId, m_ButtonMappingTimer->IsRunning());
// If the Id has changed or the timer is not running we should start one
if( GetButtonWaitingID != GetId || !m_ButtonMappingTimer->IsRunning() )
if( GetButtonWaitingID != _GetId || !m_ButtonMappingTimer->IsRunning() )
{
if(m_ButtonMappingTimer->IsRunning())
{
@ -512,26 +507,26 @@ void WiimotePadConfigDialog::DoGetButtons(int GetId)
GetButtonWaitingTimer = 0;
// Update the old textbox
SetButtonText(GetButtonWaitingID, "");
SetButtonText(GetButtonWaitingID, (char *)"");
}
// Save the button Id
GetButtonWaitingID = GetId;
GetButtonWaitingID = _GetId;
// Reset the key in case we happen to have an old one
g_Pressed = 0;
// Update the text box
sprintf(format, "[%d]", Seconds);
SetButtonText(GetId, format);
SetButtonText(_GetId, format);
// Start the timer
#if wxUSE_TIMER
m_ButtonMappingTimer->Start( floor((double)(1000 / TimesPerSecond)) );
#endif
INFO_LOG(CONSOLE, "Timer Started for Pad:%i GetId:%i\n"
INFO_LOG(CONSOLE, "Timer Started for Pad:%i _GetId:%i\n"
"Allowed input is Axis:%i LeftRight:%i XInput:%i Button:%i Hat:%i\n",
WiiMoteEmu::PadMapping[Controller].ID, GetId,
WiiMoteEmu::PadMapping[Controller].ID, _GetId,
Axis, LeftRight, XInput, Button, Hat);
}
@ -565,7 +560,7 @@ void WiimotePadConfigDialog::DoGetButtons(int GetId)
// Update text
sprintf(format, "[%d]", TmpTime);
SetButtonText(GetId, format);
SetButtonText(_GetId, format);
/* Debug
INFO_LOG(CONSOLE, "Keyboard: %i\n", g_Pressed);*/
@ -576,7 +571,7 @@ void WiimotePadConfigDialog::DoGetButtons(int GetId)
{
Stop = true;
// Leave a blank mapping
SetButtonTextAll(GetId, "-1");
SetButtonTextAll(_GetId, (char *)"-1");
}
// If we got a button
@ -585,7 +580,7 @@ void WiimotePadConfigDialog::DoGetButtons(int GetId)
Stop = true;
// Write the number of the pressed button to the text box
sprintf(format, "%d", pressed);
SetButtonTextAll(GetId, format);
SetButtonTextAll(_GetId, format);
}
// Stop the timer
@ -594,21 +589,23 @@ void WiimotePadConfigDialog::DoGetButtons(int GetId)
m_ButtonMappingTimer->Stop();
GetButtonWaitingTimer = 0;
/* Update the button mapping for all slots that use this device. (It doesn't make sense to have several slots
controlled by the same device, but several DirectInput instances of different but identical devices may possible
have the same id, I don't know. So we have to do this. The user may also have selected the same device for
several disabled slots. */
/* Update the button mapping for all slots that use this device. (It
doesn't make sense to have several slots controlled by the same
device, but several DirectInput instances of different but identical
devices may possible have the same id, I don't know. So we have to
do this. The user may also have selected the same device for several
disabled slots. */
SaveButtonMappingAll(Controller);
INFO_LOG(CONSOLE, "Timer Stopped for Pad:%i GetId:%i\n",
WiiMoteEmu::PadMapping[Controller].ID, GetId);
INFO_LOG(CONSOLE, "Timer Stopped for Pad:%i _GetId:%i\n",
WiiMoteEmu::PadMapping[Controller].ID, _GetId);
}
// If we got a bad button
if(g_Pressed == -1)
{
// Update text
SetButtonTextAll(GetId, "-1");
SetButtonTextAll(_GetId, (char *)"-1");
// Notify the user
wxMessageBox(wxString::Format(wxT(
@ -625,14 +622,10 @@ void WiimotePadConfigDialog::DoGetButtons(int GetId)
m_JoyButtonHalfpress[0]->GetValue().c_str(), m_JoyButtonHalfpress[1]->GetValue().c_str(), m_JoyButtonHalfpress[2]->GetValue().c_str(), m_JoyButtonHalfpress[3]->GetValue().c_str()
);*/
}
/////////////////////////////////////////////////////////// Configure button mapping
//////////////////////////////////////////////////////////////////////////////////////////
// Show current input status
// ¯¯¯¯¯¯¯¯¯¯
// Convert the 0x8000 range values to BoxW and BoxH for the plot
void WiimotePadConfigDialog::Convert2Box(int &x)
{
@ -644,13 +637,13 @@ void WiimotePadConfigDialog::Convert2Box(int &x)
}
// Update the input status boxes
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
void WiimotePadConfigDialog::PadGetStatus()
{
//INFO_LOG(CONSOLE, "SDL_WasInit: %i\n", SDL_WasInit(0));
/* Return if it's not detected. The ID should never be less than zero here, it can only be that
because of a manual ini file change, but we make that check anway. */
/* Return if it's not detected. The ID should never be less than zero here,
it can only be that because of a manual ini file change, but we make
that check anway. */
if(WiiMoteEmu::PadMapping[Page].ID < 0 || WiiMoteEmu::PadMapping[Page].ID >= SDL_NumJoysticks())
{
m_TStatusLeftIn[Page]->SetLabel(wxT("Not connected"));
@ -685,7 +678,6 @@ void WiimotePadConfigDialog::PadGetStatus()
//////////////////////////////////////
// Analog stick
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
// Set Deadzones perhaps out of function
//int deadzone = (int)(((float)(128.00/100.00)) * (float)(PadMapping[_numPAD].deadzone+1));
//int deadzone2 = (int)(((float)(-128.00/100.00)) * (float)(PadMapping[_numPAD].deadzone+1));
@ -722,9 +714,7 @@ void WiimotePadConfigDialog::PadGetStatus()
right_y_after = 0;
}
// -------------------------------------------
// Show the adjusted angles in the status box
// --------------
// Change 0x8000 to 180
/*
float x8000 = 0x8000;
@ -740,7 +730,6 @@ void WiimotePadConfigDialog::PadGetStatus()
main_x_after = main_x_after * (x8000 / 180);
main_y_after = main_y_after * (x8000 / 180);
*/
// ---------------------
// Convert the values to fractions
float f_x = main_x / 32767.0;
@ -778,13 +767,9 @@ void WiimotePadConfigDialog::PadGetStatus()
m_bmpDotLeftOut[Page]->SetPosition(wxPoint(main_x_after, main_y_after));
m_bmpDotRightIn[Page]->SetPosition(wxPoint(right_x, right_y));
m_bmpDotRightOut[Page]->SetPosition(wxPoint(right_x_after, right_y_after));
///////////////////// Analog stick
//////////////////////////////////////
// Triggers
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
int TriggerValue = 0;
// Get the selected keys
long Left, Right;
@ -806,11 +791,9 @@ void WiimotePadConfigDialog::PadGetStatus()
wxT("%03i"), TriggerLeft));
m_TriggerStatusRx[Page]->SetLabel(wxString::Format(
wxT("%03i"), TriggerRight));
///////////////////// Triggers
}
// Populate the advanced tab
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
void WiimotePadConfigDialog::UpdatePad(wxTimerEvent& WXUNUSED(event))
{
// Show the current status

View File

@ -28,7 +28,6 @@
#include "EmuMain.h" // for LoadRecordedMovements()
#include "EmuSubroutines.h" // for WmRequestStatus
void WiimoteRecordingConfigDialog::LoadFile()
{
INFO_LOG(CONSOLE, "LoadFile()\n");
@ -289,9 +288,7 @@ void WiimoteRecordingConfigDialog::CreateGUIControlsRecording()
m_RecordIRBytesText[i]->Enable(false);
m_RecordSpeed[i]->Enable(false);
// ------------------------------------
// Row 2 Sizers
// -----------
sRealRecord[i]->Add(m_RecordButton[i], 0, wxEXPAND | (wxLEFT), 5);
sRealRecord[i]->Add(m_RecordHotKeySwitch[i], 0, wxEXPAND | (wxLEFT), 5);
sRealRecord[i]->Add(m_RecordHotKeyWiimote[i], 0, wxEXPAND | (wxLEFT), 2);
@ -364,8 +361,10 @@ void WiimoteRecordingConfigDialog::ConvertToString()
TmpTime += StringFromFormat("%05i", Time);
if (i < ((int)m_vRecording.size() - 1)) TmpTime += ",";
// Break just short of the IniFile.cpp byte limit so that we don't crash file.Load() the next time.
// This limit should never be hit because of the recording limit below. I keep it here just in case.
/* Break just short of the IniFile.cpp byte limit so that we don't
crash file.Load() the next time. This limit should never be hit
because of the recording limit below. I keep it here just in
case. */
if(TmpStr.length() > (1024*10 - 10) || TmpIR.length() > (1024*10 - 10) || TmpTime.length() > (1024*10 - 10))
{
break;
@ -434,8 +433,8 @@ void WiimoteRecordingConfigDialog::RecordMovement(wxCommandEvent& event)
else
{
m_RecordButton[m_iRecordTo]->SetLabel(wxT("Press +"));
// This is for usability purposes, it may not be obvious at all that this must be unchecked
// for the recording to work
// This is for usability purposes, it may not be obvious at all that
// this must be unchecked for the recording to work
for(int i = 0; i < MAX_WIIMOTES; i++)
m_BasicConfigFrame->m_UseRealWiimote[i]->SetValue(false);
g_Config.bUseRealWiimote = false;
@ -513,4 +512,5 @@ void WiimoteRecordingConfigDialog::DoRecordMovement(int _x, int _y, int _z, cons
ConvertToString();
UpdateRecordingGUI();
}
}
}

View File

@ -17,21 +17,19 @@
// ===================================================
/* Data reports guide. The different structures location in the Input reports. The ? in
the IR coordinates is the High coordinates that are four in one byte.
/* Data reports guide. The different structures location in the Input
reports. The ? in the IR coordinates is the High coordinates that are four
in one byte.
0x37: For the data reportingmode 0x37 there are five unused IR bytes in the end (represented)
by "..." below, it seems like they can be set to either 0xff or 0x00 without affecting the
IR emulation. */
// ----------------
0x37: For the data reportingmode 0x37 there are five unused IR bytes in the
end (represented) by "..." below, it seems like they can be set to either
0xff or 0x00 without affecting the IR emulation. */
/* 0x33
[c.left etc] [c.a etc] acc.x y z ir0.x y ? ir1.x y ? ir2.x y ? ir3.x y ?
/* 0x33 [c.left etc] [c.a etc] acc.x y z ir0.x y ? ir1.x y ? ir2.x y ? ir3.x y
?
0x37
[c.left etc] [c.a etc] acc.x y z ir0.x1 y1 ? x2 y2 ir1.x1 y1 ? x2 y2 ... ext.jx jy ax ay az bt
0x37 [c.left etc] [c.a etc] acc.x y z ir0.x1 y1 ? x2 y2 ir1.x1 y1 ? x2 y2
... ext.jx jy ax ay az bt
The Data Report's path from here is
@ -41,9 +39,8 @@
WII_IPC_HLE_Device_usb.cpp:
CWII_IPC_HLE_Device_usb_oh1_57e_305::SendACLFrame()
at that point the message is queued and will be sent by the next
CWII_IPC_HLE_Device_usb_oh1_57e_305::Update() */
// ================
CWII_IPC_HLE_Device_usb_oh1_57e_305::Update()
*/
#include "pluginspecs_wiimote.h"
@ -61,23 +58,19 @@
#include "Encryption.h" // for extension encryption
#include "Config.h" // for g_Config
extern SWiimoteInitialize g_WiimoteInitialize;
extern SWiimoteInitialize g_WiimoteInitialize;
namespace WiiMoteEmu
{
//******************************************************************************
// Subroutines
//******************************************************************************
// ===================================================
/* Update the data reporting mode */
// ----------------
// Update the data reporting mode
void WmDataReporting(u16 _channelID, wm_data_reporting* dr)
{
INFO_LOG(WII_IPC_WIIMOTE, "===========================================================");
DEBUG_LOG(WII_IPC_WIIMOTE, " Set Data reporting mode");
DEBUG_LOG(WII_IPC_WIIMOTE, " Rumble: %x", dr->rumble);
DEBUG_LOG(WII_IPC_WIIMOTE, " Continuous: %x", dr->continuous);
@ -105,14 +98,11 @@ void WmDataReporting(u16 _channelID, wm_data_reporting* dr)
// WmSendAck(_channelID, WM_DATA_REPORTING);
INFO_LOG(WII_IPC_WIIMOTE, "===========================================================");
}
// ===================================================
/* Case 0x30: Core Buttons */
// ----------------
void SendReportCore(u16 _channelID)
{
u8 DataFrame[1024];
@ -134,9 +124,7 @@ void SendReportCore(u16 _channelID)
}
// ===================================================
/* 0x31: Core Buttons and Accelerometer */
// ----------------
void SendReportCoreAccel(u16 _channelID)
{
u8 DataFrame[1024];
@ -162,9 +150,7 @@ void SendReportCoreAccel(u16 _channelID)
}
// ===================================================
/* 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);
@ -193,9 +179,7 @@ void SendReportCoreAccelIr12(u16 _channelID) {
}
// ===================================================
/* Case 0x35: Core Buttons and Accelerometer with 16 Extension Bytes */
// ----------------
void SendReportCoreAccelExt16(u16 _channelID)
{
u8 DataFrame[1024];
@ -225,7 +209,7 @@ void SendReportCoreAccelExt16(u16 _channelID)
#if defined(HAVE_WX) && HAVE_WX
FillReportClassicExtension(_ext);
#endif
// Copy _ext to pReport->ext
//TODO // Copy _ext to pReport->ext
memcpy(&pReport->ext, &_ext, sizeof(_ext));
}
@ -240,9 +224,7 @@ void SendReportCoreAccelExt16(u16 _channelID)
}
// ===================================================
/* Case 0x37: Core Buttons and Accelerometer with 10 IR bytes and 6 Extension Bytes */
// ----------------
void SendReportCoreAccelIr10Ext(u16 _channelID)
{
u8 DataFrame[1024];
@ -261,7 +243,7 @@ void SendReportCoreAccelIr10Ext(u16 _channelID)
FillReportAcc(pReport->a);
FillReportIRBasic(pReport->ir[0], pReport->ir[1]);
#endif
//TODO
if(g_Config.iExtensionConnected == EXT_NUNCHUCK)
{
#if defined(HAVE_WX) && HAVE_WX

View File

@ -45,9 +45,7 @@ namespace WiiMoteEmu
//******************************************************************************
//////////////////////////////////////////////////////////////////////////////////////////
// Test the calculations
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
void TiltTest(u8 x, u8 y, u8 z)
{
int Roll, Pitch, RollAdj, PitchAdj;
@ -63,13 +61,11 @@ void TiltTest(u8 x, u8 y, u8 z)
(_Pitch >= 0) ? StringFromFormat(" %03i", (int)_Pitch).c_str() : StringFromFormat("%04i", (int)_Pitch).c_str());
INFO_LOG(CONSOLE, "%s\n", To.c_str());
}
////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
/* Angles adjustment for the upside down state when both roll and pitch is used. When the absolute values
of the angles go over 90° the Wiimote is upside down and these adjustments are needed. */
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
/* Angles adjustment for the upside down state when both roll and pitch is
used. When the absolute values of the angles go over 90° the Wiimote is
upside down and these adjustments are needed. */
void AdjustAngles(float &Roll, float &Pitch)
{
float OldPitch = Pitch;
@ -90,12 +86,9 @@ void AdjustAngles(float &Roll, float &Pitch)
Roll = -180 - Roll; // -15 to -165
}
}
////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Angles to accelerometer values
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
void PitchDegreeToAccelerometer(float _Roll, float _Pitch, u8 &_x, u8 &_y, u8 &_z)
{
// We need radiands for the math functions
@ -119,21 +112,22 @@ void PitchDegreeToAccelerometer(float _Roll, float _Pitch, u8 &_x, u8 &_y, u8 &_
else
{
// ====================================================
/* This seems to always produce the exact same combination of x, y, z and Roll and Pitch that the
real Wiimote produce. There is an unlimited amount of x, y, z combinations for any combination of
Roll and Pitch. But if we select a Z from the smallest of the absolute value of cos(Roll) and
cos (Pitch) we get the right values. */
/* This seems to always produce the exact same combination of x, y, z
and Roll and Pitch that the real Wiimote produce. There is an
unlimited amount of x, y, z combinations for any combination of Roll
and Pitch. But if we select a Z from the smallest of the absolute
value of cos(Roll) and cos (Pitch) we get the right values. */
// ---------
if (abs(cos(_Roll)) < abs(cos(_Pitch))) z = cos(_Roll); else z = cos(_Pitch);
/* I got these from reversing the calculation in PitchAccelerometerToDegree() in a math program
I don't know if we can derive these from some kind of matrix or something */
/* I got these from reversing the calculation in
PitchAccelerometerToDegree() in a math program I don't know if we
can derive these from some kind of matrix or something */
float x_num = 2 * tanf(0.5f * _Roll) * z;
float x_den = pow2f(tanf(0.5f * _Roll)) - 1;
x = - (x_num / x_den);
float y_num = 2 * tanf(0.5f * _Pitch) * z;
float y_den = pow2f(tanf(0.5f * _Pitch)) - 1;
y = - (y_num / y_den);
// =========================
}
// Multiply with the neutral of z and its g
@ -156,9 +150,7 @@ void PitchDegreeToAccelerometer(float _Roll, float _Pitch, u8 &_x, u8 &_y, u8 &_
_z = iz;
}
//////////////////////////////////////////////////////////////////////////////////////////
// Accelerometer to roll and pitch angles
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
float AccelerometerToG(float Current, float Neutral, float G)
{
float _G = (Current - Neutral) / G;
@ -208,11 +200,7 @@ void PitchAccelerometerToDegree(u8 _x, u8 _y, u8 _z, int &_Roll, int &_Pitch, in
// IR data functions
//******************************************************************************
//////////////////////////////////////////////////////////////////////////////////////////
// Calculate dot positions from the basic 10 byte IR data
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
void IRData2DotsBasic(u8 *Data)
{
struct SDot* Dot = g_Wiimote_kbd.IR.Dot;
@ -252,9 +240,7 @@ void IRData2DotsBasic(u8 *Data)
}
//////////////////////////////////////////////////////////////////////////////////////////
// Calculate dot positions from the extented 12 byte IR data
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
void IRData2Dots(u8 *Data)
{
struct SDot* Dot = g_Wiimote_kbd.IR.Dot;
@ -284,12 +270,9 @@ void IRData2Dots(u8 *Data)
ReorderIRDots();
IRData2Distance();
}
////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Reorder the IR dots according to their x-axis value
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
void ReorderIRDots()
{
// Create a shortcut
@ -320,12 +303,9 @@ void ReorderIRDots()
Dot[i].Order = order;
}
}
////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Calculate dot positions from the extented 12 byte IR data
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
void IRData2Distance()
{
// Create a shortcut
@ -355,7 +335,6 @@ void IRData2Distance()
// Save the distance
g_Wiimote_kbd.IR.Distance = (int)sqrt((float)(xd*xd) + (float)(yd*yd));
}
////////////////////////////////
//******************************************************************************

View File

@ -38,9 +38,7 @@ extern SWiimoteInitialize g_WiimoteInitialize;
namespace WiiMoteEmu
{
// ===================================================
/* Bit shift conversions */
// -------------
u32 convert24bit(const u8* src) {
return (src[0] << 16) | (src[1] << 8) | src[2];
}
@ -48,12 +46,9 @@ u32 convert24bit(const u8* src) {
u16 convert16bit(const u8* src) {
return (src[0] << 8) | src[1];
}
// ==============
// ===================================================
/* Calibrate the mouse position to the emulation window. g_WiimoteInitialize.hWnd is the rendering window handle. */
// ----------------
void GetMousePos(float& x, float& y)
{
#ifdef _WIN32
@ -72,10 +67,8 @@ void GetMousePos(float& x, float& y)
float XOffset = 0, YOffset = 0;
float PictureWidth = WinWidth, PictureHeight = WinHeight;
// -----------------------------------------------------------------------
/* Calculate the actual picture size and location */
// Output: PictureWidth, PictureHeight, XOffset, YOffset
// ------------------
if (g_Config.bKeepAR43 || g_Config.bKeepAR169)
{
// The rendering window aspect ratio as a proportion of the 4:3 or 16:9 ratio
@ -84,55 +77,38 @@ void GetMousePos(float& x, float& y)
// Check if height or width is the limiting factor. If ratio > 1 the picture is to wide and have to limit the width.
if (Ratio > 1)
{
// ------------------------------------------------
// Calculate the new width and height for glViewport, this is not the actual size of either the picture or the screen
// ----------------
PictureWidth = WinWidth / Ratio;
// --------------------
// ------------------------------------------------
// Calculate the new X offset
// ----------------
// Move the left of the picture to the middle of the screen
XOffset = XOffset + WinWidth / 2.0f;
// Then remove half the picture height to move it to the horizontal center
XOffset = XOffset - PictureWidth / 2.0f;
// --------------------
}
// The window is to high, we have to limit the height
else
{
// ------------------------------------------------
// Calculate the new width and height for glViewport, this is not the actual size of either the picture or the screen
// ----------------
// Invert the ratio to make it > 1
Ratio = 1.0f / Ratio;
PictureHeight = WinHeight / Ratio;
// --------------------
// ------------------------------------------------
// Calculate the new Y offset
// ----------------
// Move the top of the picture to the middle of the screen
YOffset = YOffset + WinHeight / 2.0f;
// Then remove half the picture height to move it to the vertical center
YOffset = YOffset - PictureHeight / 2.0f;
// --------------------
}
// Logging
/*
// Console::ClearScreen();
INFO_LOG(CONSOLE, "Screen Width:%4.0f Height:%4.0f Ratio:%1.2f\n", WinWidth, WinHeight, Ratio);
INFO_LOG(CONSOLE, "Picture Width:%4.1f Height:%4.1f YOffset:%4.0f XOffset:%4.0f\n", PictureWidth, PictureHeight, YOffset, XOffset);
INFO_LOG(CONSOLE, "----------------------------------------------------------------\n");
INFO_LOG(WII_IPC_WIIMOTE, "Screen Width:%4.0f Height:%4.0f Ratio:%1.2f\n", WinWidth, WinHeight, Ratio);
INFO_LOG(WII_IPC_WIIMOTE, "Picture Width:%4.1f Height:%4.1f YOffset:%4.0f XOffset:%4.0f\n", PictureWidth, PictureHeight, YOffset, XOffset);
*/
}
// -------------------------------------
// -----------------------------------------------------------------------
/* Crop the picture from 4:3 to 5:4 or from 16:9 to 16:10. */
// Crop the picture from 4:3 to 5:4 or from 16:9 to 16:10.
// Output: PictureWidth, PictureHeight, XOffset, YOffset
// ------------------
if ((g_Config.bKeepAR43 || g_Config.bKeepAR169) && g_Config.bCrop)
{
float Ratio = g_Config.bKeepAR43 ? ((4.0f / 3.0f) / (5.0f / 4.0f)) : (((16.0f / 9.0f) / (16.0f / 10.0f)));
@ -149,41 +125,31 @@ void GetMousePos(float& x, float& y)
XOffset = float(XOffset - (IncreasedWidth / 2.0));
YOffset = float(YOffset - (IncreasedHeight / 2.0));
// Logging
/*
INFO_LOG(CONSOLE, "Crop Ratio:%1.2f IncrWidth:%3.0f IncrHeight:%3.0f\n", Ratio, IncreasedWidth, IncreasedHeight);
INFO_LOG(CONSOLE, "Picture Width:%4.1f Height:%4.1f YOffset:%4.0f XOffset:%4.0f\n", PictureWidth, PictureHeight, YOffset, XOffset);
INFO_LOG(CONSOLE, "----------------------------------------------------------------\n");
INFO_LOG(WII_IPC_WIIMOTE, "Crop Ratio:%1.2f IncrWidth:%3.0f IncrHeight:%3.0f\n", Ratio, IncreasedWidth, IncreasedHeight);
INFO_LOG(WII_IPC_WIIMOTE, "Picture Width:%4.1f Height:%4.1f YOffset:%4.0f XOffset:%4.0f\n", PictureWidth, PictureHeight, YOffset, XOffset);
*/
}
// -------------------------------------
// Return the mouse position as a fraction of one, inside the picture, with (0.0, 0.0) being the upper left corner of the picture
x = ((float)point.x - XOffset) / PictureWidth;
y = ((float)point.y - YOffset) / PictureHeight;
// ----------------------------------------------------------
// Logging
// -------------
/*
INFO_LOG(CONSOLE, "GetCursorPos: %i %i\n", point.x, point.y);
INFO_LOG(CONSOLE, "GetClientRect: %i %i %i %i\n", Rect.left, Rect.right, Rect.top, Rect.bottom);
INFO_LOG(CONSOLE, "Position X:%1.2f Y:%1.2f\n", x, y);
INFO_LOG(WII_IPC_WIIMOTE, "GetCursorPos: %i %i\n", point.x, point.y);
INFO_LOG(WII_IPC_WIIMOTE, "GetClientRect: %i %i %i %i\n", Rect.left, Rect.right, Rect.top, Rect.bottom);
INFO_LOG(WII_IPC_WIIMOTE, "Position X:%1.2f Y:%1.2f\n", x, y);
*/
// ---------------------------
#else
// TODO fix on linux
x = 0.5f;
y = 0.5f;
#endif
}
// ==============
// ===================================================
/* Homebrew encryption for 16 byte zero keys. */
// ----------------
void CryptBuffer(u8* _buffer, u8 _size)
{
for (int i=0; i<_size; i++)
@ -198,41 +164,33 @@ void WriteCrypted16(u8* _baseBlock, u16 _address, u16 _value)
CryptBuffer((u8*)&cryptedValue, sizeof(u16));
*(u16*)(_baseBlock + _address) = cryptedValue;
//PanicAlert("Converted %04x to %04x", _value, cryptedValue);
}
// ================
// ===================================================
/* Calculate Extenstion Regisister Calibration Checksum */
// This function is not currently used, it's just here to show how the values in EmuDefinitions.h are calculated.
// ----------------
// This function is not currently used, it's just here to show how the values
// in EmuDefinitions.h are calculated.
void GetCalibrationChecksum()
{
u8 sum = 0;
for (int i = 0; i < sizeof(nunchuck_calibration) - 2; i++)
for (u32 i = 0; i < sizeof(nunchuck_calibration) - 2; i++)
sum += nunchuck_calibration[i];
u8 Check1 = sum + 0x55;
u8 Check2 = sum + 0xaa;
INFO_LOG(CONSOLE, "0x%02x 0x%02x", Check1, Check2);
INFO_LOG(WII_IPC_WIIMOTE, "0x%02x 0x%02x", (sum + 0x55), (sum + 0xaa));
}
// ================
// ===================================================
/* Load pre-recorded movements */
// ----------------
void LoadRecordedMovements()
{
INFO_LOG(CONSOLE, "LoadRecordedMovements()\n");
INFO_LOG(WII_IPC_WIIMOTE, "LoadRecordedMovements()\n");
IniFile file;
file.Load(FULL_CONFIG_DIR "WiimoteMovement.ini");
for(int i = 0; i < RECORDING_ROWS; i++)
{
// Logging
//INFO_LOG(CONSOLE, "Recording%i ", i + 1);
//INFO_LOG(WII_IPC_WIIMOTE, "Recording%i ", i + 1);
// Temporary storage
int iTmp;
@ -276,12 +234,11 @@ void LoadRecordedMovements()
Tmp.y = atoi(StrY.c_str());
Tmp.z = atoi(StrZ.c_str());
// ---------------------------------
// Go to next set of IR values
// ---------
// If there is no IR data saving we fill the array with zeroes. This should only be able to occur from manual ini editing
// but we check for it anyway
if (TmpIRBytes == 0) for(int i = 0; i < 12; i++) Tmp.IR[i] = 0;
// If there is no IR data saving we fill the array with
// zeroes. This should only be able to occur from manual ini
// editing but we check for it anyway
for(int ii = 0; ii < TmpIRBytes; ii++)
{
if(TmpIR.length() < (u32)(k + i + TmpIRBytes)) continue; // Safety check
@ -291,7 +248,6 @@ void LoadRecordedMovements()
Tmp.IR[ii] = (u8)TmpU32;
}
if (TmpIRBytes == 10) k += (10*2 + 1); else k += (12*2 + 1);
// ---------------------
// Go to next set of time values
double Time = (double)atoi(TmpTime.substr(l, 5).c_str());
@ -301,13 +257,11 @@ void LoadRecordedMovements()
// Save the values
VRecording.at(i).Recording.push_back(Tmp);
// ---------------------------------
// Log results
// ---------
/*INFO_LOG(CONSOLE, "Time:%f\n", Tmp.Time);
/*INFO_LOG(WII_IPC_WIIMOTE, "Time:%f\n", Tmp.Time);
std::string TmpIRLog = ArrayToString(Tmp.IR, TmpIRBytes, 0, 30);
INFO_LOG(CONSOLE, "IR: %s\n", TmpIRLog.c_str());
INFO_LOG(CONSOLE, "\n");*/
INFO_LOG(WII_IPC_WIIMOTE, "IR: %s\n", TmpIRLog.c_str());
INFO_LOG(WII_IPC_WIIMOTE, "\n");*/
}
// Get HotKey
@ -320,24 +274,20 @@ void LoadRecordedMovements()
int TmpPlaybackSpeed; file.Get(SaveName.c_str(), "PlaybackSpeed", &TmpPlaybackSpeed, -1);
VRecording.at(i).PlaybackSpeed = TmpPlaybackSpeed;
// ---------------------------------
// Logging
// ---------
/*std::string TmpIRLog;
if(TmpIRBytes > 0 && VRecording.size() > i)
TmpIRLog = ArrayToString(VRecording.at(i).Recording.at(0).IR, TmpIRBytes, 0, 30);
else
TmpIRLog = "";
INFO_LOG(CONSOLE, "Size:%i HotKey:%i PlSpeed:%i IR:%s X:%i Y:%i Z:%i\n",
INFO_LOG(WII_IPC_WIIMOTE, "Size:%i HotKey:%i PlSpeed:%i IR:%s X:%i Y:%i Z:%i\n",
VRecording.at(i).Recording.size(), VRecording.at(i).HotKeyWiimote, VRecording.at(i).PlaybackSpeed,
TmpIRLog.c_str(),
VRecording.at(i).Recording.at(0).x, VRecording.at(i).Recording.at(0).y, VRecording.at(i).Recording.at(0).z
);*/
// ---------------------
}
}
// ================
// Update the accelerometer neutral values
void UpdateEeprom()
@ -349,7 +299,7 @@ void UpdateEeprom()
g_wm.cal_g.y = g_Eeprom[27] - g_Eeprom[24];
g_wm.cal_g.z = g_Eeprom[28] - g_Eeprom[24];
INFO_LOG(CONSOLE, "\nUpdateEeprom: %i %i %i\n",
INFO_LOG(WII_IPC_WIIMOTE, "\nUpdateEeprom: %i %i %i\n",
WiiMoteEmu::g_Eeprom[22], WiiMoteEmu::g_Eeprom[23], WiiMoteEmu::g_Eeprom[28]);
if(g_Config.iExtensionConnected == EXT_NUNCHUCK)
@ -367,7 +317,7 @@ void UpdateEeprom()
g_nu.jy.min = g_RegExt[0x2c];
g_nu.jy.center = g_RegExt[0x2d];
INFO_LOG(CONSOLE, "UpdateNunchuck: %i %i %i %i %i\n\n",
INFO_LOG(WII_IPC_WIIMOTE, "UpdateNunchuck: %i %i %i %i %i\n\n",
WiiMoteEmu::g_RegExt[0x2a], WiiMoteEmu::g_RegExt[0x2d],
WiiMoteEmu::g_RegExt[0x20], WiiMoteEmu::g_RegExt[0x21], WiiMoteEmu::g_RegExt[0x26]);
}
@ -390,7 +340,7 @@ void UpdateEeprom()
g_ClassicContCalibration.Tl.neutral = g_RegExt[0x2c];
g_ClassicContCalibration.Tr.neutral = g_RegExt[0x2d];
INFO_LOG(CONSOLE, "UpdateCC: %i %i %i %i %i\n\n",
INFO_LOG(WII_IPC_WIIMOTE, "UpdateCC: %i %i %i %i %i\n\n",
WiiMoteEmu::g_RegExt[0x2a], WiiMoteEmu::g_RegExt[0x2d],
WiiMoteEmu::g_RegExt[0x20], WiiMoteEmu::g_RegExt[0x21], WiiMoteEmu::g_RegExt[0x26]);
}
@ -401,14 +351,14 @@ void UpdateEeprom()
// Calculate checksum for the nunchuck calibration. The last two bytes.
void ExtensionChecksum(u8 * Calibration)
{
u8 sum = 0; u8 Byte15, Byte16;
for (int i = 0; i < sizeof(Calibration) - 2; i++)
u8 sum = 0; //u8 Byte15, Byte16;
for (u32 i = 0; i < sizeof(Calibration) - 2; i++)
{
sum += Calibration[i];
printf("Plus 0x%02x\n", Calibration[i]);
}
Byte15 = sum + 0x55; // Byte 15
Byte16 = sum + 0xaa; // Byte 16
// Byte15 = sum + 0x55; // Byte 15
// Byte16 = sum + 0xaa; // Byte 16
}
// Set initial valuesm this done both in Init and Shutdown
@ -460,15 +410,13 @@ void SetDefaultExtensionRegistry()
memcpy(g_RegExt + 0xfa, gh3glp_id, sizeof(gh3glp_id));
}
INFO_LOG(CONSOLE, "\nSetDefaultExtensionRegistry()\n\n");
INFO_LOG(WII_IPC_WIIMOTE, "\nSetDefaultExtensionRegistry()\n\n");
UpdateEeprom();
}
// ===================================================
/* Write initial values to Eeprom and registers. */
// ----------------
void Initialize()
{
if (g_EmulatedWiiMoteInitialized) return;
@ -476,14 +424,15 @@ void Initialize()
// Reset variables
ResetVariables();
// Write default Eeprom data to g_Eeprom[], this may be overwritten by WiiMoteReal::Initialize()
// after this function.
// 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));
/* Populate joyinfo for all attached devices and do g_Config.Load() if the configuration window is
not already open, if it's already open we continue with the settings we have */
/* Populate joyinfo for all attached devices and do g_Config.Load() if the
configuration window is not already open, if it's already open we
continue with the settings we have */
if(!g_FrameOpen)
{
Search_Devices(joyinfo, NumPads, NumGoodPads);
@ -498,15 +447,15 @@ void Initialize()
// Load pre-recorded movements
LoadRecordedMovements();
/* The Nuncheck extension ID for homebrew applications that use the zero key. This writes 0x0000
in encrypted form (0xfefe) to 0xfe in the extension register. */
/* The Nuncheck extension ID for homebrew applications that use the zero
key. This writes 0x0000 in encrypted form (0xfefe) to 0xfe in the
extension register. */
//WriteCrypted16(g_RegExt, 0xfe, 0x0000); // Fully inserted Nunchuk
// I forgot what these were for? Is this the zero key encrypted 0xa420?
// g_RegExt[0xfd] = 0x1e;
// g_RegExt[0xfc] = 0x9a;
}
// ================
void DoState(PointerWrap &p)
@ -542,24 +491,24 @@ void DoState(PointerWrap &p)
p.Do(g_ClassicContExt);
}
/* This is not needed if we call FreeLibrary() when we stop a game, but if it's not called we need to reset
these variables. */
/* This is not needed if we call FreeLibrary() when we stop a game, but if it's
not called we need to reset these variables. */
void Shutdown(void)
{
INFO_LOG(CONSOLE, "ShutDown\n");
INFO_LOG(WII_IPC_WIIMOTE, "ShutDown\n");
ResetVariables();
/* Close all devices carefully. We must check that we are not accessing any undefined
vector elements or any bad devices */
/* Close all devices carefully. We must check that we are not accessing any
undefined vector elements or any bad devices */
for (int i = 0; i < 1; i++)
{
if (PadMapping[i].enabled && joyinfo.size() > (u32)PadMapping[i].ID)
if (joyinfo.at(PadMapping[i].ID).Good)
{
INFO_LOG(CONSOLE, "ShutDown: %i\n", PadState[i].joy);
/* SDL_JoystickClose() crashes for some reason so I avoid this for now, SDL_Quit() should
close the pads to I think */
INFO_LOG(WII_IPC_WIIMOTE, "ShutDown: %i\n", PadState[i].joy);
/* SDL_JoystickClose() crashes for some reason so I avoid this
for now, SDL_Quit() should close the pads to I think */
//if(SDL_JoystickOpened(PadMapping[i].ID)) SDL_JoystickClose(PadState[i].joy);
//PadState[i].joy = NULL;
}
@ -575,12 +524,11 @@ void Shutdown(void)
}
// ===================================================
/* An ack delay of 1 was not small enough, but 2 seemed to work, that was about between 20 ms and
100 ms in my case in Zelda - TP. You may have to increase this value for other things to work, for
example in the wpad demo I had to set it to at least 3 for the Sound to be able to turned on (I have
an update rate of around 150 fps in the wpad demo) */
// ----------------
/* An ack delay of 1 was not small enough, but 2 seemed to work, that was about
between 20 ms and 100 ms in my case in Zelda - TP. You may have to increase
this value for other things to work, for example in the wpad demo I had to
set it to at least 3 for the Sound to be able to turned on (I have an update
rate of around 150 fps in the wpad demo) */
void CreateAckDelay(u8 _ChannelID, u16 _ReportID)
{
// Settings
@ -610,27 +558,24 @@ void CheckAckDelay()
}
AckDelay.at(i).Delay--;
//INFO_LOG(CONSOLE, "%i 0x%04x 0x%02x", i, AckDelay.at(i).ChannelID, AckDelay.at(i).ReportID);
//INFO_LOG(WII_IPC_WIIMOTE, "%i 0x%04x 0x%02x", i, AckDelay.at(i).ChannelID, AckDelay.at(i).ReportID);
}
}
}
// ================
// ===================================================
/* This function produce Wiimote Input, i.e. reports from the Wiimote in response
to Output from the Wii. */
// ----------------
/* This function produce Wiimote Input, i.e. reports from the Wiimote in
response to Output from the Wii. */
void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size)
{
//INFO_LOG(CONSOLE, "Emu InterruptChannel\n");
//INFO_LOG(WII_IPC_WIIMOTE, "Emu InterruptChannel\n");
DEBUG_LOG(WII_IPC_WIIMOTE, "=============================================================");
DEBUG_LOG(WII_IPC_WIIMOTE, "Wiimote_Input");
const u8* data = (const u8*)_pData;
/* Debugging. We have not yet decided how much of 'data' we will use, it's not determined
by sizeof(data). We have to determine it by looking at the data cases. */
/* Debugging. We have not yet decided how much of 'data' we will use, it's
not determined by sizeof(data). We have to determine it by looking at
the data cases. */
InterruptDebugging(true, data);
hid_packet* hidp = (hid_packet*) data;
@ -645,19 +590,23 @@ void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size)
wm_report* sr = (wm_report*)hidp->data;
HidOutputReport(_channelID, sr);
/* This is the 0x22 answer to all Inputs. In most games it didn't matter
if it was written before or after HidOutputReport(), but Wii Sports
and Mario Galaxy would stop working if it was placed before
HidOutputReport(). Zelda - TP is even more sensitive and require
a delay after the Input for the Nunchuck to work. It seemed to be
enough to delay only the Nunchuck registry reads and writes but
for now I'm delaying all inputs. Both for status changes and Eeprom
and registry reads and writes. */
/* This is the 0x22 answer to all Inputs. In most games it
didn't matter if it was written before or after
HidOutputReport(), but Wii Sports and Mario Galaxy would
stop working if it was placed before
HidOutputReport(). Zelda - TP is even more sensitive and
require a delay after the Input for the Nunchuck to
work. It seemed to be enough to delay only the Nunchuck
registry reads and writes but for now I'm delaying all
inputs. Both for status changes and Eeprom and registry
reads and writes. */
// There are no 0x22 replys to these report from the real wiimote from what I could see
// Report 0x10 that seems to be only used for rumble, and we don't need to answer that,
// also if we do *we should update the 0x22 to have the core keys* otherwise the game will
// think we release the key every time it rumbles
// There are no 0x22 replys to these report from the real
// wiimote from what I could see Report 0x10 that seems to
// be only used for rumble, and we don't need to answer
// that, also if we do *we should update the 0x22 to have
// the core keys* otherwise the game will think we release
// the key every time it rumbles
if(!(data[1] == WM_READ_DATA && data[2] == 0x00)
&& !(data[1] == WM_REQUEST_STATUS)
&& !(data[1] == WM_WRITE_SPEAKER_DATA)
@ -667,7 +616,6 @@ void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size)
break;
default:
ERROR_LOG(WII_IPC_WIIMOTE, "HidInput: HID_TYPE_DATA - param 0x%02x", hidp->type, hidp->param);
PanicAlert("HidInput: HID_TYPE_DATA - param 0x%02x", hidp->type, hidp->param);
break;
}
@ -675,26 +623,21 @@ void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size)
break;
default:
ERROR_LOG(WII_IPC_WIIMOTE,"HidInput: Unknown type 0x%02x and param 0x%02x", hidp->type, hidp->param);
PanicAlert("HidInput: Unknown type 0x%02x and param 0x%02x", hidp->type, hidp->param);
break;
}
DEBUG_LOG(WII_IPC_WIIMOTE, "=============================================================");
}
void ControlChannel(u16 _channelID, const void* _pData, u32 _Size)
{
//INFO_LOG(CONSOLE, "Emu ControlChannel\n");
//INFO_LOG(WII_IPC_WIIMOTE, "Emu ControlChannel\n");
const u8* data = (const u8*)_pData;
// Dump raw data
{
INFO_LOG(WII_IPC_WIIMOTE, "Wiimote_ControlChannel");
std::string Temp = ArrayToString(data, 0, _Size);
#if defined(HAVE_WX) && HAVE_WX
INFO_LOG(CONSOLE, "\n%s: ControlChannel: %s\n", Tm().c_str(), Temp.c_str());
#endif
DEBUG_LOG(WII_IPC_WIIMOTE, " Data: %s", Temp.c_str());
}
@ -704,12 +647,10 @@ void ControlChannel(u16 _channelID, const void* _pData, u32 _Size)
case HID_TYPE_HANDSHAKE:
if (hidp->param == HID_PARAM_INPUT)
{
ERROR_LOG(WII_IPC_WIIMOTE, "HID_TYPE_HANDSHAKE - HID_PARAM_INPUT");
PanicAlert("HID_TYPE_HANDSHAKE - HID_PARAM_INPUT");
}
else
{
ERROR_LOG(WII_IPC_WIIMOTE, "HID_TYPE_HANDSHAKE - HID_PARAM_OUTPUT");
PanicAlert("HID_TYPE_HANDSHAKE - HID_PARAM_OUTPUT");
}
break;
@ -717,7 +658,6 @@ void ControlChannel(u16 _channelID, const void* _pData, u32 _Size)
case HID_TYPE_SET_REPORT:
if (hidp->param == HID_PARAM_INPUT)
{
ERROR_LOG(WII_IPC_WIIMOTE, "HID_TYPE_SET_REPORT input");
PanicAlert("HID_TYPE_SET_REPORT input");
}
else
@ -731,12 +671,10 @@ void ControlChannel(u16 _channelID, const void* _pData, u32 _Size)
break;
case HID_TYPE_DATA:
ERROR_LOG(WII_IPC_WIIMOTE, "HID_TYPE_DATA %s", hidp->type, hidp->param == HID_PARAM_INPUT ? "input" : "output");
PanicAlert("HID_TYPE_DATA %s", hidp->type, hidp->param == HID_PARAM_INPUT ? "input" : "output");
break;
default:
ERROR_LOG(WII_IPC_WIIMOTE, "HidControlChannel: Unknown type %x and param %x", hidp->type, hidp->param);
PanicAlert("HidControlChannel: Unknown type %x and param %x", hidp->type, hidp->param);
break;
}
@ -744,15 +682,14 @@ void ControlChannel(u16 _channelID, const void* _pData, u32 _Size)
}
// ===================================================
/* This is called from Wiimote_Update(). See SystemTimers.cpp for a documentation. I'm
not sure exactly how often this function is called but I think it's tied to the frame
rate of the game rather than a certain amount of times per second. */
// ----------------
/* This is called from Wiimote_Update(). See SystemTimers.cpp for a
documentation. I'm not sure exactly how often this function is called but I
think it's tied to the frame rate of the game rather than a certain amount
of times per second. */
void Update()
{
//LOG(WII_IPC_WIIMOTE, "Wiimote_Update");
//INFO_LOG(CONSOLE, "Emu Update: %i\n", g_ReportingMode);
//INFO_LOG(WII_IPC_WIIMOTE, "Emu Update: %i\n", g_ReportingMode);
// Check if the pad state should be updated
if ((g_Config.Trigger.Type == g_Config.Trigger.TRIGGER || g_Config.Trigger.Type == g_Config.Trigger.ANALOG1 || g_Config.Trigger.Type == g_Config.Trigger.ANALOG2
@ -781,4 +718,4 @@ void Update()
}
} // end of namespace
} // end of namespace

View File

@ -15,6 +15,7 @@
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include <vector>
#include <string>
@ -39,9 +40,7 @@ extern SWiimoteInitialize g_WiimoteInitialize;
namespace WiiMoteEmu
{
// ===================================================
// Fill joyinfo with the current connected devices
// ----------------
bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_NumGoodPads)
{
bool Success = InputCommon::SearchDevices(_joyinfo, _NumPads, _NumGoodPads);
@ -66,11 +65,8 @@ bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_N
return Success;
}
// ===========================
//////////////////////////////////////////////////////////////////////////////////////////
// Return adjusted input values
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
void PadStateAdjustments(int &Lx, int &Ly, int &Rx, int &Ry, int &Tl, int &Tr)
{
// This has to be changed if multiple Wiimotes are to be supported later
@ -120,16 +116,11 @@ void PadStateAdjustments(int &Lx, int &Ly, int &Rx, int &Ry, int &Tl, int &Tr)
}
}
////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Request joystick state
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
/* Called from: PAD_GetStatus()
Input: The virtual device 0, 1, 2 or 3
Function: Updates the PadState struct with the current pad status. The input value "controller" is
for a virtual controller 0 to 3. */
/* Called from: PAD_GetStatus() Input: The virtual device 0, 1, 2 or 3
Function: Updates the PadState struct with the current pad status. The input
value "controller" is for a virtual controller 0 to 3. */
void GetJoyState(InputCommon::CONTROLLER_STATE_NEW &_PadState, InputCommon::CONTROLLER_MAPPING_NEW _PadMapping, int controller, int NumButtons)
{
@ -182,7 +173,6 @@ void GetJoyState(InputCommon::CONTROLLER_STATE_NEW &_PadState, InputCommon::CONT
_PadState.Axis.Lx, _PadState.Axis.Ly
);*/
}
////////////////////////////////////////////
} // end of namespace WiiMoteEmu

View File

@ -16,11 +16,7 @@
// http://code.google.com/p/dolphin-emu/
// ===================================================
/* HID reports access guide. */
// ----------------
/* 0x10 - 0x1a Output EmuMain.cpp: HidOutputReport()
0x10 - 0x14: General
@ -33,9 +29,6 @@
0x10 - 0x1a leads to a 0x22 Input report
0x30 - 0x3f Input This file: Update() */
// ================
#include <vector>
#include <string>
@ -46,7 +39,6 @@
#include "EmuMain.h" // Local
#include "EmuSubroutines.h"
#include "Config.h" // for g_Config
/////////////////////////////////
extern SWiimoteInitialize g_WiimoteInitialize;
@ -59,10 +51,10 @@ namespace WiiMoteEmu
//******************************************************************************
// ===================================================
/* Here we process the Output Reports that the Wii sends. Our response will be an Input Report
back to the Wii. Input and Output is from the Wii's perspective, Output means data to
the Wiimote (from the Wii), Input means data from the Wiimote.
/* Here we process the Output Reports that the Wii sends. Our response will be
an Input Report back to the Wii. Input and Output is from the Wii's
perspective, Output means data to the Wiimote (from the Wii), Input means
data from the Wiimote.
The call browser:
@ -71,10 +63,9 @@ namespace WiiMoteEmu
The IR lights and speaker enable/disable and mute/unmute values are
0x2 = Disable
0x6 = Enable */
// ----------------
0x6 = Enable
*/
void HidOutputReport(u16 _channelID, wm_report* sr) {
INFO_LOG(WII_IPC_WIIMOTE, "===========================================================");
INFO_LOG(WII_IPC_WIIMOTE, "HidOutputReport (0x%02x)", sr->channel);
std::string Temp;
@ -98,8 +89,8 @@ void HidOutputReport(u16 _channelID, wm_report* sr) {
if (!g_Config.bUseRealWiimote || !g_RealWiiMotePresent) WmReadData(_channelID, (wm_read_data*)sr->data);
break;
/* This enables or disables the IR lights, we update the global variable g_IR
so that WmRequestStatus() knows about it */
/* This enables or disables the IR lights, we update the global variable
g_IR so that WmRequestStatus() knows about it */
case WM_IR_PIXEL_CLOCK: // 0x13
case WM_IR_LOGIC: // 0x1a
WARN_LOG(WII_IPC_WIIMOTE, " IR Enable 0x%02x: 0x%02x", sr->channel, sr->data[0]);
@ -128,18 +119,15 @@ void HidOutputReport(u16 _channelID, wm_report* sr) {
break;
default:
ERROR_LOG(WII_IPC_WIIMOTE, "HidOutputReport: Unknown channel 0x%02x", sr->channel);
PanicAlert("HidOutputReport: Unknown channel 0x%02x", sr->channel);
return;
}
INFO_LOG(WII_IPC_WIIMOTE, "===========================================================");
}
// ===================================================
/* Generate the right header for wm reports. The returned values is the length of the header before
the data begins. It's always two for all reports 0x20 - 0x22, 0x30 - 0x37 */
// ----------------
/* Generate the right header for wm reports. The returned values is the length
of the header before the data begins. It's always two for all reports 0x20 -
0x22, 0x30 - 0x37 */
int WriteWmReport(u8* dst, u8 channel)
{
// Update the first byte to 0xa1
@ -157,26 +145,18 @@ int WriteWmReport(u8* dst, u8 channel)
}
// ===================================================
/* LED (blue lights) report. */
// ----------------
void WmLeds(u16 _channelID, wm_leds* leds) {
INFO_LOG(WII_IPC_WIIMOTE, "===========================================================");
INFO_LOG(WII_IPC_WIIMOTE, " Set LEDs");
INFO_LOG(WII_IPC_WIIMOTE, " Leds: %x", leds->leds);
INFO_LOG(WII_IPC_WIIMOTE, " Rumble: %x", leds->rumble);
INFO_LOG(WII_IPC_WIIMOTE, " Set LEDs Leds: %x Rumble: %x", leds->leds, leds->rumble);
g_Leds = leds->leds;
INFO_LOG(WII_IPC_WIIMOTE, "===========================================================");
}
// ===================================================
/* This will generate the 0x22 acknowledgment after all Input reports. It will
have the form a1 22 00 00 _reportID 00. The first two bytes are the core buttons data,
they are 00 00 when nothing is pressed. The last byte is the success code 00. */
// ----------------
have the form a1 22 00 00 _reportID 00. The first two bytes are the core
buttons data, they are 00 00 when nothing is pressed. The last byte is the
success code 00. */
void WmSendAck(u16 _channelID, u8 _reportID, u32 address)
{
u8 DataFrame[1024];
@ -216,26 +196,22 @@ void WmSendAck(u16 _channelID, u8 _reportID, u32 address)
}
// ===================================================
/* Read data from Wiimote and Extensions registers. */
// ----------------
void WmReadData(u16 _channelID, wm_read_data* rd)
{
INFO_LOG(WII_IPC_WIIMOTE, "===========================================================");
u32 address = convert24bit(rd->address);
u16 size = convert16bit(rd->size);
std::string Temp;
INFO_LOG(WII_IPC_WIIMOTE, "Read data");
INFO_LOG(WII_IPC_WIIMOTE, " Address space: %x", rd->space);
INFO_LOG(WII_IPC_WIIMOTE, " Address: 0x%06x", address);
INFO_LOG(WII_IPC_WIIMOTE, " Size: 0x%04x", size);
INFO_LOG(WII_IPC_WIIMOTE, " Rumble: %x", rd->rumble);
INFO_LOG(WII_IPC_WIIMOTE, "Read data Address space: %x", rd->space);
INFO_LOG(WII_IPC_WIIMOTE, "Read data Address: 0x%06x", address);
INFO_LOG(WII_IPC_WIIMOTE, "Read data Size: 0x%04x", size);
INFO_LOG(WII_IPC_WIIMOTE, "Read data Rumble: %x", rd->rumble);
//u32 _address = address;
std::string Tmp; // Debugging
/* Now we determine what address space we are reading from. Space 0 is Eeprom and
space 1 and 2 is the registers. */
/* Now we determine what address space we are reading from. Space 0 is
Eeprom and space 1 and 2 is the registers. */
if(rd->space == WM_SPACE_EEPROM)
{
if (address + size > WIIMOTE_EEPROM_SIZE)
@ -281,15 +257,12 @@ void WmReadData(u16 _channelID, wm_read_data* rd)
size, address, (address & 0xffff), Tmp.c_str());*/
break;
default:
ERROR_LOG(WII_IPC_WIIMOTE, "WmReadData: bad register block!");
PanicAlert("WmReadData: bad register block!");
ERROR_LOG(WII_IPC_WIIMOTE, "WmWriteData: bad register block!");
return;
}
// -----------------------------------------
// Encrypt data that is read from the Wiimote Extension Register
// -------------
if(((address >> 16) & 0xfe) == 0xa4)
{
/* Debugging
@ -334,25 +307,21 @@ void WmReadData(u16 _channelID, wm_read_data* rd)
PanicAlert("WmReadData: unimplemented parameters (size: %i, addr: 0x%x!", size, rd->space);
}
INFO_LOG(WII_IPC_WIIMOTE, "===========================================================");
}
// ===================================================
/* Here we produce the actual 0x21 Input report that we send to the Wii. The message
is divided into 16 bytes pieces and sent piece by piece. There will be five formatting
bytes at the begging of all reports. A common format is 00 00 f0 00 20, the 00 00
means that no buttons are pressed, the f means 16 bytes in the message, the 0
means no error, the 00 20 means that the message is at the 00 20 offest in the
registry that was read.
/* Here we produce the actual 0x21 Input report that we send to the Wii. The
message is divided into 16 bytes pieces and sent piece by piece. There will
be five formatting bytes at the begging of all reports. A common format is
00 00 f0 00 20, the 00 00 means that no buttons are pressed, the f means 16
bytes in the message, the 0 means no error, the 00 20 means that the message
is at the 00 20 offest in the registry that was read.
_Base: The data beginning at _Base[0]
_Address: The starting address inside the registry, this is used to check for out of bounds reading
_Size: The total size to send
_Base: The data beginning at _Base[0] _Address: The starting address inside
the registry, this is used to check for out of bounds reading _Size: The
total size to send
*/
// ----------------
void SendReadDataReply(u16 _channelID, void* _Base, u16 _Address, u8 _Size)
{
INFO_LOG(WII_IPC_WIIMOTE, "=========================================");
int dataOffset = 0;
const u8* data = (const u8*)_Base;
@ -386,10 +355,11 @@ void SendReadDataReply(u16 _channelID, void* _Base, u16 _Address, u8 _Size)
// Update DataOffset for the next loop
dataOffset += copySize;
/* Out of bounds. The real Wiimote generate an error for the first request to 0x1770
if we dont't replicate that the game will never read the capibration data at the
beginning of Eeprom. I think this error is supposed to occur when we try to read above
the freely usable space that ends at 0x16ff. */
/* Out of bounds. The real Wiimote generate an error for the first
request to 0x1770 if we dont't replicate that the game will never
read the capibration data at the beginning of Eeprom. I think this
error is supposed to occur when we try to read above the freely
usable space that ends at 0x16ff. */
if (Common::swap16(pReply->address + pReply->size) > WIIMOTE_EEPROM_FREE_SIZE)
{
pReply->size = 0x0f;
@ -421,20 +391,14 @@ void SendReadDataReply(u16 _channelID, void* _Base, u16 _Address, u8 _Size)
}
if (_Size != 0) {
ERROR_LOG(WII_IPC_WIIMOTE, "WiiMote-Plugin: SendReadDataReply() failed");
PanicAlert("WiiMote-Plugin: SendReadDataReply() failed");
}
INFO_LOG(WII_IPC_WIIMOTE, "==========================================");
}
// ================
// ===================================================
/* Write data to Wiimote and Extensions registers. */
// ----------------
void WmWriteData(u16 _channelID, wm_write_data* wd)
{
INFO_LOG(WII_IPC_WIIMOTE, "========================================================");
u32 address = convert24bit(wd->address);
INFO_LOG(WII_IPC_WIIMOTE, "Write data");
DEBUG_LOG(WII_IPC_WIIMOTE, " Address space: %x", wd->space);
@ -474,9 +438,7 @@ void WmWriteData(u16 _channelID, wm_write_data* wd)
case 0xA4:
block = g_RegExt; // Extension Controller register
blockSize = WIIMOTE_REG_EXT_SIZE;
//LOGV(WII_IPC_WIIMOTE, 0, " *******************************************************");
INFO_LOG(WII_IPC_WIIMOTE, " Case 0xa4: ExtReg");
//LOGV(WII_IPC_WIIMOTE, 0, " *******************************************************");
/*INFO_LOG(CONSOLE, "Write RegExt Size: %i Address: %08x Offset: %08x \n",
wd->size, address, (address & 0xffff));
INFO_LOG(CONSOLE, "Data: %s\n", Temp.c_str());*/
@ -500,7 +462,6 @@ void WmWriteData(u16 _channelID, wm_write_data* wd)
// Check if the address is within bounds
if(address + wd->size > blockSize) {
ERROR_LOG(WII_IPC_WIIMOTE, "WmWriteData: address + size out of bounds!");
PanicAlert("WmWriteData: address + size out of bounds!");
return;
}
@ -509,9 +470,7 @@ void WmWriteData(u16 _channelID, wm_write_data* wd)
memcpy(block + address, wd->data, wd->size);
// -----------------------------------------
// Generate key for the Wiimote Extension
// -------------
if(blockSize == WIIMOTE_REG_EXT_SIZE)
{
/* Debugging. Write the data.
@ -528,29 +487,23 @@ void WmWriteData(u16 _channelID, wm_write_data* wd)
} else {
ERROR_LOG(WII_IPC_WIIMOTE, "WmWriteData: unimplemented parameters!");
PanicAlert("WmWriteData: unimplemented parameters!");
}
/* Just added for home brew... Isn't it enough that we call this from
InterruptChannel()? Or is there a separate route here that don't pass though
InterruptChannel()? */
InterruptChannel()? Or is there a separate route here that don't pass
though InterruptChannel()? */
//WmSendAck(_channelID, WM_WRITE_DATA, _address);
INFO_LOG(WII_IPC_WIIMOTE, "==========================================================");
}
// ===================================================
/* Here we produce a 0x20 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. */
// ----------------
/* Here we produce a 0x20 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, int Extension)
{
//PanicAlert("WmRequestStatus");
INFO_LOG(WII_IPC_WIIMOTE, "================================================");
INFO_LOG(WII_IPC_WIIMOTE, " Request Status");
INFO_LOG(WII_IPC_WIIMOTE, " Rumble: %x", rs->rumble);
INFO_LOG(WII_IPC_WIIMOTE, " Channel: %04x", _channelID);
INFO_LOG(WII_IPC_WIIMOTE, " Request Status: Rumble: %x Channel: %04x",
rs->rumble, _channelID);
//SendStatusReport();
u8 DataFrame[1024];
@ -590,12 +543,11 @@ void WmRequestStatus(u16 _channelID, wm_request_status* rs, int Extension)
}
INFO_LOG(WII_IPC_WIIMOTE, " Extension: %x", pStatus->extension);
INFO_LOG(WII_IPC_WIIMOTE, " SendStatusReport()");
DEBUG_LOG(WII_IPC_WIIMOTE, " Flags: 0x%02x", pStatus->padding1[2]);
DEBUG_LOG(WII_IPC_WIIMOTE, " Battery: %d", pStatus->battery);
INFO_LOG(WII_IPC_WIIMOTE, " SendStatusReport() Flags: 0x%02x Battery: %d"
,pStatus->padding1[2], pStatus->battery);
g_WiimoteInitialize.pWiimoteInput(_channelID, DataFrame, Offset);
INFO_LOG(WII_IPC_WIIMOTE, "=================================================");
// Debugging
ReadDebugging(true, DataFrame, Offset);

View File

@ -246,9 +246,7 @@ void gentabs(u8 *rand, u8 *key, u8 idx, u8 *ft, u8 *sb)
// ===================================================
/* Generate key from the 0x40-0x4c data in g_RegExt */
// ----------------
void wiimote_gen_key(wiimote_key *key, u8 *keydata)
{
u8 rand[10];
@ -282,9 +280,7 @@ void wiimote_gen_key(wiimote_key *key, u8 *keydata)
}
// ===================================================
/* Encrypt data */
// ----------------
void wiimote_encrypt(wiimote_key *key, u8 *data, int addr, u8 len)
{
for(int i = 0; i < len; i++, addr++)
@ -292,9 +288,7 @@ void wiimote_encrypt(wiimote_key *key, u8 *data, int addr, u8 len)
}
// ===================================================
/* Decrypt data */
// ----------------
void wiimote_decrypt(wiimote_key *key, u8 *data, int addr, u8 len)
{
for(int i = 0; i < len; i++, addr++)

View File

@ -37,24 +37,16 @@ namespace WiiMoteEmu
{
//**************************************************************************************
// Recorded movements
//**************************************************************************************
// ------------------------------------------
// Variables: 0 = Wiimote, 1 = Nunchuck
// ----------------
int g_RecordingPlaying[3]; //g_RecordingPlaying[0] = -1; g_RecordingPlaying[1] = -1;
int g_RecordingCounter[3]; //g_RecordingCounter[0] = 0; g_RecordingCounter[1] = 0;
int g_RecordingPoint[3]; //g_RecordingPoint[0] = 0; g_RecordingPoint[1] = 0;
double g_RecordingStart[3]; //g_RecordingStart[0] = 0; g_RecordingStart[1] = 0;
double g_RecordingCurrentTime[3]; //g_RecordingCurrentTime[0] = 0; g_RecordingCurrentTime[1] = 0;
// --------------------------
/////////////////////////////////////////////////////////////////////////
/* Convert from -350 to -3.5 g. The Nunchuck gravity size is 51 compared to the 26 to 28 for the Wiimote.
So the maximum g values are higher for the Wiimote. */
// ---------------
int G2Accelerometer(int _G, int XYZ, int Wm)
{
float G = (float)_G / 100.0;
@ -378,12 +370,9 @@ int IsKey(int Key)
return false;
#endif
}
//////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
// Wiimote core buttons
// ---------------
void FillReportInfo(wm_core& _core)
{
/* This has to be filled with zeroes (and not for example 0xff) because when no buttons are pressed the
@ -425,24 +414,20 @@ void FillReportInfo(wm_core& _core)
_core.down = IsKey(g_Wiimote_kbd.D) ? 1 : 0;
}
}
//////////////////////////
///////////////////////////////////////////////////////////////////
// Wiimote accelerometer
// ---------------
/* The accelerometer x, y and z values range from 0x00 to 0xff with the default netural values
being [y = 0x84, x = 0x84, z = 0x9f] according to a source. The extremes are 0x00 for (-)
and 0xff for (+). It's important that all values are not 0x80, the mouse pointer can disappear
from the screen permanently then, until z is adjusted back. This is because the game detects
/* The accelerometer x, y and z values range from 0x00 to 0xff with the default
netural values being [y = 0x84, x = 0x84, z = 0x9f] according to a
source. The extremes are 0x00 for (-) and 0xff for (+). It's important that
all values are not 0x80, the mouse pointer can disappear from the screen
permanently then, until z is adjusted back. This is because the game detects
a steep pitch of the Wiimote then. */
// ----------
// Global declarations for FillReportAcc: These variables are global so they can be changed during debugging
//int A = 0, B = 128, C = 64; // for debugging
//int a = 1, b = 1, c = 2, d = -2; // for debugging
//int consoleDisplay = 0;
// Global declarations for FillReportAcc: These variables are global so they
//can be changed during debugging int A = 0, B = 128, C = 64; // for debugging
//int a = 1, b = 1, c = 2, d = -2; // for debugging int consoleDisplay = 0;
// For all functions
u8 g_x, g_y, g_z, g_X, g_Y, g_Z;
@ -454,9 +439,7 @@ int Shake[] = {-1, -1};
std::vector<u8> yhist(15, 0); float KbDegree;
// ------------------------------------------
// Single shake of Wiimote while holding it sideways (Wario Land pound ground)
// ---------------
void SingleShake(u8 &_y, u8 &_z, int i)
{
#ifdef _WIN32
@ -483,11 +466,9 @@ void SingleShake(u8 &_y, u8 &_z, int i)
}
// ------------------------------------------
/* Tilting Wiimote with gamepad. We can guess that the game will calculate a Wiimote pitch and use it as a
measure of the tilting of the Wiimote. We are interested in this tilting range
90° to -90° */
// ---------------
/* Tilting Wiimote with gamepad. We can guess that the game will calculate a
Wiimote pitch and use it as a measure of the tilting of the Wiimote. We are
interested in this tilting range 90° to -90° */
void TiltWiimoteGamepad(float &Roll, float &Pitch)
{
// Return if we have no pads
@ -496,10 +477,12 @@ void TiltWiimoteGamepad(float &Roll, float &Pitch)
// This has to be changed if multiple Wiimotes are to be supported later
const int Page = 0;
/* Adjust the pad state values, including a downscaling from the original 0x8000 size values
to 0x80. The only reason we do this is that the code below crrently assume that the range
is 0 to 255 for all axes. If we lose any precision by doing this we could consider not
doing this adjustment. And instead for example upsize the XInput trigger from 0x80 to 0x8000. */
/* Adjust the pad state values, including a downscaling from the original
0x8000 size values to 0x80. The only reason we do this is that the code
below crrently assume that the range is 0 to 255 for all axes. If we
lose any precision by doing this we could consider not doing this
adjustment. And instead for example upsize the XInput trigger from 0x80
to 0x8000. */
int _Lx, _Ly, _Rx, _Ry, _Tl, _Tr;
PadStateAdjustments(_Lx, _Ly, _Rx, _Ry, _Tl, _Tr);
float Lx = (float)_Lx;
@ -526,8 +509,9 @@ void TiltWiimoteGamepad(float &Roll, float &Pitch)
- Tr * (PitchRange / 128.0);
}
/* For the analog stick roll us by default set to the X-axis, pitch is by default set to the Y-axis.
By changing the axis mapping and the invert options this can be altered in any way */
/* For the analog stick roll us by default set to the X-axis, pitch is by
default set to the Y-axis. By changing the axis mapping and the invert
options this can be altered in any way */
else if (g_Config.Trigger.Type == g_Config.Trigger.ANALOG1)
{
// Adjust the trigger to go between negative and positive values
@ -560,9 +544,7 @@ void TiltWiimoteGamepad(float &Roll, float &Pitch)
}
// ------------------------------------------
// Tilting Wiimote with keyboard
// ---------------
void TiltWiimoteKeyboard(float &Roll, float &Pitch)
{
#ifdef _WIN32
@ -579,9 +561,7 @@ void TiltWiimoteKeyboard(float &Roll, float &Pitch)
KbDegree -= 3; // aim right
}
// -----------------------------------
// Check for inactivity in the tilting, the Y value will be reset after ten inactive updates
// ----------
// Check for activity
yhist[yhist.size() - 1] = (
IsKey(g_Wiimote_kbd.PITCH_L)
@ -605,13 +585,10 @@ void TiltWiimoteKeyboard(float &Roll, float &Pitch)
Pitch = KbDegree;
//INFO_LOG(CONSOLE, "Degree: %2.1f\n", KbDegree);
}
// --------------------
#endif
}
// ------------------------------------------
// Tilting Wiimote (Wario Land aiming, Mario Kart steering and other things)
// ---------------
void Tilt(u8 &_x, u8 &_y, u8 &_z)
{
// Ceck if it's on
@ -635,7 +612,6 @@ void Tilt(u8 &_x, u8 &_y, u8 &_z)
if (g_DebugData)
{
//Console::ClearScreen();
/*INFO_LOG(CONSOLE, "L:%2.1f R:%2.1f Lx:%2.1f Range:%2.1f Degree:%2.1f L:%i R:%i\n",
Tl, Tr, Lx, Range, Degree, PadState[Page].Axis.Tl, PadState[Page].Axis.Tr);*/
/*INFO_LOG(CONSOLE, "Roll:%2.1f Pitch:%2.1f\n", Roll, Pitch);*/
@ -644,9 +620,7 @@ void Tilt(u8 &_x, u8 &_y, u8 &_z)
void FillReportAcc(wm_accel& _acc)
{
// ------------------------------------
// Recorded movements
// --------------
// Check for a playback command
if(g_RecordingPlaying[0] < 0)
{
@ -658,7 +632,6 @@ void FillReportAcc(wm_accel& _acc)
if (RecordingPlay(_acc.x, _acc.y, _acc.z, 0)) return;
//INFO_LOG(CONSOLE, "X, Y, Z: %u %u %u\n", _acc.x, _acc.y, _acc.z);
}
// ---------------------
// The default values can change so we need to update them all the time
g_X = g_wm.cal_zero.x;
@ -675,9 +648,7 @@ void FillReportAcc(wm_accel& _acc)
return;
}
// ------------------------------------------------
// Wiimote to Gamepad translations
// ------------
// The following functions may or may not update these values
g_x = g_X;
@ -696,9 +667,7 @@ void FillReportAcc(wm_accel& _acc)
_acc.z = g_z;
// ----------------------------
// Debugging for translating Wiimote to Keyboard (or Gamepad)
// ----------
/*
// Toogle console display
@ -773,7 +742,6 @@ void FillReportAcc(wm_accel& _acc)
AX, AY, AZ
);*/
}
/////////////////////////
@ -783,14 +751,10 @@ void FillReportAcc(wm_accel& _acc)
Bottom = BOTTOM, SensorBarRadius = SENSOR_BAR_RADIUS;
*/
///////////////////////////////////////////////////////////////////
// The extended 12 byte (3 byte per object) reporting
// ---------------
void FillReportIR(wm_ir_extended& _ir0, wm_ir_extended& _ir1)
{
// ------------------------------------
// Recorded movements
// --------------
// Check for a playback command
if(g_RecordingPlaying[2] < 0)
{
@ -801,10 +765,10 @@ void FillReportIR(wm_ir_extended& _ir0, wm_ir_extended& _ir1)
//INFO_LOG(CONSOLE, "X, Y, Z: %u %u %u\n", _acc.x, _acc.y, _acc.z);
if (RecordingPlayIR(_ir0)) return;
}
// ---------------------
/* Fill with 0xff if empty. The real Wiimote seems to use 0xff when it doesn't see a certain point,
at least from how WiiMoteReal::SendEvent() works. */
/* Fill with 0xff if empty. The real Wiimote seems to use 0xff when it
doesn't see a certain point, at least from how WiiMoteReal::SendEvent()
works. */
memset(&_ir0, 0xff, sizeof(wm_ir_extended));
memset(&_ir1, 0xff, sizeof(wm_ir_extended));
@ -814,19 +778,13 @@ void FillReportIR(wm_ir_extended& _ir0, wm_ir_extended& _ir1)
// If we are outside the screen leave the values at 0xff
if(MouseX > 1 || MouseX < 0 || MouseY > 1 || MouseY < 0) return;
// --------------------------------------
// Position calculation
// ----------
int y0 = g_Config.iIRTop + (MouseY * g_Config.iIRHeight);
int y1 = y0;
// The distance between the x positions are two sensor bar radii
int x0 = g_Config.iIRLeft + (MouseX * g_Config.iIRWidth) - SENSOR_BAR_RADIUS;
int x1 = g_Config.iIRLeft + (MouseX * g_Config.iIRWidth) + SENSOR_BAR_RADIUS;
// ------------------
// ----------------------------
// Debugging for calibration
// ----------
/*
if(!GetAsyncKeyState(VK_CONTROL) && GetAsyncKeyState(VK_RIGHT))
Right +=1;
@ -854,12 +812,9 @@ void FillReportIR(wm_ir_extended& _ir0, wm_ir_extended& _ir1)
INFO_LOG(CONSOLE, "x0:%03i x1:%03i y0:%03i y1:%03i | T:%i L:%i R:%i B:%i S:%i\n",
x0, x1, y0, y1, Top, Left, Right, Bottom, SensorBarRadius
);*/
// ------------------
// --------------------------------------
// Converted to IR data
// ----------
// The width is 0 to 1023
// The height is 0 to 767
x0 = 1023 - x0;
@ -872,18 +827,13 @@ void FillReportIR(wm_ir_extended& _ir0, wm_ir_extended& _ir1)
_ir1.x = x1 & 0xff; _ir1.xHi = x1 >> 8;
_ir1.y = y1 & 0xff; _ir1.yHi = y1 >> 8;
_ir1.size = 10;
// ------------------
}
///////////////////////////////////////////////////////////////////
// The 10 byte reporting used when an extension is connected
// ---------------
void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1)
{
// ------------------------------------
// Recorded movements
// --------------
// Check for a playback command
if(g_RecordingPlaying[2] < 0)
{
@ -895,7 +845,6 @@ void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1)
//INFO_LOG(CONSOLE, "X, Y, Z: %u %u %u\n", _acc.x, _acc.y, _acc.z);
if (RecordingPlayIR(_ir0)) return;
}
// ---------------------
// Fill with 0xff if empty
memset(&_ir0, 0xff, sizeof(wm_ir_basic));
@ -913,8 +862,9 @@ void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1)
int x1 = g_Config.iIRLeft + (MouseX * g_Config.iIRWidth) - SENSOR_BAR_RADIUS;
int x2 = g_Config.iIRLeft + (MouseX * g_Config.iIRWidth) + SENSOR_BAR_RADIUS;
/* As with the extented report we settle with emulating two out of four possible objects
the only difference is that we don't report any size of the tracked object here */
/* As with the extented report we settle with emulating two out of four
possible objects the only difference is that we don't report any size of
the tracked object here */
x1 = 1023 - x1;
_ir0.x1 = x1 & 0xff; _ir0.x1Hi = (x1 >> 8); // we are dealing with 2 bit values here
_ir0.y1 = y1 & 0xff; _ir0.y1Hi = (y1 >> 8);
@ -924,9 +874,7 @@ void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1)
_ir0.y2 = y2 & 0xff; _ir0.y2Hi = (y2 >> 8);
// ------------------------------------
// Debugging for calibration
// ----------
/*
if(GetAsyncKeyState(VK_NUMPAD1))
Right +=1;
@ -966,19 +914,14 @@ void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1)
}
//**************************************************************************************
// Extensions
//**************************************************************************************
// ===================================================
/* Generate the 6 byte extension report for the Nunchuck, encrypted. The bytes are JX JY AX AY AZ BT. */
// ----------------
/* Generate the 6 byte extension report for the Nunchuck, encrypted. The bytes
are JX JY AX AY AZ BT. */
void FillReportExtension(wm_extension& _ext)
{
// ------------------------------------------
// Recorded movements
// --------------
// Check for a playback command
if(g_RecordingPlaying[1] < 0) g_RecordingPlaying[1] = RecordingCheckKeys(1);
@ -990,18 +933,14 @@ void FillReportExtension(wm_extension& _ext)
_ext.ay = g_nu.cal_zero.y;
_ext.az = g_nu.cal_zero.z + g_nu.cal_g.z;
}
// ---------------------
// Shake the Wiimote
SingleShake(_ext.ay, _ext.az, 1);
// ------------------------------------
// The default joystick and button values unless we use them
// --------------
_ext.jx = g_nu.jx.center;
_ext.jy = g_nu.jy.center;
_ext.bt = 0x03; // 0x03 means no button pressed, the button is zero active
// ---------------------
// Update the analog stick
if (g_Config.Nunchuck.Type == g_Config.Nunchuck.KEYBOARD)
@ -1026,9 +965,10 @@ void FillReportExtension(wm_extension& _ext)
_Ly = 0xff - _Ly;
_Ry = 0xff - _Ry;
/* This is if we are also using a real Nunchuck that we are sharing the calibration with. It's not
needed if we are using our default values. We adjust the values to the configured range, we even
allow the center to not be 0x80. */
/* This is if we are also using a real Nunchuck that we are sharing the
calibration with. It's not needed if we are using our default
values. We adjust the values to the configured range, we even allow
the center to not be 0x80. */
if(g_nu.jx.max != 0xff || g_nu.jy.max != 0xff
|| g_nu.jx.min != 0 || g_nu.jy.min != 0
|| g_nu.jx.center != 0x80 || g_nu.jy.center != 0x80)
@ -1037,8 +977,8 @@ void FillReportExtension(wm_extension& _ext)
float Ly = (float)_Ly;
float Rx = (float)_Rx;
float Ry = (float)_Ry;
float Tl = (float)_Tl;
float Tr = (float)_Tr;
// float Tl = (float)_Tl;
// float Tr = (float)_Tr;
float XRangePos = (float) (g_nu.jx.max - g_nu.jx.center);
float XRangeNeg = (float) (g_nu.jx.center - g_nu.jx.min);
@ -1093,13 +1033,10 @@ void FillReportExtension(wm_extension& _ext)
// Write it back to the struct
memcpy(&_ext, Tmp, sizeof(_ext));
}
// =======================
// ===================================================
/* Generate the 6 byte extension report for the Classic Controller, encrypted.
The bytes are ... */
// ----------------
void FillReportClassicExtension(wm_classic_extension& _ext)
{
/* These are the default neutral values for the analog triggers and sticks */
@ -1125,11 +1062,9 @@ void FillReportClassicExtension(wm_classic_extension& _ext)
_ext.b2.bB = 0x01;
_ext.b2.bZL = 0x01;
// --------------------------------------
// Check that Dolphin is in focus
if (IsFocus())
{
// --------------------------------------
/* Left and right analog sticks and analog triggers
u8 Lx : 6; // byte 0
@ -1169,10 +1104,13 @@ void FillReportClassicExtension(wm_classic_extension& _ext)
_Ly = 0xff - _Ly;
_Ry = 0xff - _Ry;
/* This is if we are also using a real Classic Controller that we are sharing the calibration with.
It's not needed if we are using our default values. We adjust the values to the configured range.
/* This is if we are also using a real Classic Controller that we
are sharing the calibration with. It's not needed if we are
using our default values. We adjust the values to the configured
range.
Status: Not added, we are not currently sharing the calibration with the real Classic Controller
Status: Not added, we are not currently sharing the calibration
with the real Classic Controller
*/
if (g_Config.ClassicController.LType == g_Config.ClassicController.ANALOG1)
@ -1208,10 +1146,13 @@ void FillReportClassicExtension(wm_classic_extension& _ext)
_Ly = 0xff - _Ly;
_Ry = 0xff - _Ry;
/* This is if we are also using a real Classic Controller that we are sharing the calibration with.
It's not needed if we are using our default values. We adjust the values to the configured range.
/* This is if we are also using a real Classic Controller that we
are sharing the calibration with. It's not needed if we are
using our default values. We adjust the values to the configured
range.
Status: Not added, we are not currently sharing the calibration with the real Classic Controller
Status: Not added, we are not currently sharing the calibration
with the real Classic Controller
*/
if (g_Config.ClassicController.RType == g_Config.ClassicController.ANALOG1)
@ -1240,25 +1181,28 @@ void FillReportClassicExtension(wm_classic_extension& _ext)
int _Lx, _Ly, _Rx, _Ry, _Tl, _Tr;
PadStateAdjustments(_Lx, _Ly, _Rx, _Ry, _Tl, _Tr);
/* This is if we are also using a real Classic Controller that we are sharing the calibration with.
It's not needed if we are using our default values. We adjust the values to the configured range.
/* This is if we are also using a real Classic Controller that we
are sharing the calibration with. It's not needed if we are
using our default values. We adjust the values to the configured
range.
Status: Not added, we are not currently sharing the calibration with the real Classic Controller
Status: Not added, we are not currently sharing the calibration
with the real Classic Controller
*/
// Check if the trigger is fully pressed, then update the digital trigger values to
// Check if the trigger is fully pressed, then update the digital
// trigger values to
if (_Tl == 0xff) _ext.b1.bLT = 0x00;
if (_Tr == 0xff) _ext.b1.bRT = 0x00;
// These can be copied directly, the bitshift further down fix this value to
// These can be copied directly, the bitshift further down fix this
// value to
lT = _Tl;
rT = _Tr;
}
// --------------
// --------------------------------------
/* D-Pad
u8 b1;
@ -1274,9 +1218,7 @@ void FillReportClassicExtension(wm_classic_extension& _ext)
if(IsKey(g_ClassicContExt.Du)) _ext.b2.bdU = 0x00; // Up
if(IsKey(g_ClassicContExt.Dr)) _ext.b1.bdR = 0x00; // Right
if(IsKey(g_ClassicContExt.Dd)) _ext.b1.bdD = 0x00; // Down
// --------------
// --------------------------------------
/* Buttons
u8 b1;
0:
@ -1323,14 +1265,10 @@ void FillReportClassicExtension(wm_classic_extension& _ext)
// All buttons pressed
//if(GetAsyncKeyState('C') && GetAsyncKeyState('Z'))
// { _ext.b2.bA = 0x01; _ext.b2.bB = 0x01; }
// --------------
}
// --------------------------------------
// --------------------------------------
// Convert data for reporting
// --------------
_ext.Lx = (Lx >> 2);
_ext.Ly = (Ly >> 2);
// 5 bit to 1 bit
@ -1346,7 +1284,6 @@ void FillReportClassicExtension(wm_classic_extension& _ext)
// 5 bit to the highest two bits
_ext.lT2 = (lT >> 3) >> 3;
_ext.rT = (rT >> 3);
// --------------
/* Here we encrypt the report */
@ -1362,12 +1299,10 @@ void FillReportClassicExtension(wm_classic_extension& _ext)
// Write it back to the struct
memcpy(&_ext, Tmp, sizeof(_ext));
}
// =======================
// ===================================================
/* Generate the 6 byte extension report for the Classic Controller, encrypted.
/* Generate the 6 byte extension report for the GH3 Controller, encrypted.
The bytes are ... */
// ----------------
void FillReportGuitarHero3Extension(wm_GH3_extension& _ext)
{
//_ext.SX : 6;
@ -1399,11 +1334,9 @@ void FillReportGuitarHero3Extension(wm_GH3_extension& _ext)
_ext.BO = 1;
// --------------------------------------
// Check that Dolphin is in focus
if (IsFocus())
{
// --------------------------------------
/* Left and right analog sticks and analog triggers
u8 Lx : 6; // byte 0
@ -1481,12 +1414,8 @@ void FillReportGuitarHero3Extension(wm_GH3_extension& _ext)
if(IsKey(g_GH3Ext.BO))
_ext.BO = 0x00;
}
// --------------------------------------
// --------------------------------------
// Convert data for reporting
// --------------
_ext.SX = (SX >> 2);
_ext.SY = (SY >> 2);
@ -1505,7 +1434,6 @@ void FillReportGuitarHero3Extension(wm_GH3_extension& _ext)
// 5 bit to the highest two bits
_ext.lT2 = (lT >> 3) >> 3;
_ext.rT = (rT >> 3);
// --------------
*/
/* Here we encrypt the report */

View File

@ -229,7 +229,6 @@ void handle_event(struct wiimote_t* wm)
if(!g_DebugData)
{
// Console::ClearScreen();
INFO_LOG(CONSOLE, "Roll:%03i Pitch:%03i\n", (int)wm->orient.roll, (int)wm->orient.pitch);
}
if(m_PadConfigFrame)

View File

@ -24,7 +24,6 @@ if wmenv['HAVE_WX']:
"ConfigRecordingDlg.cpp",
"ConfigGamepad.cpp",
"ConfigRecording.cpp",
"Logging.cpp",
"FillReport.cpp",
]

View File

@ -16,15 +16,20 @@
// http://code.google.com/p/dolphin-emu/
// Current issues
/*
The real Wiimote fails to answer the core correctly sometmes. Leading to an unwanted disconnection. And
there is currenty no functions to reconnect with the game. There are two ways to solve this:
1. Make a reconnect function in the IOS emulation
2. Detect failed answers in this plugin and solve it by replacing them with emulated answers.
The real Wiimote fails to answer the core correctly sometmes. Leading to an
unwanted disconnection. And there is currenty no functions to reconnect with
the game. There are two ways to solve this:
The first solution seems easier, if I knew a little better how the /dev/usb/oh1 and Wiimote functions
worked.
1. Make a reconnect function in the IOS emulation
2. Detect failed answers in this plugin and solve it by replacing them with
emulated answers.
The first solution seems easier, if I knew a little better how the /dev/usb/oh1
and Wiimote functions worked.
*/
#include "Common.h" // Common
@ -119,7 +124,7 @@ BOOL APIENTRY DllMain(HINSTANCE hinstDLL, // DLL module handle
return FALSE;
#endif
}
break;
break;
case DLL_PROCESS_DETACH:
#if defined(HAVE_WX) && HAVE_WX
@ -150,9 +155,7 @@ wxWindow* GetParentedWxWindow(HWND Parent)
}
#endif
//******************************************************************************
// Exports
//******************************************************************************
void GetDllInfo(PLUGIN_INFO* _PluginInfo)
{
_PluginInfo->Version = 0x0100;
@ -179,7 +182,7 @@ void DllDebugger(HWND _hParent, bool Show) {}
void DllConfig(HWND _hParent)
{
#if defined(HAVE_WX) && HAVE_WX
DoInitialize();
if (!m_BasicConfigFrame)
@ -198,7 +201,7 @@ void DllConfig(HWND _hParent)
void Initialize(void *init)
{
// Declarations
SWiimoteInitialize _WiimoteInitialize = *(SWiimoteInitialize *)init;
SWiimoteInitialize _WiimoteInitialize = *(SWiimoteInitialize *)init;
g_WiimoteInitialize = _WiimoteInitialize;
g_EmulatorRunning = true;
@ -283,17 +286,14 @@ void DoState(unsigned char **ptr, int mode)
}
// ===================================================
/* This function produce Wiimote Input (reports from the Wiimote) in response
to Output from the Wii. It's called from WII_IPC_HLE_WiiMote.cpp.
Switch between real and emulated wiimote: We send all this Input to WiiMoteEmu::InterruptChannel()
so that it knows the channel ID and the data reporting mode at all times.
*/
// ----------------
void Wiimote_InterruptChannel(u16 _channelID, const void* _pData, u32 _Size)
{
DEBUG_LOG(WII_IPC_WIIMOTE, "=============================================================");
const u8* data = (const u8*)_pData;
// Debugging
@ -311,18 +311,13 @@ void Wiimote_InterruptChannel(u16 _channelID, const void* _pData, u32 _Size)
if (g_RealWiiMotePresent)
WiiMoteReal::InterruptChannel(_channelID, _pData, _Size);
#endif
DEBUG_LOG(WII_IPC_WIIMOTE, "=============================================================");
}
// ==============================
// ===================================================
/* Function: Used for the initial Bluetooth HID handshake. */
// ----------------
// Function: Used for the initial Bluetooth HID handshake.
void Wiimote_ControlChannel(u16 _channelID, const void* _pData, u32 _Size)
{
DEBUG_LOG(WII_IPC_WIIMOTE, "=============================================================");
const u8* data = (const u8*)_pData;
// Check for custom communication
@ -351,16 +346,11 @@ void Wiimote_ControlChannel(u16 _channelID, const void* _pData, u32 _Size)
if (g_RealWiiMotePresent)
WiiMoteReal::ControlChannel(_channelID, _pData, _Size);
#endif
DEBUG_LOG(WII_IPC_WIIMOTE, "=============================================================");
}
// ==============================
// ===================================================
/* This sends a Data Report from the Wiimote. See SystemTimers.cpp for the documentation of this
update. */
// ----------------
void Wiimote_Update()
{
// Tell us about the update rate, but only about once every second to avoid a major slowdown
@ -407,55 +397,15 @@ unsigned int Wiimote_GetAttachedControllers()
{
return 1;
}
// ================
//******************************************************************************
// Supporting functions
//******************************************************************************
// ----------------------------------------
// Debugging window
// ----------
/*
void OpenConsole(bool Open)
{
// Close the console window
#ifdef _WIN32
// if (Console::GetHwnd() != NULL && !Open)
#else
if (false)
#endif
{
// Console::Close();
// Wait here until we have let go of the button again
#ifdef _WIN32
while(GetAsyncKeyState(VK_INSERT)) {Sleep(10);}
#endif
return;
}
// Open the console window
// Console::Open(140, 1000, "Wiimote"); // give room for 20 rows
INFO_LOG(CONSOLE, "\n\nWiimote console opened\n");
// Move window
#ifdef _WIN32
//MoveWindow(Console::GetHwnd(), 0,400, 100*8,10*14, true); // small window
//MoveWindow(Console::GetHwnd(), 400,0, 100*8,70*14, true); // big window
// MoveWindow(Console::GetHwnd(), 200,0, 140*8,70*14, true); // big wide window
#endif
}*/
// ---------------
// ----------------------------------------
// Check if Dolphin is in focus
// ----------
bool IsFocus()
{
#ifdef _WIN32
@ -538,9 +488,7 @@ void ReadDebugging(bool Emu, const void* _pData, int Size)
// data[4]: Size and error
// data[5, 6]: The registry offset
// ---------------------------------------------------------------------
// Show the extension ID
// --------------------------
if ((data[4] == 0x10 || data[4] == 0x20 || data[4] == 0x50) && data[5] == 0x00 && (data[6] == 0xfa || data[6] == 0xfe))
{
if(data[4] == 0x10)
@ -590,13 +538,11 @@ void ReadDebugging(bool Emu, const void* _pData, int Size)
INFO_LOG(CONSOLE, "Game got the decrypted extension ID: %02x%02x%02x%02x%02x%02x\n\n", data[7], data[8], data[9], data[10], data[11], data[12]);
}
}
// ---------------------------------------------
// ---------------------------------------------------------------------
// Show the Wiimote neutral values
// --------------------------
/* The only difference between the Nunchuck and Wiimote that we go after is calibration here is
the offset in memory. If needed we can check the preceding 0x17 request to. */
/* The only difference between the Nunchuck and Wiimote that we go
after is calibration here is the offset in memory. If needed we can
check the preceding 0x17 request to. */
if(data[4] == 0xf0 && data[5] == 0x00 && data[6] == 0x10)
{
if(data[6] == 0x10)
@ -610,11 +556,8 @@ void ReadDebugging(bool Emu, const void* _pData, int Size)
INFO_LOG(CONSOLE, "Cal_g.z: %i\n", data[7 +12]);
}
}
// ---------------------------------------------
// ---------------------------------------------------------------------
// Show the Nunchuck neutral values
// --------------------------
if(data[4] == 0xf0 && data[5] == 0x00 && (data[6] == 0x20 || data[6] == 0x30))
{
// Save the encrypted data
@ -686,7 +629,6 @@ void ReadDebugging(bool Emu, const void* _pData, int Size)
// Show the encrypted data
INFO_LOG(CONSOLE, "%s", TmpData.c_str());
}
// ---------------------------------------------
break;
case WM_WRITE_DATA_REPLY: // 0x22
@ -733,9 +675,9 @@ void ReadDebugging(bool Emu, const void* _pData, int Size)
if (!DataReport && g_DebugComm)
{
std::string TmpData = ArrayToString(data, size + 2, 0, 30);
std::string tmpData = ArrayToString(data, size + 2, 0, 30);
//LOGV(WII_IPC_WIIMOTE, 3, " Data: %s", Temp.c_str());
INFO_LOG(CONSOLE, "Read[%s] %s: %s\n", (Emu ? "Emu" : "Real"), Name.c_str(), TmpData.c_str()); // No timestamp
INFO_LOG(CONSOLE, "Read[%s] %s: %s\n", (Emu ? "Emu" : "Real"), Name.c_str(), tmpData.c_str()); // No timestamp
//INFO_LOG(CONSOLE, " (%s): %s\n", Tm(true).c_str(), Temp.c_str()); // Timestamp
}
@ -1036,9 +978,9 @@ double GetDoubleTime()
wxDateTime datetime = wxDateTime::UNow(); // Get timestamp
u64 TmpSeconds = Common::Timer::GetTimeSinceJan1970(); // Get continous timestamp
// Remove a few years. We only really want enough seconds to make sure that we are
// detecting actual actions, perhaps 60 seconds is enough really, but I leave a
// year of seconds anyway, in case the user's clock is incorrect or something like that
/* Remove a few years. We only really want enough seconds to make sure that we are
detecting actual actions, perhaps 60 seconds is enough really, but I leave a
year of seconds anyway, in case the user's clock is incorrect or something like that */
TmpSeconds = TmpSeconds - (38 * 365 * 24 * 60 * 60);
//if (TmpSeconds < 0) return 0; // Check the the user's clock is working somewhat
@ -1092,13 +1034,14 @@ void DoInitialize()
// Run this first so that WiiMoteReal::Initialize() overwrites g_Eeprom
WiiMoteEmu::Initialize();
/* We will run WiiMoteReal::Initialize() even if we are not using a real wiimote,
to check if there is a real wiimote connected. We will initiate wiiuse.dll, but
we will return before creating a new thread for it if we find no real Wiimotes.
Then g_RealWiiMotePresent will also be false. This function call will be done
instantly whether there is a real Wiimote connected or not. It takes no time for
Wiiuse to check for connected Wiimotes. */
/* We will run WiiMoteReal::Initialize() even if we are not using a real
wiimote, to check if there is a real wiimote connected. We will initiate
wiiuse.dll, but we will return before creating a new thread for it if we
find no real Wiimotes. Then g_RealWiiMotePresent will also be
false. This function call will be done instantly whether there is a real
Wiimote connected or not. It takes no time for Wiiuse to check for
connected Wiimotes. */
#if HAVE_WIIUSE
if (g_Config.bConnectRealWiimote) WiiMoteReal::Initialize();
#endif
}
}

View File

@ -82,10 +82,6 @@ struct SRecordingAll
// Movement recording
extern std::vector<SRecordingAll> VRecording;
//#if defined(HAVE_WX) && HAVE_WX && defined(__CONFIGDIALOG_h__)
// extern ConfigDialog *frame;
//#endif
#endif

View File

@ -259,9 +259,7 @@ struct wm_GH3_extension
//******************************************************************************
// Data reports
//******************************************************************************
#define WM_REPORT_CORE 0x30
struct wm_report_core {
@ -321,9 +319,7 @@ struct wm_report_ext21
#define WM_WRITE_SPEAKER_DATA 0x18
//******************************************************************************
// Custom structs
//******************************************************************************
/**
* @struct accel_t
@ -367,4 +363,4 @@ struct gh3_cal
#pragma pack(pop)
#endif //WIIMOTE_HID_H
#endif //WIIMOTE_HID_H

View File

@ -37,14 +37,11 @@
extern SWiimoteInitialize g_WiimoteInitialize;
namespace WiiMoteReal
{
//******************************************************************************
// Forwarding
//******************************************************************************
class CWiiMote;
#ifdef _WIN32
@ -52,10 +49,9 @@ class CWiiMote;
#else
void* ReadWiimote_ThreadFunc(void* arg);
#endif
//******************************************************************************
// Variable declarations
//******************************************************************************
wiimote_t** g_WiiMotesFromWiiUse = NULL;
Common::Thread* g_pReadThread = NULL;
int g_NumberOfWiiMotes;
@ -71,17 +67,12 @@ bool g_RunTemporary = false;
int g_RunTemporaryCountdown = 0;
u8 g_EventBuffer[32];
//******************************************************************************
// Probably this class should be in its own file
//******************************************************************************
class CWiiMote
{
public:
//////////////////////////////////////////
// On create and on uncreate
// ---------------
CWiiMote(u8 _WiimoteNumber, wiimote_t* _pWiimote)
: m_WiimoteNumber(_WiimoteNumber)
, m_channelID(0)
@ -103,12 +94,9 @@ virtual ~CWiiMote()
{
delete m_pCriticalSection;
};
//////////////////////
//////////////////////////////////////////
// Queue raw HID data from the core to the wiimote
// ---------------
void SendData(u16 _channelID, const u8* _pData, u32 _Size)
{
m_channelID = _channelID;
@ -125,12 +113,9 @@ void SendData(u16 _channelID, const u8* _pData, u32 _Size)
}
m_pCriticalSection->Leave();
}
/////////////////////
//////////////////////////////////////////////////
/* Read and write data to the Wiimote */
// ---------------
void ReadData()
{
m_pCriticalSection->Enter();
@ -188,12 +173,9 @@ void ReadData()
}
}
};
/////////////////////
//////////////////////////////////////////
// Send queued data to the core
// ---------------
void Update()
{
// Thread function
@ -213,12 +195,9 @@ void Update()
m_pCriticalSection->Leave();
};
/////////////////////
//////////////////////////////////////////
// Clear events
// ---------------
void ClearEvents()
{
while (!m_EventReadQueue.empty())
@ -226,7 +205,6 @@ void ClearEvents()
while (!m_EventWriteQueue.empty())
m_EventWriteQueue.pop();
}
/////////////////////
private:
@ -249,9 +227,7 @@ private:
SEvent m_LastReport;
wiimote_t* m_pWiiMote; // This is g_WiiMotesFromWiiUse[]
//////////////////////////////////////////
// Send queued data to the core
// ---------------
void SendEvent(SEvent& _rEvent)
{
// We don't have an answer channel
@ -267,8 +243,9 @@ void SendEvent(SEvent& _rEvent)
// Create the buffer
memcpy(&Buffer[Offset], _rEvent.m_PayLoad, MAX_PAYLOAD);
/* This Offset value is not exactly correct like it is for the emulated Wiimote reports. It's
often to big, but I guess that's okay. The game will know how big the actual data is. */
/* This Offset value is not exactly correct like it is for the emulated
Wiimote reports. It's often to big, but I guess that's okay. The game
will know how big the actual data is. */
Offset += MAX_PAYLOAD;
// Send it
@ -277,14 +254,11 @@ void SendEvent(SEvent& _rEvent)
// Debugging
// ReadDebugging(false, Buffer, Offset);
}
/////////////////////
};
//******************************************************************************
// Function Definitions
//******************************************************************************
void SendAcc(u8 _ReportID)
{
@ -381,11 +355,13 @@ int Initialize()
// If we are not using the emulated wiimote we can run the thread temporary until the data has beeen copied
if(g_Config.bUseRealWiimote) g_RunTemporary = true;
/* Allocate memory and copy the Wiimote eeprom accelerometer neutral values to g_Eeprom. Unlike with
and extension we have to do this here, because this data is only read once when the Wiimote
is connected. Also, we can't change the neutral values the wiimote will report, I think, unless
we update its eeprom? In any case it's probably better to let the current calibration be where it
is and adjust the global values after that to avoid overwriting critical data on any Wiimote. */
/* Allocate memory and copy the Wiimote eeprom accelerometer neutral values
to g_Eeprom. Unlike with and extension we have to do this here, because
this data is only read once when the Wiimote is connected. Also, we
can't change the neutral values the wiimote will report, I think, unless
we update its eeprom? In any case it's probably better to let the
current calibration be where it is and adjust the global values after
that to avoid overwriting critical data on any Wiimote. */
// TODO: Update for multiple wiimotes?
byte *data = (byte*)malloc(sizeof(byte) * sizeof(WiiMoteEmu::EepromData_0));
wiiuse_read_data(g_WiiMotesFromWiiUse[0], data, 0, sizeof(WiiMoteEmu::EepromData_0));
@ -449,9 +425,7 @@ void ControlChannel(u16 _channelID, const void* _pData, u32 _Size)
}
//////////////////////////////////
// Read the Wiimote once
// ---------------
void Update()
{
//INFO_LOG(CONSOLE, "Real Update\n");
@ -461,11 +435,10 @@ void Update()
}
}
//////////////////////////////////
/* Continuously read the Wiimote status. However, the actual sending of data occurs in Update(). If we are
not currently using the real Wiimote we allow the separate ReadWiimote() function to run. Wo don't use
them at the same time to avoid a potential collision. */
// ---------------
/* Continuously read the Wiimote status. However, the actual sending of data
occurs in Update(). If we are not currently using the real Wiimote we allow
the separate ReadWiimote() function to run. Wo don't use them at the same
time to avoid a potential collision. */
#ifdef _WIN32
DWORD WINAPI ReadWiimote_ThreadFunc(void* arg)
#else
@ -477,8 +450,7 @@ void Update()
// We need g_ThreadGoing to do a manual WaitForSingleObject() from the configuration window
g_ThreadGoing = true;
if(g_Config.bUseRealWiimote && !g_RunTemporary)
for (int i = 0; i < g_NumberOfWiiMotes; i++)
g_WiiMotes[i]->ReadData();
for (int i = 0; i < g_NumberOfWiiMotes; i++) g_WiiMotes[i]->ReadData();
else
ReadWiimote();
g_ThreadGoing = false;

View File

@ -23,7 +23,6 @@
#include "wiiuse.h"
#include "ChunkFile.h"
namespace WiiMoteReal
{