# error This library requires C++
#endif
+#include <plib/js.h>
+
#include <simgear/compiler.h>
+#include <simgear/misc/commands.hxx>
#include <simgear/misc/props.hxx>
#include <Main/fgfs.hxx>
{
public:
- enum Action {
- ACTION_NONE,
- ACTION_SWITCH,
- ACTION_ADJUST,
- ACTION_ASSIGN
- };
-
+ /**
+ * Default constructor.
+ */
FGBinding ();
+
+
+ /**
+ * Copy constructor.
+ */
+ FGBinding (const FGBinding &binding);
+
+
+ /**
+ * Convenience constructor.
+ *
+ * @param node The binding will be built from this node.
+ */
FGBinding (const SGPropertyNode * node);
+
+
+ /**
+ * Destructor.
+ */
virtual ~FGBinding ();
- virtual Action getAction () const { return _action; }
- virtual SGPropertyNode * getProperty () { return _node; }
- virtual const SGPropertyNode * getProperty () const { return _node; }
- virtual const SGValue * getAdjustStep () const { return _adjust_step; }
- virtual const SGValue * getAssignValue () const { return _assign_value; }
+
+ /**
+ * Get the command name.
+ *
+ * @return The string name of the command for this binding.
+ */
+ virtual const string &getCommandName () const { return _command_name; }
+
+
+ /**
+ * Get the command itself.
+ *
+ * @return The command associated with this binding, or 0 if none
+ * is present.
+ */
+ virtual SGCommandMgr::command_t getCommand () const { return _command; }
+
+
+ /**
+ * Get the argument that will be passed to the command.
+ *
+ * @return A property node that will be passed to the command as its
+ * argument, or 0 if none was supplied.
+ */
+ virtual const SGPropertyNode * getArg () { return _arg; }
- virtual void setAction (Action action);
- virtual void setProperty (SGPropertyNode * node);
- virtual void setAdjustStep (const SGValue * step);
- virtual void setAssignValue (const SGValue * value);
+ /**
+ * Read a binding from a property node.
+ *
+ * @param node The property node containing the binding.
+ */
virtual void read (const SGPropertyNode * node);
+
+ /**
+ * Fire a binding.
+ */
virtual void fire () const;
-// virtual void fire (double value);
-// virtual void fire (int xdelta, int ydelta);
+
+
+ /**
+ * Fire a binding with a setting (i.e. joystick axis).
+ *
+ * A double 'setting' property will be added to the arguments.
+ *
+ * @param setting The input setting, usually between -1.0 and 1.0.
+ */
+ virtual void fire (double setting) const;
+
private:
- Action _action;
- SGPropertyNode * _node;
- const SGValue * _adjust_step;
- const SGValue * _assign_value;
+ string _command_name;
+ SGCommandMgr::command_t _command;
+ mutable SGPropertyNode * _arg;
+ mutable SGPropertyNode * _setting;
+ mutable SGCommandState * _command_state;
};
public:
enum {
- MOD_NONE = 0,
- MOD_SHIFT = 1,
- MOD_CTRL = 2,
- MOD_ALT = 4,
- MOD_MAX = 8 // one past all modifiers
+ FG_MOD_NONE = 0,
+ FG_MOD_UP = 1, // key- or button-up
+ FG_MOD_SHIFT = 2,
+ FG_MOD_CTRL = 4,
+ FG_MOD_ALT = 8,
+ FG_MOD_MAX = 16 // enough to handle all combinations
};
FGInput();
* @param modifiers Modifier keys pressed (bitfield).
* @param x The mouse x position at the time of keypress.
* @param y The mouse y position at the time of keypress.
- * @see #MOD_SHIFT
- * @see #MOD_CTRL
- * @see #MOD_ALT
+ * @see #FG_MOD_SHIFT
+ * @see #FG_MOD_CTRL
+ * @see #FG_MOD_ALT
*/
virtual void doKey (int k, int modifiers, int x, int y);
+private:
+
+ // Constants
+ enum
+ {
+ MAX_KEYS = 1024,
+
+ #ifdef WIN32
+ MAX_JOYSTICKS = 2,
+ #else
+ MAX_JOYSTICKS = 10,
+ #endif
+ MAX_AXES = _JS_MAX_AXES,
+ MAX_BUTTONS = 32
+ };
+
+
+ typedef vector<FGBinding> binding_list_t;
+
/**
- * Fire off a single-trigger action.
- *
- * <p>This method fires an action triggered by a key or button
- * press, with no additional quantity information.</p>
- *
- * @param binding The property node with the binding.
+ * Settings for a key or button.
*/
- virtual void action (const SGPropertyNode * binding);
+ struct button {
+ button ()
+ : is_repeatable(false),
+ last_state(-1)
+ {}
+ bool is_repeatable;
+ int last_state;
+ binding_list_t bindings[FG_MOD_MAX];
+ };
/**
- * Fire off a quantity action.
- *
- * <p>This method fires an action triggered by a change in value,
- * such as a slider or axis.</p>
- *
- * @param action The property node with the binding.
- * @param value The new value.
+ * Settings for a single joystick axis.
*/
-// virtual void action (const SGPropertyNode * binding, double value);
+ struct axis {
+ axis ()
+ : last_value(9999999),
+ tolerance(0.002),
+ low_threshold(-0.9),
+ high_threshold(0.9)
+ {}
+ float last_value;
+ float tolerance;
+ binding_list_t bindings[FG_MOD_MAX];
+ float low_threshold;
+ float high_threshold;
+ struct button low;
+ struct button high;
+ };
/**
- * Fire off a movement action.
- *
- * <p>This method fires an action triggered by relative movement
- * rather than an absolute value; it is especially applicable to
- * mouse-movement bindings.</p>
- *
- * @param binding The property node containing the binding.
- * @param xdelta The amount of X movement.
- * @param ydelta The amount of Y movement.
+ * Settings for a joystick.
*/
-// virtual void action (const SGPropertyNode * binding, int xdelta, int ydelta);
+ struct joystick {
+ virtual ~joystick () {
+ delete js;
+ delete[] axes;
+ delete[] buttons;
+ }
+ int naxes;
+ int nbuttons;
+ jsJoystick * js;
+ axis * axes;
+ button * buttons;
+ };
+
+
+ /**
+ * Initialize key bindings.
+ */
+ void _init_keyboard ();
+
+
+ /**
+ * Initialize joystick bindings.
+ */
+ void _init_joystick ();
-private:
- typedef map<int,vector<FGBinding> > keyboard_map;
- keyboard_map _key_bindings[MOD_MAX];
+ /**
+ * Initialize a single button.
+ */
+ inline void _init_button (const SGPropertyNode * node,
+ button &b,
+ const string name);
+
+
+ /**
+ * Update the keyboard.
+ */
+ void _update_keyboard ();
+
+
+ /**
+ * Update the joystick.
+ */
+ void _update_joystick ();
+
+
+ /**
+ * Update a single button.
+ */
+ inline void _update_button (button &b, int modifiers, bool pressed);
+
+
+ /**
+ * Read bindings and modifiers.
+ */
+ void _read_bindings (const SGPropertyNode * node,
+ binding_list_t * binding_list,
+ int modifiers);
+
+ /**
+ * Look up the bindings for a key code.
+ */
+ const vector<FGBinding> &_find_key_bindings (unsigned int k, int modifiers);
+
+ button _key_bindings[MAX_KEYS];
+ joystick _joystick_bindings[MAX_JOYSTICKS];
};
+// Handle keyboard events
+void GLUTkey(unsigned char k, int x, int y);
+void GLUTkeyup(unsigned char k, int x, int y);
+void GLUTspecialkey(int k, int x, int y);
+void GLUTspecialkeyup(int k, int x, int y);
+
extern FGInput current_input;
#endif // _CONTROLS_HXX