Wiimote: Switch between emulated and real Wiimote during gameplay.
Notice: It's currently not very user friendly and can crash or fail under some circumstances. I'll make it better momentarily. You currently have to first open the Wiimote config window and the start a game to be able to use switch back and forth after that. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2011 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
c9ca6ef55a
commit
8eeb1d0202
|
@ -407,26 +407,24 @@ THREAD_RETURN EmuThread(void *pArg)
|
||||||
|
|
||||||
if (!_CoreParameter.bUseDualCore)
|
if (!_CoreParameter.bUseDualCore)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
cpuThread = new Common::Thread(CpuThread, pArg);
|
cpuThread = new Common::Thread(CpuThread, pArg);
|
||||||
//Common::SetCurrentThreadName("Idle thread");
|
//Common::SetCurrentThreadName("Idle thread");
|
||||||
//TODO(ector) : investigate using GetMessage instead .. although
|
//TODO(ector) : investigate using GetMessage instead .. although
|
||||||
//then we lose the powerdown check. ... unless powerdown sends a message :P
|
//then we lose the powerdown check. ... unless powerdown sends a message :P
|
||||||
while (PowerPC::state != PowerPC::CPU_POWERDOWN)
|
while (PowerPC::state != PowerPC::CPU_POWERDOWN)
|
||||||
{
|
{
|
||||||
if (Callback_PeekMessages) {
|
if (Callback_PeekMessages) Callback_PeekMessages();
|
||||||
Callback_PeekMessages();
|
Common::SleepCurrentThread(20);
|
||||||
}
|
}
|
||||||
Common::SleepCurrentThread(20);
|
#else
|
||||||
}
|
// In single-core mode, the Emulation main thread is also the CPU thread
|
||||||
#else
|
CpuThread(pArg);
|
||||||
// In single-core mode, the Emulation main thread is also the CPU thread
|
#endif
|
||||||
CpuThread(pArg);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Plugins.GetVideo()->Video_Prepare(); //wglMakeCurrent
|
Plugins.GetVideo()->Video_Prepare(); // wglMakeCurrent
|
||||||
cpuThread = new Common::Thread(CpuThread, pArg);
|
cpuThread = new Common::Thread(CpuThread, pArg);
|
||||||
Common::SetCurrentThreadName("Video thread");
|
Common::SetCurrentThreadName("Video thread");
|
||||||
Plugins.GetVideo()->Video_EnterLoop();
|
Plugins.GetVideo()->Video_EnterLoop();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="Windows-1252"?>
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
<VisualStudioProject
|
<VisualStudioProject
|
||||||
ProjectType="Visual C++"
|
ProjectType="Visual C++"
|
||||||
Version="9.00"
|
Version="9,00"
|
||||||
Name="Plugin_Wiimote"
|
Name="Plugin_Wiimote"
|
||||||
ProjectGUID="{8D612734-FAA5-4B8A-804F-4DEA2367D495}"
|
ProjectGUID="{8D612734-FAA5-4B8A-804F-4DEA2367D495}"
|
||||||
RootNamespace="Plugin_Wiimote"
|
RootNamespace="Plugin_Wiimote"
|
||||||
|
@ -515,14 +515,6 @@
|
||||||
<References>
|
<References>
|
||||||
</References>
|
</References>
|
||||||
<Files>
|
<Files>
|
||||||
<Filter
|
|
||||||
Name="misc"
|
|
||||||
>
|
|
||||||
<File
|
|
||||||
RelativePath="..\..\PluginSpecs\pluginspecs_wiimote.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
<Filter
|
<Filter
|
||||||
Name="Debugging"
|
Name="Debugging"
|
||||||
>
|
>
|
||||||
|
@ -586,6 +578,10 @@
|
||||||
<Filter
|
<Filter
|
||||||
Name="Real Wiimote"
|
Name="Real Wiimote"
|
||||||
>
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Src\ReadWiimote.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Src\wiimote_real.cpp"
|
RelativePath=".\Src\wiimote_real.cpp"
|
||||||
>
|
>
|
||||||
|
@ -619,6 +615,14 @@
|
||||||
RelativePath=".\Src\main.cpp"
|
RelativePath=".\Src\main.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Src\main.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\PluginSpecs\pluginspecs_wiimote.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
</Files>
|
</Files>
|
||||||
<Globals>
|
<Globals>
|
||||||
</Globals>
|
</Globals>
|
||||||
|
|
|
@ -39,6 +39,9 @@ void Config::Load()
|
||||||
iniFile.Get("Settings", "WideScreen", &bWideScreen, false);
|
iniFile.Get("Settings", "WideScreen", &bWideScreen, false);
|
||||||
iniFile.Get("Settings", "NunchuckConnected", &bNunchuckConnected, false);
|
iniFile.Get("Settings", "NunchuckConnected", &bNunchuckConnected, false);
|
||||||
iniFile.Get("Settings", "ClassicControllerConnected", &bClassicControllerConnected, false);
|
iniFile.Get("Settings", "ClassicControllerConnected", &bClassicControllerConnected, false);
|
||||||
|
|
||||||
|
iniFile.Get("Real", "Connect", &bConnectRealWiimote, true);
|
||||||
|
iniFile.Get("Real", "Use", &bUseRealWiimote, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Config::Save()
|
void Config::Save()
|
||||||
|
@ -50,6 +53,8 @@ void Config::Save()
|
||||||
iniFile.Set("Settings", "NunchuckConnected", bNunchuckConnected);
|
iniFile.Set("Settings", "NunchuckConnected", bNunchuckConnected);
|
||||||
iniFile.Set("Settings", "ClassicControllerConnected", bClassicControllerConnected);
|
iniFile.Set("Settings", "ClassicControllerConnected", bClassicControllerConnected);
|
||||||
|
|
||||||
|
iniFile.Set("Real", "Connect", bConnectRealWiimote);
|
||||||
|
iniFile.Set("Real", "Use", bUseRealWiimote);
|
||||||
|
|
||||||
iniFile.Save(FULL_CONFIG_DIR "Wiimote.ini");
|
iniFile.Save(FULL_CONFIG_DIR "Wiimote.ini");
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,10 +30,13 @@ struct Config
|
||||||
void Load();
|
void Load();
|
||||||
void Save();
|
void Save();
|
||||||
|
|
||||||
// General
|
// Emulated Wiimote
|
||||||
bool bSidewaysDPad;
|
bool bSidewaysDPad;
|
||||||
bool bWideScreen;
|
bool bWideScreen;
|
||||||
bool bNunchuckConnected, bClassicControllerConnected;
|
bool bNunchuckConnected, bClassicControllerConnected;
|
||||||
|
|
||||||
|
// Real Wiimote
|
||||||
|
bool bConnectRealWiimote, bUseRealWiimote;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Config g_Config;
|
extern Config g_Config;
|
||||||
|
|
|
@ -23,14 +23,15 @@
|
||||||
#include "ConfigDlg.h"
|
#include "ConfigDlg.h"
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "EmuSubroutines.h" // for WmRequestStatus
|
#include "EmuSubroutines.h" // for WmRequestStatus
|
||||||
|
#include "main.h"
|
||||||
|
#include "wiimote_real.h"
|
||||||
/////////////////////////////
|
/////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
// Defines
|
// Definitions
|
||||||
// ------------
|
// ------------
|
||||||
#ifndef _WIN32
|
|
||||||
#define Sleep(x) usleep(x*1000)
|
|
||||||
#endif
|
|
||||||
/////////////////////////
|
/////////////////////////
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -44,6 +45,10 @@ BEGIN_EVENT_TABLE(ConfigDialog,wxDialog)
|
||||||
EVT_CHECKBOX(ID_WIDESCREEN, ConfigDialog::GeneralSettingsChanged)
|
EVT_CHECKBOX(ID_WIDESCREEN, ConfigDialog::GeneralSettingsChanged)
|
||||||
EVT_CHECKBOX(ID_NUNCHUCKCONNECTED, ConfigDialog::GeneralSettingsChanged)
|
EVT_CHECKBOX(ID_NUNCHUCKCONNECTED, ConfigDialog::GeneralSettingsChanged)
|
||||||
EVT_CHECKBOX(ID_CLASSICCONTROLLERCONNECTED, ConfigDialog::GeneralSettingsChanged)
|
EVT_CHECKBOX(ID_CLASSICCONTROLLERCONNECTED, ConfigDialog::GeneralSettingsChanged)
|
||||||
|
|
||||||
|
EVT_CHECKBOX(ID_CONNECT_REAL, ConfigDialog::GeneralSettingsChanged)
|
||||||
|
EVT_CHECKBOX(ID_USE_REAL, ConfigDialog::GeneralSettingsChanged)
|
||||||
|
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
/////////////////////////////
|
/////////////////////////////
|
||||||
|
|
||||||
|
@ -57,6 +62,8 @@ ConfigDialog::ConfigDialog(wxWindow *parent, wxWindowID id, const wxString &titl
|
||||||
|
|
||||||
ConfigDialog::~ConfigDialog()
|
ConfigDialog::~ConfigDialog()
|
||||||
{
|
{
|
||||||
|
g_FrameOpen = false;
|
||||||
|
if (!g_EmulatorRunning) Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -76,7 +83,10 @@ void ConfigDialog::CreateGUIControls()
|
||||||
//m_About = new wxButton(this, ID_ABOUTOGL, wxT("About"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
//m_About = new wxButton(this, ID_ABOUTOGL, wxT("About"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
m_Close = new wxButton(this, ID_CLOSE, wxT("Close"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
m_Close = new wxButton(this, ID_CLOSE, wxT("Close"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
|
|
||||||
// Put notebook and buttons in sizers
|
|
||||||
|
////////////////////////////////////////////
|
||||||
|
// Put notebook and buttons in sMain
|
||||||
|
// ----------------
|
||||||
wxBoxSizer* sButtons;
|
wxBoxSizer* sButtons;
|
||||||
sButtons = new wxBoxSizer(wxHORIZONTAL);
|
sButtons = new wxBoxSizer(wxHORIZONTAL);
|
||||||
//sButtons->Add(m_About, 0, wxALL, 5); // there is no about
|
//sButtons->Add(m_About, 0, wxALL, 5); // there is no about
|
||||||
|
@ -87,10 +97,14 @@ void ConfigDialog::CreateGUIControls()
|
||||||
sMain = new wxBoxSizer(wxVERTICAL);
|
sMain = new wxBoxSizer(wxVERTICAL);
|
||||||
sMain->Add(m_Notebook, 1, wxEXPAND|wxALL, 5);
|
sMain->Add(m_Notebook, 1, wxEXPAND|wxALL, 5);
|
||||||
sMain->Add(sButtons, 0, wxEXPAND, 5);
|
sMain->Add(sButtons, 0, wxEXPAND, 5);
|
||||||
|
/////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////
|
||||||
|
// Emulated Wiimote
|
||||||
|
// ----------------
|
||||||
// General
|
// General
|
||||||
sbBasic = new wxStaticBoxSizer(wxVERTICAL, m_PageEmu, wxT("Basic Settings"));
|
wxStaticBoxSizer * sEmulatedBasic = new wxStaticBoxSizer(wxVERTICAL, m_PageEmu, wxT("Basic Settings"));
|
||||||
m_SidewaysDPad = new wxCheckBox(m_PageEmu, ID_SIDEWAYSDPAD, wxT("Sideways D-Pad"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
m_SidewaysDPad = new wxCheckBox(m_PageEmu, ID_SIDEWAYSDPAD, wxT("Sideways D-Pad"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
m_SidewaysDPad->SetValue(g_Config.bSidewaysDPad);
|
m_SidewaysDPad->SetValue(g_Config.bSidewaysDPad);
|
||||||
m_WideScreen = new wxCheckBox(m_PageEmu, ID_WIDESCREEN, wxT("WideScreen Mode (for correct aiming)"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
m_WideScreen = new wxCheckBox(m_PageEmu, ID_WIDESCREEN, wxT("WideScreen Mode (for correct aiming)"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
|
@ -100,30 +114,56 @@ void ConfigDialog::CreateGUIControls()
|
||||||
m_ClassicControllerConnected = new wxCheckBox(m_PageEmu, ID_CLASSICCONTROLLERCONNECTED, wxT("Classic Controller connected"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
m_ClassicControllerConnected = new wxCheckBox(m_PageEmu, ID_CLASSICCONTROLLERCONNECTED, wxT("Classic Controller connected"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||||
m_ClassicControllerConnected->SetValue(g_Config.bClassicControllerConnected);
|
m_ClassicControllerConnected->SetValue(g_Config.bClassicControllerConnected);
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
// Set up sGeneral and sBasic
|
// Set up sGeneral and sBasic
|
||||||
// Usage: The wxGBPosition() must have a column and row
|
// Usage: The wxGBPosition() must have a column and row
|
||||||
// ----------------
|
// ----------------
|
||||||
sGeneral = new wxBoxSizer(wxVERTICAL);
|
wxBoxSizer * sEmulatedMain = new wxBoxSizer(wxVERTICAL);
|
||||||
sBasic = new wxGridBagSizer(0, 0);
|
wxGridBagSizer * GbsBasic = new wxGridBagSizer(0, 0);
|
||||||
sBasic->Add(m_SidewaysDPad, wxGBPosition(0, 0), wxGBSpan(1, 2), wxALL, 5);
|
GbsBasic->Add(m_SidewaysDPad, wxGBPosition(0, 0), wxGBSpan(1, 2), wxALL, 5);
|
||||||
sBasic->Add(m_WideScreen, wxGBPosition(1, 0), wxGBSpan(1, 2), wxALL, 5);
|
GbsBasic->Add(m_WideScreen, wxGBPosition(1, 0), wxGBSpan(1, 2), wxALL, 5);
|
||||||
sBasic->Add(m_NunchuckConnected, wxGBPosition(2, 0), wxGBSpan(1, 2), wxALL, 5);
|
GbsBasic->Add(m_NunchuckConnected, wxGBPosition(2, 0), wxGBSpan(1, 2), wxALL, 5);
|
||||||
sBasic->Add(m_ClassicControllerConnected, wxGBPosition(3, 0), wxGBSpan(1, 2), wxALL, 5);
|
GbsBasic->Add(m_ClassicControllerConnected, wxGBPosition(3, 0), wxGBSpan(1, 2), wxALL, 5);
|
||||||
sbBasic->Add(sBasic);
|
sEmulatedBasic->Add(GbsBasic);
|
||||||
sGeneral->Add(sbBasic, 0, wxEXPAND|wxALL, 5);
|
sEmulatedMain->Add(sEmulatedBasic, 0, wxEXPAND | (wxALL), 5);
|
||||||
|
/////////////////////////////////
|
||||||
|
|
||||||
m_PageEmu->SetSizer(sGeneral);
|
|
||||||
sGeneral->Layout();
|
|
||||||
|
|
||||||
this->SetSizer(sMain);
|
////////////////////////////////////////////
|
||||||
this->Layout();
|
// Real Wiimote
|
||||||
// ----------------
|
// ----------------
|
||||||
|
// General
|
||||||
|
wxStaticBoxSizer * sbRealBasic = new wxStaticBoxSizer(wxVERTICAL, m_PageReal, wxT("Basic Settings"));
|
||||||
|
m_ConnectRealWiimote = new wxCheckBox(m_PageReal, ID_CONNECT_REAL, wxT("Connect real Wiimote"));
|
||||||
|
m_UseRealWiimote = new wxCheckBox(m_PageReal, ID_USE_REAL, wxT("Use real Wiimote"));
|
||||||
|
m_ConnectRealWiimote->SetToolTip(wxT("Connected to the real wiimote"));
|
||||||
|
m_UseRealWiimote->SetToolTip(wxT("Use the real Wiimote in the game"));
|
||||||
|
m_ConnectRealWiimote->SetValue(g_Config.bConnectRealWiimote);
|
||||||
|
m_UseRealWiimote->SetValue(g_Config.bUseRealWiimote);
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Set up sizers
|
||||||
|
// ----------------
|
||||||
|
wxBoxSizer * sRealMain = new wxBoxSizer(wxVERTICAL);
|
||||||
|
sRealMain->Add(sbRealBasic, 0, wxEXPAND | (wxALL), 5);
|
||||||
|
sbRealBasic->Add(m_ConnectRealWiimote, 0, wxEXPAND | (wxALL), 5);
|
||||||
|
sbRealBasic->Add(m_UseRealWiimote, 0, wxEXPAND | (wxALL), 5);
|
||||||
|
/////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////
|
||||||
|
// Set sizers and layout
|
||||||
|
// ----------------
|
||||||
|
m_PageEmu->SetSizer(sEmulatedMain);
|
||||||
|
m_PageReal->SetSizer(sRealMain);
|
||||||
|
this->SetSizer(sMain);
|
||||||
|
|
||||||
|
//sEmulatedMain->Layout();
|
||||||
|
this->Layout();
|
||||||
|
|
||||||
Fit();
|
Fit();
|
||||||
Center();
|
Center();
|
||||||
|
/////////////////////////////////
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigDialog::OnClose(wxCloseEvent& WXUNUSED (event))
|
void ConfigDialog::OnClose(wxCloseEvent& WXUNUSED (event))
|
||||||
|
@ -141,7 +181,27 @@ void ConfigDialog::AboutClick(wxCommandEvent& WXUNUSED (event))
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
//////////////////////////
|
/////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ===================================================
|
||||||
|
/* Do use real wiimote */
|
||||||
|
// ----------------
|
||||||
|
void ConfigDialog::DoConnectReal()
|
||||||
|
{
|
||||||
|
g_Config.bConnectRealWiimote = m_ConnectRealWiimote->IsChecked();
|
||||||
|
|
||||||
|
if(g_Config.bConnectRealWiimote)
|
||||||
|
{
|
||||||
|
if (!g_RealWiiMoteInitialized) WiiMoteReal::Initialize();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (g_RealWiiMoteInitialized) WiiMoteReal::Shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ===================================================
|
// ===================================================
|
||||||
|
@ -159,7 +219,7 @@ void ConfigDialog::DoExtensionConnectedDisconnected()
|
||||||
|
|
||||||
|
|
||||||
// ===================================================
|
// ===================================================
|
||||||
/* Change general Emulated Wii Remote settings */
|
/* Change settings */
|
||||||
// ----------------
|
// ----------------
|
||||||
void ConfigDialog::GeneralSettingsChanged(wxCommandEvent& event)
|
void ConfigDialog::GeneralSettingsChanged(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
|
@ -214,5 +274,31 @@ void ConfigDialog::GeneralSettingsChanged(wxCommandEvent& event)
|
||||||
memcpy(WiiMoteEmu::g_RegExt + 0xfa, WiiMoteEmu::classic_id, sizeof(WiiMoteEmu::classic_id));
|
memcpy(WiiMoteEmu::g_RegExt + 0xfa, WiiMoteEmu::classic_id, sizeof(WiiMoteEmu::classic_id));
|
||||||
DoExtensionConnectedDisconnected();
|
DoExtensionConnectedDisconnected();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////
|
||||||
|
// Real Wiimote
|
||||||
|
// -----------
|
||||||
|
case ID_CONNECT_REAL:
|
||||||
|
DoConnectReal();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ID_USE_REAL:
|
||||||
|
g_Config.bUseRealWiimote = m_UseRealWiimote->IsChecked();
|
||||||
|
break;
|
||||||
|
/////////////////
|
||||||
}
|
}
|
||||||
|
UpdateGUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// =======================================================
|
||||||
|
// Update the enabled/disabled status
|
||||||
|
// -------------
|
||||||
|
void ConfigDialog::UpdateGUI()
|
||||||
|
{
|
||||||
|
// Save status
|
||||||
|
m_ConnectRealWiimote->Enable(g_RealWiiMotePresent);
|
||||||
|
m_UseRealWiimote->Enable(g_RealWiiMotePresent && g_Config.bConnectRealWiimote);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,20 +43,18 @@ class ConfigDialog : public wxDialog
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DECLARE_EVENT_TABLE();
|
DECLARE_EVENT_TABLE();
|
||||||
|
|
||||||
wxBoxSizer* sGeneral;
|
|
||||||
wxStaticBoxSizer* sbBasic;
|
|
||||||
wxGridBagSizer* sBasic;
|
|
||||||
|
|
||||||
wxButton *m_About;
|
wxButton *m_About;
|
||||||
wxButton *m_Close;
|
wxButton *m_Close;
|
||||||
wxNotebook *m_Notebook;
|
wxNotebook *m_Notebook;
|
||||||
wxPanel *m_PageEmu, *m_PageReal;
|
wxPanel *m_PageEmu, *m_PageReal;
|
||||||
|
|
||||||
wxCheckBox *m_SidewaysDPad; // general settings
|
wxCheckBox *m_SidewaysDPad; // Emulated Wiimote settings
|
||||||
wxCheckBox *m_WideScreen;
|
wxCheckBox *m_WideScreen;
|
||||||
wxCheckBox *m_NunchuckConnected, *m_ClassicControllerConnected;
|
wxCheckBox *m_NunchuckConnected, *m_ClassicControllerConnected;
|
||||||
|
|
||||||
|
wxCheckBox *m_ConnectRealWiimote, *m_UseRealWiimote; // Real Wiimote settings
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
ID_CLOSE = 1000,
|
ID_CLOSE = 1000,
|
||||||
|
@ -66,17 +64,25 @@ class ConfigDialog : public wxDialog
|
||||||
ID_PAGEEMU,
|
ID_PAGEEMU,
|
||||||
ID_PAGEREAL,
|
ID_PAGEREAL,
|
||||||
|
|
||||||
ID_SIDEWAYSDPAD,
|
ID_SIDEWAYSDPAD, // Emulated
|
||||||
ID_WIDESCREEN,
|
ID_WIDESCREEN,
|
||||||
ID_NUNCHUCKCONNECTED, ID_CLASSICCONTROLLERCONNECTED
|
ID_NUNCHUCKCONNECTED, ID_CLASSICCONTROLLERCONNECTED,
|
||||||
|
|
||||||
|
// Real
|
||||||
|
ID_CONNECT_REAL, ID_USE_REAL
|
||||||
};
|
};
|
||||||
|
|
||||||
void OnClose(wxCloseEvent& event);
|
void OnClose(wxCloseEvent& event);
|
||||||
void CreateGUIControls();
|
void CreateGUIControls();
|
||||||
|
|
||||||
void AboutClick(wxCommandEvent& event);
|
void AboutClick(wxCommandEvent& event);
|
||||||
void DoExtensionConnectedDisconnected();
|
|
||||||
|
void DoConnectReal(); // Real
|
||||||
|
|
||||||
|
void DoExtensionConnectedDisconnected(); // Emulated
|
||||||
|
|
||||||
void GeneralSettingsChanged(wxCommandEvent& event);
|
void GeneralSettingsChanged(wxCommandEvent& event);
|
||||||
|
void UpdateGUI();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -91,8 +91,8 @@ void WmDataReporting(u16 _channelID, wm_data_reporting* dr)
|
||||||
LOG(WII_IPC_WIIMOTE, " Continuous: %x", dr->continuous);
|
LOG(WII_IPC_WIIMOTE, " Continuous: %x", dr->continuous);
|
||||||
LOG(WII_IPC_WIIMOTE, " All The Time: %x (not only on data change)", dr->all_the_time);
|
LOG(WII_IPC_WIIMOTE, " All The Time: %x (not only on data change)", dr->all_the_time);
|
||||||
LOG(WII_IPC_WIIMOTE, " Mode: 0x%02x", dr->mode);
|
LOG(WII_IPC_WIIMOTE, " Mode: 0x%02x", dr->mode);
|
||||||
//Console::Print("Data reporting mode: 0x%02x\n", dr->mode);
|
Console::Print("Data reporting mode: 0x%02x\n", dr->mode);
|
||||||
//Console::Print("Data reporting channel: 0x%04x\n", _channelID);
|
Console::Print("Data reporting channel: 0x%04x\n", _channelID);
|
||||||
|
|
||||||
g_ReportingMode = dr->mode;
|
g_ReportingMode = dr->mode;
|
||||||
g_ReportingChannel = _channelID;
|
g_ReportingChannel = _channelID;
|
||||||
|
|
|
@ -267,7 +267,7 @@ void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size)
|
||||||
//if((data[1] == WM_WRITE_DATA || data[1] == WM_READ_DATA)
|
//if((data[1] == WM_WRITE_DATA || data[1] == WM_READ_DATA)
|
||||||
// && data[3] == 0xa4)
|
// && data[3] == 0xa4)
|
||||||
//{
|
//{
|
||||||
CreateAckDelay((u8)_channelID, (u16)sr->channel);
|
if (!g_Config.bUseRealWiimote) CreateAckDelay((u8)_channelID, (u16)sr->channel);
|
||||||
//}
|
//}
|
||||||
//else
|
//else
|
||||||
//{
|
//{
|
||||||
|
@ -353,15 +353,16 @@ void ControlChannel(u16 _channelID, const void* _pData, u32 _Size)
|
||||||
void Update()
|
void Update()
|
||||||
{
|
{
|
||||||
//LOG(WII_IPC_WIIMOTE, "Wiimote_Update");
|
//LOG(WII_IPC_WIIMOTE, "Wiimote_Update");
|
||||||
|
Console::Print("g_ReportingMode %i\n", g_ReportingMode);
|
||||||
|
|
||||||
switch(g_ReportingMode)
|
switch(g_ReportingMode)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case WM_REPORT_CORE: SendReportCore(g_ReportingChannel); break;
|
case WM_REPORT_CORE: SendReportCore(g_ReportingChannel); break;
|
||||||
case WM_REPORT_CORE_ACCEL: SendReportCoreAccel(g_ReportingChannel); break;
|
case WM_REPORT_CORE_ACCEL: SendReportCoreAccel(g_ReportingChannel); break;
|
||||||
case WM_REPORT_CORE_ACCEL_IR12: SendReportCoreAccelIr12(g_ReportingChannel);break;
|
case WM_REPORT_CORE_ACCEL_IR12: SendReportCoreAccelIr12(g_ReportingChannel); break;
|
||||||
case WM_REPORT_CORE_ACCEL_EXT16: SendReportCoreAccelExt16(g_ReportingChannel);break;
|
case WM_REPORT_CORE_ACCEL_EXT16: SendReportCoreAccelExt16(g_ReportingChannel); break;
|
||||||
case WM_REPORT_CORE_ACCEL_IR10_EXT6: SendReportCoreAccelIr10Ext(g_ReportingChannel);break;
|
case WM_REPORT_CORE_ACCEL_IR10_EXT6: SendReportCoreAccelIr10Ext(g_ReportingChannel);break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,12 +97,12 @@ void HidOutputReport(u16 _channelID, wm_report* sr) {
|
||||||
WmDataReporting(_channelID, (wm_data_reporting*)sr->data);
|
WmDataReporting(_channelID, (wm_data_reporting*)sr->data);
|
||||||
break;
|
break;
|
||||||
case WM_REQUEST_STATUS: // 0x15
|
case WM_REQUEST_STATUS: // 0x15
|
||||||
WmRequestStatus(_channelID, (wm_request_status*)sr->data);
|
if (!g_Config.bUseRealWiimote) WmRequestStatus(_channelID, (wm_request_status*)sr->data);
|
||||||
//Temp = ArrayToString(sr->data, sizeof(wm_request_status), 0);
|
//Temp = ArrayToString(sr->data, sizeof(wm_request_status), 0);
|
||||||
//Console::Print("\n%s: InterruptChannel: %s\n", Tm().c_str(), Temp.c_str());
|
//Console::Print("\n%s: InterruptChannel: %s\n", Tm().c_str(), Temp.c_str());
|
||||||
break;
|
break;
|
||||||
case WM_READ_DATA: // 0x17
|
case WM_READ_DATA: // 0x17
|
||||||
WmReadData(_channelID, (wm_read_data*)sr->data);
|
if (!g_Config.bUseRealWiimote) WmReadData(_channelID, (wm_read_data*)sr->data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* This enables or disables the IR lights, we update the global variable g_IR
|
/* This enables or disables the IR lights, we update the global variable g_IR
|
||||||
|
@ -116,7 +116,7 @@ void HidOutputReport(u16 _channelID, wm_report* sr) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_WRITE_DATA: // 0x16
|
case WM_WRITE_DATA: // 0x16
|
||||||
WmWriteData(_channelID, (wm_write_data*)sr->data);
|
if (!g_Config.bUseRealWiimote) WmWriteData(_channelID, (wm_write_data*)sr->data);
|
||||||
break;
|
break;
|
||||||
case WM_SPEAKER_ENABLE: // 0x14
|
case WM_SPEAKER_ENABLE: // 0x14
|
||||||
LOGV(WII_IPC_WIIMOTE, 1, " WM Speaker Enable 0x%02x: 0x%02x", sr->channel, sr->data[0]);
|
LOGV(WII_IPC_WIIMOTE, 1, " WM Speaker Enable 0x%02x: 0x%02x", sr->channel, sr->data[0]);
|
||||||
|
|
|
@ -0,0 +1,139 @@
|
||||||
|
// Copyright (C) 2003-2008 Dolphin Project.
|
||||||
|
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
|
// Official SVN repository and contact information can be found at
|
||||||
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Includes
|
||||||
|
// ¯¯¯¯¯¯¯¯¯¯
|
||||||
|
#include <iostream> // System
|
||||||
|
#include "pluginspecs_wiimote.h"
|
||||||
|
|
||||||
|
#include "wiiuse.h" // Externals
|
||||||
|
|
||||||
|
#include "ConsoleWindow.h" // Common
|
||||||
|
|
||||||
|
#include "wiimote_real.h" // Local
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
|
namespace WiiMoteReal
|
||||||
|
{
|
||||||
|
|
||||||
|
void handle_ctrl_status(struct wiimote_t* wm)
|
||||||
|
{
|
||||||
|
printf("\n\n--- CONTROLLER STATUS [wiimote id %i] ---\n", wm->unid);
|
||||||
|
|
||||||
|
printf("attachment: %i\n", wm->exp.type);
|
||||||
|
printf("speaker: %i\n", WIIUSE_USING_SPEAKER(wm));
|
||||||
|
printf("ir: %i\n", WIIUSE_USING_IR(wm));
|
||||||
|
printf("leds: %i %i %i %i\n", WIIUSE_IS_LED_SET(wm, 1), WIIUSE_IS_LED_SET(wm, 2), WIIUSE_IS_LED_SET(wm, 3), WIIUSE_IS_LED_SET(wm, 4));
|
||||||
|
printf("battery: %f %%\n", wm->battery_level);
|
||||||
|
}
|
||||||
|
|
||||||
|
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_B)) printf("B pressed\n");
|
||||||
|
if (IS_PRESSED(wm, WIIMOTE_BUTTON_UP)) printf("UP pressed\n");
|
||||||
|
if (IS_PRESSED(wm, WIIMOTE_BUTTON_DOWN)) printf("DOWN pressed\n");
|
||||||
|
if (IS_PRESSED(wm, WIIMOTE_BUTTON_LEFT)) printf("LEFT pressed\n");
|
||||||
|
if (IS_PRESSED(wm, WIIMOTE_BUTTON_RIGHT)) printf("RIGHT pressed\n");
|
||||||
|
if (IS_PRESSED(wm, WIIMOTE_BUTTON_MINUS)) printf("MINUS pressed\n");
|
||||||
|
if (IS_PRESSED(wm, WIIMOTE_BUTTON_PLUS)) printf("PLUS pressed\n");
|
||||||
|
if (IS_PRESSED(wm, WIIMOTE_BUTTON_ONE)) printf("ONE pressed\n");
|
||||||
|
//if (IS_PRESSED(wm, WIIMOTE_BUTTON_ONE)) g_Run = false;
|
||||||
|
if (IS_PRESSED(wm, WIIMOTE_BUTTON_TWO)) printf("TWO pressed\n");
|
||||||
|
if (IS_PRESSED(wm, WIIMOTE_BUTTON_HOME)) printf("HOME pressed\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReadWiimote()
|
||||||
|
{
|
||||||
|
if (wiiuse_poll(g_WiiMotesFromWiiUse, MAX_WIIMOTES))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This happens if something happened on any wiimote.
|
||||||
|
* So go through each one and check if anything happened.
|
||||||
|
*/
|
||||||
|
int i = 0;
|
||||||
|
for (; i < MAX_WIIMOTES; ++i)
|
||||||
|
{
|
||||||
|
switch (g_WiiMotesFromWiiUse[i]->event)
|
||||||
|
{
|
||||||
|
case WIIUSE_EVENT:
|
||||||
|
/* a generic event occured */
|
||||||
|
handle_event(g_WiiMotesFromWiiUse[i]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WIIUSE_STATUS:
|
||||||
|
/* a status event occured */
|
||||||
|
handle_ctrl_status(g_WiiMotesFromWiiUse[i]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WIIUSE_DISCONNECT:
|
||||||
|
case WIIUSE_UNEXPECTED_DISCONNECT:
|
||||||
|
/* the wiimote disconnected */
|
||||||
|
//handle_disconnect(wiimotes[i]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WIIUSE_READ_DATA:
|
||||||
|
/*
|
||||||
|
* Data we requested to read was returned.
|
||||||
|
* Take a look at wiimotes[i]->read_req
|
||||||
|
* for the data.
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WIIUSE_NUNCHUK_INSERTED:
|
||||||
|
/*
|
||||||
|
* a nunchuk was inserted
|
||||||
|
* This is a good place to set any nunchuk specific
|
||||||
|
* threshold values. By default they are the same
|
||||||
|
* as the wiimote.
|
||||||
|
*/
|
||||||
|
//wiiuse_set_nunchuk_orient_threshold((struct nunchuk_t*)&wiimotes[i]->exp.nunchuk, 90.0f);
|
||||||
|
//wiiuse_set_nunchuk_accel_threshold((struct nunchuk_t*)&wiimotes[i]->exp.nunchuk, 100);
|
||||||
|
printf("Nunchuk inserted.\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WIIUSE_CLASSIC_CTRL_INSERTED:
|
||||||
|
//printf("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");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WIIUSE_NUNCHUK_REMOVED:
|
||||||
|
case WIIUSE_CLASSIC_CTRL_REMOVED:
|
||||||
|
case WIIUSE_GUITAR_HERO_3_CTRL_REMOVED:
|
||||||
|
/* some expansion was removed */
|
||||||
|
//handle_ctrl_status(wiimotes[i]);
|
||||||
|
printf("An expansion was removed.\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // end of namespace
|
|
@ -29,6 +29,7 @@ cxxflags = [ '-fPIC' ]
|
||||||
if wmenv['HAVE_WIIUSE']:
|
if wmenv['HAVE_WIIUSE']:
|
||||||
libs += [ 'wiiuse' ]
|
libs += [ 'wiiuse' ]
|
||||||
files += [ "wiimote_real.cpp" ]
|
files += [ "wiimote_real.cpp" ]
|
||||||
|
files += [ "ReadWiimote.cpp" ]
|
||||||
cxxflags += ['-DHAVE_WIIUSE']
|
cxxflags += ['-DHAVE_WIIUSE']
|
||||||
|
|
||||||
wmenv.Append(
|
wmenv.Append(
|
||||||
|
|
|
@ -25,16 +25,16 @@
|
||||||
#include "ConsoleWindow.h" // For Start, Print, GetHwnd
|
#include "ConsoleWindow.h" // For Start, Print, GetHwnd
|
||||||
|
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
#if defined(HAVE_WX) && HAVE_WX
|
||||||
#include <wx/aboutdlg.h>
|
#include <wx/aboutdlg.h>
|
||||||
#include "ConfigDlg.h"
|
#include "ConfigDlg.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define EXCLUDEMAIN_H // Avoid certain declarations in main.h
|
||||||
|
#include "Main.h" // Local
|
||||||
#include "pluginspecs_wiimote.h"
|
#include "pluginspecs_wiimote.h"
|
||||||
|
|
||||||
#include "EmuMain.h"
|
#include "EmuMain.h"
|
||||||
|
|
||||||
#if HAVE_WIIUSE
|
#if HAVE_WIIUSE
|
||||||
#include "wiimote_real.h"
|
#include "wiimote_real.h"
|
||||||
#endif
|
#endif
|
||||||
///////////////////////////////////
|
///////////////////////////////////
|
||||||
|
|
||||||
|
@ -44,7 +44,10 @@
|
||||||
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
|
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
|
||||||
SWiimoteInitialize g_WiimoteInitialize;
|
SWiimoteInitialize g_WiimoteInitialize;
|
||||||
|
|
||||||
bool g_UseRealWiiMote = false;
|
bool g_EmulatorRunning = false;
|
||||||
|
bool g_FrameOpen = false;
|
||||||
|
bool g_RealWiiMotePresent = false;
|
||||||
|
bool g_RealWiiMoteInitialized = false;
|
||||||
|
|
||||||
HINSTANCE g_hInstance;
|
HINSTANCE g_hInstance;
|
||||||
|
|
||||||
|
@ -105,67 +108,64 @@ extern "C" void GetDllInfo (PLUGIN_INFO* _PluginInfo)
|
||||||
{
|
{
|
||||||
_PluginInfo->Version = 0x0100;
|
_PluginInfo->Version = 0x0100;
|
||||||
_PluginInfo->Type = PLUGIN_TYPE_WIIMOTE;
|
_PluginInfo->Type = PLUGIN_TYPE_WIIMOTE;
|
||||||
#ifdef DEBUGFAST
|
#ifdef DEBUGFAST
|
||||||
sprintf(_PluginInfo->Name, "Dolphin Wiimote Plugin (DebugFast)");
|
sprintf(_PluginInfo->Name, "Dolphin Wiimote Plugin (DebugFast)");
|
||||||
#else
|
#else
|
||||||
#ifndef _DEBUG
|
#ifndef _DEBUG
|
||||||
sprintf(_PluginInfo->Name, "Dolphin Wiimote Plugin");
|
sprintf(_PluginInfo->Name, "Dolphin Wiimote Plugin");
|
||||||
#else
|
#else
|
||||||
sprintf(_PluginInfo->Name, "Dolphin Wiimote Plugin (Debug)");
|
sprintf(_PluginInfo->Name, "Dolphin Wiimote Plugin (Debug)");
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetDllGlobals(PLUGIN_GLOBALS* _pPluginGlobals) {
|
void SetDllGlobals(PLUGIN_GLOBALS* _pPluginGlobals) {}
|
||||||
}
|
|
||||||
|
|
||||||
void DllDebugger(HWND _hParent, bool Show) {
|
void DllDebugger(HWND _hParent, bool Show) {}
|
||||||
}
|
|
||||||
|
|
||||||
void DllConfig(HWND _hParent)
|
void DllConfig(HWND _hParent)
|
||||||
{
|
{
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
#if defined(HAVE_WX) && HAVE_WX
|
||||||
|
|
||||||
wxWindow win;
|
wxWindow win;
|
||||||
#ifdef _WIN32
|
|
||||||
win.SetHWND(_hParent);
|
#ifdef _WIN32
|
||||||
#endif
|
win.SetHWND(_hParent);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DoInitialize();
|
||||||
|
g_FrameOpen = true;
|
||||||
ConfigDialog frame(&win);
|
ConfigDialog frame(&win);
|
||||||
frame.ShowModal();
|
frame.ShowModal();
|
||||||
#ifdef _WIN32
|
//frame.Show();
|
||||||
win.SetHWND(0);
|
|
||||||
#endif
|
#ifdef _WIN32
|
||||||
|
win.SetHWND(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void Initialize(void *init)
|
extern "C" void Initialize(void *init)
|
||||||
{
|
{
|
||||||
|
// Declarations
|
||||||
SWiimoteInitialize _WiimoteInitialize = *(SWiimoteInitialize *)init;
|
SWiimoteInitialize _WiimoteInitialize = *(SWiimoteInitialize *)init;
|
||||||
// ----------------------------------------
|
|
||||||
// Debugging window
|
|
||||||
// ----------
|
|
||||||
/*Console::Open(100, 750, "Wiimote"); // give room for 20 rows
|
|
||||||
Console::Print("Wiimote console opened\n");
|
|
||||||
|
|
||||||
// Move window
|
|
||||||
//MoveWindow(Console::GetHwnd(), 0,400, 100*8,10*14, true); // small window
|
|
||||||
MoveWindow(Console::GetHwnd(), 400,0, 100*8,70*14, true); // big window*/
|
|
||||||
// ---------------
|
|
||||||
|
|
||||||
g_WiimoteInitialize = _WiimoteInitialize;
|
g_WiimoteInitialize = _WiimoteInitialize;
|
||||||
|
|
||||||
/* We will run WiiMoteReal::Initialize() even if we are not using a real wiimote,
|
g_EmulatorRunning = true;
|
||||||
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_UseRealWiiMote will also be false. This function call will be done
|
|
||||||
instantly if there is no real Wiimote connected. I'm not sure how long time
|
|
||||||
it takes if a Wiimote is connected. */
|
|
||||||
#if HAVE_WIIUSE
|
|
||||||
g_UseRealWiiMote = WiiMoteReal::Initialize() > 0;
|
|
||||||
#endif
|
|
||||||
g_Config.Load(); // load config settings
|
|
||||||
|
|
||||||
WiiMoteEmu::Initialize();
|
DoInitialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void Shutdown(void)
|
||||||
|
{
|
||||||
|
// We will only shutdown when both a game and the frame is closed
|
||||||
|
if (g_FrameOpen) { g_EmulatorRunning = false; return; }
|
||||||
|
|
||||||
|
#if HAVE_WIIUSE
|
||||||
|
if(g_RealWiiMoteInitialized) WiiMoteReal::Shutdown();
|
||||||
|
#endif
|
||||||
|
WiiMoteEmu::Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -177,13 +177,6 @@ extern "C" void DoState(unsigned char **ptr, int mode)
|
||||||
WiiMoteEmu::DoState(ptr, mode);
|
WiiMoteEmu::DoState(ptr, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void Shutdown(void)
|
|
||||||
{
|
|
||||||
#if HAVE_WIIUSE
|
|
||||||
WiiMoteReal::Shutdown();
|
|
||||||
#endif
|
|
||||||
WiiMoteEmu::Shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===================================================
|
// ===================================================
|
||||||
/* This function produce Wiimote Input (reports from the Wiimote) in response
|
/* This function produce Wiimote Input (reports from the Wiimote) in response
|
||||||
|
@ -203,16 +196,21 @@ extern "C" void Wiimote_InterruptChannel(u16 _channelID, const void* _pData, u32
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decice where to send the message
|
// Decice where to send the message
|
||||||
if (! g_UseRealWiiMote)
|
//if (!g_Config.bUseRealWiimote || !g_RealWiiMotePresent)
|
||||||
WiiMoteEmu::InterruptChannel(_channelID, _pData, _Size);
|
WiiMoteEmu::InterruptChannel(_channelID, _pData, _Size);
|
||||||
#if HAVE_WIIUSE
|
#if HAVE_WIIUSE
|
||||||
else
|
//else if (g_RealWiiMotePresent)
|
||||||
WiiMoteReal::InterruptChannel(_channelID, _pData, _Size);
|
WiiMoteReal::InterruptChannel(_channelID, _pData, _Size);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LOGV(WII_IPC_WIIMOTE, 3, "=============================================================");
|
LOGV(WII_IPC_WIIMOTE, 3, "=============================================================");
|
||||||
}
|
}
|
||||||
|
// ==============================
|
||||||
|
|
||||||
|
|
||||||
|
// ===================================================
|
||||||
|
/* Function: Used for the initial Bluetooth HID handshake. */
|
||||||
|
// ----------------
|
||||||
extern "C" void Wiimote_ControlChannel(u16 _channelID, const void* _pData, u32 _Size)
|
extern "C" void Wiimote_ControlChannel(u16 _channelID, const void* _pData, u32 _Size)
|
||||||
{
|
{
|
||||||
LOGV(WII_IPC_WIIMOTE, 3, "=============================================================");
|
LOGV(WII_IPC_WIIMOTE, 3, "=============================================================");
|
||||||
|
@ -225,16 +223,16 @@ extern "C" void Wiimote_ControlChannel(u16 _channelID, const void* _pData, u32 _
|
||||||
LOGV(WII_IPC_WIIMOTE, 3, " Data: %s", Temp.c_str());
|
LOGV(WII_IPC_WIIMOTE, 3, " Data: %s", Temp.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!g_Config.bUseRealWiimote || !g_RealWiiMotePresent)
|
||||||
if (! g_UseRealWiiMote)
|
WiiMoteEmu::ControlChannel(_channelID, _pData, _Size);
|
||||||
WiiMoteEmu::ControlChannel(_channelID, _pData, _Size);
|
|
||||||
#if HAVE_WIIUSE
|
#if HAVE_WIIUSE
|
||||||
else
|
else if (g_RealWiiMotePresent)
|
||||||
WiiMoteReal::ControlChannel(_channelID, _pData, _Size);
|
WiiMoteReal::ControlChannel(_channelID, _pData, _Size);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LOGV(WII_IPC_WIIMOTE, 3, "=============================================================");
|
LOGV(WII_IPC_WIIMOTE, 3, "=============================================================");
|
||||||
}
|
}
|
||||||
|
// ==============================
|
||||||
|
|
||||||
|
|
||||||
// ===================================================
|
// ===================================================
|
||||||
|
@ -243,11 +241,11 @@ extern "C" void Wiimote_ControlChannel(u16 _channelID, const void* _pData, u32 _
|
||||||
// ----------------
|
// ----------------
|
||||||
extern "C" void Wiimote_Update()
|
extern "C" void Wiimote_Update()
|
||||||
{
|
{
|
||||||
if (! g_UseRealWiiMote)
|
if (!g_Config.bUseRealWiimote || !g_RealWiiMotePresent)
|
||||||
WiiMoteEmu::Update();
|
WiiMoteEmu::Update();
|
||||||
#if HAVE_WIIUSE
|
#if HAVE_WIIUSE
|
||||||
else
|
else if (g_RealWiiMotePresent)
|
||||||
WiiMoteReal::Update();
|
WiiMoteReal::Update();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,9 +256,44 @@ extern "C" unsigned int Wiimote_GetAttachedControllers()
|
||||||
// ================
|
// ================
|
||||||
|
|
||||||
|
|
||||||
// ===================================================
|
//******************************************************************************
|
||||||
/* Logging functions. */
|
// Supporting functions
|
||||||
// ----------------
|
//******************************************************************************
|
||||||
|
|
||||||
|
void DoInitialize()
|
||||||
|
{
|
||||||
|
// ----------------------------------------
|
||||||
|
// Debugging window
|
||||||
|
// ----------
|
||||||
|
/*Console::Open(100, 750, "Wiimote"); // give room for 20 rows
|
||||||
|
Console::Print("Wiimote console opened\n");
|
||||||
|
|
||||||
|
// Move window
|
||||||
|
//MoveWindow(Console::GetHwnd(), 0,400, 100*8,10*14, true); // small window
|
||||||
|
MoveWindow(Console::GetHwnd(), 400,0, 100*8,70*14, true); // big window*/
|
||||||
|
// ---------------
|
||||||
|
|
||||||
|
// Load config settings
|
||||||
|
g_Config.Load();
|
||||||
|
|
||||||
|
/* 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 if there is no real Wiimote connected. I'm not sure how long time
|
||||||
|
it takes if a Wiimote is connected. */
|
||||||
|
#if HAVE_WIIUSE
|
||||||
|
if (g_Config.bConnectRealWiimote) WiiMoteReal::Initialize();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
WiiMoteEmu::Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//******************************************************************************
|
||||||
|
// Logging functions
|
||||||
|
//******************************************************************************
|
||||||
|
|
||||||
void __Log(int log, const char *_fmt, ...)
|
void __Log(int log, const char *_fmt, ...)
|
||||||
{
|
{
|
||||||
char Msg[512];
|
char Msg[512];
|
||||||
|
@ -285,4 +318,6 @@ void __Logv(int log, int v, const char *_fmt, ...)
|
||||||
|
|
||||||
g_WiimoteInitialize.pLog(Msg, v);
|
g_WiimoteInitialize.pLog(Msg, v);
|
||||||
}
|
}
|
||||||
// ================
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
// Copyright (C) 2003-2008 Dolphin Project.
|
||||||
|
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
|
// Official SVN repository and contact information can be found at
|
||||||
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
|
#ifndef MAIN_H
|
||||||
|
#define MAIN_H
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Includes
|
||||||
|
// ¯¯¯¯¯¯¯¯¯¯
|
||||||
|
#include <iostream> // System
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Definitions
|
||||||
|
// ¯¯¯¯¯¯¯¯¯
|
||||||
|
#ifndef _WIN32
|
||||||
|
#define Sleep(x) usleep(x*1000)
|
||||||
|
#endif
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Declarations
|
||||||
|
// ¯¯¯¯¯¯¯¯¯
|
||||||
|
void DoInitialize();
|
||||||
|
|
||||||
|
#ifndef EXCLUDEMAIN_H
|
||||||
|
extern bool g_EmulatorRunning;
|
||||||
|
extern bool g_FrameOpen;
|
||||||
|
extern bool g_RealWiiMotePresent;
|
||||||
|
extern bool g_RealWiiMoteInitialized;
|
||||||
|
#endif
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
#endif // MAIN_H
|
|
@ -15,6 +15,11 @@
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Includes
|
||||||
|
// ¯¯¯¯¯¯¯¯¯¯
|
||||||
|
#include <iostream> // System
|
||||||
#include "pluginspecs_wiimote.h"
|
#include "pluginspecs_wiimote.h"
|
||||||
|
|
||||||
#include "wiiuse.h"
|
#include "wiiuse.h"
|
||||||
|
@ -22,273 +27,340 @@
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "Thread.h"
|
#include "Thread.h"
|
||||||
|
#include "StringUtil.h"
|
||||||
|
#include "ConsoleWindow.h"
|
||||||
|
|
||||||
#include "wiimote_hid.h"
|
#include "wiimote_hid.h"
|
||||||
|
#include "main.h"
|
||||||
#include "EmuMain.h"
|
#include "EmuMain.h"
|
||||||
|
#define EXCLUDE_H // Avoid certain declarations in main.h
|
||||||
|
#include "wiimote_real.h"
|
||||||
|
|
||||||
extern SWiimoteInitialize g_WiimoteInitialize;
|
extern SWiimoteInitialize g_WiimoteInitialize;
|
||||||
//extern void __Log(int log, const char *format, ...);
|
////////////////////////////////////////
|
||||||
//extern void __Log(int log, int v, const char *format, ...);
|
|
||||||
|
|
||||||
|
|
||||||
namespace WiiMoteReal
|
namespace WiiMoteReal
|
||||||
{
|
{
|
||||||
#define MAX_WIIMOTES 1
|
|
||||||
|
|
||||||
//******************************************************************************
|
//******************************************************************************
|
||||||
// Forwarding
|
// Forwarding
|
||||||
//******************************************************************************
|
//******************************************************************************
|
||||||
|
|
||||||
class CWiiMote;
|
class CWiiMote;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
DWORD WINAPI ReadWiimote_ThreadFunc(void* arg);
|
DWORD WINAPI ReadWiimote_ThreadFunc(void* arg);
|
||||||
#else
|
#else
|
||||||
void* ReadWiimote_ThreadFunc(void* arg);
|
void* ReadWiimote_ThreadFunc(void* arg);
|
||||||
#endif
|
#endif
|
||||||
//******************************************************************************
|
//******************************************************************************
|
||||||
// Variable declarations
|
// Variable declarations
|
||||||
//******************************************************************************
|
//******************************************************************************
|
||||||
|
|
||||||
wiimote_t** g_WiiMotesFromWiiUse = NULL;
|
wiimote_t** g_WiiMotesFromWiiUse = NULL;
|
||||||
Common::Thread* g_pReadThread = NULL;
|
Common::Thread* g_pReadThread = NULL;
|
||||||
int g_NumberOfWiiMotes;
|
int g_NumberOfWiiMotes;
|
||||||
CWiiMote* g_WiiMotes[MAX_WIIMOTES];
|
CWiiMote* g_WiiMotes[MAX_WIIMOTES];
|
||||||
bool g_Shutdown = false;
|
bool g_Shutdown = false;
|
||||||
|
bool g_LocalThread = true;
|
||||||
|
|
||||||
//******************************************************************************
|
//******************************************************************************
|
||||||
// Probably this class should be in its own file
|
// Probably this class should be in its own file
|
||||||
//******************************************************************************
|
//******************************************************************************
|
||||||
|
|
||||||
class CWiiMote
|
class CWiiMote
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
//////////////////////////////////////////
|
||||||
|
// On create and on uncreate
|
||||||
|
// ---------------
|
||||||
|
CWiiMote(u8 _WiimoteNumber, wiimote_t* _pWiimote)
|
||||||
|
: m_WiimoteNumber(_WiimoteNumber)
|
||||||
|
, m_channelID(0)
|
||||||
|
, m_pWiiMote(_pWiimote)
|
||||||
|
, m_pCriticalSection(NULL)
|
||||||
|
, m_LastReportValid(false)
|
||||||
|
{
|
||||||
|
m_pCriticalSection = new Common::CriticalSection();
|
||||||
|
|
||||||
|
//wiiuse_set_leds(m_pWiiMote, WIIMOTE_LED_4);
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
// F|RES: i dunno if we really need this
|
||||||
|
CancelIo(m_pWiiMote->dev_handle);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~CWiiMote()
|
||||||
|
{
|
||||||
|
delete m_pCriticalSection;
|
||||||
|
};
|
||||||
|
//////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////
|
||||||
|
// Send raw HID data from the core to wiimote
|
||||||
|
// ---------------
|
||||||
|
void SendData(u16 _channelID, const u8* _pData, u32 _Size)
|
||||||
|
{
|
||||||
|
m_channelID = _channelID;
|
||||||
|
|
||||||
|
m_pCriticalSection->Enter();
|
||||||
{
|
{
|
||||||
public:
|
SEvent WriteEvent;
|
||||||
|
memcpy(WriteEvent.m_PayLoad, _pData+1, _Size-1);
|
||||||
CWiiMote(u8 _WiimoteNumber, wiimote_t* _pWiimote)
|
m_EventWriteQueue.push(WriteEvent);
|
||||||
: m_WiimoteNumber(_WiimoteNumber)
|
}
|
||||||
, m_channelID(0)
|
m_pCriticalSection->Leave();
|
||||||
, m_pWiiMote(_pWiimote)
|
}
|
||||||
, m_pCriticalSection(NULL)
|
/////////////////////
|
||||||
, m_LastReportValid(false)
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////
|
||||||
|
// Read data from wiimote (but don't send it to the core, just filter and queue)
|
||||||
|
// ---------------
|
||||||
|
void ReadData()
|
||||||
|
{
|
||||||
|
m_pCriticalSection->Enter();
|
||||||
|
|
||||||
|
// Send data to the Wiimote
|
||||||
|
if (!m_EventWriteQueue.empty())
|
||||||
|
{
|
||||||
|
SEvent& rEvent = m_EventWriteQueue.front();
|
||||||
|
wiiuse_io_write(m_pWiiMote, (byte*)rEvent.m_PayLoad, MAX_PAYLOAD);
|
||||||
|
m_EventWriteQueue.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pCriticalSection->Leave();
|
||||||
|
|
||||||
|
if (wiiuse_io_read(m_pWiiMote))
|
||||||
|
{
|
||||||
|
const byte* pBuffer = m_pWiiMote->event_buf;
|
||||||
|
|
||||||
|
// Check if we have a channel (connection) if so save the data...
|
||||||
|
if (m_channelID > 0)
|
||||||
{
|
{
|
||||||
m_pCriticalSection = new Common::CriticalSection();
|
|
||||||
|
|
||||||
wiiuse_set_leds(m_pWiiMote, WIIMOTE_LED_4);
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
// F|RES: i dunno if we really need this
|
|
||||||
CancelIo(m_pWiiMote->dev_handle);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~CWiiMote()
|
|
||||||
{
|
|
||||||
delete m_pCriticalSection;
|
|
||||||
};
|
|
||||||
|
|
||||||
// send raw HID data from the core to wiimote
|
|
||||||
void SendData(u16 _channelID, const u8* _pData, u32 _Size)
|
|
||||||
{
|
|
||||||
m_channelID = _channelID;
|
|
||||||
|
|
||||||
m_pCriticalSection->Enter();
|
m_pCriticalSection->Enter();
|
||||||
|
|
||||||
|
// Filter out reports
|
||||||
|
if (pBuffer[0] >= 0x30)
|
||||||
{
|
{
|
||||||
SEvent WriteEvent;
|
// Copy Buffer to LastReport
|
||||||
memcpy(WriteEvent.m_PayLoad, _pData+1, _Size-1);
|
memcpy(m_LastReport.m_PayLoad, pBuffer, MAX_PAYLOAD);
|
||||||
m_EventWriteQueue.push(WriteEvent);
|
m_LastReportValid = true;
|
||||||
}
|
}
|
||||||
m_pCriticalSection->Leave();
|
|
||||||
}
|
|
||||||
|
|
||||||
// read data from wiimote (but don't send it to the core, just filter
|
|
||||||
// and queue)
|
|
||||||
void ReadData()
|
|
||||||
{
|
|
||||||
m_pCriticalSection->Enter();
|
|
||||||
|
|
||||||
if (!m_EventWriteQueue.empty())
|
|
||||||
{
|
|
||||||
SEvent& rEvent = m_EventWriteQueue.front();
|
|
||||||
wiiuse_io_write(m_pWiiMote, (byte*)rEvent.m_PayLoad, MAX_PAYLOAD);
|
|
||||||
m_EventWriteQueue.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pCriticalSection->Leave();
|
|
||||||
|
|
||||||
if (wiiuse_io_read(m_pWiiMote))
|
|
||||||
{
|
|
||||||
const byte* pBuffer = m_pWiiMote->event_buf;
|
|
||||||
|
|
||||||
// check if we have a channel (connection) if so save the
|
|
||||||
// data...
|
|
||||||
if (m_channelID > 0)
|
|
||||||
{
|
|
||||||
m_pCriticalSection->Enter();
|
|
||||||
|
|
||||||
// filter out reports
|
|
||||||
if (pBuffer[0] >= 0x30)
|
|
||||||
{
|
|
||||||
memcpy(m_LastReport.m_PayLoad, pBuffer,
|
|
||||||
MAX_PAYLOAD);
|
|
||||||
m_LastReportValid = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SEvent ImportantEvent;
|
|
||||||
memcpy(ImportantEvent.m_PayLoad, pBuffer,
|
|
||||||
MAX_PAYLOAD);
|
|
||||||
m_EventReadQueue.push(ImportantEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pCriticalSection->Leave();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// send queued data to the core
|
|
||||||
void Update()
|
|
||||||
{
|
|
||||||
m_pCriticalSection->Enter();
|
|
||||||
|
|
||||||
if (m_EventReadQueue.empty())
|
|
||||||
{
|
|
||||||
if (m_LastReportValid)
|
|
||||||
SendEvent(m_LastReport);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
SendEvent(m_EventReadQueue.front());
|
|
||||||
m_EventReadQueue.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pCriticalSection->Leave();
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
struct SEvent
|
|
||||||
{
|
|
||||||
SEvent()
|
|
||||||
{
|
{
|
||||||
memset(m_PayLoad, 0, MAX_PAYLOAD);
|
// Copy Buffer to ImportantEvent
|
||||||
|
SEvent ImportantEvent;
|
||||||
|
memcpy(ImportantEvent.m_PayLoad, pBuffer, MAX_PAYLOAD);
|
||||||
|
m_EventReadQueue.push(ImportantEvent);
|
||||||
}
|
}
|
||||||
byte m_PayLoad[MAX_PAYLOAD];
|
m_pCriticalSection->Leave();
|
||||||
};
|
|
||||||
typedef std::queue<SEvent> CEventQueue;
|
|
||||||
|
|
||||||
u8 m_WiimoteNumber; // just for debugging
|
|
||||||
u16 m_channelID;
|
|
||||||
wiimote_t* m_pWiiMote;
|
|
||||||
|
|
||||||
Common::CriticalSection* m_pCriticalSection;
|
|
||||||
CEventQueue m_EventReadQueue;
|
|
||||||
CEventQueue m_EventWriteQueue;
|
|
||||||
bool m_LastReportValid;
|
|
||||||
SEvent m_LastReport;
|
|
||||||
|
|
||||||
void SendEvent(SEvent& _rEvent)
|
|
||||||
{
|
|
||||||
// we don't have an answer channel
|
|
||||||
if (m_channelID == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// check event buffer;
|
|
||||||
u8 Buffer[1024];
|
|
||||||
u32 Offset = 0;
|
|
||||||
hid_packet* pHidHeader = (hid_packet*)(Buffer + Offset);
|
|
||||||
Offset += sizeof(hid_packet);
|
|
||||||
pHidHeader->type = HID_TYPE_DATA;
|
|
||||||
pHidHeader->param = HID_PARAM_INPUT;
|
|
||||||
|
|
||||||
memcpy(&Buffer[Offset], _rEvent.m_PayLoad, MAX_PAYLOAD);
|
|
||||||
Offset += MAX_PAYLOAD;
|
|
||||||
|
|
||||||
g_WiimoteInitialize.pWiimoteInput(m_channelID, Buffer, Offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//std::string Temp = ArrayToString(pBuffer, sizeof(pBuffer), 0);
|
||||||
|
//Console::Print("Data:\n%s\n", Temp.c_str());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////
|
||||||
|
// Send queued data to the core
|
||||||
|
// ---------------
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
// Thread function
|
||||||
|
m_pCriticalSection->Enter();
|
||||||
|
|
||||||
|
if (m_EventReadQueue.empty())
|
||||||
|
{
|
||||||
|
if (m_LastReportValid) SendEvent(m_LastReport);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SendEvent(m_EventReadQueue.front());
|
||||||
|
m_EventReadQueue.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pCriticalSection->Leave();
|
||||||
|
};
|
||||||
|
/////////////////////
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
struct SEvent
|
||||||
|
{
|
||||||
|
SEvent()
|
||||||
|
{
|
||||||
|
memset(m_PayLoad, 0, MAX_PAYLOAD);
|
||||||
|
}
|
||||||
|
byte m_PayLoad[MAX_PAYLOAD];
|
||||||
};
|
};
|
||||||
|
typedef std::queue<SEvent> CEventQueue;
|
||||||
|
|
||||||
|
u8 m_WiimoteNumber; // Just for debugging
|
||||||
|
u16 m_channelID;
|
||||||
|
|
||||||
|
Common::CriticalSection* m_pCriticalSection;
|
||||||
|
CEventQueue m_EventReadQueue;
|
||||||
|
CEventQueue m_EventWriteQueue;
|
||||||
|
bool m_LastReportValid;
|
||||||
|
SEvent m_LastReport;
|
||||||
|
wiimote_t* m_pWiiMote; // This is g_WiiMotesFromWiiUse[]
|
||||||
|
|
||||||
|
//////////////////////////////////////////
|
||||||
|
// Send event
|
||||||
|
// ---------------
|
||||||
|
void SendEvent(SEvent& _rEvent)
|
||||||
|
{
|
||||||
|
// We don't have an answer channel
|
||||||
|
if (m_channelID == 0) return;
|
||||||
|
|
||||||
|
// Check event buffer;
|
||||||
|
u8 Buffer[1024];
|
||||||
|
u32 Offset = 0;
|
||||||
|
hid_packet* pHidHeader = (hid_packet*)(Buffer + Offset);
|
||||||
|
Offset += sizeof(hid_packet);
|
||||||
|
pHidHeader->type = HID_TYPE_DATA;
|
||||||
|
pHidHeader->param = HID_PARAM_INPUT;
|
||||||
|
|
||||||
|
memcpy(&Buffer[Offset], _rEvent.m_PayLoad, MAX_PAYLOAD);
|
||||||
|
Offset += MAX_PAYLOAD;
|
||||||
|
|
||||||
|
g_WiimoteInitialize.pWiimoteInput(m_channelID, Buffer, Offset);
|
||||||
|
}
|
||||||
|
/////////////////////
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//******************************************************************************
|
//******************************************************************************
|
||||||
// Function Definitions
|
// Function Definitions
|
||||||
//******************************************************************************
|
//******************************************************************************
|
||||||
|
|
||||||
int Initialize()
|
int Initialize()
|
||||||
|
{
|
||||||
|
if (g_RealWiiMoteInitialized) return g_NumberOfWiiMotes;
|
||||||
|
|
||||||
|
memset(g_WiiMotes, 0, sizeof(CWiiMote*) * MAX_WIIMOTES);
|
||||||
|
|
||||||
|
// Call Wiiuse.dll
|
||||||
|
g_WiiMotesFromWiiUse = wiiuse_init(MAX_WIIMOTES);
|
||||||
|
g_NumberOfWiiMotes = wiiuse_find(g_WiiMotesFromWiiUse, MAX_WIIMOTES, 5);
|
||||||
|
|
||||||
|
if (g_NumberOfWiiMotes > 0) g_RealWiiMotePresent = true;
|
||||||
|
|
||||||
|
Console::Print("Found No of Wiimotes: %i\n", g_NumberOfWiiMotes);
|
||||||
|
|
||||||
|
// For the status window
|
||||||
|
if (!g_EmulatorRunning)
|
||||||
|
{
|
||||||
|
// Do I need this?
|
||||||
|
//int Connect = wiiuse_connect(g_WiiMotesFromWiiUse, MAX_WIIMOTES);
|
||||||
|
//Console::Print("Connected: %i\n", Connect);
|
||||||
|
|
||||||
|
wiiuse_rumble(g_WiiMotesFromWiiUse[0], 1);
|
||||||
|
wiiuse_set_leds(g_WiiMotesFromWiiUse[0], WIIMOTE_LED_4);
|
||||||
|
Sleep(40);
|
||||||
|
wiiuse_set_leds(g_WiiMotesFromWiiUse[0], WIIMOTE_LED_NONE);
|
||||||
|
Sleep(40);
|
||||||
|
wiiuse_set_leds(g_WiiMotesFromWiiUse[0], WIIMOTE_LED_4);
|
||||||
|
Sleep(120);
|
||||||
|
wiiuse_rumble(g_WiiMotesFromWiiUse[0], 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//wiiuse_disconnect(g_WiiMotesFromWiiUse);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create Wiimote clasess
|
||||||
|
for (int i = 0; i < g_NumberOfWiiMotes; i++)
|
||||||
|
g_WiiMotes[i] = new CWiiMote(i + 1, g_WiiMotesFromWiiUse[i]);
|
||||||
|
|
||||||
|
// Create a nee thread and start listening for Wiimote data
|
||||||
|
if (g_NumberOfWiiMotes > 0)
|
||||||
|
g_pReadThread = new Common::Thread(ReadWiimote_ThreadFunc, NULL);
|
||||||
|
|
||||||
|
// Initialized
|
||||||
|
if (g_NumberOfWiiMotes > 0) { g_RealWiiMoteInitialized = true; g_Shutdown = false; }
|
||||||
|
|
||||||
|
return g_NumberOfWiiMotes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoState(void* ptr, int mode) {}
|
||||||
|
|
||||||
|
void Shutdown(void)
|
||||||
|
{
|
||||||
|
g_Shutdown = true;
|
||||||
|
|
||||||
|
// Stop the thread
|
||||||
|
if (g_pReadThread != NULL)
|
||||||
|
{
|
||||||
|
g_pReadThread->WaitForDeath();
|
||||||
|
delete g_pReadThread;
|
||||||
|
g_pReadThread = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the wiimotes
|
||||||
|
for (int i = 0; i < g_NumberOfWiiMotes; i++)
|
||||||
|
{
|
||||||
|
delete g_WiiMotes[i];
|
||||||
|
g_WiiMotes[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up wiiuse
|
||||||
|
wiiuse_cleanup(g_WiiMotesFromWiiUse, g_NumberOfWiiMotes);
|
||||||
|
|
||||||
|
// Uninitialized
|
||||||
|
g_RealWiiMoteInitialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size)
|
||||||
|
{
|
||||||
|
g_WiiMotes[0]->SendData(_channelID, (const u8*)_pData, _Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ControlChannel(u16 _channelID, const void* _pData, u32 _Size)
|
||||||
|
{
|
||||||
|
g_WiiMotes[0]->SendData(_channelID, (const u8*)_pData, _Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////
|
||||||
|
// Read the Wiimote once
|
||||||
|
// ---------------
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < g_NumberOfWiiMotes; i++)
|
||||||
{
|
{
|
||||||
memset(g_WiiMotes, 0, sizeof(CWiiMote*) * MAX_WIIMOTES);
|
g_WiiMotes[i]->Update();
|
||||||
|
|
||||||
// Call Wiiuse.dll
|
|
||||||
g_WiiMotesFromWiiUse = wiiuse_init(MAX_WIIMOTES);
|
|
||||||
g_NumberOfWiiMotes = wiiuse_find(g_WiiMotesFromWiiUse, MAX_WIIMOTES, 5);
|
|
||||||
|
|
||||||
for (int i=0; i<g_NumberOfWiiMotes; i++)
|
|
||||||
{
|
|
||||||
g_WiiMotes[i] = new CWiiMote(i+1, g_WiiMotesFromWiiUse[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_NumberOfWiiMotes > 0)
|
|
||||||
g_pReadThread = new Common::Thread(ReadWiimote_ThreadFunc, NULL);
|
|
||||||
|
|
||||||
return g_NumberOfWiiMotes;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DoState(void* ptr, int mode)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void Shutdown(void)
|
|
||||||
{
|
|
||||||
g_Shutdown = true;
|
|
||||||
|
|
||||||
// stop the thread
|
|
||||||
if (g_pReadThread != NULL)
|
|
||||||
{
|
|
||||||
g_pReadThread->WaitForDeath();
|
|
||||||
delete g_pReadThread;
|
|
||||||
g_pReadThread = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// delete the wiimotes
|
|
||||||
for (int i=0; i<g_NumberOfWiiMotes; i++)
|
|
||||||
{
|
|
||||||
delete g_WiiMotes[i];
|
|
||||||
g_WiiMotes[i] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// clean up wiiuse
|
|
||||||
wiiuse_cleanup(g_WiiMotesFromWiiUse, g_NumberOfWiiMotes);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size)
|
|
||||||
{
|
|
||||||
g_WiiMotes[0]->SendData(_channelID, (const u8*)_pData, _Size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ControlChannel(u16 _channelID, const void* _pData, u32 _Size)
|
|
||||||
{
|
|
||||||
g_WiiMotes[0]->SendData(_channelID, (const u8*)_pData, _Size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Update()
|
|
||||||
{
|
|
||||||
for (int i=0; i<g_NumberOfWiiMotes; i++)
|
|
||||||
{
|
|
||||||
g_WiiMotes[i]->Update();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////
|
||||||
|
// Continuously read the Wiimote status
|
||||||
|
// ---------------
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
DWORD WINAPI ReadWiimote_ThreadFunc(void* arg)
|
DWORD WINAPI ReadWiimote_ThreadFunc(void* arg)
|
||||||
#else
|
#else
|
||||||
void *ReadWiimote_ThreadFunc(void* arg)
|
void *ReadWiimote_ThreadFunc(void* arg)
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
|
while (!g_Shutdown)
|
||||||
{
|
{
|
||||||
while (!g_Shutdown)
|
if(g_EmulatorRunning)
|
||||||
{
|
for (int i = 0; i < g_NumberOfWiiMotes; i++) g_WiiMotes[i]->ReadData();
|
||||||
for (int i=0; i<g_NumberOfWiiMotes; i++)
|
else
|
||||||
{
|
ReadWiimote();
|
||||||
g_WiiMotes[i]->ReadData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
////////////////////
|
||||||
|
|
||||||
|
|
||||||
}; // end of namespace
|
}; // end of namespace
|
||||||
|
|
||||||
|
|
|
@ -19,16 +19,31 @@
|
||||||
#ifndef WIIMOTE_REAL_H
|
#ifndef WIIMOTE_REAL_H
|
||||||
#define WIIMOTE_REAL_H
|
#define WIIMOTE_REAL_H
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Includes
|
||||||
|
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
|
||||||
|
#include "wiiuse.h"
|
||||||
|
///////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
namespace WiiMoteReal
|
namespace WiiMoteReal
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#define MAX_WIIMOTES 1
|
||||||
|
|
||||||
int Initialize();
|
int Initialize();
|
||||||
void DoState(void* ptr, int mode);
|
void DoState(void* ptr, int mode);
|
||||||
void Shutdown(void);
|
void Shutdown(void);
|
||||||
void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size);
|
void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size);
|
||||||
void ControlChannel(u16 _channelID, const void* _pData, u32 _Size) ;
|
void ControlChannel(u16 _channelID, const void* _pData, u32 _Size);
|
||||||
void Update();
|
void Update();
|
||||||
|
void ReadWiimote();
|
||||||
|
|
||||||
};
|
#ifndef EXCLUDE_H
|
||||||
|
extern wiimote_t** g_WiiMotesFromWiiUse;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}; // WiiMoteReal
|
||||||
|
|
||||||
#endif
|
#endif
|
Loading…
Reference in New Issue