// Description: a node that spits out joystick data
//
//notes:
//
//- derived nodes inherit all messages from their base classes
//
- see reset method for default settings
//
- reads straight from the joystick port on the host machine.
//
- useful if you want driving without trackd.
//
//
//
// Category: User
// Author: Ben Chang
// Revision: 2/10/04
//
#include
#include
#include
#include "ygWorld.h"
#include "ygUtil.h"
#include "ygUser.h"
#include "JoystickNode.h"
using namespace std;
extern "C" ygNode* construct_JoystickNode(const char* name,bool master) { return new JoystickNode(name,master); }
JoystickNode::JoystickNode(const char* name,bool master) : ygNode(name,master)
{
char axiscount = 4;
char buttoncount=16;
int version = 0x000800;
char jname[NAME_LENGTH] = "Unknown";
char *devname = "/dev/js0";
if ((fd_ = open(devname, O_RDONLY)) < 0) {
perror("couldn't open joystick port");
}
ioctl(fd_, JSIOCGVERSION, &version);
ioctl(fd_, JSIOCGAXES, &axiscount);
ioctl(fd_, JSIOCGBUTTONS, &buttoncount);
ioctl(fd_, JSIOCGNAME(NAME_LENGTH), jname);
for (int i=0;i<16;i++) {
buttonmapping[i] = i;
buttons[i]=0;
}
for (int i=0;i<4;i++) {
axis[i]=0;
}
}
void JoystickNode::reset(void)
{
ygNode::reset();
}
void JoystickNode::message(const ygMessage& msg)
{
//move the user to the absolute position given
// button remapping
if (msg == "remapButton")
{
if (msg.args.size()>1)
setButtonMapping (msg.intArg(0),msg.intArg(1));
}
//turn on collision detection with objects
else
ygNode::message(msg);
}
void JoystickNode::setButtonMapping(int real,int reported)
{
buttonmapping[real]=reported;
}
void JoystickNode::app(void)
{
// 1. read joystick data
// 2. check events, update joystick values, check and move and stuff.
//if the joystick X direction is above threshold
//fprintf (stderr,"x: %f y:%f\n",CAVE_JOYSTICK_X,CAVE_JOYSTICK_Y);
float fJS_X,fJS_Y;
struct js_event js;
struct timeval tv;
int readrc;
fd_set set;
tv.tv_sec = 0;
tv.tv_usec = JS_SELECT_UDELAY;
FD_ZERO (&set);
FD_SET (fd_,&set);
if (select(fd_+1,&set,NULL,NULL, &tv))
{
readrc = read(fd_,&js,sizeof(struct js_event));
if (readrc == sizeof(struct js_event)) {
//printf ("%d\n",js.type);
switch ((js.type&3)) {
case JS_EVENT_BUTTON:
char messagestring[32];
//printf ("[button %d:%d] \n ",js.number, js.value);
buttons[buttonmapping[js.number]] = js.value;
if (js.value==1)
sprintf (messagestring,"button%d",js.number+1);
else
sprintf (messagestring,"buttonUp%d",js.number+1);
eventOccurred (messagestring);
break;
case JS_EVENT_AXIS:
float v=js.value;
if (v>32000) v=32000;
if (v<-32000) v=-32000;
v = v/32000;
//cerr << "axis " << js.number << ":" << js.value << "\n";
axis[js.number] = v;
// post events
char valuestring[32];
ygString args;
for (int i=0;i<4;i++) {
sprintf (valuestring,"axis%d=%f ",i+1,axis[i]);
args += valuestring;
}
eventOccurred ("axisChanged",args);
break;
}
} else if (errno != EAGAIN) {
perror ("\njoystick: error reading");
}
}
ygNode::app();
}