diff --git a/src/Input/Makefile.am b/src/Input/Makefile.am index 7ee2ac39f..25948add6 100644 --- a/src/Input/Makefile.am +++ b/src/Input/Makefile.am @@ -2,4 +2,14 @@ noinst_LIBRARIES = libInput.a libInput_a_SOURCES = input.cxx input.hxx +bin_PROGRAMS = js_demo fgjs + +js_demo_SOURCES = js_demo.cxx + +js_demo_LDADD = $(audio_LIBS) + +fgjs_SOURCES = fgjs.cxx jsinput.cxx jssuper.cxx + +fgjs_LDADD = + INCLUDES += -I$(top_srcdir) -I$(top_srcdir)/src diff --git a/src/Input/fgjs.cxx b/src/Input/fgjs.cxx new file mode 100644 index 000000000..15fc46ce0 --- /dev/null +++ b/src/Input/fgjs.cxx @@ -0,0 +1,201 @@ +// fgjs.cxx -- assign joystick axes to flightgear properties +// +// Written by Tony Peden, started May 2001 +// +// Copyright (C) 2001 Tony Peden (apeden@earthlink.net) +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include +#include +#include +#include +#include + +string axes_humannames[8] = { "elevator", "ailerons", "rudder", "throttle", + "mixture","propller pitch", "lateral view", + "longitudinal view" + }; + +string axes_propnames[8]={ "/controls/elevator","/controls/aileron", + "/controls/rudder","/controls/throttle", + "/controls/mixture","/controls/pitch", + "/sim/views/axes/lat","/sim/views/axes/long" + }; + +bool half_range[8]={ false,false,false,true,true,true,false,false }; + + +string button_humannames[7]= { "apply all brakes", "apply left brake", + "apply right brake", "step flaps up", + "step flaps down","apply nose-up trim", + "apply nose-down trim" + }; + +string button_propnames[7]={ "/controls/brakes/all", "/controls/brakes/left", + "/controls/brakes/right", "/controls/flaps", + "/controls/flaps","/controls/elevator-trim", + "/controls/elevator-trim" + }; + + +float button_step[7]={ 1.0, 1.0, 1.0, 0.34, -0.34, 0.001, -0.001 }; + +string button_repeat[7]={ "false", "false", "false", "false", "false", + "true", "true" }; + + +void waitForButton(jsSuper *jss, int wait_ms) { + int b,lastb; + float axes[_JS_MAX_AXES]; + b=0; + ulMilliSecondSleep(wait_ms); + do { + lastb=b; + do { + jss->getJoystick()->read ( &b, axes ) ; + } while( jss->nextJoystick()); + + ulMilliSecondSleep(1); + + }while( lastb == b ); + ulMilliSecondSleep(wait_ms); +} + +void writeAxisProperties(fstream &fs, int control,int joystick, int axis) { + + char jsDesc[25]; + snprintf(jsDesc,25,"--prop:/input/js%d/axis%d",joystick,axis); + fs << jsDesc << "/control=" << axes_propnames[control] << endl; + + fs << jsDesc << "/dead-band=0.02" << endl; + + if( half_range[control] == true) { + fs << jsDesc << "/offset=-1.0" << endl; + fs << jsDesc << "/factor=0.5" << endl; + } else { + fs << jsDesc << "/offset=0.0" << endl; + fs << jsDesc << "/factor=1.0" << endl; + } + fs << endl; +} + +void writeButtonProperties(fstream &fs, int property,int joystick, int button) { + + char jsDesc[25]; + snprintf(jsDesc,25,"--prop:/input/js%d/button%d",joystick,button); + + fs << jsDesc << "/action=adjust" << endl; + fs << jsDesc << "/control=" << button_propnames[property] << endl; + fs << jsDesc << "/step=" << button_step[property] << endl; + fs << jsDesc << "/repeatable=" << button_repeat[property] << endl; + fs << endl; +} + + + + +int main(void) { + jsSuper *jss=new jsSuper(); + jsInput *jsi=new jsInput(jss); + jsi->displayValues(false); + int i; + int control=0; + + + cout << "Found " << jss->getNumJoysticks() << " joystick(s)" << endl; + + if(jss->getNumJoysticks() <= 0) { + cout << "Can't find any joysticks ..." << endl; + exit(1); + } + + jss->firstJoystick(); + do { + cout << "Joystick " << jss->getCurrentJoystickId() << " has " + << jss->getJoystick()->getNumAxes() << " axes" << endl; + } while( jss->nextJoystick() ); + + fstream fs("fgfsrc.js",ios::out); + + + for(control=0;control<=7;control++) { + cout << "Move the control you wish to use for " << axes_humannames[control] + << endl; + fflush( stdout ); + jsi->getInput(); + + if(jsi->getInputAxis() != -1) { + cout << endl << "Assigned axis " << jsi->getInputAxis() + << " on joystick " << jsi->getInputJoystick() + << " to control " << axes_humannames[control] + << endl; + + writeAxisProperties( fs, control, jsi->getInputJoystick(), + jsi->getInputAxis() ); + } else { + cout << "Skipping Axis" << endl; + } + + cout << "Press any button for next control" << endl; + + waitForButton(jss,500); + cout << endl; + } + + for(control=0;control<=6;control++) { + cout << "Press the button you wish to use to " + << button_humannames[control] + << endl; + fflush( stdout ); + jsi->getInput(); + if(jsi->getInputButton() != -1) { + + cout << endl << "Assigned button " << jsi->getInputButton() + << " on joystick " << jsi->getInputJoystick() + << " to control " << button_humannames[control] + << endl; + + writeButtonProperties( fs, control, jsi->getInputJoystick(), + jsi->getInputButton() ); + } else { + cout << "Skipping..." << endl; + } + + cout << "Press any button for next axis" << endl; + + waitForButton(jss,500); + cout << endl; + } + + + delete jsi; + delete jss; + + cout << "Your joystick settings are in the file fgfsrc.js" << endl; + cout << "Check and edit as desired (especially important if you are" + << " using a hat switch" << endl; + cout << "as this program will, most likely, not get those right). "; + + cout << "Once you are happy, " << endl + << "append its contents to your .fgfsrc or system.fgfsrc" << endl; + + return 1; +} + + + diff --git a/src/Input/js_demo.cxx b/src/Input/js_demo.cxx new file mode 100644 index 000000000..904a4097d --- /dev/null +++ b/src/Input/js_demo.cxx @@ -0,0 +1,110 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef HAVE_WINDOWS_H +# include +#endif + +#include // plib/js.h should really include this !!!!!! +#include + +#define Z 8 + +int main ( int, char ** ) +{ + jsJoystick *js[Z] ; + float *ax[Z] ; + int i, j, t, useful[Z]; + + for ( i = 0; i < Z; i++ ) + js[i] = new jsJoystick ( i ) ; + + printf ( "Joystick test program.\n" ) ; + printf ( "~~~~~~~~~~~~~~~~~~~~~~\n" ) ; + + t = 0; + for ( i = 0; i < Z; i++ ) + { useful[i] = ! ( js[i]->notWorking () ); + if ( useful[i] ) + t++; + else printf ( "Joystick %i not detected\n", i ) ; + } + if ( t == 0 ) exit ( 1 ) ; + + for ( i = 0; i < Z; i++ ) + if ( useful[i] ) + ax[i] = new float [ js[i]->getNumAxes () ] ; + + for ( i = 0 ; i < Z ; i++ ) + if ( useful[i] ) + printf ( "+--------------------JS.%d----------------------", i ) ; + + printf ( "+\n" ) ; + + for ( i = 0 ; i < Z ; i++ ) + if ( useful[i] ) + { + if ( js[i]->notWorking () ) + printf ( "| ~~~ Not Detected ~~~ " ) ; + else + { + printf ( "| Btns " ) ; + + for ( j = 0 ; j < js[i]->getNumAxes () ; j++ ) + printf ( "Ax:%1d ", j ) ; + + for ( ; j < 8 ; j++ ) + printf ( " " ) ; + } + } + + printf ( "|\n" ) ; + + for ( i = 0 ; i < Z ; i++ ) + if ( useful[i] ) + printf ( "+----------------------------------------------" ) ; + + printf ( "+\n" ) ; + + while (1) + { + for ( i = 0 ; i < Z ; i++ ) + if ( useful[i] ) + { + if ( js[i]->notWorking () ) + printf ( "| . . . . . . . . . . . " ) ; + else + { + int b ; + + js[i]->read ( &b, ax[i] ) ; + + printf ( "| %04x ", b ) ; + + for ( j = 0 ; j < js[i]->getNumAxes () ; j++ ) + printf ( "%+.1f ", ax[i][j] ) ; + + for ( ; j < 8 ; j++ ) + printf ( " . " ) ; + } + } + + printf ( "|\r" ) ; + fflush ( stdout ) ; + + /* give other processes a chance */ + +#ifdef WIN32 + Sleep ( 1 ) ; +#elif defined(sgi) + sginap ( 1 ) ; +#else + usleep ( 1000 ) ; +#endif + } + + return 0 ; +} + + diff --git a/src/Input/jsinput.cxx b/src/Input/jsinput.cxx new file mode 100644 index 000000000..48d0d74be --- /dev/null +++ b/src/Input/jsinput.cxx @@ -0,0 +1,117 @@ +// jsinput.cxx -- wait for and identify input from joystick +// +// Written by Tony Peden, started May 2001 +// +// Copyright (C) 2001 Tony Peden (apeden@earthlink.net) +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#include +#include +#include +#include + + +jsInput::jsInput(jsSuper *j) { + jss=j; + pretty_display=false; + joystick=axis=button=-1; + axis_threshold=0.2; +} + +jsInput::~jsInput(void) {} + +int jsInput::getInput(void){ + + bool gotit=false; + + float delta; + int i,current_button=0,button_bits; + + joystick=axis=button=-1; + + if(pretty_display) { + printf ( "+----------------------------------------------\n" ) ; + printf ( "| Btns " ) ; + + for ( i = 0 ; i < jss->getJoystick()->getNumAxes() ; i++ ) + printf ( "Ax:%1d ", i ) ; + + for ( ; i < 8 ; i++ ) + printf ( " " ) ; + + printf ( "|\n" ) ; + + printf ( "+----------------------------------------------\n" ) ; + } + + + jss->firstJoystick(); + do { + jss->getJoystick()->read ( &button_iv[jss->getCurrentJoystickId()], + axes_iv[jss->getCurrentJoystickId()] ) ; + } while( jss->nextJoystick() ); + + + + while(!gotit) { + jss->firstJoystick(); + do { + + jss->getJoystick()->read ( ¤t_button, axes ) ; + + if(pretty_display) printf ( "| %04x ", current_button ) ; + + for ( i = 0 ; i < jss->getJoystick()->getNumAxes(); i++ ) { + + delta = axes[i] - axes_iv[jss->getCurrentJoystickId()][i]; + if(pretty_display) printf ( "%+.1f ", delta ) ; + if(!gotit) { + if( fabs(delta) > axis_threshold ) { + gotit=true; + joystick=jss->getCurrentJoystickId(); + axis=i; + } else if( current_button != 0 ) { + gotit=true; + joystick=jss->getCurrentJoystickId(); + button_bits=current_button; + } + } + } + + if(pretty_display) { + for ( ; i < 8 ; i++ ) + printf ( " . " ) ; + } + + + } while( jss->nextJoystick() && !gotit); + if(pretty_display) { + printf ( "|\r" ) ; + fflush ( stdout ) ; + } + + ulMilliSecondSleep(1); + } + if(button_bits != 0) { + for(int i=1;i<=31;i++) { + if( ( button_bits & (1 << i) ) > 0 ) { + button=i; + break; + } + } + } +} + diff --git a/src/Input/jsinput.h b/src/Input/jsinput.h new file mode 100644 index 000000000..b173a3a71 --- /dev/null +++ b/src/Input/jsinput.h @@ -0,0 +1,59 @@ +// jsinput.h -- wait for and identify input from joystick +// +// Written by Tony Peden, started May 2001 +// +// Copyright (C) 2001 Tony Peden (apeden@earthlink.net) +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + + +#ifndef _JSINPUT_H +#define _JSINPUT_H + +#include +#include + +class jsInput { + private: + jsSuper *jss; + bool pretty_display; + float axes[_JS_MAX_AXES]; + float axes_iv[MAX_JOYSTICKS][_JS_MAX_AXES]; + int button_iv[MAX_JOYSTICKS]; + + int joystick,axis,button; + + float axis_threshold; + + public: + jsInput(jsSuper *jss); + ~jsInput(void); + + inline void displayValues(bool bb) { pretty_display=bb; } + + int getInput(void); + + inline int getInputJoystick(void) { return joystick; } + inline int getInputAxis(void) { return axis; } + inline int getInputButton(void) { return button; } + + inline float getReturnThreshold(void) { return axis_threshold; } + inline void setReturnThreshold(float ff) + { if(fabs(ff) <= 1.0) axis_threshold=ff; } +}; + + +#endif diff --git a/src/Input/jssuper.cxx b/src/Input/jssuper.cxx new file mode 100644 index 000000000..4e1bf8059 --- /dev/null +++ b/src/Input/jssuper.cxx @@ -0,0 +1,83 @@ +// jssuper.cxx -- manage access to multiple joysticks +// +// Written by Tony Peden, started May 2001 +// +// Copyright (C) 2001 Tony Peden (apeden@earthlink.net) +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include // plib/js.h should really include this !!!!!! +#include + +#include + + +jsSuper::jsSuper(void) { + int i; + + activeJoysticks=0; + currentJoystick=0; + first=-1; + last=0; + for ( i = 0; i < MAX_JOYSTICKS; i++ ) + js[i] = new jsJoystick( i ); + + for ( i = 0; i < MAX_JOYSTICKS; i++ ) + { + active[i] = ! ( js[i]->notWorking () ); + if ( active[i] ) { + activeJoysticks++; + if(first < 0) { + first=i; + } + last=i; + } + } + +} + + +int jsSuper::nextJoystick(void) { + int i; + if(!activeJoysticks) return 0; + if(currentJoystick == last ) return 0; + currentJoystick++; + while(!active[currentJoystick]){ currentJoystick++; }; + return 1; +} + +int jsSuper::prevJoystick(void) { + int i; + if(!activeJoysticks) return 0; + if(currentJoystick == first ) return 0; + currentJoystick--; + while(!active[currentJoystick]){ currentJoystick--; }; + return 1; +} + + + + +jsSuper::~jsSuper(void) { + int i; + for ( i = 0; i < MAX_JOYSTICKS; i++ ) + delete js[i]; +} + + + + + diff --git a/src/Input/jssuper.h b/src/Input/jssuper.h new file mode 100644 index 000000000..356256dfe --- /dev/null +++ b/src/Input/jssuper.h @@ -0,0 +1,65 @@ +// jssuper.h -- manage access to multiple joysticks +// +// Written by Tony Peden, started May 2001 +// +// Copyright (C) 2001 Tony Peden (apeden@earthlink.net) +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#ifndef _JSSUPER_H +#define _JSSUPER_H + + +#ifdef HAVE_WINDOWS_H +# include +#endif + +#include // plib/js.h should really include this !!!!!! +#include + +#define MAX_JOYSTICKS 8 + +class jsSuper { + private: + int activeJoysticks; + int active[MAX_JOYSTICKS]; + int currentJoystick; + int first, last; + jsJoystick* js[MAX_JOYSTICKS]; + + public: + jsSuper(void); + ~jsSuper(void); + + inline int getNumJoysticks(void) { return activeJoysticks; } + + inline int atFirst(void) { return currentJoystick == first; } + inline int atLast(void) { return currentJoystick == last; } + + inline void firstJoystick(void) { currentJoystick=first; } + inline void lastJoystick(void) { currentJoystick=last; } + + int nextJoystick(void); + int prevJoystick(void); + + inline jsJoystick* getJoystick(int Joystick) + { currentJoystick=Joystick; return js[Joystick]; } + + inline jsJoystick* getJoystick(void) { return js[currentJoystick]; } + + inline int getCurrentJoystickId(void) { return currentJoystick; } +}; + +#endif