psycho-text.C
Go to the documentation of this file.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 #include "Component/ModelManager.H"
00040 #include "Image/Image.H"
00041 #include "Image/DrawOps.H"
00042 #include "Image/SimpleFont.H"
00043 #include "Psycho/PsychoDisplay.H"
00044 #include "Psycho/EyeTrackerConfigurator.H"
00045 #include "Psycho/EyeTracker.H"
00046 #include "Psycho/PsychoOpts.H"
00047 #include "Component/EventLog.H"
00048 #include "Component/ComponentOpts.H"
00049 #include "Util/Types.H"
00050 #include "Util/StringConversions.H"
00051 #include "Util/StringUtil.H"
00052
00053 #include <fstream>
00054
00055 #define HDEG 54.9
00056
00057 extern "C" int main(const int argc, char** argv)
00058 {
00059 MYLOGVERB = LOG_INFO;
00060
00061
00062 ModelManager manager("Psycho Text");
00063
00064
00065 nub::soft_ref<PsychoDisplay> d(new PsychoDisplay(manager));
00066 manager.addSubComponent(d);
00067
00068 nub::soft_ref<EyeTrackerConfigurator>
00069 etc(new EyeTrackerConfigurator(manager));
00070 manager.addSubComponent(etc);
00071
00072 nub::soft_ref<EventLog> el(new EventLog(manager));
00073 manager.addSubComponent(el);
00074
00075 manager.setOptionValString(&OPT_EventLogFileName, "psychodata.psy");
00076 manager.setOptionValString(&OPT_EyeTrackerType, "ISCAN");
00077
00078
00079 if (manager.parseCommandLine(argc, argv,
00080 "<textfile> visual-angle-of-single-character",
00081 1, 2)==false)
00082 return(1);
00083 double fontsize = fromStr<double>(manager.getExtraArg(1));
00084
00085
00086 nub::soft_ref<EyeTracker> et = etc->getET();
00087 d->setEyeTracker(et);
00088 d->setEventLog(el);
00089 et->setEventLog(el);
00090
00091
00092 manager.start();
00093
00094
00095 et->calibrate(d);
00096
00097 d->clearScreen();
00098 d->displayText("<space> for random order, other key for ordered play.");
00099 int c = d->waitForKey();
00100 d->clearScreen();
00101
00102
00103
00104
00105
00106
00107
00108 std::ifstream *itsFile;
00109 itsFile = new std::ifstream(manager.getExtraArg(0).c_str());
00110
00111
00112 if (itsFile->is_open() == false)
00113 LFATAL("Cannot open '%s' for reading",manager.getExtraArg(0).c_str());
00114
00115
00116 std::string line;
00117 std::vector<std::vector<std::string> > lines;
00118 std::vector<uint> itsType;
00119 uint scount = 0;
00120
00121
00122 while (!itsFile->eof())
00123 {
00124 getline(*itsFile, line);
00125
00126 std::vector<std::string> temp;
00127
00128 if (line[0] == '#')
00129 {
00130 line.erase(0,1);
00131 temp.push_back(line);
00132 lines.push_back(temp);
00133 itsType.push_back(1);
00134 scount++;
00135 }
00136 else if (line[0] =='!')
00137 {
00138 line.erase(0,1);
00139 temp.push_back(line);
00140 lines.push_back(temp);
00141 itsType.push_back(0);
00142 scount++;
00143 }
00144 else
00145 {
00146 if (line.size() > 1)
00147 {
00148 scount--;
00149 lines[scount].push_back(line);
00150 scount++;
00151 }
00152 }
00153 }
00154 itsFile->close();
00155
00156
00157 int w = d->getWidth();
00158 int h = d->getHeight();
00159 uint fontwidth = uint(fontsize * w / HDEG);
00160 SimpleFont fnt = SimpleFont::fixedMaxWidth(fontwidth);
00161 std::vector<Image<PixRGB<byte> > > itsSImage;
00162 std::vector<Image<PixRGB<byte> > > itsQImage;
00163
00164 for (uint i = 0; i < lines.size(); i++)
00165 {
00166 int space = 0;
00167 int hanchor = int(h/2) - int(fnt.h()/2);
00168 Image<PixRGB<byte> > timage(w,h,ZEROS);
00169 timage += d->getGrey();
00170
00171 for (uint j = 0; j < lines[i].size(); j++)
00172 {
00173 if (j < 1)
00174 space = int( double(w - fnt.w() * lines[i][j].size()) / 2.0 );
00175 if (j > 0)
00176 hanchor = hanchor + fnt.h();
00177 Point2D<int> tanchor(space, hanchor);
00178 writeText(timage,tanchor,lines[i][j].c_str(),
00179 PixRGB<byte>(0,0,0),
00180 d->getGrey(),
00181 fnt);
00182 }
00183 if (itsType[i] == 0)
00184 itsSImage.push_back(timage);
00185 else
00186 itsQImage.push_back(timage);
00187 }
00188
00189 uint count = scount/2;
00190 int indexS[count];
00191 int indexQ[count];
00192 for (uint i = 0; i < count; i ++)
00193 {
00194 indexS[i] = i;
00195 indexQ[i] = i;
00196 }
00197
00198 if (c == ' ')
00199 {
00200 LINFO("Randomizing images...");
00201 randShuffle(indexS, count);
00202 randShuffle(indexQ, count);
00203 }
00204
00205 bool nextSentence = true;
00206 uint ii =0;
00207
00208 for (uint i = 0; i < scount; i ++)
00209 {
00210
00211 d->clearScreen();
00212 Image< PixRGB<byte> > image;
00213 if (nextSentence)
00214 image = itsSImage[indexS[ii]];
00215 else
00216 image = itsQImage[indexQ[ii]];
00217
00218 SDL_Surface *surf = d->makeBlittableSurface(image, true);
00219
00220 if (nextSentence)
00221 LINFO("sentence '%d' ready.", ii);
00222 else
00223 LINFO("question '%d' ready.", ii);
00224 d->displayFixation();
00225
00226
00227 d->waitForKey();
00228 d->waitNextRequestedVsync(false, true);
00229
00230 if (nextSentence)
00231 d->pushEvent(std::string("===== Showing Sentence: ") +
00232 toStr<int>(indexS[ii]) + " =====");
00233 else
00234 d->pushEvent(std::string("===== Showing Question: ") +
00235 toStr<int>(indexQ[ii]) + " =====");
00236
00237 nextSentence = !nextSentence;
00238 if (i%2 != 0)
00239 ii++;
00240
00241
00242 et->track(true);
00243
00244
00245 d->displayFixationBlink();
00246
00247
00248 d->displaySurface(surf, -2);
00249
00250
00251 c = d->waitForKey();
00252
00253
00254 SDL_FreeSurface(surf);
00255
00256
00257 d->clearScreen();
00258
00259
00260 usleep(50000);
00261 et->track(false);
00262 }
00263
00264 d->clearScreen();
00265 d->displayText("Experiment complete. Thank you!");
00266 d->waitForKey();
00267
00268
00269 manager.stop();
00270
00271
00272 return 0;
00273 }
00274
00275
00276
00277
00278
00279