00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include "P_SensorConfig.h"
00024 #include "Inform.h"
00025 #include "utilities.h"
00026
00027
00028
00029
00030
00031
00032
00033 enum Scanning_Behaviors { PARSE_FOR_NAMES, PARSE_FOR_DEVICE };
00034
00035 void SensorConfig::ScanSensorFiles (int behavior, SensorConfig *sensor, void* params) {
00036 JString sensorfile;
00037 FILE *file;
00038 int found_sensorfile=FALSE;
00039
00040 #if !defined(_MSC_VER)
00041
00042
00043 sensorfile = getenv("HOME");
00044 sensorfile += "/.vmdsensors";
00045 if ( (file = fopen(sensorfile,"r")) ) {
00046 found_sensorfile=TRUE;
00047 switch (behavior) {
00048 case PARSE_FOR_DEVICE:
00049 sensor->parseconfigfordevice(file, params);
00050 break;
00051 case PARSE_FOR_NAMES:
00052 parseconfigfornames(file, params);
00053 break;
00054 }
00055 fclose(file);
00056 }
00057 #endif
00058
00059
00060 if (!found_sensorfile) {
00061 char *sensorfile_str = getenv("VMDSENSORS");
00062 if (sensorfile_str && (file = fopen(sensorfile_str,"r"))) {
00063 found_sensorfile=TRUE;
00064 switch (behavior) {
00065 case PARSE_FOR_DEVICE:
00066 sensor->parseconfigfordevice(file, params);
00067 break;
00068 case PARSE_FOR_NAMES:
00069 parseconfigfornames(file, params);
00070 break;
00071 }
00072 fclose(file);
00073 }
00074 }
00075
00076
00077
00078 if (!found_sensorfile) {
00079 sensorfile = getenv("VMDDIR");
00080 #if defined(_MSC_VER)
00081 sensorfile += "\\.vmdsensors";
00082 #else
00083 sensorfile += "/.vmdsensors";
00084 #endif
00085 if ((file = fopen(sensorfile,"r"))) {
00086 switch (behavior) {
00087 case PARSE_FOR_DEVICE:
00088 sensor->parseconfigfordevice(file, params);
00089 break;
00090 case PARSE_FOR_NAMES:
00091 parseconfigfornames(file, params);
00092 break;
00093 }
00094 fclose(file);
00095 }
00096 }
00097
00098 }
00099
00100
00101 static int splitline(FILE *f, JString *argv, int maxarg) {
00102 int argc, pos;
00103 char buf[100], word[100];
00104 if(!fgets(buf,100,f)) return -1;
00105
00106 argc = 0;
00107 pos = 0;
00108 while(argc<maxarg && pos<100 && buf[pos]!=0 && buf[pos]!='\n'
00109 && buf[pos]!='\r') {
00110 if(buf[pos]!=' ' && buf[pos]!='\t') {
00111 sscanf(buf+pos,"%99s",word);
00112 pos += strlen(word);
00113 argv[argc] = (JString)word;
00114 argc++;
00115 }
00116 else pos++;
00117 }
00118
00119 return argc;
00120 }
00121
00122
00123 static int need_args(int argc,int need, int line) {
00124 if(need!=argc) {
00125 msgErr << "SensorConfig: Wrong number of arguments at line " << line << "." << sendmsg;
00126 msgErr << "Expected " << need << ", got " << argc << "." << sendmsg;
00127 return 1;
00128 }
00129 return 0;
00130 }
00131
00132 float SensorConfig::getfloat(const char *from, float defalt) {
00133 int ret;
00134 float f;
00135 ret=sscanf(from,"%f",&f);
00136 if(!ret) {
00137 msgErr << "SensorConfig: Error parsing float at line " << line << sendmsg;
00138 return defalt;
00139 }
00140 return f;
00141 }
00142
00143 int SensorConfig::needargs(int argc,int need) {
00144 return need_args(argc,need,line);
00145 }
00146
00147
00148 void SensorConfig::parseconfigfordevice(FILE *file, void *) {
00149
00150 int found=FALSE, argc;
00151 line = 0;
00152 JString argv[20];
00153 while ((argc=splitline(file,argv,20))>=0) {
00154 line++;
00155
00156 if (!argc) continue;
00157 if (argv[0][0]=='#') continue;
00158
00159 if (!compare(argv[0],"device")) {
00160 if (found) break;
00161 if (needargs(argc,3)) return;
00162 if (!compare(argv[1],device)) {
00163
00164
00165
00166 found = TRUE;
00167 USL = argv[2];
00168 continue;
00169 }
00170 }
00171
00172 if (!found) continue;
00173
00174
00175
00176
00177
00178 if (!compare(argv[0],"scale")) {
00179 if (needargs(argc,2)) return;
00180 scale = getfloat(argv[1],1);
00181 }
00182 else if (!compare(argv[0],"maxforce")) {
00183
00184
00185
00186 #if 0
00187 if (needargs(argc,2)) return;
00188 maxforce = getfloat(argv[1],1);
00189 #else
00190 msgInfo << "Sorry, maxforce parameter not currently implemented."
00191 << sendmsg;
00192 #endif
00193 }
00194 else if (!compare(argv[0],"offset")) {
00195 int i;
00196 if (needargs(argc,4)) return;
00197 for (i=0;i<3;i++)
00198 offset[i] = getfloat(argv[1+i],0);
00199 }
00200 else if (!compare(argv[0],"rot")) {
00201 int i;
00202 if (needargs(argc,11)) return;
00203 if (!compare(argv[1],"right"))
00204 for (i=0;i<9;i++)
00205 right_rot.mat[i+i/3] = getfloat(argv[2+i],right_rot.mat[i+i/3]);
00206 else
00207 for (i=0;i<9;i++)
00208 left_rot.mat[i+i/3] = getfloat(argv[2+i],right_rot.mat[i+i/3]);
00209 }
00210 else msgErr << "Error: Unrecognized tool option on line " << line << sendmsg;
00211 }
00212
00213 if (USL=="") msgErr << "Device " << device << " not found." << sendmsg;
00214 else parseUSL();
00215 }
00216
00217
00218 SensorConfig::SensorConfig(const char *thedevice) {
00219
00220 if (thedevice==NULL) return;
00221
00222 USL = "";
00223 strcpy(nums,"");
00224 strcpy(name,"");
00225 strcpy(place,"");
00226 strcpy(type,"");
00227 strcpy(device,thedevice);
00228 offset[0] = offset[1] = offset[2] = 0;
00229 scale = 1;
00230 maxforce = -1;
00231 right_rot.identity();
00232 left_rot.identity();
00233
00234 ScanSensorFiles(PARSE_FOR_DEVICE, this, NULL);
00235 }
00236
00237
00238 int SensorConfig::parseUSL() {
00239 int ret;
00240 strcpy(nums,"0");
00241
00242 ret = sscanf(USL,"%20[^:]://%100[^/]/%100[^:]:%101s",
00243 type, place, name, nums);
00244
00245 if(ret<3) {
00246 msgErr << "USL on line " << line << " is not of the form: "
00247 << "type://place/name[:num,num,...]" << sendmsg;
00248 return 0;
00249 }
00250
00251 read_sensor_nums();
00252
00253 return 1;
00254 }
00255
00256 void SensorConfig::read_sensor_nums() {
00257 char *s=strdup(nums);
00258 char *r=s;
00259
00260 for (int cur=0; cur<= 200; cur++) {
00261 if(s[cur]==',' || s[cur]==0) {
00262 int tmp = 0;
00263 sscanf(r,"%d",&tmp);
00264 sensors.append(tmp);
00265 r = s + cur + 1;
00266 if(s[cur]==0) break;
00267 s[cur]=0;
00268 }
00269 }
00270
00271 free(s);
00272 }
00273
00274
00275
00276 void SensorConfig::parseconfigfornames(FILE *f, void *ret_void) {
00277 int argc, line=0;
00278 JString argv[20];
00279
00280 while((argc=splitline(f,argv,20))>=0) {
00281 line++;
00282
00283 if(!argc) continue;
00284 if(argv[0][0]=='#') continue;
00285
00286 if(!compare(argv[0],"device")) {
00287 if(need_args(argc,3,line)) continue;
00288 JString *newname = new JString(argv[1]);
00289 ((ResizeArray<JString *>*) ret_void)->append(newname);
00290 }
00291 }
00292 }
00293
00294
00295 ResizeArray<JString *> *SensorConfig::getnames() {
00296 ResizeArray<JString *> *ret = new ResizeArray<JString *>;
00297
00298 ScanSensorFiles(PARSE_FOR_NAMES, NULL, (void*)ret);
00299 return ret;
00300 }
00301
00302
00303 const char *SensorConfig::getUSL() const {
00304 return USL;
00305 }
00306
00307 float SensorConfig::getscale() const {
00308 return scale;
00309 }
00310
00311 float SensorConfig::getmaxforce() const {
00312 return maxforce;
00313 }
00314
00315 const float *SensorConfig::getoffset() const {
00316 return offset;
00317 }
00318
00319 const Matrix4 *SensorConfig::getright_rot() const {
00320 return &right_rot;
00321 }
00322
00323 const Matrix4 *SensorConfig::getleft_rot() const {
00324 return &left_rot;
00325 }
00326
00327 const char *SensorConfig::getdevice() const { return device; }
00328 const char *SensorConfig::gettype() const { return type; }
00329 const char *SensorConfig::getplace() const { return place; }
00330 const char *SensorConfig::getname() const { return name; }
00331 const char *SensorConfig::getnums() const { return nums; }
00332 const ResizeArray<int> *SensorConfig::getsensors() const { return &sensors; }
00333
00334 SensorConfig::~SensorConfig() {
00335 }
00336
00337 int SensorConfig::have_one_sensor() const {
00338 if (sensors.num() != 1) {
00339 msgErr << "Please specify exactly one sensor." << sendmsg;
00340 return 0;
00341 }
00342 return 1;
00343 }
00344
00345 void SensorConfig::make_vrpn_address(char *buf) const {
00346 if (!name || !place)
00347 *buf = '\0';
00348 else {
00349
00350
00351
00352
00353 if (strstr(name,"@tcp"))
00354 sprintf(buf, "%s://%s", name, place);
00355 else
00356 sprintf(buf, "%s@%s", name, place);
00357 }
00358 }
00359
00360 int SensorConfig::require_local() const {
00361 if(strcmp(place,"local")) {
00362 msgErr << "Sorry, this local device requires place name \"local\"."
00363 << sendmsg;
00364 return 0;
00365 }
00366 return 1;
00367 }
00368
00369 int SensorConfig::require_cave_name() const {
00370 if(!require_local()) return 0;
00371 if(strcmp(name,"cave")) {
00372 msgErr << "Sorry, the device name for the CAVE is \"cave\"." << sendmsg;
00373 return 0;
00374 }
00375 return 1;
00376 }
00377
00378 int SensorConfig::require_freevr_name() const {
00379 if(!require_local()) return 0;
00380 if(strcmp(name,"freevr")) {
00381 msgErr << "Sorry, the device name for FreeVR is \"freevr\"." << sendmsg;
00382 return 0;
00383 }
00384 return 1;
00385 }
00386