Wiimote: The first working IR recording, use Alt + the numerical HotKey to play back the IR data associated with a recording
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2078 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
ace2ea395d
commit
220eafad0e
|
@ -149,14 +149,15 @@ std::string StringFromFormat(const char* format, ...)
|
|||
// ===================================================
|
||||
/* For Debugging. Read out an u8 array. */
|
||||
// ----------------
|
||||
std::string ArrayToString(const u8 *data, u32 size, u32 offset, int line_len)
|
||||
std::string ArrayToString(const u8 *data, u32 size, u32 offset, int line_len, bool Spaces)
|
||||
{
|
||||
//const u8* _data = (const u8*)data;
|
||||
std::string Temp;
|
||||
for (u32 i = 0; i < size; i++)
|
||||
{
|
||||
char Buffer[128];
|
||||
sprintf(Buffer, "%02x ", data[i + offset]);
|
||||
if (Spaces) sprintf(Buffer, "%02x ", data[i + offset]);
|
||||
else sprintf(Buffer, "%02x", data[i + offset]);
|
||||
if((i + 1) % line_len == 0) Temp.append("\n"); // break long lines
|
||||
Temp.append(Buffer);
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ void StringFromFormatV(std::string* out, const char* format, va_list args);
|
|||
bool CharArrayFromFormatV(char* out, int outsize, const char* format, va_list args);
|
||||
|
||||
// Good
|
||||
std::string ArrayToString(const u8 *data, u32 size, u32 offset = 0, int line_len = 20);
|
||||
std::string ArrayToString(const u8 *data, u32 size, u32 offset = 0, int line_len = 20, bool Spaces = true);
|
||||
|
||||
|
||||
template<size_t Count>
|
||||
|
|
|
@ -192,6 +192,10 @@ void ConfigDialog::LoadFile()
|
|||
std::string TmpGameName; file.Get(SaveName.c_str(), "GameName", &TmpGameName, "");
|
||||
m_RecordGameText[i]->SetValue(wxString::FromAscii(TmpGameName.c_str()));
|
||||
|
||||
// IR Bytes
|
||||
std::string TmpIRBytes; file.Get(SaveName.c_str(), "IRBytes", &TmpIRBytes, "");
|
||||
m_RecordIRBytesText[i]->SetValue(wxString::FromAscii(TmpIRBytes.c_str()));
|
||||
|
||||
// Recording speed
|
||||
int TmpRecordSpeed; file.Get(SaveName.c_str(), "RecordingSpeed", &TmpRecordSpeed, -1);
|
||||
if(TmpRecordSpeed != -1)
|
||||
|
@ -343,6 +347,7 @@ void ConfigDialog::CreateGUIControls()
|
|||
wxStaticBoxSizer * sbRealRoll = new wxStaticBoxSizer(wxHORIZONTAL, m_PageReal, wxT("Roll and Pitch"));
|
||||
wxStaticBoxSizer * sbRealGForce = new wxStaticBoxSizer(wxHORIZONTAL, m_PageReal, wxT("G-Force"));
|
||||
wxStaticBoxSizer * sbRealAccel = new wxStaticBoxSizer(wxHORIZONTAL, m_PageReal, wxT("Accelerometer"));
|
||||
wxStaticBoxSizer * sbRealIR = new wxStaticBoxSizer(wxHORIZONTAL, m_PageReal, wxT("IR"));
|
||||
|
||||
// Width and height of the gauges
|
||||
static const int Gw = 35, Gh = 130;
|
||||
|
@ -357,6 +362,12 @@ void ConfigDialog::CreateGUIControls()
|
|||
m_GaugeAccel[1] = new wxGauge( m_PageReal, wxID_ANY, 255, wxDefaultPosition, wxSize(Gw, Gh), wxGA_VERTICAL | wxNO_BORDER | wxGA_SMOOTH);
|
||||
m_GaugeAccel[2] = new wxGauge( m_PageReal, wxID_ANY, 255, wxDefaultPosition, wxSize(Gw, Gh), wxGA_VERTICAL | wxNO_BORDER | wxGA_SMOOTH);
|
||||
|
||||
// The text controls
|
||||
m_TextIR = new wxStaticText(m_PageReal, wxID_ANY, wxT("Cursor: 000 000\nDistance: 0000"));
|
||||
|
||||
// -----------------------------
|
||||
// The sizers for all gauges together with their label
|
||||
// -----------
|
||||
wxBoxSizer * sBoxBattery = new wxBoxSizer(wxVERTICAL);
|
||||
wxBoxSizer * sBoxRoll[2];
|
||||
sBoxRoll[0] = new wxBoxSizer(wxVERTICAL);
|
||||
|
@ -377,7 +388,11 @@ void ConfigDialog::CreateGUIControls()
|
|||
m_TextX[0] = new wxStaticText(m_PageReal, wxID_ANY, wxT("X"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); m_TextX[1] = new wxStaticText(m_PageReal, wxID_ANY, wxT("X"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
|
||||
m_TextY[0] = new wxStaticText(m_PageReal, wxID_ANY, wxT("Y"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); m_TextY[1] = new wxStaticText(m_PageReal, wxID_ANY, wxT("Y"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
|
||||
m_TextZ[0] = new wxStaticText(m_PageReal, wxID_ANY, wxT("Z"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); m_TextZ[1] = new wxStaticText(m_PageReal, wxID_ANY, wxT("Z"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
|
||||
// ----------------
|
||||
|
||||
// -----------------------------
|
||||
// Set up sizers
|
||||
// -----------
|
||||
sBoxBattery->Add(m_GaugeBattery, 0, wxEXPAND | (wxALL), 5); sBoxBattery->Add(m_TextBattery, 0, wxEXPAND | (wxALL), 0);
|
||||
|
||||
sBoxRoll[0]->Add(m_GaugeRoll[0], 0, wxEXPAND | (wxALL), 5); sBoxRoll[0]->Add(m_TextRoll, 0, wxEXPAND | (wxALL), 0);
|
||||
|
@ -395,12 +410,16 @@ void ConfigDialog::CreateGUIControls()
|
|||
sbRealRoll->Add(sBoxRoll[0], 0, wxEXPAND | (wxALL), 5); sbRealRoll->Add(sBoxRoll[1], 0, wxEXPAND | (wxALL), 5);
|
||||
sbRealGForce->Add(sBoxGForce[0], 0, wxEXPAND | (wxALL), 5); sbRealGForce->Add(sBoxGForce[1], 0, wxEXPAND | (wxALL), 5); sbRealGForce->Add(sBoxGForce[2], 0, wxEXPAND | (wxALL), 5);
|
||||
sbRealAccel->Add(sBoxAccel[0], 0, wxEXPAND | (wxALL), 5); sbRealAccel->Add(sBoxAccel[1], 0, wxEXPAND | (wxALL), 5); sbRealAccel->Add(sBoxAccel[2], 0, wxEXPAND | (wxALL), 5);
|
||||
|
||||
sbRealIR->Add(m_TextIR, 0, wxEXPAND | (wxALL), 5);
|
||||
|
||||
sbRealWiimoteStatus->Add(sbRealBattery, 0, wxEXPAND | (wxLEFT), 0);
|
||||
sbRealWiimoteStatus->Add(sbRealRoll, 0, wxEXPAND | (wxLEFT), 5);
|
||||
sbRealWiimoteStatus->Add(sbRealGForce, 0, wxEXPAND | (wxLEFT), 5);
|
||||
sbRealWiimoteStatus->Add(sbRealAccel, 0, wxEXPAND | (wxLEFT), 5);
|
||||
sbRealWiimoteStatus->Add(sbRealIR, 0, wxEXPAND | (wxLEFT), 5);
|
||||
// ----------------
|
||||
|
||||
// Tool tips
|
||||
m_GaugeBattery->SetToolTip(wxT("Press '+' to show the current status. Press '-' to stop recording the status."));
|
||||
// ==========================================
|
||||
|
||||
|
@ -423,7 +442,8 @@ void ConfigDialog::CreateGUIControls()
|
|||
wxStaticText * m_TextHotKey = new wxStaticText(m_PageReal, wxID_ANY, wxT("HotKey"), wxDefaultPosition, wxSize(40, 15), wxALIGN_CENTRE);
|
||||
wxStaticText * m_TextMovement = new wxStaticText(m_PageReal, wxID_ANY, wxT("Movement name"), wxDefaultPosition, wxSize(200, 15), wxALIGN_CENTRE);
|
||||
wxStaticText * m_TextGame = new wxStaticText(m_PageReal, wxID_ANY, wxT("Game name"), wxDefaultPosition, wxSize(200, 15), wxALIGN_CENTRE);
|
||||
wxStaticText * m_TextRecSped = new wxStaticText(m_PageReal, wxID_ANY, wxT("R. s."), wxDefaultPosition, wxSize(30, 15), wxALIGN_CENTRE);
|
||||
wxStaticText * m_TextIRBytes = new wxStaticText(m_PageReal, wxID_ANY, wxT("IR"), wxDefaultPosition, wxSize(20, 15), wxALIGN_CENTRE);
|
||||
wxStaticText * m_TextRecSped = new wxStaticText(m_PageReal, wxID_ANY, wxT("R. s."), wxDefaultPosition, wxSize(33, 15), wxALIGN_CENTRE);
|
||||
wxStaticText * m_TextPlaySpeed = new wxStaticText(m_PageReal, wxID_ANY, wxT("Pl. s."), wxDefaultPosition, wxSize(40, 15), wxALIGN_CENTRE);
|
||||
m_TextRec->SetToolTip(wxT(
|
||||
"To record a movement first press this button, then start the recording by pressing 'A' on the Wiimote and stop the recording\n"
|
||||
|
@ -444,6 +464,7 @@ void ConfigDialog::CreateGUIControls()
|
|||
sRealRecord[0]->Add(m_TextHotKey, 0, wxEXPAND | (wxLEFT), 5);
|
||||
sRealRecord[0]->Add(m_TextMovement, 0, wxEXPAND | (wxLEFT), 5);
|
||||
sRealRecord[0]->Add(m_TextGame, 0, wxEXPAND | (wxLEFT), 5);
|
||||
sRealRecord[0]->Add(m_TextIRBytes, 0, wxEXPAND | (wxLEFT), 5);
|
||||
sRealRecord[0]->Add(m_TextRecSped, 0, wxEXPAND | (wxLEFT), 5);
|
||||
sRealRecord[0]->Add(m_TextPlaySpeed, 0, wxEXPAND | (wxLEFT), 5);
|
||||
sbRealRecord->Add(sRealRecord[0], 0, wxEXPAND | (wxALL), 0);
|
||||
|
@ -455,17 +476,20 @@ void ConfigDialog::CreateGUIControls()
|
|||
m_RecordHotKey[i] = new wxChoice(m_PageReal, IDC_RECORD + i, wxDefaultPosition, wxDefaultSize, StrHotKey);
|
||||
m_RecordText[i] = new wxTextCtrl(m_PageReal, IDT_RECORD_TEXT, wxT(""), wxDefaultPosition, wxSize(200, 19));
|
||||
m_RecordGameText[i] = new wxTextCtrl(m_PageReal, IDT_RECORD_GAMETEXT, wxT(""), wxDefaultPosition, wxSize(200, 19));
|
||||
m_RecordIRBytesText[i] = new wxTextCtrl(m_PageReal, IDT_RECORD_IRBYTESTEXT, wxT(""), wxDefaultPosition, wxSize(25, 19));
|
||||
m_RecordSpeed[i] = new wxTextCtrl(m_PageReal, IDT_RECORD_SPEED, wxT(""), wxDefaultPosition, wxSize(30, 19), wxTE_READONLY | wxTE_CENTRE);
|
||||
m_RecordPlayBackSpeed[i] = new wxChoice(m_PageReal, IDT_RECORD_PLAYSPEED, wxDefaultPosition, wxDefaultSize, StrPlayBackSpeed);
|
||||
|
||||
m_RecordText[i]->SetMaxLength(35);
|
||||
m_RecordGameText[i]->SetMaxLength(35);
|
||||
m_RecordIRBytesText[i]->Enable(false);
|
||||
m_RecordSpeed[i]->Enable(false);
|
||||
|
||||
sRealRecord[i]->Add(m_RecordButton[i], 0, wxEXPAND | (wxLEFT), 5);
|
||||
sRealRecord[i]->Add(m_RecordHotKey[i], 0, wxEXPAND | (wxLEFT), 5);
|
||||
sRealRecord[i]->Add(m_RecordText[i], 0, wxEXPAND | (wxLEFT), 5);
|
||||
sRealRecord[i]->Add(m_RecordGameText[i], 0, wxEXPAND | (wxLEFT), 5);
|
||||
sRealRecord[i]->Add(m_RecordIRBytesText[i], 0, wxEXPAND | (wxLEFT), 5);
|
||||
sRealRecord[i]->Add(m_RecordSpeed[i], 0, wxEXPAND | (wxLEFT), 5);
|
||||
sRealRecord[i]->Add(m_RecordPlayBackSpeed[i], 0, wxEXPAND | (wxLEFT), 5);
|
||||
|
||||
|
@ -519,7 +543,7 @@ void ConfigDialog::ConvertToString()
|
|||
// Load ini file
|
||||
IniFile file;
|
||||
file.Load("WiimoteMovement.ini");
|
||||
std::string TmpStr = "", TmpTime = "";
|
||||
std::string TmpStr = "", TmpIR = "", TmpTime = "";
|
||||
|
||||
for (int i = 0; i < m_vRecording.size(); i++)
|
||||
{
|
||||
|
@ -529,19 +553,23 @@ void ConfigDialog::ConvertToString()
|
|||
TmpStr += StringFromFormat("%02x", m_vRecording.at(i).z);
|
||||
if(i < (m_vRecording.size() - 1)) TmpStr += ",";
|
||||
|
||||
/* 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))
|
||||
{
|
||||
break;
|
||||
PanicAlert("Your recording was to long, the entire recording was not saved.");
|
||||
}
|
||||
// Write the IR data
|
||||
TmpIR += ArrayToString(m_vRecording.at(i).IR, IRBytes, 0, 30, false);
|
||||
if(i < (m_vRecording.size() - 1)) TmpIR += ",";
|
||||
|
||||
// Write the timestamps. The upper limit is 99 seconds.
|
||||
int Time = (int)((m_vRecording.at(i).Time - m_vRecording.at(0).Time) * 1000);
|
||||
TmpTime += StringFromFormat("%05i", Time);
|
||||
if(i < (m_vRecording.size() - 1)) TmpTime += ",";
|
||||
//Console::Print("Time: %f %i\n", m_vRecording.at(i).Time, Time);
|
||||
|
||||
/* 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;
|
||||
PanicAlert("Your recording was to long, the entire recording was not saved.");
|
||||
}
|
||||
}
|
||||
|
||||
// Recordings per second
|
||||
|
@ -553,12 +581,15 @@ void ConfigDialog::ConvertToString()
|
|||
if (Time == 0 || m_vRecording.size() == 0) Rate = 0;
|
||||
|
||||
// Update GUI
|
||||
m_RecordIRBytesText[m_iRecordTo]->SetValue(wxString::Format(wxT("%i"), IRBytes));
|
||||
m_RecordSpeed[m_iRecordTo]->SetValue(wxString::Format(wxT("%i"), Rate));
|
||||
|
||||
// Save file
|
||||
std::string SaveName = StringFromFormat("Recording%i", m_iRecordTo);
|
||||
file.Set(SaveName.c_str(), "Movement", TmpStr.c_str());
|
||||
file.Set(SaveName.c_str(), "IR", TmpIR.c_str());
|
||||
file.Set(SaveName.c_str(), "Time", TmpTime.c_str());
|
||||
file.Set(SaveName.c_str(), "IRBytes", IRBytes);
|
||||
file.Set(SaveName.c_str(), "RecordingSpeed", Rate);
|
||||
|
||||
// Set a default playback speed if none is set already
|
||||
|
@ -651,8 +682,11 @@ void ConfigDialog::DoRecordA(bool Pressed)
|
|||
UpdateGUI();
|
||||
}
|
||||
|
||||
void ConfigDialog::DoRecordMovement(u8 _x, u8 _y, u8 _z)
|
||||
void ConfigDialog::DoRecordMovement(u8 _x, u8 _y, u8 _z, const u8 *_IR, int _IRBytes)
|
||||
{
|
||||
//std::string Tmp1 = ArrayToString(_IR, 20, 0, 30);
|
||||
//Console::Print("DoRecordMovement: %s\n", Tmp1.c_str());
|
||||
|
||||
if (!m_bRecording) return;
|
||||
|
||||
//Console::Print("DoRecordMovement\n");
|
||||
|
@ -662,8 +696,12 @@ void ConfigDialog::DoRecordMovement(u8 _x, u8 _y, u8 _z)
|
|||
Tmp.y = _y;
|
||||
Tmp.z = _z;
|
||||
Tmp.Time = GetDoubleTime();
|
||||
memcpy(Tmp.IR, _IR, _IRBytes);
|
||||
m_vRecording.push_back(Tmp);
|
||||
|
||||
// Save the number of IR bytes
|
||||
IRBytes = _IRBytes;
|
||||
|
||||
/* The upper limit of a recording coincides with the IniFile.cpp limit, each list element
|
||||
is 7 bytes, therefore be divide by 7 */
|
||||
if (m_vRecording.size() > (10*1024 / 7 - 2) )
|
||||
|
@ -834,8 +872,8 @@ void ConfigDialog::UpdateGUI()
|
|||
unplugged and reinserted extensions. */
|
||||
m_NunchuckConnected->SetValue(g_Config.bNunchuckConnected);
|
||||
m_ClassicControllerConnected->SetValue(g_Config.bClassicControllerConnected);
|
||||
m_NunchuckConnected->Enable(!(g_RealWiiMotePresent && g_Config.bConnectRealWiimote));
|
||||
m_ClassicControllerConnected->Enable(!(g_RealWiiMotePresent && g_Config.bConnectRealWiimote));
|
||||
m_NunchuckConnected->Enable(!(g_RealWiiMotePresent && g_Config.bConnectRealWiimote && g_EmulatorRunning));
|
||||
m_ClassicControllerConnected->Enable(!(g_RealWiiMotePresent && g_Config.bConnectRealWiimote && g_EmulatorRunning));
|
||||
|
||||
/* I have disabled this option during a running game because it's enough to be able to switch
|
||||
between using and not using then. To also use the connect option during a running game would
|
||||
|
@ -845,9 +883,6 @@ void ConfigDialog::UpdateGUI()
|
|||
m_ConnectRealWiimote->Enable(!g_EmulatorRunning);
|
||||
m_UseRealWiimote->Enable(g_RealWiiMotePresent && g_Config.bConnectRealWiimote);
|
||||
|
||||
|
||||
|
||||
|
||||
// Linux has no FindItem()
|
||||
#ifdef _WIN32
|
||||
for(int i = IDB_RECORD + 1; i < (IDB_RECORD + RECORDING_ROWS + 1); i++)
|
||||
|
|
|
@ -48,15 +48,16 @@ class ConfigDialog : public wxDialog
|
|||
void OnKeyDown(wxKeyEvent& event);
|
||||
void LoadFile(); void SaveFile();
|
||||
|
||||
// Status
|
||||
// General status
|
||||
wxStaticText * m_TextUpdateRate;
|
||||
|
||||
// Wiimote status
|
||||
wxGauge *m_GaugeBattery, *m_GaugeRoll[2], *m_GaugeGForce[3], *m_GaugeAccel[3];
|
||||
wxStaticText * m_TextIR;
|
||||
bool m_bWaitForRecording, m_bRecording, m_bAllowA;
|
||||
int m_iRecordTo;
|
||||
void RecordMovement(wxCommandEvent& event);
|
||||
void DoRecordMovement(u8 _x, u8 _y, u8 _z);
|
||||
void DoRecordMovement(u8 _x, u8 _y, u8 _z, const u8 *_IR, int IRBytes);
|
||||
void DoRecordA(bool Pressed);
|
||||
void ConvertToString();
|
||||
wxTimer *m_TimeoutTimer, *m_TimeoutATimer;
|
||||
|
@ -83,6 +84,7 @@ class ConfigDialog : public wxDialog
|
|||
wxChoice * m_RecordHotKey[RECORDING_ROWS + 1];
|
||||
wxTextCtrl * m_RecordText[RECORDING_ROWS + 1];
|
||||
wxTextCtrl * m_RecordGameText[RECORDING_ROWS + 1];
|
||||
wxTextCtrl * m_RecordIRBytesText[RECORDING_ROWS + 1];
|
||||
wxTextCtrl * m_RecordSpeed[RECORDING_ROWS + 1];
|
||||
wxChoice * m_RecordPlayBackSpeed[RECORDING_ROWS + 1];
|
||||
|
||||
|
@ -96,6 +98,7 @@ class ConfigDialog : public wxDialog
|
|||
};
|
||||
*/
|
||||
std::vector<SRecording> m_vRecording;
|
||||
int IRBytes;
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -116,7 +119,7 @@ class ConfigDialog : public wxDialog
|
|||
ID_CONNECT_REAL, ID_USE_REAL, ID_UPDATE_REAL, IDT_STATUS,
|
||||
IDB_RECORD = 2000,
|
||||
IDC_RECORD = 3000,
|
||||
IDT_RECORD_TEXT, IDT_RECORD_GAMETEXT, IDT_RECORD_SPEED, IDT_RECORD_PLAYSPEED
|
||||
IDT_RECORD_TEXT, IDT_RECORD_GAMETEXT, IDT_RECORD_IRBYTESTEXT, IDT_RECORD_SPEED, IDT_RECORD_PLAYSPEED
|
||||
};
|
||||
|
||||
void OnClose(wxCloseEvent& event);
|
||||
|
|
|
@ -185,8 +185,10 @@ void SendReportCoreAccelIr12(u16 _channelID) {
|
|||
FillReportInfo(pReport->c);
|
||||
FillReportAcc(pReport->a);
|
||||
|
||||
// We settle with emulating two objects, not all four. We leave object 2 and 3 with zero.
|
||||
// We settle with emulating two objects, not all four. We leave object 2 and 3 with 0xff.
|
||||
FillReportIR(pReport->ir[0], pReport->ir[1]);
|
||||
memset(&pReport->ir[2], 0xff, sizeof(wm_ir_extended));
|
||||
memset(&pReport->ir[3], 0xff, sizeof(wm_ir_extended));
|
||||
|
||||
LOGV(WII_IPC_WIIMOTE, 2, " SendReportCoreAccelIr12()");
|
||||
LOGV(WII_IPC_WIIMOTE, 2, " Offset: %08x", Offset);
|
||||
|
|
|
@ -56,11 +56,11 @@ namespace WiiMoteEmu
|
|||
#define wSENSOR_BAR_RADIUS 200
|
||||
|
||||
// Movement recording
|
||||
extern int g_RecordingPlaying[2];
|
||||
extern int g_RecordingCounter[2];
|
||||
extern int g_RecordingPoint[2];
|
||||
extern double g_RecordingStart[2];
|
||||
extern double g_RecordingCurrentTime[2];
|
||||
extern int g_RecordingPlaying[3];
|
||||
extern int g_RecordingCounter[3];
|
||||
extern int g_RecordingPoint[3];
|
||||
extern double g_RecordingStart[3];
|
||||
extern double g_RecordingCurrentTime[3];
|
||||
|
||||
// Registry sizes
|
||||
#define WIIMOTE_EEPROM_SIZE (16*1024)
|
||||
|
|
|
@ -126,17 +126,27 @@ void LoadRecordedMovements()
|
|||
|
||||
for(int i = 0; i < RECORDING_ROWS; i++)
|
||||
{
|
||||
// Logging
|
||||
Console::Print("Recording%i ", i + 1);
|
||||
|
||||
// Get row name
|
||||
std::string SaveName = StringFromFormat("Recording%i", i + 1);
|
||||
|
||||
// Get movement
|
||||
std::string TmpMovement; file.Get(SaveName.c_str(), "Movement", &TmpMovement, "");
|
||||
|
||||
// Get IR
|
||||
std::string TmpIR; file.Get(SaveName.c_str(), "IR", &TmpIR, "");
|
||||
|
||||
// Get time
|
||||
std::string TmpTime; file.Get(SaveName.c_str(), "Time", &TmpTime, "");
|
||||
|
||||
// Get IR bytes
|
||||
int TmpIRBytes; file.Get(SaveName.c_str(), "IRBytes", &TmpIRBytes, 0);
|
||||
VRecording.at(i).IRBytes = TmpIRBytes;
|
||||
|
||||
SRecording Tmp;
|
||||
for (int j = 0, k = 0; j < TmpMovement.length(); j+=7)
|
||||
for (int j = 0, k = 0, l = 0; j < TmpMovement.length(); j+=7)
|
||||
{
|
||||
// Skip blank savings
|
||||
if (TmpMovement.length() < 3) continue;
|
||||
|
@ -152,26 +162,62 @@ void LoadRecordedMovements()
|
|||
Tmp.y = (u8)TmpY;
|
||||
Tmp.z = (u8)TmpZ;
|
||||
|
||||
// Go to next set of time values
|
||||
double Time = (double)atoi(TmpTime.substr(k, 5).c_str());
|
||||
Tmp.Time = (double)(Time/1000);
|
||||
VRecording.at(i).Recording.push_back(Tmp);
|
||||
k += 6;
|
||||
// ---------------------------------
|
||||
// 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;
|
||||
for(int ii = 0; ii < TmpIRBytes; ii++)
|
||||
{
|
||||
if(TmpIR.length() < (k + i + TmpIRBytes)) continue; // Safety check
|
||||
std::string TmpStr = TmpIR.substr(k + ii*2, 2);
|
||||
u32 TmpU32;
|
||||
AsciiToHex(TmpStr.c_str(), TmpU32);
|
||||
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());
|
||||
Tmp.Time = (double)(Time/1000);
|
||||
l += 6;
|
||||
|
||||
// Save the values
|
||||
VRecording.at(i).Recording.push_back(Tmp);
|
||||
|
||||
// ---------------------------------
|
||||
// Log results
|
||||
// ---------
|
||||
//Console::Print("Time:%f\n", Tmp.Time);
|
||||
//std::string TmpIRLog = ArrayToString(Tmp.IR, TmpIRBytes, 0, 30);
|
||||
//Console::Print("IR: %s\n", TmpIRLog.c_str());
|
||||
//Console::Print("\n");
|
||||
}
|
||||
|
||||
// HotKey
|
||||
// Get HotKey
|
||||
int TmpRecordHotKey; file.Get(SaveName.c_str(), "HotKey", &TmpRecordHotKey, -1);
|
||||
VRecording.at(i).HotKey = TmpRecordHotKey;
|
||||
|
||||
// Recording speed
|
||||
// Get Recording speed
|
||||
int TmpPlaybackSpeed; file.Get(SaveName.c_str(), "PlaybackSpeed", &TmpPlaybackSpeed, -1);
|
||||
VRecording.at(i).PlaybackSpeed = TmpPlaybackSpeed;
|
||||
|
||||
Console::Print("Size:%i HotKey:%i Speed:%i\n",
|
||||
VRecording.at(i).Recording.size(), VRecording.at(i).HotKey, VRecording.at(i).PlaybackSpeed
|
||||
// ---------------------------------
|
||||
// Logging
|
||||
// ---------
|
||||
std::string TmpIRLog;
|
||||
if(TmpIRBytes > 0)
|
||||
TmpIRLog = ArrayToString(VRecording.at(i).Recording.at(0).IR, TmpIRBytes, 0, 30);
|
||||
else
|
||||
TmpIRLog = "";
|
||||
|
||||
Console::Print("Size:%i HotKey:%i Speed:%i IR: %s\n",
|
||||
VRecording.at(i).Recording.size(), VRecording.at(i).HotKey, VRecording.at(i).PlaybackSpeed,
|
||||
TmpIRLog.c_str()
|
||||
);
|
||||
// ---------------------
|
||||
}
|
||||
}
|
||||
// ================
|
||||
|
@ -331,22 +377,10 @@ void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size)
|
|||
for now I'm delaying all inputs. Both for status changes and Eeprom
|
||||
and registry reads and writes. */
|
||||
|
||||
// Limit the delay to certain registry reads and writes
|
||||
//if((data[1] == WM_WRITE_DATA || data[1] == WM_READ_DATA)
|
||||
// && data[3] == 0xa4)
|
||||
//{
|
||||
// There are no 0x22 replys to these report from the real wiimote
|
||||
if(!(data[1] == WM_READ_DATA && data[2] == 0x00)
|
||||
&& !(data[1] == WM_REQUEST_STATUS)
|
||||
)
|
||||
if (!g_Config.bUseRealWiimote || !g_RealWiiMotePresent) CreateAckDelay((u8)_channelID, (u16)sr->channel);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
//wm_write_data *wd = (wm_write_data*)sr->data;
|
||||
//u32 address = convert24bit(wd->address);
|
||||
//WmSendAck(_channelID, sr->channel, address);
|
||||
//}
|
||||
// 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
|
||||
if(!(data[1] == WM_READ_DATA && data[2] == 0x00) && !(data[1] == WM_REQUEST_STATUS))
|
||||
if (!g_Config.bUseRealWiimote || !g_RealWiiMotePresent) CreateAckDelay((u8)_channelID, (u16)sr->channel);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -43,28 +43,29 @@ namespace WiiMoteEmu
|
|||
{
|
||||
|
||||
|
||||
//******************************************************************************
|
||||
//**************************************************************************************
|
||||
// Recorded movements
|
||||
//******************************************************************************
|
||||
//**************************************************************************************
|
||||
|
||||
// ------------------------------------------
|
||||
// Variables: 0 = Wiimote, 1 = Nunchuck
|
||||
// ----------------
|
||||
int g_RecordingPlaying[2]; //g_RecordingPlaying[0] = -1; g_RecordingPlaying[1] = -1;
|
||||
int g_RecordingCounter[2]; //g_RecordingCounter[0] = 0; g_RecordingCounter[1] = 0;
|
||||
int g_RecordingPoint[2]; //g_RecordingPoint[0] = 0; g_RecordingPoint[1] = 0;
|
||||
double g_RecordingStart[2]; //g_RecordingStart[0] = 0; g_RecordingStart[1] = 0;
|
||||
double g_RecordingCurrentTime[2]; //g_RecordingCurrentTime[0] = 0; g_RecordingCurrentTime[1] = 0;
|
||||
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;
|
||||
// --------------------------
|
||||
|
||||
void RecordingPlay(u8 &_x, u8 &_y, u8 &_z, int Wm)
|
||||
template<class IRReportType>
|
||||
bool RecordingPlayAccIR(u8 &_x, u8 &_y, u8 &_z, IRReportType &_IR, int Wm)
|
||||
{
|
||||
// Return if the list is empty
|
||||
if(VRecording.at(g_RecordingPlaying[Wm]).Recording.size() == 0)
|
||||
{
|
||||
g_RecordingPlaying[Wm] = -1;
|
||||
Console::Print("Empty\n\n");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return if the playback speed is unset
|
||||
|
@ -72,7 +73,22 @@ void RecordingPlay(u8 &_x, u8 &_y, u8 &_z, int Wm)
|
|||
{
|
||||
Console::Print("PlaybackSpeed empty: %i\n\n", g_RecordingPlaying[Wm]);
|
||||
g_RecordingPlaying[Wm] = -1;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get IR bytes
|
||||
int IRBytes = VRecording.at(g_RecordingPlaying[Wm]).IRBytes;
|
||||
|
||||
// Return if the IR mode is wrong
|
||||
if (Wm == WM_RECORDING_IR
|
||||
&& ( (IRBytes == 12 && !(g_ReportingMode == 0x33))
|
||||
|| (IRBytes == 10 && !(g_ReportingMode == 0x36 || g_ReportingMode == 0x37))
|
||||
)
|
||||
)
|
||||
{
|
||||
Console::Print("Wrong IR mode: %i\n\n", g_RecordingPlaying[Wm]);
|
||||
g_RecordingPlaying[Wm] = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get starting time
|
||||
|
@ -106,13 +122,14 @@ void RecordingPlay(u8 &_x, u8 &_y, u8 &_z, int Wm)
|
|||
g_RecordingStart[Wm] = 0;
|
||||
g_RecordingCurrentTime[Wm] = 0;
|
||||
Console::Print("End\n\n");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Update values
|
||||
_x = VRecording.at(g_RecordingPlaying[Wm]).Recording.at(g_RecordingPoint[Wm]).x;
|
||||
_y = VRecording.at(g_RecordingPlaying[Wm]).Recording.at(g_RecordingPoint[Wm]).y;
|
||||
_z = VRecording.at(g_RecordingPlaying[Wm]).Recording.at(g_RecordingPoint[Wm]).z;
|
||||
if(Wm == WM_RECORDING_IR) memcpy(&_IR, VRecording.at(g_RecordingPlaying[Wm]).Recording.at(g_RecordingPoint[Wm]).IR, IRBytes);
|
||||
|
||||
/**/
|
||||
if (g_DebugAccelerometer)
|
||||
|
@ -124,25 +141,53 @@ void RecordingPlay(u8 &_x, u8 &_y, u8 &_z, int Wm)
|
|||
);
|
||||
Console::Print("Accel x, y, z: %03u %03u %03u\n\n", _x, _y, _z);
|
||||
}
|
||||
|
||||
|
||||
g_RecordingCounter[Wm]++;
|
||||
|
||||
return true;
|
||||
}
|
||||
/* Because the playback is neatly controlled by RecordingPlayAccIR() we use these functions to be able to
|
||||
use RecordingPlayAccIR() for both accelerometer and IR recordings */
|
||||
bool RecordingPlay(u8 &_x, u8 &_y, u8 &_z, int Wm)
|
||||
{
|
||||
wm_ir_basic IR;
|
||||
return RecordingPlayAccIR(_x, _y, _z, IR, Wm);
|
||||
}
|
||||
template<class IRReportType>
|
||||
bool RecordingPlayIR(IRReportType &_IR)
|
||||
{
|
||||
u8 x, y, z;
|
||||
return RecordingPlayAccIR(x, y, z, _IR, 2);
|
||||
}
|
||||
|
||||
// Check if we should play a recording
|
||||
int RecordingCheckKeys(bool Wiimote)
|
||||
// Check if we should start the playback of a recording. Once it has been started it can not currently
|
||||
// be stopped, it will always run to the end of the recording.
|
||||
int RecordingCheckKeys(int Wiimote)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
//Console::Print("RecordingCheckKeys\n");
|
||||
//Console::Print("RecordingCheckKeys: %i\n", Wiimote);
|
||||
|
||||
// Return if we don't have both a Shift and Ctrl
|
||||
// ------------------------------------
|
||||
// Don't allow multiple action keys
|
||||
// --------------
|
||||
// Return if we have both a Shift, Ctrl, and Alt
|
||||
if ( GetAsyncKeyState(VK_SHIFT) && GetAsyncKeyState(VK_CONTROL) && GetAsyncKeyState(VK_MENU) ) return -1;
|
||||
// Return if we have both a Shift and Ctrl
|
||||
if ( (GetAsyncKeyState(VK_SHIFT) && GetAsyncKeyState(VK_CONTROL)) ) return -1;
|
||||
// Return if we have both a Ctrl and Alt
|
||||
if ( (GetAsyncKeyState(VK_CONTROL) && GetAsyncKeyState(VK_MENU)) ) return -1;
|
||||
// Return if we have both a Shift and Alt
|
||||
if ( (GetAsyncKeyState(VK_SHIFT) && GetAsyncKeyState(VK_MENU)) ) return -1;
|
||||
// ---------------------
|
||||
|
||||
// Return if we don't have both a Wiimote and Shift
|
||||
if ( Wiimote && !GetAsyncKeyState(VK_SHIFT) ) return -1;
|
||||
if ( Wiimote == 0 && !GetAsyncKeyState(VK_SHIFT) ) return -1;
|
||||
|
||||
// Return if we don't have both a Nunchuck and Ctrl
|
||||
if ( !Wiimote && !GetAsyncKeyState(VK_CONTROL) ) return -1;
|
||||
if ( Wiimote == 1 && !GetAsyncKeyState(VK_CONTROL) ) return -1;
|
||||
|
||||
// Return if we don't have both a IR call and Alt
|
||||
if ( Wiimote == 2 && !GetAsyncKeyState(VK_MENU) ) return -1;
|
||||
|
||||
// Check if we have exactly one numerical key
|
||||
int Keys = 0;
|
||||
|
@ -279,13 +324,13 @@ void FillReportAcc(wm_accel& _acc)
|
|||
// Check for a playback command
|
||||
if(g_RecordingPlaying[0] < 0)
|
||||
{
|
||||
g_RecordingPlaying[0] = RecordingCheckKeys(true);
|
||||
g_RecordingPlaying[0] = RecordingCheckKeys(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
RecordingPlay(_acc.x, _acc.y, _acc.z, 0);
|
||||
// If the recording reached the end or failed somehow we will not return
|
||||
if (RecordingPlay(_acc.x, _acc.y, _acc.z, 0)) return;
|
||||
//Console::Print("X, Y, Z: %u %u %u\n", _acc.x, _acc.y, _acc.z);
|
||||
if (_acc.x != 0 && _acc.y != 0 && _acc.z != 0) return;
|
||||
}
|
||||
// ---------------------
|
||||
|
||||
|
@ -481,10 +526,27 @@ void FillReportAcc(wm_accel& _acc)
|
|||
// ---------------
|
||||
void FillReportIR(wm_ir_extended& _ir0, wm_ir_extended& _ir1)
|
||||
{
|
||||
// ------------------------------------
|
||||
// Recorded movements
|
||||
// --------------
|
||||
// Check for a playback command
|
||||
if(g_RecordingPlaying[2] < 0)
|
||||
{
|
||||
g_RecordingPlaying[2] = RecordingCheckKeys(2);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Console::Print("X, Y, Z: %u %u %u\n", _acc.x, _acc.y, _acc.z);
|
||||
if (RecordingPlayIR(_ir0)) return;
|
||||
}
|
||||
// ---------------------
|
||||
|
||||
/* DESCRIPTION: The calibration is controlled by these values, their absolute value and
|
||||
the relative distance between between them control the calibration. WideScreen mode
|
||||
has its own settings. */
|
||||
|
||||
// --------------------------------------
|
||||
/* The calibration is controlled by these values, their absolute value and
|
||||
the relative distance between between them control the calibration. WideScreen mode
|
||||
has its own settings. */
|
||||
// ----------
|
||||
int Top, Left, Right, Bottom, SensorBarRadius;
|
||||
if(g_Config.bWideScreen)
|
||||
{
|
||||
|
@ -496,9 +558,10 @@ void FillReportIR(wm_ir_extended& _ir0, wm_ir_extended& _ir1)
|
|||
Top = TOP; Left = LEFT; Right = RIGHT;
|
||||
Bottom = BOTTOM; SensorBarRadius = SENSOR_BAR_RADIUS;
|
||||
}
|
||||
// ------------------
|
||||
|
||||
/* Fill with 0xff if empty. The real Wiimote seems to use 0xff when it sees to ojbects, 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));
|
||||
|
||||
|
@ -508,6 +571,9 @@ 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;
|
||||
|
||||
// --------------------------------------
|
||||
// Actual position calculation
|
||||
// ----------
|
||||
int y0 = Top + (MouseY * (Bottom - Top));
|
||||
int y1 = Top + (MouseY * (Bottom - Top));
|
||||
|
||||
|
@ -527,7 +593,7 @@ void FillReportIR(wm_ir_extended& _ir0, wm_ir_extended& _ir1)
|
|||
_ir1.size = 10;
|
||||
_ir1.xHi = x1 >> 8;
|
||||
_ir1.yHi = y1 >> 8;
|
||||
|
||||
// ------------------
|
||||
|
||||
// ----------------------------
|
||||
// Debugging for calibration
|
||||
|
@ -565,14 +631,33 @@ void FillReportIR(wm_ir_extended& _ir0, wm_ir_extended& _ir1)
|
|||
_ir0.y, _ir0.yHi, _ir1.y, _ir1.yHi,
|
||||
_ir0.size, _ir1.size
|
||||
);*/
|
||||
// ------------------
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// The extended 10 byte reporting
|
||||
// The 10 byte reporting used when an extension is connected
|
||||
// ---------------
|
||||
void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1)
|
||||
{
|
||||
/* See description above */
|
||||
// ------------------------------------
|
||||
// Recorded movements
|
||||
// --------------
|
||||
// Check for a playback command
|
||||
if(g_RecordingPlaying[2] < 0)
|
||||
{
|
||||
g_RecordingPlaying[2] = RecordingCheckKeys(2);
|
||||
}
|
||||
// We are playing back a recording, we don't accept any manual input this time
|
||||
else
|
||||
{
|
||||
//Console::Print("X, Y, Z: %u %u %u\n", _acc.x, _acc.y, _acc.z);
|
||||
if (RecordingPlayIR(_ir0)) return;
|
||||
}
|
||||
// ---------------------
|
||||
|
||||
// --------------------------------------
|
||||
/* See calibration description above */
|
||||
// ----------
|
||||
int Top, Left, Right, Bottom, SensorBarRadius;
|
||||
|
||||
if(g_Config.bWideScreen)
|
||||
|
@ -585,6 +670,7 @@ void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1)
|
|||
Top = TOP; Left = LEFT; Right = RIGHT;
|
||||
Bottom = BOTTOM; SensorBarRadius = SENSOR_BAR_RADIUS;
|
||||
}
|
||||
// ------------------
|
||||
|
||||
// Fill with 0xff if empty
|
||||
memset(&_ir0, 0xff, sizeof(wm_ir_basic));
|
||||
|
@ -602,8 +688,7 @@ void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1)
|
|||
int x1 = Left + (MouseX * (Right - Left)) - SensorBarRadius;
|
||||
int x2 = Left + (MouseX * (Right - Left)) + SensorBarRadius;
|
||||
|
||||
/* As with the extented report we settle with emulating two out of four
|
||||
possible objects */
|
||||
/* As with the extented report we settle with emulating two out of four possible objects */
|
||||
x1 = 1023 - x1;
|
||||
_ir0.x1 = x1 & 0xff;
|
||||
_ir0.y1 = y1 & 0xff;
|
||||
|
@ -620,10 +705,10 @@ void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1)
|
|||
//_ir1.x1Hi = (x1 >> 8) & 0x3;
|
||||
//_ir1.y1Hi = (y1 >> 8) & 0x3;
|
||||
|
||||
// ----------------------------
|
||||
// ------------------------------------
|
||||
// Debugging for calibration
|
||||
// ----------
|
||||
|
||||
// ----------
|
||||
/*
|
||||
if(GetAsyncKeyState(VK_NUMPAD1))
|
||||
Right +=1;
|
||||
else if(GetAsyncKeyState(VK_NUMPAD2))
|
||||
|
@ -644,7 +729,7 @@ void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1)
|
|||
SensorBarRadius += 1;
|
||||
else if(GetAsyncKeyState(VK_DELETE))
|
||||
SensorBarRadius -= 1;
|
||||
/*
|
||||
|
||||
//ClearScreen();
|
||||
//if(consoleDisplay == 1)
|
||||
|
||||
|
@ -658,53 +743,56 @@ void FillReportIRBasic(wm_ir_basic& _ir0, wm_ir_basic& _ir1)
|
|||
_ir1.x1, _ir1.x1Hi, _ir1.x2, _ir1.x2Hi,
|
||||
_ir1.y1, _ir1.y1Hi, _ir1.y2, _ir1.y2Hi
|
||||
);*/
|
||||
// ------------------
|
||||
}
|
||||
|
||||
int abc = 0;
|
||||
|
||||
//**************************************************************************************
|
||||
// Extensions
|
||||
//**************************************************************************************
|
||||
|
||||
|
||||
// ===================================================
|
||||
/* Generate the 6 byte extension report for the Nunchuck, encrypted. The bytes are JX JY AX AY AZ BT. */
|
||||
// ----------------
|
||||
void FillReportExtension(wm_extension& _ext)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
// ------------------------------------
|
||||
// Recorded movements
|
||||
// --------------
|
||||
// Check for a playback command
|
||||
if(g_RecordingPlaying[1] < 0)
|
||||
{
|
||||
g_RecordingPlaying[1] = RecordingCheckKeys(false);
|
||||
g_RecordingPlaying[1] = RecordingCheckKeys(1);
|
||||
|
||||
}
|
||||
// We should play back the accelerometer values
|
||||
else
|
||||
{
|
||||
RecordingPlay(_ext.ax, _ext.ay, _ext.az, 1);
|
||||
//Console::Print("X: %u\n", _acc.x);
|
||||
return;
|
||||
//
|
||||
if (!RecordingPlay(_ext.ax, _ext.ay, _ext.az, 1))
|
||||
{
|
||||
/* These are the default neutral values for the nunchuck accelerometer according to the calibration
|
||||
data we have in nunchuck_calibration[] */
|
||||
_ext.ax = 0x80;
|
||||
_ext.ay = 0x80;
|
||||
_ext.az = 0xb3;
|
||||
}
|
||||
}
|
||||
// ---------------------
|
||||
#endif
|
||||
|
||||
/* These are the default neutral values for the nunchuck accelerometer according
|
||||
to a source. */
|
||||
_ext.ax = 0x80;
|
||||
_ext.ay = 0x80;
|
||||
_ext.az = 0xb3;
|
||||
|
||||
|
||||
_ext.ax += abc;
|
||||
|
||||
abc ++;
|
||||
if (abc > 50) abc = 0;
|
||||
|
||||
|
||||
_ext.jx = 0x80; // these are the default values unless we use them
|
||||
// ------------------------------------
|
||||
// The default joystick and button values unless we use them
|
||||
// --------------
|
||||
_ext.jx = 0x80;
|
||||
_ext.jy = 0x80;
|
||||
_ext.bt = 0x03; // 0x03 means no button pressed, the button is zero active
|
||||
|
||||
// ---------------------
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
/* We use a 192 range (32 to 224) that match our calibration values in
|
||||
nunchuck_calibration */
|
||||
/* We use a 192 range (32 to 224) that match our calibration values in nunchuck_calibration[] */
|
||||
if(GetAsyncKeyState(VK_NUMPAD4)) // left
|
||||
_ext.jx = 0x20;
|
||||
|
||||
|
|
|
@ -53,12 +53,30 @@ void handle_ctrl_status(struct wiimote_t* wm)
|
|||
printf("battery: %f %%\n", wm->battery_level);
|
||||
}
|
||||
|
||||
|
||||
bool IRDataOK(struct wiimote_t* wm)
|
||||
{
|
||||
//Console::Print("IRDataOK: ");
|
||||
// The report size is 0x33 = 18, 0x37 = 22 withouth the leading (a1) byte
|
||||
int ReportSize; if(WIIUSE_USING_EXP(wm)) ReportSize = 22; else ReportSize = 18;
|
||||
for(int i = 0; i < ReportSize; i++)
|
||||
{
|
||||
//Console::Print("%02x ", wm->event_buf[i]);
|
||||
if (wm->event_buf[i] > 0)
|
||||
{
|
||||
//Console::Print("\n");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void handle_event(struct wiimote_t* wm)
|
||||
{
|
||||
printf("\n\n--- EVENT [id %i] ---\n", wm->unid);
|
||||
|
||||
/* if a button is pressed, report it */
|
||||
//if (IS_PRESSED(wm, WIIMOTE_BUTTON_A)) Console::Print("A pressed\n");
|
||||
if (IS_PRESSED(wm, WIIMOTE_BUTTON_A)) Console::Print("A pressed\n");
|
||||
if (IS_PRESSED(wm, WIIMOTE_BUTTON_B)) Console::Print("B pressed\n");
|
||||
if (IS_PRESSED(wm, WIIMOTE_BUTTON_UP)) Console::Print("UP pressed\n");
|
||||
if (IS_PRESSED(wm, WIIMOTE_BUTTON_DOWN)) Console::Print("DOWN pressed\n");
|
||||
|
@ -78,22 +96,19 @@ void handle_event(struct wiimote_t* wm)
|
|||
if (IS_JUST_PRESSED(wm, WIIMOTE_BUTTON_MINUS))
|
||||
{
|
||||
wiiuse_motion_sensing(wm, 0);
|
||||
wiiuse_set_ir(wm, 0);
|
||||
g_MotionSensing = false;
|
||||
}
|
||||
/*
|
||||
* Pressing plus will tell the wiimote we are interested in movement.
|
||||
*/
|
||||
// Turn aceelerometer and IR reporting on, there is some kind of bug that prevents us from turing these on
|
||||
// directly after each other, so we have to wait for another wiiuse_poll() this way
|
||||
if (IS_JUST_PRESSED(wm, WIIMOTE_BUTTON_PLUS))
|
||||
{
|
||||
wiiuse_motion_sensing(wm, 1);
|
||||
g_MotionSensing = true;
|
||||
}
|
||||
|
||||
// Turn IR reporting on and off
|
||||
if (IS_JUST_PRESSED(wm, WIIMOTE_BUTTON_UP))
|
||||
// Turn IR reporting on
|
||||
if (g_MotionSensing && !WIIUSE_USING_IR(wm))
|
||||
wiiuse_set_ir(wm, 1);
|
||||
if (IS_JUST_PRESSED(wm, WIIMOTE_BUTTON_DOWN))
|
||||
wiiuse_set_ir(wm, 0);
|
||||
|
||||
/* Print battery status */
|
||||
if(frame)
|
||||
|
@ -101,15 +116,42 @@ void handle_event(struct wiimote_t* wm)
|
|||
frame->m_GaugeBattery->SetValue((int)floor((wm->battery_level * 100) + 0.5));
|
||||
|
||||
/* If the accelerometer is turned on then print angles */
|
||||
if (WIIUSE_USING_ACC(wm))
|
||||
if (WIIUSE_USING_ACC(wm) && WIIUSE_USING_IR(wm))
|
||||
{
|
||||
|
||||
std::string Tmp;
|
||||
Tmp += StringFromFormat("Roll: %2.1f ", wm->orient.roll);
|
||||
Tmp += StringFromFormat("Pitch: %2.1f ", wm->orient.pitch);
|
||||
Tmp += StringFromFormat("Battery: %1.2f\n", wm->battery_level);
|
||||
Tmp += StringFromFormat("G-Force x, y, z: %1.2f %1.2f %1.2f\n", wm->gforce.x, wm->gforce.y, wm->gforce.z);
|
||||
Tmp += StringFromFormat("Accel x, y, z: %03i %03i %03i\n\n", wm->accel.x, wm->accel.y, wm->accel.z);
|
||||
Tmp += StringFromFormat("Accel x, y, z: %03i %03i %03i\n", wm->accel.x, wm->accel.y, wm->accel.z);
|
||||
|
||||
// The report size is 0x33 = 18, 0x37 = 22
|
||||
int ReportSize; if(WIIUSE_USING_EXP(wm)) ReportSize = 22; else ReportSize = 18;
|
||||
|
||||
// wm->event_buf is cleared at the end of all wiiuse_poll(), so wm->event_buf will always be zero
|
||||
// after that. To get the raw IR data we need to read the wiimote again. This seems to work most of the time,
|
||||
// it seems to fails with a regular interval about each tenth read.
|
||||
if(wiiuse_io_read(wm))
|
||||
{
|
||||
// Check that it's not zero
|
||||
if (IRDataOK(wm)) memcpy(g_EventBuffer, wm->event_buf, ReportSize);
|
||||
}
|
||||
|
||||
// Go through each of the 4 possible IR sources
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
// Check if the source is visible
|
||||
if (wm->ir.dot[i].visible)
|
||||
Tmp += StringFromFormat("IR source %i: (%u, %u)\n", i, wm->ir.dot[i].x, wm->ir.dot[i].y);
|
||||
}
|
||||
|
||||
Tmp += StringFromFormat("IR cursor: (%u, %u)\n", wm->ir.x, wm->ir.y);
|
||||
Tmp += StringFromFormat("IR z distance: %f\n", wm->ir.z);
|
||||
std::string TmpData = ArrayToString(g_EventBuffer, ReportSize, 0, 30);
|
||||
Tmp += "Data: " + TmpData;
|
||||
|
||||
Console::ClearScreen();
|
||||
Console::Print("%s\n\n", Tmp.c_str());
|
||||
|
||||
if(frame)
|
||||
{
|
||||
|
@ -129,11 +171,19 @@ void handle_event(struct wiimote_t* wm)
|
|||
frame->m_GaugeAccel[1]->SetValue(wm->accel.y);
|
||||
frame->m_GaugeAccel[2]->SetValue(wm->accel.z);
|
||||
|
||||
frame->m_TextIR->SetLabel(wxString::Format(
|
||||
"Cursor: %03u %03u\nDistance:%4.0f", wm->ir.x, wm->ir.y, wm->ir.z));
|
||||
|
||||
if(frame->m_bRecording)
|
||||
Console::Print("Wiiuse Recorded accel x, y, z: %03i %03i %03i\n", wm->accel.x, wm->accel.y, wm->accel.z);
|
||||
}
|
||||
|
||||
// Send the data to be saved
|
||||
//const u8* data = (const u8*)wm->event_buf;
|
||||
frame->DoRecordMovement(wm->accel.x, wm->accel.y, wm->accel.z, (g_EventBuffer + 6),
|
||||
(WIIUSE_USING_EXP(wm) ? 10 : 12));
|
||||
|
||||
frame->DoRecordMovement(wm->accel.x, wm->accel.y, wm->accel.z);
|
||||
// Turn recording on and off
|
||||
if (IS_PRESSED(wm, WIIMOTE_BUTTON_A)) frame->DoRecordA(true);
|
||||
else frame->DoRecordA(false);
|
||||
}
|
||||
|
@ -143,43 +193,20 @@ void handle_event(struct wiimote_t* wm)
|
|||
{
|
||||
if (frame)
|
||||
{
|
||||
frame->m_GaugeRoll[0]->SetValue(0);
|
||||
frame->m_GaugeRoll[1]->SetValue(0);
|
||||
|
||||
frame->m_GaugeGForce[0]->SetValue(0);
|
||||
frame->m_GaugeGForce[1]->SetValue(0);
|
||||
frame->m_GaugeGForce[2]->SetValue(0);
|
||||
|
||||
frame->m_GaugeAccel[0]->SetValue(0);
|
||||
frame->m_GaugeAccel[1]->SetValue(0);
|
||||
frame->m_GaugeAccel[2]->SetValue(0);
|
||||
|
||||
frame->m_TextIR->SetLabel(wxT("Cursor:\nDistance:"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* If IR tracking is enabled then print the coordinates
|
||||
* on the virtual screen that the wiimote is pointing to.
|
||||
*
|
||||
* Also make sure that we see at least 1 dot.
|
||||
*/
|
||||
if (IS_JUST_PRESSED(wm, WIIMOTE_BUTTON_UP))
|
||||
wiiuse_set_ir(wm, 1);
|
||||
if (IS_JUST_PRESSED(wm, WIIMOTE_BUTTON_DOWN))
|
||||
wiiuse_set_ir(wm, 0);
|
||||
|
||||
if (WIIUSE_USING_IR(wm))
|
||||
{
|
||||
/*Console::ClearScreen();
|
||||
|
||||
// Go through each of the 4 possible IR sources
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
// Check if the source is visible
|
||||
if (wm->ir.dot[i].visible)
|
||||
Console::Print("IR source %i: (%u, %u)\n", i, wm->ir.dot[i].x, wm->ir.dot[i].y);
|
||||
}
|
||||
|
||||
Console::Print("IR cursor: (%u, %u)\n", wm->ir.x, wm->ir.y);
|
||||
Console::Print("IR z distance: %f\n", wm->ir.z);
|
||||
|
||||
const byte* pBuffer = wm->event_buf;
|
||||
std::string Temp = ArrayToString(pBuffer, 20, 0, 30);
|
||||
Console::Print("Data: %s\n", Temp.c_str());*/
|
||||
}
|
||||
}
|
||||
|
||||
void ReadWiimote()
|
||||
|
@ -246,13 +273,13 @@ void ReadWiimote()
|
|||
break;
|
||||
|
||||
case WIIUSE_CLASSIC_CTRL_INSERTED:
|
||||
//printf("Classic controller inserted.\n");
|
||||
Console::Print("Classic controller inserted.\n");
|
||||
break;
|
||||
|
||||
case WIIUSE_GUITAR_HERO_3_CTRL_INSERTED:
|
||||
/* some expansion was inserted */
|
||||
//handle_ctrl_status(wiimotes[i]);
|
||||
printf("Guitar Hero 3 controller inserted.\n");
|
||||
Console::Print("Guitar Hero 3 controller inserted.\n");
|
||||
break;
|
||||
|
||||
case WIIUSE_NUNCHUK_REMOVED:
|
||||
|
@ -260,7 +287,7 @@ void ReadWiimote()
|
|||
case WIIUSE_GUITAR_HERO_3_CTRL_REMOVED:
|
||||
/* some expansion was removed */
|
||||
//handle_ctrl_status(wiimotes[i]);
|
||||
printf("An expansion was removed.\n");
|
||||
Console::Print("An expansion was removed.\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -46,18 +46,23 @@ bool IsFocus();
|
|||
|
||||
// Movement recording
|
||||
#define RECORDING_ROWS 15
|
||||
#define WM_RECORDING_WIIMOTE 0
|
||||
#define WM_RECORDING_NUNCHUCK 1
|
||||
#define WM_RECORDING_IR 2
|
||||
struct SRecording
|
||||
{
|
||||
u8 x;
|
||||
u8 y;
|
||||
u8 z;
|
||||
double Time;
|
||||
u8 IR[12];
|
||||
};
|
||||
struct SRecordingAll
|
||||
{
|
||||
std::vector<SRecording> Recording;
|
||||
int HotKey;
|
||||
int PlaybackSpeed;
|
||||
int IRBytes;
|
||||
};
|
||||
|
||||
#ifndef EXCLUDEMAIN_H
|
||||
|
|
|
@ -154,7 +154,7 @@ struct wm_accel {
|
|||
u8 x, y, z;
|
||||
};
|
||||
|
||||
//filled with 0xFF if empty
|
||||
// Filled with 0xFF if empty
|
||||
struct wm_ir_basic
|
||||
{
|
||||
u8 x1;
|
||||
|
|
|
@ -70,10 +70,12 @@ int g_NumberOfWiiMotes;
|
|||
CWiiMote* g_WiiMotes[MAX_WIIMOTES];
|
||||
bool g_Shutdown = false;
|
||||
bool g_LocalThread = true;
|
||||
bool g_IRSensing = false;
|
||||
bool g_MotionSensing = false;
|
||||
u64 g_UpdateTime = 0;
|
||||
int g_UpdateCounter = 0;
|
||||
bool g_RunTemporary = false;
|
||||
u8 g_EventBuffer[32];
|
||||
|
||||
//******************************************************************************
|
||||
// Probably this class should be in its own file
|
||||
|
|
|
@ -48,9 +48,11 @@ void ReadWiimote();
|
|||
extern wiimote_t** g_WiiMotesFromWiiUse;
|
||||
extern int g_NumberOfWiiMotes;
|
||||
extern bool g_MotionSensing;
|
||||
extern bool g_IRSensing;
|
||||
extern u64 g_UpdateTime;
|
||||
extern int g_UpdateCounter;
|
||||
extern bool g_RunTemporary;
|
||||
extern u8 g_EventBuffer[32];
|
||||
#endif
|
||||
|
||||
}; // WiiMoteReal
|
||||
|
|
Loading…
Reference in New Issue