1
0
Fork 0

Joystick updates from David Megginson to add the beginnings of button support.

This commit is contained in:
curt 2000-07-14 15:46:27 +00:00
parent 4f19d10485
commit 4dcd4cda79
3 changed files with 299 additions and 26 deletions

View file

@ -41,6 +41,7 @@ using std::string;
static const int MAX_JOYSTICKS = 10;
static const int MAX_AXES = 10;
static const int MAX_BUTTONS = 10;
/**
@ -54,6 +55,10 @@ static const char * axisNames[] = {
"axis0", "axis1", "axis2", "axis3", "axis4",
"axis5", "axis6", "axis7", "axis8", "axis9"
};
static const char * buttonNames[] = {
"button0", "button1", "button2", "button3", "button4",
"button5", "button6", "button7", "button8", "button9"
};
/**
@ -70,6 +75,25 @@ struct axis {
};
/**
* Settings for a single button.
*/
struct button {
enum Action {
TOGGLE,
SWITCH,
ADJUST
};
button () : value(0), step(0.0), action(ADJUST), isRepeatable(true),
lastState(-1) {}
FGValue * value;
float step;
Action action;
bool isRepeatable;
int lastState;
};
/**
* Settings for a single joystick.
*/
@ -77,6 +101,7 @@ struct joystick {
virtual ~joystick () { delete js; delete axes; }
jsJoystick * js;
axis * axes;
button * buttons;
};
@ -121,6 +146,61 @@ setupDefaults ()
if (!props.getValue("/input/js0/axis3/control")) {
props.setStringValue("/input/js0/axis3/control", "/controls/rudder");
props.setFloatValue("/input/js0/axis3/dead-band", 0.3);
}
// Default button 0 to all brakes
if (!props.getValue("/input/js0/button0/control")) {
props.setStringValue("/input/js0/button0/action", "switch");
props.setStringValue("/input/js0/button0/control", "/controls/brake");
props.setFloatValue("/input/js0/button0/step", 1.0);
props.setFloatValue("/input/js0/button0/repeatable", false);
}
// Default button 1 to left brake.
if (!props.getValue("/input/js0/button1/control")) {
props.setStringValue("/input/js0/button1/action", "switch");
props.setStringValue("/input/js0/button1/control", "/controls/left-brake");
props.setFloatValue("/input/js0/button1/step", 1.0);
props.setFloatValue("/input/js0/button1/repeatable", false);
}
// Default button 2 to right brake.
if (!props.getValue("/input/js0/button2/control")) {
props.setStringValue("/input/js0/button2/action", "switch");
props.setStringValue("/input/js0/button2/control",
"/controls/right-brake");
props.setFloatValue("/input/js0/button2/step", 1.0);
props.setFloatValue("/input/js0/button2/repeatable", false);
}
// Default buttons 3 and 4 to elevator trim
if (!props.getValue("/input/js0/button3/control")) {
props.setStringValue("/input/js0/button3/action", "adjust");
props.setStringValue("/input/js0/button3/control",
"/controls/elevator-trim");
props.setFloatValue("/input/js0/button3/step", 0.001);
props.setBoolValue("/input/js0/button3/repeatable", true);
}
if (!props.getValue("/input/js0/button4/control")) {
props.setStringValue("/input/js0/button4/action", "adjust");
props.setStringValue("/input/js0/button4/control",
"/controls/elevator-trim");
props.setFloatValue("/input/js0/button4/step", -0.001);
props.setBoolValue("/input/js0/button4/repeatable", true);
}
// Default buttons 5 and 6 to flaps
if (!props.getValue("/input/js0/button5/control")) {
props.setStringValue("/input/js0/button5/action", "adjust");
props.setStringValue("/input/js0/button5/control", "/controls/flaps");
props.setFloatValue("/input/js0/button5/step", -0.34);
props.setBoolValue("/input/js0/button5/repeatable", false);
}
if (!props.getValue("/input/js0/button6/control")) {
props.setStringValue("/input/js0/button6/action", "adjust");
props.setStringValue("/input/js0/button6/control", "/controls/flaps");
props.setFloatValue("/input/js0/button6/step", 0.34);
props.setBoolValue("/input/js0/button6/repeatable", false);
}
}
@ -158,10 +238,17 @@ fgJoystickInit()
js->getMaxRange(maxRange);
js->getCenter(center);
// Allocate axes
// Allocate axes and buttons
joysticks[i].axes = new axis[js->getNumAxes()];
joysticks[i].buttons = new button[MAX_BUTTONS];
//
// Initialize the axes.
//
for (int j = 0; j < min(js->getNumAxes(), MAX_AXES); j++) {
axis &a = joysticks[i].axes[j];
string base = "/input/";
base += jsNames[i];
base += '/';
@ -177,7 +264,7 @@ fgJoystickInit()
continue;
}
const string &control = value->getStringValue();
joysticks[i].axes[j].value = current_properties.getValue(control, true);
a.value = current_properties.getValue(control, true);
FG_LOG(FG_INPUT, FG_INFO, " using control " << control);
// Dead band
@ -193,9 +280,8 @@ fgJoystickInit()
name += "/offset";
value = current_properties.getValue(name);
if (value != 0)
joysticks[i].axes[j].offset = value->getFloatValue();
FG_LOG(FG_INPUT, FG_INFO, " offset is "
<< joysticks[i].axes[j].offset);
a.offset = value->getFloatValue();
FG_LOG(FG_INPUT, FG_INFO, " offset is " << a.offset);
// Factor
@ -203,9 +289,8 @@ fgJoystickInit()
name += "/factor";
value = current_properties.getValue(name);
if (value != 0)
joysticks[i].axes[j].factor = value->getFloatValue();
FG_LOG(FG_INPUT, FG_INFO, " factor is "
<< joysticks[i].axes[j].factor);
a.factor = value->getFloatValue();
FG_LOG(FG_INPUT, FG_INFO, " factor is " << a.factor);
// Tolerance
@ -213,9 +298,8 @@ fgJoystickInit()
name += "/tolerance";
value = current_properties.getValue(name);
if (value != 0)
joysticks[i].axes[j].tolerance = value->getFloatValue();
FG_LOG(FG_INPUT, FG_INFO, " tolerance is "
<< joysticks[i].axes[j].tolerance);
a.tolerance = value->getFloatValue();
FG_LOG(FG_INPUT, FG_INFO, " tolerance is " << a.tolerance);
// Saturation
@ -251,6 +335,74 @@ fgJoystickInit()
FG_LOG(FG_INPUT, FG_INFO, " center is " << center[j]);
}
//
// Initialize the buttons.
//
for (int j = 0; j < MAX_BUTTONS; j++) {
button &b = joysticks[i].buttons[j];
string base = "/input/";
base += jsNames[i];
base += '/';
base += buttonNames[j];
FG_LOG(FG_INPUT, FG_INFO, " Button " << j << ':');
// Control property
string name = base;
name += "/control";
cout << "Trying name " << name << endl;
FGValue * value = current_properties.getValue(name);
if (value == 0) {
FG_LOG(FG_INPUT, FG_INFO, " no control defined");
continue;
}
const string &control = value->getStringValue();
b.value = current_properties.getValue(control, true);
FG_LOG(FG_INPUT, FG_INFO, " using control " << control);
// Step
name = base;
name += "/step";
value = current_properties.getValue(name);
if (value != 0)
b.step = value->getFloatValue();
FG_LOG(FG_INPUT, FG_INFO, " step is " << b.step);
// Type
name = base;
name += "/action";
value = current_properties.getValue(name);
string action = "adjust";
if (value != 0)
action = value->getStringValue();
if (action == "toggle") {
b.action = button::TOGGLE;
b.isRepeatable = false;
} else if (action == "switch") {
b.action = button::SWITCH;
b.isRepeatable = false;
} else if (action == "adjust") {
b.action = button::ADJUST;
b.isRepeatable = true;
} else {
FG_LOG(FG_INPUT, FG_ALERT, " unknown action " << action);
action = "adjust";
b.action = button::ADJUST;
b.isRepeatable = true;
}
FG_LOG(FG_INPUT, FG_INFO, " action is " << action);
// Repeatability.
name = base;
name += "/repeatable";
value = current_properties.getValue(name);
if (value != 0)
b.isRepeatable = value->getBoolValue();
FG_LOG(FG_INPUT, FG_INFO, (b.isRepeatable ?
" repeatable" : " not repeatable"));
}
js->setMinRange(minRange);
js->setMaxRange(maxRange);
js->setCenter(center);
@ -282,28 +434,101 @@ fgJoystickRead()
js->read(&buttons, axis_values);
//
// Axes
//
for (int j = 0; j < min(MAX_AXES, js->getNumAxes()); j++) {
bool flag = true;
axis &a = joysticks[i].axes[j];
// If the axis hasn't changed, don't
// force the value.
if (fabs(axis_values[j] - joysticks[i].axes[j].last_value) <=
joysticks[i].axes[j].tolerance)
if (fabs(axis_values[j] - a.last_value) <= a.tolerance)
continue;
else
joysticks[i].axes[j].last_value = axis_values[j];
a.last_value = axis_values[j];
FGValue * value = joysticks[i].axes[j].value;
if (value) {
if (!value->setDoubleValue((axis_values[j] +
joysticks[i].axes[j].offset) *
joysticks[i].axes[j].factor))
FG_LOG(FG_INPUT, FG_ALERT, "Failed to set value for joystick "
<< i << ", axis " << j);
if (a.value)
flag = a.value->setDoubleValue((axis_values[j] + a.offset) *
a.factor);
if (!flag)
FG_LOG(FG_INPUT, FG_ALERT, "Failed to set value for joystick "
<< i << ", axis " << j);
}
//
// Buttons
//
for (int j = 0; j < MAX_BUTTONS; j++) {
bool flag;
button &b = joysticks[i].buttons[j];
if (b.value == 0)
continue;
// Button is on.
if ((buttons & (1 << j)) > 0) {
// Repeating?
if (b.lastState == 1 && !b.isRepeatable)
continue;
switch (b.action) {
case button::TOGGLE:
if (b.step != 0.0) {
if (b.value->getDoubleValue() == 0.0)
flag = b.value->setDoubleValue(b.step);
else
flag = b.value->setDoubleValue(0.0);
} else {
if (b.value->getBoolValue())
flag = b.value->setBoolValue(false);
else
flag = b.value->setBoolValue(true);
}
break;
case button::SWITCH:
flag = b.value->setDoubleValue(b.step);
break;
case button::ADJUST:
if (!b.value->setDoubleValue(b.value->getDoubleValue() + b.step))
FG_LOG(FG_INPUT, FG_ALERT, "Failed to set value for joystick "
<< i << ", axis " << j);
break;
default:
flag = false;
break;
}
b.lastState = 1;
// Button is off
} else {
// Repeating?
if (b.lastState == 0 && !b.isRepeatable)
continue;
switch (b.action) {
case button::TOGGLE:
// no op
break;
case button::SWITCH:
flag = b.value->setDoubleValue(0.0);
break;
case button::ADJUST:
// no op
break;
default:
flag = false;
break;
}
b.lastState = 0;
}
if (!flag)
FG_LOG(FG_INPUT, FG_ALERT, "Failed to set value for "
<< jsNames[i] << ' ' << buttonNames[j]);
}
}
return true; // FIXME
return true;
}
// end of joystick.cxx

View file

@ -149,6 +149,10 @@ FGBFI::init ()
getElevatorTrim, setElevatorTrim);
current_properties.tieDouble("/controls/brake",
getBrake, setBrake);
current_properties.tieDouble("/controls/left-brake",
getLeftBrake, setLeftBrake);
current_properties.tieDouble("/controls/right-brake",
getRightBrake, setRightBrake);
// Autopilot
current_properties.tieBool("/autopilot/locks/altitude",
@ -509,7 +513,7 @@ double
FGBFI::getAGL ()
{
return current_aircraft.fdm_state->get_Altitude()
- scenery.cur_elev * METER_TO_FEET;
- (scenery.cur_elev * METER_TO_FEET);
}
@ -866,7 +870,7 @@ double
FGBFI::getBrake ()
{
// FIXME: add brake selector
return controls.get_brake(0);
return controls.get_brake(2);
}
@ -876,12 +880,52 @@ FGBFI::getBrake ()
void
FGBFI::setBrake (double brake)
{
// FIXME: clamp?
// FIXME: allow brake selection
controls.set_brake(FGControls::ALL_WHEELS, brake);
}
/**
* Get the left brake, from 0.0 (none) to 1.0 (full).
*/
double
FGBFI::getLeftBrake ()
{
return controls.get_brake(0);
}
/**
* Set the left brake, from 0.0 (none) to 1.0 (full).
*/
void
FGBFI::setLeftBrake (double brake)
{
controls.set_brake(0, brake);
}
/**
* Get the right brake, from 0.0 (none) to 1.0 (full).
*/
double
FGBFI::getRightBrake ()
{
return controls.get_brake(1);
}
/**
* Set the right brake, from 0.0 (none) to 1.0 (full).
*/
void
FGBFI::setRightBrake (double brake)
{
controls.set_brake(1, brake);
}
////////////////////////////////////////////////////////////////////////
// Autopilot

View file

@ -111,6 +111,8 @@ public:
static double getElevator ();
static double getElevatorTrim ();
static double getBrake ();
static double getLeftBrake ();
static double getRightBrake ();
static void setThrottle (double throttle);
static void setFlaps (double flaps);
@ -119,6 +121,8 @@ public:
static void setElevator (double elevator);
static void setElevatorTrim (double trim);
static void setBrake (double brake);
static void setLeftBrake (double brake);
static void setRightBrake (double brake);
// Autopilot