1
0
Fork 0

Bug #923 : repeatable flag set on input reload.

Clean-up how axes and button bindings are destroyed are re-built on reinit of the FGJoystickInput subsystem, so we get new, cleanly initialised items each time.
This commit is contained in:
James Turner 2012-12-29 12:16:51 +00:00
parent 12076bce0e
commit e9ecf4eb52
3 changed files with 98 additions and 86 deletions

View file

@ -26,7 +26,7 @@
#define FGBUTTON_H
#include "FGCommonInput.hxx"
#include <Main/fg_os.hxx>
#include <Main/fg_os.hxx> // for KEYMOD_MAX
class FGButton : public FGCommonInput {
public:

View file

@ -52,7 +52,6 @@ FGJoystickInput::axis::~axis ()
FGJoystickInput::joystick::joystick ()
: jsnum(0),
js(0),
naxes(0),
nbuttons(0),
axes(0),
@ -61,17 +60,20 @@ FGJoystickInput::joystick::joystick ()
{
}
FGJoystickInput::joystick::~joystick ()
void FGJoystickInput::joystick::clearAxesAndButtons()
{
// delete js? no, since js == this - and we're in the destructor already.
delete[] axes;
delete[] buttons;
jsnum = 0;
js = NULL;
naxes = 0;
nbuttons = 0;
axes = NULL;
buttons = NULL;
naxes = 0;
nbuttons = 0;
}
FGJoystickInput::joystick::~joystick ()
{
jsnum = 0;
clearAxesAndButtons();
}
@ -90,12 +92,13 @@ void FGJoystickInput::_remove(bool all)
for (int i = 0; i < MAX_JOYSTICKS; i++)
{
joystick* joy = &joysticks[i];
// do not remove predefined joysticks info on reinit
if (all || (!bindings[i].predefined))
if (all || (!joy->predefined))
js_nodes->removeChild("js", i, false);
if (bindings[i].js)
delete bindings[i].js;
bindings[i].js = NULL;
joy->plibJS.reset();
joy->clearAxesAndButtons();
}
}
@ -110,7 +113,7 @@ void FGJoystickInput::init()
for (int i = 0; i < MAX_JOYSTICKS; i++) {
jsJoystick * js = new jsJoystick(i);
bindings[i].js = js;
joysticks[i].plibJS.reset(js);
if (js->notWorking()) {
SG_LOG(SG_INPUT, SG_DEBUG, "Joystick " << i << " not found");
@ -124,7 +127,7 @@ void FGJoystickInput::init()
SG_LOG(SG_INPUT, SG_INFO, "Using existing bindings for joystick " << i);
} else {
bindings[i].predefined = false;
joysticks[i].predefined = false;
SG_LOG(SG_INPUT, SG_INFO, "Looking for bindings for joystick \"" << name << '"');
SGPropertyNode_ptr named;
@ -163,7 +166,7 @@ void FGJoystickInput::postinit()
for (int i = 0; i < MAX_JOYSTICKS; i++) {
SGPropertyNode_ptr js_node = js_nodes->getChild("js", i);
jsJoystick *js = bindings[i].js;
jsJoystick *js = joysticks[i].plibJS.get();
if (!js_node || js->notWorking())
continue;
@ -178,8 +181,8 @@ void FGJoystickInput::postinit()
int naxes = js->getNumAxes();
if (naxes > MAX_JOYSTICK_AXES) naxes = MAX_JOYSTICK_AXES;
bindings[i].naxes = naxes;
bindings[i].nbuttons = nbuttons;
joysticks[i].naxes = naxes;
joysticks[i].nbuttons = nbuttons;
SG_LOG(SG_INPUT, SG_DEBUG, "Initializing joystick " << i);
@ -194,8 +197,8 @@ void FGJoystickInput::postinit()
js->getCenter(center);
// Allocate axes and buttons
bindings[i].axes = new axis[naxes];
bindings[i].buttons = new FGButton[nbuttons];
joysticks[i].axes = new axis[naxes];
joysticks[i].buttons = new FGButton[nbuttons];
//
// Initialize nasal groups.
@ -243,7 +246,7 @@ void FGJoystickInput::postinit()
SG_LOG(SG_INPUT, SG_DEBUG, "Dropping bindings for axis " << n_axis);
continue;
}
axis &a = bindings[i].axes[n_axis];
axis &a = joysticks[i].axes[n_axis];
js->setDeadBand(n_axis, axis_node->getDoubleValue("dead-band", 0.0));
@ -284,7 +287,7 @@ void FGJoystickInput::postinit()
buf << (unsigned)n_but;
SG_LOG(SG_INPUT, SG_DEBUG, "Initializing button " << buf.str());
FGButton &b = bindings[i].buttons[n_but];
FGButton &b = joysticks[i].buttons[n_but];
b.init(button_node, buf.str(), module );
// get interval-sec property
b.interval_sec = button_node->getDoubleValue("interval-sec",0.0);
@ -297,24 +300,22 @@ void FGJoystickInput::postinit()
}
}
void FGJoystickInput::update( double dt )
void FGJoystickInput::updateJoystick(int index, FGJoystickInput::joystick* joy, double dt)
{
float axis_values[MAX_JOYSTICK_AXES];
int modifiers = fgGetKeyModifiers();
int buttons;
for (int i = 0; i < MAX_JOYSTICKS; i++) {
jsJoystick * js = bindings[i].js;
jsJoystick * js = joy->plibJS.get();
if (js == 0 || js->notWorking())
continue;
return;
js->read(&buttons, axis_values);
if (js->notWorking()) // If js is disconnected
continue;
return;
// Update device status
SGPropertyNode_ptr status = status_node->getChild("joystick", i, true);
SGPropertyNode_ptr status = status_node->getChild("joystick", index, true);
for (int j = 0; j < MAX_JOYSTICK_AXES; j++) {
status->getChild("axis", j, true)->setFloatValue(axis_values[j]);
}
@ -324,8 +325,8 @@ void FGJoystickInput::update( double dt )
}
// Fire bindings for the axes.
for (int j = 0; j < bindings[i].naxes; j++) {
axis &a = bindings[i].axes[j];
for (int j = 0; j < joy->naxes; j++) {
axis &a = joy->axes[j];
// Do nothing if the axis position
// is unchanged; only a change in
@ -342,24 +343,31 @@ void FGJoystickInput::update( double dt )
a.last_dt += dt;
if(a.last_dt >= a.interval_sec) {
if (a.low.bindings[modifiers].size())
bindings[i].axes[j].low.update( modifiers, axis_values[j] < a.low_threshold );
joy->axes[j].low.update( modifiers, axis_values[j] < a.low_threshold );
if (a.high.bindings[modifiers].size())
bindings[i].axes[j].high.update( modifiers, axis_values[j] > a.high_threshold );
joy->axes[j].high.update( modifiers, axis_values[j] > a.high_threshold );
a.last_dt -= a.interval_sec;
}
}
} // of axes iteration
// Fire bindings for the buttons.
for (int j = 0; j < bindings[i].nbuttons; j++) {
FGButton &b = bindings[i].buttons[j];
for (int j = 0; j < joy->nbuttons; j++) {
FGButton &b = joy->buttons[j];
b.last_dt += dt;
if(b.last_dt >= b.interval_sec) {
bindings[i].buttons[j].update( modifiers, (buttons & (1u << j)) > 0 );
joy->buttons[j].update( modifiers, (buttons & (1u << j)) > 0 );
b.last_dt -= b.interval_sec;
}
}
} // of butotns iterations
}
void FGJoystickInput::update( double dt )
{
for (int i = 0; i < MAX_JOYSTICKS; i++) {
updateJoystick(i, &joysticks[i], dt);
}
}

View file

@ -25,12 +25,10 @@
#ifndef _FGJOYSTICKINPUT_HXX
#define _FGJOYSTICKINPUT_HXX
#ifndef __cplusplus
# error This library requires C++
#endif
#include "FGCommonInput.hxx"
#include "FGButton.hxx"
#include <memory> // for std::auto_ptr
#include <simgear/structure/subsystem_mgr.hxx>
#include <plib/js.h>
@ -52,6 +50,8 @@ public:
static const int MAX_JOYSTICK_BUTTONS = 32;
private:
void _remove(bool all);
SGPropertyNode_ptr status_node;
@ -79,14 +79,18 @@ private:
joystick ();
virtual ~joystick ();
int jsnum;
jsJoystick * js;
std::auto_ptr<jsJoystick> plibJS;
int naxes;
int nbuttons;
axis * axes;
FGButton * buttons;
bool predefined;
void clearAxesAndButtons();
};
joystick bindings[MAX_JOYSTICKS];
joystick joysticks[MAX_JOYSTICKS];
void updateJoystick(int index, joystick* joy, double dt);
};