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
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "Component/ModelManager.H"
00039 #include "Image/Image.H"
00040 #include "Psycho/PsychoDisplay.H"
00041 #include "Psycho/EyeTrackerConfigurator.H"
00042 #include "Psycho/EyeTracker.H"
00043 #include "Psycho/PsychoOpts.H"
00044 #include "Component/EventLog.H"
00045 #include "Component/ComponentOpts.H"
00046 #include "Raster/Raster.H"
00047 #include "Util/MathFunctions.H"
00048 #include "Util/Types.H"
00049 #include "GameBoard/basic-graphics.H"
00050 #include <sys/types.h>
00051 #include <dirent.h>
00052 #include <errno.h>
00053 #include <vector>
00054 #include <string>
00055 #include <iostream>
00056 #include <SDL/SDL.h>
00057 #include <SDL/SDL_image.h>
00058 #include <stdio.h>
00059 #include <stdlib.h>
00060 #include <sstream>
00061 #include <time.h>
00062 #include "Image/DrawOps.H"
00063 #include "GameBoard/resize.h"
00064 #include <iostream>
00065 #include <fstream>
00066 #include <set>
00067 #include <algorithm>
00068 #include <ctime>
00069 #include "Devices/SimpleMotor.H"
00070 #include <SDL/SDL_mixer.h>
00071
00072 #ifndef INVT_HAVE_LIBSDL_IMAGE
00073 #include <cstdio>
00074 int main()
00075 {
00076 fprintf(stderr, "The SDL_image library must be installed to use this program\n");
00077 return 1;
00078 }
00079
00080 #else
00081
00082
00083
00084 using namespace std;
00085
00086
00087
00088 ModelManager manager("Psycho-Concurrent-Digit");
00089 nub::soft_ref<PsychoDisplay> d(new PsychoDisplay(manager));
00090 nub::soft_ref<SimpleMotor> motor(new SimpleMotor(manager));
00091 map<uint,uint> testMap ;
00092 map<string,string> argMap ;
00093 map<string,vector<SDL_Rect*>*> clipsmap;
00094 Mix_Chunk *whitenoise_chunk = NULL;
00095
00096
00097
00098
00099 template <class T> std::string stringify(T i)
00100 {
00101 ostringstream o ;
00102 o << i ;
00103 return o.str();
00104 }
00105
00106
00107
00108 double getAvarage(vector<long> v){
00109 double f = 0.0 ;
00110 for( uint i = 0 ; i < v.size() ; i++ ){
00111 f += v[i] ;
00112 }
00113 if (v.size()!=0) return f/v.size() ;
00114 return -1 ;
00115 }
00116
00117 double getVariance(vector<long> v){
00118 double m = getAvarage(v);
00119 double var = 0.0 ;
00120 for( uint i = 0 ; i < v.size(); i++ ){
00121 var += (v[i]-m)*(v[i]-m) ;
00122 }
00123 if (v.size()!=0) return var/v.size() ;
00124 return -1 ;
00125 }
00126
00127
00128
00129 int getdir (string dir, vector<string> &files)
00130 {
00131 DIR *dp;
00132 struct dirent *dirp;
00133 if((dp = opendir(dir.c_str())) == NULL) {
00134 cout << "Error(" << errno << ") opening " << dir << endl;
00135 return errno;
00136 }
00137 string fn = "" ;
00138 size_t found;
00139 string extension = "" ;
00140 while ((dirp = readdir(dp)) != NULL) {
00141 fn = string(dirp->d_name) ;
00142 found = fn.find_last_of(".");
00143 if(found > 0 && found <1000){
00144 extension = fn.substr(found) ;
00145 if(extension.compare(".png")== 0 || extension.compare(".jpg")==0 )
00146 files.push_back(dir+"/"+fn);
00147 }
00148 }
00149 closedir(dp);
00150 return 0;
00151 }
00152
00153
00154
00155
00156
00157
00158 SDL_Surface* getButtonImage(string label , PixRGB<byte> txtcolor=PixRGB<byte>(0,0,0) , PixRGB<byte> bgcolor=PixRGB<byte>(255,255,255) ,Point2D<int> size = Point2D<int>(100,100) ,PixRGB<byte> bordercolor=PixRGB<byte>(0,0,0) , int border=3){
00159 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00160 textIm.clear(bgcolor);
00161 writeText(textIm, Point2D<int>((size.i - label.length()*10)/2,(size.j-20) /2),label.c_str(),txtcolor,bgcolor);
00162 SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00163 Uint32 bc = d->getUint32color(bordercolor);
00164 drawRectangle(surf,bc,0,0,size.i -1,size.j -1 ,border);
00165 SDL_Surface* blank =getABlankSurface(size.i , size.j);
00166 SDL_Rect clip;
00167 clip.x = 0 ;
00168 clip.y = 0 ;
00169 clip.w = size.i ;
00170 clip.h = size.j ;
00171 apply_surface(0,0,*surf,*blank,clip);
00172 dumpSurface(surf) ;
00173 return blank ;
00174 }
00175
00176
00177
00178
00179
00180
00181 SDL_Surface* getKeyPad(string alphabet,map<string , SDL_Rect>& buttmap){
00182 SDL_Surface* pad= getABlankSurface(d->getWidth()/4,d->getHeight()/3);
00183 SDL_Rect clip;
00184 clip.x=0;
00185 clip.y=0;
00186 int numofrows = alphabet.size()/3 +1;
00187 if(alphabet.size()%3 != 0 ) numofrows++ ;
00188 int numofcolumns = 3 ;
00189 clip.w= pad->w / numofcolumns ;
00190 clip.h = pad->h / numofrows ;
00191
00192
00193 for( int i = 0 ; i < numofrows*3 ; i++){
00194 SDL_Surface* but ;
00195 if((uint)i < alphabet.size()){
00196 but = getButtonImage(alphabet.substr(i,1),PixRGB<byte>(0,0,0),PixRGB<byte>(255,255,255),Point2D<int>(pad->w / numofcolumns , pad->h / numofrows),PixRGB<byte>(255, 98 , 25),3);
00197 }else{
00198 but = getButtonImage(" ",PixRGB<byte>(0,0,0),PixRGB<byte>(255,255,255),Point2D<int>(pad->w / numofcolumns , pad->h / numofrows),PixRGB<byte>(255, 98 , 25),3);
00199 }
00200
00201 SDL_Rect cl ;
00202 cl.x = ((i)%numofcolumns)*(pad->w)/numofcolumns ; cl.y= ((i)/numofcolumns)*((pad->h)/numofrows) ;
00203 cl.w = clip.w ;
00204 cl.h = clip.h ;
00205 apply_surface( cl.x , cl.y ,*but,*pad,clip);
00206 if((uint)i < alphabet.size()) buttmap[alphabet.substr(i,1)] = cl ;
00207 dumpSurface(but);
00208 }
00209 SDL_Rect cl1 ;
00210 cl1.x = 0 ; cl1.y= (numofrows-1)*((pad->h)/numofrows) ;
00211 cl1.w = clip.w ;
00212 cl1.h = clip.h ;
00213 buttmap["!"] = cl1 ;
00214 SDL_Surface* but = getButtonImage(string("<-"),PixRGB<byte>(0,0,0),PixRGB<byte>(255,255,255),Point2D<int>(pad->w / numofcolumns , pad->h / numofrows),PixRGB<byte>(255, 98 , 25),3);
00215 apply_surface(0, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00216 dumpSurface(but);
00217 SDL_Rect cl2 ;
00218 cl2.x = (pad->w)/numofcolumns ; cl2.y= (numofrows-1)*((pad->h)/numofrows) ;
00219 cl2.w = clip.w ;
00220 cl2.h = clip.h ;
00221 buttmap[" "] = cl2 ;
00222 but = getButtonImage(string("spc"),PixRGB<byte>(0,0,0),PixRGB<byte>(255,255,255),Point2D<int>(pad->w / numofcolumns , pad->h / numofrows),PixRGB<byte>(255, 98 , 25),3);
00223 apply_surface((pad->w)/numofcolumns, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00224 dumpSurface(but);
00225 SDL_Rect cl3 ;
00226 cl3.x = 2*(pad->w)/numofcolumns ; cl3.y= (numofrows-1)*((pad->h)/numofrows) ;
00227 cl3.w = clip.w ;
00228 cl3.h = clip.h ;
00229 buttmap["*"] = cl3 ;
00230 but = getButtonImage(string("Ok"),PixRGB<byte>(0,0,0),PixRGB<byte>(255,255,255),Point2D<int>(pad->w / numofcolumns , pad->h / numofrows),PixRGB<byte>(255, 98 , 25),3);
00231 apply_surface(2*(pad->w)/numofcolumns, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00232 dumpSurface(but);
00233 return pad ;
00234 }
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244 string getPressedButtonCommand(map<string , SDL_Rect>& buttmap,Point2D<int> offset=Point2D<int>(0,0)){
00245 int quit = 0 ;
00246 string s ;
00247 SDL_Event event ;
00248 while( quit!=2 ){
00249 while( SDL_PollEvent( &event ) ) {
00250 if(event.type == SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_LEFT ){
00251 for( map<string , SDL_Rect>::iterator it = buttmap.begin() ; it!=buttmap.end() ; ++it){
00252 if(event.button.x >= (it->second).x + offset.i && event.button.x <= (it->second).x + (it->second).w + offset.i && event.button.y >= (it->second).y+ offset.j && event.button.y <= (it->second).y + (it->second).h + offset.j) {
00253 quit = 2 ;
00254 s = it->first ;
00255 break;
00256 }
00257
00258 }
00259 }
00260
00261 }
00262 }
00263 return s ;
00264
00265 }
00266
00267
00268
00269
00270
00271
00272
00273 string getDigitSequenceFromSubject(string alphabet="0123456789" , uint maxl = 7 ){
00274 d->showCursor(true) ;
00275
00276 map<string , SDL_Rect>* buttmap = new map<string , SDL_Rect>();
00277
00278 SDL_Surface * keypad = getKeyPad(alphabet,*buttmap);
00279
00280 SDL_Rect offset ;
00281 offset.x = (d->getWidth() - keypad->w) /2;
00282 offset.y = (d-> getHeight() - keypad->h) /2;
00283
00284 d->displaySDLSurfacePatch(keypad , &offset,NULL , -2,false, true);
00285
00286 string p = string("") ;
00287
00288 string tp = string("");
00289
00290 while( tp.compare("*")!=0 ){
00291
00292 SDL_Surface* dp = getButtonImage(p ,PixRGB<byte>(195,60,12) ,PixRGB<byte>(255,255,255) ,Point2D<int>(d->getWidth()/6,d->getHeight() /15) ,PixRGB<byte>(0,25,180) , 4) ;
00293 SDL_Rect offs ; offs.x = (d->getWidth() - dp->w) /2 ; offs.y = d->getHeight()/6 ;
00294 d->displaySDLSurfacePatch(dp , &offs , NULL , -2 , false ,true ) ;
00295
00296 tp = getPressedButtonCommand(*buttmap,Point2D<int>(offset.x,offset.y)) ;
00297 dumpSurface(dp) ;
00298 if(tp.compare("!")==0 && p.size()>=0 ) {
00299 if (p.size()>0) p = p.substr(0,p.size()-1) ;
00300 }else{
00301 if(p.size() < maxl && tp.compare("*")!=0) {
00302 p +=tp ;
00303 }
00304
00305 }
00306
00307 }
00308 buttmap = 0 ;
00309 dumpSurface(keypad) ;
00310 d->clearScreen() ;
00311 return p ;
00312
00313 }
00314
00315
00316
00317
00318 int addArgument(const string st,const string delim="="){
00319 int i = st.find(delim) ;
00320 argMap[st.substr(0,i)] = st.substr(i+1);
00321
00322 return 0 ;
00323 }
00324
00325 std::string getArgumentValue(string arg){
00326 return argMap[arg] ;
00327 }
00328
00329 std::string getUsageComment(){
00330
00331 string com = string("\nlist of arguments : \n");
00332
00333 com += "\nlogfile=[logfilename.psy] {default = psycho-stroop-concurrent.psy}\n" ;
00334 com += "\nmemo=[a_string_without_white_space]\n";
00335 com += "\nrange=[x-y](the size of string){default=200-500} \n";
00336 com += "\nsubject=[subject_name] \n" ;
00337 com += "\ndelay=[>0] (number of frames that subject should do subtraction operation){default=30000000}\n";
00338 com += "\ntest-rounds=[>1] (number of tests ) {default=5}\n";
00339 com += "\ndigit-onset=[>1] (number of frames that the string will remain onset ){default=10}\n";
00340 com += "\nsubtraction-step=[>0] (the subtraction number){default=3} ";
00341 com += "\nsound-dir=[path to wav files directory]{default=..}\n";
00342 com += "\nnoise-file=[white noise file]{default=whitenoise.wav}\n";
00343 com += "\npuase-frames=[number of frames for stopping the motor]{default=5}\n";
00344 com += "\nmin-reaction-time=[>0](minimum value for avarage reaction time in microsecond in order to consider a trial valid){default=1000000}\n" ;
00345 com += "\nmax-miss=[>0](maximum misses in a trial in order to be considered as a valid one){default=10}\n";
00346 com += "\ninterrupt-time-range=[x-y](this defines a range of uniform radom distribution by which the perceptual interruption happens){default=500000-5000000}\n" ;
00347 return com ;
00348 }
00349
00350 int myCheckForMouseClick()
00351 {
00352 SDL_Event event;
00353
00354 while(SDL_PollEvent(&event))
00355 {
00356 if (event.type == SDL_MOUSEBUTTONDOWN)
00357 {
00358 if(event.button.button == SDL_BUTTON_LEFT) {
00359 return 1 ;
00360 }
00361 if(event.button.button == SDL_BUTTON_RIGHT) {
00362 return 2 ;
00363 }
00364
00365 }
00366
00367 }
00368
00369
00370 return -1;
00371 }
00372
00373
00374
00375 int getClick(){
00376
00377 SDL_Event event;
00378 bool report = false ;
00379 int i = 0;
00380 do {
00381 do { SDL_WaitEvent(&event); } while (event.type != SDL_MOUSEBUTTONDOWN);
00382 if (event.button.button == SDL_BUTTON_LEFT) {
00383 i = 0 ;
00384 report = true ;
00385 }
00386 if (event.button.button == SDL_BUTTON_RIGHT) {
00387 i = 1 ;
00388 report = true ;
00389 }
00390
00391 }while(!report) ;
00392
00393 return i ;
00394
00395 }
00396
00397 int getAllKindOfClick(){
00398
00399 SDL_Event event;
00400 bool report = false ;
00401 int i = 0;
00402 do {
00403 do { SDL_WaitEvent(&event); } while (event.type != SDL_MOUSEBUTTONDOWN);
00404 long st = d->getTimerValue();
00405 long et = st ;
00406
00407 if (event.button.button == SDL_BUTTON_LEFT) {
00408 i = 0 ;
00409 report = true ;
00410 while( et-st < 300000){
00411 et = d->getTimerValue() ;
00412 if(myCheckForMouseClick()==1) return 2 ;
00413 }
00414 }
00415 if (event.button.button == SDL_BUTTON_RIGHT) {
00416 i = 1 ;
00417 report = true ;
00418 }
00419
00420 }while(!report) ;
00421
00422 return i ;
00423
00424 }
00425
00426 int getNext(int i){
00427
00428 int r = 1 ;
00429 if(i == 0 || i == 2) return 1 ;
00430 if(i==1) return 0;
00431 return r ;
00432 }
00433
00434 extern "C" int main(const int argc, char** argv)
00435 {
00436
00437 MYLOGVERB = LOG_INFO;
00438
00439 argMap["experiment"]="subtraction-working-memory";
00440 argMap["logfile"]="psycho-ws-m.psy" ;
00441 argMap["string-size"]="5" ;
00442 argMap["test-rounds"]="5";
00443 argMap["subject"]="" ;
00444 argMap["memo"]="" ;
00445 argMap["digit-onset"]="10" ;
00446 argMap["range"]="200-500";
00447 argMap["delay"]="30000000" ;
00448 argMap["subtraction-step"]="3" ;
00449 argMap["sound-dir"]="..";
00450 argMap["noise-file"]="whitenoise.wav";
00451 argMap["pause-frames"]="5" ;
00452 argMap["min-reaction-time"]="1000000" ;
00453 argMap["max-miss"]="10" ;
00454 argMap["interrupt-time-range"]= "500000-5000000";
00455 argMap["mode"]="1";
00456
00457 manager.addSubComponent(d);
00458 manager.addSubComponent(motor) ;
00459 nub::soft_ref<EventLog> el(new EventLog(manager));
00460 manager.addSubComponent(el);
00461 d->setEventLog(el);
00462
00463 if (manager.parseCommandLine(argc, argv,
00464 "at least one argument needed", 1, -1)==false){
00465 cout<<getUsageComment()<<endl;
00466 return(1);
00467 }
00468
00469 for(uint i = 0 ; i < manager.numExtraArgs() ; i++){
00470 addArgument(manager.getExtraArg(i),std::string("=")) ;
00471 }
00472
00473 manager.setOptionValString(&OPT_EventLogFileName, argMap["logfile"]);
00474
00475 if( Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 4096 ) == -1 ){
00476 LINFO( "did not open the mix-audio") ;
00477 return -1 ;
00478 }
00479 string noisestr = argMap["sound-dir"] + "/" + argMap["noise-file"];
00480 whitenoise_chunk = Mix_LoadWAV(noisestr.c_str());
00481 if( whitenoise_chunk == NULL )
00482 {
00483 LINFO("did not find the indicated wav files!");
00484 return -1;
00485 }
00486
00487
00488
00489
00490 manager.start();
00491 for(map<string,string>::iterator it= argMap.begin(); it!= argMap.end() ; ++it) d->pushEvent("arg:"+ it->first+" value:"+it->second ) ;
00492
00493 d->clearScreen();
00494 d->displayISCANcalib();
00495 d->waitForMouseClick();
00496 d->displayText("Here the experiment starts! click to start!");
00497 d->waitForMouseClick();
00498 d->clearScreen();
00499
00500
00501 int numOfTests = atoi(argMap["test-rounds"].c_str()) ;
00502 int onsetDel = atoi(argMap["digit-onset"].c_str()) ;
00503 int opDelay = atoi(argMap["delay"].c_str());
00504 int in = argMap["range"].find("-") ;
00505 int rangeU = atoi( argMap["range"].substr(in+1).c_str()) ;
00506 int rangeL = atoi(argMap["range"].substr(0,in).c_str()) ;
00507 int step = atoi(argMap["subtraction-step"].c_str());
00508 int max_miss = atoi(argMap["max-miss"].c_str());
00509 in = argMap["interrupt-time-range"].find("-") ;
00510 long iub = atol(argMap["interrupt-time-range"].substr(in+1).c_str());
00511 long ilb = atol(argMap["interrupt-time-range"].substr(0,in).c_str()) ;
00512 long min_reaction_time = atol(argMap["min-reaction-time"].c_str()) ;
00513
00514 int cr = 0 ;
00515 vector<int> speedVector;
00516 speedVector.push_back(110) ;
00517 speedVector.push_back(-110) ;
00518 speedVector.push_back(150) ;
00519 int pause_frames = atoi(argMap["pause-frames"].c_str());
00520 if(argMap["mode"].compare("2")==0){
00521 while( cr <numOfTests ){
00522
00523 vector<long> reactionTimes ;
00524 int missed = 0 ;
00525 d->pushEvent("**************************************") ;
00526 d->showCursor(true);
00527 d->displayText("click one of the mouse buttons to start!");
00528 d->waitForMouseClick() ;
00529 d->showCursor(false) ;
00530 int initialNum = rangeL+ random()%(rangeU-rangeL) ;
00531 d->clearScreen() ;
00532 d->displayFixationBlink();
00533 d->pushEvent("the initial number is: "+stringify(initialNum)) ;
00534 d->displayText(stringify(initialNum),true,0) ;
00535 d->pushEvent("manupulation starts") ;
00536 d->waitFrames(onsetDel) ;
00537 Mix_PlayChannel( -1, whitenoise_chunk , 300 ) ;
00538 d->clearScreen() ;
00539 long dst = 0 ;
00540 long det = 0 ;
00541 long dl = 0 ;
00542 int cs = 0 ;
00543 motor->setMotor(speedVector[cs]) ;
00544 dl = ilb+ random() % (iub-ilb);
00545 dst = d->getTimerValue() ;
00546 det = dst ;
00547 long tst = 0 ;
00548 long tet = 0 ;
00549 long st = d->getTimerValue();
00550 long et = st ;
00551 bool clickFlag = false ;
00552
00553 while( et - st < opDelay ){
00554
00555 if (det - dst > dl ){
00556
00557 cs = getNext(cs) ;
00558 motor->setMotor(0) ;
00559 d->waitFrames(pause_frames);
00560 motor->setMotor(speedVector[cs]) ;
00561
00562 tst = d->getTimerValue() ;
00563 if(clickFlag){
00564 missed++ ;
00565 d->pushEvent("missed one change");
00566 }
00567 clickFlag = true ;
00568 dst = tst ;
00569 det = dst ;
00570 dl = ilb+ random() % (iub-ilb);
00571 et= tst ;
00572 }
00573 det = d->getTimerValue() ;
00574 et = det ;
00575 if(clickFlag){
00576 int c = myCheckForMouseClick() ;
00577 if(c==1 || c==2){
00578 clickFlag = false ;
00579 tet = d->getTimerValue() ;
00580 d->pushEvent("reaction time :" + stringify(tet-tst));
00581 reactionTimes.push_back(tet-tst) ;
00582 }
00583
00584 }else{
00585 myCheckForMouseClick() ;
00586 }
00587
00588 }
00589 d->pushEvent("manipulation ends") ;
00590 motor->setMotor(0) ;
00591 Mix_Pause(-1);
00592 d->clearScreen();
00593 string answer = getDigitSequenceFromSubject("0123456789" , 3);
00594 d->pushEvent("the reported number: "+answer);
00595 int finalNum = atoi(answer.c_str()) ;
00596 d->pushEvent("number of operations: "+stringify((initialNum-finalNum)/step));
00597 d->pushEvent("avarage reaction time : "+ stringify(getAvarage(reactionTimes))) ;
00598 d->pushEvent("number of missed events : "+stringify(missed));
00599 d->pushEvent("number of caught events : "+stringify(reactionTimes.size())) ;
00600 if(missed < max_miss && getAvarage(reactionTimes)<= min_reaction_time ){
00601 cr++;
00602 d->pushEvent("valid trial");
00603 }else{
00604 if(missed >= max_miss) {
00605 d->displayText("Trial failed, too many events missed! Click to start over!");
00606 d->waitForMouseClick();
00607 }
00608 if(getAvarage(reactionTimes) > min_reaction_time){
00609 d->displayText("Trial failed, reaction slower than limit! Click to start over!");
00610 d->waitForMouseClick();
00611 }
00612 d->pushEvent("invalid trial");
00613 }
00614 }
00615 }
00616
00617 if(argMap["mode"].compare("1")==0){
00618 while( cr <numOfTests ){
00619
00620 vector<long> reactionTimes ;
00621 int missed = 0 ;
00622 d->pushEvent("**************************************") ;
00623 d->showCursor(true);
00624 d->displayText("click one of the mouse buttons to start!");
00625 d->waitForMouseClick() ;
00626 d->showCursor(false) ;
00627 d->clearScreen() ;
00628 d->displayFixationBlink();
00629 d->pushEvent("manupulation starts") ;
00630 Mix_PlayChannel( -1, whitenoise_chunk , 300 ) ;
00631
00632 d->clearScreen() ;
00633 long dst = 0 ;
00634 long det = 0 ;
00635 long dl = 0 ;
00636 int cs = 0 ;
00637 motor->setMotor(speedVector[cs]) ;
00638 dl = ilb+ random() % (iub-ilb);
00639 dst = d->getTimerValue() ;
00640 det = dst ;
00641 long tst = 0 ;
00642 long tet = 0 ;
00643 long st = d->getTimerValue();
00644 long et = st ;
00645 bool clickFlag = false ;
00646
00647 while( et - st < opDelay ){
00648
00649 if (det - dst > dl ){
00650 cs = getNext(cs) ;
00651 motor->setMotor(0) ;
00652 d->waitFrames(pause_frames);
00653 motor->setMotor(speedVector[cs]) ;
00654
00655 tst = d->getTimerValue() ;
00656 if(clickFlag){
00657 missed++ ;
00658 d->pushEvent("missed one change");
00659 }
00660 clickFlag = true ;
00661 dst = tst ;
00662 det = dst ;
00663 dl = ilb+ random() % (iub-ilb);
00664 et= tst ;
00665 }
00666 det = d->getTimerValue() ;
00667 et = det ;
00668 if(clickFlag){
00669 int c = myCheckForMouseClick() ;
00670 if(c==1 || c==2){
00671 clickFlag = false ;
00672 tet = d->getTimerValue() ;
00673 d->pushEvent("reaction time :" + stringify(tet-tst));
00674 reactionTimes.push_back(tet-tst) ;
00675 }
00676
00677 }else{
00678 myCheckForMouseClick() ;
00679 }
00680
00681 }
00682 d->pushEvent("manipulation ends") ;
00683 motor->setMotor(0) ;
00684 Mix_Pause(-1);
00685 d->clearScreen();
00686 d->pushEvent("avarage reaction time : "+ stringify(getAvarage(reactionTimes))) ;
00687 d->pushEvent("number of missed events : "+stringify(missed));
00688 d->pushEvent("number of caught events : "+stringify(reactionTimes.size())) ;
00689 if(missed < max_miss && getAvarage(reactionTimes)<= min_reaction_time ){
00690 cr++;
00691 d->pushEvent("valid trial");
00692 }else{
00693 if(missed >= max_miss) {
00694 d->displayText("Trial failed, too many events missed! Click to start over!");
00695 d->waitForMouseClick();
00696 }
00697 if(getAvarage(reactionTimes) > min_reaction_time){
00698 d->displayText("Trial failed, reaction slower than limit! Click to start over!");
00699 d->waitForMouseClick();
00700 }
00701 d->pushEvent("invalid trial");
00702 }
00703 }
00704 }
00705
00706 d->clearScreen();
00707 d->displayText("Experiment complete. Thank you!");
00708 d->waitForMouseClick();
00709 Mix_FreeChunk( whitenoise_chunk );
00710 Mix_CloseAudio();
00711
00712 manager.stop();
00713
00714
00715
00716 return 0;
00717 }
00718
00719 #endif // INVT_HAVE_LIBSDL_IMAGE
00720