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
00069
00070 #ifndef INVT_HAVE_LIBSDL_IMAGE
00071 #include <cstdio>
00072 int main()
00073 {
00074 fprintf(stderr, "The SDL_image library must be installed to use this program\n");
00075 return 1;
00076 }
00077
00078 #else
00079
00080
00081
00082 using namespace std;
00083
00084 ModelManager manager("Psycho-Concurrent-Digit");
00085 nub::soft_ref<PsychoDisplay> d(new PsychoDisplay(manager));
00086 map<uint,uint> testMap ;
00087 map<string,string> argMap ;
00088 map<string,vector<SDL_Rect*>*> clipsmap;
00089
00090
00091
00092
00093 template <class T> std::string stringify(T i)
00094 {
00095 ostringstream o ;
00096 o << i ;
00097 return o.str();
00098 }
00099
00100
00101
00102 void getMouseEvent(){
00103 bool quit = false ;
00104 SDL_Event event ;
00105 while( quit == false ) {
00106 while( SDL_PollEvent( &event ) ) {
00107 if( event.type == SDL_MOUSEBUTTONDOWN ) { quit = true; }
00108 }
00109 }
00110 }
00111
00112 int getdir (string dir, vector<string> &files)
00113 {
00114 DIR *dp;
00115 struct dirent *dirp;
00116 if((dp = opendir(dir.c_str())) == NULL) {
00117 cout << "Error(" << errno << ") opening " << dir << endl;
00118 return errno;
00119 }
00120 string fn = "" ;
00121 size_t found;
00122 string extension = "" ;
00123 while ((dirp = readdir(dp)) != NULL) {
00124 fn = string(dirp->d_name) ;
00125 found = fn.find_last_of(".");
00126 if(found > 0 && found <1000){
00127 extension = fn.substr(found) ;
00128 if(extension.compare(".png")== 0 || extension.compare(".jpg")==0 )
00129 files.push_back(dir+"/"+fn);
00130 }
00131 }
00132 closedir(dp);
00133 return 0;
00134 }
00135
00136 bool itIsInThere(int x , vector<int> bag){
00137 for( uint i=0 ; i < bag.size(); i++ ){
00138 if(x == bag[i]) return true ;
00139 }
00140 return false ;
00141 }
00142
00143
00144
00145
00146 string digitMemorizationTask(uint l, int maxForDigit=10 ,float wp = 1.0f, float hp = 1.0f, int displayFrame = 10 , int delayFrame = 30 ){
00147 d->clearScreen() ;
00148 vector<int> pickedones = vector<int>() ;
00149 string test = string("") ;
00150 string tp = string("") ;
00151 int widthRange = (int)((float)(d->getWidth()) * wp);
00152 int heightRange = (int)((float)(d->getHeight()) * hp);
00153 int wMargin = (d->getWidth() - widthRange)/2 ;
00154 int hMargin = (d->getHeight() - heightRange) / 2 ;
00155 for(uint i = 0 ; i < l ; i++){
00156 int nd;
00157 do{ nd= rand()% maxForDigit ; }while(itIsInThere(nd,pickedones) && pickedones.size() < 11) ;
00158 pickedones.push_back(nd);
00159 tp = stringify(nd) ;
00160
00161
00162
00163 test += tp ;
00164
00165 d->clearScreen() ;
00166
00167
00168 }
00169
00170 int x = (rand()%widthRange) + wMargin;
00171 int y = (rand()%heightRange ) + hMargin ;
00172 d->displayText(test,Point2D<int>(x,y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ;
00173 d->waitFrames(displayFrame*l) ;
00174 return test ;
00175 }
00176
00177
00178
00179
00180
00181 string unlimitedDigitMemorizationTask(int maxForDigit=10 ,float wp = 1.0f, float hp = 1.0f, int displayFrame = 30 , int delayFrame = 30){
00182 vector<int> pickedones = vector<int>() ;
00183
00184 string test = string("") ;
00185 string tp = string("") ;
00186 int widthRange = (int)((float)(d->getWidth()) * wp);
00187 int heightRange = (int)((float)(d->getHeight()) * hp);
00188 int wMargin = (d->getWidth() - widthRange)/2 ;
00189 int hMargin = (d->getHeight() - heightRange) / 2 ;
00190
00191 SDL_Event event;
00192
00193
00194 while( true ){
00195 d->clearScreen() ;
00196 while( SDL_PollEvent(&event) != 0 ){
00197 if (event.type == SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_LEFT) return test ;
00198 }
00199 d->waitFrames(delayFrame) ;
00200 int nd;
00201 do{ nd= rand()% maxForDigit ; }while(itIsInThere(nd,pickedones) && pickedones.size() < 11) ;
00202 pickedones.push_back(nd);
00203 tp = stringify(nd) ;
00204
00205
00206
00207 test += tp ;
00208
00209
00210 }
00211 int x = (rand()%widthRange) + wMargin;
00212 int y = (rand()%heightRange ) + hMargin ;
00213 d->displayText(test,Point2D<int>(x,y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ;
00214 d->waitFrames(displayFrame) ;
00215 return test ;
00216 }
00217
00218
00219
00220
00221
00222 void scramble(vector<string>& v){
00223 vector<string> tv = vector<string>() ;
00224 while(v.size()>0){
00225 tv.push_back(v[0]);
00226 v.erase(v.begin());
00227 }
00228 int i = 0 ;
00229 while(tv.size()>0){
00230 i = rand()%tv.size() ;
00231 v.push_back(tv[i]);
00232 tv.erase(tv.begin()+i);
00233 }
00234 }
00235
00236
00237
00238
00239
00240 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){
00241 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00242 textIm.clear(bgcolor);
00243 writeText(textIm, Point2D<int>((size.i - label.length()*10)/2,(size.j-20) /2),label.c_str(),txtcolor,bgcolor);
00244 SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00245 Uint32 bc = d->getUint32color(bordercolor);
00246 drawRectangle(surf,bc,0,0,size.i -1,size.j -1 ,border);
00247 SDL_Surface* blank =getABlankSurface(size.i , size.j);
00248 SDL_Rect clip;
00249 clip.x = 0 ;
00250 clip.y = 0 ;
00251 clip.w = size.i ;
00252 clip.h = size.j ;
00253 apply_surface(0,0,*surf,*blank,clip);
00254 dumpSurface(surf) ;
00255 return blank ;
00256 }
00257
00258
00259
00260
00261
00262
00263 SDL_Surface* getKeyPad(map<string , SDL_Rect>& buttmap){
00264 SDL_Surface* pad= getABlankSurface(d->getWidth()/4,d->getHeight()/3);
00265 SDL_Rect clip;
00266 clip.x=0;
00267 clip.y=0;
00268 clip.w= pad->w / 3 ;
00269 clip.h = pad->h / 4 ;
00270
00271 for( int i = 1 ; i < 10 ; i++){
00272 SDL_Surface* but = getButtonImage(stringify(i),PixRGB<byte>(0,0,0),PixRGB<byte>(255,255,255),Point2D<int>(pad->w / 3 , pad->h / 4),PixRGB<byte>(255, 98 , 25),3);
00273 SDL_Rect cl ;
00274 cl.x = ((i-1)%3)*(pad->w)/3 ; cl.y= ((i-1)/3)*((pad->h)/4) ;
00275 cl.w = clip.w ;
00276 cl.h = clip.h ;
00277 apply_surface( cl.x , cl.y ,*but,*pad,clip);
00278 buttmap[stringify(i)] = cl ;
00279 dumpSurface(but);
00280 }
00281 SDL_Rect cl1 ;
00282 cl1.x = 0 ; cl1.y= 3*((pad->h)/4) ;
00283 cl1.w = clip.w ;
00284 cl1.h = clip.h ;
00285 buttmap["z"] = cl1 ;
00286 SDL_Surface* but = getButtonImage(string("<-"),PixRGB<byte>(0,0,0),PixRGB<byte>(255,255,255),Point2D<int>(pad->w / 3 , pad->h / 4),PixRGB<byte>(255, 98 , 25),3);
00287 apply_surface(0, 3*((pad->h)/4),*but,*pad,clip);
00288 dumpSurface(but);
00289 SDL_Rect cl2 ;
00290 cl2.x = (pad->w)/3 ; cl2.y= 3*((pad->h)/4) ;
00291 cl2.w = clip.w ;
00292 cl2.h = clip.h ;
00293 buttmap["0"] = cl2 ;
00294 but = getButtonImage(string("0"),PixRGB<byte>(0,0,0),PixRGB<byte>(255,255,255),Point2D<int>(pad->w / 3 , pad->h / 4),PixRGB<byte>(255, 98 , 25),3);
00295 apply_surface((pad->w)/3, 3*((pad->h)/4),*but,*pad,clip);
00296 dumpSurface(but);
00297 SDL_Rect cl3 ;
00298 cl3.x = 2*(pad->w)/3 ; cl3.y= 3*((pad->h)/4) ;
00299 cl3.w = clip.w ;
00300 cl3.h = clip.h ;
00301 buttmap["o"] = cl3 ;
00302 but = getButtonImage(string("Ok"),PixRGB<byte>(0,0,0),PixRGB<byte>(255,255,255),Point2D<int>(pad->w / 3 , pad->h / 4),PixRGB<byte>(255, 98 , 25),3);
00303 apply_surface(2*(pad->w)/3, 3*((pad->h)/4),*but,*pad,clip);
00304 dumpSurface(but);
00305 return pad ;
00306 }
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316 string getPressedButtonCommand(map<string , SDL_Rect>& buttmap,Point2D<int> offset=Point2D<int>(0,0)){
00317 int quit = 0 ;
00318 string s ;
00319 SDL_Event event ;
00320 while( quit!=2 ){
00321 while( SDL_PollEvent( &event ) ) {
00322 if(event.type == SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_LEFT ){
00323 for( map<string , SDL_Rect>::iterator it = buttmap.begin() ; it!=buttmap.end() ; ++it){
00324 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) {
00325 quit = 2 ;
00326 s = it->first ;
00327 break;
00328 }
00329
00330 }
00331 }
00332
00333 }
00334 }
00335 return s ;
00336
00337 }
00338
00339
00340
00341
00342
00343
00344
00345 string getDigitSequenceFromSubject(uint maxl = 7 ){
00346 d->showCursor(true) ;
00347
00348 map<string , SDL_Rect>* buttmap = new map<string , SDL_Rect>();
00349
00350 SDL_Surface * keypad = getKeyPad(*buttmap);
00351
00352 SDL_Rect offset ;
00353 offset.x = (d->getWidth() - keypad->w) /2;
00354 offset.y = (d-> getHeight() - keypad->h) /2;
00355
00356 d->displaySDLSurfacePatch(keypad , &offset,NULL , -2,false, true);
00357
00358 string p = string("") ;
00359
00360 string tp = string("");
00361
00362 while( tp.compare("o")!=0 ){
00363
00364 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) ;
00365 SDL_Rect offs ; offs.x = (d->getWidth() - dp->w) /2 ; offs.y = d->getHeight()/6 ;
00366 d->displaySDLSurfacePatch(dp , &offs , NULL , -2 , false ,true ) ;
00367
00368 tp = getPressedButtonCommand(*buttmap,Point2D<int>(offset.x,offset.y)) ;
00369 dumpSurface(dp) ;
00370 if(tp.compare("z")==0 && p.size()>=0 ) {
00371 if (p.size()>0) p = p.substr(0,p.size()-1) ;
00372 }else{
00373 if(p.size() < maxl && tp.compare("o")!=0) {
00374 p +=tp ;
00375 }
00376
00377 }
00378
00379 }
00380 buttmap = 0 ;
00381 dumpSurface(keypad) ;
00382 d->clearScreen() ;
00383 return p ;
00384
00385 }
00386
00387
00388
00389
00390
00391
00392
00393 string ascSort(string st)
00394 {
00395 string res = "" ;
00396 vector<string> v = vector<string>();
00397 for(uint i = 0 ; i < st.size() ; i++) v.push_back(st.substr(i,1)) ;
00398
00399 std::sort(v.begin(), v.end());
00400
00401 for ( uint i = 0 ; i < v.size() ; i++ ){
00402 res += v[i] ;
00403 }
00404 return res;
00405 }
00406
00407
00408
00409
00410
00411 string desSort(string st)
00412 {
00413 string res = "" ;
00414 vector<string> v = vector<string>();
00415 for(uint i = 0 ; i < st.size() ; i++) v.push_back(st.substr(i,1)) ;
00416 std::sort(v.begin(), v.end());
00417 std::reverse(v.begin(), v.end());
00418 for ( uint i = 0 ; i < v.size() ; i++ ){
00419 res += v[i] ;
00420 }
00421 return res;
00422 }
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432 bool isAnswerCorrect(string test , string answer , int mode){
00433
00434 if(mode == 0 && answer.compare(test)==0) return true ;
00435
00436 if(mode == 1 && answer.compare(ascSort(test))==0) return true ;
00437
00438 if(mode == 2 && answer.compare(desSort(test))==0) return true ;
00439
00440 return false;
00441 }
00442
00443
00444
00445 int addArgument(const string st,const string delim="="){
00446 int i = st.find(delim) ;
00447 argMap[st.substr(0,i)] = st.substr(i+1);
00448
00449 return 0 ;
00450 }
00451
00452 std::string getArgumentValue(string arg){
00453 return argMap[arg] ;
00454 }
00455
00456 std::string getUsageComment(){
00457
00458 string com = string("\nlist of arguments : \n");
00459
00460 com += "\ndelay-interval=[>1]:[>1] (the interval for random delay after stroop task) {default=10}\n";
00461 com += "\nfixation-blink=[y/n] (show the blink for fixation after stroop task or no) {defaule y}\n";
00462 com += "\nimage-dir=[path to image directory] (needed for mode 2 and 3) {default=60:160} \n" ;
00463 com += "\nlogfile=[logfilename.psy] {default = psycho-stroop-concurrent.psy}\n" ;
00464 com += "\nmemo=[a_string_without_white_space]\n";
00465 com += "\nmode=[1..5] (1 memorization only , 2 dynamic memorization only (ending with evens ascending and ending with odds discending)"
00466 ", 3 memorization + image display , 4 for dynamic memorization + image display "
00467 "5 for image display only ) {default=1}\n";
00468 com += "\ndigit-test-size=[<1](number of words in the stroop task){default=6} \n" ;
00469 com += "\nsubject=[subject_name] \n" ;
00470 com += "\ntest-rounds=[>1] (needed for mode1) {default=5}\n";
00471 com += "\ndigit-onset=[>1] (number of frames that the digit will remain onset per digit){default=10}\n";
00472 com += "\ndigit-offset=[>1](number of frames that between two consequent digit onset){default=30}\n";
00473 com += "\nwidth-range=[1..100](the percentage of the width of screen for showing the digits){default=100}\n";
00474 com += "\nheight-range=[1..100](the percentage of the height of screen for showing the digits){default=100}\n";
00475 com += "\nblink-num=[>1](number of blinking of fixation cross){default=3} \n";
00476 com += "\nblink-delay=[>1](delay for blinking cross apprearnce on the screen){default=2}\n";
00477 com += "\ncalib-refresh-period=[>1](number of tests between two calibration){default=12} \n";
00478 return com ;
00479 }
00480
00481
00482 extern "C" int main(const int argc, char** argv)
00483 {
00484
00485 MYLOGVERB = LOG_INFO;
00486
00487 argMap["mode"] = "1" ;
00488 argMap["logfile"]="psycho-digit-concurrent.psy" ;
00489 argMap["digit-test-size"]="6" ;
00490 argMap["image-dir"]="..";
00491 argMap["test-rounds"]="5";
00492 argMap["delay-interval"]="60:160" ;
00493 argMap["subject"]="" ;
00494 argMap["memo"]="" ;
00495 argMap["fixation-blink"]="y" ;
00496 argMap["digit-onset"]="10" ;
00497 argMap["digit-offset"]="30" ;
00498 argMap["width-range"]="100" ;
00499 argMap["height-range"]="100" ;
00500 argMap["blink-num"]="3" ;
00501 argMap["blink-delay"]="2" ;
00502 argMap["calib-refresh-period"] = "12" ;
00503 manager.addSubComponent(d);
00504 nub::soft_ref<EventLog> el(new EventLog(manager));
00505 manager.addSubComponent(el);
00506 nub::soft_ref<EyeTrackerConfigurator>
00507 etc(new EyeTrackerConfigurator(manager));
00508 manager.addSubComponent(etc);
00509
00510 if (manager.parseCommandLine(argc, argv,
00511 "at least one argument needed", 1, -1)==false){
00512 cout<<getUsageComment()<<endl;
00513 return(1);
00514 }
00515
00516 for(uint i = 0 ; i < manager.numExtraArgs() ; i++){
00517 addArgument(manager.getExtraArg(i),std::string("=")) ;
00518 }
00519
00520 manager.setOptionValString(&OPT_EventLogFileName, argMap["logfile"]);
00521 manager.setOptionValString(&OPT_EyeTrackerType, "ISCAN");
00522
00523 nub::soft_ref<EyeTracker> et = etc->getET();
00524 d->setEyeTracker(et);
00525 d->setEventLog(el);
00526 et->setEventLog(el);
00527
00528
00529
00530 manager.start();
00531 for(map<string,string>::iterator it= argMap.begin(); it!= argMap.end() ; ++it) d->pushEvent("arg:"+ it->first+" value:"+it->second ) ;
00532
00533 d->clearScreen();
00534 d->displayISCANcalib();
00535 d->waitForMouseClick();
00536
00537
00538 d->displayText("CLICK LEFT button to calibrate; RIGHT to skip");
00539 int c = d->waitForMouseClick();
00540 if (c == 1) d->displayEyeTrackerCalibration(3,5,1 , true);
00541
00542 d->clearScreen();
00543 int calibPeriod = atoi(argMap["calib-refresh-period"].c_str());
00544
00545 int blinkNum = atoi(argMap["blink-num"].c_str());
00546 int blinkDelay = atoi(argMap["blink-delay"].c_str());
00547
00548 int mode = atoi(argMap["mode"].c_str()) ;
00549
00550
00551
00552 if(mode==1 || mode==2 ){
00553 int numOfTests = atoi(argMap["test-rounds"].c_str()) ;
00554 int stringSize = atoi(argMap["digit-test-size"].c_str()) ;
00555 string::size_type position = argMap["delay-interval"].find(":");
00556 int minDel = atoi(argMap["delay-interval"].substr(0,position).c_str()) ;
00557 int maxDel = atoi(argMap["delay-interval"].substr(position+1).c_str()) ;
00558 float wr = ((float)(atoi(argMap["width-range"].c_str())))/100.0f;
00559 float hr = ((float)(atoi(argMap["height-range"].c_str())))/100.0f;
00560 int onsetDel = atoi(argMap["digit-onset"].c_str()) ;
00561 int offsetDel = atoi(argMap["digit-offset"].c_str()) ;
00562
00563 for(int i = 0 ; i < numOfTests ; i++){
00564 d->pushEvent("**************************************") ;
00565 d->showCursor(true);
00566 d->displayText("click one of the mouse buttons to start!");
00567 d->waitForMouseClick() ;
00568 d->showCursor(false);
00569
00570 string testString ;
00571 if(stringSize == 0 ){
00572 testString = unlimitedDigitMemorizationTask( 10 , wr , hr , onsetDel , offsetDel);
00573 }else{
00574 testString = digitMemorizationTask(stringSize, 10 , wr , hr , onsetDel , offsetDel) ;
00575 }
00576
00577 d->pushEvent("the memorization sequence is : "+testString) ;
00578 d->waitFrames((rand()%(maxDel - minDel)) +minDel);
00579 string answer = getDigitSequenceFromSubject(testString.size());
00580 bool af = false ;
00581 if(mode==1){
00582 af = isAnswerCorrect(testString,answer,0);
00583 }else{
00584 int m = atoi(testString.substr(testString.size()-1).c_str()) % 2 ;
00585 switch( m ){
00586 case 0 : af = isAnswerCorrect(testString , answer , 1 ) ; break ;
00587 case 1 : af = isAnswerCorrect(testString , answer , 2 ) ; break ;
00588 }
00589
00590 }
00591 d->pushEvent("subject keyed : "+answer);
00592 if(af){
00593 d->pushEvent("answer was correct");
00594 }else{
00595 d->pushEvent("answer was incorrect");
00596 }
00597
00598 }
00599 }
00600
00601
00602
00603
00604 if(mode == 3 || mode == 4){
00605 string::size_type position = argMap["delay-interval"].find(":");
00606 int minDel = atoi(argMap["delay-interval"].substr(0,position).c_str()) ;
00607 int maxDel = atoi(argMap["delay-interval"].substr(position+1).c_str()) ;
00608 int stringSize = atoi(argMap["digit-test-size"].c_str()) ;
00609 string dir = argMap["image-dir"];
00610 vector<string> files = vector<string>();
00611 getdir(dir,files);
00612 float wr = ((float)(atoi(argMap["width-range"].c_str())))/100.0f;
00613 float hr = ((float)(atoi(argMap["height-range"].c_str())))/100.0f;
00614 int onsetDel = atoi(argMap["digit-onset"].c_str()) ;
00615 int offsetDel = atoi(argMap["digit-offset"].c_str()) ;
00616 int c = 0 ;
00617 while(files.size()>0){
00618 c++ ;
00619 if(c%calibPeriod == 0){
00620
00621 d->displayText("CLICK LEFT button to calibrate; RIGHT to skip");
00622 int cl = d->waitForMouseClick();
00623 if (cl == 1) d->displayEyeTrackerCalibration(3,5,1 , true);
00624 d->clearScreen();
00625 }
00626 int imageIndex = rand()%files.size() ;
00627 SDL_Surface *surf = load_image(files[imageIndex]);
00628 float r1 = (float)d->getWidth()/(float)surf->w ;
00629 float r2 = (float)d->getHeight() / (float)surf->h ;
00630 surf = SDL_Resize(surf ,min(r1,r2) , 5 );
00631 SDL_Rect offset;
00632 offset.x = (d->getWidth() - surf->w) /2;
00633 offset.y = (d-> getHeight() - surf->h) /2;
00634 d->pushEvent("**************************************") ;
00635 d->showCursor(true);
00636 d->displayText("click a mouse button to start!");
00637 d->waitForMouseClick() ;
00638 d->showCursor(false);
00639 string testString ;
00640 if(stringSize == 0 ){
00641 testString = unlimitedDigitMemorizationTask( 10 , wr , hr , onsetDel , offsetDel);
00642 }else{
00643 testString = digitMemorizationTask(stringSize, 10 , wr , hr , onsetDel , offsetDel) ;
00644 }
00645 d->pushEvent("the memorization sequence is : "+testString) ;
00646
00647 d->clearScreen() ;
00648 d->waitNextRequestedVsync(false, true);
00649 d->pushEvent(std::string("===== Showing image: ") +
00650 files[imageIndex] + " =====");
00651
00652 et->track(true);
00653
00654 if(argMap["fixation-blink"].compare("y")==0) d->displayFixationBlink(-1,-1,blinkNum,blinkDelay);
00655 d->pushEvent("image will go up");
00656 d->displaySDLSurfacePatch(surf , &offset,NULL , -2,false, true);
00657 d->waitFrames((rand()%(maxDel-minDel)) +minDel );
00658 d->clearScreen() ;
00659 d->pushEvent("image is down");
00660 dumpSurface(surf);
00661
00662 usleep(50000);
00663 et->track(false);
00664
00665 string answer = getDigitSequenceFromSubject(testString.size());
00666 bool af = false ;
00667 if(mode==3){
00668 af = isAnswerCorrect(testString,answer,0);
00669 }else{
00670 int m = atoi(testString.substr(testString.size()-1).c_str()) % 2 ;
00671 switch( m ){
00672 case 0 : af = isAnswerCorrect(testString , answer , 1 ) ; break ;
00673 case 1 : af = isAnswerCorrect(testString , answer , 2 ) ; break ;
00674 }
00675
00676 }
00677 d->pushEvent("subject keyed : "+answer);
00678 if(af){
00679 d->pushEvent("answer was correct");
00680 }else{
00681 d->pushEvent("answer was incorrect");
00682 }
00683 d->clearScreen() ;
00684 files.erase(files.begin()+imageIndex);
00685 }
00686 }
00687
00688
00689 if(mode == 5){
00690 string::size_type position = argMap["delay-interval"].find(":");
00691 int minDel = atoi(argMap["delay-interval"].substr(0,position).c_str()) ;
00692 int maxDel = atoi(argMap["delay-interval"].substr(position+1).c_str()) ;
00693 string dir = argMap["image-dir"];
00694 vector<string> files = vector<string>();
00695 getdir(dir,files);
00696 int c = 0 ;
00697
00698 while(files.size()>0){
00699 c++ ;
00700 if(c%calibPeriod == 0){
00701
00702 d->displayText("CLICK LEFT button to calibrate; RIGHT to skip");
00703 int cl = d->waitForMouseClick();
00704 if (cl == 1) d->displayEyeTrackerCalibration(3,5,1 , true);
00705 d->clearScreen();
00706 }
00707 int imageIndex = rand()%files.size() ;
00708
00709
00710
00711
00712
00713 SDL_Surface *surf = load_image(files[imageIndex]);
00714 float r1 = (float)d->getWidth()/(float)surf->w ;
00715 float r2 = (float)d->getHeight() / (float)surf->h ;
00716 surf = SDL_Resize(surf ,min(r1,r2) , 5 );
00717 SDL_Rect offset;
00718 offset.x = (d->getWidth() - surf->w) /2;
00719 offset.y = (d-> getHeight() - surf->h) /2;
00720 d->waitFrames(45);
00721 d->waitNextRequestedVsync(false, true);
00722 d->pushEvent(std::string("===== Showing image: ") +
00723 files[imageIndex] + " =====");
00724
00725
00726 et->track(true);
00727
00728 if(argMap["fixation-blink"].compare("y")==0) d->displayFixationBlink(-1,-1,blinkNum,blinkDelay);
00729
00730 d->displaySDLSurfacePatch(surf , &offset,NULL , -2,false, true);
00731 d->waitFrames((rand()%(maxDel-minDel)) +minDel );
00732 dumpSurface(surf);
00733
00734 usleep(50000);
00735 et->track(false);
00736 d->clearScreen() ;
00737 files.erase(files.begin()+imageIndex);
00738 }
00739
00740 }
00741
00742 d->clearScreen();
00743 d->displayText("Experiment complete. Thank you!");
00744 d->waitForMouseClick();
00745
00746
00747 manager.stop();
00748
00749
00750
00751 return 0;
00752 }
00753
00754 #endif // INVT_HAVE_LIBSDL_IMAGE
00755