Clean up "ControllerInterface" a bit.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7339 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Jordan Woyak
2011-03-14 01:20:11 +00:00
parent 37e31f2df6
commit 8fedc3db38
16 changed files with 416 additions and 659 deletions

View File

@ -51,64 +51,64 @@ static const char* const named_motors[] =
"Motor R"
};
void Init( std::vector<ControllerInterface::Device*>& devices )
void Init(DeviceList& devices)
{
XINPUT_CAPABILITIES caps;
for ( int i = 0; i < 4; ++i )
if ( ERROR_SUCCESS == XInputGetCapabilities( i, 0, &caps ) )
devices.push_back( new Device( &caps, i ) );
for (int i = 0; i != 4; ++i)
if (ERROR_SUCCESS == XInputGetCapabilities(i, 0, &caps))
devices.push_back(new Device(caps, i));
}
Device::Device( const XINPUT_CAPABILITIES* const caps, const unsigned int index )
: m_index(index), m_subtype(caps->SubType)
Device::Device(const XINPUT_CAPABILITIES& caps, u8 index)
: m_index(index), m_subtype(caps.SubType)
{
ZeroMemory( &m_state_out, sizeof(m_state_out) );
ZeroMemory( &m_current_state_out, sizeof(m_current_state_out) );
ZeroMemory(&m_state_out, sizeof(m_state_out));
ZeroMemory(&m_current_state_out, sizeof(m_current_state_out));
// XInputGetCaps seems to always claim all capabilities are supported
// but i will leave all this stuff in, incase m$ fixes xinput up a bit
// get supported buttons
for ( int i = 0; i < sizeof(named_buttons)/sizeof(*named_buttons); ++i )
if ( named_buttons[i].bitmask & caps->Gamepad.wButtons )
AddInput( new Button( /*xinput_named_buttons[i].bitmask, */i ) );
for (int i = 0; i != sizeof(named_buttons)/sizeof(*named_buttons); ++i)
if (named_buttons[i].bitmask & caps.Gamepad.wButtons)
AddInput(new Button(i, m_state_in.Gamepad.wButtons));
// get supported triggers
for ( int i = 0; i < sizeof(named_triggers)/sizeof(*named_triggers); ++i )
for (int i = 0; i != sizeof(named_triggers)/sizeof(*named_triggers); ++i)
{
//BYTE val = (&caps->Gamepad.bLeftTrigger)[i]; // should be max value / msdn lies
if ( (&caps->Gamepad.bLeftTrigger)[i] )
AddInput( new Trigger( i, 255 ) );
//BYTE val = (&caps.Gamepad.bLeftTrigger)[i]; // should be max value / msdn lies
if ((&caps.Gamepad.bLeftTrigger)[i])
AddInput(new Trigger(i, (&m_state_in.Gamepad.bLeftTrigger)[i], 255 ));
}
// get supported axes
for ( int i = 0; i < sizeof(named_axes)/sizeof(*named_axes); ++i )
for (int i = 0; i != sizeof(named_axes)/sizeof(*named_axes); ++i)
{
//SHORT val = (&caps->Gamepad.sThumbLX)[i]; // xinput doesnt give the range / msdn is lier
if ( (&caps->Gamepad.sThumbLX)[i] )
//SHORT val = (&caps.Gamepad.sThumbLX)[i]; // xinput doesnt give the range / msdn is lier
if ((&caps.Gamepad.sThumbLX)[i])
{
const SHORT& ax = (&m_state_in.Gamepad.sThumbLX)[i];
// each axis gets a negative and a positive input instance associated with it
AddInput( new Axis( i, -32768 ) );
AddInput( new Axis( i, 32767 ) );
AddInput(new Axis(i, ax, -32768));
AddInput(new Axis(i, ax, 32767));
}
}
// get supported motors
for ( int i = 0; i < sizeof(named_motors)/sizeof(*named_motors); ++i )
for (int i = 0; i != sizeof(named_motors)/sizeof(*named_motors); ++i)
{
//WORD val = (&caps->Vibration.wLeftMotorSpeed)[i]; // should be max value / nope, more lies
if ( (&caps->Vibration.wLeftMotorSpeed)[i] )
AddOutput( new Motor(i, 65535 ) );
//WORD val = (&caps.Vibration.wLeftMotorSpeed)[i]; // should be max value / nope, more lies
if ((&caps.Vibration.wLeftMotorSpeed)[i])
AddOutput(new Motor(i, (&m_state_out.wLeftMotorSpeed)[i], 65535));
}
ClearInputState();
}
void Device::ClearInputState()
{
ZeroMemory( &m_state_in, sizeof(m_state_in) );
ZeroMemory(&m_state_in, sizeof(m_state_in));
}
std::string Device::GetName() const
@ -117,7 +117,7 @@ std::string Device::GetName() const
// subtype doesn't seem to work, i tested with 2 diff arcade sticks, both were shown as gamepad
// ill leave it in anyway, maybe m$ will fix it
switch ( m_subtype )
switch (m_subtype)
{
case XINPUT_DEVSUBTYPE_GAMEPAD : return "Gamepad"; break;
case 0x02 /*XINPUT_DEVSUBTYPE_WHEEL*/ : return "Wheel"; break;
@ -144,17 +144,17 @@ std::string Device::GetSource() const
bool Device::UpdateInput()
{
return ( ERROR_SUCCESS == XInputGetState( m_index, &m_state_in ) );
return (ERROR_SUCCESS == XInputGetState(m_index, &m_state_in));
}
bool Device::UpdateOutput()
{
// this if statement is to make rumble work better when multiple ControllerInterfaces are using the device
// only calls XInputSetState if the state changed
if ( memcmp( &m_state_out, &m_current_state_out, sizeof(m_state_out) ) )
if (memcmp(&m_state_out, &m_current_state_out, sizeof(m_state_out)))
{
m_current_state_out = m_state_out;
return ( ERROR_SUCCESS == XInputSetState( m_index, &m_state_out ) );
return (ERROR_SUCCESS == XInputSetState(m_index, &m_state_out));
}
else
return true;
@ -162,7 +162,6 @@ bool Device::UpdateOutput()
// GET name/source/id
std::string Device::Button::GetName() const
{
return named_buttons[m_index].name;
@ -183,38 +182,26 @@ std::string Device::Motor::GetName() const
return named_motors[m_index];
}
// get/set control state
ControlState Device::GetInputState( const ControllerInterface::Device::Input* const input ) const
{
return ((Input*)input)->GetState( &m_state_in.Gamepad );
}
void Device::SetOutputState( const ControllerInterface::Device::Output* const output, const ControlState state )
{
return ((Output*)output)->SetState( state, &m_state_out );
}
// GET / SET STATES
ControlState Device::Button::GetState( const XINPUT_GAMEPAD* const gamepad ) const
ControlState Device::Button::GetState() const
{
return (gamepad->wButtons & named_buttons[m_index].bitmask) > 0;
return (m_buttons & named_buttons[m_index].bitmask) > 0;
}
ControlState Device::Trigger::GetState( const XINPUT_GAMEPAD* const gamepad ) const
ControlState Device::Trigger::GetState() const
{
return ControlState((&gamepad->bLeftTrigger)[m_index]) / m_range;
return ControlState(m_trigger) / m_range;
}
ControlState Device::Axis::GetState( const XINPUT_GAMEPAD* const gamepad ) const
ControlState Device::Axis::GetState() const
{
return std::max( 0.0f, ControlState((&gamepad->sThumbLX)[m_index]) / m_range );
return std::max( 0.0f, ControlState(m_axis) / m_range );
}
void Device::Motor::SetState( const ControlState state, XINPUT_VIBRATION* const vibration )
void Device::Motor::SetState(ControlState state)
{
(&vibration->wLeftMotorSpeed)[m_index] = (WORD)(state * m_range);
m_motor = (WORD)(state * m_range);
}
}

View File

@ -12,101 +12,75 @@ namespace ciface
namespace XInput
{
void Init( std::vector<ControllerInterface::Device*>& devices );
void Init(DeviceList& devices);
class Device : public ControllerInterface::Device
{
friend class ControllerInterface;
friend class ControllerInterface::ControlReference;
protected:
class Input : public ControllerInterface::Device::Input
{
friend class Device;
protected:
virtual ControlState GetState( const XINPUT_GAMEPAD* const gamepad ) const = 0;
};
class Output : public ControllerInterface::Device::Output
{
friend class Device;
protected:
virtual void SetState( const ControlState state, XINPUT_VIBRATION* const vibration ) = 0;
};
private:
class Button : public Input
{
friend class Device;
public:
std::string GetName() const;
protected:
Button( const unsigned int index ) : m_index(index) {}
ControlState GetState( const XINPUT_GAMEPAD* const gamepad ) const;
Button(u8 index, const WORD& buttons) : m_index(index), m_buttons(buttons) {}
ControlState GetState() const;
private:
const unsigned int m_index;
const WORD& m_buttons;
u8 m_index;
};
class Axis : public Input
{
friend class Device;
public:
std::string GetName() const;
protected:
Axis( const unsigned int index, const SHORT range ) : m_index(index), m_range(range) {}
ControlState GetState( const XINPUT_GAMEPAD* const gamepad ) const;
Axis(u8 index, const SHORT& axis, SHORT range) : m_index(index), m_axis(axis), m_range(range) {}
ControlState GetState() const;
private:
const unsigned int m_index;
const SHORT m_range;
const SHORT& m_axis;
const SHORT m_range;
const u8 m_index;
};
class Trigger : public Input
{
friend class Device;
public:
std::string GetName() const;
protected:
Trigger( const unsigned int index, const BYTE range ) : m_index(index), m_range(range) {}
ControlState GetState( const XINPUT_GAMEPAD* const gamepad ) const;
Trigger(u8 index, const BYTE& trigger, BYTE range) : m_index(index), m_trigger(trigger), m_range(range) {}
ControlState GetState() const;
private:
const unsigned int m_index;
const BYTE m_range;
const BYTE& m_trigger;
const BYTE m_range;
const u8 m_index;
};
class Motor : public Output
{
friend class Device;
public:
std::string GetName() const;
protected:
Motor( const unsigned int index, const WORD range ) : m_index(index), m_range(range) {}
void SetState( const ControlState state, XINPUT_VIBRATION* const vibration );
Motor(u8 index, WORD& motor, WORD range) : m_index(index), m_motor(motor), m_range(range) {}
void SetState(ControlState state);
private:
const unsigned int m_index;
const WORD m_range;
WORD& m_motor;
const WORD m_range;
const u8 m_index;
};
public:
bool UpdateInput();
bool UpdateOutput();
ControlState GetInputState( const ControllerInterface::Device::Input* const input ) const;
void SetOutputState( const ControllerInterface::Device::Output* const input, const ControlState state );
void ClearInputState();
public:
Device( const XINPUT_CAPABILITIES* const capabilities, const unsigned int index );
Device(const XINPUT_CAPABILITIES& capabilities, u8 index);
std::string GetName() const;
int GetId() const;
std::string GetSource() const;
private:
const unsigned int m_index;
XINPUT_STATE m_state_in;
XINPUT_VIBRATION m_state_out;
XINPUT_VIBRATION m_current_state_out;
const unsigned int m_subtype;
XINPUT_STATE m_state_in;
XINPUT_VIBRATION m_state_out, m_current_state_out;
const BYTE m_subtype;
const u8 m_index;
};