Пример #1
0
// ######################################################################
Point2D<int> EyeTrackerEyeLink::getEyePos() const
{
#ifndef HAVE_EYELINK
  LFATAL("Proprietary EyeLink developer API not installed");
	return Point2D<int>(-1,-1);
#else
	// get gaze position
	eyelink_newest_float_sample(&evt);

	// make sure pupil is present
	if(evt.fs.gx[RIGHT_EYE]!=MISSING_DATA && 
		 evt.fs.gy[RIGHT_EYE]!=MISSING_DATA && evt.fs.pa[RIGHT_EYE]>0){
		return Point2D<int>((int)evt.fs.gx[RIGHT_EYE], (int)evt.fs.gy[RIGHT_EYE]);
	} else {
		return Point2D<int>(-1, -1);
	}
#endif
}
      // Run gaze-contingent window trial
      // <fgbm> is bitmap to display within window
      // <bgbm> is bitmap to display outside window
      // <wwidth, wheight> is size of window in pixels
      // <mask> flags whether to treat window as a mask
      // <time_limit> is the maximum time the stimuli are displayed 
int gc_window_trial(HBITMAP fgbm, HBITMAP bgbm, 
                    int wwidth, int wheight, int mask, UINT32 time_limit)
{
  UINT32 trial_start=0;	// trial start time (for timeout) 
  UINT32 drawing_time;  // retrace-to-draw delay
  int button;		// the button pressed (0 if timeout) 
  int error;            // trial result code

  ALLF_DATA evt;         // buffer to hold sample and event data
  int first_display = 1; // used to determine first drawing of display  
  int eye_used = 0;      // indicates which eye's data to display
  float x, y;		 // gaze position 

    // NOTE: TRIALID AND TITLE MUST HAVE BEEN SET BEFORE DRIFT CORRECTION!
    // FAILURE TO INCLUDE THESE MAY CAUSE INCOMPATIBILITIES WITH ANALYSIS SOFTWARE!


       // Set size and type of gaze-contingent window 
  RECT display_rect;

  display_rect.top    = dispinfo.top;
  display_rect.bottom = dispinfo.bottom;
  display_rect.left   = dispinfo.left;
  display_rect.right  = dispinfo.right;
  initialize_gc_window(wwidth, wheight, fgbm, bgbm, 
                       full_screen_window, display_rect, 
                       mask, SCRWIDTH/300);  // sets 0.1 degree deadband

	   // DO PRE-TRIAL DRIFT CORRECTION 
	   // We repeat if ESC key pressed to do setup. 
  while(1)
    {              // Check link often so we can exit if tracker stopped
      if(!eyelink_is_connected()) return ABORT_EXPT;
	   // We let do_drift_correct() draw target in this example
	   // 3rd argument would be 0 if we already drew the display
      error = do_drift_correct((INT16)(SCRWIDTH/2), (INT16)(SCRHEIGHT/2), 1, 1);
           // repeat if ESC was pressed to access Setup menu 
      if(error!=27) break;
    }

  clear_full_screen_window(target_background_color);  // make sure display is blank
  
	// Start data recording to EDF file, BEFORE DISPLAYING STIMULUS 
	// You should always start recording 50-100 msec before required
	// otherwise you may lose a few msec of data 
  
	//  tell start_recording() to send link data
  error = start_recording(1,1,1,1);	// record with link data enabled
  if(error != 0) return error;          // ERROR: couldn't start recording
                              // record for 100 msec before displaying stimulus 
  begin_realtime_mode(100);   // Windows 2000/XP: no interruptions from now on

    // DONT DISPLAY OUR IMAGES TO SUBJECT until we have first gaze postion!
  
  if(!eyelink_wait_for_block_start(100, 1, 0))  // wait for link sample data
    {
      end_trial();
      alert_printf("ERROR: No link samples received!");
      return TRIAL_ERROR;
    }
  eye_used = eyelink_eye_available(); // determine which eye(s) are available 
  switch(eye_used)		      // select eye, add annotation to EDF file	
    {			
      case RIGHT_EYE:
        eyemsg_printf("EYE_USED 1 RIGHT");
        break;
      case BINOCULAR:           // both eye's data present: use left eye only
        eye_used = LEFT_EYE;
      case LEFT_EYE:
        eyemsg_printf("EYE_USED 0 LEFT");
        break;
    }
                                 // Now get ready for trial loop
  eyelink_flush_keybuttons(0);   // reset keys and buttons from tracker 
                       // we don't use getkey() especially in a time-critical trial
                       // as Windows may interrupt us and cause an unpredicatable delay
                       // so we would use buttons or tracker keys only  

     // Trial loop: till timeout or response -- added code for reading samples and moving cursor
  while(1) 
    {                            // First, check if recording aborted 
      if((error=check_recording())!=0) return error;  
                                 // Check if trial time limit expired
      if(current_time() > trial_start+time_limit && trial_start!=0)
        {
          eyemsg_printf("TIMEOUT");    // message to log the timeout 
	  end_trial();                 // local function to stop recording
	  button = 0;                  // trial result message is 0 if timeout 
	  break;                       // exit trial loop
	}

      if(break_pressed())     // check for program termination or ALT-F4 or CTRL-C keys
	{
	   end_trial();         // local function to stop recording
	   return ABORT_EXPT;   // return this code to terminate experiment
	 }

      if(escape_pressed())    // check for local ESC key to abort trial (useful in debugging)   
         {
	   end_trial();         // local function to stop recording
	   return SKIP_TRIAL;   // return this code if trial terminated
         }

		/* BUTTON RESPONSE TEST */
		// Check for eye-tracker buttons pressed
		// This is the preferred way to get response data or end trials	
      button = eyelink_last_button_press(NULL);
      if(button!=0)       // button number, or 0 if none pressed
	{
	   eyemsg_printf("ENDBUTTON %d", button);  // message to log the button press
	   end_trial();                            // local function to stop recording
	   break;                                  // exit trial loop
	 }
  
                // NEW CODE FOR GAZE CONTINGENT WINDOW 
  
      if(eyelink_newest_float_sample(NULL)>0)  // check for new sample update
	{
	  eyelink_newest_float_sample(&evt);   // get the sample 
          x = evt.fs.gx[eye_used];    // yes: get gaze position from sample 
	  y = evt.fs.gy[eye_used];
	  if(x!=MISSING_DATA && 
             y!=MISSING_DATA &&
	     evt.fs.pa[eye_used]>0)     // make sure pupil is present
            {
              if(first_display)  // mark display start AFTER first drawing of window
                {       
                  wait_for_video_refresh();	  // synchronize before drawing so all seen at once
                  drawing_time = current_msec();  // time of retrace
                  trial_start = drawing_time;   // record the display onset time 
                }
	      redraw_gc_window((int)x, (int)y);  // move window if visible
              if(first_display)  // mark display start AFTER first drawing of window
                {       
                  first_display = 0;      
                  drawing_time = current_msec() - drawing_time; // delay from retrace
                  eyemsg_printf("%d DISPLAY ON", drawing_time);	// message for RT recording in analysis 
                  eyemsg_printf("SYNCTIME %d", drawing_time);	// message marks zero-plot time for EDFVIEW 
                }
            }
	  else
            {
	        // Don't move window during blink
                // To hide window, use:   redraw_gc_window(MISSING, MISSING);
            }
        } 
    }                       // END OF RECORDING LOOP

  end_realtime_mode();      // safety cleanup code
  while(getkey());          // dump any accumulated key presses

			   // report response result: 0=timeout, else button number
  eyemsg_printf("TRIAL_RESULT %d", button);
			   // Call this at the end of the trial, to handle special conditions
  return check_record_exit();
}
Пример #3
0
int record_mode_display(void)
{
  ALLF_DATA evt;
  UINT16 key;
  int eye_used = -1;   /* which eye to show gaze for */
  float x, y;	       /* gaze position  */
  float ox=-1, oy=-1;  /* old gaze position (to determine change)  */

  /* create font for position display */
  get_new_font( "Arial", SCRWIDTH/50, 0);
  while(getkey()); /* dump any pending local keys  */

  /*enable link data reception without changing tracker mode */
  eyelink_reset_data(1);   
  initialize_cursor(window, SCRWIDTH/50);
  eyelink_data_switch(RECORD_LINK_SAMPLES | RECORD_LINK_EVENTS);
  
  while(1)    /* loop while in record mode */
    {
	  
      if(eyelink_tracker_mode() != EL_RECORD_MODE) break;
      key = getkey();            /* Local keys/abort test */
      if(key==TERMINATE_KEY)     /* test ALT-F4 or end of execution */
         break;
      else if(key)             /* OTHER: echo to tracker for control */
		eyelink_send_keybutton(key,0,KB_PRESS);

               /* CODE FOR PLOTTING GAZE CURSOR  */
      if(eyelink_newest_float_sample(NULL)>0)  /* new sample? */
		{
			eyelink_newest_float_sample(&evt);  /* get the sample data */
			if(eye_used == -1)   /* set which eye to track by first sample */
			{
				eye_used = eyelink_eye_available(); 
				if(eye_used == BINOCULAR)  /* use left eye if both tracked */
					eye_used = LEFT_EYE;
			}
			else
			{
				x = evt.fs.gx[eye_used];   /* get gaze position from sample  */
				y = evt.fs.gy[eye_used];
				if(x!=MISSING_DATA && y!=MISSING_DATA &&
					evt.fs.pa[eye_used]>0)  /* plot if not in blink */
                {                        /* plot in local coords   */
					draw_gaze_cursor(track2local_x(x), 
                                    track2local_y(y));
                              /* report gaze position (tracker coords) */
               
                     {
					   SDL_Rect r = {(INT16)(SCRWIDTH*0.87), 0, (INT16)(window->w -SCRWIDTH*0.87), 50};
					   SDL_FillRect(window,&r,SDL_MapRGB(window->format,0, 0, 0));
                       graphic_printf(window, target_foreground_color, NONE, (int)(SCRWIDTH*0.87), 0, " %4.0f  ", x);
                       graphic_printf(window, target_foreground_color, NONE, (int)(SCRWIDTH*0.93), 0, " %4.0f  ", y);
                     }
                   ox = x;
                   oy = y;
                 }
				else
				{
					erase_gaze_cursor();   /* hide cursor during blink */
				}
                
				/* print tracker timestamp of sample */
				{
			   		SDL_Rect r = {(INT16)(SCRWIDTH*0.75), 0, (INT16)(SCRWIDTH*0.87 -SCRWIDTH*0.75), 50};
					SDL_FillRect(window,&r,SDL_MapRGB(window->format,0, 0, 0));
					graphic_printf(window,target_foreground_color, NONE, (int)(SCRWIDTH*0.75), 0, " % 8d ", evt.fs.time);
				}
			}
		}
    }	
  erase_gaze_cursor();   /* erase gaze cursor if visible */
  return 0;
}