mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-20 18:40:51 +00:00
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:
|
||||
virtual std::string GetName() const = 0;
|
||||
virtual ~Control() {}
|
||||
};
|
||||
|
||||
//
|
||||
@ -138,6 +139,8 @@ public:
|
||||
public:
|
||||
ControlQualifier() {};
|
||||
ControlQualifier( const std::string& _name ) : name(_name) {}
|
||||
virtual ~ControlQualifier() {}
|
||||
|
||||
virtual bool operator==(const Device::Control* const in) const;
|
||||
void FromControl(const Device::Control* const in);
|
||||
|
||||
@ -184,6 +187,7 @@ public:
|
||||
{
|
||||
public:
|
||||
ControlReference( const bool _is_input ) : range(1), is_input(_is_input), device(NULL) {}
|
||||
virtual ~ControlReference() {}
|
||||
|
||||
virtual ControlState State( const ControlState state = 0 ) = 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() ] );
|
||||
|
||||
// dont need to save empty values
|
||||
inifile.Clean();
|
||||
//inifile.Clean();
|
||||
|
||||
std::ofstream file;
|
||||
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;
|
||||
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;
|
||||
dc.SelectObject(bitmap);
|
||||
dc.Clear();
|
||||
dc.SelectObject(wxNullBitmap);
|
||||
static_bitmap = new wxStaticBitmap( parent, -1, bitmap, wxDefaultPosition, wxDefaultSize, wxBITMAP_TYPE_BMP );
|
||||
|
||||
PadSettingChoice* threshold_cbox = new PadSettingChoice( parent, group->settings[0] );
|
||||
_connect_macro_( threshold_cbox, GamepadPage::AdjustSetting, wxEVT_COMMAND_CHOICE_SELECTED, eventsink );
|
||||
std::vector<ControllerEmu::ControlGroup::Setting*>::const_iterator
|
||||
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 );
|
||||
}
|
||||
break;
|
||||
|
@ -79,9 +79,9 @@ void ConfigDialog::UpdateBitmaps(wxTimerEvent& WXUNUSED(event))
|
||||
else
|
||||
dc.DrawRectangle( 16, 16, 32, 32 );
|
||||
|
||||
// deadzone circle
|
||||
if ( GROUP_TYPE_CURSOR != (*g)->control_group->type )
|
||||
{
|
||||
// deadzone circle
|
||||
dc.SetBrush(*wxLIGHT_GREY_BRUSH);
|
||||
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 );
|
||||
}
|
||||
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 :
|
||||
{
|
||||
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(64, n*12, 32, 14);
|
||||
}
|
||||
|
||||
// threshold box
|
||||
dc.SetPen(*wxLIGHT_GREY_PEN);
|
||||
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
||||
dc.DrawRectangle(thresh*64, 0, 128, trigger_count*14);
|
||||
|
||||
|
@ -4,11 +4,9 @@
|
||||
#include <X11/Xlib.h>
|
||||
#endif
|
||||
|
||||
const char modifier[] = "Modifier";
|
||||
|
||||
|
||||
ControllerEmu::~ControllerEmu()
|
||||
{
|
||||
// control groups
|
||||
std::vector<ControlGroup*>::const_iterator
|
||||
i = groups.begin(),
|
||||
e = groups.end();
|
||||
@ -18,12 +16,14 @@ ControllerEmu::~ControllerEmu()
|
||||
|
||||
ControllerEmu::ControlGroup::~ControlGroup()
|
||||
{
|
||||
// controls
|
||||
std::vector<Control*>::const_iterator
|
||||
ci = controls.begin(),
|
||||
ce = controls.end();
|
||||
for ( ; ci!=ce; ++ci )
|
||||
delete *ci;
|
||||
|
||||
// settings
|
||||
std::vector<Setting*>::const_iterator
|
||||
si = settings.begin(),
|
||||
se = settings.end();
|
||||
@ -31,6 +31,20 @@ ControllerEmu::ControlGroup::~ControlGroup()
|
||||
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 )
|
||||
{
|
||||
std::vector<ControlGroup*>::const_iterator
|
||||
@ -170,7 +184,7 @@ void ControllerEmu::ControlGroup::SaveConfig( IniFile::Section& sec, const std::
|
||||
for ( ; ci!=ce; ++ci )
|
||||
{
|
||||
// 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 );
|
||||
|
||||
// range
|
||||
@ -200,7 +214,7 @@ void ControllerEmu::SaveConfig( IniFile::Section& sec, const std::string& base )
|
||||
{
|
||||
const std::string defdev = default_device.ToString();
|
||||
if ( base.empty() )
|
||||
sec[ std::string(" ") + base + "Device" ] = defdev;
|
||||
sec.Set( std::string(" ") + base + "Device", defdev );
|
||||
|
||||
std::vector<ControlGroup*>::const_iterator i = groups.begin(),
|
||||
e = groups.end();
|
||||
@ -213,7 +227,7 @@ ControllerEmu::AnalogStick::AnalogStick( const char* const _name ) : ControlGrou
|
||||
for ( unsigned int i = 0; i < 4; ++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("Square Stick", 0 ) );
|
||||
@ -230,6 +244,11 @@ ControllerEmu::MixedTriggers::MixedTriggers( const char* const _name ) : Control
|
||||
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 )
|
||||
{
|
||||
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( "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("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)
|
||||
{
|
||||
unsigned int win_width = 2, win_height = 2;
|
||||
|
@ -28,6 +28,7 @@ enum
|
||||
GROUP_TYPE_EXTENSION,
|
||||
GROUP_TYPE_TILT,
|
||||
GROUP_TYPE_CURSOR,
|
||||
GROUP_TYPE_TRIGGERS,
|
||||
};
|
||||
|
||||
const char * const named_directions[] =
|
||||
@ -55,9 +56,7 @@ public:
|
||||
: control_ref(_ref), name(_name){}
|
||||
public:
|
||||
|
||||
|
||||
//virtual std::string GetName() const = 0;
|
||||
|
||||
virtual ~Control();
|
||||
ControllerInterface::ControlReference* const control_ref;
|
||||
const char * const name;
|
||||
|
||||
@ -105,7 +104,6 @@ public:
|
||||
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 = "" );
|
||||
|
||||
//const unsigned int type;
|
||||
const char* const name;
|
||||
const unsigned int type;
|
||||
|
||||
@ -147,7 +145,7 @@ public:
|
||||
ControlState ang_cos = cos(ang);
|
||||
|
||||
// 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
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
@ -259,7 +274,7 @@ public:
|
||||
ControlState ang_cos = cos(ang);
|
||||
|
||||
// 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
|
||||
// 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>
|
||||
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();
|
||||
|
||||
// hide
|
||||
@ -335,7 +344,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
//ControlState z;
|
||||
const SWiimoteInitialize* const wiimote_initialize;
|
||||
|
||||
};
|
||||
@ -347,6 +355,7 @@ public:
|
||||
: ControlGroup( _name, GROUP_TYPE_EXTENSION )
|
||||
, switch_extension(0)
|
||||
, active_extension(0) {}
|
||||
~Extension();
|
||||
|
||||
void GetState( u8* const data, const bool focus = true );
|
||||
|
||||
@ -368,8 +377,6 @@ public:
|
||||
|
||||
std::vector< ControlGroup* > groups;
|
||||
|
||||
ControlGroup* options;
|
||||
|
||||
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] ) );
|
||||
|
||||
// options
|
||||
groups.push_back( options = new ControlGroup( "Options" ) );
|
||||
options->settings.push_back( new ControlGroup::Setting( "Background Input", false ) );
|
||||
groups.push_back( m_options = new ControlGroup( "Options" ) );
|
||||
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 )
|
||||
{
|
||||
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
|
||||
m_buttons->GetState( &pad->button, button_bitmasks );
|
||||
// TODO: set analog A/B analog to full or w/e, prolly not needed
|
||||
|
||||
// TODO: set analog A/B to full or w/e
|
||||
// dpad
|
||||
m_dpad->GetState( &pad->button, dpad_bitmasks );
|
||||
|
||||
// dpad
|
||||
m_dpad->GetState( &pad->button, dpad_bitmasks );
|
||||
// sticks
|
||||
m_main_stick->GetState( &pad->stickX, &pad->stickY, 0x80, 127 );
|
||||
m_c_stick->GetState( &pad->substickX, &pad->substickY, 0x80, 127 );
|
||||
|
||||
// sticks
|
||||
m_main_stick->GetState( &pad->stickX, &pad->stickY, 0x80, 127 );
|
||||
m_c_stick->GetState( &pad->substickX, &pad->substickY, 0x80, 127 );
|
||||
|
||||
// triggers
|
||||
m_triggers->GetState( &pad->button, trigger_bitmasks, &pad->triggerLeft, 0xFF );
|
||||
// triggers
|
||||
m_triggers->GetState( &pad->button, trigger_bitmasks, &pad->triggerLeft, 0xFF );
|
||||
}
|
||||
else
|
||||
{
|
||||
// center sticks
|
||||
memset( &pad->stickX, 0x80, 4 );
|
||||
}
|
||||
}
|
||||
|
||||
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>
|
||||
|
||||
extern SPADInitialize *g_PADInitialize;
|
||||
|
||||
class GCPad : public ControllerEmu
|
||||
{
|
||||
public:
|
||||
@ -22,6 +24,7 @@ private:
|
||||
Buttons* m_dpad;
|
||||
MixedTriggers* m_triggers;
|
||||
ControlGroup* m_rumble;
|
||||
ControlGroup* m_options;
|
||||
|
||||
const unsigned int m_index;
|
||||
|
||||
|
@ -161,19 +161,8 @@ void PAD_GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)
|
||||
}
|
||||
_last_numPAD = _numPAD;
|
||||
|
||||
// if we want background input or have focus
|
||||
if ( g_plugin.controllers[_numPAD]->options[0].settings[0]->value || g_PADInitialize->pRendererHasFocus() )
|
||||
{
|
||||
// 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 );
|
||||
}
|
||||
// get input
|
||||
((GCPad*)g_plugin.controllers[ _numPAD ])->GetInput( _pPADStatus );
|
||||
|
||||
// leave
|
||||
g_plugin.controls_crit.Leave();
|
||||
@ -202,9 +191,9 @@ void PAD_Rumble(u8 _numPAD, unsigned int _uType, unsigned int _uStrength)
|
||||
// enter
|
||||
if ( g_plugin.controls_crit.TryEnter() )
|
||||
{
|
||||
// only on/off rumble, if we have focus or background input on
|
||||
if ( g_plugin.controllers[_numPAD]->options[0].settings[0]->value || g_PADInitialize->pRendererHasFocus() )
|
||||
((GCPad*)g_plugin.controllers[ _numPAD ])->SetOutput( 1 == _uType && _uStrength > 2 );
|
||||
// TODO: this has potential to not stop rumble if user is messing with GUI at the perfect time
|
||||
// set rumble
|
||||
((GCPad*)g_plugin.controllers[ _numPAD ])->SetOutput( 1 == _uType && _uStrength > 2 );
|
||||
|
||||
// leave
|
||||
g_plugin.controls_crit.Leave();
|
||||
|
@ -571,6 +571,22 @@
|
||||
RelativePath=".\Src\WiimoteEmu\Attachment\Classic.h"
|
||||
>
|
||||
</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
|
||||
RelativePath=".\Src\WiimoteEmu\Attachment\Nunchuk.cpp"
|
||||
>
|
||||
|
@ -11,6 +11,8 @@ files = [
|
||||
'WiimoteEmu/Attachment/Classic.cpp',
|
||||
'WiimoteEmu/Attachment/Attachment.cpp',
|
||||
'WiimoteEmu/Attachment/Nunchuk.cpp',
|
||||
'WiimoteEmu/Attachment/Drums.cpp',
|
||||
'WiimoteEmu/Attachment/Guitar.cpp',
|
||||
'WiimoteEmu/EmuSubroutines.cpp',
|
||||
'WiimoteEmu/Encryption.cpp',
|
||||
'WiimoteNew.cpp',
|
||||
|
@ -5,8 +5,6 @@ namespace WiimoteEmu
|
||||
{
|
||||
|
||||
// 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
|
||||
static const u8 nothing_id[] = { 0x00, 0x00, 0x00, 0x00, 0x2e, 0x2e };
|
||||
// The id for a partially inserted extension
|
||||
|
@ -4,7 +4,7 @@
|
||||
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 */
|
||||
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::Classic() : Attachment( "Classic Controller" )
|
||||
Classic::Classic() : Attachment( "Classic" )
|
||||
{
|
||||
// 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
|
||||
{
|
||||
|
||||
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
|
||||
extension register. 0x80 is the neutral x and y accelerators and 0xb3 is the
|
||||
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, " Mode: 0x%02x", dr->mode);
|
||||
|
||||
m_rumble_on = (dr->rumble != 0);
|
||||
|
||||
m_reporting_auto = dr->all_the_time;
|
||||
m_reporting_mode = dr->mode;
|
||||
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);
|
||||
|
||||
// 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)
|
||||
{
|
||||
case WM_RUMBLE : // 0x10
|
||||
m_rumble_on = (sr->data[0] != 0);
|
||||
// this is handled above
|
||||
return; // no ack
|
||||
break;
|
||||
|
||||
@ -116,6 +118,7 @@ void Wiimote::HidOutputReport(const u16 _channelID, wm_report* sr)
|
||||
|
||||
case WM_SPEAKER_ENABLE : // 0x14
|
||||
//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;
|
||||
break;
|
||||
|
||||
@ -135,12 +138,24 @@ void Wiimote::HidOutputReport(const u16 _channelID, wm_report* sr)
|
||||
|
||||
case WM_WRITE_SPEAKER_DATA : // 0x18
|
||||
// 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
|
||||
break;
|
||||
|
||||
case WM_SPEAKER_MUTE : // 0x19
|
||||
//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;
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
// old comment
|
||||
/* Here we produce a 0x20 status report to send to the Wii. We currently ignore
|
||||
the status request rs and all its eventual instructions it may include (for
|
||||
example turn off rumble or something else) and just send the status
|
||||
report. */
|
||||
void Wiimote::RequestStatus(const u16 _channelID, wm_request_status* rs)
|
||||
{
|
||||
if (rs)
|
||||
m_rumble_on = (rs->rumble != 0);
|
||||
//if (rs)
|
||||
|
||||
// handle 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
|
||||
address &= 0xFEFFFF;
|
||||
|
||||
m_rumble_on = ( wd->rumble != 0 );
|
||||
|
||||
if (wd->size > 16)
|
||||
{
|
||||
PanicAlert("WriteData: size is > 16 bytes");
|
||||
@ -278,6 +291,10 @@ void Wiimote::WriteData(const u16 _channelID, wm_write_data* wd)
|
||||
|
||||
switch (address >> 16)
|
||||
{
|
||||
// speaker
|
||||
case 0xa2 :
|
||||
//PanicAlert("Write to speaker!!");
|
||||
break;
|
||||
// extension register
|
||||
case 0xa4 :
|
||||
{
|
||||
@ -311,8 +328,6 @@ void Wiimote::ReadData(const u16 _channelID, wm_read_data* rd)
|
||||
// ignore the 0x010000 bit
|
||||
address &= 0xFEFFFF;
|
||||
|
||||
m_rumble_on = (rd->rumble != 0);
|
||||
|
||||
ReadRequest rr;
|
||||
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);
|
||||
// Read from EEPROM
|
||||
if (address + size > WIIMOTE_EEPROM_FREE_SIZE)
|
||||
if (address + size >= WIIMOTE_EEPROM_FREE_SIZE)
|
||||
{
|
||||
if (address + size > WIIMOTE_EEPROM_SIZE)
|
||||
{
|
||||
@ -362,17 +377,20 @@ void Wiimote::ReadData(const u16 _channelID, wm_read_data* rd)
|
||||
|
||||
switch (address >> 16)
|
||||
{
|
||||
// speaker
|
||||
case 0xa2 :
|
||||
//PanicAlert("read from speaker!!");
|
||||
break;
|
||||
// extension
|
||||
case 0xa4 :
|
||||
{
|
||||
// Encrypt data read from extension register
|
||||
// Check if encrypted reads is on
|
||||
if ( m_reg_ext[0xf0] == 0xaa )
|
||||
{
|
||||
// I probably totally f'ed this up
|
||||
wiimote_encrypt(&m_ext_key, block, address & 0xffff, (u8)size);
|
||||
}
|
||||
}
|
||||
break;
|
||||
// motion plus
|
||||
case 0xa6 :
|
||||
{
|
||||
// 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
|
||||
}
|
||||
|
||||
|
||||
// TODO: is there a reason these can only handle a length of 255?
|
||||
/* Encrypt data */
|
||||
void wiimote_encrypt(wiimote_key *key, u8 *data, int addr, u8 len)
|
||||
{
|
||||
|
@ -1,6 +1,8 @@
|
||||
|
||||
#include "Attachment/Classic.h"
|
||||
#include "Attachment/Nunchuk.h"
|
||||
#include "Attachment/Guitar.h"
|
||||
#include "Attachment/Drums.h"
|
||||
|
||||
#include "WiimoteEmu.h"
|
||||
#include "WiimoteHid.h"
|
||||
@ -39,6 +41,7 @@ static const u8 eeprom_data_0[] = {
|
||||
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[] = {
|
||||
0x00, 0x00, 0x00, 0xFF, 0x11, 0xEE, 0x00, 0x00,
|
||||
@ -110,6 +113,7 @@ void Wiimote::Reset()
|
||||
m_reporting_auto = false;
|
||||
|
||||
m_rumble_on = false;
|
||||
m_speaker_mute = false;
|
||||
|
||||
// will make the first Update() call send a status request
|
||||
// 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[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_motion_plus = &m_register[0xa60000][0];
|
||||
m_reg_motion_plus = &m_register[0xa60000][0];
|
||||
m_reg_ir = &m_register[0xB00000][0];
|
||||
|
||||
// testing
|
||||
//memcpy( m_reg_motion_plus + 0xfa, motion_plus_id, sizeof(motion_plus_id) );
|
||||
|
||||
// status
|
||||
memset( &m_status, 0, sizeof(m_status) );
|
||||
// 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::Nunchuk() );
|
||||
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
|
||||
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" ) );
|
||||
|
||||
// options
|
||||
groups.push_back( options = new ControlGroup( "Options" ) );
|
||||
options->settings.push_back( new ControlGroup::Setting( "Background Input", false ) );
|
||||
options->settings.push_back( new ControlGroup::Setting( "Sideways Wiimote", false ) );
|
||||
groups.push_back( m_options = new ControlGroup( "Options" ) );
|
||||
m_options->settings.push_back( new ControlGroup::Setting( "Background Input", false ) );
|
||||
m_options->settings.push_back( new ControlGroup::Setting( "Sideways Wiimote", false ) );
|
||||
|
||||
|
||||
// --- reset eeprom/register/values to default ---
|
||||
@ -211,16 +219,29 @@ std::string Wiimote::GetName() const
|
||||
|
||||
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
|
||||
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
|
||||
if (false == focus)
|
||||
m_rumble_on = false;
|
||||
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
|
||||
m_status.buttons = 0;
|
||||
if ( focus )
|
||||
@ -324,7 +345,7 @@ void Wiimote::Update()
|
||||
else
|
||||
m_shake_step = 0;
|
||||
|
||||
// swing
|
||||
// TODO: swing
|
||||
//u8 swing[3];
|
||||
//m_swing->GetState( swing, 0x80, 60 );
|
||||
//for ( unsigned int i=0; i<3; ++i )
|
||||
@ -337,7 +358,11 @@ void Wiimote::Update()
|
||||
if (rpt.ext)
|
||||
{
|
||||
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
|
||||
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
|
||||
#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_EXT_SIZE 0x100
|
||||
#define WIIMOTE_REG_IR_SIZE 0x34
|
||||
@ -28,20 +28,22 @@ extern const u8 shake_data[8];
|
||||
class Wiimote : public ControllerEmu
|
||||
{
|
||||
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
|
||||
{
|
||||
unsigned int address, size, position;
|
||||
u8* data;
|
||||
};
|
||||
|
||||
Wiimote( const unsigned int index );
|
||||
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 HidOutputReport(const u16 _channelID, wm_report* sr);
|
||||
void SendAck(const u16 _channelID, u8 _reportID);
|
||||
@ -51,10 +53,7 @@ public:
|
||||
void ReadData(const u16 _channelID, wm_read_data* rd);
|
||||
void SendReadDataReply(const u16 _channelID, ReadRequest& _request);
|
||||
|
||||
std::string GetName() const;
|
||||
|
||||
private:
|
||||
|
||||
// control groups
|
||||
Buttons* m_buttons;
|
||||
Buttons* m_dpad;
|
||||
Buttons* m_shake;
|
||||
@ -63,11 +62,13 @@ private:
|
||||
Force* m_swing;
|
||||
ControlGroup* m_rumble;
|
||||
Extension* m_extension;
|
||||
// TODO: add ir
|
||||
ControlGroup* m_options;
|
||||
|
||||
// wiimote index, 0-3
|
||||
const unsigned int m_index;
|
||||
|
||||
bool m_rumble_on;
|
||||
bool m_speaker_mute;
|
||||
|
||||
bool m_reporting_auto;
|
||||
unsigned int m_reporting_mode;
|
||||
@ -90,13 +91,20 @@ private:
|
||||
// maybe read requests cancel any current requests
|
||||
std::queue< ReadRequest > m_read_requests;
|
||||
|
||||
//u8 m_eeprom[WIIMOTE_EEPROM_SIZE];
|
||||
u8 m_eeprom[WIIMOTE_EEPROM_SIZE];
|
||||
//std::queue< u8 > m_speaker_data;
|
||||
|
||||
//u8* m_reg_speaker;
|
||||
//u8* m_reg_motion_plus;
|
||||
u8* m_reg_ir;
|
||||
u8 m_eeprom[WIIMOTE_EEPROM_SIZE];
|
||||
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;
|
||||
};
|
||||
|
@ -99,7 +99,7 @@ struct wm_classic_extension
|
||||
u16 bt; // byte 4, 5
|
||||
};
|
||||
|
||||
struct wm_GH3_extension
|
||||
struct wm_guitar_extension
|
||||
{
|
||||
u8 sx : 6;
|
||||
u8 pad1 : 2; // 1 on gh3, 0 on ghwt
|
||||
@ -113,23 +113,28 @@ struct wm_GH3_extension
|
||||
u8 whammy : 5;
|
||||
u8 pad4 : 3; // always 0
|
||||
|
||||
u8 pad5 : 2; // always 1
|
||||
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;
|
||||
u16 bt; // buttons
|
||||
};
|
||||
|
||||
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 {
|
||||
u8 wm;
|
||||
@ -279,7 +284,10 @@ struct wm_report_ext21
|
||||
#define WM_SPEAKER_ENABLE 0x14
|
||||
#define WM_SPEAKER_MUTE 0x19
|
||||
#define WM_WRITE_SPEAKER_DATA 0x18
|
||||
|
||||
struct wm_speaker_data {
|
||||
u8 length; // shifted left by three bits
|
||||
u8 data[20];
|
||||
};
|
||||
|
||||
// Custom structs
|
||||
|
||||
|
@ -140,13 +140,7 @@ void InitPlugin( void* const hwnd )
|
||||
void Wiimote_ControlChannel(int _number, u16 _channelID, const void* _pData, u32 _Size)
|
||||
{
|
||||
//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 );
|
||||
|
||||
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)
|
||||
{
|
||||
//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 );
|
||||
|
||||
g_plugin.controls_crit.Leave();
|
||||
}
|
||||
|
||||
// __________________________________________________________________________________________________
|
||||
@ -337,7 +325,7 @@ void Shutdown(void)
|
||||
//
|
||||
void DoState(unsigned char **ptr, int mode)
|
||||
{
|
||||
// prolly won't need this
|
||||
// do this later
|
||||
}
|
||||
|
||||
// ___________________________________________________________________________
|
||||
|
Loading…
x
Reference in New Issue
Block a user