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