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
00039
00040 #include "Component/ModelManager.H"
00041 #include "Image/Image.H"
00042 #include "Psycho/PsychoDisplay.H"
00043 #include "Psycho/EyeTrackerConfigurator.H"
00044 #include "Psycho/EyeTracker.H"
00045 #include "Psycho/PsychoOpts.H"
00046 #include "Component/EventLog.H"
00047 #include "Component/ComponentOpts.H"
00048 #include "Raster/Raster.H"
00049 #include "Util/MathFunctions.H"
00050 #include "Util/Types.H"
00051 #include "GameBoard/basic-graphics.H"
00052 #include <sys/types.h>
00053 #include <dirent.h>
00054 #include <errno.h>
00055 #include <vector>
00056 #include <string>
00057 #include <iostream>
00058 #include <SDL/SDL.h>
00059 #include <SDL/SDL_image.h>
00060 #include <SDL/SDL_mixer.h>
00061 #include <stdio.h>
00062 #include <stdlib.h>
00063 #include <sstream>
00064 #include <time.h>
00065 #include "Image/DrawOps.H"
00066 #include "GameBoard/resize.h"
00067 #include <iostream>
00068 #include <fstream>
00069 #include <set>
00070 #include <algorithm>
00071 #include <ctime>
00072
00073 #ifndef INVT_HAVE_LIBSDL_IMAGE
00074 #include <cstdio>
00075 int main()
00076 {
00077 fprintf(stderr, "The SDL_image library must be installed to use this program\n");
00078 return 1;
00079 }
00080
00081 #else
00082
00083
00084
00085 using namespace std;
00086
00087
00088
00089 ModelManager manager("Psycho-Serial-Recall");
00090 nub::soft_ref<PsychoDisplay> d(new PsychoDisplay(manager));
00091 map<uint,uint> testMap ;
00092 map<string,string> argMap ;
00093 map<string,vector<SDL_Rect*>*> clipsmap;
00094
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 double getAvarage(vector<long> v){
00108 double f = 0.0 ;
00109 for( uint i = 0 ; i < v.size() ; i++ ){
00110 f += v[i] ;
00111 }
00112 if (v.size()!=0) return f/v.size() ;
00113 return -1 ;
00114 }
00115
00116 double getVariance(vector<long> v){
00117 double m = getAvarage(v);
00118 double var = 0.0 ;
00119 for( uint i = 0 ; i < v.size(); i++ ){
00120 var += (v[i]-m)*(v[i]-m) ;
00121 }
00122 if (v.size()!=0) return var/v.size() ;
00123 return -1 ;
00124 }
00125
00126 bool itIsInThere(int x , vector<int> bag){
00127 for( uint i=0 ; i < bag.size(); i++ ){
00128 if(x == bag[i]) return true ;
00129 }
00130 return false ;
00131 }
00132
00133
00134
00135
00136
00137
00138 string ascSort(string st)
00139 {
00140 string res = "" ;
00141 vector<string> v = vector<string>();
00142 for(uint i = 0 ; i < st.size() ; i++) v.push_back(st.substr(i,1)) ;
00143
00144 std::sort(v.begin(), v.end());
00145
00146 for ( uint i = 0 ; i < v.size() ; i++ ){
00147 res += v[i] ;
00148 }
00149 return res;
00150 }
00151
00152
00153
00154
00155
00156
00157
00158 string desSort(string st)
00159 {
00160 string res = "" ;
00161 vector<string> v = vector<string>();
00162 for(uint i = 0 ; i < st.size() ; i++) v.push_back(st.substr(i,1)) ;
00163 std::sort(v.begin(), v.end());
00164 std::reverse(v.begin(), v.end());
00165 for ( uint i = 0 ; i < v.size() ; i++ ){
00166 res += v[i] ;
00167 }
00168 return res;
00169 }
00170
00171
00172
00173
00174
00175
00176 string getARandomString(uint l, string alphabet="0123456789" ){
00177
00178 string test = string("") ;
00179 string retString ;
00180 test = "" ;
00181 string tp = string("") ;
00182 vector<int> pickedones = vector<int>() ;
00183 for(uint i = 0 ; i < l ; i++){
00184 int nd;
00185 do{ nd= rand()% alphabet.size() ; }while(itIsInThere(nd,pickedones)) ;
00186 pickedones.push_back(nd);
00187 tp = alphabet.substr(nd,1) ;
00188 test += tp ;
00189 }
00190 retString = test ;
00191 return retString ;
00192 }
00193
00194
00195
00196
00197
00198 string digitMemorizationTask(uint l, string alphabet="0123456789" , int displayFrame = 10 ){
00199 d->clearScreen() ;
00200 vector<int> pickedones = vector<int>() ;
00201 string test = string("") ;
00202 string tp = string("") ;
00203 for(uint i = 0 ; i < l ; i++){
00204 int nd;
00205 do{ nd= rand()% alphabet.size() ; }while(itIsInThere(nd,pickedones) && pickedones.size() <= alphabet.size()) ;
00206 pickedones.push_back(nd);
00207 tp = alphabet.substr(nd,1) ;
00208 test += tp ;
00209 }
00210 d->displayText(test,true,0) ;
00211 d->waitFrames(displayFrame) ;
00212 d->clearScreen() ;
00213 return test ;
00214 }
00215
00216
00217
00218
00219
00220 void scramble(vector<string>& v){
00221 vector<string> tv = vector<string>() ;
00222 while(v.size()>0){
00223 tv.push_back(v[0]);
00224 v.erase(v.begin());
00225 }
00226 int i = 0 ;
00227 while(tv.size()>0){
00228 i = rand()%tv.size() ;
00229 v.push_back(tv[i]);
00230 tv.erase(tv.begin()+i);
00231 }
00232 }
00233
00234 void scramble(vector<int>& v){
00235 vector<int> tv = vector<int>() ;
00236 while(v.size()>0){
00237 tv.push_back(v[0]);
00238 v.erase(v.begin());
00239 }
00240 int i = 0 ;
00241 while(tv.size()>0){
00242 i = rand()%tv.size() ;
00243 v.push_back(tv[i]);
00244 tv.erase(tv.begin()+i);
00245 }
00246 }
00247
00248
00249
00250
00251 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){
00252 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00253 textIm.clear(bgcolor);
00254 writeText(textIm, Point2D<int>((size.i - label.length()*10)/2,(size.j-20) /2),label.c_str(),txtcolor,bgcolor);
00255 SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00256 Uint32 bc = d->getUint32color(bordercolor);
00257 drawRectangle(surf,bc,0,0,size.i -1,size.j -1 ,border);
00258 SDL_Surface* blank =getABlankSurface(size.i , size.j);
00259 SDL_Rect clip;
00260 clip.x = 0 ;
00261 clip.y = 0 ;
00262 clip.w = size.i ;
00263 clip.h = size.j ;
00264 apply_surface(0,0,*surf,*blank,clip);
00265 dumpSurface(surf) ;
00266 return blank ;
00267 }
00268
00269
00270
00271
00272
00273
00274 SDL_Surface* getKeyPad(string alphabet,map<string , SDL_Rect>& buttmap){
00275 SDL_Surface* pad= getABlankSurface(d->getWidth()/4,d->getHeight()/3);
00276 SDL_Rect clip;
00277 clip.x=0;
00278 clip.y=0;
00279 int numofrows = alphabet.size()/3 +1;
00280 if(alphabet.size()%3 != 0 ) numofrows++ ;
00281 int numofcolumns = 3 ;
00282 clip.w= pad->w / numofcolumns ;
00283 clip.h = pad->h / numofrows ;
00284
00285
00286 for( int i = 0 ; i < numofrows*3 ; i++){
00287 SDL_Surface* but ;
00288 if((uint)i < alphabet.size()){
00289 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);
00290 }else{
00291 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);
00292 }
00293
00294 SDL_Rect cl ;
00295 cl.x = ((i)%numofcolumns)*(pad->w)/numofcolumns ; cl.y= ((i)/numofcolumns)*((pad->h)/numofrows) ;
00296 cl.w = clip.w ;
00297 cl.h = clip.h ;
00298 apply_surface( cl.x , cl.y ,*but,*pad,clip);
00299 if((uint)i < alphabet.size()) buttmap[alphabet.substr(i,1)] = cl ;
00300 dumpSurface(but);
00301 }
00302 SDL_Rect cl1 ;
00303 cl1.x = 0 ; cl1.y= (numofrows-1)*((pad->h)/numofrows) ;
00304 cl1.w = clip.w ;
00305 cl1.h = clip.h ;
00306 buttmap["!"] = cl1 ;
00307 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);
00308 apply_surface(0, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00309 dumpSurface(but);
00310 SDL_Rect cl2 ;
00311 cl2.x = (pad->w)/numofcolumns ; cl2.y= (numofrows-1)*((pad->h)/numofrows) ;
00312 cl2.w = clip.w ;
00313 cl2.h = clip.h ;
00314 buttmap[" "] = cl2 ;
00315 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);
00316 apply_surface((pad->w)/numofcolumns, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00317 dumpSurface(but);
00318 SDL_Rect cl3 ;
00319 cl3.x = 2*(pad->w)/numofcolumns ; cl3.y= (numofrows-1)*((pad->h)/numofrows) ;
00320 cl3.w = clip.w ;
00321 cl3.h = clip.h ;
00322 buttmap["*"] = cl3 ;
00323 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);
00324 apply_surface(2*(pad->w)/numofcolumns, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00325 dumpSurface(but);
00326 return pad ;
00327 }
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 string getPressedButtonCommand(map<string , SDL_Rect>& buttmap,Point2D<int> offset=Point2D<int>(0,0)){
00338 int quit = 0 ;
00339 string s ;
00340 SDL_Event event ;
00341 while( quit!=2 ){
00342 while( SDL_PollEvent( &event ) ) {
00343 if(event.type == SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_LEFT ){
00344 for( map<string , SDL_Rect>::iterator it = buttmap.begin() ; it!=buttmap.end() ; ++it){
00345 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) {
00346 quit = 2 ;
00347 s = it->first ;
00348 break;
00349 }
00350
00351 }
00352 }
00353
00354 }
00355 }
00356 return s ;
00357
00358 }
00359
00360
00361
00362
00363
00364
00365
00366 string getDigitSequenceFromSubject(string alphabet="0123456789" , uint maxl = 7 , string message=""){
00367 d->showCursor(true) ;
00368
00369 map<string , SDL_Rect>* buttmap = new map<string , SDL_Rect>();
00370
00371 SDL_Surface * keypad = getKeyPad(alphabet,*buttmap);
00372
00373 SDL_Rect offset ;
00374 offset.x = (d->getWidth() - keypad->w) /2;
00375 offset.y = (d-> getHeight() - keypad->h) /2;
00376
00377 SDL_Surface* msgp = getButtonImage(message ,PixRGB<byte>(195,60,12) ,PixRGB<byte>(127,127,127) ,Point2D<int>(d->getWidth()/6,d->getHeight() /15) ,PixRGB<byte>(127,127,127) , 4) ;
00378 SDL_Rect msgoffs ; msgoffs.x = (d->getWidth() - msgp->w) /2 ; msgoffs.y = 2*d->getHeight()/9 ;
00379 d->displaySDLSurfacePatch(msgp , &msgoffs , NULL , -2 , false ,true ) ;
00380 dumpSurface(msgp) ;
00381
00382 d->displaySDLSurfacePatch(keypad , &offset,NULL , -2,false, true);
00383
00384 string p = string("") ;
00385
00386 string tp = string("");
00387
00388 while( tp.compare("*")!=0 ){
00389
00390 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) ;
00391 SDL_Rect offs ; offs.x = (d->getWidth() - dp->w) /2 ; offs.y = d->getHeight()/6 ;
00392 d->displaySDLSurfacePatch(dp , &offs , NULL , -2 , false ,true ) ;
00393
00394 tp = getPressedButtonCommand(*buttmap,Point2D<int>(offset.x,offset.y)) ;
00395 dumpSurface(dp) ;
00396 if(tp.compare("!")==0 && p.size()>=0 ) {
00397 if (p.size()>0) p = p.substr(0,p.size()-1) ;
00398 }else{
00399 if(p.size() < maxl && tp.compare("*")!=0) {
00400 p +=tp ;
00401 }
00402
00403 }
00404
00405 }
00406
00407 buttmap = 0 ;
00408 dumpSurface(keypad) ;
00409 d->clearScreen() ;
00410 return p ;
00411
00412 }
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424 bool isAnswerCorrect(string test , string answer , int mode){
00425
00426 if(mode == 0 && answer.compare(test)==0) return true ;
00427
00428 if(mode == 1 && answer.compare(ascSort(test))==0) return true ;
00429
00430 if(mode == 2 && answer.compare(desSort(test))==0) return true ;
00431
00432 return false;
00433 }
00434
00435
00436
00437 int addArgument(const string st,const string delim="="){
00438 int i = st.find(delim) ;
00439 argMap[st.substr(0,i)] = st.substr(i+1);
00440
00441 return 0 ;
00442 }
00443
00444 std::string getArgumentValue(string arg){
00445 return argMap[arg] ;
00446 }
00447
00448
00449 void displayWholeNumber(string s , int onsetTime , int wsd){
00450 int x = (d->getWidth()-s.size()*wsd)/2 ;
00451 int y = (d->getHeight())/2 -10;
00452 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00453 textIm.clear(PixRGB<byte>(128,128,128));
00454 for( uint k = 0 ; k < s.size() ; k++ ){
00455
00456 writeText(textIm, Point2D<int>(x+k*wsd,y),s.substr(k,1).c_str(),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128));
00457 }
00458 SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00459 SDL_Rect offs ; offs.x = 0 ; offs.y = 0 ;
00460 d->displaySDLSurfacePatch(surf , &offs , NULL , -2 , false ,true ) ;
00461 dumpSurface(surf);
00462 d->waitFrames(onsetTime);
00463 d->clearScreen() ;
00464 }
00465
00466 void displayWholeNumberVertically(string s , int onsetTime , int wsd){
00467 int x = (d->getWidth())/2 ;
00468 int y = (d->getHeight()-s.size()*wsd)/2 ;
00469 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00470 textIm.clear(PixRGB<byte>(128,128,128));
00471 for( uint k = 0 ; k < s.size() ; k++ ){
00472
00473 writeText(textIm, Point2D<int>(x,y+k*wsd),s.substr(k,1).c_str(),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128));
00474 }
00475 SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00476 SDL_Rect offs ; offs.x = 0 ; offs.y = 0 ;
00477 d->displaySDLSurfacePatch(surf , &offs , NULL , -2 , false ,true ) ;
00478 dumpSurface(surf);
00479 d->waitFrames(onsetTime);
00480 d->clearScreen() ;
00481 }
00482
00483 void showBoxesHorizontally(uint numofboxes , int wsd , string ds){
00484
00485 int x = (d->getWidth()-numofboxes*wsd)/2 ;
00486 int y = (d->getHeight())/2 -10;
00487 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00488 textIm.clear(PixRGB<byte>(128,128,128));
00489 for( uint k = 0 ; k < numofboxes ; k++ ){
00490
00491 writeText(textIm, Point2D<int>(x+k*wsd,y),ds.c_str(),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128));
00492 }
00493 SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00494 SDL_Rect offs ; offs.x = 0 ; offs.y = 0 ;
00495 d->displaySDLSurfacePatch(surf , &offs , NULL , -2 , false ,true ) ;
00496 dumpSurface(surf);
00497 }
00498
00499 void showBoxesVertically(uint numofboxes , int wsd, string ds ){
00500
00501 int x = (d->getWidth()-numofboxes*wsd)/2 ;
00502 int y = (d->getHeight())/2 -10;
00503 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00504 textIm.clear(PixRGB<byte>(128,128,128));
00505 for( uint k = 0 ; k < numofboxes ; k++ ){
00506
00507 writeText(textIm, Point2D<int>(x,y+k*wsd),ds.c_str(),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128));
00508 }
00509 SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00510 SDL_Rect offs ; offs.x = 0 ; offs.y = 0 ;
00511 d->displaySDLSurfacePatch(surf , &offs , NULL , -2 , false ,true ) ;
00512 dumpSurface(surf);
00513 }
00514
00515 void flashDisplayHorizontally(string box, string s , int l , int onsetTime , int wsd , uint p){
00516 string tmpstr="";
00517 for (int i = 0 ; i < l ; i++) tmpstr += box;
00518 tmpstr.replace(p,1,s);
00519 int x = (d->getWidth()-s.size()*wsd)/2 ;
00520 int y = (d->getHeight())/2 -10;
00521 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00522 textIm.clear(PixRGB<byte>(128,128,128));
00523 for( uint k = 0 ; k < tmpstr.size() ; k++ ){
00524 writeText(textIm, Point2D<int>(x+k*wsd,y),tmpstr.substr(k,1).c_str(),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128));
00525 }
00526 SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00527 SDL_Rect offs ; offs.x = 0 ; offs.y = 0 ;
00528 d->displaySDLSurfacePatch(surf , &offs , NULL , -2 , false ,true ) ;
00529 dumpSurface(surf);
00530 d->waitFrames(onsetTime);
00531 d->clearScreen() ;
00532 }
00533
00534
00535
00536 void flashDisplayVertically(string box, string s , int l , int onsetTime , int wsd , uint p){
00537 string tmpstr="";
00538 for (int i = 0 ; i < l ; i++) tmpstr += box;
00539 tmpstr.replace(p,1,s);
00540 int x = (d->getWidth()-s.size()*wsd)/2 ;
00541 int y = (d->getHeight())/2 -10;
00542 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00543 textIm.clear(PixRGB<byte>(128,128,128));
00544 for( uint k = 0 ; k < tmpstr.size() ; k++ ){
00545 writeText(textIm, Point2D<int>(x,y+k*wsd),tmpstr.substr(k,1).c_str(),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128));
00546 }
00547 SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00548 SDL_Rect offs ; offs.x = 0 ; offs.y = 0 ;
00549 d->displaySDLSurfacePatch(surf , &offs , NULL , -2 , false ,true ) ;
00550 dumpSurface(surf);
00551 d->waitFrames(onsetTime);
00552 d->clearScreen() ;
00553 }
00554
00555 void displayRandom(string s , int onsetTime){
00556 for( uint k = 0 ; k < s.size() ; k++ ){
00557 int x = 9*d->getWidth()/20 + rand()%(d->getWidth()/10);
00558 int y = 9*d->getHeight()/20 + rand()%(d->getHeight()/10) ;
00559 d->displayText(s.substr(k,1),Point2D<int>(x,y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ;
00560 d->waitFrames(onsetTime);
00561 d->clearScreen() ;
00562 }
00563 }
00564
00565 void displayLinear(string s , int onsetTime){
00566 int x = (d->getWidth()-s.size()*10)/2 ;
00567 int y = d->getHeight()/2 - 10;
00568 for( uint k = 0 ; k < s.size() ; k++ ){
00569 d->displayText(s.substr(k,1),Point2D<int>(x+k*10,y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ;
00570 d->waitFrames(onsetTime);
00571 d->clearScreen() ;
00572 }
00573 }
00574
00575 void displayLinearReverse(string s , int onsetTime){
00576 int x = (d->getWidth()-s.size()*10)/2 ;
00577 int y = d->getHeight()/2 - 10;
00578 for( uint k = 0 ; k < s.size() ; k++ ){
00579 d->displayText(s.substr(k,1),Point2D<int>(x+(s.size()-k)*10,y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ;
00580 d->waitFrames(onsetTime);
00581 d->clearScreen() ;
00582 }
00583 }
00584 void displayLinearRandom(string s , int onsetTime){
00585 int x = (d->getWidth()-s.size()*10)/2 ;
00586 int y = d->getHeight()/2 - 10;
00587 for( uint k = 0 ; k < s.size() ; k++ ){
00588 d->displayText(s.substr(k,1),Point2D<int>(x+ (random()%s.size())*10,y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ;
00589 d->waitFrames(onsetTime);
00590 d->clearScreen() ;
00591 }
00592 }
00593
00594 void displayLinearRandomVertically(string s , int onsetTime){
00595 int x = (d->getWidth())/2 ;
00596 int y = (d->getHeight()-s.size()*10)/2 - 10;
00597 for( uint k = 0 ; k < s.size() ; k++ ){
00598 d->displayText(s.substr(k,1),Point2D<int>(x, (random()%s.size())*10+y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ;
00599 d->waitFrames(onsetTime);
00600 d->clearScreen() ;
00601 }
00602 }
00603
00604 void displayLinearRandomNoRepeating(string s , int onsetTime){
00605 int x = (d->getWidth()-s.size()*10)/2 ;
00606 int y = d->getHeight()/2 - 10;
00607 for( uint k = 0 ; k < s.size() ; k++ ){
00608 d->displayText(s.substr(k,1),Point2D<int>(x+ (random()%s.size())*10,y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ;
00609 d->waitFrames(onsetTime);
00610 d->clearScreen() ;
00611 }
00612 }
00613
00614
00615 void showMask(int frames, string alphabet="0123456789"){
00616 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00617 PixRGB<byte> bgcolor = PixRGB<byte>(128,128,128);
00618 PixRGB<byte> txtcolor = PixRGB<byte>(0,0,0);
00619 textIm.clear(bgcolor);
00620 for(int i = 0 ; i < 200 ; i++)
00621 writeText(textIm, Point2D<int>((int)random()%(d->getWidth()),(int)random()%(d->getHeight())),alphabet.substr(random()%(int)alphabet.size(),1).c_str(),txtcolor,bgcolor);
00622 SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00623 SDL_Rect offs ; offs.x = 0 ; offs.y = 0 ;
00624 d->displaySDLSurfacePatch(surf , &offs , NULL , -2 , false ,true ) ;
00625 d->waitFrames(frames) ;
00626 d->clearScreen();
00627 dumpSurface(surf) ;
00628 }
00629
00630 vector<int> spatial_memory_task(int onsetTime, int isd , int dir , int ma=30 ,int Ma=120){
00631
00632 int w = d->getWidth();
00633 int h = d->getHeight();
00634 int neg = rand()%(Ma-ma) +ma ;
00635 int pos = rand()%(Ma-ma) +ma ;
00636
00637 if(dir==0) {
00638 d->displayRedDotFixation(w/2+pos,h/2);
00639 d->waitFrames(onsetTime);
00640 d->clearScreen();
00641 d->waitFrames(isd);
00642 d->displayRedDotFixation(w/2-neg,h/2);
00643 d->waitFrames(onsetTime);
00644 d->clearScreen();
00645 }
00646 if(dir==1) {
00647 d->displayRedDotFixation(w/2,h/2+pos);
00648 d->waitFrames(onsetTime);
00649 d->clearScreen();
00650 d->waitFrames(isd);
00651 d->displayRedDotFixation(w/2,h/2-neg);
00652 d->waitFrames(onsetTime);
00653 d->clearScreen();
00654 }
00655 vector<int> locations;
00656 locations.push_back(neg);
00657 locations.push_back(pos);
00658 return locations ;
00659 }
00660
00661 int spatial_memory_retrival(vector<int> dotsVector,int dir ,float cr = 0.5 ){
00662
00663 int w = d->getWidth();
00664 int h = d->getHeight();
00665 int change = rand()%2;
00666 int neg = dotsVector.at(0); int pos = dotsVector.at(1);
00667 switch( change ){
00668 case 0 : d->pushEvent("same target");break;
00669 case 1 : d->pushEvent("target changed");break;
00670 }
00671 if(change == 1){
00672 int chDir = rand()%2;
00673 int c=0;
00674 switch(chDir){
00675 case 0: c =((rand()%2 -0.5)/0.5 ); neg = neg + c* cr*neg ; break ;
00676 case 1: c =((rand()%2 -0.5)/0.5 ); pos = pos + c* cr*pos ; break ;
00677 }
00678 }
00679
00680 d->pushEvent("for retrieval dots showed at negative side :"+ stringify(neg)+" positive side:" + stringify(pos));
00681 if(dir == 0){
00682 d->displayRedDotFixation(w/2+pos,h/2);
00683 d->displayRedDotFixation(w/2-neg,h/2);
00684 }
00685 if(dir == 1){
00686 d->displayRedDotFixation(w/2,h/2+pos);
00687 d->displayRedDotFixation(w/2,h/2-neg);
00688 }
00689 d->waitFrames(30);
00690 d->clearScreen();
00691 string ans = getDigitSequenceFromSubject("yn-",1);
00692 int res = 0 ;
00693 if(change==0 && ans.compare("y")==0) res=1;
00694 if(change==1 && ans.compare("n")==0) res=1;
00695 return res ;
00696 }
00697
00698 vector<int> executive_memory_task(Mix_Music* tone1 , Mix_Music* tone2 ,string initial_string,int counter_length, int min_tone_wait, int max_tone_wait ){
00699 int t1c = 0 ;
00700 int t2c = 0 ;
00701 vector<int> wFrames;
00702 vector<int> toneSequence ;
00703 vector<int> retVector ;
00704 map<int,string> strMap;
00705
00706 int flag=0;
00707 float milisum=0;
00708 do{
00709 int rtmp = rand()%(max_tone_wait - min_tone_wait) + min_tone_wait;
00710 milisum += rtmp*33.33 + 240;
00711 if(milisum > counter_length*33.33) {
00712 milisum = milisum -rtmp*33.33 - 240;
00713 flag=1;
00714 }else{
00715 wFrames.push_back(rtmp);
00716 toneSequence.push_back(rand()%2);
00717 }
00718 }while(flag==0);
00719 int lagFrames = (int)((counter_length - milisum)/33.33);
00720
00721 for(uint i = 0 ; i < wFrames.size() ; i++){
00722 d->pushEvent("will wait for "+stringify(wFrames[i]));
00723 d->waitFrames(wFrames[i]);
00724 if(toneSequence[i]==0){
00725 d->pushEvent("tone1 playing");
00726 t1c++;
00727 if(Mix_PlayMusic(tone1,0)==-1){return retVector;}
00728 while(Mix_PlayingMusic()==1){} ;
00729 }else{
00730 d->pushEvent("tone2 playing");
00731 t2c++ ;
00732 if(Mix_PlayMusic(tone2,0)==-1){return retVector;}
00733 while(Mix_PlayingMusic()==1){} ;
00734 }
00735 }
00736 d->waitFrames(lagFrames);
00737 retVector.push_back(t1c);
00738 retVector.push_back(t2c);
00739 d->clearScreen();
00740 d->displayFixation();
00741 return retVector ;
00742
00743 }
00744
00745
00746
00747 std::string getUsageComment(){
00748
00749 string com = string("\nlist of arguments : \n");
00750
00751 com += "\nlogfile=[logfilename.psy] {default = psycho-sm-or.psy}\n" ;
00752 com += "\nmemo=[a_string_without_white_space]\n";
00753 com += "\nstring-size=[>0](the size of counter string){default=4} \n";
00754 com += "\nsubject=[subject_name] \n" ;
00755 com += "\nnum-of-trials=[>1] (number of trials ) {default=10}\n";
00756 com += "\nalphabet=[a string of characters](a string of characters){default=abcdefghijklmnopqrstuvwxyz}\n";
00757 com += "\nmode=[1,2](1 horizontal stimulus presentation 2 for vertical){default=1}\n";
00758 com += "\nsingle-dot-onset=[>1](number of frames that the single dot should be presented){default=16}\n";
00759 com += "\ndots_ISI=[>1](number of frames between dots presentations){default=16}\n";
00760 com += "\ndots_radius=[>1](the radius for circle of dots in pixel){default=100}\n";
00761 com += "\ndots_min_angle=[>0](minimum angle between dots on the circle){default=45}\n";
00762 com += "\ndots_max_angle=[>0] (maximum angle between dots on the circle){default=90}\n";
00763 com += "\nspatial-delay=[>0](number of frames for spatial memory task ){default=180}\n";
00764 com += "\n spatial-counter-ISI=[>1](numer of frames between last dot presentation and start of counter task){default=16}\n";
00765 com += "\n counter-length=[>1](total lenght of counter experiment in frames){default=300}\n";
00766 com += "\n counter-spatial-query-ISI=[>1](the delay between end of counter trail and start of spatial memory query in number of frames){default=16}\n";
00767 com += "\n spatial-query-length=[>1](the total length for showing the spatial memory test in number of frames){default=60}\n";
00768 com += "\n spatial-query-counter-query-ISI=[>1](number of frames between the unspeeded spatial memory query and showing the counter query){default=30}\n";
00769 com += "\n counter-query-length=[>1](number of frames for presenting the counter query){default=60}\n";
00770 com += "\n cue-onset-frames=[>1](){default=3}\n";;
00771 com += "\nsound-dir=[path to wav files directory]{default=..}\n";
00772 com += "\ntone1=[a valid file name](name of wav file without extension for tone 1){default=sin}\n";
00773 com += "\ntone2=[a valid file name](name of wav file without extension for tone 2){default=square}\n";
00774 com += "\ncue-file=[a valid file name](name of a wav file without extension for the audio cue){default=cue1}\n";
00775 com += "\nmin-tone-wait=[>1](minimum number of frames waiting on each tone){default=60}\n";
00776 com += "\nmax-tone-wait=[>1](maximum number of frames waiting on each tone){default=90}\n";
00777 com += "\ndot-shift=[>1](amount of shift in dots position in pixel)[default=16]\n";
00778 return com ;
00779 }
00780
00781 extern "C" int main(const int argc, char** argv)
00782 {
00783
00784 MYLOGVERB = LOG_INFO;
00785
00786 argMap["experiment"]="twsr";
00787 argMap["logfile"]="psycho-twsr.psy" ;
00788 argMap["string-size"]="6" ;
00789 argMap["num-of-trials"]="10";
00790 argMap["subject"]="" ;
00791 argMap["memo"]="" ;
00792 argMap["alphabet"]="bfgkms";
00793 argMap["mode"]="1" ;
00794 argMap["sound-dir"]="..";
00795 argMap["tone1"]="sine";
00796 argMap["tone2"]="square";
00797 argMap["white-space"]="30";
00798 argMap["box-sign"]=".";
00799 argMap["stimulus-onset-frames"]="20";
00800
00801
00802
00803
00804 manager.addSubComponent(d);
00805 nub::soft_ref<EventLog> el(new EventLog(manager));
00806 manager.addSubComponent(el);
00807 d->setEventLog(el);
00808
00809
00810
00811
00812 if (manager.parseCommandLine(argc, argv,
00813 "at least one argument needed", 1, -1)==false){
00814 cout<<getUsageComment()<<endl;
00815 return(1);
00816 }
00817
00818 for(uint i = 0 ; i < manager.numExtraArgs() ; i++){
00819 addArgument(manager.getExtraArg(i),std::string("=")) ;
00820 }
00821
00822 manager.setOptionValString(&OPT_EventLogFileName, argMap["logfile"]);
00823
00824
00825
00826
00827
00828
00829
00830 manager.start();
00831 for(map<string,string>::iterator it= argMap.begin(); it!= argMap.end() ; ++it) d->pushEvent("arg:"+ it->first+" value:"+it->second ) ;
00832
00833 d->clearScreen();
00834 d->displayISCANcalib();
00835 d->waitForMouseClick();
00836 d->displayText("Here the experiment starts! click to start!");
00837 d->waitForMouseClick();
00838 d->clearScreen();
00839
00840
00841 string masterString=argMap["alphabet"];
00842
00843
00844 int numOfTests = atoi(argMap["num-of-trials"].c_str()) ;
00845 int stringSize = atoi(argMap["string-size"].c_str());
00846 int dots_ISI = atoi(argMap["dots-ISI"].c_str()) ;
00847 int dot_onset = atoi(argMap["single-dot-onset"].c_str());
00848 int dots_min_radius = atoi(argMap["dots_min_radius"].c_str());
00849 int dots_max_radius = atoi(argMap["dots_max_radius"].c_str());
00850 int mode = atoi(argMap["mode"].c_str());
00851 int counter_length = atoi(argMap["counter-length"].c_str());
00852 int min_tone_wait = atoi(argMap["min-tone-wait"].c_str());
00853 int max_tone_wait = atoi(argMap["max-tone-wait"].c_str());
00854 float dot_max_change = atof(argMap["dot-shift"].c_str());
00855 vector<int> orVector;
00856 for( int i = 0 ; i< numOfTests/2 ; i++ ){
00857 orVector.push_back(0);
00858 }
00859 for( int i =numOfTests/2; i<numOfTests ; i++){
00860 orVector.push_back(1);
00861 }
00862 scramble(orVector);
00863
00864
00865
00866 d->clearScreen();
00867
00868 cout<< stringify(d->getWidth())<<" x "<<stringify(d->getHeight())<<endl;
00869 Mix_Music* cueMusic = NULL;
00870 Mix_Music* tone1 = NULL;
00871 Mix_Music* tone2 = NULL;
00872 map<int,Mix_Music*> audio_map ;
00873 map<string,int> charmap ;
00874 map<int,string> charinvmap ;
00875
00876 if( Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 4096 ) == -1 ){
00877 LINFO( "did not open the mix-audio") ;
00878 return -1 ;
00879 }
00880
00881 for(uint i = 0; i < masterString.size() ; i++){
00882 string str = argMap["sound-dir"]+"/"+masterString.substr(i,1)+".wav";
00883 audio_map[i]=Mix_LoadMUS(str.c_str());
00884 charmap[masterString.substr(i,1)]=i;
00885 charinvmap[i]=masterString.substr(i,1) ;
00886 }
00887
00888 for( uint i=10;i<100 ;i++ ){
00889 charmap[stringify(i)]=i;
00890 charinvmap[i]=stringify(i);
00891 }
00892
00893 if(argMap["cue-type"].compare("a")==0){
00894 string str = argMap["sound-dir"]+"/"+argMap["cue-file"]+".wav" ;
00895 cueMusic = Mix_LoadMUS(str.c_str());
00896 }
00897
00898 string tmpstr = argMap["sound-dir"]+"/"+argMap["tone1"]+".wav";
00899 tone1 = Mix_LoadMUS(tmpstr.c_str());
00900 tmpstr = argMap["sound-dir"]+"/"+argMap["tone2"]+".wav";
00901 tone2 = Mix_LoadMUS(tmpstr.c_str());
00902
00903 int cr = numOfTests ;
00904 d->showCursor(true);
00905 d->displayText("click one of the mouse buttons to start!");
00906 d->waitForMouseClick() ;
00907 d->showCursor(false);
00908
00909 int correctHSpatialMemory=0;
00910 int correctVSpatialMemory=0;
00911 int incorrectHSpatialMemory=0;
00912 int incorrectVSpatialMemory=0;
00913 int correctCounting=0;
00914 int incorrectCounting=0;
00915 int missCounting=0;
00916 cr=0;
00917 while( cr < numOfTests ){
00918 string inStr = getARandomString(stringSize,"34567");
00919 d->showCursor(false);
00920 d->clearScreen() ;
00921 d->pushEvent("**************************************") ;
00922 d->pushEvent("initial string :" + inStr);
00923 for(uint i = 0 ; i < inStr.size(); i++){
00924 d->pushEvent("playing character "+inStr.substr(i,1));
00925 if(Mix_PlayMusic(audio_map[charmap[inStr.substr(i,1)]],0)==-1){return 1;}
00926 while(Mix_PlayingMusic()==1){} ;
00927 d->pushEvent("ended playing character "+inStr.substr(i,1));
00928 }
00929 d->waitFrames(60);
00930 d->displayFixation();
00931 d->waitFrames(10);
00932 d->clearScreen() ;
00933 d->pushEvent("presentation orientation: " + stringify(orVector.at(cr)));
00934 vector<int> dotsVector = spatial_memory_task(dot_onset,dots_ISI,orVector.at(cr),dots_min_radius,dots_max_radius);
00935 d->pushEvent("dots showed at negative:"+ stringify(dotsVector.at(0))+" positive:" + stringify(dotsVector.at(1)));
00936 d->waitFrames(10);
00937 d->displayFixation();
00938 vector<int> tonesVector = executive_memory_task( tone1 , tone2 , inStr, counter_length, min_tone_wait, max_tone_wait );
00939 string newStr ;
00940 if (stringSize == 2)
00941 newStr = charinvmap[charmap[inStr.substr(0,1)]+tonesVector.at(0)]+charinvmap[charmap[inStr.substr(inStr.size()-1,1)]+tonesVector.at(1)];
00942 if (stringSize>2)
00943 newStr = charinvmap[charmap[inStr.substr(0,1)]+tonesVector.at(0)]+inStr.substr(1,inStr.size()-2)+charinvmap[charmap[inStr.substr(inStr.size()-1,1)]+tonesVector.at(1)];
00944 if(mode==1 || mode==3){
00945 int spMemAns = spatial_memory_retrival(dotsVector,orVector.at(cr),dot_max_change);
00946 if(orVector.at(cr)==0){
00947 if (spMemAns ==1){
00948 d->pushEvent("correct horizontal spatial memory recall");
00949 correctHSpatialMemory++;
00950 }else{
00951 d->pushEvent("incorrect horizontal spatial memory recall");
00952 incorrectHSpatialMemory++;
00953 }
00954 }else{
00955 if (spMemAns ==1){
00956 d->pushEvent("correct horizontal spatial memory recall");
00957 correctVSpatialMemory++;
00958 }else{
00959 d->pushEvent("incorrect horizontal spatial memory recall");
00960 incorrectVSpatialMemory++;
00961 }
00962
00963 }
00964 }
00965
00966
00967 if(mode ==1){
00968
00969 string ans1 = getDigitSequenceFromSubject(masterString,1,"first digit");
00970 d->pushEvent("subject keyed:" + ans1 + " for first digit");
00971 string ans2 = getDigitSequenceFromSubject(masterString,1,"second digit");
00972 d->pushEvent("subject keyed:" + ans2 + " for second digit");
00973
00974 if(ans1.compare(inStr.substr(0,1))==0 && ans2.compare(inStr.substr(inStr.size()-1,1))==0 ) {
00975 correctCounting++;
00976 }else{
00977 incorrectCounting++ ;
00978 }
00979
00980 }
00981
00982 if(mode ==2 || mode==3){
00983 int sineCounter = tonesVector.at(0)+atoi(inStr.substr(0,1).c_str());
00984 int squareCounter = tonesVector.at(1)+atoi(inStr.substr(inStr.size()-1,1).c_str());
00985 d->pushEvent("sine signal counter is :"+stringify(sineCounter));
00986 d->pushEvent("square signal counter is :"+stringify(squareCounter));
00987 string ans1 = getDigitSequenceFromSubject(masterString,2,"soft tone counter");
00988 d->pushEvent("subject keyed:" + ans1 + " for sine counter");
00989 string ans2 = getDigitSequenceFromSubject(masterString,2,"rough tone counter");
00990 d->pushEvent("subject keyed:" + ans2 + " for square counter");
00991 d->pushEvent("trial misscounting: " + stringify(abs(atoi(ans1.c_str()) - sineCounter) + abs(atoi(ans2.c_str()) - squareCounter)));
00992 missCounting += abs(atoi(ans1.c_str()) - sineCounter) + abs(atoi(ans2.c_str()) - squareCounter);
00993
00994 }
00995 cr++;
00996 }
00997 d->pushEvent("correct horizontal spatial memory: " +stringify(correctHSpatialMemory));
00998 d->pushEvent("incorrect horizontal spatial memory: " +stringify(incorrectHSpatialMemory));
00999
01000 d->pushEvent("correct vertical spatial memory: " +stringify(correctVSpatialMemory));
01001 d->pushEvent("incorrect vertical spatial memory: " +stringify(incorrectVSpatialMemory));
01002 d->pushEvent("correct counting: " +stringify(correctCounting));
01003 d->pushEvent("incorrect counting: " +stringify(incorrectCounting));
01004 d->pushEvent("total misscounting: "+stringify(missCounting));
01005 d->displayText("Experiment complete. Thank you!");
01006 d->waitForMouseClick();
01007
01008
01009 manager.stop();
01010
01011
01012
01013 return 0;
01014 }
01015
01016 #endif // INVT_HAVE_LIBSDL_IMAGE
01017