- added Melchior's patches to allow a joystick axis to act as a pair
of buttons (by adding "high" or "low" to the path before "binding")
This commit is contained in:
parent
6814f9966b
commit
4d96e62a10
2 changed files with 90 additions and 37 deletions
|
@ -592,25 +592,25 @@ FGInput::_init_joystick ()
|
||||||
center[j] = axis_node->getDoubleValue("center", center[j]);
|
center[j] = axis_node->getDoubleValue("center", center[j]);
|
||||||
|
|
||||||
_read_bindings(axis_node, a.bindings, FG_MOD_NONE);
|
_read_bindings(axis_node, a.bindings, FG_MOD_NONE);
|
||||||
|
|
||||||
|
// Initialize the virtual axis buttons.
|
||||||
|
_init_button(axis_node->getChild("low"), a.low, "low");
|
||||||
|
a.low_threshold = axis_node->getDoubleValue("low-threshold", -0.9);
|
||||||
|
|
||||||
|
_init_button(axis_node->getChild("high"), a.high, "high");
|
||||||
|
a.high_threshold = axis_node->getDoubleValue("high-threshold", 0.9);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Initialize the buttons.
|
// Initialize the buttons.
|
||||||
//
|
//
|
||||||
|
char buf[8];
|
||||||
for (j = 0; j < nbuttons; j++) {
|
for (j = 0; j < nbuttons; j++) {
|
||||||
const SGPropertyNode * button_node = js_node->getChild("button", j);
|
sprintf(buf, "%d", j);
|
||||||
if (button_node == 0) {
|
_init_button(js_node->getChild("button", j),
|
||||||
SG_LOG(SG_INPUT, SG_INFO, "No bindings for button " << j);
|
_joystick_bindings[i].buttons[j],
|
||||||
continue;
|
buf);
|
||||||
}
|
|
||||||
|
|
||||||
button &b = _joystick_bindings[i].buttons[j];
|
|
||||||
|
|
||||||
b.is_repeatable =
|
|
||||||
button_node->getBoolValue("repeatable", b.is_repeatable);
|
|
||||||
|
|
||||||
// Get the bindings for the button
|
|
||||||
_read_bindings(button_node, b.bindings, FG_MOD_NONE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
js->setMinRange(minRange);
|
js->setMinRange(minRange);
|
||||||
|
@ -620,6 +620,23 @@ FGInput::_init_joystick ()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void
|
||||||
|
FGInput::_init_button (const SGPropertyNode * node,
|
||||||
|
button &b,
|
||||||
|
const string name)
|
||||||
|
{
|
||||||
|
if (node == 0)
|
||||||
|
SG_LOG(SG_INPUT, SG_INFO, "No bindings for button " << name);
|
||||||
|
else {
|
||||||
|
_read_bindings(node, b.bindings, FG_MOD_NONE);
|
||||||
|
b.is_repeatable = node->getBoolValue("repeatable", b.is_repeatable);
|
||||||
|
|
||||||
|
// Get the bindings for the button
|
||||||
|
_read_bindings(node, b.bindings, FG_MOD_NONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
FGInput::_update_keyboard ()
|
FGInput::_update_keyboard ()
|
||||||
{
|
{
|
||||||
|
@ -663,34 +680,50 @@ FGInput::_update_joystick ()
|
||||||
for (unsigned int k = 0; k < a.bindings[modifiers].size(); k++)
|
for (unsigned int k = 0; k < a.bindings[modifiers].size(); k++)
|
||||||
a.bindings[modifiers][k].fire(axis_values[j]);
|
a.bindings[modifiers][k].fire(axis_values[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// do we have to emulate axis buttons?
|
||||||
|
if (a.low.bindings[modifiers].size())
|
||||||
|
_update_button(_joystick_bindings[i].axes[j].low,
|
||||||
|
modifiers,
|
||||||
|
axis_values[j] < a.low_threshold);
|
||||||
|
|
||||||
|
if (a.high.bindings[modifiers].size())
|
||||||
|
_update_button(_joystick_bindings[i].axes[j].high,
|
||||||
|
modifiers,
|
||||||
|
axis_values[j] > a.high_threshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fire bindings for the buttons.
|
// Fire bindings for the buttons.
|
||||||
for (j = 0; j < _joystick_bindings[i].nbuttons; j++) {
|
for (j = 0; j < _joystick_bindings[i].nbuttons; j++)
|
||||||
bool pressed = ((buttons & (1 << j)) > 0);
|
_update_button(_joystick_bindings[i].buttons[j],
|
||||||
button &b = _joystick_bindings[i].buttons[j];
|
modifiers,
|
||||||
|
(buttons & (1 << j)) > 0);
|
||||||
if (pressed) {
|
|
||||||
// The press event may be repeated.
|
|
||||||
if (!b.last_state || b.is_repeatable) {
|
|
||||||
// SG_LOG(SG_INPUT, SG_INFO, "Button " << j << " has been pressed");
|
|
||||||
for (unsigned int k = 0; k < b.bindings[modifiers].size(); k++)
|
|
||||||
b.bindings[modifiers][k].fire();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// The release event is never repeated.
|
|
||||||
if (b.last_state)
|
|
||||||
// SG_LOG(SG_INPUT, SG_INFO, "Button " << j << " has been released");
|
|
||||||
for (unsigned int k = 0; k < b.bindings[modifiers|FG_MOD_UP].size(); k++)
|
|
||||||
b.bindings[modifiers|FG_MOD_UP][k].fire();
|
|
||||||
}
|
|
||||||
|
|
||||||
b.last_state = pressed;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void
|
||||||
|
FGInput::_update_button (button &b, int modifiers, bool pressed)
|
||||||
|
{
|
||||||
|
if (pressed) {
|
||||||
|
// The press event may be repeated.
|
||||||
|
if (!b.last_state || b.is_repeatable) {
|
||||||
|
// SG_LOG(SG_INPUT, SG_INFO, "Button " << j << " has been pressed");
|
||||||
|
for (unsigned int k = 0; k < b.bindings[modifiers].size(); k++)
|
||||||
|
b.bindings[modifiers][k].fire();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// The release event is never repeated.
|
||||||
|
if (b.last_state)
|
||||||
|
// SG_LOG(SG_INPUT, SG_INFO, "Button " << j << " has been released");
|
||||||
|
for (unsigned int k = 0; k < b.bindings[modifiers|FG_MOD_UP].size(); k++)
|
||||||
|
b.bindings[modifiers|FG_MOD_UP][k].fire();
|
||||||
|
}
|
||||||
|
|
||||||
|
b.last_state = pressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
FGInput::_read_bindings (const SGPropertyNode * node,
|
FGInput::_read_bindings (const SGPropertyNode * node,
|
||||||
binding_list_t * binding_list,
|
binding_list_t * binding_list,
|
||||||
|
|
|
@ -184,8 +184,6 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
typedef vector<FGBinding> binding_list_t;
|
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -201,6 +199,8 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef vector<FGBinding> binding_list_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Settings for a key or button.
|
* Settings for a key or button.
|
||||||
*/
|
*/
|
||||||
|
@ -221,11 +221,17 @@ private:
|
||||||
struct axis {
|
struct axis {
|
||||||
axis ()
|
axis ()
|
||||||
: last_value(9999999),
|
: last_value(9999999),
|
||||||
tolerance(0.002)
|
tolerance(0.002),
|
||||||
|
low_threshold(-0.9),
|
||||||
|
high_threshold(0.9)
|
||||||
{}
|
{}
|
||||||
float last_value;
|
float last_value;
|
||||||
float tolerance;
|
float tolerance;
|
||||||
binding_list_t bindings[FG_MOD_MAX];
|
binding_list_t bindings[FG_MOD_MAX];
|
||||||
|
float low_threshold;
|
||||||
|
float high_threshold;
|
||||||
|
struct button low;
|
||||||
|
struct button high;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -258,6 +264,14 @@ private:
|
||||||
void _init_joystick ();
|
void _init_joystick ();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a single button.
|
||||||
|
*/
|
||||||
|
inline void _init_button (const SGPropertyNode * node,
|
||||||
|
button &b,
|
||||||
|
const string name);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the keyboard.
|
* Update the keyboard.
|
||||||
*/
|
*/
|
||||||
|
@ -270,6 +284,12 @@ private:
|
||||||
void _update_joystick ();
|
void _update_joystick ();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a single button.
|
||||||
|
*/
|
||||||
|
inline void _update_button (button &b, int modifiers, bool pressed);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read bindings and modifiers.
|
* Read bindings and modifiers.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue