More improvements to new wiimote plugin: Added emulated Drums/Guitar extensions. Wiimote rumble now handled for every output report. Fixed some mem leaks. Hopefully fixed a floating point exception in Linux, thanks to glennrics.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5403 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
1d8db5ce3f
commit
23689387e1
|
@ -57,6 +57,7 @@ public:
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual std::string GetName() const = 0;
|
virtual std::string GetName() const = 0;
|
||||||
|
virtual ~Control() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -138,6 +139,8 @@ public:
|
||||||
public:
|
public:
|
||||||
ControlQualifier() {};
|
ControlQualifier() {};
|
||||||
ControlQualifier( const std::string& _name ) : name(_name) {}
|
ControlQualifier( const std::string& _name ) : name(_name) {}
|
||||||
|
virtual ~ControlQualifier() {}
|
||||||
|
|
||||||
virtual bool operator==(const Device::Control* const in) const;
|
virtual bool operator==(const Device::Control* const in) const;
|
||||||
void FromControl(const Device::Control* const in);
|
void FromControl(const Device::Control* const in);
|
||||||
|
|
||||||
|
@ -184,6 +187,7 @@ public:
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ControlReference( const bool _is_input ) : range(1), is_input(_is_input), device(NULL) {}
|
ControlReference( const bool _is_input ) : range(1), is_input(_is_input), device(NULL) {}
|
||||||
|
virtual ~ControlReference() {}
|
||||||
|
|
||||||
virtual ControlState State( const ControlState state = 0 ) = 0;
|
virtual ControlState State( const ControlState state = 0 ) = 0;
|
||||||
virtual bool Detect( const unsigned int ms, const unsigned int count = 1 ) = 0;
|
virtual bool Detect( const unsigned int ms, const unsigned int count = 1 ) = 0;
|
||||||
|
|
|
@ -48,7 +48,7 @@ void Plugin::SaveConfig()
|
||||||
(*i)->SaveConfig( inifile[ (*i)->GetName() ] );
|
(*i)->SaveConfig( inifile[ (*i)->GetName() ] );
|
||||||
|
|
||||||
// dont need to save empty values
|
// dont need to save empty values
|
||||||
inifile.Clean();
|
//inifile.Clean();
|
||||||
|
|
||||||
std::ofstream file;
|
std::ofstream file;
|
||||||
file.open( (std::string(File::GetUserPath(D_CONFIG_IDX)) + ini_name + ".ini" ).c_str() );
|
file.open( (std::string(File::GetUserPath(D_CONFIG_IDX)) + ini_name + ".ini" ).c_str() );
|
||||||
|
|
|
@ -714,24 +714,36 @@ ControlGroupBox::ControlGroupBox( ControllerEmu::ControlGroup* const group, wxWi
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GROUP_TYPE_MIXED_TRIGGERS :
|
case GROUP_TYPE_MIXED_TRIGGERS :
|
||||||
|
case GROUP_TYPE_TRIGGERS :
|
||||||
{
|
{
|
||||||
wxBitmap bitmap(64+12+1, int(6*group->controls.size())+1);
|
int height = (int)(6 * group->controls.size());
|
||||||
|
int width = 64+12+1;
|
||||||
|
if (GROUP_TYPE_TRIGGERS == group->type)
|
||||||
|
{
|
||||||
|
height *= 2;
|
||||||
|
width = 64;
|
||||||
|
}
|
||||||
|
wxBitmap bitmap(width, height+1);
|
||||||
wxMemoryDC dc;
|
wxMemoryDC dc;
|
||||||
dc.SelectObject(bitmap);
|
dc.SelectObject(bitmap);
|
||||||
dc.Clear();
|
dc.Clear();
|
||||||
dc.SelectObject(wxNullBitmap);
|
dc.SelectObject(wxNullBitmap);
|
||||||
static_bitmap = new wxStaticBitmap( parent, -1, bitmap, wxDefaultPosition, wxDefaultSize, wxBITMAP_TYPE_BMP );
|
static_bitmap = new wxStaticBitmap( parent, -1, bitmap, wxDefaultPosition, wxDefaultSize, wxBITMAP_TYPE_BMP );
|
||||||
|
|
||||||
PadSettingChoice* threshold_cbox = new PadSettingChoice( parent, group->settings[0] );
|
std::vector<ControllerEmu::ControlGroup::Setting*>::const_iterator
|
||||||
_connect_macro_( threshold_cbox, GamepadPage::AdjustSetting, wxEVT_COMMAND_CHOICE_SELECTED, eventsink );
|
i = group->settings.begin(),
|
||||||
|
e = group->settings.end();
|
||||||
|
for ( ; i!=e; ++i )
|
||||||
|
{
|
||||||
|
PadSettingChoice* cbox = new PadSettingChoice( parent, *i );
|
||||||
|
_connect_macro_( cbox, GamepadPage::AdjustSetting, wxEVT_COMMAND_CHOICE_SELECTED, eventsink );
|
||||||
|
options.push_back( cbox );
|
||||||
|
wxBoxSizer* const szr = new wxBoxSizer( wxHORIZONTAL );
|
||||||
|
szr->Add( new wxStaticText( parent, -1, wxString::FromAscii( (*i)->name ) ), 0, wxCENTER|wxRIGHT, 5 );
|
||||||
|
szr->Add( cbox, 0, wxRIGHT, 5 );
|
||||||
|
Add( szr, 0, wxALL|wxCENTER, 5 );
|
||||||
|
}
|
||||||
|
|
||||||
options.push_back( threshold_cbox );
|
|
||||||
|
|
||||||
wxBoxSizer* const szr = new wxBoxSizer( wxHORIZONTAL );
|
|
||||||
szr->Add( new wxStaticText( parent, -1, wxString::FromAscii( group->settings[0]->name ) ), 0, wxCENTER|wxRIGHT, 5 );
|
|
||||||
szr->Add( threshold_cbox, 0, wxRIGHT, 5 );
|
|
||||||
|
|
||||||
Add( szr, 0, wxALL|wxCENTER, 5 );
|
|
||||||
Add( static_bitmap, 0, wxALL|wxCENTER, 5 );
|
Add( static_bitmap, 0, wxALL|wxCENTER, 5 );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -79,9 +79,9 @@ void ConfigDialog::UpdateBitmaps(wxTimerEvent& WXUNUSED(event))
|
||||||
else
|
else
|
||||||
dc.DrawRectangle( 16, 16, 32, 32 );
|
dc.DrawRectangle( 16, 16, 32, 32 );
|
||||||
|
|
||||||
// deadzone circle
|
|
||||||
if ( GROUP_TYPE_CURSOR != (*g)->control_group->type )
|
if ( GROUP_TYPE_CURSOR != (*g)->control_group->type )
|
||||||
{
|
{
|
||||||
|
// deadzone circle
|
||||||
dc.SetBrush(*wxLIGHT_GREY_BRUSH);
|
dc.SetBrush(*wxLIGHT_GREY_BRUSH);
|
||||||
dc.DrawCircle( 32, 32, ((*g)->control_group)->settings[0]->value * 32 );
|
dc.DrawCircle( 32, 32, ((*g)->control_group)->settings[0]->value * 32 );
|
||||||
|
|
||||||
|
@ -166,7 +166,52 @@ void ConfigDialog::UpdateBitmaps(wxTimerEvent& WXUNUSED(event))
|
||||||
(*g)->static_bitmap->SetBitmap( bitmap );
|
(*g)->static_bitmap->SetBitmap( bitmap );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case GROUP_TYPE_TRIGGERS :
|
||||||
|
{
|
||||||
|
const unsigned int trigger_count = ((unsigned int)((*g)->control_group->controls.size()));
|
||||||
|
// setup
|
||||||
|
wxBitmap bitmap( 64, 12*trigger_count+1);
|
||||||
|
wxMemoryDC dc;
|
||||||
|
dc.SelectObject(bitmap);
|
||||||
|
dc.Clear();
|
||||||
|
|
||||||
|
// draw the shit
|
||||||
|
dc.SetPen(*wxGREY_PEN);
|
||||||
|
ControlState deadzone = (*g)->control_group->settings[0]->value;
|
||||||
|
|
||||||
|
unsigned int* const trigs = new unsigned int[trigger_count];
|
||||||
|
((ControllerEmu::Triggers*)(*g)->control_group)->GetState( trigs, 64 );
|
||||||
|
|
||||||
|
for ( unsigned int n = 0; n < trigger_count; ++n )
|
||||||
|
{
|
||||||
|
ControlState trig_r = (*g)->control_group->controls[n]->control_ref->State();
|
||||||
|
|
||||||
|
dc.SetBrush(*wxGREY_BRUSH);
|
||||||
|
dc.DrawRectangle(0, n*12, trig_r*64, 14);
|
||||||
|
|
||||||
|
dc.SetBrush(*wxRED_BRUSH);
|
||||||
|
dc.DrawRectangle(0, n*12, trigs[n], 14);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] trigs;
|
||||||
|
|
||||||
|
// deadzone box
|
||||||
|
dc.SetPen(*wxLIGHT_GREY_PEN);
|
||||||
|
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
||||||
|
dc.DrawRectangle(0, 0, deadzone*64, trigger_count*14);
|
||||||
|
|
||||||
|
// box outline
|
||||||
|
// Windows XP color
|
||||||
|
dc.SetPen(wxPen(_T("#7f9db9")));
|
||||||
|
dc.DrawRectangle(0, 0, bitmap.GetWidth(), bitmap.GetHeight());
|
||||||
|
|
||||||
|
// done drawing
|
||||||
|
dc.SelectObject(wxNullBitmap);
|
||||||
|
|
||||||
|
// set the shit
|
||||||
|
(*g)->static_bitmap->SetBitmap( bitmap );
|
||||||
|
}
|
||||||
|
break;
|
||||||
case GROUP_TYPE_MIXED_TRIGGERS :
|
case GROUP_TYPE_MIXED_TRIGGERS :
|
||||||
{
|
{
|
||||||
const unsigned int trigger_count = ((unsigned int)((*g)->control_group->controls.size() / 2));
|
const unsigned int trigger_count = ((unsigned int)((*g)->control_group->controls.size() / 2));
|
||||||
|
@ -194,6 +239,9 @@ void ConfigDialog::UpdateBitmaps(wxTimerEvent& WXUNUSED(event))
|
||||||
dc.DrawRectangle(trig_a*64, n*12, 64+20, 14);
|
dc.DrawRectangle(trig_a*64, n*12, 64+20, 14);
|
||||||
dc.DrawRectangle(64, n*12, 32, 14);
|
dc.DrawRectangle(64, n*12, 32, 14);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// threshold box
|
||||||
|
dc.SetPen(*wxLIGHT_GREY_PEN);
|
||||||
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
||||||
dc.DrawRectangle(thresh*64, 0, 128, trigger_count*14);
|
dc.DrawRectangle(thresh*64, 0, 128, trigger_count*14);
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,9 @@
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const char modifier[] = "Modifier";
|
|
||||||
|
|
||||||
|
|
||||||
ControllerEmu::~ControllerEmu()
|
ControllerEmu::~ControllerEmu()
|
||||||
{
|
{
|
||||||
|
// control groups
|
||||||
std::vector<ControlGroup*>::const_iterator
|
std::vector<ControlGroup*>::const_iterator
|
||||||
i = groups.begin(),
|
i = groups.begin(),
|
||||||
e = groups.end();
|
e = groups.end();
|
||||||
|
@ -18,12 +16,14 @@ ControllerEmu::~ControllerEmu()
|
||||||
|
|
||||||
ControllerEmu::ControlGroup::~ControlGroup()
|
ControllerEmu::ControlGroup::~ControlGroup()
|
||||||
{
|
{
|
||||||
|
// controls
|
||||||
std::vector<Control*>::const_iterator
|
std::vector<Control*>::const_iterator
|
||||||
ci = controls.begin(),
|
ci = controls.begin(),
|
||||||
ce = controls.end();
|
ce = controls.end();
|
||||||
for ( ; ci!=ce; ++ci )
|
for ( ; ci!=ce; ++ci )
|
||||||
delete *ci;
|
delete *ci;
|
||||||
|
|
||||||
|
// settings
|
||||||
std::vector<Setting*>::const_iterator
|
std::vector<Setting*>::const_iterator
|
||||||
si = settings.begin(),
|
si = settings.begin(),
|
||||||
se = settings.end();
|
se = settings.end();
|
||||||
|
@ -31,6 +31,20 @@ ControllerEmu::ControlGroup::~ControlGroup()
|
||||||
delete *si;
|
delete *si;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ControllerEmu::Extension::~Extension()
|
||||||
|
{
|
||||||
|
// attachments
|
||||||
|
std::vector<ControllerEmu*>::const_iterator
|
||||||
|
ai = attachments.begin(),
|
||||||
|
ae = attachments.end();
|
||||||
|
for ( ; ai!=ae; ++ai )
|
||||||
|
delete *ai;
|
||||||
|
}
|
||||||
|
ControllerEmu::ControlGroup::Control::~Control()
|
||||||
|
{
|
||||||
|
delete control_ref;
|
||||||
|
}
|
||||||
|
|
||||||
void ControllerEmu::UpdateReferences( ControllerInterface& devi )
|
void ControllerEmu::UpdateReferences( ControllerInterface& devi )
|
||||||
{
|
{
|
||||||
std::vector<ControlGroup*>::const_iterator
|
std::vector<ControlGroup*>::const_iterator
|
||||||
|
@ -170,7 +184,7 @@ void ControllerEmu::ControlGroup::SaveConfig( IniFile::Section& sec, const std::
|
||||||
for ( ; ci!=ce; ++ci )
|
for ( ; ci!=ce; ++ci )
|
||||||
{
|
{
|
||||||
// control and dev qualifier
|
// control and dev qualifier
|
||||||
sec[group + (*ci)->name] = (*ci)->control_ref->control_qualifier.name;
|
sec.Set( group+(*ci)->name, (*ci)->control_ref->control_qualifier.name );
|
||||||
sec.Set( group+(*ci)->name+"/Device", (*ci)->control_ref->device_qualifier.ToString(), defdev );
|
sec.Set( group+(*ci)->name+"/Device", (*ci)->control_ref->device_qualifier.ToString(), defdev );
|
||||||
|
|
||||||
// range
|
// range
|
||||||
|
@ -200,7 +214,7 @@ void ControllerEmu::SaveConfig( IniFile::Section& sec, const std::string& base )
|
||||||
{
|
{
|
||||||
const std::string defdev = default_device.ToString();
|
const std::string defdev = default_device.ToString();
|
||||||
if ( base.empty() )
|
if ( base.empty() )
|
||||||
sec[ std::string(" ") + base + "Device" ] = defdev;
|
sec.Set( std::string(" ") + base + "Device", defdev );
|
||||||
|
|
||||||
std::vector<ControlGroup*>::const_iterator i = groups.begin(),
|
std::vector<ControlGroup*>::const_iterator i = groups.begin(),
|
||||||
e = groups.end();
|
e = groups.end();
|
||||||
|
@ -213,7 +227,7 @@ ControllerEmu::AnalogStick::AnalogStick( const char* const _name ) : ControlGrou
|
||||||
for ( unsigned int i = 0; i < 4; ++i )
|
for ( unsigned int i = 0; i < 4; ++i )
|
||||||
controls.push_back( new Input( named_directions[i] ) );
|
controls.push_back( new Input( named_directions[i] ) );
|
||||||
|
|
||||||
controls.push_back( new Input( modifier ) );
|
controls.push_back( new Input( "Modifier" ) );
|
||||||
|
|
||||||
settings.push_back( new Setting("Dead Zone", 0, 1, 50 ) );
|
settings.push_back( new Setting("Dead Zone", 0, 1, 50 ) );
|
||||||
settings.push_back( new Setting("Square Stick", 0 ) );
|
settings.push_back( new Setting("Square Stick", 0 ) );
|
||||||
|
@ -230,6 +244,11 @@ ControllerEmu::MixedTriggers::MixedTriggers( const char* const _name ) : Control
|
||||||
settings.push_back( new Setting("Threshold", 0.9f ) );
|
settings.push_back( new Setting("Threshold", 0.9f ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ControllerEmu::Triggers::Triggers( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_TRIGGERS )
|
||||||
|
{
|
||||||
|
settings.push_back( new Setting("Dead Zone", 0, 1, 50 ) );
|
||||||
|
}
|
||||||
|
|
||||||
ControllerEmu::Force::Force( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_FORCE )
|
ControllerEmu::Force::Force( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_FORCE )
|
||||||
{
|
{
|
||||||
controls.push_back( new Input( "X-" ) );
|
controls.push_back( new Input( "X-" ) );
|
||||||
|
@ -255,7 +274,7 @@ ControllerEmu::Tilt::Tilt( const char* const _name ) : ControlGroup( _name, GROU
|
||||||
controls.push_back( new Input( "Left" ) );
|
controls.push_back( new Input( "Left" ) );
|
||||||
controls.push_back( new Input( "Right" ) );
|
controls.push_back( new Input( "Right" ) );
|
||||||
|
|
||||||
controls.push_back( new Input( modifier ) );
|
controls.push_back( new Input( "Modifier" ) );
|
||||||
|
|
||||||
settings.push_back( new Setting("Dead Zone", 0, 1, 50 ) );
|
settings.push_back( new Setting("Dead Zone", 0, 1, 50 ) );
|
||||||
settings.push_back( new Setting("Circle Stick", 0 ) );
|
settings.push_back( new Setting("Circle Stick", 0 ) );
|
||||||
|
@ -275,31 +294,6 @@ ControllerEmu::Cursor::Cursor( const char* const _name, const SWiimoteInitialize
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//void GetMousePos(float& x, float& y, const SWiimoteInitialize* const wiimote_initialize)
|
|
||||||
//{
|
|
||||||
//#ifdef _WIN32
|
|
||||||
// // Get the cursor position for the entire screen
|
|
||||||
// POINT point;
|
|
||||||
// GetCursorPos(&point);
|
|
||||||
// // Get the cursor position relative to the upper left corner of the rendering window
|
|
||||||
// ScreenToClient(wiimote_initialize->hWnd, &point);
|
|
||||||
//
|
|
||||||
// // Get the size of the rendering window. (In my case Rect.top and Rect.left was zero.)
|
|
||||||
// RECT Rect;
|
|
||||||
// GetClientRect(wiimote_initialize->hWnd, &Rect);
|
|
||||||
// // Width and height is the size of the rendering window
|
|
||||||
// float WinWidth = (float)(Rect.right - Rect.left);
|
|
||||||
// float WinHeight = (float)(Rect.bottom - Rect.top);
|
|
||||||
// float XOffset = 0, YOffset = 0;
|
|
||||||
// float PictureWidth = WinWidth, PictureHeight = WinHeight;
|
|
||||||
//#endif
|
|
||||||
//
|
|
||||||
// x = ((float)point.x - XOffset) / PictureWidth;
|
|
||||||
// y = ((float)point.y - YOffset) / PictureHeight;
|
|
||||||
// x *=2; x-=1;
|
|
||||||
// y *=2; y-=1;
|
|
||||||
//}
|
|
||||||
|
|
||||||
void GetMousePos(float& x, float& y, const SWiimoteInitialize* const wiimote_initialize)
|
void GetMousePos(float& x, float& y, const SWiimoteInitialize* const wiimote_initialize)
|
||||||
{
|
{
|
||||||
unsigned int win_width = 2, win_height = 2;
|
unsigned int win_width = 2, win_height = 2;
|
||||||
|
|
|
@ -28,6 +28,7 @@ enum
|
||||||
GROUP_TYPE_EXTENSION,
|
GROUP_TYPE_EXTENSION,
|
||||||
GROUP_TYPE_TILT,
|
GROUP_TYPE_TILT,
|
||||||
GROUP_TYPE_CURSOR,
|
GROUP_TYPE_CURSOR,
|
||||||
|
GROUP_TYPE_TRIGGERS,
|
||||||
};
|
};
|
||||||
|
|
||||||
const char * const named_directions[] =
|
const char * const named_directions[] =
|
||||||
|
@ -55,9 +56,7 @@ public:
|
||||||
: control_ref(_ref), name(_name){}
|
: control_ref(_ref), name(_name){}
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
virtual ~Control();
|
||||||
//virtual std::string GetName() const = 0;
|
|
||||||
|
|
||||||
ControllerInterface::ControlReference* const control_ref;
|
ControllerInterface::ControlReference* const control_ref;
|
||||||
const char * const name;
|
const char * const name;
|
||||||
|
|
||||||
|
@ -105,7 +104,6 @@ public:
|
||||||
void LoadConfig( IniFile::Section& sec, const std::string& defdev = "", const std::string& base = "" );
|
void LoadConfig( IniFile::Section& sec, const std::string& defdev = "", const std::string& base = "" );
|
||||||
void SaveConfig( IniFile::Section& sec, const std::string& defdev = "", const std::string& base = "" );
|
void SaveConfig( IniFile::Section& sec, const std::string& defdev = "", const std::string& base = "" );
|
||||||
|
|
||||||
//const unsigned int type;
|
|
||||||
const char* const name;
|
const char* const name;
|
||||||
const unsigned int type;
|
const unsigned int type;
|
||||||
|
|
||||||
|
@ -147,7 +145,7 @@ public:
|
||||||
ControlState ang_cos = cos(ang);
|
ControlState ang_cos = cos(ang);
|
||||||
|
|
||||||
// the amt a full square stick would have at current angle
|
// the amt a full square stick would have at current angle
|
||||||
ControlState square_full = std::min( 1/abs(ang_sin), 1/abs(ang_cos) );
|
ControlState square_full = std::min( ang_sin ? 1/abs(ang_sin) : 2, ang_cos ? 1/abs(ang_cos) : 2 );
|
||||||
|
|
||||||
// the amt a full stick would have that was ( user setting squareness) at current angle
|
// the amt a full stick would have that was ( user setting squareness) at current angle
|
||||||
// i think this is more like a pointed circle rather than a rounded square like it should be
|
// i think this is more like a pointed circle rather than a rounded square like it should be
|
||||||
|
@ -217,6 +215,23 @@ public:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Triggers : public ControlGroup
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
template <typename S>
|
||||||
|
void GetState( S* analog, const unsigned int range )
|
||||||
|
{
|
||||||
|
const unsigned int trig_count = ((unsigned int) (controls.size()));
|
||||||
|
const ControlState deadzone = settings[0]->value;
|
||||||
|
for ( unsigned int i=0; i<trig_count; ++i,++analog )
|
||||||
|
*analog = S( std::max(controls[i]->control_ref->State() - deadzone, 0.0f) / (1 - deadzone) * range );
|
||||||
|
}
|
||||||
|
|
||||||
|
Triggers( const char* const _name );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class Force : public ControlGroup
|
class Force : public ControlGroup
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -259,7 +274,7 @@ public:
|
||||||
ControlState ang_cos = cos(ang);
|
ControlState ang_cos = cos(ang);
|
||||||
|
|
||||||
// the amt a full square stick would have at current angle
|
// the amt a full square stick would have at current angle
|
||||||
ControlState square_full = std::min( 1/abs(ang_sin), 1/abs(ang_cos) );
|
ControlState square_full = std::min( ang_sin ? 1/abs(ang_sin) : 2, ang_cos ? 1/abs(ang_cos) : 2 );
|
||||||
|
|
||||||
// the amt a full stick would have that was ( user setting circular ) at current angle
|
// the amt a full stick would have that was ( user setting circular ) at current angle
|
||||||
// i think this is more like a pointed circle rather than a rounded square like it should be
|
// i think this is more like a pointed circle rather than a rounded square like it should be
|
||||||
|
@ -292,12 +307,6 @@ public:
|
||||||
template <typename C>
|
template <typename C>
|
||||||
void GetState( C* const x, C* const y, C* const forward, const bool adjusted = false )
|
void GetState( C* const x, C* const y, C* const forward, const bool adjusted = false )
|
||||||
{
|
{
|
||||||
// this is flawed when GetState() isn't called at regular intervals
|
|
||||||
//const ControlState zz = controls[4]->control_ref->State();
|
|
||||||
//if (z < zz)
|
|
||||||
// z = std::min( z + 0.01f, zz );
|
|
||||||
//else
|
|
||||||
// z = std::max( z - 0.01f, zz );
|
|
||||||
const ControlState z = controls[4]->control_ref->State();
|
const ControlState z = controls[4]->control_ref->State();
|
||||||
|
|
||||||
// hide
|
// hide
|
||||||
|
@ -335,7 +344,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//ControlState z;
|
|
||||||
const SWiimoteInitialize* const wiimote_initialize;
|
const SWiimoteInitialize* const wiimote_initialize;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -347,6 +355,7 @@ public:
|
||||||
: ControlGroup( _name, GROUP_TYPE_EXTENSION )
|
: ControlGroup( _name, GROUP_TYPE_EXTENSION )
|
||||||
, switch_extension(0)
|
, switch_extension(0)
|
||||||
, active_extension(0) {}
|
, active_extension(0) {}
|
||||||
|
~Extension();
|
||||||
|
|
||||||
void GetState( u8* const data, const bool focus = true );
|
void GetState( u8* const data, const bool focus = true );
|
||||||
|
|
||||||
|
@ -368,8 +377,6 @@ public:
|
||||||
|
|
||||||
std::vector< ControlGroup* > groups;
|
std::vector< ControlGroup* > groups;
|
||||||
|
|
||||||
ControlGroup* options;
|
|
||||||
|
|
||||||
ControllerInterface::DeviceQualifier default_device;
|
ControllerInterface::DeviceQualifier default_device;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -64,8 +64,8 @@ GCPad::GCPad( const unsigned int index ) : m_index(index)
|
||||||
m_dpad->controls.push_back( new ControlGroup::Input( named_directions[i] ) );
|
m_dpad->controls.push_back( new ControlGroup::Input( named_directions[i] ) );
|
||||||
|
|
||||||
// options
|
// options
|
||||||
groups.push_back( options = new ControlGroup( "Options" ) );
|
groups.push_back( m_options = new ControlGroup( "Options" ) );
|
||||||
options->settings.push_back( new ControlGroup::Setting( "Background Input", false ) );
|
m_options->settings.push_back( new ControlGroup::Setting( "Background Input", false ) );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,25 +76,33 @@ std::string GCPad::GetName() const
|
||||||
|
|
||||||
void GCPad::GetInput( SPADStatus* const pad )
|
void GCPad::GetInput( SPADStatus* const pad )
|
||||||
{
|
{
|
||||||
std::vector< ControlGroup::Control* >::iterator i,e;
|
// if window has focus or background input enabled
|
||||||
|
if (g_PADInitialize->pRendererHasFocus() || m_options[0].settings[0]->value )
|
||||||
|
{
|
||||||
|
// buttons
|
||||||
|
m_buttons->GetState( &pad->button, button_bitmasks );
|
||||||
|
|
||||||
// buttons
|
// TODO: set analog A/B analog to full or w/e, prolly not needed
|
||||||
m_buttons->GetState( &pad->button, button_bitmasks );
|
|
||||||
|
|
||||||
// TODO: set analog A/B to full or w/e
|
// dpad
|
||||||
|
m_dpad->GetState( &pad->button, dpad_bitmasks );
|
||||||
|
|
||||||
// dpad
|
// sticks
|
||||||
m_dpad->GetState( &pad->button, dpad_bitmasks );
|
m_main_stick->GetState( &pad->stickX, &pad->stickY, 0x80, 127 );
|
||||||
|
m_c_stick->GetState( &pad->substickX, &pad->substickY, 0x80, 127 );
|
||||||
|
|
||||||
// sticks
|
// triggers
|
||||||
m_main_stick->GetState( &pad->stickX, &pad->stickY, 0x80, 127 );
|
m_triggers->GetState( &pad->button, trigger_bitmasks, &pad->triggerLeft, 0xFF );
|
||||||
m_c_stick->GetState( &pad->substickX, &pad->substickY, 0x80, 127 );
|
}
|
||||||
|
else
|
||||||
// triggers
|
{
|
||||||
m_triggers->GetState( &pad->button, trigger_bitmasks, &pad->triggerLeft, 0xFF );
|
// center sticks
|
||||||
|
memset( &pad->stickX, 0x80, 4 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GCPad::SetOutput( const bool on )
|
void GCPad::SetOutput( const bool on )
|
||||||
{
|
{
|
||||||
m_rumble->controls[0]->control_ref->State( on );
|
// only rumble if window has focus or background input is enabled
|
||||||
|
m_rumble->controls[0]->control_ref->State( on && (g_PADInitialize->pRendererHasFocus() || m_options[0].settings[0]->value) );
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#include <ControllerEmu.h>
|
#include <ControllerEmu.h>
|
||||||
|
|
||||||
|
extern SPADInitialize *g_PADInitialize;
|
||||||
|
|
||||||
class GCPad : public ControllerEmu
|
class GCPad : public ControllerEmu
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -22,6 +24,7 @@ private:
|
||||||
Buttons* m_dpad;
|
Buttons* m_dpad;
|
||||||
MixedTriggers* m_triggers;
|
MixedTriggers* m_triggers;
|
||||||
ControlGroup* m_rumble;
|
ControlGroup* m_rumble;
|
||||||
|
ControlGroup* m_options;
|
||||||
|
|
||||||
const unsigned int m_index;
|
const unsigned int m_index;
|
||||||
|
|
||||||
|
|
|
@ -161,19 +161,8 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
|
||||||
}
|
}
|
||||||
_last_numPAD = _numPAD;
|
_last_numPAD = _numPAD;
|
||||||
|
|
||||||
// if we want background input or have focus
|
// get input
|
||||||
if ( g_plugin.controllers[_numPAD]->options[0].settings[0]->value || g_PADInitialize->pRendererHasFocus() )
|
((GCPad*)g_plugin.controllers[ _numPAD ])->GetInput( _pPADStatus );
|
||||||
{
|
|
||||||
// get input
|
|
||||||
((GCPad*)g_plugin.controllers[ _numPAD ])->GetInput( _pPADStatus );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// center sticks
|
|
||||||
memset( &_pPADStatus->stickX, 0x80, 4 );
|
|
||||||
// stop rumble
|
|
||||||
((GCPad*)g_plugin.controllers[ _numPAD ])->SetOutput( false );
|
|
||||||
}
|
|
||||||
|
|
||||||
// leave
|
// leave
|
||||||
g_plugin.controls_crit.Leave();
|
g_plugin.controls_crit.Leave();
|
||||||
|
@ -202,9 +191,9 @@ void PAD_Rumble(u8 _numPAD, unsigned int _uType, unsigned int _uStrength)
|
||||||
// enter
|
// enter
|
||||||
if ( g_plugin.controls_crit.TryEnter() )
|
if ( g_plugin.controls_crit.TryEnter() )
|
||||||
{
|
{
|
||||||
// only on/off rumble, if we have focus or background input on
|
// TODO: this has potential to not stop rumble if user is messing with GUI at the perfect time
|
||||||
if ( g_plugin.controllers[_numPAD]->options[0].settings[0]->value || g_PADInitialize->pRendererHasFocus() )
|
// set rumble
|
||||||
((GCPad*)g_plugin.controllers[ _numPAD ])->SetOutput( 1 == _uType && _uStrength > 2 );
|
((GCPad*)g_plugin.controllers[ _numPAD ])->SetOutput( 1 == _uType && _uStrength > 2 );
|
||||||
|
|
||||||
// leave
|
// leave
|
||||||
g_plugin.controls_crit.Leave();
|
g_plugin.controls_crit.Leave();
|
||||||
|
|
|
@ -571,6 +571,22 @@
|
||||||
RelativePath=".\Src\WiimoteEmu\Attachment\Classic.h"
|
RelativePath=".\Src\WiimoteEmu\Attachment\Classic.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Src\WiimoteEmu\Attachment\Drums.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Src\WiimoteEmu\Attachment\Drums.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Src\WiimoteEmu\Attachment\Guitar.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Src\WiimoteEmu\Attachment\Guitar.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Src\WiimoteEmu\Attachment\Nunchuk.cpp"
|
RelativePath=".\Src\WiimoteEmu\Attachment\Nunchuk.cpp"
|
||||||
>
|
>
|
||||||
|
|
|
@ -11,6 +11,8 @@ files = [
|
||||||
'WiimoteEmu/Attachment/Classic.cpp',
|
'WiimoteEmu/Attachment/Classic.cpp',
|
||||||
'WiimoteEmu/Attachment/Attachment.cpp',
|
'WiimoteEmu/Attachment/Attachment.cpp',
|
||||||
'WiimoteEmu/Attachment/Nunchuk.cpp',
|
'WiimoteEmu/Attachment/Nunchuk.cpp',
|
||||||
|
'WiimoteEmu/Attachment/Drums.cpp',
|
||||||
|
'WiimoteEmu/Attachment/Guitar.cpp',
|
||||||
'WiimoteEmu/EmuSubroutines.cpp',
|
'WiimoteEmu/EmuSubroutines.cpp',
|
||||||
'WiimoteEmu/Encryption.cpp',
|
'WiimoteEmu/Encryption.cpp',
|
||||||
'WiimoteNew.cpp',
|
'WiimoteNew.cpp',
|
||||||
|
|
|
@ -5,8 +5,6 @@ namespace WiimoteEmu
|
||||||
{
|
{
|
||||||
|
|
||||||
// Extension device IDs to be written to the last bytes of the extension reg
|
// Extension device IDs to be written to the last bytes of the extension reg
|
||||||
static const u8 gh3glp_id[] = { 0x00, 0x00, 0xa4, 0x20, 0x01, 0x03 };
|
|
||||||
static const u8 ghwtdrums_id[] = { 0x01, 0x00, 0xa4, 0x20, 0x01, 0x03 };
|
|
||||||
// The id for nothing inserted
|
// The id for nothing inserted
|
||||||
static const u8 nothing_id[] = { 0x00, 0x00, 0x00, 0x00, 0x2e, 0x2e };
|
static const u8 nothing_id[] = { 0x00, 0x00, 0x00, 0x00, 0x2e, 0x2e };
|
||||||
// The id for a partially inserted extension
|
// The id for a partially inserted extension
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
namespace WiimoteEmu
|
namespace WiimoteEmu
|
||||||
{
|
{
|
||||||
|
|
||||||
static const u8 classic_id[] = { 0x00, 0x00, 0xa4, 0x20, 0x01, 0x01 };
|
static const u8 classic_id[] = { 0x00, 0x00, 0xa4, 0x20, 0x01, 0x01 };
|
||||||
/* Classic Controller calibration */
|
/* Classic Controller calibration */
|
||||||
static const u8 classic_calibration[] =
|
static const u8 classic_calibration[] =
|
||||||
{
|
{
|
||||||
|
@ -68,7 +68,7 @@ const u16 classic_dpad_bitmasks[] =
|
||||||
CLASSIC_PAD_UP, CLASSIC_PAD_DOWN, CLASSIC_PAD_LEFT, CLASSIC_PAD_RIGHT
|
CLASSIC_PAD_UP, CLASSIC_PAD_DOWN, CLASSIC_PAD_LEFT, CLASSIC_PAD_RIGHT
|
||||||
};
|
};
|
||||||
|
|
||||||
Classic::Classic() : Attachment( "Classic Controller" )
|
Classic::Classic() : Attachment( "Classic" )
|
||||||
{
|
{
|
||||||
// buttons
|
// buttons
|
||||||
groups.push_back( m_buttons = new Buttons( "Buttons" ) );
|
groups.push_back( m_buttons = new Buttons( "Buttons" ) );
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
#include "Drums.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace WiimoteEmu
|
||||||
|
{
|
||||||
|
|
||||||
|
static const u8 drums_id[] = { 0x01, 0x00, 0xa4, 0x20, 0x01, 0x03 };
|
||||||
|
|
||||||
|
// drums buttons
|
||||||
|
#define DRUMS_PLUS 0x04
|
||||||
|
#define DRUMS_MINUS 0x10
|
||||||
|
|
||||||
|
#define DRUMS_BASS 0x0400
|
||||||
|
#define DRUMS_BLUE 0x0800
|
||||||
|
#define DRUMS_GREEN 0x1000
|
||||||
|
#define DRUMS_YELLOW 0x2000
|
||||||
|
#define DRUMS_RED 0x4000
|
||||||
|
#define DRUMS_ORANGE 0x8000
|
||||||
|
|
||||||
|
const u16 drum_pad_bitmasks[] =
|
||||||
|
{
|
||||||
|
DRUMS_RED,
|
||||||
|
DRUMS_BLUE,
|
||||||
|
DRUMS_GREEN,
|
||||||
|
DRUMS_YELLOW,
|
||||||
|
DRUMS_ORANGE,
|
||||||
|
DRUMS_BASS,
|
||||||
|
};
|
||||||
|
|
||||||
|
const char* drum_pad_names[] =
|
||||||
|
{
|
||||||
|
"Red","Blue","Green","Yellow","Orange","Bass"
|
||||||
|
};
|
||||||
|
|
||||||
|
const u16 drum_button_bitmasks[] =
|
||||||
|
{
|
||||||
|
DRUMS_MINUS,
|
||||||
|
DRUMS_PLUS,
|
||||||
|
};
|
||||||
|
|
||||||
|
Drums::Drums() : Attachment( "Drums" )
|
||||||
|
{
|
||||||
|
// pads
|
||||||
|
groups.push_back( m_pads = new Buttons( "Pads" ) );
|
||||||
|
for ( unsigned int i = 0; i < sizeof(drum_pad_names)/sizeof(*drum_pad_names); ++i )
|
||||||
|
m_pads->controls.push_back( new ControlGroup::Input( drum_pad_names[i] ) );
|
||||||
|
|
||||||
|
// stick
|
||||||
|
groups.push_back( m_stick = new AnalogStick( "Stick" ) );
|
||||||
|
|
||||||
|
// buttons
|
||||||
|
groups.push_back( m_buttons = new Buttons( "Buttons" ) );
|
||||||
|
m_buttons->controls.push_back( new ControlGroup::Input("Minus") );
|
||||||
|
m_buttons->controls.push_back( new ControlGroup::Input("Plus") );
|
||||||
|
|
||||||
|
// set up register
|
||||||
|
// id
|
||||||
|
memcpy( ®[0xfa], drums_id, sizeof(drums_id) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Drums::GetState(u8* const data, const bool focus)
|
||||||
|
{
|
||||||
|
wm_drums_extension* const ddata = (wm_drums_extension*)data;
|
||||||
|
|
||||||
|
// calibration data not figured out yet?
|
||||||
|
|
||||||
|
// stick
|
||||||
|
{
|
||||||
|
u8 x, y;
|
||||||
|
m_stick->GetState( &x, &y, 0x20, focus ? 0x1F /*0x15*/ : 0 );
|
||||||
|
|
||||||
|
ddata->sx = x;
|
||||||
|
ddata->sy = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: softness maybe
|
||||||
|
data[2] = 0xFF;
|
||||||
|
data[3] = 0xFF;
|
||||||
|
|
||||||
|
if (focus)
|
||||||
|
{
|
||||||
|
// buttons
|
||||||
|
m_buttons->GetState( &ddata->bt, drum_button_bitmasks );
|
||||||
|
// pads
|
||||||
|
m_pads->GetState( &ddata->bt, drum_pad_bitmasks );
|
||||||
|
}
|
||||||
|
|
||||||
|
// flip button bits
|
||||||
|
ddata->bt ^= 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
#include "Attachment.h"
|
||||||
|
|
||||||
|
namespace WiimoteEmu
|
||||||
|
{
|
||||||
|
|
||||||
|
class Drums : public Attachment
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Drums();
|
||||||
|
void GetState( u8* const data, const bool focus );
|
||||||
|
|
||||||
|
private:
|
||||||
|
Buttons* m_buttons;
|
||||||
|
Buttons* m_pads;
|
||||||
|
AnalogStick* m_stick;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,113 @@
|
||||||
|
#include "Guitar.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace WiimoteEmu
|
||||||
|
{
|
||||||
|
|
||||||
|
static const u8 guitar_id[] = { 0x00, 0x00, 0xa4, 0x20, 0x01, 0x03 };
|
||||||
|
|
||||||
|
// guitar buttons
|
||||||
|
#define GUITAR_PLUS 0x04
|
||||||
|
#define GUITAR_MINUS 0x10
|
||||||
|
#define GUITAR_BAR_DOWN 0x40
|
||||||
|
|
||||||
|
#define GUITAR_BAR_UP 0x0100
|
||||||
|
#define GUITAR_YELLOW 0x0800
|
||||||
|
#define GUITAR_GREEN 0x1000
|
||||||
|
#define GUITAR_BLUE 0x2000
|
||||||
|
#define GUITAR_RED 0x4000
|
||||||
|
#define GUITAR_ORANGE 0x8000
|
||||||
|
|
||||||
|
const u16 guitar_fret_bitmasks[] =
|
||||||
|
{
|
||||||
|
GUITAR_GREEN,
|
||||||
|
GUITAR_RED,
|
||||||
|
GUITAR_YELLOW,
|
||||||
|
GUITAR_BLUE,
|
||||||
|
GUITAR_ORANGE,
|
||||||
|
};
|
||||||
|
|
||||||
|
const char* guitar_fret_names[] =
|
||||||
|
{
|
||||||
|
"Green","Red","Yellow","Blue","Orange",
|
||||||
|
};
|
||||||
|
|
||||||
|
const u16 guitar_button_bitmasks[] =
|
||||||
|
{
|
||||||
|
GUITAR_MINUS,
|
||||||
|
GUITAR_PLUS,
|
||||||
|
};
|
||||||
|
|
||||||
|
const u16 guitar_strum_bitmasks[] =
|
||||||
|
{
|
||||||
|
GUITAR_BAR_UP,
|
||||||
|
GUITAR_BAR_DOWN,
|
||||||
|
};
|
||||||
|
|
||||||
|
Guitar::Guitar() : Attachment( "Guitar" )
|
||||||
|
{
|
||||||
|
// frets
|
||||||
|
groups.push_back( m_frets = new Buttons( "Frets" ) );
|
||||||
|
for ( unsigned int i = 0; i < sizeof(guitar_fret_names)/sizeof(*guitar_fret_names); ++i )
|
||||||
|
m_frets->controls.push_back( new ControlGroup::Input( guitar_fret_names[i] ) );
|
||||||
|
|
||||||
|
// stick
|
||||||
|
groups.push_back( m_stick = new AnalogStick( "Stick" ) );
|
||||||
|
|
||||||
|
// strum
|
||||||
|
groups.push_back( m_strum = new Buttons( "Strum" ) );
|
||||||
|
m_strum->controls.push_back( new ControlGroup::Input("Up") );
|
||||||
|
m_strum->controls.push_back( new ControlGroup::Input("Down") );
|
||||||
|
|
||||||
|
// whammy
|
||||||
|
groups.push_back( m_whammy = new Triggers( "Whammy" ) );
|
||||||
|
m_whammy->controls.push_back( new ControlGroup::Input("Bar") );
|
||||||
|
|
||||||
|
// buttons
|
||||||
|
groups.push_back( m_buttons = new Buttons( "Buttons" ) );
|
||||||
|
m_buttons->controls.push_back( new ControlGroup::Input("Minus") );
|
||||||
|
m_buttons->controls.push_back( new ControlGroup::Input("Plus") );
|
||||||
|
|
||||||
|
// set up register
|
||||||
|
// id
|
||||||
|
memcpy( ®[0xfa], guitar_id, sizeof(guitar_id) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Guitar::GetState(u8* const data, const bool focus)
|
||||||
|
{
|
||||||
|
wm_guitar_extension* const gdata = (wm_guitar_extension*)data;
|
||||||
|
|
||||||
|
// calibration data not figured out yet?
|
||||||
|
|
||||||
|
// stick
|
||||||
|
{
|
||||||
|
u8 x, y;
|
||||||
|
m_stick->GetState( &x, &y, 0x20, focus ? 0x1F /*0x15*/ : 0 );
|
||||||
|
|
||||||
|
gdata->sx = x;
|
||||||
|
gdata->sy = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: touch bar, probably not
|
||||||
|
gdata->tb = 0x0F; // not touched
|
||||||
|
|
||||||
|
// whammy bar
|
||||||
|
u8 whammy;
|
||||||
|
m_whammy->GetState( &whammy, 0x1F );
|
||||||
|
gdata->whammy = whammy;
|
||||||
|
|
||||||
|
if (focus)
|
||||||
|
{
|
||||||
|
// buttons
|
||||||
|
m_buttons->GetState( &gdata->bt, guitar_button_bitmasks );
|
||||||
|
// frets
|
||||||
|
m_frets->GetState( &gdata->bt, guitar_fret_bitmasks );
|
||||||
|
// strum
|
||||||
|
m_strum->GetState( &gdata->bt, guitar_strum_bitmasks );
|
||||||
|
}
|
||||||
|
|
||||||
|
// flip button bits
|
||||||
|
gdata->bt ^= 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
#include "Attachment.h"
|
||||||
|
|
||||||
|
namespace WiimoteEmu
|
||||||
|
{
|
||||||
|
|
||||||
|
class Guitar : public Attachment
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Guitar();
|
||||||
|
void GetState( u8* const data, const bool focus );
|
||||||
|
|
||||||
|
private:
|
||||||
|
Buttons* m_buttons;
|
||||||
|
Buttons* m_frets;
|
||||||
|
Buttons* m_strum;
|
||||||
|
Triggers* m_whammy;
|
||||||
|
AnalogStick* m_stick;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -4,7 +4,7 @@
|
||||||
namespace WiimoteEmu
|
namespace WiimoteEmu
|
||||||
{
|
{
|
||||||
|
|
||||||
static const u8 nunchuck_id[] = { 0x00, 0x00, 0xa4, 0x20, 0x00, 0x00 };
|
static const u8 nunchuck_id[] = { 0x00, 0x00, 0xa4, 0x20, 0x00, 0x00 };
|
||||||
/* Default calibration for the nunchuck. It should be written to 0x20 - 0x3f of the
|
/* Default calibration for the nunchuck. It should be written to 0x20 - 0x3f of the
|
||||||
extension register. 0x80 is the neutral x and y accelerators and 0xb3 is the
|
extension register. 0x80 is the neutral x and y accelerators and 0xb3 is the
|
||||||
neutral z accelerometer that is adjusted for gravity. */
|
neutral z accelerometer that is adjusted for gravity. */
|
||||||
|
|
|
@ -61,8 +61,6 @@ void Wiimote::ReportMode(const u16 _channelID, wm_report_mode* dr)
|
||||||
//DEBUG_LOG(WIIMOTE, " All The Time: %x", dr->all_the_time);
|
//DEBUG_LOG(WIIMOTE, " All The Time: %x", dr->all_the_time);
|
||||||
//DEBUG_LOG(WIIMOTE, " Mode: 0x%02x", dr->mode);
|
//DEBUG_LOG(WIIMOTE, " Mode: 0x%02x", dr->mode);
|
||||||
|
|
||||||
m_rumble_on = (dr->rumble != 0);
|
|
||||||
|
|
||||||
m_reporting_auto = dr->all_the_time;
|
m_reporting_auto = dr->all_the_time;
|
||||||
m_reporting_mode = dr->mode;
|
m_reporting_mode = dr->mode;
|
||||||
m_reporting_channel = _channelID;
|
m_reporting_channel = _channelID;
|
||||||
|
@ -93,10 +91,14 @@ void Wiimote::HidOutputReport(const u16 _channelID, wm_report* sr)
|
||||||
{
|
{
|
||||||
INFO_LOG(WIIMOTE, "HidOutputReport (page: %i, cid: 0x%02x, wm: 0x%02x)", m_index, _channelID, sr->wm);
|
INFO_LOG(WIIMOTE, "HidOutputReport (page: %i, cid: 0x%02x, wm: 0x%02x)", m_index, _channelID, sr->wm);
|
||||||
|
|
||||||
|
// wiibrew:
|
||||||
|
// In every single Output Report, bit 0 (0x01) of the first byte controls the Rumble feature.
|
||||||
|
m_rumble_on = (sr->data[0] & 0x01) != 0;
|
||||||
|
|
||||||
switch (sr->wm)
|
switch (sr->wm)
|
||||||
{
|
{
|
||||||
case WM_RUMBLE : // 0x10
|
case WM_RUMBLE : // 0x10
|
||||||
m_rumble_on = (sr->data[0] != 0);
|
// this is handled above
|
||||||
return; // no ack
|
return; // no ack
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -116,6 +118,7 @@ void Wiimote::HidOutputReport(const u16 _channelID, wm_report* sr)
|
||||||
|
|
||||||
case WM_SPEAKER_ENABLE : // 0x14
|
case WM_SPEAKER_ENABLE : // 0x14
|
||||||
//INFO_LOG(WIIMOTE, "WM Speaker Enable: 0x%02x", sr->data[0]);
|
//INFO_LOG(WIIMOTE, "WM Speaker Enable: 0x%02x", sr->data[0]);
|
||||||
|
//PanicAlert( "WM Speaker Enable: %d", sr->data[0] );
|
||||||
m_status.speaker = (sr->data[0] & 0x04) ? 1 : 0;
|
m_status.speaker = (sr->data[0] & 0x04) ? 1 : 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -135,12 +138,24 @@ void Wiimote::HidOutputReport(const u16 _channelID, wm_report* sr)
|
||||||
|
|
||||||
case WM_WRITE_SPEAKER_DATA : // 0x18
|
case WM_WRITE_SPEAKER_DATA : // 0x18
|
||||||
// TODO: Does this need an ack?
|
// TODO: Does this need an ack?
|
||||||
|
{
|
||||||
|
// testing
|
||||||
|
//wm_speaker_data* const sd = (wm_speaker_data*)sr->data;
|
||||||
|
//unsigned int length = sd->length >> 3;
|
||||||
|
|
||||||
|
//PanicAlert( "WM Speaker Data:\nlength: %d\nformat: 0x%x\nrate: 0x%x\nvolume: 0x%x",
|
||||||
|
//length, m_reg_speaker->format, m_reg_speaker->sample_rate, m_reg_speaker->volume );
|
||||||
|
|
||||||
|
//for (unsigned int i=0; i<length; ++i)
|
||||||
|
// m_speaker_data.push(0);
|
||||||
|
}
|
||||||
return; // no ack
|
return; // no ack
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_SPEAKER_MUTE : // 0x19
|
case WM_SPEAKER_MUTE : // 0x19
|
||||||
//INFO_LOG(WIIMOTE, "WM Speaker Mute: 0x%02x", sr->data[0]);
|
//INFO_LOG(WIIMOTE, "WM Speaker Mute: 0x%02x", sr->data[0]);
|
||||||
//m_speaker_mute = (sr->data[0] & 0x04) ? 1 : 0;
|
//PanicAlert( "WM Speaker Mute: %d", sr->data[0] & 0x04 );
|
||||||
|
m_speaker_mute = (sr->data[0] & 0x04) ? 1 : 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_IR_LOGIC: // 0x1a
|
case WM_IR_LOGIC: // 0x1a
|
||||||
|
@ -182,14 +197,14 @@ void Wiimote::SendAck(const u16 _channelID, u8 _reportID)
|
||||||
g_WiimoteInitialize.pWiimoteInput( m_index, _channelID, data, sizeof(data));
|
g_WiimoteInitialize.pWiimoteInput( m_index, _channelID, data, sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// old comment
|
||||||
/* Here we produce a 0x20 status report to send to the Wii. We currently ignore
|
/* Here we produce a 0x20 status report to send to the Wii. We currently ignore
|
||||||
the status request rs and all its eventual instructions it may include (for
|
the status request rs and all its eventual instructions it may include (for
|
||||||
example turn off rumble or something else) and just send the status
|
example turn off rumble or something else) and just send the status
|
||||||
report. */
|
report. */
|
||||||
void Wiimote::RequestStatus(const u16 _channelID, wm_request_status* rs)
|
void Wiimote::RequestStatus(const u16 _channelID, wm_request_status* rs)
|
||||||
{
|
{
|
||||||
if (rs)
|
//if (rs)
|
||||||
m_rumble_on = (rs->rumble != 0);
|
|
||||||
|
|
||||||
// handle switch extension
|
// handle switch extension
|
||||||
if ( m_extension->active_extension != m_extension->switch_extension )
|
if ( m_extension->active_extension != m_extension->switch_extension )
|
||||||
|
@ -230,8 +245,6 @@ void Wiimote::WriteData(const u16 _channelID, wm_write_data* wd)
|
||||||
// ignore the 0x010000 bit
|
// ignore the 0x010000 bit
|
||||||
address &= 0xFEFFFF;
|
address &= 0xFEFFFF;
|
||||||
|
|
||||||
m_rumble_on = ( wd->rumble != 0 );
|
|
||||||
|
|
||||||
if (wd->size > 16)
|
if (wd->size > 16)
|
||||||
{
|
{
|
||||||
PanicAlert("WriteData: size is > 16 bytes");
|
PanicAlert("WriteData: size is > 16 bytes");
|
||||||
|
@ -278,6 +291,10 @@ void Wiimote::WriteData(const u16 _channelID, wm_write_data* wd)
|
||||||
|
|
||||||
switch (address >> 16)
|
switch (address >> 16)
|
||||||
{
|
{
|
||||||
|
// speaker
|
||||||
|
case 0xa2 :
|
||||||
|
//PanicAlert("Write to speaker!!");
|
||||||
|
break;
|
||||||
// extension register
|
// extension register
|
||||||
case 0xa4 :
|
case 0xa4 :
|
||||||
{
|
{
|
||||||
|
@ -311,8 +328,6 @@ void Wiimote::ReadData(const u16 _channelID, wm_read_data* rd)
|
||||||
// ignore the 0x010000 bit
|
// ignore the 0x010000 bit
|
||||||
address &= 0xFEFFFF;
|
address &= 0xFEFFFF;
|
||||||
|
|
||||||
m_rumble_on = (rd->rumble != 0);
|
|
||||||
|
|
||||||
ReadRequest rr;
|
ReadRequest rr;
|
||||||
u8* block = new u8[size];
|
u8* block = new u8[size];
|
||||||
|
|
||||||
|
@ -322,7 +337,7 @@ void Wiimote::ReadData(const u16 _channelID, wm_read_data* rd)
|
||||||
{
|
{
|
||||||
//PanicAlert("ReadData: reading from EEPROM: address: 0x%x size: 0x%x", address, size);
|
//PanicAlert("ReadData: reading from EEPROM: address: 0x%x size: 0x%x", address, size);
|
||||||
// Read from EEPROM
|
// Read from EEPROM
|
||||||
if (address + size > WIIMOTE_EEPROM_FREE_SIZE)
|
if (address + size >= WIIMOTE_EEPROM_FREE_SIZE)
|
||||||
{
|
{
|
||||||
if (address + size > WIIMOTE_EEPROM_SIZE)
|
if (address + size > WIIMOTE_EEPROM_SIZE)
|
||||||
{
|
{
|
||||||
|
@ -362,17 +377,20 @@ void Wiimote::ReadData(const u16 _channelID, wm_read_data* rd)
|
||||||
|
|
||||||
switch (address >> 16)
|
switch (address >> 16)
|
||||||
{
|
{
|
||||||
|
// speaker
|
||||||
|
case 0xa2 :
|
||||||
|
//PanicAlert("read from speaker!!");
|
||||||
|
break;
|
||||||
|
// extension
|
||||||
case 0xa4 :
|
case 0xa4 :
|
||||||
{
|
{
|
||||||
// Encrypt data read from extension register
|
// Encrypt data read from extension register
|
||||||
// Check if encrypted reads is on
|
// Check if encrypted reads is on
|
||||||
if ( m_reg_ext[0xf0] == 0xaa )
|
if ( m_reg_ext[0xf0] == 0xaa )
|
||||||
{
|
|
||||||
// I probably totally f'ed this up
|
|
||||||
wiimote_encrypt(&m_ext_key, block, address & 0xffff, (u8)size);
|
wiimote_encrypt(&m_ext_key, block, address & 0xffff, (u8)size);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
// motion plus
|
||||||
case 0xa6 :
|
case 0xa6 :
|
||||||
{
|
{
|
||||||
// motion plus crap copied from old wiimote plugin
|
// motion plus crap copied from old wiimote plugin
|
||||||
|
|
|
@ -279,7 +279,7 @@ void wiimote_gen_key(wiimote_key *key, u8 *keydata)
|
||||||
// for homebrew, ft and sb are all 0x97 which is equivalent to 0x17
|
// for homebrew, ft and sb are all 0x97 which is equivalent to 0x17
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: is there a reason these can only handle a length of 255?
|
||||||
/* Encrypt data */
|
/* Encrypt data */
|
||||||
void wiimote_encrypt(wiimote_key *key, u8 *data, int addr, u8 len)
|
void wiimote_encrypt(wiimote_key *key, u8 *data, int addr, u8 len)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
|
||||||
#include "Attachment/Classic.h"
|
#include "Attachment/Classic.h"
|
||||||
#include "Attachment/Nunchuk.h"
|
#include "Attachment/Nunchuk.h"
|
||||||
|
#include "Attachment/Guitar.h"
|
||||||
|
#include "Attachment/Drums.h"
|
||||||
|
|
||||||
#include "WiimoteEmu.h"
|
#include "WiimoteEmu.h"
|
||||||
#include "WiimoteHid.h"
|
#include "WiimoteHid.h"
|
||||||
|
@ -39,6 +41,7 @@ static const u8 eeprom_data_0[] = {
|
||||||
0x82, 0x82, 0x82, 0x15, 0x9C, 0x9C, 0x9E, 0x38, 0x40, 0x3E
|
0x82, 0x82, 0x82, 0x15, 0x9C, 0x9C, 0x9E, 0x38, 0x40, 0x3E
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const u8 motion_plus_id[] = { 0x00, 0x00, 0xA6, 0x20, 0x00, 0x05 };
|
||||||
|
|
||||||
static const u8 eeprom_data_16D0[] = {
|
static const u8 eeprom_data_16D0[] = {
|
||||||
0x00, 0x00, 0x00, 0xFF, 0x11, 0xEE, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0xFF, 0x11, 0xEE, 0x00, 0x00,
|
||||||
|
@ -110,6 +113,7 @@ void Wiimote::Reset()
|
||||||
m_reporting_auto = false;
|
m_reporting_auto = false;
|
||||||
|
|
||||||
m_rumble_on = false;
|
m_rumble_on = false;
|
||||||
|
m_speaker_mute = false;
|
||||||
|
|
||||||
// will make the first Update() call send a status request
|
// will make the first Update() call send a status request
|
||||||
// the first call to RequestStatus() will then set up the status struct extension bit
|
// the first call to RequestStatus() will then set up the status struct extension bit
|
||||||
|
@ -129,11 +133,14 @@ void Wiimote::Reset()
|
||||||
m_register[0xa60000].resize(WIIMOTE_REG_EXT_SIZE,0);
|
m_register[0xa60000].resize(WIIMOTE_REG_EXT_SIZE,0);
|
||||||
m_register[0xB00000].resize(WIIMOTE_REG_IR_SIZE,0);
|
m_register[0xB00000].resize(WIIMOTE_REG_IR_SIZE,0);
|
||||||
|
|
||||||
//m_reg_speaker = &m_register[0xa20000][0];
|
m_reg_speaker = (SpeakerConfig*)&m_register[0xa20000][0];
|
||||||
m_reg_ext = &m_register[0xa40000][0];
|
m_reg_ext = &m_register[0xa40000][0];
|
||||||
//m_reg_motion_plus = &m_register[0xa60000][0];
|
m_reg_motion_plus = &m_register[0xa60000][0];
|
||||||
m_reg_ir = &m_register[0xB00000][0];
|
m_reg_ir = &m_register[0xB00000][0];
|
||||||
|
|
||||||
|
// testing
|
||||||
|
//memcpy( m_reg_motion_plus + 0xfa, motion_plus_id, sizeof(motion_plus_id) );
|
||||||
|
|
||||||
// status
|
// status
|
||||||
memset( &m_status, 0, sizeof(m_status) );
|
memset( &m_status, 0, sizeof(m_status) );
|
||||||
// Battery levels in voltage
|
// Battery levels in voltage
|
||||||
|
@ -183,7 +190,8 @@ Wiimote::Wiimote( const unsigned int index ) : m_index(index)
|
||||||
m_extension->attachments.push_back( new WiimoteEmu::None() );
|
m_extension->attachments.push_back( new WiimoteEmu::None() );
|
||||||
m_extension->attachments.push_back( new WiimoteEmu::Nunchuk() );
|
m_extension->attachments.push_back( new WiimoteEmu::Nunchuk() );
|
||||||
m_extension->attachments.push_back( new WiimoteEmu::Classic() );
|
m_extension->attachments.push_back( new WiimoteEmu::Classic() );
|
||||||
//m_extension->attachments.push_back( new Attachment::GH3() );
|
m_extension->attachments.push_back( new WiimoteEmu::Guitar() );
|
||||||
|
m_extension->attachments.push_back( new WiimoteEmu::Drums() );
|
||||||
|
|
||||||
// dpad
|
// dpad
|
||||||
groups.push_back( m_dpad = new Buttons( "D-Pad" ) );
|
groups.push_back( m_dpad = new Buttons( "D-Pad" ) );
|
||||||
|
@ -195,9 +203,9 @@ Wiimote::Wiimote( const unsigned int index ) : m_index(index)
|
||||||
m_rumble->controls.push_back( new ControlGroup::Output( "Motor" ) );
|
m_rumble->controls.push_back( new ControlGroup::Output( "Motor" ) );
|
||||||
|
|
||||||
// options
|
// options
|
||||||
groups.push_back( options = new ControlGroup( "Options" ) );
|
groups.push_back( m_options = new ControlGroup( "Options" ) );
|
||||||
options->settings.push_back( new ControlGroup::Setting( "Background Input", false ) );
|
m_options->settings.push_back( new ControlGroup::Setting( "Background Input", false ) );
|
||||||
options->settings.push_back( new ControlGroup::Setting( "Sideways Wiimote", false ) );
|
m_options->settings.push_back( new ControlGroup::Setting( "Sideways Wiimote", false ) );
|
||||||
|
|
||||||
|
|
||||||
// --- reset eeprom/register/values to default ---
|
// --- reset eeprom/register/values to default ---
|
||||||
|
@ -211,16 +219,29 @@ std::string Wiimote::GetName() const
|
||||||
|
|
||||||
void Wiimote::Update()
|
void Wiimote::Update()
|
||||||
{
|
{
|
||||||
const bool is_sideways = options->settings[1]->value > 0;
|
const bool is_sideways = m_options->settings[1]->value > 0;
|
||||||
|
|
||||||
// if windows is focused or background input is enabled
|
// if windows is focused or background input is enabled
|
||||||
const bool focus = g_WiimoteInitialize.pRendererHasFocus() || (options->settings[0]->value != 0);
|
const bool focus = g_WiimoteInitialize.pRendererHasFocus() || (m_options->settings[0]->value != 0);
|
||||||
|
|
||||||
// no rumble if no focus
|
// no rumble if no focus
|
||||||
if (false == focus)
|
if (false == focus)
|
||||||
m_rumble_on = false;
|
m_rumble_on = false;
|
||||||
m_rumble->controls[0]->control_ref->State(m_rumble_on);
|
m_rumble->controls[0]->control_ref->State(m_rumble_on);
|
||||||
|
|
||||||
|
// testing speaker stuff
|
||||||
|
//m_rumble->controls[0]->control_ref->State( m_speaker_data.size() > 0 );
|
||||||
|
//while ( m_speaker_data.size() )
|
||||||
|
//{
|
||||||
|
// std::ofstream file;
|
||||||
|
// file.open( "test.pcm", std::ios::app | std::ios::out | std::ios::binary );
|
||||||
|
// file.put(m_speaker_data.front());
|
||||||
|
// file.close();
|
||||||
|
// m_speaker_data.pop();
|
||||||
|
//}
|
||||||
|
//if ( m_speaker_data.size() )
|
||||||
|
// m_speaker_data.pop();
|
||||||
|
|
||||||
// update buttons in status struct
|
// update buttons in status struct
|
||||||
m_status.buttons = 0;
|
m_status.buttons = 0;
|
||||||
if ( focus )
|
if ( focus )
|
||||||
|
@ -324,7 +345,7 @@ void Wiimote::Update()
|
||||||
else
|
else
|
||||||
m_shake_step = 0;
|
m_shake_step = 0;
|
||||||
|
|
||||||
// swing
|
// TODO: swing
|
||||||
//u8 swing[3];
|
//u8 swing[3];
|
||||||
//m_swing->GetState( swing, 0x80, 60 );
|
//m_swing->GetState( swing, 0x80, 60 );
|
||||||
//for ( unsigned int i=0; i<3; ++i )
|
//for ( unsigned int i=0; i<3; ++i )
|
||||||
|
@ -337,7 +358,11 @@ void Wiimote::Update()
|
||||||
if (rpt.ext)
|
if (rpt.ext)
|
||||||
{
|
{
|
||||||
m_extension->GetState(data + rpt.ext, focus);
|
m_extension->GetState(data + rpt.ext, focus);
|
||||||
wiimote_encrypt(&m_ext_key, data + rpt.ext, 0x00, sizeof(wm_extension));
|
|
||||||
|
// both of these ifs work
|
||||||
|
//if ( m_reg_ext[0xf0] != 0x55 )
|
||||||
|
if ( m_reg_ext[0xf0] == 0xaa )
|
||||||
|
wiimote_encrypt(&m_ext_key, data + rpt.ext, 0x00, sizeof(wm_extension));
|
||||||
|
|
||||||
// i dont think anything accesses the extension data like this, but ill support it
|
// i dont think anything accesses the extension data like this, but ill support it
|
||||||
memcpy(m_reg_ext + 8, data + rpt.ext, sizeof(wm_extension));
|
memcpy(m_reg_ext + 8, data + rpt.ext, sizeof(wm_extension));
|
||||||
|
@ -613,3 +638,4 @@ void Wiimote::Register::Write( size_t address, void* src, size_t length )
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
// Registry sizes
|
// Registry sizes
|
||||||
#define WIIMOTE_EEPROM_SIZE (16*1024)
|
#define WIIMOTE_EEPROM_SIZE (16*1024)
|
||||||
#define WIIMOTE_EEPROM_FREE_SIZE 0x16ff
|
#define WIIMOTE_EEPROM_FREE_SIZE 0x1700
|
||||||
#define WIIMOTE_REG_SPEAKER_SIZE 10
|
#define WIIMOTE_REG_SPEAKER_SIZE 10
|
||||||
#define WIIMOTE_REG_EXT_SIZE 0x100
|
#define WIIMOTE_REG_EXT_SIZE 0x100
|
||||||
#define WIIMOTE_REG_IR_SIZE 0x34
|
#define WIIMOTE_REG_IR_SIZE 0x34
|
||||||
|
@ -28,20 +28,22 @@ extern const u8 shake_data[8];
|
||||||
class Wiimote : public ControllerEmu
|
class Wiimote : public ControllerEmu
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Wiimote( const unsigned int index );
|
||||||
|
std::string GetName() const;
|
||||||
|
|
||||||
|
void Update();
|
||||||
|
void InterruptChannel(const u16 _channelID, const void* _pData, u32 _Size);
|
||||||
|
void ControlChannel(const u16 _channelID, const void* _pData, u32 _Size);
|
||||||
|
|
||||||
|
private:
|
||||||
struct ReadRequest
|
struct ReadRequest
|
||||||
{
|
{
|
||||||
unsigned int address, size, position;
|
unsigned int address, size, position;
|
||||||
u8* data;
|
u8* data;
|
||||||
};
|
};
|
||||||
|
|
||||||
Wiimote( const unsigned int index );
|
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
void Update();
|
|
||||||
void InterruptChannel(const u16 _channelID, const void* _pData, u32 _Size);
|
|
||||||
void ControlChannel(const u16 _channelID, const void* _pData, u32 _Size);
|
|
||||||
|
|
||||||
void ReportMode(const u16 _channelID, wm_report_mode* dr);
|
void ReportMode(const u16 _channelID, wm_report_mode* dr);
|
||||||
void HidOutputReport(const u16 _channelID, wm_report* sr);
|
void HidOutputReport(const u16 _channelID, wm_report* sr);
|
||||||
void SendAck(const u16 _channelID, u8 _reportID);
|
void SendAck(const u16 _channelID, u8 _reportID);
|
||||||
|
@ -51,10 +53,7 @@ public:
|
||||||
void ReadData(const u16 _channelID, wm_read_data* rd);
|
void ReadData(const u16 _channelID, wm_read_data* rd);
|
||||||
void SendReadDataReply(const u16 _channelID, ReadRequest& _request);
|
void SendReadDataReply(const u16 _channelID, ReadRequest& _request);
|
||||||
|
|
||||||
std::string GetName() const;
|
// control groups
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
Buttons* m_buttons;
|
Buttons* m_buttons;
|
||||||
Buttons* m_dpad;
|
Buttons* m_dpad;
|
||||||
Buttons* m_shake;
|
Buttons* m_shake;
|
||||||
|
@ -63,11 +62,13 @@ private:
|
||||||
Force* m_swing;
|
Force* m_swing;
|
||||||
ControlGroup* m_rumble;
|
ControlGroup* m_rumble;
|
||||||
Extension* m_extension;
|
Extension* m_extension;
|
||||||
// TODO: add ir
|
ControlGroup* m_options;
|
||||||
|
|
||||||
|
// wiimote index, 0-3
|
||||||
const unsigned int m_index;
|
const unsigned int m_index;
|
||||||
|
|
||||||
bool m_rumble_on;
|
bool m_rumble_on;
|
||||||
|
bool m_speaker_mute;
|
||||||
|
|
||||||
bool m_reporting_auto;
|
bool m_reporting_auto;
|
||||||
unsigned int m_reporting_mode;
|
unsigned int m_reporting_mode;
|
||||||
|
@ -90,13 +91,20 @@ private:
|
||||||
// maybe read requests cancel any current requests
|
// maybe read requests cancel any current requests
|
||||||
std::queue< ReadRequest > m_read_requests;
|
std::queue< ReadRequest > m_read_requests;
|
||||||
|
|
||||||
//u8 m_eeprom[WIIMOTE_EEPROM_SIZE];
|
//std::queue< u8 > m_speaker_data;
|
||||||
u8 m_eeprom[WIIMOTE_EEPROM_SIZE];
|
|
||||||
|
|
||||||
//u8* m_reg_speaker;
|
u8 m_eeprom[WIIMOTE_EEPROM_SIZE];
|
||||||
//u8* m_reg_motion_plus;
|
|
||||||
u8* m_reg_ir;
|
|
||||||
u8* m_reg_ext;
|
u8* m_reg_ext;
|
||||||
|
u8* m_reg_ir;
|
||||||
|
u8* m_reg_motion_plus;
|
||||||
|
struct SpeakerConfig
|
||||||
|
{
|
||||||
|
u16 : 16;
|
||||||
|
u8 format;
|
||||||
|
u16 sample_rate;
|
||||||
|
u8 volume;
|
||||||
|
|
||||||
|
} *m_reg_speaker;
|
||||||
|
|
||||||
wiimote_key m_ext_key;
|
wiimote_key m_ext_key;
|
||||||
};
|
};
|
||||||
|
|
|
@ -99,7 +99,7 @@ struct wm_classic_extension
|
||||||
u16 bt; // byte 4, 5
|
u16 bt; // byte 4, 5
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wm_GH3_extension
|
struct wm_guitar_extension
|
||||||
{
|
{
|
||||||
u8 sx : 6;
|
u8 sx : 6;
|
||||||
u8 pad1 : 2; // 1 on gh3, 0 on ghwt
|
u8 pad1 : 2; // 1 on gh3, 0 on ghwt
|
||||||
|
@ -113,23 +113,28 @@ struct wm_GH3_extension
|
||||||
u8 whammy : 5;
|
u8 whammy : 5;
|
||||||
u8 pad4 : 3; // always 0
|
u8 pad4 : 3; // always 0
|
||||||
|
|
||||||
u8 pad5 : 2; // always 1
|
u16 bt; // buttons
|
||||||
u8 plus : 1;
|
|
||||||
u8 pad6 : 1; // always 1
|
|
||||||
u8 minus : 1;
|
|
||||||
u8 pad7 : 1; // always 1
|
|
||||||
u8 strumdown : 1;
|
|
||||||
u8 pad8 : 1; // always 1
|
|
||||||
|
|
||||||
u8 strumup : 1;
|
|
||||||
u8 pad9 : 2; // always 1
|
|
||||||
u8 yellow : 1;
|
|
||||||
u8 green : 1;
|
|
||||||
u8 blue : 1;
|
|
||||||
u8 red : 1;
|
|
||||||
u8 orange : 1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct wm_drums_extension
|
||||||
|
{
|
||||||
|
u8 sx : 6;
|
||||||
|
u8 pad1 : 2; // always 0
|
||||||
|
|
||||||
|
u8 sy : 6;
|
||||||
|
u8 pad2 : 2; // always 0
|
||||||
|
|
||||||
|
u8 pad3 : 1; // unknown
|
||||||
|
u8 which : 5;
|
||||||
|
u8 none : 1;
|
||||||
|
u8 hhp : 1;
|
||||||
|
|
||||||
|
u8 pad4 : 1; // unknown
|
||||||
|
u8 velocity : 4; // unknown
|
||||||
|
u8 softness : 3;
|
||||||
|
|
||||||
|
u16 bt; // buttons
|
||||||
|
};
|
||||||
|
|
||||||
struct wm_report {
|
struct wm_report {
|
||||||
u8 wm;
|
u8 wm;
|
||||||
|
@ -279,7 +284,10 @@ struct wm_report_ext21
|
||||||
#define WM_SPEAKER_ENABLE 0x14
|
#define WM_SPEAKER_ENABLE 0x14
|
||||||
#define WM_SPEAKER_MUTE 0x19
|
#define WM_SPEAKER_MUTE 0x19
|
||||||
#define WM_WRITE_SPEAKER_DATA 0x18
|
#define WM_WRITE_SPEAKER_DATA 0x18
|
||||||
|
struct wm_speaker_data {
|
||||||
|
u8 length; // shifted left by three bits
|
||||||
|
u8 data[20];
|
||||||
|
};
|
||||||
|
|
||||||
// Custom structs
|
// Custom structs
|
||||||
|
|
||||||
|
|
|
@ -140,13 +140,7 @@ void InitPlugin( void* const hwnd )
|
||||||
void Wiimote_ControlChannel(int _number, u16 _channelID, const void* _pData, u32 _Size)
|
void Wiimote_ControlChannel(int _number, u16 _channelID, const void* _pData, u32 _Size)
|
||||||
{
|
{
|
||||||
//PanicAlert( "Wiimote_ControlChannel" );
|
//PanicAlert( "Wiimote_ControlChannel" );
|
||||||
|
|
||||||
// TODO: change this to a TryEnter, and make it give empty input on failure
|
|
||||||
g_plugin.controls_crit.Enter();
|
|
||||||
|
|
||||||
((WiimoteEmu::Wiimote*)g_plugin.controllers[ _number ])->ControlChannel( _channelID, _pData, _Size );
|
((WiimoteEmu::Wiimote*)g_plugin.controllers[ _number ])->ControlChannel( _channelID, _pData, _Size );
|
||||||
|
|
||||||
g_plugin.controls_crit.Leave();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// __________________________________________________________________________________________________
|
// __________________________________________________________________________________________________
|
||||||
|
@ -159,13 +153,7 @@ void Wiimote_ControlChannel(int _number, u16 _channelID, const void* _pData, u32
|
||||||
void Wiimote_InterruptChannel(int _number, u16 _channelID, const void* _pData, u32 _Size)
|
void Wiimote_InterruptChannel(int _number, u16 _channelID, const void* _pData, u32 _Size)
|
||||||
{
|
{
|
||||||
//PanicAlert( "Wiimote_InterruptChannel" );
|
//PanicAlert( "Wiimote_InterruptChannel" );
|
||||||
|
|
||||||
// TODO: change this to a TryEnter, and make it give empty input on failure
|
|
||||||
g_plugin.controls_crit.Enter();
|
|
||||||
|
|
||||||
((WiimoteEmu::Wiimote*)g_plugin.controllers[ _number ])->InterruptChannel( _channelID, _pData, _Size );
|
((WiimoteEmu::Wiimote*)g_plugin.controllers[ _number ])->InterruptChannel( _channelID, _pData, _Size );
|
||||||
|
|
||||||
g_plugin.controls_crit.Leave();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// __________________________________________________________________________________________________
|
// __________________________________________________________________________________________________
|
||||||
|
@ -337,7 +325,7 @@ void Shutdown(void)
|
||||||
//
|
//
|
||||||
void DoState(unsigned char **ptr, int mode)
|
void DoState(unsigned char **ptr, int mode)
|
||||||
{
|
{
|
||||||
// prolly won't need this
|
// do this later
|
||||||
}
|
}
|
||||||
|
|
||||||
// ___________________________________________________________________________
|
// ___________________________________________________________________________
|
||||||
|
|
Loading…
Reference in New Issue