00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef _GAMEPAD_H_
00028 #define _GAMEPAD_H_
00029
00035 #include <linux/joystick.h>
00036
00037 #include <unistd.h>
00038 #include <stdio.h>
00039 #include <stdlib.h>
00040 #include <signal.h>
00041 #include <string.h>
00042 #include <fcntl.h>
00043 #include <vector>
00044
00045 #include <sigc++/functors/slot.h>
00046 #include <sigc++/functors/ptr_fun.h>
00047 #include <sigc++/functors/mem_fun.h>
00048 #include <boost/shared_ptr.hpp>
00049
00095
00096 class Button
00097 {
00098 public:
00099 Button()
00100 {
00101 value=0;
00102 }
00104 int value;
00105
00107 sigc::slot<void, int> callback;
00108 };
00109
00110 typedef boost::shared_ptr<Button> ButtonPtr;
00111
00117 class Gamepad
00118 {
00119 public:
00121 typedef enum {AXIS,BUTTON} e_type;
00122
00126 Gamepad():
00127 ret(0),
00128 fd(0),
00129 n_buttons(0),
00130 n_axes(0)
00131 {
00132 }
00133
00137 ~Gamepad()
00138 {
00139 close(fd);
00140 }
00141
00142
00149 int startComm(const char*device)
00150 {
00151 fd = open(device, O_RDONLY | O_NONBLOCK);
00152 if(fd<0)
00153 {
00154 sprintf(err,"Unable to open device: %s",device);
00155 return -3;
00156 }
00157
00158 ret=ioctl(fd, JSIOCGAXES, &n_axes);
00159 if(ret<0)
00160 {
00161 strcpy(err,"Unable to read number of axes");
00162 return -3;
00163 }
00164
00165 ret=ioctl(fd, JSIOCGBUTTONS, &n_buttons);
00166 if(ret<0)
00167 {
00168 strcpy(err,"Unable to read number of buttons");
00169 return -3;
00170 }
00171
00172 ret=ioctl(fd, JSIOCGNAME(sizeof(name)), name);
00173 if(ret<0)
00174 strcpy(name,"Unknown");
00175
00176 printf("\33[1m\33[36mGamepad\33[0m %s\n",name);
00177
00178 for(int i=0;i<n_buttons;i++)
00179 {
00180 ButtonPtr button(new Button);
00181 buttons_.push_back(button);
00182 }
00183
00184 for(int i=0;i<n_axes;i++)
00185 {
00186 ButtonPtr button(new Button);
00187 axes_.push_back(button);
00188 }
00189
00190 return 0;
00191 }
00192
00198 int dispatch(bool debug=false)
00199 {
00200 struct js_event buffer[64];
00201
00202 ret = read (fd, buffer, sizeof(struct js_event)*64);
00203 if(ret<0)
00204 return 0;
00205
00206 for(int i=0; i<ret/(signed int)sizeof(struct js_event);i++)
00207 {
00208 if(buffer[i].type & JS_EVENT_BUTTON & ~JS_EVENT_INIT)
00209 {
00210 if(debug)printf("Button %d Value %d\n",buffer[i].number,buffer[i].value);
00211 if(buttons_[buffer[i].number]->callback.empty())
00212 continue;
00213
00214 buttons_[buffer[i].number]->value = buffer[i].value;
00215 buttons_[buffer[i].number]->callback(buttons_[buffer[i].number]->value);
00216 }else if(buffer[i].type == JS_EVENT_AXIS)
00217 {
00218 if(debug)printf("Axis %d Value %d\n",buffer[i].number,buffer[i].value);
00219 if(axes_[buffer[i].number]->callback.empty())
00220 continue;
00221
00222 axes_[buffer[i].number]->value = buffer[i].value;
00223 axes_[buffer[i].number]->callback(axes_[buffer[i].number]->value);
00224 }
00225 }
00226
00227 return 0;
00228 }
00229
00241 void plerr(int ret)
00242 {
00243 if(ret==-1)
00244 {
00245 printf("Error!! ");
00246 printf("%s (raising SIGINT)\n",err);
00247 raise(SIGINT);
00248 }else if(ret==-2)
00249 {
00250 printf("Warning!! ");
00251 printf("%s\n",err);
00252 }else if(ret==-3)
00253 {
00254 printf("Error!! ");
00255 printf("%s, ",err);fflush(stdout);
00256 perror(NULL);
00257 raise(SIGINT);
00258 }
00259 }
00260
00261
00262 ButtonPtr buttons(uint i)
00263 {
00264 if(i>0 || i<buttons_.size())
00265 return buttons_[i];
00266 else
00267 {
00268 ButtonPtr empty;
00269 return empty;
00270 }
00271 }
00272
00273 ButtonPtr axes(uint i)
00274 {
00275 if(i>0 || i<axes_.size())
00276 return axes_[i];
00277 else
00278 {
00279 ButtonPtr empty;
00280 return empty;
00281 }
00282 }
00283
00284 private:
00285
00287 std::vector<ButtonPtr> buttons_;
00289 std::vector<ButtonPtr> axes_;
00290
00292 int ret;
00293
00295 int fd;
00296
00298 int n_buttons;
00299
00301 int n_axes;
00302
00304 __u8 m_axes[ABS_CNT];
00306 __u16 m_buttons[KEY_MAX - BTN_MISC + 1];
00307
00309 char name[1024];
00310
00312 char err[1024];
00313
00315 char text[1024];
00316 };
00317 #endif