-
- int naxes = js->getNumAxes();
- if (naxes > MAX_JOYSTICK_AXES) naxes = MAX_JOYSTICK_AXES;
- _joystick_bindings[i].naxes = naxes;
- _joystick_bindings[i].nbuttons = nbuttons;
-
- SG_LOG(SG_INPUT, SG_DEBUG, "Initializing joystick " << i);
-
- // Set up range arrays
- float minRange[MAX_JOYSTICK_AXES];
- float maxRange[MAX_JOYSTICK_AXES];
- float center[MAX_JOYSTICK_AXES];
-
- // Initialize with default values
- js->getMinRange(minRange);
- js->getMaxRange(maxRange);
- js->getCenter(center);
-
- // Allocate axes and buttons
- _joystick_bindings[i].axes = new axis[naxes];
- _joystick_bindings[i].buttons = new button[nbuttons];
-
- //
- // Initialize nasal groups.
- //
- string init;
- init = "this=\"" + string(js_node->getPath()) + "\"";
- sprintf(_module, "__js%d", i);
- nasalsys->createModule(_module, _module, init.c_str(), init.size());
-
- vector<SGPropertyNode_ptr> nasal = js_node->getChildren("nasal");
- unsigned int j;
- for (j = 0; j < nasal.size(); j++) {
- nasal[j]->setStringValue("module", _module);
- nasalsys->handleCommand(nasal[j]);
- }
-
- //
- // Initialize the axes.
- //
- vector<SGPropertyNode_ptr> axes = js_node->getChildren("axis");
- size_t nb_axes = axes.size();
- for (j = 0; j < nb_axes; j++ ) {
- const SGPropertyNode * axis_node = axes[j];
- const SGPropertyNode * num_node = axis_node->getChild("number");
- int n_axis = axis_node->getIndex();
- if (num_node != 0) {
- n_axis = num_node->getIntValue(TGT_PLATFORM, -1);
-
- // Silently ignore platforms that are not specified within the
- // <number></number> section
- if (n_axis < 0)
- continue;
- }
-
- if (n_axis >= naxes) {
- SG_LOG(SG_INPUT, SG_DEBUG, "Dropping bindings for axis " << n_axis);
- continue;
- }
- axis &a = _joystick_bindings[i].axes[n_axis];
-
- js->setDeadBand(n_axis, axis_node->getDoubleValue("dead-band", 0.0));
-
- a.tolerance = axis_node->getDoubleValue("tolerance", 0.002);
- minRange[n_axis] = axis_node->getDoubleValue("min-range", minRange[n_axis]);
- maxRange[n_axis] = axis_node->getDoubleValue("max-range", maxRange[n_axis]);
- center[n_axis] = axis_node->getDoubleValue("center", center[n_axis]);
-
- _read_bindings(axis_node, a.bindings, KEYMOD_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);
- a.interval_sec = axis_node->getDoubleValue("interval-sec",0.0);
- a.last_dt = 0.0;
- }
-
- //
- // Initialize the buttons.
- //
- vector<SGPropertyNode_ptr> buttons = js_node->getChildren("button");
- char buf[32];
- for (j = 0; j < buttons.size() && j < nbuttons; j++) {
- const SGPropertyNode * button_node = buttons[j];
- const SGPropertyNode * num_node = button_node->getChild("number");
- size_t n_but = button_node->getIndex();
- if (num_node != 0) {
- n_but = num_node->getIntValue(TGT_PLATFORM,n_but);
- }
-
- if (n_but >= nbuttons) {
- SG_LOG(SG_INPUT, SG_DEBUG, "Dropping bindings for button " << n_but);
- continue;
- }
-
- sprintf(buf, "%d", n_but);
- SG_LOG(SG_INPUT, SG_DEBUG, "Initializing button " << n_but);
- _init_button(button_node,
- _joystick_bindings[i].buttons[n_but],
- buf);
-
- // get interval-sec property
- button &b = _joystick_bindings[i].buttons[n_but];
- if (button_node != 0) {
- b.interval_sec = button_node->getDoubleValue("interval-sec",0.0);
- b.last_dt = 0.0;
- }
- }
-
- js->setMinRange(minRange);
- js->setMaxRange(maxRange);
- js->setCenter(center);
- }
-}
-
-
-//
-// Map of all known cursor names
-// This used to contain all the Glut cursors, but those are
-// not defined by other toolkits. It now supports only the cursor
-// images we actually use, in the interest of portability. Someday,
-// it would be cool to write an OpenGL cursor renderer, with the
-// cursors defined as textures referenced in the property tree. This
-// list could then be eliminated. -Andy
-//
-static struct {
- const char * name;
- int cursor;
-} mouse_cursor_map[] = {
- { "none", MOUSE_CURSOR_NONE },
- { "inherit", MOUSE_CURSOR_POINTER },
- { "wait", MOUSE_CURSOR_WAIT },
- { "crosshair", MOUSE_CURSOR_CROSSHAIR },
- { "left-right", MOUSE_CURSOR_LEFTRIGHT },
- { 0, 0 }
-};
-
-void
-FGInput::_init_mouse ()
-{
- SG_LOG(SG_INPUT, SG_DEBUG, "Initializing mouse bindings");
- _module[0] = 0;
-
- SGPropertyNode * mouse_nodes = fgGetNode("/input/mice");
- if (mouse_nodes == 0) {
- SG_LOG(SG_INPUT, SG_WARN, "No mouse bindings (/input/mice)!!");
- mouse_nodes = fgGetNode("/input/mice", true);
- }
-
- int j;
- for (int i = 0; i < MAX_MICE; i++) {
- SGPropertyNode * mouse_node = mouse_nodes->getChild("mouse", i, true);
- mouse &m = _mouse_bindings[i];
-
- // Grab node pointers
- char buf[64];
- sprintf(buf, "/devices/status/mice/mouse[%d]/mode", i);
- m.mode_node = fgGetNode(buf);
- if (m.mode_node == NULL) {
- m.mode_node = fgGetNode(buf, true);
- m.mode_node->setIntValue(0);
- }
- for (j = 0; j < MAX_MOUSE_BUTTONS; j++) {
- sprintf(buf, "/devices/status/mice/mouse[%d]/button[%d]", i, j);
- m.mouse_button_nodes[j] = fgGetNode(buf, true);
- m.mouse_button_nodes[j]->setBoolValue(false);
- }
-
- // Read all the modes
- m.nModes = mouse_node->getIntValue("mode-count", 1);
- m.modes = new mouse_mode[m.nModes];
-
- for (int j = 0; j < m.nModes; j++) {
- int k;
-
- // Read the mouse cursor for this mode
- SGPropertyNode * mode_node = mouse_node->getChild("mode", j, true);
- const char * cursor_name =
- mode_node->getStringValue("cursor", "inherit");
- m.modes[j].cursor = MOUSE_CURSOR_POINTER;
- for (k = 0; mouse_cursor_map[k].name != 0; k++) {
- if (!strcmp(mouse_cursor_map[k].name, cursor_name)) {
- m.modes[j].cursor = mouse_cursor_map[k].cursor;
- break;
- }
- }
-
- // Read other properties for this mode
- m.modes[j].constrained = mode_node->getBoolValue("constrained", false);
- m.modes[j].pass_through = mode_node->getBoolValue("pass-through", false);
-
- // Read the button bindings for this mode
- m.modes[j].buttons = new button[MAX_MOUSE_BUTTONS];
- char buf[32];
- for (k = 0; k < MAX_MOUSE_BUTTONS; k++) {
- sprintf(buf, "mouse button %d", k);
- SG_LOG(SG_INPUT, SG_DEBUG, "Initializing mouse button " << k);
- _init_button(mode_node->getChild("button", k),
- m.modes[j].buttons[k],
- buf);
- }
-
- // Read the axis bindings for this mode
- _read_bindings(mode_node->getChild("x-axis", 0, true),
- m.modes[j].x_bindings,
- KEYMOD_NONE);
- _read_bindings(mode_node->getChild("y-axis", 0, true),
- m.modes[j].y_bindings,
- KEYMOD_NONE);
- }
- }
-}
-
-
-void
-FGInput::_init_button (const SGPropertyNode * node,
- button &b,
- const string name)
-{
- if (node == 0) {
- SG_LOG(SG_INPUT, SG_DEBUG, "No bindings for button " << name);
- } else {
- b.is_repeatable = node->getBoolValue("repeatable", b.is_repeatable);
-
- // Get the bindings for the button
- _read_bindings(node, b.bindings, KEYMOD_NONE);
- }
-}
-
-
-void
-FGInput::_update_keyboard ()
-{
- // no-op
-}
-
-
-void
-FGInput::_update_joystick (double dt)
-{
- int modifiers = KEYMOD_NONE; // FIXME: any way to get the real ones?
- int buttons;
- // float js_val, diff;
- float axis_values[MAX_JOYSTICK_AXES];
-
- int i;
- int j;
-
- for ( i = 0; i < MAX_JOYSTICKS; i++) {
-
- jsJoystick * js = _joystick_bindings[i].js;
- if (js == 0 || js->notWorking())
- continue;
-
- js->read(&buttons, axis_values);
-
- // Fire bindings for the axes.
- for ( j = 0; j < _joystick_bindings[i].naxes; j++) {
- axis &a = _joystick_bindings[i].axes[j];
-
- // Do nothing if the axis position
- // is unchanged; only a change in
- // position fires the bindings.
- if (fabs(axis_values[j] - a.last_value) > a.tolerance) {
-// SG_LOG(SG_INPUT, SG_DEBUG, "Axis " << j << " has moved");
- a.last_value = axis_values[j];
-// SG_LOG(SG_INPUT, SG_DEBUG, "There are "
-// << a.bindings[modifiers].size() << " bindings");
- for (unsigned int k = 0; k < a.bindings[modifiers].size(); k++)
- a.bindings[modifiers][k]->fire(axis_values[j]);
- }
-
- // do we have to emulate axis buttons?
- a.last_dt += dt;
- if(a.last_dt >= a.interval_sec) {
- if (a.low.bindings[modifiers].size())
- _update_button(_joystick_bindings[i].axes[j].low,
- modifiers,
- axis_values[j] < a.low_threshold,
- -1, -1);
-
- if (a.high.bindings[modifiers].size())
- _update_button(_joystick_bindings[i].axes[j].high,
- modifiers,
- axis_values[j] > a.high_threshold,
- -1, -1);
- a.last_dt -= a.interval_sec;
- }
- }
-
- // Fire bindings for the buttons.
- for (j = 0; j < _joystick_bindings[i].nbuttons; j++) {
- button &b = _joystick_bindings[i].buttons[j];
- b.last_dt += dt;
- if(b.last_dt >= b.interval_sec) {
- _update_button(_joystick_bindings[i].buttons[j],
- modifiers,
- (buttons & (1 << j)) > 0,
- -1, -1);
- b.last_dt -= b.interval_sec;
- }
- }
- }
-}
-
-void
-FGInput::_update_mouse ( double dt )
-{
- mouse &m = _mouse_bindings[0];
- int mode = m.mode_node->getIntValue();
- if (mode != m.current_mode) {
- m.current_mode = mode;
- m.timeout = fgGetDouble( "/sim/mouse/cursor-timeout-sec", 10.0 );
- if (mode >= 0 && mode < m.nModes) {
- fgSetMouseCursor(m.modes[mode].cursor);
- m.x = fgGetInt("/sim/startup/xsize", 800) / 2;
- m.y = fgGetInt("/sim/startup/ysize", 600) / 2;
- fgWarpMouse(m.x, m.y);
- } else {
- SG_LOG(SG_INPUT, SG_DEBUG, "Mouse mode " << mode << " out of range");
- fgSetMouseCursor(MOUSE_CURSOR_POINTER);
- }
- }
-
- if ( fgGetBool( "/sim/mouse/hide-cursor", true ) ) {
- if ( m.x != m.save_x || m.y != m.save_y ) {
- m.timeout = fgGetDouble( "/sim/mouse/cursor-timeout-sec", 10.0 );
- fgSetMouseCursor(m.modes[mode].cursor);
- } else {
- m.timeout -= dt;
- if ( m.timeout <= 0.0 ) {
- fgSetMouseCursor(MOUSE_CURSOR_NONE);
- m.timeout = 0.0;
- }
- }
- m.save_x = m.x;
- m.save_y = m.y;
- }