(cleanup) InputPluginCommon is dead. Long live InputCommon and InputUICommon.

I hope I didn't break the mac+linux builds - if i did, fixing it should be a simple matter of adjusting the sconscripts.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5661 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard
2010-06-12 17:39:33 +00:00
parent 3e3aa2364e
commit 1cd25e2406
15 changed files with 484 additions and 498 deletions

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Version="9,00"
Name="InputCommon"
ProjectGUID="{C7E5D50A-2916-464B-86A7-E10B3CC88ADA}"
RootNamespace="VideoCommon"
@ -480,6 +480,14 @@
RelativePath=".\Src\Configuration.cpp"
>
</File>
<File
RelativePath=".\Src\ControllerEmu.cpp"
>
</File>
<File
RelativePath=".\Src\ControllerEmu.h"
>
</File>
<File
RelativePath=".\Src\DirectInputBase.cpp"
>
@ -508,6 +516,14 @@
RelativePath=".\Src\InputCommon.h"
>
</File>
<File
RelativePath=".\Src\InputConfig.cpp"
>
</File>
<File
RelativePath=".\Src\InputConfig.h"
>
</File>
<File
RelativePath=".\Src\SDL_Util.cpp"
>

View File

@ -0,0 +1,375 @@
// Copyright (C) 2010 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "ControllerEmu.h"
#if defined(HAVE_X11) && HAVE_X11
#include <X11/Xlib.h>
#endif
ControllerEmu::~ControllerEmu()
{
// control groups
std::vector<ControlGroup*>::const_iterator
i = groups.begin(),
e = groups.end();
for ( ; i!=e; ++i )
delete *i;
}
ControllerEmu::ControlGroup::~ControlGroup()
{
// controls
std::vector<Control*>::const_iterator
ci = controls.begin(),
ce = controls.end();
for ( ; ci!=ce; ++ci )
delete *ci;
// settings
std::vector<Setting*>::const_iterator
si = settings.begin(),
se = settings.end();
for ( ; si!=se; ++si )
delete *si;
}
ControllerEmu::Extension::~Extension()
{
// attachments
std::vector<ControllerEmu*>::const_iterator
ai = attachments.begin(),
ae = attachments.end();
for ( ; ai!=ae; ++ai )
delete *ai;
}
ControllerEmu::ControlGroup::Control::~Control()
{
delete control_ref;
}
void ControllerEmu::UpdateReferences( ControllerInterface& devi )
{
std::vector<ControlGroup*>::const_iterator
i = groups.begin(),
e = groups.end();
for ( ; i!=e; ++i )
{
std::vector<ControlGroup::Control*>::const_iterator
ci = (*i)->controls.begin(),
ce = (*i)->controls.end();
for ( ; ci!=ce; ++ci )
devi.UpdateReference( (*ci)->control_ref );
// extension
if ( GROUP_TYPE_EXTENSION == (*i)->type )
{
std::vector<ControllerEmu*>::const_iterator
ai = ((Extension*)*i)->attachments.begin(),
ae = ((Extension*)*i)->attachments.end();
for ( ; ai!=ae; ++ai )
(*ai)->UpdateReferences( devi );
}
}
}
void ControllerEmu::UpdateDefaultDevice()
{
std::vector<ControlGroup*>::const_iterator
i = groups.begin(),
e = groups.end();
for ( ; i!=e; ++i )
{
std::vector<ControlGroup::Control*>::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 )
{
std::vector<ControllerEmu*>::const_iterator
ai = ((Extension*)*i)->attachments.begin(),
ae = ((Extension*)*i)->attachments.end();
for ( ; ai!=ae; ++ai )
{
(*ai)->default_device = default_device;
(*ai)->UpdateDefaultDevice();
}
}
}
}
void ControllerEmu::ControlGroup::LoadConfig(IniFile::Section *sec, const std::string& defdev, const std::string& base )
{
std::string group( base + name ); group += "/";
// settings
std::vector<ControlGroup::Setting*>::const_iterator
si = settings.begin(),
se = settings.end();
for ( ; si!=se; ++si )
{
sec->Get((group+(*si)->name).c_str(), &(*si)->value, (*si)->default_value*100);
(*si)->value /= 100;
}
// controls
std::vector<ControlGroup::Control*>::const_iterator
ci = controls.begin(),
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);
// 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
if ( GROUP_TYPE_EXTENSION == type )
{
Extension* const ex = ((Extension*)this);
ex->switch_extension = 0;
unsigned int n = 0;
std::string extname;
sec->Get((base + name).c_str(), &extname, "");
std::vector<ControllerEmu*>::const_iterator
ai = ((Extension*)this)->attachments.begin(),
ae = ((Extension*)this)->attachments.end();
for ( ; ai!=ae; ++ai,++n )
{
(*ai)->default_device.FromString( defdev );
(*ai)->LoadConfig( sec, base + (*ai)->GetName() + "/" );
if ( (*ai)->GetName() == extname )
ex->switch_extension = n;
}
}
}
void ControllerEmu::LoadConfig( IniFile::Section *sec, const std::string& base )
{
std::string defdev = default_device.ToString();
if (base.empty())
{
sec->Get((base + "Device").c_str(), &defdev, "");
default_device.FromString(defdev);
}
std::vector<ControlGroup*>::const_iterator i = groups.begin(),
e = groups.end();
for ( ; i!=e; ++i )
(*i)->LoadConfig(sec, defdev, base);
}
void ControllerEmu::ControlGroup::SaveConfig( IniFile::Section *sec, const std::string& defdev, const std::string& base )
{
std::string group( base + name ); group += "/";
// settings
std::vector<ControlGroup::Setting*>::const_iterator
si = settings.begin(),
se = settings.end();
for ( ; si!=se; ++si )
sec->Set( (group+(*si)->name).c_str(), (*si)->value*100.0f, (*si)->default_value*100.0f);
// controls
std::vector<ControlGroup::Control*>::const_iterator
ci = controls.begin(),
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);
// 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
if ( GROUP_TYPE_EXTENSION == type )
{
Extension* const ext = ((Extension*)this);
sec->Set((base + name).c_str(), ext->attachments[ext->switch_extension]->GetName(), "None");
std::vector<ControllerEmu*>::const_iterator
ai = ((Extension*)this)->attachments.begin(),
ae = ((Extension*)this)->attachments.end();
for ( ; ai!=ae; ++ai )
(*ai)->SaveConfig( sec, base + (*ai)->GetName() + "/" );
}
}
void ControllerEmu::SaveConfig( IniFile::Section *sec, const std::string& base )
{
const std::string defdev = default_device.ToString();
if ( base.empty() )
sec->Set( (/*std::string(" ") +*/ base + "Device").c_str(), defdev, "");
std::vector<ControlGroup*>::const_iterator i = groups.begin(),
e = groups.end();
for ( ; i!=e; ++i )
(*i)->SaveConfig( sec, defdev, base );
}
ControllerEmu::AnalogStick::AnalogStick( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_STICK )
{
for ( unsigned int i = 0; i < 4; ++i )
controls.push_back( new Input( named_directions[i] ) );
controls.push_back( new Input( "Modifier" ) );
settings.push_back( new Setting("Dead Zone", 0, 0, 50 ) );
settings.push_back( new Setting("Square Stick", 0 ) );
}
ControllerEmu::Buttons::Buttons( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_BUTTONS )
{
settings.push_back( new Setting("Threshold", 0.5f ) );
}
ControllerEmu::MixedTriggers::MixedTriggers( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_MIXED_TRIGGERS )
{
settings.push_back( new Setting("Threshold", 0.9f ) );
}
ControllerEmu::Triggers::Triggers( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_TRIGGERS )
{
settings.push_back( new Setting("Dead Zone", 0, 0, 50 ) );
}
ControllerEmu::Force::Force( const char* const _name ) : ControlGroup( _name, GROUP_TYPE_FORCE )
{
controls.push_back( new Input( "Up" ) );
controls.push_back( new Input( "Down" ) );
controls.push_back( new Input( "Left" ) );
controls.push_back( new Input( "Right" ) );
controls.push_back( new Input( "Forward" ) );
controls.push_back( new Input( "Backward" ) );
controls.push_back( new Input( "Modifier" ) );
settings.push_back( new Setting("Dead Zone", 0, 0, 50 ) );
}
ControllerEmu::Tilt::Tilt( const char* const _name )
: ControlGroup( _name, GROUP_TYPE_TILT )
{
memset(m_tilt, 0, sizeof(m_tilt));
//for ( unsigned int i = 0; i < 4; ++i )
//controls.push_back( new Input( named_directions[i] ) );
controls.push_back( new Input( "Forward" ) );
controls.push_back( new Input( "Backward" ) );
controls.push_back( new Input( "Left" ) );
controls.push_back( new Input( "Right" ) );
controls.push_back( new Input( "Modifier" ) );
settings.push_back( new Setting("Dead Zone", 0, 0, 50 ) );
settings.push_back( new Setting("Circle Stick", 0 ) );
}
ControllerEmu::Cursor::Cursor( const char* const _name, const SWiimoteInitialize* const _wiimote_initialize )
: ControlGroup( _name, GROUP_TYPE_CURSOR )
, wiimote_initialize(_wiimote_initialize)
, m_z(0)
{
for ( unsigned int i = 0; i < 4; ++i )
controls.push_back( new Input( named_directions[i] ) );
controls.push_back( new Input( "Forward" ) );
controls.push_back( new Input( "Backward" ) );
controls.push_back( new Input( "Hide" ) );
settings.push_back( new Setting("Center", 0.5f ) );
settings.push_back( new Setting("Width", 0.5f ) );
settings.push_back( new Setting("Height", 0.5f ) );
}
void GetMousePos(float& x, float& y, const SWiimoteInitialize* const wiimote_initialize)
{
#if ( defined(_WIN32) || (defined(HAVE_X11) && HAVE_X11))
unsigned int win_width = 2, win_height = 2;
#endif
#ifdef _WIN32
// Get the cursor position for the entire screen
POINT point = { 1, 1 };
GetCursorPos(&point);
// Get the cursor position relative to the upper left corner of the rendering window
ScreenToClient(wiimote_initialize->hWnd, &point);
// Get the size of the rendering window. (In my case Rect.top and Rect.left was zero.)
RECT Rect;
GetClientRect(wiimote_initialize->hWnd, &Rect);
// Width and height is the size of the rendering window
win_width = Rect.right - Rect.left;
win_height = Rect.bottom - Rect.top;
#elif defined(HAVE_X11) && HAVE_X11
int root_x, root_y;
struct
{
int x, y;
} point = { 1, 1 };
Display* const wm_display = (Display*)wiimote_initialize->hWnd;
Window glwin = *(Window *)wiimote_initialize->pXWindow;
XWindowAttributes win_attribs;
XGetWindowAttributes (wm_display, glwin, &win_attribs);
win_width = win_attribs.width;
win_height = win_attribs.height;
Window root_dummy, child_win;
unsigned int mask;
XQueryPointer(wm_display, glwin, &root_dummy, &child_win, &root_x, &root_y, &point.x, &point.y, &mask);
#endif
#if ( defined(_WIN32) || (defined(HAVE_X11) && HAVE_X11))
// Return the mouse position as a range from -1 to 1
x = (float)point.x / (float)win_width * 2 - 1;
y = (float)point.y / (float)win_height * 2 - 1;
#else
x = 0;
y = 0;
#endif
}

View File

@ -0,0 +1,438 @@
// Copyright (C) 2010 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _CONTROLLEREMU_H_
#define _CONTROLLEREMU_H_
// windows crap
#define NOMINMAX
#include "pluginspecs_pad.h"
#include "pluginspecs_wiimote.h"
#include <math.h>
#include "ControllerInterface/ControllerInterface.h"
#include "IniFile.h"
#include <vector>
#include <string>
#include <algorithm>
#define sign(x) ((x)?(x)<0?-1:1:0)
enum
{
GROUP_TYPE_OTHER,
GROUP_TYPE_STICK,
GROUP_TYPE_MIXED_TRIGGERS,
GROUP_TYPE_BUTTONS,
GROUP_TYPE_FORCE,
GROUP_TYPE_EXTENSION,
GROUP_TYPE_TILT,
GROUP_TYPE_CURSOR,
GROUP_TYPE_TRIGGERS,
};
const char * const named_directions[] =
{
"Up",
"Down",
"Left",
"Right"
};
void GetMousePos(float& x, float& y, const SWiimoteInitialize* const wiimote_initialize);
class ControllerEmu
{
public:
class ControlGroup
{
public:
class Control
{
protected:
Control( ControllerInterface::ControlReference* const _ref, const char * const _name )
: control_ref(_ref), name(_name){}
public:
virtual ~Control();
ControllerInterface::ControlReference* const control_ref;
const char * const name;
};
class Input : public Control
{
public:
Input( const char * const _name )
: Control( new ControllerInterface::InputReference, _name ) {}
};
class Output : public Control
{
public:
Output( const char * const _name )
: Control( new ControllerInterface::OutputReference, _name ) {}
};
class Setting
{
public:
Setting(const char* const _name, const ControlState def_value
, const unsigned int _low = 0, const unsigned int _high = 100 )
: name(_name)
, value(def_value)
, default_value(def_value)
, low(_low)
, high(_high){}
const char* const name;
ControlState value;
const ControlState default_value;
const unsigned int low, high;
};
ControlGroup( const char* const _name, const unsigned int _type = GROUP_TYPE_OTHER ) : name(_name), type(_type) {}
virtual ~ControlGroup();
void LoadConfig(IniFile::Section *sec, const std::string& defdev = "", const std::string& base = "" );
void SaveConfig(IniFile::Section *sec, const std::string& defdev = "", const std::string& base = "" );
const char* const name;
const unsigned int type;
std::vector< Control* > controls;
std::vector< Setting* > settings;
};
class AnalogStick : public ControlGroup
{
public:
template <typename C>
void GetState( C* const x, C* const y, const unsigned int base, const unsigned int range )
{
// this is all a mess
ControlState yy = controls[0]->control_ref->State() - controls[1]->control_ref->State();
ControlState xx = controls[3]->control_ref->State() - controls[2]->control_ref->State();
ControlState deadzone = settings[0]->value;
ControlState square = settings[1]->value;
ControlState m = controls[4]->control_ref->State();
// modifier code
if ( m )
{
yy = (abs(yy)>deadzone) * sign(yy) * (m + deadzone/2);
xx = (abs(xx)>deadzone) * sign(xx) * (m + deadzone/2);
}
// deadzone / square stick code
if ( deadzone || square )
{
// this section might be all wrong, but its working good enough, i think
ControlState ang = atan2( yy, xx );
ControlState ang_sin = sin(ang);
ControlState ang_cos = cos(ang);
// the amt a full square stick would have at current angle
ControlState square_full = std::min( ang_sin ? 1/abs(ang_sin) : 2, ang_cos ? 1/abs(ang_cos) : 2 );
// the amt a full stick would have that was ( user setting squareness) at current angle
// i think this is more like a pointed circle rather than a rounded square like it should be
ControlState stick_full = ( 1 + ( square_full - 1 ) * square );
ControlState dist = sqrt(xx*xx + yy*yy);
// dead zone code
dist = std::max( 0.0f, dist - deadzone * stick_full );
dist /= ( 1 - deadzone );
// square stick code
ControlState amt = dist / stick_full;
dist -= ((square_full - 1) * amt * square);
yy = std::max( -1.0f, std::min( 1.0f, ang_sin * dist ) );
xx = std::max( -1.0f, std::min( 1.0f, ang_cos * dist ) );
}
*y = C( yy * range + base );
*x = C( xx * range + base );
}
AnalogStick( const char* const _name );
};
class Buttons : public ControlGroup
{
public:
Buttons( const char* const _name );
template <typename C>
void GetState( C* const buttons, const C* bitmasks )
{
std::vector<Control*>::iterator i = controls.begin(),
e = controls.end();
for ( ; i!=e; ++i, ++bitmasks )
if ( (*i)->control_ref->State() > settings[0]->value ) // threshold
*buttons |= *bitmasks;
}
};
class MixedTriggers : public ControlGroup
{
public:
template <typename C, typename S>
void GetState( C* const digital, const C* bitmasks, S* analog, const unsigned int range )
{
const unsigned int trig_count = ((unsigned int) (controls.size() / 2));
for ( unsigned int i=0; i<trig_count; ++i,++bitmasks,++analog )
{
if ( controls[i]->control_ref->State() > settings[0]->value ) //threshold
{
*analog = range;
*digital |= *bitmasks;
}
else
*analog = S(controls[i+trig_count]->control_ref->State() * range);
}
}
MixedTriggers( const char* const _name );
};
class Triggers : public ControlGroup
{
public:
template <typename S>
void GetState( S* analog, const unsigned int range )
{
const unsigned int trig_count = ((unsigned int) (controls.size()));
const ControlState deadzone = settings[0]->value;
for ( unsigned int i=0; i<trig_count; ++i,++analog )
*analog = S( std::max(controls[i]->control_ref->State() - deadzone, 0.0f) / (1 - deadzone) * range );
}
Triggers( const char* const _name );
};
class Force : public ControlGroup
{
public:
Force( const char* const _name );
template <typename C, typename R>
void GetState( C* axis, const u8 base, const R range )
{
const float deadzone = settings[0]->value;
for ( unsigned int i=0; i<6; i+=2 )
{
const float state = controls[i+1]->control_ref->State() - controls[i]->control_ref->State();
if (abs(state) > deadzone)
*axis++ = (C)((state - (deadzone * sign(state))) / (1 - deadzone) * range + base);
//*axis++ = state * range + base;
else
*axis++ = (C)(base);
}
}
};
class Tilt : public ControlGroup
{
public:
Tilt( const char* const _name );
template <typename C, typename R>
void GetState( C* const x, C* const y, const unsigned int base, const R range )
{
// this is all a mess
ControlState yy = controls[0]->control_ref->State() - controls[1]->control_ref->State();
ControlState xx = controls[3]->control_ref->State() - controls[2]->control_ref->State();
ControlState deadzone = settings[0]->value;
ControlState circle = settings[1]->value;
ControlState m = controls[4]->control_ref->State();
// modifier code
if ( m )
{
yy = (abs(yy)>deadzone) * sign(yy) * (m + deadzone/2);
xx = (abs(xx)>deadzone) * sign(xx) * (m + deadzone/2);
}
// deadzone / circle stick code
if ( deadzone || circle )
{
// this section might be all wrong, but its working good enough, i think
ControlState ang = atan2( yy, xx );
ControlState ang_sin = sin(ang);
ControlState ang_cos = cos(ang);
// the amt a full square stick would have at current angle
ControlState square_full = std::min( ang_sin ? 1/abs(ang_sin) : 2, ang_cos ? 1/abs(ang_cos) : 2 );
// the amt a full stick would have that was ( user setting circular ) at current angle
// i think this is more like a pointed circle rather than a rounded square like it should be
ControlState stick_full = (square_full * (1 - circle)) + (circle);
ControlState dist = sqrt(xx*xx + yy*yy);
// dead zone code
dist = std::max( 0.0f, dist - deadzone * stick_full );
dist /= (1 - deadzone);
// circle stick code
ControlState amt = dist / stick_full;
dist += (square_full - 1) * amt * circle;
yy = std::max( -1.0f, std::min( 1.0f, ang_sin * dist ) );
xx = std::max( -1.0f, std::min( 1.0f, ang_cos * dist ) );
}
// this is kinda silly here
// gui being open will make this happen 2x as fast, o well
if (xx > m_tilt[0])
m_tilt[0] = std::min(m_tilt[0] + 0.1f, xx);
else if (xx < m_tilt[0])
m_tilt[0] = std::max(m_tilt[0] - 0.1f, xx);
if (yy > m_tilt[1])
m_tilt[1] = std::min(m_tilt[1] + 0.1f, yy);
else if (yy < m_tilt[1])
m_tilt[1] = std::max(m_tilt[1] - 0.1f, yy);
*y = C( m_tilt[1] * range + base );
*x = C( m_tilt[0] * range + base );
}
private:
float m_tilt[2];
};
class Cursor : public ControlGroup
{
public:
Cursor( const char* const _name, const SWiimoteInitialize* const _wiimote_initialize );
template <typename C>
void GetState( C* const x, C* const y, C* const z, const bool adjusted = false )
{
const float zz = controls[4]->control_ref->State() - controls[5]->control_ref->State();
// silly being here
if (zz > m_z)
m_z = std::min(m_z + 0.1f, zz);
else if (zz < m_z)
m_z = std::max(m_z - 0.1f, zz);
*z = m_z;
// hide
if (controls[6]->control_ref->State() > 0.5f)
{
*x = 10000; *y = 0;
}
else
{
float xx, yy;
GetMousePos(xx, yy, wiimote_initialize);
// 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() )
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() )
xx = controls[3]->control_ref->State() - controls[2]->control_ref->State();
// adjust cursor according to settings
if (adjusted)
{
xx *= ( settings[1]->value * 2 );
yy *= ( settings[2]->value * 2 );
yy += ( settings[0]->value - 0.5f );
}
*x = xx;
*y = yy;
}
}
private:
const SWiimoteInitialize* const wiimote_initialize;
float m_z;
};
class Extension : public ControlGroup
{
public:
Extension( const char* const _name )
: ControlGroup( _name, GROUP_TYPE_EXTENSION )
, switch_extension(0)
, active_extension(0) {}
~Extension();
void GetState( u8* const data, const bool focus = true );
std::vector<ControllerEmu*> attachments;
int switch_extension;
int active_extension;
};
virtual ~ControllerEmu();
virtual std::string GetName() const = 0;
virtual void LoadDefaults() {}
void LoadConfig(IniFile::Section *sec, const std::string& base = "");
void SaveConfig(IniFile::Section *sec, const std::string& base = "");
void UpdateDefaultDevice();
void UpdateReferences( ControllerInterface& devi );
std::vector< ControlGroup* > groups;
ControllerInterface::DeviceQualifier default_device;
};
#endif

View File

@ -0,0 +1,69 @@
// Copyright (C) 2010 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "InputConfig.h"
Plugin::Plugin( const char* const _ini_name, const char* const _gui_name, const char* const _profile_name )
: ini_name(_ini_name)
, gui_name(_gui_name)
, profile_name(_profile_name)
{
// GCPads
//for ( unsigned int i = 0; i<4; ++i )
//controllers.push_back( new GCPad( i ) );
// Wiimotes / disabled, cause it only the GUI half is done
//for ( unsigned int i = 0; i<4; ++i )
// controllers.push_back( new Wiimote( i ) );
};
Plugin::~Plugin()
{
// delete pads
std::vector<ControllerEmu*>::const_iterator i = controllers.begin(),
e = controllers.end();
for ( ; i != e; ++i )
delete *i;
}
bool Plugin::LoadConfig()
{
IniFile inifile;
if (false == inifile.Load(std::string(File::GetUserPath(D_CONFIG_IDX)) + ini_name + ".ini"))
return false;
std::vector< ControllerEmu* >::const_iterator
i = controllers.begin(),
e = controllers.end();
for ( ; i!=e; ++i ) {
(*i)->LoadConfig(inifile.GetOrCreateSection((*i)->GetName().c_str()));
}
}
void Plugin::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();
for ( ; i!=e; ++i )
(*i)->SaveConfig(inifile.GetOrCreateSection((*i)->GetName().c_str()));
inifile.Save(ini_filename);
}

View File

@ -0,0 +1,53 @@
// Copyright (C) 2010 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _CONFIG_H_
#define _CONFIG_H_
#include "Thread.h"
#include "FileUtil.h"
#include "IniFile.h"
#include "ControllerInterface/ControllerInterface.h"
#include "ControllerEmu.h"
#include <string>
#include <vector>
#include <map>
#include <sstream>
class Plugin
{
public:
Plugin( const char* const _ini_name, const char* const _gui_name, const char* const _profile_name );
~Plugin();
bool LoadConfig();
void SaveConfig();
std::vector< ControllerEmu* > controllers;
Common::CriticalSection controls_crit, interface_crit; // lock controls first
ControllerInterface controller_interface;
const char * const ini_name;
const char * const gui_name;
const char * const profile_name;
};
#endif

View File

@ -4,8 +4,10 @@ Import('env')
files = [
'Configuration.cpp',
'ControllerEmu.cpp',
'EventHandler.cpp',
'InputCommon.cpp',
'InputConfig.cpp',
'SDL_Util.cpp',
'ControllerInterface/ControllerInterface.cpp',
'ControllerInterface/SDL/SDL.cpp'