1
0
Fork 0

- read all joystick files from $FG_ROOT/Input/Joysticks automatically

(no need to list the paths explicitly in $FG_ROOT/joysticks.xml any more)
- move identified js nodes to /input/joysticks/js[0-9], but
- don't overwrite already set joystick data there
- remove all nodes when they aren't used any more
- add "id" node, which contains the js id that lead to the selection
  of a "named js" config
- add "source" node containing the path of the used js config file
- execute all nasal script groups at initialization time
This commit is contained in:
mfranz 2005-06-11 14:26:11 +00:00
parent 57aa9274d7
commit 325d545132
2 changed files with 120 additions and 34 deletions

View file

@ -50,6 +50,7 @@
#include <Cockpit/panel_io.hxx> #include <Cockpit/panel_io.hxx>
#include <GUI/gui.h> #include <GUI/gui.h>
#include <Model/panelnode.hxx> #include <Model/panelnode.hxx>
#include <Scripting/NasalSys.hxx>
#include <Main/globals.hxx> #include <Main/globals.hxx>
#include <Main/fg_props.hxx> #include <Main/fg_props.hxx>
@ -185,6 +186,12 @@ FGInput::reinit ()
init(); init();
} }
void
FGInput::postinit ()
{
_postinit_joystick();
}
void void
FGInput::update (double dt) FGInput::update (double dt)
{ {
@ -388,6 +395,31 @@ FGInput::_init_keyboard ()
} }
void
FGInput::_scan_joystick_dir(SGPath *path, SGPropertyNode* node, int *index)
{
ulDir *dir = ulOpenDir(path->c_str());
if (dir) {
ulDirEnt* dent;
while ((dent = ulReadDir(dir)) != 0) {
if (dent->d_name[0] == '.')
continue;
SGPath p(path->str());
p.append(dent->d_name);
_scan_joystick_dir(&p, node, index);
}
ulCloseDir(dir);
} else if (path->extension() == "xml") {
SG_LOG(SG_INPUT, SG_DEBUG, "Reading joystick file " << path->str());
SGPropertyNode *n = node->getChild("js-named", (*index)++, true);
readProperties(path->str(), n);
n->setStringValue("source", path->c_str());
}
}
void void
FGInput::_init_joystick () FGInput::_init_joystick ()
{ {
@ -400,40 +432,65 @@ FGInput::_init_joystick ()
js_nodes = fgGetNode("/input/joysticks", true); js_nodes = fgGetNode("/input/joysticks", true);
} }
for (int i = 0; i < MAX_JOYSTICKS; i++) { // read all joystick xml files into /input/joysticks/js_named[1000++]
SGPropertyNode_ptr js_node = js_nodes->getChild("js", i); SGPath path(globals->get_fg_root());
if (js_node == 0) { path.append("Input/Joysticks");
SG_LOG(SG_INPUT, SG_DEBUG, "No bindings for joystick " << i); int js_named_index = 1000;
js_node = js_nodes->getChild("js", i, true); _scan_joystick_dir(&path, js_nodes, &js_named_index);
// build name->node map for each <name> (reverse order)
map<string, SGPropertyNode_ptr> jsmap;
vector<SGPropertyNode_ptr> js_named = js_nodes->getChildren("js-named");
for (int k = (int)js_named.size() - 1; k >= 0; k--) {
SGPropertyNode *n = js_named[k];
vector<SGPropertyNode_ptr> names = n->getChildren("name");
if (names.size() && (n->getChildren("axis").size() || n->getChildren("button").size()))
for (unsigned int j = 0; j < names.size(); j++)
jsmap[names[j]->getStringValue()] = n;
} }
for (int i = 0; i < MAX_JOYSTICKS; i++) {
jsJoystick * js = new jsJoystick(i); jsJoystick * js = new jsJoystick(i);
_joystick_bindings[i].js = js; _joystick_bindings[i].js = js;
if (js->notWorking()) { if (js->notWorking()) {
SG_LOG(SG_INPUT, SG_DEBUG, "Joystick " << i << " not found"); SG_LOG(SG_INPUT, SG_DEBUG, "Joystick " << i << " not found");
continue; continue;
} else { }
bool found_js = false;
const char * name = js->getName(); const char * name = js->getName();
SG_LOG(SG_INPUT, SG_INFO, "Looking for bindings for joystick \"" SGPropertyNode_ptr js_node = js_nodes->getChild("js", i);
<< name << '"');
vector<SGPropertyNode_ptr> nodes = js_nodes->getChildren("js-named"); if (js_node) {
for (unsigned int i = 0; i < nodes.size(); i++) { SG_LOG(SG_INPUT, SG_INFO, "Using existing bindings for joystick " << i);
SGPropertyNode_ptr node = nodes[i];
vector<SGPropertyNode_ptr> name_nodes = node->getChildren("name"); } else {
for (unsigned int j = 0; j < name_nodes.size(); j++) { SG_LOG(SG_INPUT, SG_INFO, "Looking for bindings for joystick \"" << name << '"');
const char * js_name = name_nodes[j]->getStringValue(); SGPropertyNode_ptr named;
SG_LOG(SG_INPUT, SG_INFO, " Trying \"" << js_name << '"');
if (!strcmp(js_name, name)) { if ((named = jsmap[name])) {
SG_LOG(SG_INPUT, SG_INFO, " Found bindings"); string source = named->getStringValue("source", "");
js_node = node; if (source.empty())
found_js = true; SG_LOG(SG_INPUT, SG_INFO, "... found joystick (user defined)");
break; else
} SG_LOG(SG_INPUT, SG_INFO, "... found joystick: \"" << source << '"');
}
if (found_js) } else if ((named = jsmap["default"])) {
break; string source = named->getStringValue("source", "");
SG_LOG(SG_INPUT, SG_INFO, "No config found for joystick \"" << name
<< "\"\nUsing default: \"" << source << '"');
} else {
SG_LOG(SG_INPUT, SG_ALERT, "No default joystick found! (<name>default</name>)");
continue;
} }
js_node = js_nodes->getChild("js", i, true);
copyProperties(named, js_node);
js_node->setStringValue("id", name);
} }
#ifdef WIN32 #ifdef WIN32
JOYCAPS jsCaps ; JOYCAPS jsCaps ;
joyGetDevCaps( i, &jsCaps, sizeof(jsCaps) ); joyGetDevCaps( i, &jsCaps, sizeof(jsCaps) );
@ -484,7 +541,7 @@ FGInput::_init_joystick ()
continue; continue;
} }
if (n_axis >= (size_t)naxes) { if (n_axis >= naxes) {
SG_LOG(SG_INPUT, SG_DEBUG, "Dropping bindings for axis " << n_axis); SG_LOG(SG_INPUT, SG_DEBUG, "Dropping bindings for axis " << n_axis);
continue; continue;
} }
@ -545,8 +602,24 @@ FGInput::_init_joystick ()
js->setMaxRange(maxRange); js->setMaxRange(maxRange);
js->setCenter(center); js->setCenter(center);
} }
for (unsigned int m = 0; m < js_named.size(); m++)
js_nodes->removeChild("js-named", js_named[m]->getIndex(), false);
} }
void
FGInput::_postinit_joystick()
{
vector<SGPropertyNode_ptr> js = fgGetNode("/input/joysticks")->getChildren("js");
for (unsigned int i = 0; i < js.size(); i++) {
vector<SGPropertyNode_ptr> nasal = js[i]->getChildren("nasal");
for (unsigned int j = 0; j < nasal.size(); j++)
((FGNasalSys*)globals->get_subsystem("nasal"))->handleCommand(nasal[j]);
}
}
// //
// Map of all known cursor names // Map of all known cursor names
// This used to contain all the Glut cursors, but those are // This used to contain all the Glut cursors, but those are
@ -696,7 +769,6 @@ FGInput::_update_joystick (double dt)
// position fires the bindings. // position fires the bindings.
if (fabs(axis_values[j] - a.last_value) > a.tolerance) { if (fabs(axis_values[j] - a.last_value) > a.tolerance) {
// SG_LOG(SG_INPUT, SG_DEBUG, "Axis " << j << " has moved"); // SG_LOG(SG_INPUT, SG_DEBUG, "Axis " << j << " has moved");
SGPropertyNode node;
a.last_value = axis_values[j]; a.last_value = axis_values[j];
// SG_LOG(SG_INPUT, SG_DEBUG, "There are " // SG_LOG(SG_INPUT, SG_DEBUG, "There are "
// << a.bindings[modifiers].size() << " bindings"); // << a.bindings[modifiers].size() << " bindings");

View file

@ -33,6 +33,7 @@
#include <simgear/compiler.h> #include <simgear/compiler.h>
#include <simgear/misc/sg_path.hxx>
#include <simgear/structure/subsystem_mgr.hxx> #include <simgear/structure/subsystem_mgr.hxx>
#include <simgear/structure/commands.hxx> #include <simgear/structure/commands.hxx>
#include <simgear/props/condition.hxx> #include <simgear/props/condition.hxx>
@ -195,6 +196,7 @@ public:
// //
virtual void init (); virtual void init ();
virtual void reinit (); virtual void reinit ();
virtual void postinit ();
virtual void update (double dt); virtual void update (double dt);
virtual void suspend (); virtual void suspend ();
virtual void resume (); virtual void resume ();
@ -359,6 +361,13 @@ private:
void _init_joystick (); void _init_joystick ();
/**
* Scan directory recursively for "named joystick" configuration files,
* and read them into /input/joysticks/js-named[index]++.
*/
void _scan_joystick_dir (SGPath *path, SGPropertyNode* node, int *index);
/** /**
* Initialize mouse bindings. * Initialize mouse bindings.
*/ */
@ -372,6 +381,11 @@ private:
button &b, button &b,
const string name); const string name);
/**
* Initialize nasal parts that had to wait for the nasal to get
* functional.
*/
void _postinit_joystick ();
/** /**
* Update the keyboard. * Update the keyboard.