Added ResponseCurveAxisFilter, LogAxisFilter and LogButtonFilter

This commit is contained in:
Ingo Ruhnke 2010-12-29 15:53:58 +01:00
parent dfee60d1e5
commit e6b1328174
6 changed files with 164 additions and 6 deletions

2
NEWS
View file

@ -5,7 +5,7 @@ xboxdrv 0.6.2 - (??/???/????)
* added ability to invert buttons
* added ability to send different events depending on how long a
button was pressed
* added generic event filters, replacing --sensitive-axis, --deadzone,
* added generic event filters, which replacing --sensitive-axis, --deadzone,
etc.

6
TODO
View file

@ -27,9 +27,11 @@ $ dput my-ppa xboxdrv_0.6.1_source.changes
Stuff to do before 0.6.1 release:
=================================
* AxisFilter: invert, sensitivy, deadzone, relative-axis
* figure out how to do absolute mouse positioning in Xorg
* ButtonFilter: invert, autofire, toggle
* AxisFilter: invert(*), sensitivy(*), deadzone(*), relative-axis(*)
* ButtonFilter: invert(*), autofire(*), toggle(*)
* Not implementable as they need more then one axis: squareaxis, four-way-restrictor, dpad-rotation

View file

@ -73,6 +73,14 @@ AxisFilter::from_string(const std::string& str)
{
return AxisFilterPtr(RelativeAxisFilter::from_string(rest));
}
else if (filtername == "resp" || filtername == "response" || filtername == "responsecurve")
{
return AxisFilterPtr(ResponseCurveAxisFilter::from_string(rest));
}
else if (filtername == "log")
{
return AxisFilterPtr(LogAxisFilter::from_string(rest));
}
else
{
std::ostringstream out;
@ -295,5 +303,78 @@ RelativeAxisFilter::filter(int value, int min, int max)
return m_state;
}
ResponseCurveAxisFilter*
ResponseCurveAxisFilter::from_string(const std::string& str)
{
std::vector<int> samples;
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
tokenizer tokens(str, boost::char_separator<char>(":", "", boost::keep_empty_tokens));
int idx = 0;
for(tokenizer::iterator t = tokens.begin(); t != tokens.end(); ++t, ++idx)
{
samples.push_back(boost::lexical_cast<int>(*t));
}
return new ResponseCurveAxisFilter(samples);
}
ResponseCurveAxisFilter::ResponseCurveAxisFilter(const std::vector<int>& samples) :
m_samples(samples)
{
}
int
ResponseCurveAxisFilter::filter(int value, int min, int max)
{
if (m_samples.empty())
{
return value;
}
else if (m_samples.size() == 1)
{
return m_samples[0];
}
else
{
// FIXME: should rewrite this to use integer only and make sure
// that the edge conditions are meet
int bucket_count = m_samples.size() - 1;
float bucket_size = (max - min) / static_cast<float>(bucket_count);
int bucket_index = int((value - min) / bucket_size);
float t = ((value - min) - (static_cast<float>(bucket_index) * bucket_size)) / bucket_size;
return ((1.0f - t) * m_samples[bucket_index]) + (t * m_samples[bucket_index + 1]);
}
}
LogAxisFilter*
LogAxisFilter::from_string(const std::string& str)
{
return new LogAxisFilter(str);
}
LogAxisFilter::LogAxisFilter(const std::string& name) :
m_name(name)
{
}
int
LogAxisFilter::filter(int value, int min, int max)
{
if (m_name.empty())
{
std::cout << value << std::endl;
}
else
{
std::cout << m_name << ": " << value << std::endl;
}
return value;
}
/* EOF */

View file

@ -19,8 +19,9 @@
#ifndef HEADER_XBOXDRV_AXIS_FILTER_HPP
#define HEADER_XBOXDRV_AXIS_FILTER_HPP
#include <string>
#include <boost/shared_ptr.hpp>
#include <string>
#include <vector>
class AxisFilter;
@ -113,6 +114,34 @@ private:
int m_max;
};
class ResponseCurveAxisFilter : public AxisFilter
{
public:
static ResponseCurveAxisFilter* from_string(const std::string& str);
public:
ResponseCurveAxisFilter(const std::vector<int>& samples);
int filter(int value, int min, int max);
private:
std::vector<int> m_samples;
};
class LogAxisFilter : public AxisFilter
{
public:
static LogAxisFilter* from_string(const std::string& str);
public:
LogAxisFilter(const std::string& name);
int filter(int value, int min, int max);
private:
std::string m_name;
};
#endif
/* EOF */

View file

@ -18,6 +18,7 @@
#include "button_filter.hpp"
#include <iostream>
#include <sstream>
#include <boost/tokenizer.hpp>
#include <boost/lexical_cast.hpp>
@ -30,7 +31,7 @@ ButtonFilter::from_string(const std::string& str)
std::string rest;
if (p != std::string::npos)
rest = str.substr(p);
rest = str.substr(p+1);
if (filtername == "toggle")
{
@ -44,6 +45,10 @@ ButtonFilter::from_string(const std::string& str)
{
return ButtonFilterPtr(AutofireButtonFilter::from_string(rest));
}
else if (filtername == "log")
{
return ButtonFilterPtr(LogButtonFilter::from_string(rest));
}
else
{
std::ostringstream out;
@ -135,4 +140,30 @@ AutofireButtonFilter::filter(bool value)
}
}
LogButtonFilter*
LogButtonFilter::from_string(const std::string& str)
{
return new LogButtonFilter(str);
}
LogButtonFilter::LogButtonFilter(const std::string& name) :
m_name(name)
{
}
bool
LogButtonFilter::filter(bool value)
{
if (m_name.empty())
{
std::cout << value << std::endl;
}
else
{
std::cout << m_name << ": " << value << std::endl;
}
return value;
}
/* EOF */

View file

@ -20,6 +20,7 @@
#define HEADER_XBOXDRV_BUTTON_FILTER_HPP
#include <boost/shared_ptr.hpp>
#include <string>
class ButtonFilter;
@ -35,7 +36,7 @@ public:
virtual ~ButtonFilter() {}
virtual bool filter(bool value) =0;
virtual void update(int msec_delta) =0;
virtual void update(int msec_delta) {}
};
class ToggleButtonFilter : public ButtonFilter
@ -78,6 +79,20 @@ private:
int m_counter;
};
class LogButtonFilter : public ButtonFilter
{
public:
static LogButtonFilter* from_string(const std::string& str);
public:
LogButtonFilter(const std::string& name);
bool filter(bool value);
private:
std::string m_name;
};
#endif
/* EOF */