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[128], word[128];
00104 memset(buf, 0, sizeof(buf));
00105 memset(word, 0, sizeof(word));
00106
00107 if(!fgets(buf, sizeof(buf), f)) return -1;
00108
00109 argc = 0;
00110 pos = 0;
00111 while (argc<maxarg && pos<100 && buf[pos]!=0 && buf[pos]!='\n'
00112 && buf[pos]!='\r') {
00113
00114 if (buf[pos]!=' ' && buf[pos]!='\t') {
00115 sscanf(buf+pos, "%99s", word);
00116 pos += strlen(word);
00117 argv[argc] = (JString)word;
00118 argc++;
00119 } else {
00120 pos++;
00121 }
00122 }
00123
00124 return argc;
00125 }
00126
00127
00128 static int need_args(int argc,int need, int line) {
00129 if (need!=argc) {
00130 msgErr << "SensorConfig: Wrong number of arguments at line " << line << "." << sendmsg;
00131 msgErr << "Expected " << need << ", got " << argc << "." << sendmsg;
00132 return 1;
00133 }
00134 return 0;
00135 }
00136
00137 float SensorConfig::getfloat(const char *from, float defalt) {
00138 int ret;
00139 float f;
00140 ret=sscanf(from,"%f",&f);
00141 if(!ret) {
00142 msgErr << "SensorConfig: Error parsing float at line " << line << sendmsg;
00143 return defalt;
00144 }
00145 return f;
00146 }
00147
00148 int SensorConfig::needargs(int argc,int need) {
00149 return need_args(argc,need,line);
00150 }
00151
00152
00153 void SensorConfig::parseconfigfordevice(FILE *file, void *) {
00154
00155 int found=FALSE, argc;
00156 line = 0;
00157 JString argv[20];
00158 while ((argc=splitline(file, argv, 20))>=0) {
00159 line++;
00160
00161 if (!argc) continue;
00162 if (argv[0][0]=='#') continue;
00163
00164 if (!compare(argv[0],"device")) {
00165 if (found) break;
00166 if (needargs(argc,3)) return;
00167 if (!compare(argv[1],device)) {
00168
00169
00170
00171 found = TRUE;
00172 USL = argv[2];
00173 continue;
00174 }
00175 }
00176
00177 if (!found) continue;
00178
00179
00180
00181
00182
00183 if (!compare(argv[0],"scale")) {
00184 if (needargs(argc,2)) return;
00185 scale = getfloat(argv[1],1);
00186 }
00187 else if (!compare(argv[0],"maxforce")) {
00188
00189
00190
00191 #if 0
00192 if (needargs(argc,2)) return;
00193 maxforce = getfloat(argv[1],1);
00194 #else
00195 msgInfo << "Sorry, maxforce parameter not currently implemented."
00196 << sendmsg;
00197 #endif
00198 }
00199 else if (!compare(argv[0],"offset")) {
00200 int i;
00201 if (needargs(argc,4)) return;
00202 for (i=0;i<3;i++)
00203 offset[i] = getfloat(argv[1+i],0);
00204 }
00205 else if (!compare(argv[0],"rot")) {
00206 int i;
00207 if (needargs(argc,11)) return;
00208 if (!compare(argv[1],"right"))
00209 for (i=0;i<9;i++)
00210 right_rot.mat[i+i/3] = getfloat(argv[2+i],right_rot.mat[i+i/3]);
00211 else
00212 for (i=0;i<9;i++)
00213 left_rot.mat[i+i/3] = getfloat(argv[2+i],right_rot.mat[i+i/3]);
00214 }
00215 else msgErr << "Error: Unrecognized tool option on line " << line << sendmsg;
00216 }
00217
00218 if (USL=="") msgErr << "Device " << device << " not found." << sendmsg;
00219 else parseUSL();
00220 }
00221
00222
00223 SensorConfig::SensorConfig(const char *thedevice) {
00224
00225 if (thedevice==NULL) return;
00226
00227 USL = "";
00228 strcpy(nums,"");
00229 strcpy(name,"");
00230 strcpy(place,"");
00231 strcpy(type,"");
00232 strcpy(device,thedevice);
00233 offset[0] = offset[1] = offset[2] = 0;
00234 scale = 1;
00235 maxforce = -1;
00236 right_rot.identity();
00237 left_rot.identity();
00238
00239 ScanSensorFiles(PARSE_FOR_DEVICE, this, NULL);
00240 }
00241
00242
00243 int SensorConfig::parseUSL() {
00244 int ret;
00245 strcpy(nums,"0");
00246
00247 ret = sscanf(USL,"%20[^:]://%100[^/]/%100[^:]:%101s",
00248 type, place, name, nums);
00249
00250 if(ret<3) {
00251 msgErr << "USL on line " << line << " is not of the form: "
00252 << "type://place/name[:num,num,...]" << sendmsg;
00253 return 0;
00254 }
00255
00256 read_sensor_nums();
00257
00258 return 1;
00259 }
00260
00261 void SensorConfig::read_sensor_nums() {
00262 char *s=strdup(nums);
00263 char *r=s;
00264
00265 for (int cur=0; cur<= 200; cur++) {
00266 if(s[cur]==',' || s[cur]==0) {
00267 int tmp = 0;
00268 sscanf(r,"%d",&tmp);
00269 sensors.append(tmp);
00270 r = s + cur + 1;
00271 if(s[cur]==0) break;
00272 s[cur]=0;
00273 }
00274 }
00275
00276 free(s);
00277 }
00278
00279
00280
00281 void SensorConfig::parseconfigfornames(FILE *f, void *ret_void) {
00282 int argc, line=0;
00283 JString argv[20];
00284
00285 while ((argc=splitline(f, argv, 20))>=0) {
00286 line++;
00287
00288 if(!argc) continue;
00289 if(argv[0][0]=='#') continue;
00290
00291 if(!compare(argv[0],"device")) {
00292 if(need_args(argc,3,line)) continue;
00293 JString *newname = new JString(argv[1]);
00294 ((ResizeArray<JString *>*) ret_void)->append(newname);
00295 }
00296 }
00297 }
00298
00299
00300 ResizeArray<JString *> *SensorConfig::getnames() {
00301 ResizeArray<JString *> *ret = new ResizeArray<JString *>;
00302
00303 ScanSensorFiles(PARSE_FOR_NAMES, NULL, (void*)ret);
00304 return ret;
00305 }
00306
00307
00308 const char *SensorConfig::getUSL() const {
00309 return USL;
00310 }
00311
00312 float SensorConfig::getscale() const {
00313 return scale;
00314 }
00315
00316 float SensorConfig::getmaxforce() const {
00317 return maxforce;
00318 }
00319
00320 const float *SensorConfig::getoffset() const {
00321 return offset;
00322 }
00323
00324 const Matrix4 *SensorConfig::getright_rot() const {
00325 return &right_rot;
00326 }
00327
00328 const Matrix4 *SensorConfig::getleft_rot() const {
00329 return &left_rot;
00330 }
00331
00332 const char *SensorConfig::getdevice() const { return device; }
00333 const char *SensorConfig::gettype() const { return type; }
00334 const char *SensorConfig::getplace() const { return place; }
00335 const char *SensorConfig::getname() const { return name; }
00336 const char *SensorConfig::getnums() const { return nums; }
00337 const ResizeArray<int> *SensorConfig::getsensors() const { return &sensors; }
00338
00339 SensorConfig::~SensorConfig() {
00340 }
00341
00342 int SensorConfig::have_one_sensor() const {
00343 if (sensors.num() != 1) {
00344 msgErr << "Please specify exactly one sensor." << sendmsg;
00345 return 0;
00346 }
00347 return 1;
00348 }
00349
00350 void SensorConfig::make_vrpn_address(char *buf) const {
00351
00352
00353
00354
00355 if (strstr(name,"@tcp"))
00356 sprintf(buf, "%s://%s", name, place);
00357 else
00358 sprintf(buf, "%s@%s", name, place);
00359 }
00360
00361 int SensorConfig::require_local() const {
00362 if(strcmp(place,"local")) {
00363 msgErr << "Sorry, this local device requires place name \"local\"."
00364 << sendmsg;
00365 return 0;
00366 }
00367 return 1;
00368 }
00369
00370 int SensorConfig::require_cave_name() const {
00371 if(!require_local()) return 0;
00372 if(strcmp(name,"cave")) {
00373 msgErr << "Sorry, the device name for the CAVE is \"cave\"." << sendmsg;
00374 return 0;
00375 }
00376 return 1;
00377 }
00378
00379 int SensorConfig::require_freevr_name() const {
00380 if(!require_local()) return 0;
00381 if(strcmp(name,"freevr")) {
00382 msgErr << "Sorry, the device name for FreeVR is \"freevr\"." << sendmsg;
00383 return 0;
00384 }
00385 return 1;
00386 }
00387