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 <SDL/SDL_mixer.h>
00059 #include <stdio.h>
00060 #include <stdlib.h>
00061 #include <sstream>
00062 #include <time.h>
00063 #include "Image/DrawOps.H"
00064 #include "GameBoard/resize.h"
00065
00066
00067
00068
00069 #ifndef INVT_HAVE_LIBSDL_IMAGE
00070 #include <cstdio>
00071 int main()
00072 {
00073 fprintf(stderr, "The SDL_image library must be installed to use this program\n");
00074 return 1;
00075 }
00076
00077 #else
00078
00079
00080
00081 using namespace std;
00082
00083 ModelManager manager("Psycho Auditory");
00084 nub::soft_ref<PsychoDisplay> d(new PsychoDisplay(manager));
00085 map<uint,uint> testMap ;
00086 map<string,string> argMap ;
00087 Mix_Chunk *highchunk = NULL;
00088 Mix_Chunk *mediumchunk = NULL;
00089 Mix_Chunk *lowchunk = NULL;
00090
00091
00092
00093
00094 template <class T> std::string stringify(T i)
00095 {
00096 ostringstream o ;
00097 o << i ;
00098 return o.str();
00099 }
00100
00101
00102
00103
00104 int getdir (string dir, vector<string> &files)
00105 {
00106 DIR *dp;
00107 struct dirent *dirp;
00108 if((dp = opendir(dir.c_str())) == NULL) {
00109 cout << "Error(" << errno << ") opening " << dir << endl;
00110 return errno;
00111 }
00112 string fn = "" ;
00113 size_t found;
00114 string extension = "" ;
00115 while ((dirp = readdir(dp)) != NULL) {
00116 fn = string(dirp->d_name) ;
00117 found = fn.find_last_of(".");
00118 if(found > 0 && found <1000){
00119 extension = fn.substr(found) ;
00120 if(extension.compare(".png")== 0 || extension.compare(".jpg")==0 )
00121 files.push_back(dir+"/"+fn);
00122 }
00123 }
00124 closedir(dp);
00125 return 0;
00126 }
00127
00128 void getMouseEvent(){
00129 bool quit = false ;
00130 SDL_Event event ;
00131 while( quit == false ) {
00132 while( SDL_PollEvent( &event ) ) {
00133 if( event.type == SDL_MOUSEBUTTONDOWN ) { quit = true; }
00134 }
00135 }
00136 }
00137
00138
00139 vector<int> getAuditoryTask(string ts){
00140
00141
00142
00143 string::size_type position = ts.find(":");
00144 int minTaskSize = atoi(ts.substr(0,position).c_str()) ;
00145 int maxTaskSize = atoi(ts.substr(position+1).c_str()) ;
00146 int taskSize = rand()%((maxTaskSize-minTaskSize)/2);
00147 taskSize += (minTaskSize-1)/2 ;
00148 taskSize = 2*taskSize +1 ;
00149 vector<int> task = vector<int>() ;
00150 for(int i = 0 ; i < taskSize ; i++){
00151 int current_task = rand()%3;
00152 task.push_back(current_task) ;
00153 }
00154
00155 return task ;
00156 }
00157
00158
00159 void scramble(vector<string>& v){
00160 vector<string> tv = vector<string>() ;
00161 while(v.size()>0){
00162 tv.push_back(v[0]);
00163 v.erase(v.begin());
00164 }
00165 int i = 0 ;
00166 while(tv.size()>0){
00167 i = rand()%tv.size() ;
00168 v.push_back(tv[i]);
00169 tv.erase(tv.begin()+i);
00170 }
00171 }
00172
00173
00174
00175
00176 bool memoryTest(vector<string> dil , vector<string> cil){
00177 d->showCursor(true);
00178 bool flag = false ;
00179
00180 int sf = (int)sqrt(dil.size()+cil.size()) ;
00181 if((uint)(sf*sf) < dil.size()+cil.size() ) sf++ ;
00182 float sizefactor = 1.0f/(float)sf ;
00183
00184 vector<string>* fls = new vector<string>() ;
00185
00186 for(uint i = 0 ; i < dil.size() ; i++){
00187 fls->push_back(dil[i]);
00188 }
00189 for(uint i = 0 ; i < cil.size() ; i++){
00190 fls->push_back(cil[i]);
00191 }
00192
00193 scramble(*fls) ;
00194
00195 SDL_Surface* blank = getABlankSurface(d->getWidth(),d->getHeight()) ;
00196
00197
00198 SDL_Surface* oblank = getABlankSurface(d->getWidth(),d->getHeight()) ;
00199 d->displayText("Time for a memory test!",true, 1);
00200
00201
00202
00203 SDL_Surface* pbar = getABlankSurface((d->getWidth())/2,(d->getHeight())/25);
00204 SDL_Rect pbarOffset = SDL_Rect();
00205 pbarOffset.x = (d->getWidth() - pbar->w )/2 ;
00206 pbarOffset.y = (d->getHeight() - pbar->h)/2 ;
00207 d->displaySDLSurfacePatch(pbar , &pbarOffset,NULL , -2,false, true);
00208
00209
00210 int c = 0 ;
00211 for(int i = 0 ; i < sf ; i++){
00212 for(int j = 0 ; j < sf ; j++){
00213 if((uint)(j*sf + i) < fls->size()){
00214 c++ ;
00215
00216 SDL_Surface* ts = load_image((*fls)[j*sf + i]);
00217 sizefactor = min(((float)(d->getWidth()))/sf/((float)(ts->w)),((float)(d->getHeight()))/sf/((float)(ts->h)));
00218
00219 ts = SDL_Resize(ts,sizefactor,5) ;
00220
00221 SDL_Rect* clip = new SDL_Rect() ;
00222 clip->x = 0 ;
00223 clip->y = 0 ;
00224 clip->w = ts->w ;
00225 clip->h = ts->h ;
00226 SDL_Rect offset;
00227 offset.x = i*(d->getWidth())/sf + ((d->getWidth())/sf - ts->w)/2;
00228 offset.y = j*(d->getHeight())/sf + ((d->getHeight())/sf - ts->h)/2;
00229
00230
00231 apply_surface(offset.x, offset.y,*ts,*blank ,*clip);
00232 apply_surface(offset.x, offset.y,*ts,*oblank ,*clip);
00233
00234 dumpSurface(ts);
00235 delete clip ;
00236
00237 Uint32 color = d->getUint32color(PixRGB<byte>(255, 98 , 25));
00238 fillRectangle(pbar,color,0,0,(int)((float)((j*sf + i + 1)*(pbar->w))/(float)(fls->size())) , pbar->h);
00239 fillRectangle(pbar,color,0,0,(int)((float)c/float(fls->size())) , pbar->h);
00240 d->displaySDLSurfacePatch(pbar , &pbarOffset,NULL , -2,false, true);
00241 }
00242
00243
00244 }
00245 }
00246
00247 d->displayText("Click to start!",true);
00248 SDL_Rect offset;
00249 offset.x = 0;
00250 offset.y = 0;
00251 getMouseEvent() ;
00252 d->displaySDLSurfacePatch(blank , &offset,NULL , -2,false, true);
00253 uint quit = 0 ;
00254 SDL_Event event ;
00255 int fmx = 0 ;
00256 int fmy = 0 ;
00257 int smx = 0 ;
00258 int smy = 0 ;
00259 int choice1 = 0 ;
00260 int choice2 = 0 ;
00261
00262 while( quit != 2 ) {
00263 while( SDL_PollEvent( &event ) ) {
00264
00265 if( event.type == SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_LEFT
00266 && event.button.x > offset.x && event.button.x <= offset.x + blank->w
00267 && event.button.y > offset.y && event.button.y <= offset.y + blank->h
00268 && quit == 1
00269 ) {
00270 smx = event.button.x ;
00271 smy = event.button.y ;
00272 choice2 = (int)(sf*(smx-offset.x)/(d->getWidth())) + sf*(int)(sf*(smy-offset.y)/(d->getHeight())) ;
00273 if(choice1 == choice2){
00274 if((uint)choice1 < fls->size()){
00275 quit = 2 ;
00276 d->pushEvent("memory test choice : "+(*fls)[choice1]);
00277
00278 for(uint f = 0 ; f < dil.size() ; f++){
00279 if((*fls)[choice1].compare(dil[f])==0) {
00280 flag = true ;
00281 break ;
00282 }
00283 }
00284
00285 if (flag==true){
00286 d->pushEvent("memory test result : correct" );
00287 }else{
00288 d->pushEvent("memory test result : incorrect" );
00289 }
00290
00291 cout<< "second choice "<< choice2 <<endl;
00292 }else{
00293 quit = 3 ;
00294 SDL_Rect* clip = new SDL_Rect() ;
00295 clip->x = 0 ;
00296 clip->y = 0 ;
00297 clip->w = d->getWidth() ;
00298 clip->h = d->getHeight() ;
00299 apply_surface(0,0,*oblank,*blank,*clip) ;
00300 delete clip ;
00301 d->displaySDLSurfacePatch(blank , &offset,NULL , -2,false, true);
00302
00303 }
00304
00305 }else{
00306 quit = 3 ;
00307 SDL_Rect* clip = new SDL_Rect() ;
00308 clip->x = 0 ;
00309 clip->y = 0 ;
00310 clip->w = d->getWidth() ;
00311 clip->h = d->getHeight() ;
00312 apply_surface(0,0,*oblank,*blank,*clip) ;
00313 delete clip ;
00314 d->displaySDLSurfacePatch(blank , &offset,NULL , -2,false, true);
00315 }
00316 }
00317
00318 if( event.type == SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_LEFT
00319 && event.button.x > offset.x && event.button.x <= offset.x + blank->w
00320 && event.button.y > offset.y && event.button.y <= offset.y + blank->h
00321 && quit == 0
00322 ) {
00323 SDL_Rect* clip = new SDL_Rect() ;
00324 clip->x = 0 ;
00325 clip->y = 0 ;
00326 clip->w = d->getWidth() ;
00327 clip->h = d->getHeight() ;
00328 apply_surface(0,0,*oblank,*blank,*clip) ;
00329 delete clip ;
00330 quit = 1;
00331 fmx = event.button.x ;
00332 fmy = event.button.y ;
00333 int i = sf*(fmx-offset.x)/(d->getWidth()) ;
00334 int j = sf*(fmy-offset.y)/(d->getHeight());
00335 cout<<"("<<sf*(fmx-offset.x)/(d->getWidth())<<","<<sf*(fmy-offset.y)/(d->getHeight())<<")"<<endl ;
00336 choice1 = (int)(sf*(fmx-offset.x)/(d->getWidth())) + sf*(int)(sf*(fmy-offset.y)/(d->getHeight())) ;
00337 cout<<"first choice:" << choice1 <<endl;
00338 Uint32 color = d->getUint32color(PixRGB<byte>(255, 98 , 25));
00339 drawRectangle(blank , color , i*(d->getWidth())/sf , j*(d->getHeight())/sf ,(d->getWidth())/sf , (d->getHeight())/sf , 5) ;
00340 d->displaySDLSurfacePatch(blank , &offset,NULL , -2,false, true);
00341 }
00342
00343 if(quit==3) quit=0 ;
00344
00345 }
00346 }
00347
00348
00349
00350 dumpSurface(blank);
00351 dumpSurface(oblank);
00352 dumpSurface(pbar) ;
00353 delete fls ;
00354 return flag ;
00355 }
00356
00357
00358 void firstTask(const uint l){
00359 Uint32 green = d->getUint32color(PixRGB<byte>(0, 255, 0));
00360 Uint32 blue = d->getUint32color(PixRGB<byte>(0, 0, 255));
00361 Uint32 red = d->getUint32color(PixRGB<byte>(255,0,0));
00362 Uint32 color = 0 ;
00363 int c = 0 ;
00364 SDL_Rect offset;
00365 d->clearScreen() ;
00366
00367 SDL_Surface* blankSurface = getABlankSurface(d->getWidth(),d->getHeight()) ;
00368 offset.x = (d->getWidth() - blankSurface->w) /2;
00369 offset.y = (d-> getHeight() - blankSurface->h) /2;
00370 for (uint i = 0 ; i < l ; i++){
00371 c = rand()%3 ;
00372 switch(c){
00373 case 0 : color = red ;break;
00374 case 1 : color = green ; break ;
00375 case 2 : color = blue ; break ;
00376 }
00377
00378 fillQuadricRadiant(blankSurface,color,rand()%(blankSurface->w -100 ) + 50 ,rand()%(blankSurface->h -100)+50,20) ;
00379 d->displaySDLSurfacePatch(blankSurface , &offset,NULL , -2,false, true);
00380 d->waitFrames(10);
00381 }
00382 dumpSurface(blankSurface) ;
00383 }
00384
00385
00386 void volumeAdjustment(const int randBase , const string extraMessage = "continue" ){
00387 int rndBase = randBase+1 ;
00388 map<int,string> imap = map<int,string>();
00389 imap[0] = "high";
00390 imap[1] = "medium" ;
00391 imap[2] = "low" ;
00392 imap[3] = extraMessage ;
00393 d->clearScreen();
00394 d->pushEvent(std::string("voluem adjustment called"));
00395 d->displayText(std::string("click on the botton to play or cancel?"),true,1);
00396
00397 d->showCursor(true);
00398 SDL_Surface* blank =getABlankSurface((d->getWidth())/2 , d->getHeight()/10);
00399
00400 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00401 textIm.clear(PixRGB<byte>(182, 145, 225));
00402
00403 for(int i = 0 ; i < rndBase ; i ++){
00404 writeText(textIm, Point2D<int>((blank->w)/(2*rndBase) -2,10+100*i), imap[i].c_str());
00405 }
00406
00407 SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00408
00409 SDL_Rect clip;
00410 clip.x = 0 ;
00411 clip.w = (blank->w)/rndBase - 2 ;
00412 clip.h =blank->h ;
00413 for(int i = 0 ; i < rndBase ; i++){
00414 clip.y = i*100 ;
00415 apply_surface(i*(clip.w + 2),0,*surf,*blank,clip);
00416 }
00417
00418 SDL_Rect offset;
00419 offset.x = (d->getWidth() - blank->w) /2;
00420 offset.y = (d-> getHeight() - blank->h) /2;
00421 d->pushEvent("the button panel is going up");
00422 d->displaySDLSurfacePatch(blank , &offset,NULL , -2,false, true);
00423
00424 bool quit = false ;
00425 SDL_Event event ;
00426 int mx = 0 ;
00427 int my = 0 ;
00428 while( quit == false ) {
00429 while( SDL_PollEvent( &event ) ) {
00430 if( event.type == SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_LEFT
00431 && event.button.x > offset.x && event.button.x <= offset.x + blank->w
00432 && event.button.y > offset.y && event.button.y <= offset.y + blank->h
00433 ) {
00434
00435 mx = event.button.x ;
00436 my = event.button.y ;
00437 switch( (mx - offset.x) / ((blank->w)/rndBase) ){
00438 case 0 : Mix_PlayChannel( -1, highchunk, 0 ) ;break ;
00439 case 1 : Mix_PlayChannel( -1, mediumchunk, 0 ) ;break ;
00440 case 2 : Mix_PlayChannel( -1, lowchunk, 0 ) ;break ;
00441 case 3 : quit=true ; break ;
00442 }
00443 }
00444 }
00445
00446 }
00447
00448 dumpSurface(blank);
00449 dumpSurface(surf) ;
00450 d->showCursor(false);
00451
00452 }
00453
00454
00455
00456
00457 void quiz(const int rndBase , const int answer ){
00458 map<int,string> imap = map<int,string>();
00459 imap[0] = "high";
00460 imap[2] = "low" ;
00461 imap[1] = "medium" ;
00462
00463
00464
00465 d->clearScreen();
00466 d->pushEvent(std::string("asking for confirmation number"));
00467 d->displayText(std::string("which one was played more?"),true,1);
00468
00469 d->showCursor(true);
00470 SDL_Surface* blank =getABlankSurface((d->getWidth())/2 , d->getHeight()/10);
00471
00472 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00473 textIm.clear(PixRGB<byte>(255, 156, 120));
00474
00475 for(int i = 0 ; i < rndBase ; i ++){
00476 writeText(textIm, Point2D<int>((blank->w)/(2*rndBase) -2,10+100*i), imap[i].c_str());
00477 }
00478
00479 SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00480
00481 SDL_Rect clip;
00482 clip.x = 0 ;
00483 clip.w = (blank->w)/rndBase - 2 ;
00484 clip.h =blank->h ;
00485 for(int i = 0 ; i < rndBase ; i++){
00486 clip.y = i*100 ;
00487 apply_surface(i*(clip.w + 2),0,*surf,*blank,clip);
00488 }
00489
00490 SDL_Rect offset;
00491 offset.x = (d->getWidth() - blank->w) /2;
00492 offset.y = (d-> getHeight() - blank->h) /2;
00493 d->pushEvent("the button panel is going up");
00494 d->displaySDLSurfacePatch(blank , &offset,NULL , -2,false, true);
00495
00496 bool quit = false ;
00497 SDL_Event event ;
00498 int mx = 0 ;
00499 int my = 0 ;
00500 while( quit == false ) {
00501 while( SDL_PollEvent( &event ) ) {
00502 if( event.type == SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_LEFT
00503 && event.button.x > offset.x && event.button.x <= offset.x + blank->w
00504 && event.button.y > offset.y && event.button.y <= offset.y + blank->h
00505 ) {
00506 quit = true;
00507 mx = event.button.x ;
00508 my = event.button.y ;
00509 }
00510 }
00511 }
00512
00513 switch( (mx - offset.x) / ((blank->w)/rndBase) ){
00514 case 0 : d->pushEvent("answered high") ; break ;
00515 case 1 : d->pushEvent("answered medium") ; break ;
00516 case 2 : d->pushEvent("answered low") ; break ;
00517 }
00518
00519 if((mx - offset.x) / ((blank->w)/rndBase) == answer) {
00520 d->pushEvent("correct answer") ;
00521 }else{
00522 d->pushEvent("incorrect answer") ;
00523 }
00524
00525 dumpSurface(blank);
00526 dumpSurface(surf) ;
00527 d->showCursor(false);
00528
00529 }
00530
00531
00532
00533
00534 void finalTask(const int rndBase = 2 , const uint delay = 10 ){
00535 int confNum = rand() % rndBase ;
00536 d->pushEvent(std::string("confirmation number : ")+stringify(confNum));
00537
00538 d->displayText(stringify(confNum),true,-2);
00539 d->waitFrames(delay);
00540 d->clearScreen();
00541 d->pushEvent(std::string("asking for confirmation number"));
00542 d->displayText(std::string("what was the number ? "),true,1);
00543
00544 d->showCursor(true);
00545 SDL_Surface* blank =getABlankSurface((d->getWidth())/2 , d->getHeight()/10);
00546
00547 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00548 textIm.clear(PixRGB<byte>(255, 255, 255));
00549
00550 for(int i = 0 ; i < rndBase ; i ++){
00551 writeText(textIm, Point2D<int>((blank->w)/(2*rndBase) -2,10+100*i), stringify(i).c_str());
00552 }
00553
00554 SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00555
00556 SDL_Rect clip;
00557 clip.x = 0 ;
00558 clip.w = (blank->w)/rndBase - 2 ;
00559 clip.h =blank->h ;
00560 for(int i = 0 ; i < rndBase ; i++){
00561 clip.y = i*100 ;
00562 apply_surface(i*(clip.w + 2),0,*surf,*blank,clip);
00563 }
00564
00565 SDL_Rect offset;
00566 offset.x = (d->getWidth() - blank->w) /2;
00567 offset.y = (d-> getHeight() - blank->h) /2;
00568 d->pushEvent("the button panel is going up");
00569 d->displaySDLSurfacePatch(blank , &offset,NULL , -2,false, true);
00570
00571 bool quit = false ;
00572 SDL_Event event ;
00573 int mx = 0 ;
00574 int my = 0 ;
00575 while( quit == false ) {
00576 while( SDL_PollEvent( &event ) ) {
00577 if( event.type == SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_LEFT
00578 && event.button.x > offset.x && event.button.x <= offset.x + blank->w
00579 && event.button.y > offset.y && event.button.y <= offset.y + blank->h
00580 ) {
00581 quit = true;
00582 mx = event.button.x ;
00583 my = event.button.y ;
00584 }
00585 }
00586 }
00587
00588 d->pushEvent("confirmed: " + stringify((mx - offset.x) / ((blank->w)/rndBase))) ;
00589 if((mx - offset.x) / ((blank->w)/rndBase) == (int)confNum) {
00590 d->pushEvent("correct confirmation") ;
00591 }else{
00592 d->pushEvent("incorrect confirmation") ;
00593 }
00594
00595 dumpSurface(blank);
00596 dumpSurface(surf) ;
00597 d->showCursor(false);
00598
00599 }
00600
00601
00602
00603 int addArgument(const string st,const string delim="="){
00604 int i = st.find(delim) ;
00605 argMap[st.substr(0,i)] = st.substr(i+1);
00606
00607 return 0 ;
00608 }
00609
00610 std::string getArgumentValue(string arg){
00611 return argMap[arg] ;
00612 }
00613
00614 std::string getUsageComment(){
00615
00616 string com = string("\nlist of arguments : \n");
00617
00618 com += "\nconf-num=[2..10] (random numbers in confirmation task) {default=2} \n" ;
00619 com += "\nconf-delay=[>1] (the delay in showing the confirmation number) {default=10}\n";
00620 com += "\ndelay-interval=[>1]:[>1] (the interval for random delay after stroop task) {default=20:30}\n";
00621 com += "\nfixation-blink=[y/n] (show the blink for fixation after stroop task or no) {defaule y}\n";
00622 com += "\nimage-dir=[path to image directory] (needed for mode 2 and 3) {default=60:160} \n" ;
00623 com += "\nlogfile=[logfilename.psy] {default = psycho-stroop-concurrent.psy}\n" ;
00624 com += "\nmemo=[a_string_without_white_space]\n";
00625 com += "\nmode=[1..6] (1 for auditory test only, 2 for auditory test + image display , "
00626 "3 for image display only ,4 for volume adjustment, 5 for volume adjustment and then auditory test"
00627 " , 6 for volume adjustment and then auditory test + image display ) {default=1}\n";
00628 com += "\ntask-size=[>1]:[>1](number of beats in a round of task){default=7:17} \n" ;
00629 com += "\nsubject=[subject_name] \n" ;
00630 com += "\ntest-rounds=[>1] (needed for mode1) {default=5}\n";
00631 com += "\nsound-dir=[path to wav files directory]{default=y}\n";
00632 com += "\nhigh-chunk=[first chunk sound]{default=high.wav}\n";
00633 com += "\nmedium-chunk=[second chunk sound]{default=medium.wav}\n";
00634 com += "\nlow-chunk=[third chunk sound]{default=low.wav}\n";
00635 com += "\nimage-onset-num=[>=0 and <=task-size] {default=2}" ;
00636 return com ;
00637 }
00638
00639
00640 extern "C" int main(const int argc, char** argv)
00641 {
00642
00643 MYLOGVERB = LOG_INFO;
00644 argMap["mode"] = "1" ;
00645 argMap["logfile"]="psycho-stroop-concurrent.psy" ;
00646 argMap["conf-number"] = "2" ;
00647 argMap["task-size"]="7:17" ;
00648 argMap["image-dir"]="..";
00649 argMap["conf-delay"]="10" ;
00650 argMap["test-rounds"]="5";
00651 argMap["delay-interval"]="20:30" ;
00652 argMap["subject"]="" ;
00653 argMap["memo"]="" ;
00654 argMap["fixation-blink"]="y" ;
00655 argMap["sound-dir"]="..";
00656 argMap["high-chunk"]="high.wav";
00657 argMap["medium-chunk"]="medium.wav";
00658 argMap["low-chunk"]="low.wav";
00659 argMap["image-onset-num"]="2";
00660
00661 manager.addSubComponent(d);
00662 nub::soft_ref<EventLog> el(new EventLog(manager));
00663 manager.addSubComponent(el);
00664 nub::soft_ref<EyeTrackerConfigurator> etc(new EyeTrackerConfigurator(manager));
00665 manager.addSubComponent(etc);
00666
00667 if (manager.parseCommandLine(argc, argv,
00668 "at least one argument needed", 1, -1)==false){
00669
00670
00671 cout<<getUsageComment()<<endl;
00672 return(1);
00673 }
00674
00675 for(uint i = 0 ; i < manager.numExtraArgs() ; i++){
00676 addArgument(manager.getExtraArg(i),std::string("=")) ;
00677 }
00678 if( Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 4096 ) == -1 ){
00679 LINFO( "did not open the mix-audio") ;
00680 return -1 ;
00681 }
00682 string highstr = argMap["sound-dir"] + "/" + argMap["high-chunk"];
00683 string mediumstr = argMap["sound-dir"] + "/" + argMap["medium-chunk"];
00684 string lowstr = argMap["sound-dir"] + "/" + argMap["low-chunk"];
00685 highchunk = Mix_LoadWAV(highstr.c_str());
00686 mediumchunk = Mix_LoadWAV(mediumstr.c_str());
00687 lowchunk = Mix_LoadWAV(lowstr.c_str());
00688 if( ( highchunk == NULL ) || ( mediumchunk == NULL ) || ( lowchunk == NULL ) )
00689 {
00690 LINFO("did not find the indicated wav files!");
00691 return -1;
00692 }
00693 manager.setOptionValString(&OPT_EventLogFileName, argMap["logfile"]);
00694 manager.setOptionValString(&OPT_EyeTrackerType, "ISCAN");
00695
00696 nub::soft_ref<EyeTracker> et = etc->getET();
00697 d->setEyeTracker(et);
00698 d->setEventLog(el);
00699 et->setEventLog(el);
00700
00701
00702
00703 manager.start();
00704 for(map<string,string>::iterator it= argMap.begin(); it!= argMap.end() ; ++it) d->pushEvent("arg:"+ it->first+" value:"+it->second ) ;
00705
00706
00707 d->clearScreen();
00708 d->displayISCANcalib();
00709 d->waitForKey();
00710
00711
00712 d->displayText("<SPACE> to calibrate; other key to skip");
00713 int c = d->waitForKey();
00714 if (c == ' ') d->displayEyeTrackerCalibration(3,3);
00715
00716 d->clearScreen();
00717 d->displayText("<SPACE> for random play; other key for ordered");
00718 c = d->waitForKey();
00719
00720 int mode = atoi(argMap["mode"].c_str()) ;
00721
00722 if(mode == 1 || mode == 5){
00723 string::size_type position = argMap["delay-interval"].find(":");
00724 int minDel = atoi(argMap["delay-interval"].substr(0,position).c_str()) ;
00725 int maxDel = atoi(argMap["delay-interval"].substr(position+1).c_str()) ;
00726 int numOfTests = atoi(argMap["test-rounds"].c_str()) ;
00727 int confNum = atoi(argMap["conf-number"].c_str()) ;
00728 int confDelay = atoi(argMap["conf-delay"].c_str()) ;
00729
00730 if(mode == 5){
00731 volumeAdjustment(3,"continue") ;
00732 }
00733 for(int i = 0 ; i < numOfTests ; i++){
00734 d->clearScreen() ;
00735 d->pushEvent("**************************************") ;
00736 d->showCursor(true);
00737 d->displayText("click one of the mouse buttons to start!");
00738 getMouseEvent() ;
00739 d->showCursor(false);
00740 d->clearScreen() ;
00741 vector<int> task = getAuditoryTask(argMap["task-size"]) ;
00742 string ts = string("");
00743 int high = 0 ;
00744 int medium = 0 ;
00745 int low = 0 ;
00746 int answ = 0 ;
00747 for( uint j = 0 ; j < task.size() ; j++){
00748 ts = ts + stringify(task[j]) ;
00749 switch( task[j] ){
00750 case 0 : high++;break ;
00751 case 1 : medium++;break;
00752 case 2 : low++;break ;
00753 }
00754 }
00755 int m = max(max(low,medium),high);
00756 if( m == high) answ = 0 ;
00757 if (m == medium ) answ = 1 ;
00758 if (m == low ) answ = 2 ;
00759 d->pushEvent("task sequence : "+ts);
00760 for( uint j = 0 ; j < task.size() ; j++ ){
00761 switch( task[j] ){
00762 case 0 : Mix_PlayChannel( -1, highchunk , 0 ) ;break ;
00763 case 1 : Mix_PlayChannel( -1, mediumchunk , 0 ); break ;
00764 case 2 : Mix_PlayChannel( -1, lowchunk , 0 ) ;break ;
00765 }
00766 d->waitFrames((rand()%(maxDel-minDel)) +minDel);
00767 }
00768 finalTask(confNum,confDelay) ;
00769 quiz(3,answ) ;
00770
00771 }
00772 }
00773
00774 if(mode == 2 || mode == 6){
00775 string::size_type position = argMap["delay-interval"].find(":");
00776 int minDel = atoi(argMap["delay-interval"].substr(0,position).c_str()) ;
00777 int maxDel = atoi(argMap["delay-interval"].substr(position+1).c_str()) ;
00778 string dir = argMap["image-dir"];
00779 vector<string> files = vector<string>();
00780 getdir(dir,files);
00781 int confNum = atoi(argMap["conf-number"].c_str()) ;
00782 int confDelay = atoi(argMap["conf-delay"].c_str()) ;
00783
00784 if(mode == 6){
00785 volumeAdjustment(3,"continue") ;
00786 }
00787 while(files.size()>0){
00788 int imageIndex = rand()%files.size() ;
00789 SDL_Surface *surf = load_image(files[imageIndex]);
00790 float r1 = (float)d->getWidth()/(float)surf->w ;
00791 float r2 = (float)d->getHeight() / (float)surf->h ;
00792 surf = SDL_Resize(surf ,min(r1,r2) , 5 );
00793 SDL_Rect offset;
00794 offset.x = (d->getWidth() - surf->w) /2;
00795 offset.y = (d-> getHeight() - surf->h) /2;
00796 d->pushEvent("**************************************") ;
00797 d->showCursor(true);
00798 d->displayText("click a mouse button to start!");
00799 getMouseEvent() ;
00800 d->showCursor(false);
00801 d->clearScreen() ;
00802 vector<int> task = getAuditoryTask(argMap["task-size"]) ;
00803 string ts = string("");
00804 int high = 0 ;
00805 int medium = 0 ;
00806 int low = 0 ;
00807 int answ = 0 ;
00808 for( uint j = 0 ; j < task.size() ; j++){
00809 ts = ts + stringify(task[j]) ;
00810 switch( task[j] ){
00811 case 0 : high++;break ;
00812 case 1 : medium++;break;
00813 case 2 : low++;break ;
00814 }
00815 }
00816 int m = max(max(low,medium),high);
00817 if( m == high) answ = 0 ;
00818 if (m == medium ) answ = 1 ;
00819 if (m == low ) answ = 2 ;
00820 d->pushEvent("task sequence : "+ts);
00821 for( uint j = 0 ; j < task.size() ; j++ ){
00822 switch( task[j] ){
00823 case 0 : Mix_PlayChannel( -1, highchunk , 0 ) ;break ;
00824 case 1 : Mix_PlayChannel( -1, mediumchunk , 0 ); break ;
00825 case 2 : Mix_PlayChannel( -1, lowchunk , 0 ) ;break ;
00826 }
00827
00828 if (j==2){
00829 d->waitNextRequestedVsync(false, true);
00830 d->pushEvent(std::string("===== Showing image: ") +
00831 files[imageIndex] + " =====");
00832
00833
00834 et->track(true);
00835
00836 if(argMap["fixation-blink"].compare("y")==0) d->displayFixationBlink();
00837
00838 d->displaySDLSurfacePatch(surf , &offset,NULL , -2,false, true);
00839 files.erase(files.begin()+imageIndex);
00840 }else{
00841 d->waitFrames((rand()%(maxDel-minDel)) +minDel);
00842 }
00843 }
00844
00845
00846 dumpSurface(surf);
00847
00848 usleep(50000);
00849 et->track(false);
00850
00851 finalTask(confNum,confDelay) ;
00852 quiz(3,answ) ;
00853 d->clearScreen() ;
00854
00855 d->clearScreen() ;
00856 }
00857 }
00858
00859 if(mode == 3){
00860 string::size_type position = argMap["delay-interval"].find(":");
00861 int minDel = atoi(argMap["delay-interval"].substr(0,position).c_str()) ;
00862 int maxDel = atoi(argMap["delay-interval"].substr(position+1).c_str()) ;
00863 string dir = argMap["image-dir"];
00864 vector<string> files = vector<string>();
00865 getdir(dir,files);
00866 int c = 0 ;
00867
00868 while(files.size()>0){
00869 c++ ;
00870 int imageIndex = rand()%files.size() ;
00871
00872
00873
00874
00875
00876 SDL_Surface *surf = load_image(files[imageIndex]);
00877 float r1 = (float)d->getWidth()/(float)surf->w ;
00878 float r2 = (float)d->getHeight() / (float)surf->h ;
00879 surf = SDL_Resize(surf ,min(r1,r2) , 5 );
00880 SDL_Rect offset;
00881 offset.x = (d->getWidth() - surf->w) /2;
00882 offset.y = (d-> getHeight() - surf->h) /2;
00883 d->waitNextRequestedVsync(false, true);
00884 d->pushEvent(std::string("===== Showing image: ") +
00885 files[imageIndex] + " =====");
00886
00887
00888 et->track(true);
00889
00890 if(argMap["fixation-blink"].compare("y")==0) d->displayFixationBlink();
00891 d->displaySDLSurfacePatch(surf , &offset,NULL , -2,false, true);
00892 d->waitFrames((rand()%(maxDel-minDel)) +minDel );
00893 dumpSurface(surf);
00894
00895 usleep(50000);
00896 et->track(false);
00897 d->clearScreen() ;
00898 files.erase(files.begin()+imageIndex);
00899 }
00900
00901 }
00902
00903 if(mode == 4){
00904 volumeAdjustment(3,"exit") ;
00905 }
00906
00907
00908 d->clearScreen();
00909 d->displayText("Experiment complete. Thank you!");
00910 d->waitForKey();
00911
00912
00913 manager.stop();
00914
00915 Mix_FreeChunk( highchunk );
00916 Mix_FreeChunk( lowchunk );
00917 Mix_FreeChunk( mediumchunk );
00918 Mix_CloseAudio();
00919
00920 return 0;
00921 }
00922
00923 #endif // INVT_HAVE_LIBSDL_IMAGE
00924