diff --git a/Source/Core/Core/Src/HW/GCPadEmu.cpp b/Source/Core/Core/Src/HW/GCPadEmu.cpp index 482291f0bc..6f05e10495 100644 --- a/Source/Core/Core/Src/HW/GCPadEmu.cpp +++ b/Source/Core/Core/Src/HW/GCPadEmu.cpp @@ -126,7 +126,7 @@ void GCPad::SetOutput( const bool on ) void GCPad::LoadDefaults() { - #define set_control(group, num, str) (group)->controls[num]->control_ref->control_qualifier.name = (str) + #define set_control(group, num, str) (group)->controls[num]->control_ref->expression = (str) // nvm, do the device part elsewhere //#ifdef _WIN32 diff --git a/Source/Core/InputCommon/InputCommon.vcproj b/Source/Core/InputCommon/InputCommon.vcproj index 7612b3fd06..1ed94a6700 100644 --- a/Source/Core/InputCommon/InputCommon.vcproj +++ b/Source/Core/InputCommon/InputCommon.vcproj @@ -1,7 +1,7 @@ + + + + ::const_iterator i = groups.begin(), @@ -73,7 +73,7 @@ void ControllerEmu::UpdateReferences( ControllerInterface& devi ) ci = (*i)->controls.begin(), ce = (*i)->controls.end(); for ( ; ci!=ce; ++ci ) - devi.UpdateReference( (*ci)->control_ref ); + devi.UpdateReference((*ci)->control_ref, default_device); // extension if ( GROUP_TYPE_EXTENSION == (*i)->type ) @@ -82,7 +82,7 @@ void ControllerEmu::UpdateReferences( ControllerInterface& devi ) ai = ((Extension*)*i)->attachments.begin(), ae = ((Extension*)*i)->attachments.end(); for ( ; ai!=ae; ++ai ) - (*ai)->UpdateReferences( devi ); + (*ai)->UpdateReferences(devi); } } } @@ -94,11 +94,11 @@ void ControllerEmu::UpdateDefaultDevice() e = groups.end(); for ( ; i!=e; ++i ) { - std::vector::const_iterator - ci = (*i)->controls.begin(), - ce = (*i)->controls.end(); - for ( ; ci!=ce; ++ci ) - (*ci)->control_ref->device_qualifier = default_device; + //std::vector::const_iterator + //ci = (*i)->controls.begin(), + //ce = (*i)->controls.end(); + //for ( ; ci!=ce; ++ci ) + //(*ci)->control_ref->device_qualifier = default_device; // extension if ( GROUP_TYPE_EXTENSION == (*i)->type ) @@ -135,19 +135,13 @@ void ControllerEmu::ControlGroup::LoadConfig(IniFile::Section *sec, const std::s ce = controls.end(); for ( ; ci!=ce; ++ci ) { - // control and dev qualifier - sec->Get((group + (*ci)->name).c_str(), &(*ci)->control_ref->control_qualifier.name, ""); - std::string dev; - sec->Get((group+(*ci)->name+"/Device").c_str(), &dev, defdev.c_str()); - (*ci)->control_ref->device_qualifier.FromString(dev); + // control expression + sec->Get((group + (*ci)->name).c_str(), &(*ci)->control_ref->expression, ""); // range sec->Get( (group+(*ci)->name+"/Range").c_str(), &(*ci)->control_ref->range, 100.0f); (*ci)->control_ref->range /= 100; - // input mode - if ( (*ci)->control_ref->is_input ) - sec->Get( (group+(*ci)->name+"/Mode").c_str(), &((ControllerInterface::InputReference*)((*ci)->control_ref))->mode, 0 ); } // extensions @@ -205,22 +199,11 @@ void ControllerEmu::ControlGroup::SaveConfig( IniFile::Section *sec, const std:: ce = controls.end(); for ( ; ci!=ce; ++ci ) { - // control and dev qualifier - sec->Set( (group+(*ci)->name).c_str(), (*ci)->control_ref->control_qualifier.name, ""); - sec->Set( (group+(*ci)->name+"/Device").c_str(), (*ci)->control_ref->device_qualifier.ToString(), defdev); + // control expression + sec->Set( (group+(*ci)->name).c_str(), (*ci)->control_ref->expression, ""); // range sec->Set( (group+(*ci)->name+"/Range").c_str(), (*ci)->control_ref->range*100.0f, 100.0f); - - // input mode - if ( (*ci)->control_ref->is_input ) - { - const int mode = ((ControllerInterface::InputReference*)((*ci)->control_ref))->mode; - if (mode) - sec->Set((group+(*ci)->name+"/Mode").c_str(), mode); - else - sec->Delete((group+(*ci)->name+"/Mode").c_str()); - } } // extensions diff --git a/Source/Core/InputCommon/Src/ControllerEmu.h b/Source/Core/InputCommon/Src/ControllerEmu.h index dbe2ec3491..616a459b7b 100644 --- a/Source/Core/InputCommon/Src/ControllerEmu.h +++ b/Source/Core/InputCommon/Src/ControllerEmu.h @@ -372,12 +372,12 @@ public: // use mouse cursor, or user defined mapping if they have something mapped // this if seems horrible - if ( controls[0]->control_ref->control_qualifier.name.size() || controls[1]->control_ref->control_qualifier.name.size() ) + if ( controls[0]->control_ref->BoundCount() || controls[1]->control_ref->BoundCount() ) yy = controls[0]->control_ref->State() - controls[1]->control_ref->State(); else yy = -yy; - if ( controls[2]->control_ref->control_qualifier.name.size() || controls[3]->control_ref->control_qualifier.name.size() ) + if ( controls[2]->control_ref->BoundCount() || controls[3]->control_ref->BoundCount() ) xx = controls[3]->control_ref->State() - controls[2]->control_ref->State(); // adjust cursor according to settings diff --git a/Source/Core/InputCommon/Src/ControllerInterface/ControllerInterface.cpp b/Source/Core/InputCommon/Src/ControllerInterface/ControllerInterface.cpp index 78a4d81244..efa81ce38b 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/ControllerInterface.cpp +++ b/Source/Core/InputCommon/Src/ControllerInterface/ControllerInterface.cpp @@ -1,7 +1,5 @@ #include "ControllerInterface.h" -namespace ciface { -} #ifdef CIFACE_USE_XINPUT #include "XInput/XInput.h" #endif @@ -19,8 +17,7 @@ namespace ciface { #endif #include "Thread.h" -//#define MAX_DOUBLE_TAP_TIME 400 -//#define MAX_HOLD_DOWN_TIME 400 + #define INPUT_DETECT_THRESHOLD 0.85 // @@ -34,19 +31,19 @@ void ControllerInterface::Init() return; #ifdef CIFACE_USE_DIRECTINPUT - ciface::DirectInput::Init( m_devices/*, (HWND)m_hwnd*/ ); + ciface::DirectInput::Init(m_devices); #endif #ifdef CIFACE_USE_XINPUT - ciface::XInput::Init( m_devices ); + ciface::XInput::Init(m_devices); #endif #ifdef CIFACE_USE_XLIB - ciface::Xlib::Init( m_devices, m_hwnd ); + ciface::Xlib::Init(m_devices, m_hwnd); #endif #ifdef CIFACE_USE_OSX - ciface::OSX::Init( m_devices ); + ciface::OSX::Init(m_devices); #endif #ifdef CIFACE_USE_SDL - ciface::SDL::Init( m_devices ); + ciface::SDL::Init(m_devices); #endif m_is_init = true; @@ -62,20 +59,22 @@ void ControllerInterface::DeInit(const bool hacks_no_sdl_quit) if ( false == m_is_init ) return; - std::vector::const_iterator d = m_devices.begin(), - Devices_end = m_devices.end(); - for ( ;d != Devices_end; ++d ) + std::vector::const_iterator + d = m_devices.begin(), + de = m_devices.end(); + for ( ;d != de; ++d ) { - std::vector::const_iterator o = (*d)->Outputs().begin(), - e = (*d)->Outputs().end(); + std::vector::const_iterator + o = (*d)->Outputs().begin(), + oe = (*d)->Outputs().end(); // set outputs to ZERO before destroying device - for ( ;o!=e; ++o) - (*d)->SetOutputState( *o, 0 ); + for ( ;o!=oe; ++o) + (*d)->SetOutputState(*o, 0); // update output (*d)->UpdateOutput(); // TODO: remove this - // major hacks to prevent gcpad/wiimote new from crashing eachother + // major hacks/memleaks to prevent gcpad/wiimote new from crashing eachother if (hacks_no_sdl_quit) if ((*d)->GetSource() == "SDL") continue; @@ -126,18 +125,19 @@ bool ControllerInterface::UpdateInput() { size_t ok_count = 0; - std::vector::const_iterator d = m_devices.begin(), - e = m_devices.end(); + std::vector::const_iterator + d = m_devices.begin(), + e = m_devices.end(); for ( ;d != e; ++d ) { - if ( (*d)->UpdateInput() ) + if ((*d)->UpdateInput()) ++ok_count; //else // disabled. it might be causing problems //(*d)->ClearInputState(); } - return ( m_devices.size() == ok_count ); + return (m_devices.size() == ok_count); } // @@ -149,23 +149,13 @@ bool ControllerInterface::UpdateOutput() { size_t ok_count = 0; - std::vector::const_iterator d = m_devices.begin(), - e = m_devices.end(); - for ( ;d != e; ++d ) + std::vector::const_iterator + d = m_devices.begin(), + e = m_devices.end(); + for (;d != e; ++d) (*d)->UpdateOutput(); - return ( m_devices.size() == ok_count ); -} - -// -// Devices -// -// i dont really like this but, -// return : constant copy of the devices vector -// -const std::vector& ControllerInterface::Devices() -{ - return m_devices; + return (m_devices.size() == ok_count); } // @@ -177,21 +167,33 @@ ControllerInterface::Device::~Device() { { // delete inputs - std::vector::iterator i = inputs.begin(), - e = inputs.end(); + std::vector::iterator + i = m_inputs.begin(), + e = m_inputs.end(); for ( ;i!=e; ++i) delete *i; } { // delete outputs - std::vector::iterator o = outputs.begin(), - e = outputs.end(); + std::vector::iterator + o = m_outputs.begin(), + e = m_outputs.end(); for ( ;o!=e; ++o) delete *o; } } +void ControllerInterface::Device::AddInput(Input* const i) +{ + m_inputs.push_back(i); +} + +void ControllerInterface::Device::AddOutput(Output* const o) +{ + m_outputs.push_back(o); +} + // // Device :: ClearInputState // @@ -206,36 +208,6 @@ void ControllerInterface::Device::ClearInputState() // kinda slow but, w/e, should only happen when user unplugs a device while playing } -// -// Device :: Inputs -// -// get a const version of the device's input vector -// -const std::vector& ControllerInterface::Device::Inputs() -{ - return inputs; -} - -// -// Device :: Outputs -// -// get a const version of the device's outputs vector -// -const std::vector& ControllerInterface::Device::Outputs() -{ - return outputs; -} - -// -// HasInit -// -// check if interface is inited -// -bool ControllerInterface::IsInit() -{ - return m_is_init; -} - // // InputReference :: State // @@ -244,55 +216,46 @@ bool ControllerInterface::IsInit() // ControlState ControllerInterface::InputReference::State( const ControlState ignore ) { - if ( NULL == device ) - return 0; + //if (NULL == device) + //return 0; ControlState state = 0; - switch ( mode ) - { - // OR - case 0 : - { - state = 0; - std::vector::const_iterator ci = controls.begin(), - ce = controls.end(); - for ( ; ci != ce; ++ci ) - state = std::max( state, device->GetInputState( (Device::Input*)*ci ) ); // meh casting - break; - } - // AND - case 1 : - { - // TODO: i think i can remove the if here + std::vector::const_iterator + ci = m_controls.begin(), + ce = m_controls.end(); + // bit of hax for NOT to work at start of expression + if (ci != ce) + if (ci->mode == 2) state = 1; - bool is_bound = false; - std::vector::const_iterator ci = controls.begin(), - ce = controls.end(); - for ( ; ci != ce; ++ci ) - { - is_bound = true; - state = std::min( state, device->GetInputState( (Device::Input*)*ci ) ); // meh casting - } - if ( !is_bound ) - state = 0; - break; - } - // NOT - case 2 : + + for (; ci!=ce; ++ci) + { + const ControlState istate = ci->device->GetInputState((Device::Input*)ci->control); + + switch (ci->mode) { - state = 0; - std::vector::const_iterator ci = controls.begin(), - ce = controls.end(); - for ( ; ci != ce; ++ci ) - state = std::max( state, device->GetInputState( (Device::Input*)*ci ) ); // meh casting - state = std::max( 0.0, 1.0 - state ); - break; + // OR + case 0 : + state = std::max(state, istate); + break; + // AND + case 1 : + state = std::min(state, istate); + break; + // NOT + case 2 : + state = std::max(std::min(state, 1.0f - istate), 0.0f); + break; + // ADD + case 3 : + state += istate; + break; } } - return std::min( 1.0f, state * range ); + return std::min(1.0f, state * range); } // @@ -302,12 +265,17 @@ ControlState ControllerInterface::InputReference::State( const ControlState igno // overrides ControlReference::State .. combined them so i could make the gui simple / inputs == same as outputs one list // i was lazy and it works so watever // -ControlState ControllerInterface::OutputReference::State( const ControlState state ) +ControlState ControllerInterface::OutputReference::State(const ControlState state) { - std::vector::iterator ci = controls.begin(), - ce = controls.end(); - for ( ; ci != ce; ++ci ) - device->SetOutputState( (Device::Output*)*ci, state * range ); // casting again + const ControlState tmp_state = std::min(1.0f, state * range); + + // output ref just ignores the modes ( |&!... ) + + std::vector::iterator + ci = m_controls.begin(), + ce = m_controls.end(); + for (; ci != ce; ++ci) + ci->device->SetOutputState((Device::Output*)ci->control, tmp_state); return state; // just return the output, watever } @@ -319,7 +287,7 @@ ControlState ControllerInterface::OutputReference::State( const ControlState sta // std::string ControllerInterface::DeviceQualifier::ToString() const { - if ( source.empty() && (cid < 0) && name.empty() ) + if (source.empty() && (cid < 0) && name.empty()) return ""; std::ostringstream ss; ss << source << '/'; @@ -338,16 +306,13 @@ void ControllerInterface::DeviceQualifier::FromString(const std::string& str) { std::istringstream ss(str); - // good - std::getline( ss, source = "", '/' ); + std::getline(ss, source = "", '/'); - - // dum - std::getline( ss, name, '/' ); + // silly + std::getline(ss, name, '/'); std::istringstream(name) >> (cid = -1); - // good - std::getline( ss, name = ""); + std::getline(ss, name = ""); } // @@ -362,177 +327,165 @@ void ControllerInterface::DeviceQualifier::FromDevice(const ControllerInterface: source= dev->GetSource(); } -// -// DeviceQualifier = = Device* -// -// check if a device matches a device qualifier -// -bool ControllerInterface::DeviceQualifier::operator==(const ControllerInterface::Device* const dev) const +bool operator==(const ControllerInterface::Device* const dev, const ControllerInterface::DeviceQualifier& devq) { - if ( dev->GetName() == name ) - if ( dev->GetId() == cid ) - if ( dev->GetSource() == source ) + if (dev->GetId() == devq.cid) + if (dev->GetName() == devq.name) + if (dev->GetSource() == devq.source) return true; return false; } -// -// ControlQualifier = FromControl -// -// set a control qualifier from a device control -// -void ControllerInterface::ControlQualifier::FromControl(const ControllerInterface::Device::Control* const c) +bool operator==(const ControllerInterface::Device::Control* const c, const std::string& name) { - // hardly needs a function for this - name = c->GetName(); + return c->GetName() == name; } -// -// ControlQualifier = = Device :: Control* -// -// check if a control qualifier matches a device control -// also |control1|control2| form, || matches all -// -bool ControllerInterface::ControlQualifier::operator==(const ControllerInterface::Device::Control* const control) const +bool ControllerInterface::DeviceQualifier::operator==(const ControllerInterface::DeviceQualifier& devq) const { - if ( name.size() ) - { - if ( '|' == name[0] && '|' == (*name.rbegin()) ) // check if using |button1|button2| format - { - return ( name.find( '|' + control->GetName() + '|' ) != name.npos || "||" == name ); - } - } - return (control->GetName() == name); + if (cid == devq.cid) + if (name == devq.name) + if (source == devq.source) + return true; + return false; } // // UpdateReference // -// updates a controlreference's binded devices then update binded controls -// need to call this after changing a device qualifier on a control reference -// if the device qualifier hasnt changed, the below functions: "UpdateControls" can be used +// updates a controlreference's binded devices/controls +// need to call this to re-parse a control reference's expression after changing it // -void ControllerInterface::UpdateReference( ControllerInterface::ControlReference* ref ) +void ControllerInterface::UpdateReference(ControllerInterface::ControlReference* ref + , const ControllerInterface::DeviceQualifier& default_device) const { - ref->device = NULL; - std::vector::const_iterator d = m_devices.begin(), - e = m_devices.end(); - for ( ; d!=e; ++d ) - if ( ref->device_qualifier == *d ) + ref->m_controls.clear(); + + // adding | to parse the last item, silly + std::istringstream ss(ref->expression + '|'); + + const std::string mode_chars("|&!#"); + + ControlReference::DeviceControl devc; + + std::string dev_str; + std::string ctrl_str; + + char c = 0; + while (ss.read(&c, 1)) + { + const size_t f = mode_chars.find(c); + + if (mode_chars.npos != f) { - ref->device = *d; - break; + // add ctrl + if (ctrl_str.size()) + { + DeviceQualifier devq; + + // using default device or alterate device inside `backticks` + if (dev_str.empty()) + devq = default_device; + else + devq.FromString(dev_str); + + // find device + const std::vector::const_iterator di = + std::find(m_devices.begin(), m_devices.end(), devq); + if (m_devices.end() != di) + devc.device = *di; + + if (devc.device) + { + // control + + // inputs or outputs, i don't like this + if (ref->is_input) + { + const std::vector::const_iterator i = + std::find(devc.device->Inputs().begin(), devc.device->Inputs().end(), ctrl_str); + if (devc.device->Inputs().end() != i) + { + devc.control = *i; + ref->m_controls.push_back(devc); + } + } + else + { + const std::vector::const_iterator i = + std::find(devc.device->Outputs().begin(), devc.device->Outputs().end(), ctrl_str); + if (devc.device->Outputs().end() != i) + { + devc.control = *i; + ref->m_controls.push_back(devc); + } + } + + } + } + // reset stuff for next ctrl + devc.mode = (int)f; + devc.device = NULL; + ctrl_str.clear(); } - ref->UpdateControls(); -} - -// -// InputReference :: UpdateControls -// -// after changing a control qualifier, need to call this to rebind the new matching controls -// -void ControllerInterface::InputReference::UpdateControls() -{ - controls.clear(); - if ( device ) - { - std::vector::const_iterator i = device->Inputs().begin(), - e = device->Inputs().end(); - for ( ;i != e; ++i ) - if ( control_qualifier == *i ) - controls.push_back( *i ); + else if ('`' == c) + { + // different device + if (false == std::getline(ss, dev_str, '`')) + break; + } + else + ctrl_str += c; } } -// -// OutputReference :: UpdateControls -// -// same as the inputRef version -// after changing a control qualifier, need to call this to rebind the new matching controls -// -void ControllerInterface::OutputReference::UpdateControls() -{ - controls.clear(); - if ( device ) - { - std::vector::const_iterator i = device->Outputs().begin(), - e = device->Outputs().end(); - for ( ;i != e; ++i ) - if ( control_qualifier == *i ) - controls.push_back( *i ); - } - -} - // // InputReference :: Detect // // wait for input on all binded devices -// supports waiting for n number of inputs // supports not detecting inputs that were held down at the time of Detect start, // which is useful for those crazy flightsticks that have certain buttons that are always held down // or some crazy axes or something -// upon input, set control qualifier, update controls and return true -// else return false +// upon input, return pointer to detected Control +// else return NULL // -bool ControllerInterface::InputReference::Detect( const unsigned int ms, const unsigned int count ) +ControllerInterface::Device::Control* ControllerInterface::InputReference::Detect(const unsigned int ms, Device* const device) { - unsigned int time = 0; + bool* const states = new bool[device->Inputs().size()]; - // don't wait if we don't have a device - if ( device ) + // get starting state of all inputs, + // so we can ignore those that were activated at time of Detect start + std::vector::const_iterator + i = device->Inputs().begin(), + e = device->Inputs().end(); + for (bool* state=states; i != e; ++i) + *state++ = (device->GetInputState(*i) > INPUT_DETECT_THRESHOLD); + + while (time < ms) { - bool* const states = new bool[device->Inputs().size()]; - - std::vector::const_iterator i = device->Inputs().begin(), - e = device->Inputs().end(); - for ( unsigned int n=0;i != e; ++i,++n ) - states[n] = ( device->GetInputState( *i ) > INPUT_DETECT_THRESHOLD ); - - std::vector detected; - - while ( (time < ms) && (detected.size() < count) ) + device->UpdateInput(); + i = device->Inputs().begin(); + for (bool* state=states; i != e; ++i,++state) { - device->UpdateInput(); - i = device->Inputs().begin(); - e = device->Inputs().end(); - - for ( unsigned int n=0;i != e; ++i,++n ) + // detected an input + if ((*i)->IsDetectable() && device->GetInputState(*i) > INPUT_DETECT_THRESHOLD) { - if ( device->GetInputState( *i ) > INPUT_DETECT_THRESHOLD ) - { - if ( false == states[n] ) - if ( std::find( detected.begin(), detected.end(), *i ) == detected.end() ) - detected.push_back( *i ); - } - else - states[n] = false; - } - Common::SleepCurrentThread( 10 ); time += 10; - } - - delete states; - - if ( detected.size() == count ) - { - controls = detected; - - if ( controls.size() > 1 ) - { - control_qualifier.name = '|'; - std::vector::const_iterator c_i = controls.begin(), - c_e = controls.end(); - for ( ; c_i != c_e; ++c_i ) - control_qualifier.name += (*c_i)->GetName() + '|'; + // input was released at some point during Detect call + // return the detected input + if (false == *state) + return *i; } else - control_qualifier.FromControl( controls[0] ); - - return true; + *state = false; } + Common::SleepCurrentThread(10); time += 10; } - return false; + + delete[] states; + + // no input was detected + return NULL; } // @@ -543,22 +496,25 @@ bool ControllerInterface::InputReference::Detect( const unsigned int ms, const u // // set all binded outputs to power for x milliseconds return false // -bool ControllerInterface::OutputReference::Detect( const unsigned int ms, const unsigned int ignored ) +ControllerInterface::Device::Control* ControllerInterface::OutputReference::Detect(const unsigned int ms, Device* const device) { + // ignore device + // dont hang if we dont even have any controls mapped - if ( controls.size() ) + if (m_controls.size()) { - State( 1 ); + State(1); unsigned int slept = 0; + // this loop is to make stuff like flashing keyboard LEDs work - while ( ms > ( slept += 10 ) ) + while (ms > (slept += 10)) { device->UpdateOutput(); - Common::SleepCurrentThread( 10 ); + Common::SleepCurrentThread(10); } - State( 0 ); + State(0); device->UpdateOutput(); } - return false; + return NULL; } diff --git a/Source/Core/InputCommon/Src/ControllerInterface/ControllerInterface.h b/Source/Core/InputCommon/Src/ControllerInterface/ControllerInterface.h index 6f326b9b36..a474a9f071 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/ControllerInterface.h +++ b/Source/Core/InputCommon/Src/ControllerInterface/ControllerInterface.h @@ -12,8 +12,10 @@ #ifdef _WIN32 #define CIFACE_USE_XINPUT #define CIFACE_USE_DIRECTINPUT_JOYSTICK - #define CIFACE_USE_DIRECTINPUT_KBM + #define CIFACE_USE_DIRECTINPUT_KEYBOARD + #define CIFACE_USE_DIRECTINPUT_MOUSE #define CIFACE_USE_DIRECTINPUT + #define DINPUT_SOURCE_NAME "DInput" #endif #if defined(HAVE_X11) && HAVE_X11 #define CIFACE_USE_XLIB @@ -43,7 +45,7 @@ public: // // Device // - // Pretty obviously, a device class + // a device class // class Device { @@ -69,7 +71,8 @@ public: class Input : public Control { public: - virtual ~Input() {} + // things like absolute axes/ absolute mouse position will override this + virtual bool IsDetectable() { return true; } }; // @@ -89,7 +92,7 @@ public: virtual int GetId() const = 0; virtual std::string GetSource() const = 0; - virtual ControlState GetInputState( const Input* const input ) = 0; + virtual ControlState GetInputState( const Input* const input ) const = 0; virtual void SetOutputState( const Output* const output, const ControlState state ) = 0; virtual bool UpdateInput() = 0; @@ -97,12 +100,16 @@ public: virtual void ClearInputState(); - const std::vector< Input* >& Inputs(); - const std::vector< Output* >& Outputs(); + const std::vector& Inputs() const { return m_inputs; } + const std::vector& Outputs() const { return m_outputs; } protected: - std::vector inputs; - std::vector outputs; + void AddInput(Input* const i); + void AddOutput(Output* const o); + + private: + std::vector m_inputs; + std::vector m_outputs; }; @@ -115,95 +122,57 @@ public: class DeviceQualifier { public: - DeviceQualifier() : cid(-1){} - DeviceQualifier( const std::string& _source, const int _id, const std::string& _name ) + DeviceQualifier() : cid(-1) {} + DeviceQualifier(const std::string& _source, const int _id, const std::string& _name) : source(_source), cid(_id), name(_name) {} - bool operator==(const Device* const dev) const; void FromDevice(const Device* const dev); void FromString(const std::string& str); std::string ToString() const; + bool operator==(const DeviceQualifier& devq) const; std::string source; int cid; std::string name; }; - // - // ControlQualifier - // - // control qualifier includes input and output qualifiers - // used to match controls on devices, only has name property - // |input1|input2| form as well, || matches anything, might change this to * or something - // - class ControlQualifier - { - 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); - - std::string name; - }; - - // - // InputQualifier - // - // ControlQualifier for inputs - // - class InputQualifier : public ControlQualifier - { - public: - InputQualifier() {}; - InputQualifier( const std::string& _name ) : ControlQualifier(_name) {} - }; - - // - // OutputQualifier - // - // ControlQualifier for outputs - // - class OutputQualifier : public ControlQualifier - { - public: - OutputQualifier() {}; - OutputQualifier( const std::string& _name ) : ControlQualifier(_name) {} - }; - // // ControlReference // // these are what you create to actually use the inputs, InputReference or OutputReference - // they have a DeviceQualifier and ControlQualifier used to match 1 or more inputs // // after being binded to devices and controls with ControllerInterface::UpdateReference, - // each one can binded to a devices, and 0+ controls the device - // ControlReference can update its own controls when you change its control qualifier - // using ControlReference::UpdateControls but when you change its device qualifer - // you must use ControllerInterface::UpdateReference + // each one can link to multiple devices and controls + // when you change a ControlReference's expression, + // you must use ControllerInterface::UpdateReference on it to rebind controls // class ControlReference { + friend class ControllerInterface; + 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; - virtual void UpdateControls() = 0; + virtual ControlState State(const ControlState state = 0) = 0; + virtual Device::Control* Detect(const unsigned int ms, Device* const device) = 0; + size_t BoundCount() const { return m_controls.size(); } ControlState range; - - DeviceQualifier device_qualifier; - ControlQualifier control_qualifier; - + std::string expression; const bool is_input; - Device* device; - std::vector controls; + protected: + ControlReference(const bool _is_input) : range(1), is_input(_is_input) {} + struct DeviceControl + { + DeviceControl() : device(NULL), control(NULL), mode(0) {} + + Device* device; + Device::Control* control; + int mode; + }; + + std::vector m_controls; }; // @@ -214,12 +183,9 @@ public: class InputReference : public ControlReference { public: - InputReference() : ControlReference(true), mode(0) {} - ControlState State( const ControlState state ); - bool Detect( const unsigned int ms, const unsigned int count ); - void UpdateControls(); - - unsigned int mode; + InputReference() : ControlReference(true) {} + ControlState State(const ControlState state); + Device::Control* Detect(const unsigned int ms, Device* const device); }; // @@ -230,25 +196,24 @@ public: class OutputReference : public ControlReference { public: - OutputReference() : ControlReference( false ) {} - ControlState State( const ControlState state ); - bool Detect( const unsigned int ms, const unsigned int count ); - void UpdateControls(); + OutputReference() : ControlReference(false) {} + ControlState State(const ControlState state); + Device::Control* Detect(const unsigned int ms, Device* const device); }; ControllerInterface() : m_is_init(false) {} - void SetHwnd( void* const hwnd ); + void SetHwnd(void* const hwnd); void Init(); // TODO: remove this hack param void DeInit(const bool hacks_no_sdl_quit = false); - bool IsInit(); + bool IsInit() const { return m_is_init; } - void UpdateReference( ControlReference* control ); + void UpdateReference(ControlReference* control, const DeviceQualifier& default_device) const; bool UpdateInput(); bool UpdateOutput(); - const std::vector& Devices(); + const std::vector& Devices() const { return m_devices; } private: bool m_is_init; @@ -256,4 +221,8 @@ private: void* m_hwnd; }; +// used for std::find n stuff +bool operator==(const ControllerInterface::Device* const dev, const ControllerInterface::DeviceQualifier& devq); +bool operator==(const ControllerInterface::Device::Control* const c, const std::string& name); + #endif diff --git a/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInput.cpp b/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInput.cpp index b1f4bb067a..d36e76b3c1 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInput.cpp +++ b/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInput.cpp @@ -4,6 +4,18 @@ #include "DirectInput.h" +#include + +#ifdef CIFACE_USE_DIRECTINPUT_JOYSTICK + #include "DirectInputJoystick.h" +#endif +#ifdef CIFACE_USE_DIRECTINPUT_KEYBOARD + #include "DirectInputKeyboard.h" +#endif +#ifdef CIFACE_USE_DIRECTINPUT_MOUSE + #include "DirectInputMouse.h" +#endif + #pragma comment(lib, "Dinput8.lib") #pragma comment(lib, "dxguid.lib") @@ -12,17 +24,60 @@ namespace ciface namespace DirectInput { +//BOOL CALLBACK DIEnumEffectsCallback(LPCDIEFFECTINFO pdei, LPVOID pvRef) +//{ +// ((std::list*)pvRef)->push_back(*pdei); +// return DIENUM_CONTINUE; +//} + +BOOL CALLBACK DIEnumDeviceObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef) +{ + ((std::list*)pvRef)->push_back(*lpddoi); + return DIENUM_CONTINUE; +} + +BOOL CALLBACK DIEnumDevicesCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) +{ + ((std::list*)pvRef)->push_back(*lpddi); + return DIENUM_CONTINUE; +} + +std::string GetDeviceName(const LPDIRECTINPUTDEVICE8 device) +{ + std::string out; + + DIPROPSTRING str; + ZeroMemory(&str, sizeof(str)); + str.diph.dwSize = sizeof(str); + str.diph.dwHeaderSize = sizeof(str.diph); + str.diph.dwHow = DIPH_DEVICE; + + if (SUCCEEDED(device->GetProperty(DIPROP_PRODUCTNAME, &str.diph))) + { + const int size = WideCharToMultiByte(CP_ACP, 0, str.wsz, -1, NULL, 0, NULL, NULL); + char* const data = new char[size]; + if (size == WideCharToMultiByte(CP_ACP, 0, str.wsz, -1, data, size, NULL, NULL)) + out.assign(data); + delete[] data; + } + + return StripSpaces(out); +} + void Init( std::vector& devices/*, HWND hwnd*/ ) { IDirectInput8* idi8; if (FAILED(DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (LPVOID*)&idi8, NULL))) return; -#ifdef CIFACE_USE_DIRECTINPUT_KBM - InitKeyboardMouse( idi8, devices ); +#ifdef CIFACE_USE_DIRECTINPUT_KEYBOARD + InitKeyboard(idi8, devices); +#endif +#ifdef CIFACE_USE_DIRECTINPUT_MOUSE + InitMouse(idi8, devices); #endif #ifdef CIFACE_USE_DIRECTINPUT_JOYSTICK - InitJoystick( idi8, devices/*, hwnd*/ ); + InitJoystick(idi8, devices/*, hwnd*/); #endif idi8->Release(); diff --git a/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInput.h b/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInput.h index 7edbe3abf8..9f4a045a55 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInput.h +++ b/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInput.h @@ -9,18 +9,18 @@ #include #include -#ifdef CIFACE_USE_DIRECTINPUT_JOYSTICK - #include "DirectInputJoystick.h" -#endif -#ifdef CIFACE_USE_DIRECTINPUT_KBM - #include "DirectInputKeyboardMouse.h" -#endif +#include namespace ciface { namespace DirectInput { +//BOOL CALLBACK DIEnumEffectsCallback(LPCDIEFFECTINFO pdei, LPVOID pvRef); +BOOL CALLBACK DIEnumDeviceObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef); +BOOL CALLBACK DIEnumDevicesCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef); +std::string GetDeviceName(const LPDIRECTINPUTDEVICE8 device); + void Init( std::vector& devices/*, HWND hwnd*/ ); } diff --git a/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputJoystick.cpp b/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputJoystick.cpp index a0ef031639..0cd7459187 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputJoystick.cpp +++ b/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputJoystick.cpp @@ -3,7 +3,7 @@ #ifdef CIFACE_USE_DIRECTINPUT_JOYSTICK #include "DirectInputJoystick.h" -#include +#include "DirectInput.h" inline bool operator<(const GUID & lhs, const GUID & rhs) { @@ -123,41 +123,9 @@ LCleanup: } #endif -std::string TStringToString( const std::basic_string& in ) -{ - const int size = WideCharToMultiByte(CP_ACP, 0, in.data(), int(in.length()), NULL, 0, NULL, NULL); - - if ( 0 == size ) - return ""; - - char* const data = new char[size]; - WideCharToMultiByte(CP_ACP, 0, in.data(), int(in.length()), data, size, NULL, NULL); - const std::string out( data, size ); - delete[] data; - return out; -} - -//BOOL CALLBACK DIEnumEffectsCallback( LPCDIEFFECTINFO pdei, LPVOID pvRef ) -//{ -// ((std::vector*)pvRef)->push_back( *pdei ); -// return DIENUM_CONTINUE; -//} - -BOOL CALLBACK DIEnumDeviceObjectsCallback( LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef ) -{ - ((std::vector*)pvRef)->push_back( *lpddoi ); - return DIENUM_CONTINUE; -} - -BOOL CALLBACK DIEnumDevicesCallback( LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef ) -{ - ((std::vector*)pvRef)->push_back( *lpddi ); - return DIENUM_CONTINUE; -} - void InitJoystick( IDirectInput8* const idi8, std::vector& devices/*, HWND hwnd*/ ) { - std::vector joysticks; + std::list joysticks; idi8->EnumDevices( DI8DEVCLASS_GAMECTRL, DIEnumDevicesCallback, (LPVOID)&joysticks, DIEDFL_ATTACHEDONLY ); // this is used to number the joysticks @@ -169,7 +137,8 @@ void InitJoystick( IDirectInput8* const idi8, std::vector::iterator i = joysticks.begin(), + std::list::iterator + i = joysticks.begin(), e = joysticks.end(); for ( ; i!=e; ++i ) { @@ -247,17 +216,17 @@ Joystick::Joystick( /*const LPCDIDEVICEINSTANCE lpddi, */const LPDIRECTINPUTDEVI // buttons for ( unsigned int i = 0; i < js_caps.dwButtons; ++i ) - inputs.push_back( new Button( i ) ); + AddInput( new Button( i ) ); // hats for ( unsigned int i = 0; i < js_caps.dwPOVs; ++i ) { // each hat gets 4 input instances associated with it, (up down left right) for ( unsigned int d = 0; d<4; ++d ) - inputs.push_back( new Hat( i, d ) ); + AddInput( new Hat( i, d ) ); } // get up to 6 axes and 2 sliders - std::vector axes; - m_device->EnumObjects( DIEnumDeviceObjectsCallback, (LPVOID)&axes, DIDFT_ABSAXIS ); + std::list axes; + m_device->EnumObjects(DIEnumDeviceObjectsCallback, (LPVOID)&axes, DIDFT_ABSAXIS); unsigned int cur_slider = 0; @@ -271,7 +240,8 @@ Joystick::Joystick( /*const LPCDIDEVICEINSTANCE lpddi, */const LPDIRECTINPUTDEVI types[GUID_RzAxis] = 5; // going in reverse leaves the list more organized in the end for me :/ - std::vector::const_reverse_iterator i = axes.rbegin(), + std::list::const_reverse_iterator + i = axes.rbegin(), e = axes.rend(); for( ; i!=e; ++i ) { @@ -287,7 +257,7 @@ Joystick::Joystick( /*const LPCDIDEVICEINSTANCE lpddi, */const LPDIRECTINPUTDEVI // but i guess not all devices support setting range m_device->SetProperty( DIPROP_RANGE, &range.diph ); // so i getproperty right afterward incase it didn't set :P - if (SUCCEEDED(m_device->GetProperty( DIPROP_RANGE, &range.diph))) + if (SUCCEEDED(m_device->GetProperty(DIPROP_RANGE, &range.diph))) { int offset = -1; @@ -314,15 +284,15 @@ Joystick::Joystick( /*const LPCDIDEVICEINSTANCE lpddi, */const LPDIRECTINPUTDEVI { const LONG base = (range.lMin + range.lMax) / 2; // each axis gets a negative and a positive input instance associated with it - inputs.push_back( new Axis( offset, base, range.lMin-base ) ); - inputs.push_back( new Axis( offset, base, range.lMax-base ) ); + AddInput( new Axis( offset, base, range.lMin-base ) ); + AddInput( new Axis( offset, base, range.lMax-base ) ); } } } // get supported ff effects - std::vector objects; - m_device->EnumObjects( DIEnumDeviceObjectsCallback, (LPVOID)&objects, DIDFT_AXIS ); + std::list objects; + m_device->EnumObjects(DIEnumDeviceObjectsCallback, (LPVOID)&objects, DIDFT_AXIS); // got some ff axes or something if ( objects.size() ) { @@ -347,13 +317,13 @@ Joystick::Joystick( /*const LPCDIDEVICEINSTANCE lpddi, */const LPDIRECTINPUTDEVI if (SUCCEEDED(m_device->CreateEffect(GUID_ConstantForce, &eff, &pEffect, NULL))) { // temp - outputs.push_back( new Force( 0 ) ); + AddOutput( new Force( 0 ) ); m_state_out.push_back( EffectState( pEffect ) ); } } // disable autocentering - if ( outputs.size() ) + if ( Outputs().size() ) { DIPROPDWORD dipdw; dipdw.diph.dwSize = sizeof( DIPROPDWORD ); @@ -392,14 +362,7 @@ void Joystick::ClearInputState() std::string Joystick::GetName() const { - DIPROPSTRING str; - ZeroMemory( &str, sizeof(str) ); - str.diph.dwSize = sizeof(str); - str.diph.dwHeaderSize = sizeof(str.diph); - str.diph.dwHow = DIPH_DEVICE; - m_device->GetProperty( DIPROP_PRODUCTNAME, &str.diph ); - return StripSpaces(TStringToString(str.wsz)); - //return m_name; + return GetDeviceName(m_device); } int Joystick::GetId() const @@ -409,7 +372,7 @@ int Joystick::GetId() const std::string Joystick::GetSource() const { - return "DirectInput"; + return DINPUT_SOURCE_NAME; } // update IO @@ -428,6 +391,9 @@ bool Joystick::UpdateInput() DIDEVICEOBJECTDATA evtbuf[DATA_BUFFER_SIZE]; DWORD numevents; + //DWORD wantevents = INFINITE; + //hr = m_device->GetDeviceData(sizeof(*evtbuf), NULL, &wantevents, DIGDD_PEEK); + GETDEVDATA : numevents = DATA_BUFFER_SIZE; hr = m_device->GetDeviceData(sizeof(*evtbuf), evtbuf, &numevents, 0); @@ -445,6 +411,9 @@ GETDEVDATA : } // if there is more data to be received + // it seems like to me this could cause problems, + // if the device was producing so many events that GetDeviceData always returned bufferoverflow + // it seems to be working fine tho if (DI_BUFFEROVERFLOW == hr) goto GETDEVDATA; } @@ -534,7 +503,7 @@ std::string Joystick::Force::GetName() const // get / set state -ControlState Joystick::GetInputState( const ControllerInterface::Device::Input* const input ) +ControlState Joystick::GetInputState( const ControllerInterface::Device::Input* const input ) const { return ((Input*)input)->GetState( &m_state_in ); } @@ -546,17 +515,17 @@ void Joystick::SetOutputState( const ControllerInterface::Device::Output* const // get / set state -ControlState Joystick::Axis::GetState( const DIJOYSTATE* const joystate ) +ControlState Joystick::Axis::GetState( const DIJOYSTATE* const joystate ) const { return std::max( 0.0f, ControlState((&joystate->lX)[m_index]-m_base) / m_range ); } -ControlState Joystick::Button::GetState( const DIJOYSTATE* const joystate ) +ControlState Joystick::Button::GetState( const DIJOYSTATE* const joystate ) const { return ControlState( joystate->rgbButtons[m_index] > 0 ); } -ControlState Joystick::Hat::GetState( const DIJOYSTATE* const joystate ) +ControlState Joystick::Hat::GetState( const DIJOYSTATE* const joystate ) const { // can this func be simplified ? const DWORD val = joystate->rgdwPOV[m_index]; diff --git a/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputJoystick.h b/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputJoystick.h index a42a7cb4a9..bdee377f72 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputJoystick.h +++ b/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputJoystick.h @@ -42,7 +42,7 @@ protected: { friend class Joystick; protected: - virtual ControlState GetState( const DIJOYSTATE* const joystate ) = 0; + virtual ControlState GetState( const DIJOYSTATE* const joystate ) const = 0; }; // can probably eliminate this base class @@ -60,7 +60,7 @@ protected: std::string GetName() const; protected: Button( const unsigned int index ) : m_index(index) {} - ControlState GetState( const DIJOYSTATE* const joystate ); + ControlState GetState( const DIJOYSTATE* const joystate ) const; private: const unsigned int m_index; }; @@ -72,7 +72,7 @@ protected: std::string GetName() const; protected: Axis( const unsigned int index, const LONG base, const LONG range ) : m_index(index), m_base(base), m_range(range) {} - ControlState GetState( const DIJOYSTATE* const joystate ); + ControlState GetState( const DIJOYSTATE* const joystate ) const; private: const unsigned int m_index; const LONG m_base; @@ -86,7 +86,7 @@ protected: std::string GetName() const; protected: Hat( const unsigned int index, const unsigned int direction ) : m_index(index), m_direction(direction) {} - ControlState GetState( const DIJOYSTATE* const joystate ); + ControlState GetState( const DIJOYSTATE* const joystate ) const; private: const unsigned int m_index; const unsigned int m_direction; @@ -107,7 +107,7 @@ protected: bool UpdateInput(); bool UpdateOutput(); - ControlState GetInputState( const ControllerInterface::Device::Input* const input ); + ControlState GetInputState( const ControllerInterface::Device::Input* const input ) const; void SetOutputState( const ControllerInterface::Device::Output* const input, const ControlState state ); void ClearInputState(); diff --git a/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputKeyboard.cpp b/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputKeyboard.cpp new file mode 100644 index 0000000000..6f39467deb --- /dev/null +++ b/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputKeyboard.cpp @@ -0,0 +1,187 @@ +#include "../ControllerInterface.h" + +#ifdef CIFACE_USE_DIRECTINPUT_KEYBOARD + +#include "DirectInputKeyboard.h" +#include "DirectInput.h" + +// TODO: maybe add a ClearInputState function to this device + +namespace ciface +{ +namespace DirectInput +{ + +struct +{ + const BYTE code; + const char* const name; +} named_keys[] = +{ +#include "NamedKeys.h" +}; + +struct +{ + const BYTE code; + const char* const name; +} named_lights[] = +{ + { VK_NUMLOCK, "NUM LOCK" }, + { VK_CAPITAL, "CAPS LOCK" }, + { VK_SCROLL, "SCROLL LOCK" } +}; + +void InitKeyboard(IDirectInput8* const idi8, std::vector& devices) +{ + LPDIRECTINPUTDEVICE8 kb_device; + + unsigned int kb_count = 0; + + std::list keyboards; + idi8->EnumDevices(DI8DEVCLASS_KEYBOARD, DIEnumDevicesCallback, (LPVOID)&keyboards, DIEDFL_ATTACHEDONLY); + + // add other keyboard devices + std::list::iterator + i = keyboards.begin(), + e = keyboards.end(); + for (; i!=e; ++i) + { + if (SUCCEEDED(idi8->CreateDevice(i->guidInstance, &kb_device, NULL))) + { + if (SUCCEEDED(kb_device->SetDataFormat(&c_dfDIKeyboard))) + if (SUCCEEDED(kb_device->SetCooperativeLevel(NULL, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE))) + { + devices.push_back(new Keyboard(kb_device, kb_count++)); + return; + } + } + kb_device->Release(); + } +} + +Keyboard::~Keyboard() +{ + // kb + m_kb_device->Unacquire(); + m_kb_device->Release(); + +} + +Keyboard::Keyboard(const LPDIRECTINPUTDEVICE8 kb_device, const int index) + : m_kb_device(kb_device) + , m_index(index) +{ + m_kb_device->Acquire(); + + ZeroMemory(&m_state_in, sizeof(m_state_in)); + ZeroMemory(m_state_out, sizeof(m_state_out)); + ZeroMemory(&m_current_state_out, sizeof(m_current_state_out)); + + // KEYBOARD + // add keys + for (unsigned int i = 0; i < sizeof(named_keys)/sizeof(*named_keys); ++i) + AddInput(new Key(i)); + // add lights + for (unsigned int i = 0; i < sizeof(named_lights)/sizeof(*named_lights); ++i) + AddOutput(new Light(i)); +} + +bool Keyboard::UpdateInput() +{ + HRESULT hr = m_kb_device->GetDeviceState(sizeof(m_state_in), m_state_in); + + if (DIERR_INPUTLOST == hr || DIERR_NOTACQUIRED == hr) + m_kb_device->Acquire(); + + return SUCCEEDED(hr); +} + +bool Keyboard::UpdateOutput() +{ + class KInput : public INPUT + { + public: + KInput( const unsigned char key, const bool up = false ) + { + memset( this, 0, sizeof(*this) ); + type = INPUT_KEYBOARD; + ki.wVk = key; + if (up) ki.dwFlags = KEYEVENTF_KEYUP; + } + }; + + std::vector< KInput > kbinputs; + for ( unsigned int i = 0; i < sizeof(m_state_out)/sizeof(*m_state_out); ++i ) + { + bool want_on = false; + if ( m_state_out[i] ) + want_on = m_state_out[i] > wxGetLocalTimeMillis() % 255 ; // light should flash when output is 0.5 + + // lights are set to their original state when output is zero + if ( want_on ^ m_current_state_out[i] ) + { + kbinputs.push_back( KInput( named_lights[i].code ) ); // press + kbinputs.push_back( KInput( named_lights[i].code, true ) ); // release + + m_current_state_out[i] ^= 1; + } + } + + if (kbinputs.size()) + return ( kbinputs.size() == SendInput( (UINT)kbinputs.size(), &kbinputs[0], sizeof( kbinputs[0] ) ) ); + else + return true; +} + +std::string Keyboard::GetName() const +{ + return "Keyboard"; +} + +int Keyboard::GetId() const +{ + return m_index; +} + +std::string Keyboard::GetSource() const +{ + return DINPUT_SOURCE_NAME; +} + +ControlState Keyboard::GetInputState(const ControllerInterface::Device::Input* const input) const +{ + return (((Input*)input)->GetState(m_state_in)); +} + +void Keyboard::SetOutputState(const ControllerInterface::Device::Output* const output, const ControlState state) +{ + ((Output*)output)->SetState(state, m_state_out); +} + +// names +std::string Keyboard::Key::GetName() const +{ + return named_keys[m_index].name; +} + +std::string Keyboard::Light::GetName() const +{ + return named_lights[ m_index ].name; +} + +// get/set state +ControlState Keyboard::Key::GetState(const BYTE keys[]) const +{ + return (keys[named_keys[m_index].code] != 0); +} + +void Keyboard::Light::SetState( const ControlState state, unsigned char* const state_out ) +{ + state_out[m_index] = state * 255; +} + +} +} + +#endif diff --git a/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputKeyboard.h b/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputKeyboard.h new file mode 100644 index 0000000000..b51a38faa4 --- /dev/null +++ b/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputKeyboard.h @@ -0,0 +1,99 @@ +#ifndef _CIFACE_DIRECTINPUT_KEYBOARD_H_ +#define _CIFACE_DIRECTINPUT_KEYBOARD_H_ + +#include "../ControllerInterface.h" + +#define DIRECTINPUT_VERSION 0x0800 +#define WIN32_LEAN_AND_MEAN +#define NOMINMAX +#include +#include + +#include +#include + +namespace ciface +{ +namespace DirectInput +{ + +void InitKeyboard(IDirectInput8* const idi8, std::vector& devices); + +class Keyboard : public ControllerInterface::Device +{ + friend class ControllerInterface; + friend class ControllerInterface::ControlReference; + +protected: + + struct State + { + + }; + + class Input : public ControllerInterface::Device::Input + { + friend class Keyboard; + protected: + virtual ControlState GetState(const BYTE keys[]) const = 0; + }; + + class Output : public ControllerInterface::Device::Output + { + friend class Keyboard; + protected: + virtual void SetState(const ControlState state, unsigned char* const state_out) = 0; + }; + + class Key : public Input + { + friend class Keyboard; + public: + std::string GetName() const; + protected: + Key(const unsigned int index) : m_index(index) {} + ControlState GetState(const BYTE keys[]) const; + private: + const unsigned int m_index; + }; + + class Light : public Output + { + friend class Keyboard; + public: + std::string GetName() const; + protected: + Light(const unsigned int index) : m_index(index) {} + void SetState(const ControlState state, unsigned char* const state_out); + private: + const unsigned int m_index; + }; + + bool UpdateInput(); + bool UpdateOutput(); + + ControlState GetInputState( const ControllerInterface::Device::Input* const input ) const; + void SetOutputState( const ControllerInterface::Device::Output* const input, const ControlState state ); + +public: + Keyboard(const LPDIRECTINPUTDEVICE8 kb_device, const int index); + ~Keyboard(); + + std::string GetName() const; + int GetId() const; + std::string GetSource() const; + +private: + const LPDIRECTINPUTDEVICE8 m_kb_device; + const int m_index; + + wxLongLong m_last_update; + BYTE m_state_in[256]; + unsigned char m_state_out[3]; // NUM CAPS SCROLL + bool m_current_state_out[3]; // NUM CAPS SCROLL +}; + +} +} + +#endif diff --git a/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputKeyboardMouse.cpp b/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputKeyboardMouse.cpp deleted file mode 100644 index 76ac358d7c..0000000000 --- a/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputKeyboardMouse.cpp +++ /dev/null @@ -1,274 +0,0 @@ -#include "../ControllerInterface.h" - -#ifdef CIFACE_USE_DIRECTINPUT_KBM - -#include "DirectInputKeyboardMouse.h" - -// TODO: maybe add a ClearInputState function to this device - - // (lower would be more sensitive) user can lower sensitivity by setting range - // seems decent here ( at 8 ), I dont think anyone would need more sensitive than this - // and user can lower it much farther than they would want to with the range -#define MOUSE_AXIS_SENSITIVITY 8 - - // if input hasn't been received for this many ms, mouse input will be skipped - // otherwise it is just some crazy value -#define DROP_INPUT_TIME 250 - -namespace ciface -{ -namespace DirectInput -{ - -struct -{ - const BYTE code; - const char* const name; -} named_keys[] = -{ -#include "NamedKeys.h" -}; - -struct -{ - const BYTE code; - const char* const name; -} named_lights[] = -{ - { VK_NUMLOCK, "NUM LOCK" }, - { VK_CAPITAL, "CAPS LOCK" }, - { VK_SCROLL, "SCROLL LOCK" } -}; - -void InitKeyboardMouse( IDirectInput8* const idi8, std::vector& devices ) -{ - // mouse and keyboard are a combined device, to allow shift+click and stuff - // if thats dumb, i will make a VirtualDevice class that just uses ranges of inputs/outputs from other devices - // so there can be a separated Keyboard and mouse, as well as combined KeyboardMouse - - LPDIRECTINPUTDEVICE8 kb_device = NULL; - LPDIRECTINPUTDEVICE8 mo_device = NULL; - - if (SUCCEEDED(idi8->CreateDevice( GUID_SysKeyboard, &kb_device, NULL))) - { - if (SUCCEEDED(kb_device->SetDataFormat(&c_dfDIKeyboard))) - if (SUCCEEDED(kb_device->SetCooperativeLevel(NULL, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE))) - { - if (SUCCEEDED(idi8->CreateDevice( GUID_SysMouse, &mo_device, NULL ))) - { - if (SUCCEEDED(mo_device->SetDataFormat(&c_dfDIMouse2))) - if (SUCCEEDED(mo_device->SetCooperativeLevel(NULL, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE))) - { - devices.push_back(new KeyboardMouse(kb_device, mo_device)); - return; - } - } - } - } - - if (kb_device) - kb_device->Release(); - if (mo_device) - mo_device->Release(); -} - -KeyboardMouse::~KeyboardMouse() -{ - // kb - m_kb_device->Unacquire(); - m_kb_device->Release(); - // mouse - m_mo_device->Unacquire(); - m_mo_device->Release(); -} - -KeyboardMouse::KeyboardMouse( const LPDIRECTINPUTDEVICE8 kb_device, const LPDIRECTINPUTDEVICE8 mo_device ) - : m_kb_device(kb_device) - , m_mo_device(mo_device) -{ - m_kb_device->Acquire(); - m_mo_device->Acquire(); - - m_last_update = wxGetLocalTimeMillis(); - - ZeroMemory( &m_state_in, sizeof(m_state_in) ); - ZeroMemory( m_state_out, sizeof(m_state_out) ); - ZeroMemory( &m_current_state_out, sizeof(m_current_state_out) ); - - // KEYBOARD - // add keys - for ( unsigned int i = 0; i < sizeof(named_keys)/sizeof(*named_keys); ++i ) - inputs.push_back( new Key( i ) ); - // add lights - for ( unsigned int i = 0; i < sizeof(named_lights)/sizeof(*named_lights); ++i ) - outputs.push_back( new Light( i ) ); - - // MOUSE - // get caps - DIDEVCAPS mouse_caps; - ZeroMemory( &mouse_caps, sizeof(mouse_caps) ); - mouse_caps.dwSize = sizeof(mouse_caps); - m_mo_device->GetCapabilities(&mouse_caps); - // mouse buttons - for ( unsigned int i = 0; i < mouse_caps.dwButtons; ++i ) - inputs.push_back( new Button( i ) ); - // mouse axes - for ( unsigned int i = 0; i < mouse_caps.dwAxes; ++i ) - { - // each axis gets a negative and a positive input instance associated with it - inputs.push_back( new Axis( i, (2==i) ? -1 : -MOUSE_AXIS_SENSITIVITY ) ); - inputs.push_back( new Axis( i, -(2==i) ? 1 : MOUSE_AXIS_SENSITIVITY ) ); - } - -} - -bool KeyboardMouse::UpdateInput() -{ - DIMOUSESTATE2 tmp_mouse; - - // if mouse position hasn't been updated in a short while, skip a dev state - wxLongLong cur_time = wxGetLocalTimeMillis(); - if ( cur_time - m_last_update > DROP_INPUT_TIME ) - { - // set axes to zero - ZeroMemory( &m_state_in.mouse, sizeof(m_state_in.mouse) ); - // skip this input state - m_mo_device->GetDeviceState( sizeof(tmp_mouse), &tmp_mouse ); - } - - m_last_update = cur_time; - - HRESULT kb_hr = m_kb_device->GetDeviceState(sizeof(m_state_in.keyboard), &m_state_in.keyboard); - HRESULT mo_hr = m_mo_device->GetDeviceState(sizeof(tmp_mouse), &tmp_mouse); - - if (DIERR_INPUTLOST == kb_hr || DIERR_NOTACQUIRED == kb_hr) - m_kb_device->Acquire(); - - if (DIERR_INPUTLOST == mo_hr || DIERR_NOTACQUIRED == mo_hr) - m_mo_device->Acquire(); - - if (SUCCEEDED(kb_hr) && SUCCEEDED(mo_hr)) - { - // need to smooth out the axes, otherwise it doesnt work for shit - for ( unsigned int i = 0; i < 3; ++i ) - ((&m_state_in.mouse.lX)[i] += (&tmp_mouse.lX)[i]) /= 2; - - // copy over the buttons - memcpy( m_state_in.mouse.rgbButtons, tmp_mouse.rgbButtons, sizeof(m_state_in.mouse.rgbButtons) ); - return true; - } - - return false; -} - -bool KeyboardMouse::UpdateOutput() -{ - class KInput : public INPUT - { - public: - KInput( const unsigned char key, const bool up = false ) - { - memset( this, 0, sizeof(*this) ); - type = INPUT_KEYBOARD; - ki.wVk = key; - if (up) ki.dwFlags = KEYEVENTF_KEYUP; - } - }; - - std::vector< KInput > kbinputs; - for ( unsigned int i = 0; i < sizeof(m_state_out)/sizeof(*m_state_out); ++i ) - { - bool want_on = false; - if ( m_state_out[i] ) - want_on = m_state_out[i] > wxGetLocalTimeMillis() % 255 ; // light should flash when output is 0.5 - - // lights are set to their original state when output is zero - if ( want_on ^ m_current_state_out[i] ) - { - kbinputs.push_back( KInput( named_lights[i].code ) ); // press - kbinputs.push_back( KInput( named_lights[i].code, true ) ); // release - - m_current_state_out[i] ^= 1; - } - } - - if (kbinputs.size()) - return ( kbinputs.size() == SendInput( (UINT)kbinputs.size(), &kbinputs[0], sizeof( kbinputs[0] ) ) ); - else - return true; -} - -std::string KeyboardMouse::GetName() const -{ - return "Keyboard Mouse"; -} - -int KeyboardMouse::GetId() const -{ - // should this be -1, idk - return 0; -} - -std::string KeyboardMouse::GetSource() const -{ - return "DirectInput"; -} - -ControlState KeyboardMouse::GetInputState( const ControllerInterface::Device::Input* const input ) -{ - return ( ((Input*)input)->GetState( &m_state_in ) ); -} - -void KeyboardMouse::SetOutputState( const ControllerInterface::Device::Output* const output, const ControlState state ) -{ - ((Output*)output)->SetState( state, m_state_out ); -} - -// names -std::string KeyboardMouse::Key::GetName() const -{ - return named_keys[m_index].name; -} - -std::string KeyboardMouse::Button::GetName() const -{ - return std::string("Button ") + char('0'+m_index); -} - -std::string KeyboardMouse::Axis::GetName() const -{ - std::string tmpstr("Mouse "); - tmpstr += "XYZ"[m_index]; tmpstr += ( m_range>0 ? '+' : '-' ); - return tmpstr; -} - -std::string KeyboardMouse::Light::GetName() const -{ - return named_lights[ m_index ].name; -} - -// get/set state -ControlState KeyboardMouse::Key::GetState( const State* const state ) -{ - return ( state->keyboard[named_keys[m_index].code] > 0 ); -} - -ControlState KeyboardMouse::Button::GetState( const State* const state ) -{ - return ( state->mouse.rgbButtons[m_index] > 0 ); -} - -ControlState KeyboardMouse::Axis::GetState( const State* const state ) -{ - return std::max( 0.0f, ControlState((&state->mouse.lX)[m_index]) / m_range ); -} - -void KeyboardMouse::Light::SetState( const ControlState state, unsigned char* const state_out ) -{ - state_out[ m_index ] = state * 255; -} - -} -} - -#endif diff --git a/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputKeyboardMouse.h b/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputKeyboardMouse.h deleted file mode 100644 index 6af5fb10d0..0000000000 --- a/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputKeyboardMouse.h +++ /dev/null @@ -1,125 +0,0 @@ -#ifndef _CIFACE_DIRECTINPUT_KBM_H_ -#define _CIFACE_DIRECTINPUT_KBM_H_ - -#include "../ControllerInterface.h" - -#define DIRECTINPUT_VERSION 0x0800 -#define WIN32_LEAN_AND_MEAN -#define NOMINMAX -#include -#include - -#include -#include - -namespace ciface -{ -namespace DirectInput -{ - -void InitKeyboardMouse( IDirectInput8* const idi8, std::vector& devices ); - -class KeyboardMouse : public ControllerInterface::Device -{ - friend class ControllerInterface; - friend class ControllerInterface::ControlReference; - -protected: - - struct State - { - BYTE keyboard[256]; - DIMOUSESTATE2 mouse; - }; - - class Input : public ControllerInterface::Device::Input - { - friend class KeyboardMouse; - protected: - virtual ControlState GetState( const State* const boardstate ) = 0; - }; - - class Output : public ControllerInterface::Device::Output - { - friend class KeyboardMouse; - protected: - virtual void SetState( const ControlState state, unsigned char* const state_out ) = 0; - }; - - class Key : public Input - { - friend class KeyboardMouse; - public: - std::string GetName() const; - protected: - Key( const unsigned int index ) : m_index(index) {} - ControlState GetState( const State* const state ); - private: - const unsigned int m_index; - }; - - class Button : public Input - { - friend class KeyboardMouse; - public: - std::string GetName() const; - protected: - Button( const unsigned int index ) : m_index(index) {} - ControlState GetState( const State* const state ); - private: - const unsigned int m_index; - }; - - class Axis : public Input - { - friend class KeyboardMouse; - public: - std::string GetName() const; - protected: - Axis( const unsigned int index, const LONG range ) : m_index(index), m_range(range) {} - ControlState GetState( const State* const state ); - private: - const unsigned int m_index; - const LONG m_range; - }; - - class Light : public Output - { - friend class KeyboardMouse; - public: - std::string GetName() const; - protected: - Light( const unsigned int index ) : m_index(index) {} - void SetState( const ControlState state, unsigned char* const state_out ); - private: - const unsigned int m_index; - }; - - bool UpdateInput(); - bool UpdateOutput(); - - ControlState GetInputState( const ControllerInterface::Device::Input* const input ); - void SetOutputState( const ControllerInterface::Device::Output* const input, const ControlState state ); - -public: - KeyboardMouse( const LPDIRECTINPUTDEVICE8 kb_device, const LPDIRECTINPUTDEVICE8 mo_device ); - ~KeyboardMouse(); - - std::string GetName() const; - int GetId() const; - std::string GetSource() const; - -private: - const LPDIRECTINPUTDEVICE8 m_kb_device; - const LPDIRECTINPUTDEVICE8 m_mo_device; - - wxLongLong m_last_update; - State m_state_in; - unsigned char m_state_out[3]; // NUM CAPS SCROLL - bool m_current_state_out[3]; // NUM CAPS SCROLL -}; - -} -} - -#endif diff --git a/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputMouse.cpp b/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputMouse.cpp new file mode 100644 index 0000000000..122582bf4f --- /dev/null +++ b/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputMouse.cpp @@ -0,0 +1,175 @@ +#include "../ControllerInterface.h" + +#ifdef CIFACE_USE_DIRECTINPUT_MOUSE + +#include "DirectInputMouse.h" +#include "DirectInput.h" + +// TODO: maybe add a ClearInputState function to this device + + // (lower would be more sensitive) user can lower sensitivity by setting range + // seems decent here ( at 8 ), I dont think anyone would need more sensitive than this + // and user can lower it much farther than they would want to with the range +#define MOUSE_AXIS_SENSITIVITY 8 + + // if input hasn't been received for this many ms, mouse input will be skipped + // otherwise it is just some crazy value +#define DROP_INPUT_TIME 250 + +namespace ciface +{ +namespace DirectInput +{ + +void InitMouse( IDirectInput8* const idi8, std::vector& devices ) +{ + LPDIRECTINPUTDEVICE8 mo_device; + + unsigned int mo_count = 0; + + std::list mice; + idi8->EnumDevices(DI8DEVCLASS_POINTER, DIEnumDevicesCallback, (LPVOID)&mice, DIEDFL_ATTACHEDONLY); + + // add other keyboard devices + std::list::iterator + i = mice.begin(), + e = mice.end(); + for (; i!=e; ++i) + { + if (SUCCEEDED(idi8->CreateDevice(i->guidInstance, &mo_device, NULL))) + { + if (SUCCEEDED(mo_device->SetDataFormat(&c_dfDIMouse2))) + if (SUCCEEDED(mo_device->SetCooperativeLevel(NULL, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE))) + { + devices.push_back(new Mouse(mo_device, mo_count++)); + return; + } + } + mo_device->Release(); + } +} + +Mouse::~Mouse() +{ + // mouse + m_mo_device->Unacquire(); + m_mo_device->Release(); +} + +Mouse::Mouse(const LPDIRECTINPUTDEVICE8 mo_device, const int index) + : m_mo_device(mo_device) + , m_index(index) +{ + m_mo_device->Acquire(); + + m_last_update = GetTickCount(); + ZeroMemory(&m_state_in, sizeof(m_state_in)); + + // MOUSE + // get caps + DIDEVCAPS mouse_caps; + ZeroMemory( &mouse_caps, sizeof(mouse_caps) ); + mouse_caps.dwSize = sizeof(mouse_caps); + m_mo_device->GetCapabilities(&mouse_caps); + // mouse buttons + for (unsigned int i = 0; i < mouse_caps.dwButtons; ++i) + AddInput(new Button(i)); + // mouse axes + for (unsigned int i = 0; i < mouse_caps.dwAxes; ++i) + { + // each axis gets a negative and a positive input instance associated with it + AddInput(new Axis(i, (2==i) ? -1 : -MOUSE_AXIS_SENSITIVITY)); + AddInput(new Axis(i, -(2==i) ? 1 : MOUSE_AXIS_SENSITIVITY)); + } + +} + +bool Mouse::UpdateInput() +{ + DIMOUSESTATE2 tmp_mouse; + HRESULT hr = m_mo_device->GetDeviceState(sizeof(tmp_mouse), &tmp_mouse); + + // if mouse position hasn't been updated in a short while, skip a dev state + const DWORD cur_time = GetTickCount(); + if (cur_time - m_last_update > DROP_INPUT_TIME) + { + // set buttons/axes to zero + // skip this input state + ZeroMemory(&m_state_in, sizeof(m_state_in)); + } + else if (SUCCEEDED(hr)) + { + // need to smooth out the axes, otherwise it doesnt work for shit + for (unsigned int i = 0; i < 3; ++i) + ((&m_state_in.lX)[i] += (&tmp_mouse.lX)[i]) /= 2; + + // copy over the buttons + memcpy(m_state_in.rgbButtons, tmp_mouse.rgbButtons, sizeof(m_state_in.rgbButtons)); + } + + m_last_update = cur_time; + + if (DIERR_INPUTLOST == hr || DIERR_NOTACQUIRED == hr) + m_mo_device->Acquire(); + + return SUCCEEDED(hr); +} + +bool Mouse::UpdateOutput() +{ + return true; +} + +std::string Mouse::GetName() const +{ + return "Mouse"; +} + +int Mouse::GetId() const +{ + return m_index; +} + +std::string Mouse::GetSource() const +{ + return DINPUT_SOURCE_NAME; +} + +ControlState Mouse::GetInputState( const ControllerInterface::Device::Input* const input ) const +{ + return (((Input*)input)->GetState(&m_state_in)); +} + +void Mouse::SetOutputState(const ControllerInterface::Device::Output* const output, const ControlState state) +{ + return; +} + +// names +std::string Mouse::Button::GetName() const +{ + return std::string("Button ") + char('0'+m_index); +} + +std::string Mouse::Axis::GetName() const +{ + std::string tmpstr("Mouse "); + tmpstr += "XYZ"[m_index]; tmpstr += ( m_range>0 ? '+' : '-' ); + return tmpstr; +} + +// get/set state +ControlState Mouse::Button::GetState(const DIMOUSESTATE2* const state) const +{ + return (state->rgbButtons[m_index] != 0); +} + +ControlState Mouse::Axis::GetState(const DIMOUSESTATE2* const state) const +{ + return std::max(0.0f, ControlState((&state->lX)[m_index]) / m_range); +} + +} +} + +#endif diff --git a/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputMouse.h b/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputMouse.h new file mode 100644 index 0000000000..c645d02727 --- /dev/null +++ b/Source/Core/InputCommon/Src/ControllerInterface/DirectInput/DirectInputMouse.h @@ -0,0 +1,83 @@ +#ifndef _CIFACE_DIRECTINPUT_MOUSE_H_ +#define _CIFACE_DIRECTINPUT_MOUSE_H_ + +#include "../ControllerInterface.h" + +#define DIRECTINPUT_VERSION 0x0800 +#define WIN32_LEAN_AND_MEAN +#define NOMINMAX +#include +#include + +namespace ciface +{ +namespace DirectInput +{ + +void InitMouse(IDirectInput8* const idi8, std::vector& devices); + +class Mouse : public ControllerInterface::Device +{ + friend class ControllerInterface; + friend class ControllerInterface::ControlReference; + +protected: + + class Input : public ControllerInterface::Device::Input + { + friend class Mouse; + protected: + virtual ControlState GetState(const DIMOUSESTATE2* const boardstate) const = 0; + }; + + class Button : public Input + { + friend class Mouse; + public: + std::string GetName() const; + protected: + Button(const unsigned int index) : m_index(index) {} + ControlState GetState(const DIMOUSESTATE2* const state) const; + private: + const unsigned int m_index; + }; + + class Axis : public Input + { + friend class Mouse; + public: + std::string GetName() const; + protected: + Axis(const unsigned int index, const LONG range) : m_index(index), m_range(range) {} + ControlState GetState(const DIMOUSESTATE2* const state) const; + private: + const unsigned int m_index; + const LONG m_range; + }; + + bool UpdateInput(); + bool UpdateOutput(); + + ControlState GetInputState( const ControllerInterface::Device::Input* const input ) const; + void SetOutputState( const ControllerInterface::Device::Output* const input, const ControlState state ); + +public: + Mouse(const LPDIRECTINPUTDEVICE8 mo_device, const int index); + ~Mouse(); + + std::string GetName() const; + int GetId() const; + std::string GetSource() const; + +private: + const LPDIRECTINPUTDEVICE8 m_mo_device; + const int m_index; + + DWORD m_last_update; + DIMOUSESTATE2 m_state_in; +}; + +} +} + +#endif diff --git a/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXKeyboard.h b/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXKeyboard.h index 84ab9ae810..22dcdc7b0c 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXKeyboard.h +++ b/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXKeyboard.h @@ -19,7 +19,7 @@ protected: { friend class Keyboard; protected: - virtual ControlState GetState(IOHIDDeviceRef device) = 0; + virtual ControlState GetState(IOHIDDeviceRef device) const = 0; }; class Key : public Input @@ -29,7 +29,7 @@ protected: std::string GetName() const; protected: Key( IOHIDElementRef element ); - ControlState GetState(IOHIDDeviceRef device); + ControlState GetState(IOHIDDeviceRef device) const; private: IOHIDElementRef m_element; std::string m_name; @@ -38,7 +38,7 @@ protected: bool UpdateInput(); bool UpdateOutput(); - ControlState GetInputState( const ControllerInterface::Device::Input* const input ); + ControlState GetInputState( const ControllerInterface::Device::Input* const input ) const; void SetOutputState( const ControllerInterface::Device::Output* const output, const ControlState state ); public: diff --git a/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXKeyboard.mm b/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXKeyboard.mm index 1f4b3fc499..eabcf9e5e6 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXKeyboard.mm +++ b/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXKeyboard.mm @@ -50,7 +50,7 @@ Keyboard::Keyboard(IOHIDDeviceRef device) IOHIDElementRef e = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, i); //DeviceElementDebugPrint(e, NULL); - try { inputs.push_back(new Key(e)); } + try { AddInput(new Key(e)); } catch (std::bad_alloc&) { /*Thrown if the key is reserved*/ } } CFRelease(elements); @@ -59,7 +59,7 @@ Keyboard::Keyboard(IOHIDDeviceRef device) [pool release]; } -ControlState Keyboard::GetInputState( const ControllerInterface::Device::Input* const input ) +ControlState Keyboard::GetInputState( const ControllerInterface::Device::Input* const input ) const { return ((Input*)input)->GetState(m_device); } @@ -110,7 +110,7 @@ Keyboard::Key::Key(IOHIDElementRef element) NSLog(@"Got key 0x%x of type RESERVED", IOHIDElementGetUsage(m_element)); } -ControlState Keyboard::Key::GetState(IOHIDDeviceRef device) +ControlState Keyboard::Key::GetState(IOHIDDeviceRef device) const { IOHIDValueRef value; if (IOHIDDeviceGetValue(device, m_element, &value) == kIOReturnSuccess) diff --git a/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXMouse.h b/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXMouse.h index 97f87942a1..58f3459da6 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXMouse.h +++ b/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXMouse.h @@ -19,7 +19,7 @@ protected: { friend class Mouse; protected: - virtual ControlState GetState(IOHIDDeviceRef device) = 0; + virtual ControlState GetState(IOHIDDeviceRef device) const = 0; }; class Button : public Input @@ -29,7 +29,7 @@ protected: std::string GetName() const; protected: Button( IOHIDElementRef element ); - ControlState GetState(IOHIDDeviceRef device); + ControlState GetState(IOHIDDeviceRef device) const; private: IOHIDElementRef m_element; std::string m_name; @@ -46,7 +46,7 @@ protected: std::string GetName() const; protected: Axis( IOHIDElementRef element, direction dir ); - ControlState GetState(IOHIDDeviceRef device); + ControlState GetState(IOHIDDeviceRef device) const; private: IOHIDElementRef m_element; std::string m_name; @@ -57,7 +57,7 @@ protected: bool UpdateInput(); bool UpdateOutput(); - ControlState GetInputState( const ControllerInterface::Device::Input* const input ); + ControlState GetInputState( const ControllerInterface::Device::Input* const input ) const; void SetOutputState( const ControllerInterface::Device::Output* const output, const ControlState state ); public: diff --git a/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXMouse.mm b/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXMouse.mm index b5b288ec1f..22746bfc24 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXMouse.mm +++ b/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXMouse.mm @@ -38,7 +38,7 @@ Mouse::Mouse(IOHIDDeviceRef device) IOHIDElementRef e = (IOHIDElementRef)CFArrayGetValueAtIndex(buttons, i); //DeviceElementDebugPrint(e, NULL); - inputs.push_back(new Button(e)); + AddInput(new Button(e)); } CFRelease(buttons); } @@ -59,8 +59,8 @@ Mouse::Mouse(IOHIDDeviceRef device) IOHIDElementRef e = (IOHIDElementRef)CFArrayGetValueAtIndex(axes, i); //DeviceElementDebugPrint(e, NULL); - inputs.push_back(new Axis(e, Axis::negative)); - inputs.push_back(new Axis(e, Axis::positive)); + AddInput(new Axis(e, Axis::negative)); + AddInput(new Axis(e, Axis::positive)); } CFRelease(axes); } @@ -68,7 +68,7 @@ Mouse::Mouse(IOHIDDeviceRef device) [pool release]; } -ControlState Mouse::GetInputState( const ControllerInterface::Device::Input* const input ) +ControlState Mouse::GetInputState( const ControllerInterface::Device::Input* const input ) const { return ((Input*)input)->GetState(m_device); } @@ -111,7 +111,7 @@ Mouse::Button::Button(IOHIDElementRef element) m_name = std::string("Button ") + s.str(); } -ControlState Mouse::Button::GetState(IOHIDDeviceRef device) +ControlState Mouse::Button::GetState(IOHIDDeviceRef device) const { IOHIDValueRef value; if (IOHIDDeviceGetValue(device, m_element, &value) == kIOReturnSuccess) diff --git a/Source/Core/InputCommon/Src/ControllerInterface/SDL/SDL.cpp b/Source/Core/InputCommon/Src/ControllerInterface/SDL/SDL.cpp index 8b53609058..8c6d8e66dc 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/SDL/SDL.cpp +++ b/Source/Core/InputCommon/Src/ControllerInterface/SDL/SDL.cpp @@ -73,7 +73,7 @@ Joystick::Joystick(SDL_Joystick* const joystick, const int sdl_index, const unsi // get buttons for ( int i = 0; i < SDL_JoystickNumButtons( m_joystick ); ++i ) { - inputs.push_back( new Button( i ) ); + AddInput( new Button( i ) ); } // get hats @@ -81,15 +81,15 @@ Joystick::Joystick(SDL_Joystick* const joystick, const int sdl_index, const unsi { // each hat gets 4 input instances associated with it, (up down left right) for ( unsigned int d = 0; d < 4; ++d ) - inputs.push_back( new Hat( i, d ) ); + AddInput( new Hat( i, d ) ); } // get axes for ( int i = 0; i < SDL_JoystickNumAxes( m_joystick ); ++i ) { // each axis gets a negative and a positive input instance associated with it - inputs.push_back( new Axis( i, -32768 ) ); - inputs.push_back( new Axis( i, 32767 ) ); + AddInput( new Axis( i, -32768 ) ); + AddInput( new Axis( i, 32767 ) ); } #ifdef USE_SDL_HAPTIC @@ -106,14 +106,14 @@ Joystick::Joystick(SDL_Joystick* const joystick, const int sdl_index, const unsi if ( supported_effects & SDL_HAPTIC_CONSTANT ) { outputs.push_back( new ConstantEffect( m_state_out.size() ) ); - m_state_out.push_back( EffectIDState() ); + AddOutput( EffectIDState() ); } // ramp effect if ( supported_effects & SDL_HAPTIC_RAMP ) { outputs.push_back( new RampEffect( m_state_out.size() ) ); - m_state_out.push_back( EffectIDState() ); + AddOutput( EffectIDState() ); } } #endif @@ -185,7 +185,7 @@ void Joystick::RampEffect::SetState( const ControlState state, Joystick::EffectI } #endif -ControlState Joystick::GetInputState(const ControllerInterface::Device::Input* input) +ControlState Joystick::GetInputState(const ControllerInterface::Device::Input* input) const { return ((Input*)input)->GetState( m_joystick ); } diff --git a/Source/Core/InputCommon/Src/ControllerInterface/SDL/SDL.h b/Source/Core/InputCommon/Src/ControllerInterface/SDL/SDL.h index b8d9d668a2..86b1c65e83 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/SDL/SDL.h +++ b/Source/Core/InputCommon/Src/ControllerInterface/SDL/SDL.h @@ -131,7 +131,7 @@ protected: bool UpdateInput(); bool UpdateOutput(); - ControlState GetInputState( const ControllerInterface::Device::Input* const input ); + ControlState GetInputState( const ControllerInterface::Device::Input* const input ) const; void SetOutputState( const ControllerInterface::Device::Output* const output, const ControlState state ); public: diff --git a/Source/Core/InputCommon/Src/ControllerInterface/XInput/XInput.cpp b/Source/Core/InputCommon/Src/ControllerInterface/XInput/XInput.cpp index a2b6c638c9..5523e7cfa8 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/XInput/XInput.cpp +++ b/Source/Core/InputCommon/Src/ControllerInterface/XInput/XInput.cpp @@ -72,14 +72,14 @@ Device::Device( const XINPUT_CAPABILITIES* const caps, const unsigned int index // get supported buttons for ( int i = 0; i < sizeof(named_buttons)/sizeof(*named_buttons); ++i ) if ( named_buttons[i].bitmask & caps->Gamepad.wButtons ) - inputs.push_back( new Button( /*xinput_named_buttons[i].bitmask, */i ) ); + AddInput( new Button( /*xinput_named_buttons[i].bitmask, */i ) ); // get supported triggers 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] ) - inputs.push_back( new Trigger( i, 255 ) ); + AddInput( new Trigger( i, 255 ) ); } // get supported axes @@ -89,8 +89,8 @@ Device::Device( const XINPUT_CAPABILITIES* const caps, const unsigned int index if ( (&caps->Gamepad.sThumbLX)[i] ) { // each axis gets a negative and a positive input instance associated with it - inputs.push_back( new Axis( i, -32768 ) ); - inputs.push_back( new Axis( i, 32767 ) ); + AddInput( new Axis( i, -32768 ) ); + AddInput( new Axis( i, 32767 ) ); } } @@ -99,7 +99,7 @@ Device::Device( const XINPUT_CAPABILITIES* const caps, const unsigned int index { //WORD val = (&caps->Vibration.wLeftMotorSpeed)[i]; // should be max value / nope, more lies if ( (&caps->Vibration.wLeftMotorSpeed)[i] ) - outputs.push_back( new Motor(i, 65535 ) ); + AddOutput( new Motor(i, 65535 ) ); } ClearInputState(); @@ -185,7 +185,7 @@ std::string Device::Motor::GetName() const // get/set control state -ControlState Device::GetInputState( const ControllerInterface::Device::Input* const input ) +ControlState Device::GetInputState( const ControllerInterface::Device::Input* const input ) const { return ((Input*)input)->GetState( &m_state_in.Gamepad ); } @@ -197,17 +197,17 @@ void Device::SetOutputState( const ControllerInterface::Device::Output* const ou // GET / SET STATES -ControlState Device::Button::GetState( const XINPUT_GAMEPAD* const gamepad ) +ControlState Device::Button::GetState( const XINPUT_GAMEPAD* const gamepad ) const { return (gamepad->wButtons & named_buttons[m_index].bitmask) > 0; } -ControlState Device::Trigger::GetState( const XINPUT_GAMEPAD* const gamepad ) +ControlState Device::Trigger::GetState( const XINPUT_GAMEPAD* const gamepad ) const { return ControlState((&gamepad->bLeftTrigger)[m_index]) / m_range; } -ControlState Device::Axis::GetState( const XINPUT_GAMEPAD* const gamepad ) +ControlState Device::Axis::GetState( const XINPUT_GAMEPAD* const gamepad ) const { return std::max( 0.0f, ControlState((&gamepad->sThumbLX)[m_index]) / m_range ); } diff --git a/Source/Core/InputCommon/Src/ControllerInterface/XInput/XInput.h b/Source/Core/InputCommon/Src/ControllerInterface/XInput/XInput.h index 194a9c19fd..57f5e6e80b 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/XInput/XInput.h +++ b/Source/Core/InputCommon/Src/ControllerInterface/XInput/XInput.h @@ -25,7 +25,7 @@ protected: { friend class Device; protected: - virtual ControlState GetState( const XINPUT_GAMEPAD* const gamepad ) = 0; + virtual ControlState GetState( const XINPUT_GAMEPAD* const gamepad ) const = 0; }; class Output : public ControllerInterface::Device::Output @@ -42,7 +42,7 @@ protected: std::string GetName() const; protected: Button( const unsigned int index ) : m_index(index) {} - ControlState GetState( const XINPUT_GAMEPAD* const gamepad ); + ControlState GetState( const XINPUT_GAMEPAD* const gamepad ) const; private: const unsigned int m_index; }; @@ -54,7 +54,7 @@ protected: 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 ); + ControlState GetState( const XINPUT_GAMEPAD* const gamepad ) const; private: const unsigned int m_index; const SHORT m_range; @@ -67,7 +67,7 @@ protected: 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 ); + ControlState GetState( const XINPUT_GAMEPAD* const gamepad ) const; private: const unsigned int m_index; const BYTE m_range; @@ -89,7 +89,7 @@ protected: bool UpdateInput(); bool UpdateOutput(); - ControlState GetInputState( const ControllerInterface::Device::Input* const input ); + ControlState GetInputState( const ControllerInterface::Device::Input* const input ) const; void SetOutputState( const ControllerInterface::Device::Output* const input, const ControlState state ); void ClearInputState(); diff --git a/Source/Core/InputCommon/Src/ControllerInterface/Xlib/Xlib.cpp b/Source/Core/InputCommon/Src/ControllerInterface/Xlib/Xlib.cpp index a2396ae9ea..0eac61eac2 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/Xlib/Xlib.cpp +++ b/Source/Core/InputCommon/Src/ControllerInterface/Xlib/Xlib.cpp @@ -26,17 +26,17 @@ Keyboard::Keyboard(Display* display) : m_display(display) { Key *temp_key = new Key(m_display, i); if (temp_key->m_keyname.length()) - inputs.push_back(temp_key); + AddInput(temp_key); else delete temp_key; } // Mouse Buttons - inputs.push_back(new Button(Button1Mask)); - inputs.push_back(new Button(Button2Mask)); - inputs.push_back(new Button(Button3Mask)); - inputs.push_back(new Button(Button4Mask)); - inputs.push_back(new Button(Button5Mask)); + AddInput(new Button(Button1Mask)); + AddInput(new Button(Button2Mask)); + AddInput(new Button(Button3Mask)); + AddInput(new Button(Button4Mask)); + AddInput(new Button(Button5Mask)); } Keyboard::~Keyboard() @@ -44,7 +44,7 @@ Keyboard::~Keyboard() } -ControlState Keyboard::GetInputState(const ControllerInterface::Device::Input* const input) +ControlState Keyboard::GetInputState(const ControllerInterface::Device::Input* const input) const { return ((Input*)input)->GetState(&m_state); } @@ -112,12 +112,12 @@ Keyboard::Key::Key(Display* const display, KeyCode keycode) m_keyname = std::string(XKeysymToString(keysym)); } -ControlState Keyboard::Key::GetState(const State* const state) +ControlState Keyboard::Key::GetState(const State* const state) const { return (state->keyboard[m_keycode/8] & (1 << (m_keycode%8))) != 0; } -ControlState Keyboard::Button::GetState(const State* const state) +ControlState Keyboard::Button::GetState(const State* const state) const { return ((state->buttons & m_index) > 0); } diff --git a/Source/Core/InputCommon/Src/ControllerInterface/Xlib/Xlib.h b/Source/Core/InputCommon/Src/ControllerInterface/Xlib/Xlib.h index 1cadd4d7e6..d9d07f17ba 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/Xlib/Xlib.h +++ b/Source/Core/InputCommon/Src/ControllerInterface/Xlib/Xlib.h @@ -30,7 +30,7 @@ protected: friend class Keyboard; protected: - virtual ControlState GetState(const State* const state) = 0; + virtual ControlState GetState(const State* const state) const = 0; }; class Key : public Input @@ -42,7 +42,7 @@ protected: protected: Key(Display* const display, KeyCode keycode); - ControlState GetState(const State* const state); + ControlState GetState(const State* const state) const; private: Display* const m_display; @@ -60,7 +60,7 @@ protected: protected: Button(const unsigned int index) : m_index(index) {} - ControlState GetState(const State* const state); + ControlState GetState(const State* const state) const; private: const unsigned int m_index; @@ -69,7 +69,7 @@ protected: bool UpdateInput(); bool UpdateOutput(); - ControlState GetInputState(const ControllerInterface::Device::Input* const input); + ControlState GetInputState(const ControllerInterface::Device::Input* const input) const; void SetOutputState(const ControllerInterface::Device::Output* const output, const ControlState state); public: diff --git a/Source/Core/InputCommon/Src/InputConfig.cpp b/Source/Core/InputCommon/Src/InputConfig.cpp index b4d8a3b546..cfba6aaec9 100644 --- a/Source/Core/InputCommon/Src/InputConfig.cpp +++ b/Source/Core/InputCommon/Src/InputConfig.cpp @@ -59,7 +59,6 @@ void InputPlugin::SaveConfig() std::string ini_filename = (std::string(File::GetUserPath(D_CONFIG_IDX)) + ini_name + ".ini" ); IniFile inifile; - inifile.Load(ini_filename); std::vector< ControllerEmu* >::const_iterator i = controllers.begin(), e = controllers.end(); diff --git a/Source/Core/InputUICommon/Src/ConfigDiag.cpp b/Source/Core/InputUICommon/Src/ConfigDiag.cpp index 30f461ea8e..0b6d352ec3 100644 --- a/Source/Core/InputUICommon/Src/ConfigDiag.cpp +++ b/Source/Core/InputUICommon/Src/ConfigDiag.cpp @@ -17,9 +17,11 @@ #include "ConfigDiag.h" -#define _connect_macro_(b, f, c, s) (b)->Connect(wxID_ANY, (c), wxCommandEventHandler( f ), (wxObject*)0, (wxEvtHandler*)s) -#define WXSTR_FROM_STR(s) (wxString::FromAscii((s).c_str())) -#define STR_FROM_WXSTR(w) (std::string((w).To8BitData())) +#define _connect_macro_(b, f, c, s) (b)->Connect(wxID_ANY, (c), wxCommandEventHandler( f ), (wxObject*)0, (wxEvtHandler*)s) +#define WXSTR_FROM_STR(s) (wxString::FromAscii((s).c_str())) +// ToAscii was causing probs with some extended ascii characters, To8BitData seems to work +#define STR_FROM_WXSTR(w) (std::string((w).To8BitData())) + void GamepadPage::ConfigExtension( wxCommandEvent& event ) { @@ -103,27 +105,32 @@ void PadSettingChoice::UpdateValue() } ControlDialog::ControlDialog(GamepadPage* const parent, InputPlugin& plugin, ControllerInterface::ControlReference* const ref) - :wxDialog( parent, -1, wxT("Configure Control"), wxDefaultPosition ) - ,control_reference(ref) - ,m_plugin(plugin) + : wxDialog(parent, -1, wxT("Configure Control"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) + , control_reference(ref) + , m_plugin(plugin) + , m_parent(parent) { + m_devq = m_parent->controller->default_device; + // GetStrings() sounds slow :/ - device_cbox = new wxComboBox( this, -1, wxString::FromAscii( ref->device_qualifier.ToString().c_str() ), wxDefaultPosition, wxSize(256,-1), parent->device_cbox->GetStrings(), wxTE_PROCESS_ENTER ); + //device_cbox = new wxComboBox(this, -1, WXSTR_FROM_STR(ref->device_qualifier.ToString()), wxDefaultPosition, wxSize(256,-1), parent->device_cbox->GetStrings(), wxTE_PROCESS_ENTER); + device_cbox = new wxComboBox(this, -1, WXSTR_FROM_STR(m_devq.ToString()), wxDefaultPosition, wxSize(256,-1), parent->device_cbox->GetStrings(), wxTE_PROCESS_ENTER); _connect_macro_( device_cbox, ControlDialog::SetDevice, wxEVT_COMMAND_COMBOBOX_SELECTED, this ); _connect_macro_( device_cbox, ControlDialog::SetDevice, wxEVT_COMMAND_TEXT_ENTER, this ); - control_chooser = new ControlChooser( this, ref, parent ); + wxStaticBoxSizer* const control_chooser = CreateControlChooser( this, parent ); wxStaticBoxSizer* const d_szr = new wxStaticBoxSizer( wxVERTICAL, this, wxT("Device") ); d_szr->Add( device_cbox, 0, wxEXPAND|wxALL, 5 ); wxBoxSizer* const szr = new wxBoxSizer( wxVERTICAL ); szr->Add( d_szr, 0, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 ); - szr->Add( control_chooser, 0, wxEXPAND|wxALL, 5 ); + szr->Add( control_chooser, 1, wxEXPAND|wxALL, 5 ); SetSizerAndFit( szr ); // needed + UpdateGUI(); } ControlButton::ControlButton( wxWindow* const parent, ControllerInterface::ControlReference* const _ref, const unsigned int width, const std::string& label ) @@ -131,9 +138,9 @@ ControlButton::ControlButton( wxWindow* const parent, ControllerInterface::Contr , control_reference( _ref ) { if ( label.empty() ) - SetLabel( wxString::FromAscii( _ref->control_qualifier.name.c_str() ) ); + SetLabel(WXSTR_FROM_STR(_ref->expression)); else - SetLabel( wxString::FromAscii( label.c_str() ) ); + SetLabel(WXSTR_FROM_STR(label)); } void InputConfigDialog::UpdateProfileComboBox() @@ -181,76 +188,63 @@ void InputConfigDialog::ClickSave( wxCommandEvent& event ) Close(); } -void ControlChooser::UpdateListContents() +void ControlDialog::UpdateListContents() { control_lbox->Clear(); - // make sure it's a valid device - if ( control_reference->device ) + const std::vector::const_iterator di = + std::find(m_plugin.controller_interface.Devices().begin(), + m_plugin.controller_interface.Devices().end(), + m_devq); + + if (m_plugin.controller_interface.Devices().end() != di) { - if ( control_reference->is_input ) + if (control_reference->is_input) { // for inputs std::vector::const_iterator - i = control_reference->device->Inputs().begin(), - e = control_reference->device->Inputs().end(); - for ( ; i!=e; ++i ) - control_lbox->Append( wxString::FromAscii( (*i)->GetName().c_str() ) ); + i = (*di)->Inputs().begin(), + e = (*di)->Inputs().end(); + for (; i!=e; ++i) + control_lbox->Append(WXSTR_FROM_STR((*i)->GetName())); } else { // for outputs std::vector::const_iterator - i = control_reference->device->Outputs().begin(), - e = control_reference->device->Outputs().end(); - for ( ; i!=e; ++i ) - control_lbox->Append( wxString::FromAscii( (*i)->GetName().c_str() ) ); + i = (*di)->Outputs().begin(), + e = (*di)->Outputs().end(); + for (; i!=e; ++i) + control_lbox->Append(WXSTR_FROM_STR((*i)->GetName())); } } - - UpdateListSelection(); } -void ControlChooser::UpdateListSelection() +void ControlDialog::SelectControl(const std::string& name) { - UpdateGUI(); + //UpdateGUI(); - wxArrayString control_names = control_lbox->GetStrings(); - const std::string cname = control_reference->control_qualifier.name; - - control_lbox->DeselectAll(); - - // if text starts and ends with '|' it's multiple controls, otherwise just single one - if (cname.size() ? ((*cname.rbegin()=='|') && (*cname.begin()=='|')) : false) - { - for (int i = int(control_names.size()) - 1; i >= 0; --i) - if (cname.find( control_names[i].Prepend(wxT('|')).Append(wxT('|')).ToAscii()) != cname.npos) - control_lbox->Select( i ); - } - else - { - const int n = control_lbox->FindString(wxString::FromAscii(cname.c_str())); - if (n >= 0) - control_lbox->Select(n); - } + const int f = control_lbox->FindString(WXSTR_FROM_STR(name)); + if (f >= 0) + control_lbox->Select(f); } -void ControlChooser::UpdateGUI() +void ControlDialog::UpdateGUI() { // update textbox - textctrl->SetValue(wxString::FromAscii(control_reference->control_qualifier.name.c_str())); + textctrl->SetValue(WXSTR_FROM_STR(control_reference->expression)); // updates the "bound controls:" label - size_t bound = control_reference->controls.size(); + size_t bound = control_reference->BoundCount(); std::ostringstream ss; ss << "Bound Controls: "; if ( bound ) ss << bound; else ss << "None"; - m_bound_label->SetLabel(WXSTR_FROM_STR(ss.str())); + m_bound_label->SetLabel( wxString::FromAscii(ss.str().c_str()) ); }; void GamepadPage::UpdateGUI() { - device_cbox->SetValue( wxString::FromAscii( controller->default_device.ToString().c_str() ) ); + device_cbox->SetValue(WXSTR_FROM_STR(controller->default_device.ToString())); std::vector< ControlGroupBox* >::const_iterator g = control_groups.begin(), ge = control_groups.end(); @@ -260,7 +254,10 @@ void GamepadPage::UpdateGUI() std::vector::const_iterator i = (*g)->control_buttons.begin() , e = (*g)->control_buttons.end(); for ( ; i!=e; ++i ) - (*i)->SetLabel(WXSTR_FROM_STR((*i)->control_reference->control_qualifier.name)); + //if (std::string::npos == (*i)->control_reference->expression.find_first_of("`|&!#")) + (*i)->SetLabel(WXSTR_FROM_STR((*i)->control_reference->expression)); + //else + //(*i)->SetLabel(wxT("...")); // cboxes std::vector::const_iterator si = (*g)->options.begin() @@ -289,14 +286,13 @@ void GamepadPage::ClearAll( wxCommandEvent& event ) void ControlDialog::SetControl( wxCommandEvent& event ) { - control_reference->control_qualifier.name = - STR_FROM_WXSTR(control_chooser->textctrl->GetValue()); + control_reference->expression = STR_FROM_WXSTR(textctrl->GetValue()); m_plugin.controls_crit.Enter(); // enter - control_reference->UpdateControls(); + m_plugin.controller_interface.UpdateReference(control_reference, m_parent->controller->default_device); m_plugin.controls_crit.Leave(); // leave - control_chooser->UpdateListSelection(); + UpdateGUI(); } void GamepadPage::SetDevice( wxCommandEvent& event ) @@ -311,35 +307,62 @@ void GamepadPage::SetDevice( wxCommandEvent& event ) // update references m_plugin.controls_crit.Enter(); // enter - controller->UpdateReferences(m_plugin.controller_interface); + controller->UpdateReferences( m_plugin.controller_interface ); m_plugin.controls_crit.Leave(); // leave } void ControlDialog::SetDevice( wxCommandEvent& event ) { - control_reference->device_qualifier.FromString(STR_FROM_WXSTR(device_cbox->GetValue())); + m_devq.FromString(STR_FROM_WXSTR(device_cbox->GetValue())); // show user what it was validated as - device_cbox->SetValue(WXSTR_FROM_STR(control_reference->device_qualifier.ToString())); - - // update references - m_plugin.controls_crit.Enter(); // enter - m_plugin.controller_interface.UpdateReference(control_reference); - m_plugin.controls_crit.Leave(); // leave + device_cbox->SetValue(WXSTR_FROM_STR(m_devq.ToString())); // update gui - control_chooser->UpdateListContents(); + UpdateListContents(); } -void ControlDialog::ClearControl( wxCommandEvent& event ) +void ControlDialog::ClearControl(wxCommandEvent& event) { - control_reference->control_qualifier.name.clear(); + control_reference->expression.clear(); m_plugin.controls_crit.Leave(); // enter - control_reference->UpdateControls(); + m_plugin.controller_interface.UpdateReference(control_reference, m_parent->controller->default_device); m_plugin.controls_crit.Leave(); // leave - control_chooser->UpdateListSelection(); + UpdateGUI(); +} + +void ControlDialog::AppendControl(wxCommandEvent& event) +{ + const int num = control_lbox->GetSelection(); + + if (num < 0) + return; + + // o boy!, hax + const wxString lbl = ((wxButton*)event.GetEventObject())->GetLabel(); + + wxString expr = textctrl->GetLabel(); + + // append the operator to the expression + if (wxT('!') == lbl[0] || false == expr.empty()) + expr += lbl[0]; + + // non-default device + if (false == (m_devq == m_parent->controller->default_device)) + expr.append(wxT('`')).append(WXSTR_FROM_STR(m_devq.ToString())).append(wxT('`')); + + // append the control name + expr += control_lbox->GetString(num); + + control_reference->expression = STR_FROM_WXSTR(expr); + + m_plugin.controls_crit.Leave(); // enter + m_plugin.controller_interface.UpdateReference(control_reference, m_parent->controller->default_device); + m_plugin.controls_crit.Leave(); // leave + + UpdateGUI(); } void GamepadPage::AdjustSetting( wxCommandEvent& event ) @@ -354,13 +377,9 @@ void GamepadPage::AdjustSetting( wxCommandEvent& event ) void GamepadPage::AdjustControlOption( wxCommandEvent& event ) { - m_plugin.controls_crit.Enter(); // enter + m_plugin.controls_crit.Enter(); // enter / prolly fine not being here - m_control_dialog->control_reference->range = ControlState( m_control_dialog->control_chooser->range_slider->GetValue() ) / SLIDER_TICK_COUNT; - - if ( m_control_dialog->control_reference->is_input ) - ((ControllerInterface::InputReference*)m_control_dialog->control_reference)->mode = - m_control_dialog->control_chooser->mode_cbox->GetSelection(); + m_control_dialog->control_reference->range = (ControlState)(m_control_dialog->range_slider->GetValue()) / SLIDER_TICK_COUNT; m_plugin.controls_crit.Leave(); // leave } @@ -378,12 +397,10 @@ void GamepadPage::ConfigControl( wxCommandEvent& event ) void GamepadPage::ClearControl( wxCommandEvent& event ) { ControlButton* const btn = (ControlButton*)event.GetEventObject(); - btn->control_reference->control_qualifier.name.clear(); - btn->control_reference->device_qualifier = controller->default_device; + btn->control_reference->expression.clear(); + //btn->control_reference->device_qualifier = controller->default_device; m_plugin.controls_crit.Enter(); - if (btn->control_reference->is_input) - ((ControllerInterface::InputReference*)btn->control_reference)->mode = 0; controller->UpdateReferences( m_plugin.controller_interface ); m_plugin.controls_crit.Leave(); @@ -391,106 +408,95 @@ void GamepadPage::ClearControl( wxCommandEvent& event ) UpdateGUI(); } -void ControlDialog::DetectControl( wxCommandEvent& event ) +void ControlDialog::DetectControl(wxCommandEvent& event) { wxButton* const btn = (wxButton*)event.GetEventObject(); - - // some hacks const wxString lbl = btn->GetLabel(); - wxChar num = lbl[0]; - if (num > '9') + + const std::vector::const_iterator di = + std::find(m_plugin.controller_interface.Devices().begin(), + m_plugin.controller_interface.Devices().end(), m_devq); + + if (m_plugin.controller_interface.Devices().end() != di) { - num = 1; btn->SetLabel(wxT("[ waiting ]")); - } - else - { - num -= 0x30; - btn->SetLabel(wxT("w")); - } - m_plugin.controls_crit.Enter(); // enter - if ( control_reference->Detect( DETECT_WAIT_TIME + (num - 1) * 500, num ) ) // if we got input, update gui - control_chooser->UpdateListSelection(); - m_plugin.controls_crit.Leave(); // leave + m_plugin.controls_crit.Enter(); // enter + ControllerInterface::Device::Control* const ctrl = control_reference->Detect(DETECT_WAIT_TIME, *di); - btn->SetLabel(lbl); + // if we got input, select it in the list + if (ctrl) + SelectControl(ctrl->GetName()); + + m_plugin.controls_crit.Leave(); // leave + + btn->SetLabel(lbl); + } } void GamepadPage::DetectControl( wxCommandEvent& event ) { ControlButton* btn = (ControlButton*)event.GetEventObject(); - btn->SetLabel(wxT("[ waiting ]")); + // find device :/ + const std::vector::const_iterator di = + std::find(m_plugin.controller_interface.Devices().begin(), + m_plugin.controller_interface.Devices().end(), controller->default_device); - m_plugin.controls_crit.Enter(); // enter - btn->control_reference->Detect( DETECT_WAIT_TIME ); - m_plugin.controls_crit.Leave(); // leave - - btn->SetLabel(WXSTR_FROM_STR(btn->control_reference->control_qualifier.name)); -} - -void ControlDialog::SelectControl( wxCommandEvent& event ) -{ - // needed for linux - if (IsBeingDeleted()) - return; - - wxListBox* const lb = (wxListBox*)event.GetEventObject(); - - wxArrayInt sels; - lb->GetSelections( sels ); - wxArrayString names = lb->GetStrings(); - - wxString final_label; - - if (sels.GetCount() == 1) - final_label = names[ sels[0] ]; - else + if (m_plugin.controller_interface.Devices().end() != di) { - final_label = wxT('|'); - for ( unsigned int i=0; iSetLabel(wxT("[ waiting ]")); + + m_plugin.controls_crit.Enter(); // enter + ControllerInterface::Device::Control* const ctrl = btn->control_reference->Detect(DETECT_WAIT_TIME, *di); + + // if we got input, update expression and reference + if (ctrl) + { + btn->control_reference->expression = ctrl->GetName(); + m_plugin.controller_interface.UpdateReference(btn->control_reference, controller->default_device); + } + + m_plugin.controls_crit.Leave(); // leave + + btn->SetLabel(WXSTR_FROM_STR(btn->control_reference->expression)); } - - control_reference->control_qualifier.name = - std::string( final_label.ToAscii() ); - - m_plugin.controls_crit.Enter(); // enter - control_reference->UpdateControls(); - m_plugin.controls_crit.Leave(); // leave - - control_chooser->UpdateGUI(); } -ControlChooser::ControlChooser( wxWindow* const parent, ControllerInterface::ControlReference* const ref, wxWindow* const eventsink ) -: wxStaticBoxSizer( wxVERTICAL, parent, ref->is_input ? wxT("Input") : wxT("Output") ) - , control_reference(ref) +wxStaticBoxSizer* ControlDialog::CreateControlChooser( wxWindow* const parent, wxWindow* const eventsink ) { - textctrl = new wxTextCtrl( parent, -1, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER ); - _connect_macro_( textctrl, ControlDialog::SetControl, wxEVT_COMMAND_TEXT_ENTER, parent); + wxStaticBoxSizer* const main_szr = new wxStaticBoxSizer(wxVERTICAL, parent, control_reference->is_input ? wxT("Input") : wxT("Output")); - wxButton* const detect_button = new wxButton( parent, -1, ref->is_input ? wxT("Detect 1") : wxT("Test") ); + textctrl = new wxTextCtrl(parent, -1, wxEmptyString, wxDefaultPosition, wxSize(-1, 48), wxTE_PROCESS_ENTER | wxTE_MULTILINE); + _connect_macro_(textctrl, ControlDialog::SetControl, wxEVT_COMMAND_TEXT_ENTER, parent); + + wxButton* const detect_button = new wxButton( parent, -1, control_reference->is_input ? wxT("Detect") : wxT("Test") ); wxButton* const clear_button = new wxButton( parent, -1, wxT("Clear"), wxDefaultPosition ); wxButton* const set_button = new wxButton( parent, -1, wxT("Set")/*, wxDefaultPosition, wxSize( 32, -1 )*/ ); + wxButton* const or_button = new wxButton( parent, -1, wxT("| OR"), wxDefaultPosition ); + // TODO: check if && is good on other OS + wxButton* const and_button = new wxButton( parent, -1, wxT("&& AND"), wxDefaultPosition ); + wxButton* const not_button = new wxButton( parent, -1, wxT("! NOT"), wxDefaultPosition ); + wxButton* const add_button = new wxButton( parent, -1, wxT("# ADD"), wxDefaultPosition ); - control_lbox = new wxListBox( parent, -1, wxDefaultPosition, wxSize( 256, 128 ), wxArrayString(), wxLB_EXTENDED ); - _connect_macro_( control_lbox, ControlDialog::SelectControl, wxEVT_COMMAND_LISTBOX_SELECTED, parent); + _connect_macro_(or_button, ControlDialog::AppendControl, wxEVT_COMMAND_BUTTON_CLICKED, parent); + _connect_macro_(and_button, ControlDialog::AppendControl, wxEVT_COMMAND_BUTTON_CLICKED, parent); + _connect_macro_(not_button, ControlDialog::AppendControl, wxEVT_COMMAND_BUTTON_CLICKED, parent); + _connect_macro_(add_button, ControlDialog::AppendControl, wxEVT_COMMAND_BUTTON_CLICKED, parent); - wxBoxSizer* const button_sizer = new wxBoxSizer( wxHORIZONTAL ); - button_sizer->Add( detect_button, 1, 0, 5 ); - if ( ref->is_input ) - for ( unsigned int i = 2; i<5; ++i ) - { - wxButton* d_btn = new wxButton( parent, -1, wxChar( '0'+i ), wxDefaultPosition, wxSize(20,-1) ); - _connect_macro_( d_btn, ControlDialog::DetectControl, wxEVT_COMMAND_BUTTON_CLICKED, parent); - button_sizer->Add( d_btn ); - } - button_sizer->Add( clear_button, 1, 0, 5 ); - button_sizer->Add( set_button, 1, 0, 5 ); + control_lbox = new wxListBox(parent, -1, wxDefaultPosition, wxSize(128, 128)); - range_slider = new wxSlider( parent, -1, SLIDER_TICK_COUNT, 0, SLIDER_TICK_COUNT, wxDefaultPosition, wxDefaultSize, wxSL_TOP | wxSL_LABELS /*| wxSL_AUTOTICKS*/ ); + wxBoxSizer* const button_sizer = new wxBoxSizer(wxVERTICAL); + button_sizer->Add(detect_button, 1, 0, 5); + button_sizer->Add(clear_button, 1, 0, 5); + button_sizer->Add(or_button, 1, 0, 5); + button_sizer->Add(and_button, 1, 0, 5); + button_sizer->Add(not_button, 1, 0, 5); + button_sizer->Add(add_button, 1, 0, 5); + button_sizer->Add(set_button, 1, 0, 5); + + range_slider = new wxSlider( parent, -1, SLIDER_TICK_COUNT, 0, SLIDER_TICK_COUNT * 2, wxDefaultPosition, wxDefaultSize, wxSL_TOP | wxSL_LABELS /*| wxSL_AUTOTICKS*/ ); range_slider->SetValue( control_reference->range * SLIDER_TICK_COUNT ); @@ -506,112 +512,96 @@ ControlChooser::ControlChooser( wxWindow* const parent, ControllerInterface::Con range_sizer->Add( range_label, 0, wxCENTER|wxLEFT, 5 ); range_sizer->Add( range_slider, 1, wxEXPAND|wxLEFT, 5 ); - wxBoxSizer* const txtbox_szr = new wxBoxSizer( wxHORIZONTAL ); + wxBoxSizer* const ctrls_sizer = new wxBoxSizer(wxHORIZONTAL); + ctrls_sizer->Add(control_lbox, 1, wxEXPAND, 0); + ctrls_sizer->Add(button_sizer, 0, wxEXPAND, 0); - txtbox_szr->Add( textctrl, 1, wxEXPAND, 0 ); - - - Add( range_sizer, 0, wxEXPAND|wxLEFT|wxRIGHT, 5 ); - if ( control_reference->is_input ) - { - mode_cbox = new wxChoice( parent, -1 ); - mode_cbox->Append( wxT("OR") ); - mode_cbox->Append( wxT("AND") ); - mode_cbox->Append( wxT("NOT") ); - mode_cbox->Select( ((ControllerInterface::InputReference*)control_reference)->mode ); - - _connect_macro_( mode_cbox, GamepadPage::AdjustControlOption, wxEVT_COMMAND_CHOICE_SELECTED, eventsink ); - - wxBoxSizer* const mode_szr = new wxBoxSizer( wxHORIZONTAL ); - mode_szr->Add( new wxStaticText( parent, -1, wxT("Mode") ), 0, wxCENTER|wxLEFT|wxRIGHT, 5 ); - mode_szr->Add( mode_cbox, 0, wxLEFT, 5 ); - - Add( mode_szr, 0, wxEXPAND|wxLEFT|wxRIGHT, 5 ); - } - Add( txtbox_szr, 0, wxEXPAND|wxTOP|wxLEFT|wxRIGHT, 5 ); - Add( button_sizer, 0, wxEXPAND|wxBOTTOM|wxLEFT|wxRIGHT, 5 ); - Add( control_lbox, 0, wxEXPAND|wxLEFT|wxRIGHT|wxBOTTOM, 5 ); - Add( m_bound_label, 0, wxEXPAND|wxLEFT, 80 ); + main_szr->Add(range_sizer, 0, wxEXPAND|wxLEFT|wxRIGHT, 5); + main_szr->Add(ctrls_sizer, 0, wxEXPAND|wxLEFT|wxRIGHT|wxBOTTOM, 5); + main_szr->Add(textctrl, 1, wxEXPAND|wxLEFT|wxRIGHT|wxBOTTOM, 5); + main_szr->Add(m_bound_label, 0, wxCENTER, 0); UpdateListContents(); + + return main_szr; +} + +void GamepadPage::GetProfilePath(std::string& path) +{ + const wxString& name = profile_cbox->GetValue(); + if (false == name.empty()) + { + // TODO: check for dumb characters maybe + + path = File::GetUserPath(D_CONFIG_IDX); + path += PROFILES_PATH; + path += m_plugin.profile_name; + path += '/'; + path += STR_FROM_WXSTR(profile_cbox->GetValue()); + path += ".ini"; + } } void GamepadPage::LoadProfile( wxCommandEvent& event ) { - // TODO: check for dumb characters maybe - if ( profile_cbox->GetValue().empty() ) - return; - - m_plugin.controls_crit.Enter(); + std::string fname; + GamepadPage::GetProfilePath(fname); - std::string fname( File::GetUserPath(D_CONFIG_IDX) ); - fname += PROFILES_PATH; fname += m_plugin.profile_name; fname += '/'; - fname += profile_cbox->GetValue().ToAscii(); fname += ".ini"; - - if ( false == File::Exists( fname.c_str() ) ) + if (false == File::Exists(fname.c_str())) return; IniFile inifile; inifile.Load(fname); - controller->LoadConfig( inifile.GetOrCreateSection("Profile")); - controller->UpdateReferences( m_plugin.controller_interface ); + m_plugin.controls_crit.Enter(); + controller->LoadConfig(inifile.GetOrCreateSection("Profile")); + controller->UpdateReferences(m_plugin.controller_interface); m_plugin.controls_crit.Leave(); + UpdateGUI(); } void GamepadPage::SaveProfile( wxCommandEvent& event ) { - // TODO: check for dumb characters - if ( profile_cbox->GetValue().empty() ) - return; + std::string fname; + GamepadPage::GetProfilePath(fname); - std::string fname( File::GetUserPath(D_CONFIG_IDX) ); - fname += PROFILES_PATH; fname += m_plugin.profile_name; fname += '/'; - if ( false == File::Exists( fname.c_str() ) ) - File::CreateFullPath( fname.c_str() ); - fname += profile_cbox->GetValue().ToAscii(); fname += ".ini"; - - // don't need lock - IniFile inifile; - inifile.Load(fname); - controller->SaveConfig( inifile.GetOrCreateSection("Profile") ); - inifile.Save(fname); + if (false == fname.empty()) + { + IniFile inifile; + controller->SaveConfig(inifile.GetOrCreateSection("Profile")); + inifile.Save(fname); + } m_config_dialog->UpdateProfileComboBox(); } void GamepadPage::DeleteProfile( wxCommandEvent& event ) { - // TODO: check for dumb characters maybe - if ( profile_cbox->GetValue().empty() ) - return; - - // don't need lock - std::string fname( File::GetUserPath(D_CONFIG_IDX) ); - fname += PROFILES_PATH; fname += m_plugin.profile_name; fname += '/'; - fname += profile_cbox->GetValue().ToAscii(); fname += ".ini"; - if ( File::Exists( fname.c_str() ) ) - File::Delete( fname.c_str() ); + std::string fname; + GamepadPage::GetProfilePath(fname); + + const char* const fnamecstr = fname.c_str(); + + if (File::Exists(fnamecstr)) + File::Delete(fnamecstr); m_config_dialog->UpdateProfileComboBox(); } void InputConfigDialog::UpdateDeviceComboBox() { - std::vector< GamepadPage* >::iterator - i = m_padpages.begin(), + std::vector< GamepadPage* >::iterator i = m_padpages.begin(), e = m_padpages.end(); ControllerInterface::DeviceQualifier dq; for ( ; i != e; ++i ) { (*i)->device_cbox->Clear(); - std::vector::const_iterator - di = m_plugin.controller_interface.Devices().begin(), + std::vector::const_iterator di = m_plugin.controller_interface.Devices().begin(), de = m_plugin.controller_interface.Devices().end(); for ( ; di!=de; ++di ) { - dq.FromDevice(*di); + dq.FromDevice( *di ); (*i)->device_cbox->Append(WXSTR_FROM_STR(dq.ToString())); } (*i)->device_cbox->SetValue(WXSTR_FROM_STR((*i)->controller->default_device.ToString())); @@ -637,7 +627,7 @@ void GamepadPage::RefreshDevices( wxCommandEvent& event ) } ControlGroupBox::ControlGroupBox( ControllerEmu::ControlGroup* const group, wxWindow* const parent, wxWindow* const eventsink ) -: wxStaticBoxSizer( wxVERTICAL, parent, wxString::FromAscii( group->name ) ) + : wxStaticBoxSizer( wxVERTICAL, parent, wxString::FromAscii( group->name ) ) { control_group = group; @@ -903,7 +893,7 @@ GamepadPage::GamepadPage( wxWindow* parent, InputPlugin& plugin, const unsigned InputConfigDialog::InputConfigDialog(wxWindow* const parent, InputPlugin& plugin, const std::string& name) - : wxDialog(parent, wxID_ANY, wxString::FromAscii(name.c_str()), wxPoint(128,-1), wxDefaultSize) + : wxDialog( parent, wxID_ANY, wxString::FromAscii(name.c_str()), wxPoint(128,-1), wxDefaultSize ) , m_plugin(plugin) { m_pad_notebook = new wxNotebook( this, -1, wxDefaultPosition, wxDefaultSize, wxNB_DEFAULT ); diff --git a/Source/Core/InputUICommon/Src/ConfigDiag.h b/Source/Core/InputUICommon/Src/ConfigDiag.h index 84d0f7c651..0f1c2e7dcd 100644 --- a/Source/Core/InputUICommon/Src/ConfigDiag.h +++ b/Source/Core/InputUICommon/Src/ConfigDiag.h @@ -88,36 +88,6 @@ public: ControlState& value; }; -class ControlChooser : public wxStaticBoxSizer -{ -public: - ControlChooser( wxWindow* const parent, ControllerInterface::ControlReference* const ref, wxWindow* const eventsink ); - - void UpdateGUI(); - void UpdateListContents(); - void UpdateListSelection(); - - ControllerInterface::ControlReference* control_reference; - - wxTextCtrl* textctrl; - wxListBox* control_lbox; - wxChoice* mode_cbox; - wxSlider* range_slider; - -private: - wxStaticText* m_bound_label; -}; - -class ControlList : public wxDialog -{ -public: - - ControlList( wxWindow* const parent, ControllerInterface::ControlReference* const ref, ControlChooser* const chooser ); - -private: - ControlChooser* const m_control_chooser; -}; - class GamepadPage; class ControlDialog : public wxDialog @@ -125,16 +95,31 @@ class ControlDialog : public wxDialog public: ControlDialog(GamepadPage* const parent, InputPlugin& plugin, ControllerInterface::ControlReference* const ref); - void SelectControl( wxCommandEvent& event ); - void DetectControl( wxCommandEvent& event ); - void ClearControl( wxCommandEvent& event ); - void SetControl( wxCommandEvent& event ); - void SetDevice( wxCommandEvent& event ); + wxStaticBoxSizer* CreateControlChooser(wxWindow* const parent, wxWindow* const eventsink ); + + void DetectControl(wxCommandEvent& event); + void ClearControl(wxCommandEvent& event); + void SetControl(wxCommandEvent& event); + void SetDevice(wxCommandEvent& event); + + void UpdateGUI(); + void UpdateListContents(); + void SelectControl(const std::string& name); + + void AppendControl(wxCommandEvent& event); ControllerInterface::ControlReference* const control_reference; InputPlugin& m_plugin; wxComboBox* device_cbox; - ControlChooser* control_chooser; + + wxTextCtrl* textctrl; + wxListBox* control_lbox; + wxSlider* range_slider; + +private: + GamepadPage* const m_parent; + wxStaticText* m_bound_label; + ControllerInterface::DeviceQualifier m_devq; }; class ExtensionButton : public wxButton @@ -180,6 +165,7 @@ class InputConfigDialog; class GamepadPage : public wxNotebookPage { friend class InputConfigDialog; + friend class ControlDialog; public: GamepadPage( wxWindow* parent, InputPlugin& plugin, const unsigned int pad_num, InputConfigDialog* const config_dialog ); @@ -205,6 +191,8 @@ public: void AdjustControlOption( wxCommandEvent& event ); void AdjustSetting( wxCommandEvent& event ); + void GetProfilePath(std::string& path); + wxComboBox* profile_cbox; wxComboBox* device_cbox; @@ -217,15 +205,16 @@ protected: private: ControlDialog* m_control_dialog; - InputConfigDialog* const m_config_dialog; + InputConfigDialog* const m_config_dialog; InputPlugin &m_plugin; }; class InputConfigDialog : public wxDialog { public: + InputConfigDialog( wxWindow* const parent, InputPlugin& plugin, const std::string& name); + //~InputConfigDialog(); - InputConfigDialog(wxWindow* const parent, InputPlugin& plugin, const std::string& name); bool Destroy(); void ClickSave( wxCommandEvent& event ); diff --git a/Source/Dolphin.sln b/Source/Dolphin.sln index 746d3579fe..da93d658cf 100644 --- a/Source/Dolphin.sln +++ b/Source/Dolphin.sln @@ -105,6 +105,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Plugin_Wiimote", "Plugins\P EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "InputCommon", "Core\InputCommon\InputCommon.vcproj", "{C7E5D50A-2916-464B-86A7-E10B3CC88ADA}" + ProjectSection(ProjectDependencies) = postProject + {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} = {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} + EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AudioCommon", "Core\AudioCommon\AudioCommon.vcproj", "{FBAFB369-07EB-4460-9CAD-08BE5789DAB6}" EndProject @@ -197,6 +200,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Plugin_WiimoteNew", "Plugin EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "InputUICommon", "Core\InputUICommon\InputUICommon.vcproj", "{374E2DB7-42DF-4E59-8474-62B6687F4978}" + ProjectSection(ProjectDependencies) = postProject + {C7E5D50A-2916-464B-86A7-E10B3CC88ADA} = {C7E5D50A-2916-464B-86A7-E10B3CC88ADA} + EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Plugin_VideoDX11", "Plugins\Plugin_VideoDX11\Plugin_VideoDX11.vcproj", "{21DBE606-2958-43AC-A14E-B6B798D56554}" ProjectSection(ProjectDependencies) = postProject