00001 /******************************************************************** 00002 Description: class for managing all kind of input devices 00003 part of the 3Dsia project 00004 created: StonedBones, 20.4.2000 00005 00006 History: 00007 date, name, changes, in funtion 00008 200400 StonedBones created source 00009 00010 ********************************************************************/ 00011 00012 00013 00014 #include "devices.h" 00015 00016 #include <dlfcn.h> 00017 #include <stdio.h> 00018 00019 /*................................................................... 00020 Description: Constructor 00021 Args: <none> 00022 Returns: <none> 00023 Created: StonedBones, 20.4.2000 00024 [ToDo:] 00025 [Comments:] 00026 Changes: 00027 -------------------------------------------------------------------*/ 00028 00029 Devices::Devices () { 00030 registeredDevices = 0; 00031 00032 for (int i = 0; i < DEVICE_EVENTS; i++) { 00033 events.push_back (0.0); 00034 }; 00035 }; 00036 00037 /*................................................................... 00038 Description: Destructor 00039 Args: <none> 00040 Returns: <none> 00041 Created: StonedBones, 20.4.2000 00042 [ToDo:] 00043 [Comments:] 00044 Changes: 00045 -------------------------------------------------------------------*/ 00046 00047 Devices::~Devices () { 00048 }; 00049 00050 /*................................................................... 00051 Description: loads and registers a new device plug-in 00052 Args: string filename: path to plug-in 00053 Returns: device name 00054 Created: StonedBones, 20.4.2000 00055 [ToDo:] 00056 [Comments:] 00057 Changes: 00058 -------------------------------------------------------------------*/ 00059 00060 string Devices::addDevicePlugIn (string filename) { 00061 typedef void* (*pfnPlugIn)(); 00062 pfnPlugIn getPlugIn; 00063 void* handler; 00064 00065 if ((handler = (pfnPlugIn) dlopen (filename.c_str (), RTLD_NOW)) != 0) { 00066 if ((getPlugIn = (pfnPlugIn)dlsym (handler, "GetDevicePlugIn")) != 0) { 00067 devs.push_back ((DevicePlugIn*) getPlugIn ()); 00068 devs.back ()->openDevice (); 00069 00070 vector<int> tmpV; 00071 for (int i = 0; i < (devs.back ()->buttons () + (devs.back ()->axes () * 2)); i++) { 00072 tmpV.push_back (0); 00073 }; 00074 cEvents.push_back (tmpV); 00075 00076 return string (devs.back ()->name ()); 00077 } else { 00078 return "Error: Not a 3Dsia device plugin !"; 00079 }; 00080 } else { 00081 return "Error: Couldn't open device plugin !"; 00082 }; 00083 }; 00084 00085 /*................................................................... 00086 Description: returns number of registered devices 00087 Args: <none> 00088 Returns: number of devices 00089 Created: StonedBones, 20.4.2000 00090 [ToDo:] 00091 [Comments:] 00092 Changes: 00093 -------------------------------------------------------------------*/ 00094 00095 int Devices::countDevices () { 00096 return devs.size (); 00097 }; 00098 00099 /*................................................................... 00100 Description: returns device-number of device-name 00101 Args: string name: name returned by addDevicePlugIn 00102 Returns: device number, -1 on failure 00103 Created: StonedBones, 20.4.2000 00104 [ToDo:] 00105 [Comments:] 00106 Changes: 00107 -------------------------------------------------------------------*/ 00108 00109 int Devices::nameToInt (string name) { 00110 for (CVectorDevicePlugIn::size_type i = 0; i < devs.size(); i++) { 00111 if (devs[i]->name () == name) return i; 00112 }; 00113 return -1; 00114 }; 00115 00116 /*................................................................... 00117 Description: returns name of device-number 00118 Args: int i: device-number 00119 Returns: device-name 00120 Created: StonedBones, 20.4.2000 00121 [ToDo:] 00122 [Comments:] 00123 Changes: 00124 -------------------------------------------------------------------*/ 00125 00126 string Devices::getDeviceName (int i) { 00127 if ((i >= 0) && ((CVectorDevicePlugIn::size_type)i < devs.size ())) { 00128 return devs[i]->name (); 00129 } else return "no such device"; 00130 }; 00131 00132 /*................................................................... 00133 Description: returns amount of axes 00134 Args: int i: device-number 00135 Returns: axes, -1 on failure 00136 Created: StonedBones, 20.4.2000 00137 [ToDo:] 00138 [Comments:] 00139 Changes: 00140 -------------------------------------------------------------------*/ 00141 00142 int Devices::getDeviceAxes (int i) { 00143 if ((i >= 0) && ((CVectorDevicePlugIn::size_type)i < devs.size ())) { 00144 return devs[i]->axes (); 00145 } else return -1; 00146 }; 00147 00148 /*................................................................... 00149 Description: return amount of buttons 00150 Args: int i: device-number 00151 Returns: buttons, -1 on failure 00152 Created: StonedBones, 20.4.2000 00153 [ToDo:] 00154 [Comments:] 00155 Changes: 00156 -------------------------------------------------------------------*/ 00157 00158 int Devices::getDeviceButtons (int i) { 00159 if ((i >= 0) && ((CVectorDevicePlugIn::size_type)i < devs.size ())) { 00160 return devs[i]->buttons (); 00161 } else return -1; 00162 }; 00163 00164 /*................................................................... 00165 Description: returns amount of slots 00166 Args: int i: device-number 00167 Returns: slots, -1 on failure 00168 Created: [name], [date] 00169 [ToDo:] 00170 [Comments:] 00171 slots = buttons + (axes * 2), because axes are splitted 00172 Changes: 00173 -------------------------------------------------------------------*/ 00174 00175 int Devices::getDeviceSlots (int i) { 00176 if ((i >= 0) && ((CVectorDevicePlugIn::size_type)i < devs.size ())) { 00177 return (devs[i]->buttons () + (devs[i]->axes () * 2)); 00178 } else return -1; 00179 }; 00180 00181 /*................................................................... 00182 Description: connect device slot to event 00183 Args: int device: device-number, int deviceslot: slot, DeviceEvent ev: event 00184 Returns: false on failure 00185 Created: StonedBones, 20.4.2000 00186 [ToDo:] 00187 [Comments:] 00188 Changes: 00189 -------------------------------------------------------------------*/ 00190 00191 bool Devices::connect (int device, int deviceslot, DeviceEvent ev) { 00192 if ((device >= 0) && ((CCEvents::size_type)device < cEvents.size ()) && (deviceslot < getDeviceSlots (device))) { 00193 cEvents[device][deviceslot] = ev; 00194 return true; 00195 } else return false; 00196 }; 00197 00198 /*................................................................... 00199 Description: returns event status 00200 Args: DeviceEvent ev: event to check 00201 Returns: event value 00202 Created: StonedBones, 20.4.2000 00203 [ToDo:] 00204 [Comments:] 00205 return value should be between 0.0 and 1.0 00206 Changes: 00207 -------------------------------------------------------------------*/ 00208 00209 float Devices::eventStatus (DeviceEvent ev) { 00210 if ((ev >= 0) && ((CEvents::size_type)ev < events.size ())) { 00211 return events[ev]; 00212 } else return 0.0; 00213 }; 00214 00215 /*................................................................... 00216 Description: returns value of device slot 00217 Args: int device: device, int slot: slot 00218 Returns: slot value 00219 Created: StonedBones, 20.4.2000 00220 [ToDo:] 00221 [Comments:] 00222 00223 Note: First button = slot 0, 00224 Last button = slot (buttons - 1), 00225 00226 First axis = slot (buttons) AND 00227 slot (buttons + 1) 00228 00229 Remember: Axes are splitted in two ! 00230 00231 Changes: 00232 -------------------------------------------------------------------*/ 00233 00234 float Devices::getSlot (int device, int slot) { 00235 if ((device >= 0) && ((CVectorDevicePlugIn::size_type)device < devs.size ()) && (slot >= 0) && (slot < getDeviceSlots (device))) { 00236 if (slot < getDeviceButtons (device)) { 00237 if (devs[device]->buttonPressed (slot)) { 00238 return 1.0; 00239 } else { 00240 return 0.0; 00241 }; 00242 } else { 00243 if (((slot - getDeviceButtons (device)) % 2) == 0) { 00244 if (devs[device]->axis ((slot - getDeviceButtons (device)) / 2) < 0) return 0.0; 00245 return (devs[device]->axis ((slot - getDeviceButtons (device)) / 2)) / 32767.0; 00246 } else { 00247 if (devs[device]->axis ((slot - getDeviceButtons (device)) / 2) > 0) return 0.0; 00248 return -(devs[device]->axis ((slot - getDeviceButtons (device)) / 2)) / 32767.0; 00249 }; 00250 }; 00251 } else return 0.0; 00252 }; 00253 00254 /*................................................................... 00255 Description: updates all devices 00256 Args: <none> 00257 Returns: false on failure 00258 Created: StonedBones, 20.4.2000 00259 [ToDo:] 00260 [Comments:] 00261 00262 This function has to be called frequently ! It refreshes the events 00263 00264 Changes: 00265 -------------------------------------------------------------------*/ 00266 00267 bool Devices::update () { 00268 if (devs.size () == 0) return false; 00269 00270 for (CEvents::size_type i = 0; i < events.size (); i++) { 00271 events[i] = 0.0; 00272 }; 00273 00274 for (CVectorDevicePlugIn::size_type i = 0; i < devs.size (); i++) { 00275 devs[i]->update (); 00276 for (CCEvents::size_type k = 0; k < cEvents[i].size (); k++) { 00277 if (events[cEvents[i][k]] == 0.0) events[cEvents[i][k]] = 0.0; 00278 }; 00279 }; 00280 00281 for (CVectorDevicePlugIn::size_type i = 0; i < devs.size (); i++) { 00282 for (CCEvents::size_type k = 0; k < cEvents[i].size (); k++) { 00283 if (events[cEvents[i][k]] == 0.0) events[cEvents[i][k]] += getSlot (i, k); 00284 }; 00285 }; 00286 00287 return true; 00288 }; 00289