/* * InputDevice.cpp * Copyright (c) 1996-1999 Vojtech Pavlik, 2001-2002 J. "MUFTI" Scheurich */ /* * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "InputDevice.h" #include #include #include "SFRotation.h" #ifdef WIN32 double copysign (double x, double y) { if (y>=0) return fabs(x); else return -fabs(x); } #endif float InputDevice::accelerate(float value,int num_axis) { float result=0; if (get_acceleration(num_axis)!=1.0) { # ifdef HAVE_POWF result=copysign(powf(get_acceleration(num_axis),fabs(value))-1,value); # else result=copysign(pow((double)get_acceleration(num_axis),fabs(value))-1, value); # endif } result+=value*get_factor(num_axis); return result*get_sign(num_axis); } static int max_position(float f1,float f2,float f3) { if (fabs(f1) >= fabs(f2)) if (fabs(f1) >= fabs(f3)) return 0; if (fabs(f2) >= fabs(f3)) if (fabs(f2) >= fabs(f1)) return 1; if (fabs(f3) >= fabs(f2)) if (fabs(f3) >= fabs(f1)) return 2; assert(0); } static int min_position(float f1,float f2,float f3) { if (fabs(f1) <= fabs(f2) ) if (fabs(f1) <= fabs(f3)) return 0; if (fabs(f2) <= fabs(f3)) if (fabs(f2) <= fabs(f1)) return 1; if (fabs(f3) <= fabs(f2)) if (fabs(f3) <= fabs(f1)) return 2; assert(0); } // test if value belongs to the greater values in 1, 2 (or 3) dimensions bool InputDevice::max_value(int index,TransformMode* tm) { if (tm==NULL) return true; if (tm->tdimension==TM_3D) return(true); if (tm->tdimension==TM_2D) if (index<3) { if (index!=min_position(value[0],value[1],value[2])) return true; } else if (index!=(3+min_position(value[3],value[4],value[5]))) return true; if (tm->tdimension==TM_1D) if (index<3) { if (index==max_position(value[0],value[1],value[2])) return true; } else if (index==(3+max_position(value[3],value[4],value[5]))) return true; return false; } void InputDevice::set_firstflag(void) { for (int i=0;i<7;i++) if (!get_zero_on_release(i)) firstflag[i]=true; } // return value, if device deliver zero if you release it, // otherwise return difference to last value float InputDevice::get_value(int index,bool check_only,int num_axis) { // value > zerosize ? float zerosize=get_zero_size_fraction(num_axis)*maxvalue(num_axis); if (fabs(value[index]) < zerosize) return 0; float val; // subtract nullsize from value if (value[index]>0) val=value[index]-zerosize; else val=value[index]+zerosize; if (get_zero_on_release(num_axis)) return(accelerate(val,num_axis)); else { float ret; if (firstflag[index]) { ret=0.0; if (check_only) { if (val!=0) { firstflag[index]=false; oldvalue[index]=val; } return(0); } firstflag[index]=false; } else ret=accelerate(val,num_axis)- accelerate(oldvalue[index],num_axis); if (!check_only) oldvalue[index]=val; return ret; } } float InputDevice::get_value(TransformMode* tm, int index, bool check_only, int num_axis, bool current) { if (ignore[num_axis]) return 0; if (current) { // value > zerosize ? float zerosize=get_zero_size_fraction(num_axis)*maxvalue(num_axis); if (fabs(value[index]) < zerosize) return 0; float val; // subtract nullsize from value if (value[index]>0) val=value[index]-zerosize; else val=value[index]+zerosize; return val; } else { if (!max_value(index,tm)) return 0.0; return get_value(index,check_only,num_axis); } } #define INPUT_DEVICE_GET(functionname,index,num_axis) \ float functionname (TransformMode* tm,bool check_only, bool current) \ { return get_value(tm, index, check_only, num_axis, current); } INPUT_DEVICE_GET(InputDevice::get_x,0,num_axis_x) INPUT_DEVICE_GET(InputDevice::get_y,1,num_axis_y) INPUT_DEVICE_GET(InputDevice::get_z,2,num_axis_z) INPUT_DEVICE_GET(InputDevice::get_xrot,3,num_axis_xrot) INPUT_DEVICE_GET(InputDevice::get_yrot,4,num_axis_yrot) INPUT_DEVICE_GET(InputDevice::get_zrot,5,num_axis_zrot) INPUT_DEVICE_GET(InputDevice::get_angle,6,num_axis_angle) Vec3f& InputDevice::get_vector(TransformMode* tm) { static Vec3f v; v.x=get_x(tm); v.y=get_y(tm); v.z=get_z(tm); if (get_number_axes()==4) v[2]=-v[2]; TMode mode=tm->tmode; if (mode==TM_TRANSLATE) { if (get_number_axes()==2) if (tm->t2axes==TM_NEAR_FAR) { float temp=v[2]; v[2]=-v[1]; v[1]=temp; } } else if (mode==TM_ROCKET) { v[0]=0; v[1]=0; } else if (mode==TM_HOVER) { if (get_number_axes()==3) { v[0]=0; } else if (get_number_axes()==2) if (tm->t2axes==TM_NEAR_FAR) { v[2]=-v[1]; v[0]=0; v[1]=0; } else if (tm->t2axes==TM_UP_DOWN) { v[1]=v[1]; v[0]=0; v[2]=0; } } else if (mode==TM_SCALE) { v[0]=-v[0]; v[2]=-v[2]; if (get_number_axes()==2) if (tm->t2axes==TM_NEAR_FAR) { float temp=v[2]; v[2]=-v[1]; v[1]=temp; } } else if (mode==TM_CENTER) { if (get_number_axes()==2) if (tm->t2axes==TM_NEAR_FAR) { float temp=v[2]; v[2]=-v[1]; v[1]=temp; } } for (int i=0;i<3;i++) v[i] *= xyzfactor; return v; } EulerAngles& InputDevice::get_eulerAngles(TransformMode* tm, bool check_only, bool current) { bool rotationOnly=false; bool rocketOnly=false; bool hoverOnly=false; static EulerAngles euler; // check for constraints on 2 axes or 3 axes or 4 axes devices if (get_number_axes()<=4) if (tm!=NULL) if (tm->tmode==TM_ROTATE) rotationOnly=true; else if (tm->tmode==TM_ROCKET) rocketOnly=true; if (tm!=NULL) if (tm->tmode==TM_HOVER) hoverOnly=true; if (rotationOnly) { if (get_number_axes()==4) { euler.x=/*RAD2DEG*/(-get_y(tm, check_only, current)); euler.y=/*RAD2DEG*/( get_xrot(tm, check_only, current)); euler.z=/*RAD2DEG*/(-get_x(tm, check_only, current)); } else if (get_number_axes()==3) { euler.x=/*RAD2DEG*/(-get_y(tm, check_only, current)); euler.y=/*RAD2DEG*/( get_z(tm, check_only, current)); euler.z=/*RAD2DEG*/(-get_x(tm, check_only, current)); } else if (get_number_axes()==2) { if (tm->t2axes==TM_NEAR_FAR) { euler.x=/*RAD2DEG*/(-get_y(tm, check_only, current)); euler.y=/*RAD2DEG*/(get_x(tm, check_only, current)); euler.z=0; } else { euler.x=/*RAD2DEG*/(-get_y(tm, check_only, current)); euler.y=0; euler.z=/*RAD2DEG*/(-get_x(tm, check_only, current)); } } } else if (rocketOnly) { if (get_number_axes()==4) { euler.x=/*RAD2DEG*/(-get_y(tm, check_only, current)); euler.y=/*RAD2DEG*/(-get_xrot(tm, check_only, current)); euler.z=/*RAD2DEG*/(-get_x(tm, check_only, current)); } else if (get_number_axes()==3) { if (tm->t2axes==TM_NEAR_FAR) { euler.x=/*RAD2DEG*/(-get_y(tm, check_only, current)); euler.y=/*RAD2DEG*/(-get_x(tm, check_only, current)); euler.z=0; } else { euler.x=/*RAD2DEG*/(-get_y(tm, check_only, current)); euler.y=0; euler.z=/*RAD2DEG*/(-get_x(tm, check_only, current)); } } } else if (hoverOnly) { if (get_number_axes()==4) { euler.x=0; euler.y=/*RAD2DEG*/(-get_xrot(tm, check_only, current)); euler.z=0; } else if (get_number_axes()==3) { euler.x=0; euler.y=/*RAD2DEG*/(-get_x(tm, check_only, current)); euler.z=0; } else if (get_number_axes()==2) { euler.x=0; euler.y=/*RAD2DEG*/(-get_x(tm, check_only, current)); euler.z=0; } else { euler.x=0; euler.y=/*RAD2DEG*/( get_yrot(tm, check_only, current)); euler.z=0; } } else { euler.x=/*RAD2DEG*/( get_xrot(tm, check_only, current)); euler.y=/*RAD2DEG*/( get_yrot(tm, check_only, current)); euler.z=/*RAD2DEG*/(-get_zrot(tm, check_only, current)); } if (!current) { euler.x *= rotfactor; euler.y *= rotfactor; euler.z *= rotfactor; } euler.w=EulOrdXYZs; return euler; } Quaternion& InputDevice::get_quaternion(TransformMode* tm, bool local, bool check_only) { Quaternion inputrot; EulerAngles euler=get_eulerAngles(tm, check_only, useCurrent()); if (local) { euler.x=-euler.x; euler.z=-euler.z; } inputrot=Eul_ToQuat(euler); inputrot.normalize(); static Quaternion ret; if (useCurrent()) { SFRotation rot(inputrot); const float *quat=rot.getValue(); float arc=quat[3]*rotfactor; SFRotation rot2(quat[0],quat[1],quat[2],arc); inputrot=rot2.getQuat(); inputrot.normalize(); if (get_zero_on_release(num_axis_angle)) ret=inputrot; else { if (firstflag[num_axis_angle]==true) firstflag[num_axis_angle]=false; else if (local) ret=old_quat.conj()*inputrot; else ret=inputrot*old_quat.conj(); if (!check_only) old_quat=inputrot; } SFRotation rot3(ret); const float *v=rot3.getValue(); float value[4] = { v[0], v[1], v[2], v[3] }; // limitation of axis make no sense for "wheel" type devices if (!isTracker() && get_zero_on_release(num_axis_angle)) { if (tm->tdimension==TM_2D) { int index=min_position(value[0],value[1],value[2]); value[index]=0; } else if (tm->tdimension==TM_1D) { int index=max_position(value[0],value[1],value[2]); for (int i=0;i<3;i++) if (i!=index) value[i]=0; } } SFRotation rot4(-value[0],value[1],value[2],value[3]); ret=rot4.getQuat(); ret.normalize(); } else ret=inputrot; return ret; } Quaternion& InputDevice::get_quaternion(TransformMode* tm, bool check_only) { return get_quaternion(tm, false, check_only); } Quaternion& InputDevice::get_localQuaternion(TransformMode* tm, bool check_only) { return get_quaternion(tm, true, check_only); } bool InputDevice::allzero(void) { if (useCurrent()) return false; if ((get_x(NULL,true)==0) && (get_y(NULL,true)==0) && (get_z(NULL,true)==0) && (get_xrot(NULL,true)==0) && (get_yrot(NULL,true)==0) && (get_zrot(NULL,true)==0) ) return true; else return false; } // signswap of value from axis int InputDevice::get_sign(int axis_number) { if ((sign_swap==NULL) || (axis_number>=number_max_axis)) return 1; else if (sign_swap[axis_number]) return -1; else return 1; } void InputDevice::set_sign_swap(int axis_number,bool value) { if (axis_number=number_max_axis)) return 1.0; else return factor[axis_number]; } void InputDevice::set_factor(int axis_number,float value) { if (axis_number=number_max_axis)) return 1.0; else return acceleration[axis_number]; } void InputDevice::set_acceleration(int axis_number,float value) { if (axis_number=number_max_axes)) return true; else return zero_on_release[axis_number]; } void InputDevice::set_zero_on_release(int axis_number,bool value) { if (axis_number=number_max_axis)) return 0; else return zero_size_fraction[axis_number]; } void InputDevice::set_zero_size_fraction(int axis_number,float value) { if (axis_number' ') { string[stringindex]=stringIn[i]; stringindex++; string[stringindex]=(char)0; } } return string; } void InputDevice::SetAxisInformation(char* info_string) { int i; char* freestring=remove_blanks(info_string); if (freestring==NULL) return; char* string=freestring; if (string[0]=='-') string++; bool found=false; for (i=0;i # include # include # include # include # include /* * initialise joystick * argument "device" is the joystickdevice, eg. "/dev/input/js0" or "/dev/js0" */ linux_joystick::linux_joystick(char *device) : InputDevice() { if ((fd = open(device, O_RDONLY)) < 0) { fprintf(stderr,"joystickdevice %s ",device); perror("joystick initialisation failed: "); } linux_js_factor=0.1; number_max_axis = 2; number_buttons = 2; version = 0x000800; strcpy(name,"Unknown"); ioctl(fd, JSIOCGVERSION, &version); ioctl(fd, JSIOCGAXES, &number_max_axis); ioctl(fd, JSIOCGBUTTONS, &number_buttons); ioctl(fd, JSIOCGNAME(NAME_LENGTH), name); fcntl(fd, F_SETFL, O_NONBLOCK); if (number_buttons>0) { button=new bool[number_buttons]; for (int i=0;i> 16, (version >> 8) & 0xff, version & 0xff); # endif } linux_joystick::~linux_joystick() { close(fd); } bool linux_joystick::readInputDevice(void) { bool ret=false; button_pressed=-1; button_released=-1; while (read(fd, &js, sizeof(struct js_event)) == sizeof(struct js_event)) { # ifdef DEBUG fprintf(stderr,"Event: type %d, time %d, number %d, value %d\n", js.type, js.time, js.number, js.value); # endif switch(js.type & ~JS_EVENT_INIT) { case JS_EVENT_BUTTON: ret=true; if (js.value) { button[js.number] = true; button_pressed=js.number; } else { button[js.number] = false; button_released=js.number; } break; case JS_EVENT_AXIS: ret=true; if (js.number==num_axis_x) value[0] = js.value/maxvalue(js.number)*linux_js_factor; if (js.number==num_axis_y) value[1] = -js.value/maxvalue(js.number)*linux_js_factor; if (js.number==num_axis_z) value[2] = -js.value/maxvalue(js.number)*linux_js_factor; if (js.number==num_axis_xrot) value[3] = js.value/maxvalue(js.number)*linux_js_factor; if (js.number==num_axis_yrot) value[4] = js.value/maxvalue(js.number)*linux_js_factor; if (js.number==num_axis_zrot) value[5] = js.value/maxvalue(js.number)*linux_js_factor; break; } if ((button_pressed!=-1) || (button_released!=-1)) break; } if (ret==false) if ((value[0]!=0) || (value[1]!=0) || (value[2]!=0) || (value[3]!=0) || (value[4]!=0) || (value[5]!=0)) { // deliver constantly values ret=true; } return ret; } # ifdef TEST_JOYSTICK int main(int argc,char** argv) { linux_joystick js=linux_joystick("/dev/input/js0"); while(1) if (js.readInputDevice()) printf("%f %f %f\n",js.get_x(),js.get_y(),js.get_z()); } # endif #endif #ifdef DIRECTX_JOYSTICK # include BOOL CALLBACK EnumJoysticksCallback(const DIDEVICEINSTANCE* pdidInstance, VOID* pContext ); /* * initialise joystick * argument "device" is the number of the joystick, eg. "0", "1" or "2" */ windows_joystick::windows_joystick(char *device) : InputDevice() { int characters_read; sscanf(device,"%d%n",&number_of_joystick,&characters_read); if ((characters_read!=strlen(device)) || (number_of_joystick>15) || (number_of_joystick<0)) { char msg[1024]; mysnprintf(msg,1024,"no joystick number \"%s\"",device); MessageBox(NULL,msg,"joystick initialisation failed",MB_OK); } if ( FAILED( InitDirectInput() ) ) { char msg[1024]; snprintf(msg,1024,"joystick number \"%s\" not present or error",device); MessageBox(NULL,msg,"joystick initialisation failed",MB_OK); } DIDEVCAPS lpDIDevCaps; lpDIDevCaps.dwSize=sizeof(DIDEVCAPS); g_pJoystick->GetCapabilities(&lpDIDevCaps); factor=1; rotfactor *= 0.1; number_max_axis=6; if (number_max_axis>0) { max_value=new int[6]; null_value=new int[6]; for (int i=0;i<6;i++) { max_value[i]=65535; null_value[i]=32768; } } number_buttons = lpDIDevCaps.dwButtons; DIDEVICEINSTANCE pdidi; pdidi.dwSize=sizeof(DIDEVICEINSTANCE); g_pJoystick->GetDeviceInfo(&pdidi); strcpy(name,pdidi.tszProductName); DIPROPDWORD dipdw; dipdw.diph.dwSize = sizeof(DIPROPDWORD); dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); dipdw.diph.dwObj = 0; dipdw.diph.dwHow = DIPH_DEVICE; g_pJoystick->GetProperty(DIPROP_VIDPID,&dipdw.diph); version = HIWORD(dipdw.dwData); ///////////////////////////////////////////////////////////////////////////77 // version = joycapabilities.wPid;//????????????????????????????????????????? ///////////////////////////////////////////////////////////////////////////// if (number_buttons>0) { button=new bool[number_buttons]; for (int i=0;i> 16, (version >> 8) & 0xff, version & 0xff); # endif } HRESULT windows_joystick::InitDirectInput() { HRESULT hr; if ( FAILED( hr = DirectInput8Create( GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&g_pDI, NULL ) ) ) return hr; // Look for a simple joystick we can use for this sample program. if ( FAILED( hr = g_pDI->EnumDevices( DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, NULL, DIEDFL_ATTACHEDONLY ) ) ) return hr; // Make sure we got a joystick if ( NULL == g_pJoystick ) { MessageBox( NULL, TEXT("Joystick not found. The sample will now exit."), TEXT("DirectInput Sample"), MB_ICONERROR | MB_OK ); return S_OK; } // Set the data format to "simple joystick" if ( FAILED( hr = g_pJoystick->SetDataFormat( &c_dfDIJoystick2 ) ) ) return hr; // Would // Set the cooperative level to let DInput know how this device should // interact with the system and with other DInput applications. // if( FAILED( hr = g_pJoystick->SetCooperativeLevel( NULL/*hier hwnd*/, DISCL_EXCLUSIVE | // DISCL_FOREGROUND ) ) ) // return hr; DIPROPRANGE diprg; diprg.diph.dwSize = sizeof(DIPROPRANGE); diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER); diprg.diph.dwHow = DIPH_DEVICE;//DIPH_BYID; diprg.diph.dwObj = 0; //pdidoi->dwType; // Specify the enumerated axis diprg.lMin = 0; diprg.lMax = +65535; if ( FAILED( hr = g_pJoystick->SetProperty( DIPROP_RANGE, &diprg.diph ) ) ) return hr; return S_OK; } windows_joystick::~windows_joystick() { } BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance, VOID* pContext ) { HRESULT hr; // Obtain an interface to the enumerated joystick. hr = g_pDI->CreateDevice( pdidInstance->guidInstance, &g_pJoystick, NULL ); // If it failed, then we can't use this joystick. (Maybe the user unplugged // it while we were in the middle of enumerating it.) if( FAILED(hr) ) return DIENUM_CONTINUE; // Stop enumeration. Note: we're just taking the first joystick we get. You // could store all the enumerated joysticks and let the user pick. return DIENUM_STOP; } bool windows_joystick::readInputDevice(void) { if( NULL == g_pJoystick ) return false; if( FAILED(g_pJoystick->Poll())) { HRESULT hr;hr = g_pJoystick->Acquire(); while( hr == DIERR_INPUTLOST ) hr = g_pJoystick->Acquire(); return false; } if(! FAILED( g_pJoystick->GetDeviceState( sizeof(DIJOYSTATE2), &js ) )) { int i; if (number_buttons>0) for( i = 0; i < 128; i++ ) { if ( js.rgbButtons[i] & 0x80 ) button[i] = true; } for (i=0;i<6;i++) value[i]=0; value[0] = (float)((int)js.lX-null_value[0])/maxvalue(0)*factor; value[1] = -(float)((int)js.lY-null_value[1])/maxvalue(1)*factor; // if (joycapabilities.wCaps & JOYCAPS_HASZ) value[2] = (float)((int)js.lZ-null_value[2])/maxvalue(2)*factor; // if (joycapabilities.wCaps & JOYCAPS_HASR) value[3] = (float)((int)js.rglSlider[0]-null_value[3])/maxvalue(3)*factor; // if (joycapabilities.wCaps & JOYCAPS_HASU) value[4] = (float)((int)js.lRz-null_value[4])/maxvalue(4)*factor; // if (joycapabilities.wCaps & JOYCAPS_HASV) // value[5] = (float)((int)js.rgdwPOV[0]-null_value[5])/maxvalue(5)*factor; // value[4] = 0; // value[3] = 0; } else return false; if ((value[0]!=0) || (value[1]!=0) || (value[2]!=0) || (value[3]!=0) || (value[4]!=0) || (value[5]!=0)) return true; return false; } # ifdef TEST_JOYSTICK int main(int argc,char** argv) { windows_joystick js=windows_joystick("0"); while(1) if (js.readInputDevice()) printf("%f %f %f\n",js.get_x(),js.get_y(),js.get_z()); } # endif #endif #ifdef WINDOWS_JOYSTICK # include /* * initialise joystick * argument "device" is the number of the joystick, eg. "0", "1" or "2" */ windows_joystick::windows_joystick(char *device) : InputDevice() { int characters_read; sscanf(device,"%d%n",&number_of_joystick,&characters_read); if ((characters_read!=strlen(device)) || (number_of_joystick>15) || (number_of_joystick<0)) { char msg[1024]; mysnprintf(msg,1024,"no joystick number \"%s\"",device); MessageBox(NULL,msg,"joystick initialisation failed",MB_OK); } MMRESULT result; result=joyGetDevCaps(number_of_joystick,&joycapabilities,sizeof(JOYCAPS)); if (result!=JOYERR_NOERROR) { char msg[1024]; mysnprintf(msg,1024,"joystick number \"%s\" not present or error",device); MessageBox(NULL,msg,"joystick initialisation failed",MB_OK); } windows_js_factor=1; rotfactor *= 0.1; number_max_axis=6; if (number_max_axis>0) { maximum=new int[6]; null_value=new int[6]; for (int i=0;i<6;i++) { switch(i) { case 0: maximum[i]=joycapabilities.wXmax; null_value[i]=(maximum[i]-joycapabilities.wXmin)/2; break; case 1: maximum[i]=joycapabilities.wYmax; null_value[i]=(maximum[i]-joycapabilities.wYmin)/2; break; case 2: maximum[i]=joycapabilities.wZmax; null_value[i]=(maximum[i]-joycapabilities.wZmin)/2; break; case 3: maximum[i]=joycapabilities.wRmax; null_value[i]=(maximum[i]-joycapabilities.wRmin)/2; break; case 4: maximum[i]=joycapabilities.wUmax; null_value[i]=(maximum[i]-joycapabilities.wUmin)/2; break; case 5: maximum[i]=joycapabilities.wVmax; null_value[i]=(maximum[i]-joycapabilities.wVmin)/2; break; } } } number_buttons = joycapabilities.wMaxButtons; version = joycapabilities.wPid; strcpy(name,joycapabilities.szPname); if (number_buttons>0) { button=new bool[number_buttons]; for (int i=0;i> 16, (version >> 8) & 0xff, version & 0xff); # endif } windows_joystick::~windows_joystick() { } bool windows_joystick::readInputDevice(void) { joyinfo_ex.dwSize=sizeof(JOYINFOEX); // joyinfo_ex.dwFlags=JOY_RETURNCENTERED ;// | JOY_RETURNBUTTONS; joyinfo_ex.dwFlags=JOY_RETURNALL | JOY_RETURNCENTERED; // | JOY_RETURNBUTTONS; MMRESULT result=joyGetPosEx(number_of_joystick, &joyinfo_ex); if (result == JOYERR_NOERROR) { int i; if (number_buttons>0) for (i=0;i= SDL_NumJoysticks()) { fprintf(stderr,"joystickdevice %s only %d joysticks\n",device, SDL_NumJoysticks()); fprintf(stderr,"joystick initialisation failed\n"); return; } const char *name = SDL_JoystickName(number_of_joystick); js = SDL_JoystickOpen(number_of_joystick); sdl_factor = 1; rotfactor *= 0.1; number_max_axis = SDL_JoystickNumAxes(js); int array_size = number_max_axis < 6 ? 6 : number_max_axis; maximum=new int[array_size]; null_value=new int[array_size]; for (int i=0;ixinput==NULL) { fprintf(stderr,"failed to initialize xinput device %s\n",device); free(swxinput); swxinput=NULL; return; } number_buttons=swxinput->number_buttons; if (number_buttons>0) { button=new bool[number_buttons]; for (i=0;inumber_axes; if (number_max_axis>0) { int array_size = number_max_axis < 7 ? 7 : number_max_axis; maximum=new float[array_size]; for (i=0;imaxvalue[i]; for (i=number_max_axis;i<7;i++) maximum[i]=1; } name="Unknown"; # ifdef DEBUG fprintf(stderr,"Xinputdevice %s has %d axes and %d buttons.\n", device, number_max_axis, number_buttons); # endif } xinput::~xinput(void) { swCloseXinputDevice(swxinput); free(swxinput); } bool xinput::readInputDevice(void) { button_pressed=-1; button_released=-1; if (swxinput==NULL) return false; for (int i=0;ixinput==NULL) return false; for (int j=0;j<7;j++) value[j] = 0; if (num_axis_x < number_max_axis) value[0]= xinput_factor*float(swxinput->axes[num_axis_x])/ swxinput->maxvalue[num_axis_x]; if (num_axis_y < number_max_axis) value[1]= xinput_factor*float(swxinput->axes[num_axis_y])/ swxinput->maxvalue[num_axis_y]; if (num_axis_z < number_max_axis) value[2]=-xinput_factor*float(swxinput->axes[num_axis_z])/ swxinput->maxvalue[num_axis_z]; if (num_axis_xrot < number_max_axis) value[3]= xinput_factor*float(swxinput->axes[num_axis_xrot])/ swxinput->maxvalue[num_axis_xrot]; if (num_axis_yrot < number_max_axis) value[4]= xinput_factor*float(swxinput->axes[num_axis_yrot])/ swxinput->maxvalue[num_axis_yrot]; if (num_axis_zrot < number_max_axis) value[5]= xinput_factor*float(swxinput->axes[num_axis_zrot])/ swxinput->maxvalue[num_axis_zrot]; if (num_axis_angle < number_max_axis) value[6]= xinput_factor*float(swxinput->axes[num_axis_angle])/ swxinput->maxvalue[num_axis_angle]; return true; } #endif // Driver for SpaceTec/LabTec Spaceball and clones. #ifdef HAVE_LIBSBALL /* * initialise spaceball * argument "device" is the spaceballdevice, eg. "/dev/ttyd2" or "/dev/ttyS0" */ spaceball::spaceball(char *device) : InputDevice() { sball=NULL; if ((sball = sball_open(device)) == NULL) { fprintf(stderr,"spaceballdevice %s ",device); fprintf(stderr,"initialisation failed\n"); return; } sball_init(sball); nullsize=0; maximum=32767.0; sball_factor=1.0; sball_set_nullregion(sball, nullsize, nullsize, nullsize, nullsize, nullsize, nullsize); number_max_axis = 6; number_buttons = 9; name="Unknown Spaceball"; if (number_buttons>0) { button=new bool[number_buttons]; for (int i=0;i0) { button=new bool[number_buttons]; for (int i=0;i 33); button[i++]=(((unsigned char)P5.m_P5Devices[number_p5].m_byBendSensor_Data[P5_INDEX]) > 33); button[i++]=(((unsigned char)P5.m_P5Devices[number_p5].m_byBendSensor_Data[P5_MIDDLE]) > 33); button[i++]=(((unsigned char)P5.m_P5Devices[number_p5].m_byBendSensor_Data[P5_RING]) > 33); button[i++]=(((unsigned char)P5.m_P5Devices[number_p5].m_byBendSensor_Data[P5_PINKY]) > 33); button[i++]=P5.m_P5Devices[number_p5].m_byButtons[0]; button[i++]=P5.m_P5Devices[number_p5].m_byButtons[1]; button[i++]=P5.m_P5Devices[number_p5].m_byButtons[2]; button[i++]=P5.m_P5Devices[number_p5].m_byButtons[3]; value[0]= (float)P5.m_P5Devices[number_p5].m_fx/maxvalue(0)*p5_factor; value[1]= (float)P5.m_P5Devices[number_p5].m_fy/maxvalue(1)*p5_factor; value[2]=-(float)P5.m_P5Devices[number_p5].m_fz/maxvalue(2)*p5_factor; value[3]= (float)(P5.m_P5Devices[number_p5].m_froll)/maxvalue(3)*p5_factor; value[4]= (float)(P5.m_P5Devices[number_p5].m_fyaw)/maxvalue(4)*p5_factor; value[5]= (float)(P5.m_P5Devices[number_p5].m_fpitch)/maxvalue(5)*p5_factor; } return bP5Present; } # ifdef TEST_P5 int main(int argc,char** argv) { windowsp5 device=windowsp5("/dev/ttyd2"); while(1) if (device.readInputDevice()) printf("%f %f %f\n",device.get_x(),device.get_y(),device.get_z()); } # endif #endif // M$Windows Driver for SpaceTec/LabTec Spaceball and clones. #ifdef HAVE_WINDOWS_SPACEBALL /* * initialise spaceball * argument "device" is the spaceballdevice, eg. "/dev/ttyd2" or "/dev/ttyS0" */ windowsspaceball::windowsspaceball(char *device) : InputDevice() { // REPLACE // sball=NULL; // REPLACE // if ((sball = sball_open(device)) == NULL) { fprintf(stderr,"windowsspaceballdevice %s ",device); fprintf(stderr,"initialisation failed\n"); return; } // REPLACE // sball_init(sball); nullsize=0; maximum=32767.0; windows_sball_factor=1.0; // REPLACE // sball_set_nullregion(sball, nullsize, nullsize, nullsize, // nullsize, nullsize, nullsize); number_max_axis = 6; number_buttons = 9; name="Unknown windowsspaceball"; if (number_buttons>0) { button=new bool[number_buttons]; for (int i=0;i /* * initialise Aflock */ AflockDevice::AflockDevice(char* dev) { /* insert your default configuration here */ device = dev; baudrate = 38400; // baudrate of device sync = 0; block = 0; numBrds = 2; // number of birds (without transmitter) transmit = 1; // number of bird transmitter unit hemi = RIGHT_HEM; // hemisphere (sit on the antenna block to see, // what is left or right 8-) filt = FILTER_DEFAULT;// use default filter set by flock autoconfig sudden_change_lock=true; report = 'Q'; calfile = ""; // calibration file /* end of configuratable data */ opened=false; flock=NULL; } AflockDevice::~AflockDevice(void) { if (flock!=NULL) if (opened) { flock->stop(); opened=false; delete flock; flock=NULL; } } void AflockDevice::setBaud(char* baudrate_string) { if (!string2int(baudrate,baudrate_string)) fprintf(stderr,"argument %s is not a integer, ignored\n",baudrate_string); } void AflockDevice::setSync(char* sync_string) { if (!string2int(sync,sync_string)) fprintf(stderr,"argument %s is not a integer, ignored\n",sync_string); } void AflockDevice::setBlock(char* block_string) { if (!string2int(block,block_string)) fprintf(stderr,"argument %s is not a integer, ignored\n",block_string); } void AflockDevice::setNumBrds(char* numBrds_string) { if (!string2int(numBrds,numBrds_string)) fprintf(stderr,"argument %s is not a integer, ignored\n",numBrds_string); } void AflockDevice::setTransmit(char* transmit_string) { if (!string2int(transmit,transmit_string)) fprintf(stderr,"argument %s is not a integer, ignored\n",transmit_string); } void AflockDevice::setHemi(char* hemi_string) { if (strcmp(hemi_string,"FRONT_HEM")==0) hemi=FRONT_HEM; else if (strcmp(hemi_string,"AFT_HEM")==0) hemi=AFT_HEM; else if (strcmp(hemi_string,"UPPER_HEM")==0) hemi=UPPER_HEM; else if (strcmp(hemi_string,"LOWER_HEM")==0) hemi=LOWER_HEM; else if (strcmp(hemi_string,"LEFT_HEM")==0) hemi=LEFT_HEM; else if (strcmp(hemi_string,"RIGHT_HEM")==0) hemi=RIGHT_HEM; else { fprintf(stderr,"argument %s is no of ",hemi_string); fprintf(stderr,"FRONT_HEM, AFT_HEM, UPPER_HEM, LOWER_HEM,"); fprintf(stderr," LEFT_HEM, RIGHT_HEM, ignored\n"); } } void AflockDevice::setFilt(char* filt_string) { if (strcmp(filt_string,"AC_NARROW")==0) filt=filt | AC_NARROW; else if (strcmp(filt_string,"AC_WIDE")==0) filt=filt | AC_WIDE; else if (strcmp(filt_string,"DC_FILTER")==0) filt=filt | DC_FILTER; else { fprintf(stderr,"argument %s is no of ",filt_string); fprintf(stderr,"AC_NARROW, AC_WIDE, DC_FILTER, ignored\n"); } } void AflockDevice::setSuddenChangeLock(char* sudden_string) { int sudden=1; if (!string2int(sudden,sudden_string)) fprintf(stderr,"argument %s is not a integer, ignored\n",sudden_string); if (sudden==0) sudden_change_lock=false; else sudden_change_lock=true; } void AflockDevice::setReport(char* report_string) { report=report_string[0]; } void AflockDevice::setCalfile(char* calfile_string) { calfile=calfile_string; } /* set device and initialise flock of birds */ Aflock* AflockDevice::getAflock(void) { if (!opened) { flock=NULL; flock = new Aflock(device,baudrate,sync,block, numBrds,transmit,hemi,filt,sudden_change_lock, report,calfile); if (!flock->start()) { flock=NULL; fprintf(stderr,"Aflock %s ",device); fprintf(stderr,"initialisation failed\n"); return flock; } sleep(1); opened=true; } return flock; } aflock::aflock(AflockDevice* device,char* receiver_string,bool headflag) : InputDevice() { head=false; wand=false; headNavigation=false; if (headflag) head=true; else wand=true; if (!string2int(receiver,receiver_string)) { fprintf(stderr,"argument %s is not a integer",receiver_string); flock=NULL; return; } if (device==NULL) { fprintf(stderr,"internal error, initialition failed"); flock=NULL; return; } flock=device->getAflock(); if (receiver==flock->getTransmitter()) flock->setMasterUseReceiver(); number_max_axis = 6; number_buttons = 3; name="Ascention flock of birds"; maximum=1.0; aflock_factor=1.0; degreefactor=M_PI/180.0; aflockFirstFlag=true; ignoreSize=0; int i; for (i=0;i<7;i++) set_zero_on_release(i,false); if (number_buttons>0) { button=new bool[number_buttons]; for (int i=0;iisActive()) { fprintf(stderr,"Bird not active\n"); return; } flock->prepareSample(); } bool aflock::readInputDevice(void) { button_pressed=-1; button_released=-1; if (flock==NULL) return false; if (!flock->isActive()) { fprintf(stderr,"Bird not active\n"); return false; } flock->sample(); for (int i=0;iyPos(receiver)/maxvalue(2)*aflock_factor; value[1]=-flock->zPos(receiver)/maxvalue(1)*aflock_factor; value[2]= flock->xPos(receiver)/maxvalue(0)*aflock_factor; if ((ignoreSize > 0) && !aflockFirstFlag) { #ifdef HAVE_AFLOCK_DEBUG #endif bool ret = true; if (fabs(old_value[0]-value[0])>ignoreSize) ret = false; if (fabs(old_value[1]-value[1])>ignoreSize) ret = false; if (fabs(old_value[2]-value[2])>ignoreSize) ret = false; if (ret == false) { fprintf(stderr,"ignoring jump flock %d: deltax=%f meter deltay=%f meter deltaz=%f meter\n", receiver, fabs(old_value[0]-value[0]), fabs(old_value[1]-value[1]), fabs(old_value[2]-value[2])); return false; } } old_value[0]=value[0]; old_value[1]=value[1]; old_value[2]=value[2]; aflockFirstFlag=false; #ifdef HAVE_AFLOCK_DEBUG if (ignoreSize == 0) printf("flock %d: x=%f meter y=%f meter z=%f meter\n",receiver, value[0],value[1],value[2]); #endif value[3]=-flock->yRot(receiver)/maxvalue(3)*degreefactor; value[4]=-flock->zRot(receiver)/maxvalue(4)*degreefactor; value[5]=-flock->xRot(receiver)/maxvalue(5)*degreefactor; return true; } void aflock::setIgnoreSize(const char* ignoresize_string) { if (!string2float(ignoreSize,ignoresize_string)) fprintf(stderr,"argument %s is not a float, ignored\n",ignoresize_string); } # ifdef TEST_AFLOCK int main(int argc,char** argv) { AflockDevice* device=new AflockDevice(); aflock device1(device,argv[1],true); for (int i=1;i<3000;i++) { if (device1.readInputDevice()) printf("1 %g %g %g\n",device1.get_x(),device1.get_y(),device1.get_z()); printf("1 rot %g %g %g\n",device1.get_xrot(),device1.get_yrot(),device1.get_zrot()); } delete device; } # endif #endif