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 #ifndef INVT_HAVE_LIBSDL_IMAGE
00039
00040 #include <cstdio>
00041 int main()
00042 {
00043 fprintf(stderr, "The SDL_image library must be installed to use this program\n");
00044 return 1;
00045 }
00046
00047 #else
00048
00049
00050
00051
00052
00053
00054 #include "Component/ModelManager.H"
00055 #include "Image/Image.H"
00056 #include "Psycho/PsychoDisplay.H"
00057 #include "Psycho/EyeTrackerConfigurator.H"
00058 #include "Psycho/EyeTracker.H"
00059 #include "Psycho/PsychoOpts.H"
00060 #include "Component/EventLog.H"
00061 #include "Component/ComponentOpts.H"
00062 #include "Raster/Raster.H"
00063 #include "Util/MathFunctions.H"
00064 #include "Util/Types.H"
00065 #include <iostream>
00066 #include <fstream>
00067 #include <SDL/SDL.h>
00068 #include <SDL/SDL_image.h>
00069 #include "psycho-skin-resize.h"
00070 #include <stdio.h>
00071 #include <stdlib.h>
00072 #include <map>
00073 #include <time.h>
00074
00075
00076 using namespace std;
00077
00078
00079
00080 const int SCREEN_WIDTH = 840;
00081 const int SCREEN_HEIGHT = 680;
00082 const int SCREEN_BPP = 32;
00083 const int NUMBER_OF_CLASSES = 6;
00084 const int MAX_CELLS = 400 ;
00085 const int IMAGE_WIDTH = 128 ;
00086 const string classes[NUMBER_OF_CLASSES]={"class1","class2","class3","class4","class5","class6"};
00087 SDL_Event event ;
00088 int delay = 15 ;
00089 bool programQuit = false ;
00090 map<string,map<string,SDL_Surface*> > skinsmap ;
00091 ModelManager manager("Psycho Skin Indexing");
00092 nub::soft_ref<PsychoDisplay> d(new PsychoDisplay(manager));
00093
00094
00095
00096 SDL_Surface *load_image( string filename )
00097 {
00098
00099 SDL_Surface* loadedImage = NULL;
00100
00101
00102 SDL_Surface* optimizedImage = NULL;
00103
00104
00105 loadedImage = IMG_Load( filename.c_str() );
00106
00107
00108 if( loadedImage != NULL )
00109 {
00110
00111 optimizedImage = SDL_DisplayFormat( loadedImage );
00112
00113
00114 SDL_FreeSurface( loadedImage );
00115
00116
00117 if( optimizedImage != NULL )
00118 {
00119
00120 Uint32 colorkey = SDL_MapRGB( optimizedImage->format, 0, 0xFF, 0xFF );
00121
00122
00123 SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, colorkey );
00124 }
00125 }else{cout<<filename;}
00126
00127
00128 return optimizedImage;
00129 }
00130
00131
00132 SDL_Surface *getAFreshSurface(int w , int h){
00133
00134 SDL_Surface *sur = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32,
00135 0x00000000, 0x00000000, 0x00000000, 0x00000000);
00136
00137 return sur ;
00138
00139 }
00140
00141
00142
00143
00144 void dumpSurface(SDL_Surface * surface){
00145
00146 SDL_FreeSurface( surface );
00147 }
00148
00149
00150
00151 void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination , SDL_Rect* clip = NULL)
00152 {
00153
00154 SDL_Rect offset;
00155
00156
00157 offset.x = x;
00158 offset.y = y;
00159
00160
00161 SDL_BlitSurface( source, clip, destination, &offset );
00162 }
00163
00164
00165 void clean_up()
00166 {
00167
00168 for( map<string,map<string,SDL_Surface*> >::iterator ii=skinsmap.begin(); ii!=skinsmap.end(); ++ii)
00169 {
00170 for(map<string,SDL_Surface*>::iterator jj=((*ii).second).begin() ; jj!= ((*ii).second).end() ; ++jj){
00171 SDL_FreeSurface(jj->second);
00172 }
00173
00174 }
00175
00176 SDL_Quit();
00177 }
00178
00179 void readTop(ifstream* inFile){
00180
00181 char ch[1000];
00182 while ((*inFile).getline(ch , 1000)){
00183 string line = ch;
00184 LINFO("top reader reads : '%s'", line.c_str());
00185 if(line.compare("end top")==0) break;
00186 string::size_type position = line.find("=");
00187 string skinname = line.substr(0, position);
00188 string path = line.substr(position+1);
00189 map<string,SDL_Surface*> themap;
00190
00191 for(int i = 0 ; i < NUMBER_OF_CLASSES ; i++){
00192 string filepath ;
00193 filepath += path+"/"+classes[i]+"/ball.png" ;
00194
00195 themap[classes[i]]= load_image(filepath) ;
00196 }
00197 skinsmap[skinname] = themap;
00198
00199 }
00200
00201 }
00202
00203 void showStaticSlide(string *slideMap,string skinName , int col , int row , int px , int py , float rf){
00204
00205 d->clearScreen();
00206 map<string,SDL_Surface*> resizedSurfacesMap;
00207 map<string,int> clipNumMap;
00208 SDL_Rect theClip ;
00209 theClip.x = 0 ;
00210 theClip.y = 0 ;
00211 theClip.w = (int)(rf* IMAGE_WIDTH) ;
00212 theClip.h = (int)(rf* IMAGE_WIDTH) ;
00213
00214 SDL_Surface* nbg = getAFreshSurface((int)(IMAGE_WIDTH*col*rf), (int)(IMAGE_WIDTH*row*rf));
00215
00216
00217
00218
00219 for(map<string,SDL_Surface*>::iterator jj=(skinsmap[skinName]).begin() ; jj!= (skinsmap[skinName]).end() ; ++jj )
00220 {
00221 int numOfImages = ((jj->second)->h)/IMAGE_WIDTH ;
00222 clipNumMap[jj->first] = numOfImages ;
00223
00224
00225 }
00226
00227
00228 for(map<string,SDL_Surface*>::iterator jj=(skinsmap[skinName]).begin() ; jj!= (skinsmap[skinName]).end() ; ++jj )
00229 {
00230 SDL_Surface *tmpSurface = getAFreshSurface(IMAGE_WIDTH,IMAGE_WIDTH);
00231 *tmpSurface = *(jj->second);
00232 tmpSurface = SDL_Resize(tmpSurface , rf , 3 );
00233 resizedSurfacesMap[jj->first] = tmpSurface;
00234
00235 }
00236
00237
00238
00239
00240 for(map<string,SDL_Surface*>::iterator jj=(skinsmap[skinName]).begin() ; jj!= (skinsmap[skinName]).end() ; ++jj){
00241 string className = jj->first;
00242
00243
00244
00245 for(int i = 0 ; i < col*row ; i++){
00246
00247 if(slideMap[i].compare( className )==0){
00248 int clipY = (int)((rand()% clipNumMap[className])*IMAGE_WIDTH*rf);
00249 theClip.y = clipY ;
00250 apply_surface((int)((i%col)*IMAGE_WIDTH*rf),(int)((i/col)*IMAGE_WIDTH*rf),resizedSurfacesMap[className],nbg,&theClip) ;
00251 }
00252 }
00253
00254
00255
00256 }
00257 SDL_Rect offset;
00258
00259
00260 offset.x = px;
00261 offset.y = py;
00262 d->displaySDLSurfacePatch(nbg , &offset,NULL , -2,false, true);
00263 d->waitNextRequestedVsync(false, true);
00264 d->waitForKey();
00265
00266
00267 for(map<string,SDL_Surface*>::iterator jj=(skinsmap[skinName]).begin() ; jj!= (skinsmap[skinName]).end() ; ++jj )
00268 {
00269 dumpSurface(resizedSurfacesMap[jj->first]);
00270 }
00271 dumpSurface(nbg) ;
00272
00273 }
00274
00275
00276 void showDynamicSlide(string *slideMap,string skinName , int col , int row , int px , int py , float rf){
00277
00278 map<string,SDL_Surface*> resizedSurfacesMap;
00279 map<string,int> clipNumMap;
00280 int phase[col*row] ;
00281 SDL_Rect theClip ;
00282 theClip.x = 0 ;
00283 theClip.y = 0 ;
00284 theClip.w = (int)(rf* IMAGE_WIDTH) ;
00285 theClip.h = (int)(rf* IMAGE_WIDTH) ;
00286 bool slideQuit = false ;
00287 SDL_Surface *nbg = getAFreshSurface((int)(IMAGE_WIDTH*col*rf), (int)(IMAGE_WIDTH*row*rf));
00288
00289
00290
00291 for(map<string,SDL_Surface*>::iterator jj=(skinsmap[skinName]).begin() ; jj!= (skinsmap[skinName]).end() ; ++jj )
00292 {
00293 int numOfImages = ((jj->second)->h)/IMAGE_WIDTH ;
00294 clipNumMap[jj->first] = numOfImages ;
00295
00296 }
00297
00298
00299 for(map<string,SDL_Surface*>::iterator jj=(skinsmap[skinName]).begin() ; jj!= (skinsmap[skinName]).end() ; ++jj )
00300 {
00301 SDL_Surface* tmpSurface = getAFreshSurface(IMAGE_WIDTH,IMAGE_WIDTH );
00302 *tmpSurface = *(jj->second);
00303 tmpSurface = SDL_Resize(tmpSurface , rf , 3 );
00304 resizedSurfacesMap[jj->first] = tmpSurface;
00305
00306 }
00307
00308 for(int i = 0 ; i < col*row ; i++){
00309
00310 phase[i] = rand()% clipNumMap[*(slideMap+i)];
00311 }
00312
00313 int l = 0 ;
00314
00315 while( slideQuit == false ) {
00316
00317 while(SDL_PollEvent( &event )){
00318
00319 if(event.type == SDL_KEYDOWN){
00320 if( event.key.keysym.sym == SDLK_SPACE )
00321 {
00322 slideQuit = true ;
00323 }
00324 if( event.key.keysym.sym == SDLK_ESCAPE )
00325 {
00326 slideQuit = true ;
00327 programQuit = true ;
00328 }
00329 if(event.key.keysym.sym == SDLK_UP){
00330 if (delay > 2 )delay -= 2 ;
00331 }
00332
00333 if(event.key.keysym.sym == SDLK_DOWN){
00334 if (delay < 500 )delay += 2 ;
00335 }
00336
00337 }
00338
00339
00340 if( event.type == SDL_QUIT || event.key.keysym.sym == SDLK_ESCAPE )
00341 {
00342 programQuit = true;
00343 slideQuit = true ;
00344 }
00345
00346
00347 }
00348
00349 for(map<string,SDL_Surface*>::iterator jj=(skinsmap[skinName]).begin() ; jj!= (skinsmap[skinName]).end() ; ++jj){
00350 string className = jj->first;
00351
00352 for(int i = 0 ; i < col*row ; i++){
00353
00354 int clipY = (int)(((l+phase[i]) % clipNumMap[className])*IMAGE_WIDTH*rf);
00355 theClip.y = clipY ;
00356
00357 if(slideMap[i].compare( className )==0){
00358 apply_surface((int)((i%col)*IMAGE_WIDTH*rf),(int)((i/col)*IMAGE_WIDTH*rf),resizedSurfacesMap[className],nbg,&theClip);
00359 }
00360 }
00361
00362
00363 }
00364
00365 SDL_Rect offset;
00366
00367
00368 offset.x = px;
00369 offset.y = py;
00370 d->displaySDLSurfacePatch(nbg , &offset ,NULL, -2,true, true);
00371
00372 l++ ;
00373 SDL_Delay( delay );
00374 }
00375
00376
00377 for(map<string,SDL_Surface*>::iterator jj=(skinsmap[skinName]).begin() ; jj!= (skinsmap[skinName]).end() ; ++jj )
00378 {
00379 dumpSurface(resizedSurfacesMap[jj->first]);
00380 }
00381 dumpSurface(nbg) ;
00382
00383 }
00384
00385
00386
00387
00388
00389 void readSlide(ifstream* inFile){
00390 char ch[1000];
00391 string skinName;
00392 float resizefactor = 1.0f;
00393 int px = 0, py = 0, rows = 0, columns = 0;
00394 string slideMap[MAX_CELLS];
00395 bool isDynamic = false ;
00396 d->clearScreen() ;
00397 d->displayRedDotFixationBlink();
00398 d->pushEvent(std::string("===== Reading Slide ====="));
00399 while ((*inFile).getline(ch , 1000)){
00400 string line = ch;
00401 LINFO("slide reader reads : '%s'...", line.c_str());
00402 d->pushEvent(line.c_str());
00403 if(line.substr(0,4).compare("skin")==0){
00404 string::size_type position = line.find("=");
00405 skinName = line.substr(position+1);
00406
00407 }
00408 if(line.substr(0,2).compare("rf")==0){
00409 string::size_type position = line.find("=");
00410 char rf[10] ;
00411 strcpy(rf,line.substr(position+1).c_str());
00412 resizefactor = atof(rf);
00413 }
00414 if(line.substr(0,2).compare("px")==0){
00415 string::size_type position = line.find("=");
00416 char rf[10] ;
00417 strcpy(rf,line.substr(position+1).c_str());
00418 px = atoi(rf);
00419 }
00420 if(line.substr(0,2).compare("py")==0){
00421 string::size_type position = line.find("=");
00422 char rf[10] ;
00423 strcpy(rf,line.substr(position+1).c_str());
00424 py = atoi(rf);
00425 }
00426 if(line.substr(0,2).compare("rs")==0){
00427 string::size_type position = line.find("=");
00428 char rf[10] ;
00429 strcpy(rf,line.substr(position+1).c_str());
00430 rows = atoi(rf);
00431 }
00432 if(line.substr(0,2).compare("cs")==0){
00433 string::size_type position = line.find("=");
00434 char rf[10] ;
00435 strcpy(rf,line.substr(position+1).c_str());
00436 columns = atoi(rf);
00437 }
00438
00439 if(line.substr(0,6).compare("static")==0){
00440 isDynamic = false ;
00441 }
00442
00443 if(line.substr(0,7).compare("dynamic")==0){
00444 isDynamic = true ;
00445 }
00446
00447 if(line.substr(0,3).compare("map")==0){
00448 int p = 3 ;
00449 string cs = "class";
00450 for (int i =0 ; i < rows*columns ; i++){
00451 int pos = p+1 +i*2 ;
00452 string cn = line.substr(pos ,1);
00453 slideMap[i] = cs+cn;
00454 }
00455 if(isDynamic == true){
00456
00457 showDynamicSlide(&slideMap[0],skinName,columns,rows,px,py,resizefactor) ;
00458
00459 }else{
00460 showStaticSlide(&slideMap[0],skinName,columns,rows,px,py,resizefactor) ;
00461 }
00462
00463
00464 }
00465
00466
00467
00468 if(line.compare("end slide")==0) break;
00469
00470
00471 }
00472
00473 }
00474
00475 int readprofile(const char* filename){
00476 ifstream inFile(filename, ios::in);
00477 if (! inFile)
00478 {
00479 return -1;
00480 }
00481
00482 char ch[1000];
00483 while (inFile.getline(ch , 500)){
00484 string line = ch;
00485 LINFO("profile reader reads : '%s'...", line.c_str());
00486 if(line.compare("top")==0 ) readTop(&inFile);
00487
00488 if(line.compare("slide")==0) readSlide(&inFile);
00489 if(programQuit == true) break ;
00490 }
00491
00492 return 0 ;
00493 }
00494
00495
00496 extern "C" int main( int argc, char* args[] ){
00497 MYLOGVERB = LOG_INFO;
00498
00499 manager.addSubComponent(d);
00500 nub::soft_ref<EventLog> el(new EventLog(manager));
00501 manager.addSubComponent(el);
00502
00503 manager.setOptionValString(&OPT_EventLogFileName, "psychodata.psy");
00504
00505 d->setEventLog(el);
00506
00507 manager.start();
00508
00509
00510 d->clearScreen();
00511 d->displayISCANcalib();
00512 d->waitForKey();
00513
00514 d->displayText("<SPACE> to calibrate; other key to skip");
00515
00516 d->waitForKey();
00517
00518
00519 d->clearScreen();
00520 d->displayText("<SPACE> for random play; other key for ordered");
00521
00522 d->waitForKey();
00523
00524 d->displayFixation();
00525
00526
00527 d->waitForKey();
00528 d->waitNextRequestedVsync(false, true);
00529
00530
00531 string filename;
00532 if(argc == 2) {
00533 if(readprofile(args[1])< 0) return -1;
00534 }else{
00535 cerr << "usage : " << args[0] << " file_name.exp \n";
00536 return -1 ;
00537 }
00538
00539 clean_up();
00540 manager.stop() ;
00541 return 0;
00542 }
00543
00544 #endif // INVT_HAVE_LIBSDL_IMAGE