:: Style
:: By Topic
:: By Search
:: By Number

FAQ#

Basic Questions, Operating Systems, Versions, Lab Setup
# 1-111Receive Operating System, DxReceive, XP
QuestionCan you use Window XP on the receive PC when using the DirectX receive program (dxrecv.exe)? What version of DirectX should I use? Which version is the most recent?
AnswerYes, you can run Dxrecv.exe on Win95/98/2000/XP. The version of Dxrecv.exe that is shipped with Cortex 595 in the \Wcortex directory can be used in any of these operating systems. Also, the latest version of the DirectX libraries from Microsoft should work on WinXP.

If you are running Dxrecv.exe in Windows 2000 or Windows XP, you may find that the Display Properties settings cannot be set to 640 x 480. Therefore, you must change the shortcut properties of DXrecv.exe. This can be achieved by right-clicking on the shortcut and selecting Properties. Once the Properties sheet comes up, click the Compatibility tab. On this tab you will see a "Compatibility mode" group box. Select "Run this program in compatibility mode for:". Once this box is checked, you will be able to choose an operating system from the drop down list box. Choose Win95 or Win98/Me, depending on your system. If you are running Cortex at 8 bits per pixel color, it is also recommended that you check the "Run in 256 colors". Also, if you are running at 640 x 480 resolution, you must check "Run in 640x480 screen resolution." These two options are located in the "Display settings" section on the Compatibility tab panel.
Back to top

# 1-169ISCAN
QuestionI would like to know if it is possible to use ISCAN signals (instead of coil) with Cortex. I know that ISCAN is able to send H and V analog outputs but it doesn’t use the same coordinate system, so I am wondering if it is a problem with Cortex? Did someone already try this configuration?
AnswerYes, Cortex will work with the ISCAN system, too. Basically, you take the EOG X & Y outputs from ISCAN (normally labeled DAO-0 and DAO-1) and plug them into the two EOG input channels for Cortex. Within the ISCAN software [I haven't used the newer, windows-based software, but the options should be the same], you need to set what goes out of those two channels. Therefore, you need to go through the options screens [pressing o for options] until you get the output screen. Then you cycle through the choices for the first output channel until you get the X position choice, and do the same for the second output channel and the y position choice. Also, you need to be in raw, not POV [point-of-view] mode.

To see if this is working, you can plug the output channel into an oscilloscope and move a ping-pong ball with a black spot [sharpie pen-made], around in front of the camera. You should see changes on the ISCAN screen showing it's moving around, and you should see voltage changes on the Oscilloscope.

The next thing is to check the DASH-16 card. The analog inputs needs to be set to 0-5V mode [they have a variety of options, and I believe default is at 0-10V?]. I'm not sure which mode should be used for each scleral coil system.

Then, calibration. Calibration should be the same as it was for the scleral coil: known distances, changing the multiplier in cortex options, offset in cortex, and playing with the offset and gains in ISCAN. How that is done in ISCAN will depend on the software used, and possibly the system too.”
Back to top

# 1-223Aborting Trial Early
QuestionWhat are the best practices for aborting all trials?
AnswerIn the DOS version of Cortex, hitting the Escape key three times in a row is supposed to end the trials. I have found that this is very time-dependent. That is, it works great if you are hitting the key between trials. However, during the trial, it seems that I need to keep hitting the Escape key repeatedly until it works.

Therefore, I usually recommend that users program their own key trapping in the timing file. This works well when your timing file has wait loops that can be used to trap the keys. Once you get the key press, make sure to call return to end the trial immediately. Here is a sample of code to capture an escape key press.
   set_timer(5000);
   while (timer_expired() == 0)
   {
      if (KeyPressed())
      {
         switch(GetAKey())
	 {
		case K_ESCAPE:  Gpurge(); return;
		default:  break;
	  }
       }
   }
Once out of the trial, the default Escape key pressing should work. Like I said, you may have to hit the Escape key 3 or more times to get it to stop the rest of the trials from running.

Other methods, such as Ctrl-break, do not seem to work as cleanly as Escape. Therefore, I would suggest sticking to the Escape key, if possible.

VCortex 1.0, 1.1, and 2.0 do not have a way to abort all trials unless you build it in to your timing file. This problem was fixed in VCortex 2.1 by enabling the Run->Stop menu item to cause the trial to stop immediately. This fix will also be included in the VCortex 1.2 release.
Back to top

# 1-242Resizing VCortex Windows
QuestionIs there a way to resize the windows in VCortex?
AnswerI'm sorry, but there is no good way to change the size of the EOG window graphics in the Windows version of Cortex. When the user screen code was transferred from DOS to Windows, I just kept the underlying sizing code from the DOS version. This is part of the problem, since the DOS version consists of one big "window" that can be partitioned into the EOG, histogram, and status sub-windows. In Windows, each window is separate. While the windows can be resized, the graphics inside the window do not grow or shrink with the window. So, unfortunately, I can't tell you a way to work around this problem. Resizing all of the graphics of the windows is on the list of things that need to be done!
Back to top

# 1-247External Data, Serial Data
QuestionIn VCortex 1.1 with Win98, I have to record external data over the serial port. I think it is possible, but where are the data after recording. Is it possible to include the serial data in the cortex-file?
AnswerIf you are reading serial data from an external device, you will need to use the built-in Cortex functions that begin with the prefix Serial_ in your timing file. As you will see, these functions just read the data as bytes (characters) or strings. The data will be available in your timing file. It will not be written to the Cortex output data file. If you want to write the data to file, you can use the functions fopen(), fprintf() and fclose() to create a data file and write to it.
Back to top

# 1-268Operating System, DOS, Win98
QuestionWould you recommend running Cortex 595 from the DOS built into WIN98, or use a real DOS system (DOS 6.22)?
AnswerOn all of my test computers for the DOS version of Cortex, I just have Win95 or Win98 installed. From these operating systems, it is easy to boot up into true DOS. I know that there are some people who configure their computers to be "dual boot" with DOS 6.22 on one partition and Windows on the other. I have never done this, but I have not heard of any problems with it. In other words, whatever you want to do it is OK, as long as you are in true DOS and not using a DOS prompt from the Windows desktop. The information below was copied from the Cortex User’s Manual.

Booting up the computer in "true" DOS

To run in true DOS mode you should shut down your computer and choose "Restart the computer." When the computer displays the "Starting Windows 95." message, press the F8 key. In the menu that appears, choose the option for "Command Prompt Only". The computer will boot to a C:> prompt.
In order to make the computer boot up in DOS without having to hit F8, you can do the following:

  1. For Win95/98, in C: there is a hidden system file called MSDOS.SYS. In order to be able to edit it, go to a DOS prompt, change to C:, and then type "attrib -h -r -s msdos.sys".
  2. Of course, before you edit it, make a backup copy!!
  3. Edit msdos.sys. In the [Options] section, add the following lines (or change them if they are already there) to look like this (explained below):
    BootMenu=1
    BootMenuDefault=6
    BootMenuDelay=60
  4. Save the file, and change it's attributes back to hidden, read-only, system file, by typing "attrib +h +r +s msdos.sys".
  5. Reboot, and it should show you the menu.
  6. NOTE: The above options are set so that:
    • BootMenu=1 means show the menu. If you no longer want to see the menu, you will have to edit it to say BootMenu=0.
    • BootMenuDefault=6 means that if you don't press any menu key, it will automatically boot up with option 6 (command prompt only). In Win98, the value should be 5.
    • BootMenuDelay=60 means that it will wait 60 seconds before running the default menu item. The default time is 30 seconds. Of course, you can make it less, if you want.
Back to top

# 1-316Sound
QuestionCan you play sound in Cortex? How?
AnswerThe ability to play sounds in Cortex was added to the dual computer Cortex program in all versions later than 5.9.2. With this code, up to 256 different sound (.wav) files can be played during an experiment. Additionally, the volume and mix of the sound from the speakers can be changed during the experiment through function calls in the Cortex timing file. Because the sound code was integrated with the 32-bit Cortex “send/receive” code, it can only be used with the two computer 32-bit version of Cortex. Also, be aware that the sound code has not yet been tested for latencies.

Capabilities:

1. DOS (rvesactx.exe) version

Up to 256 different sound (.wav) files can be played one at a time during an experiment. Additionally, the volume and mix of the sound from the speakers can be changed. Changes in the volume and mix will apply to all subsequent sounds that are played.

2. DirectX (dxrecv.exe) version

The sound component of the DirectX receive program has more functionality than the DOS version of the sound code. For example, DirectX supports the overlaying of multiple sounds, the ability to continually loop a sound, the individual control of the volume of each sound, and the ability to stop each sound one at a time. Because of these differences, the timing file functions supporting sound had to be changed to accommodate these features. In particular, SOUNDvol() and SOUNDstop() must take the sound number as input, since each sound must be controlled individually. Also, SOUNDplay() and SOUNDstart() must take a parameter to control whether or not to loop the sound continuously until SOUNDstop() is called. Existing timing files written for the DOS version should work. However, please note that these extra parameters will be set to 0. Therefore, there will be no looping, and SOUNDvol() and SOUNDstop() will operate on the first sound (i.e. sound number 0) only.

DirectX also allows the user to specify which type speakers are being used, and also the orientation of the stereo speakers, in order to optimize the sound produced. The SOUND parameter in the CORTEX.CFG file can be used to customize these features.

Installation:

1. DOS (rvesactx.exe) version
A SoundBlaster card must be installed in the receive computer. Any modern SoundBlaster card should work (e.g. SB16, AWE32, or AWE64). It might also work on SB16 compatible cards, but it has not been tested. If the SoundBlaster card has been installed properly in the computer, there is no additional configuration necessary to use the Cortex sound capabilities. The code reads the DOS “BLASTER” environment variable to get the addresses and IRQs of the card. Certain problems with the sound initialization and execution during the use of Cortex are logged to the file “rvesactx.err” on the receive computer. Please note that the sound (.wav) files must be present on the receive computer.

2. DirectX (dxrecv.exe) version
Any sound card which is supported by DirectX can be installed in the receive computer. After the sound card is installed in the computer, the DirectX driver must be installed. Please refer to the document entitled, Instructions for the DirectX Receive Program (DXRECV.EXE) for information on how to obtain and install the DirectX driver. Certain problems with the sound initialization and execution during the use of Cortex are logged to the file “dxrecv.err” on the receive computer. Please note that the sound (.wav) files must be present on the receive computer.

Interface:

The following functions can be included in a Cortex timing file:
SOUNDload, SOUNDplay, SOUNDprep, SOUNDstart, SOUNDstop, and SOUNDvolume. Refer to the online Function Reference Manual for more information about these functions.

Examples:
For the DOS version of receive program (rvesactx.exe), refer to the timing file “sound.tim” in the \cortex\demos\misc directory of the Cortex distribution files. For the DirectX version of the receive program, refer to the timing file “dxsound.tim” in the \cortex\demos\dx directory of the Cortex distribution files.

Alternate method:
If you simply require a simple beep, rather than a .wav file, the beep() function is available for the DOS version of Cortex. A timing file, contributed by a Cortex user, is pasted below:

#define do     1047
#define re     1175
#define mi     1319
#define wait(ms) set_timer(ms);  while(!timer_expired())

main () {
   playsound (do, 500, 100);
   playsound (re, 500, 100);
   playsound (mi, 500, 100);
}
 
void playsound (int freq, int dur, int inter) {
   beep (freq);
   wait (dur);
   beep (OFF);
   wait (inter);
}
Back to top

# 1-363Choosing Versions of VCortex, Dual Boot, DOS, Win98, PCI-DAS1602/12
QuestionOn the Send Cortex PC, I would like to run VCortex2.0 on Win XP. As a backup option, I would also like to have a possibility to run DOS Cortex version 595. Which operating system should I install to run successfully also Cortex Version 595 - Win 98? Both Cortex versions use the PCI - DAS1602/12 data acquisition board.
AnswerYes, this is a good idea to be able to run both versions. Since WinXP does not have an easy way to boot up into DOS, you really need to have a dual boot system. I know of a couple people who have created a dual boot system of DOS and WinXP. Another alternative is having a dual boot of Win98 and WinXP. I have never set up a computer like this, but there should be information on the Microsoft web site concerning how to do this.
Back to top

# 1-487External Variables
QuestionCan you please explain how to use external variables?
AnswerThe following code can be loaded as both a timing file and an external variables file using the Cortex menus.
/* 
#SET _int0  numtimes 1 0 
#SET _int1  cuenum  1  0 
*/ 
// numtimes and cuenum are initially zero, so the first time through 
// the cue will be TEST0. 
// If you want to change this, you will need another external variable 
// to keep track of whether or not it is the first trial...and set 
// up the variables appropriately. 

#include "css_inc.h" 

#define numtimes _int0 
#define cuenum _int1 

main() 
{ 

   if (numtimes < 3) 
   { 
      // you've had less than 3 repetitions of the same item, 
      // so display this same cue again. 
       Gon_off(cuenum, ON); 
       Gflush(1); 
       // do whatever else 
       Gon_off(cuenum, OFF); 
       Gflush(1); 
       // increment counter 
       numtimes++; 
   } 
   else 
   {   // you've had 3 repetitions of the same item, so 
      // reset counter back to 0 
      numtimes = 0; 
      // pick a new cue 
      cuenum = random(1, 10); 
      Gon_off(cuenum, ON); 
      Gflush(1); 
      // do whatever else 
      Gon_off(cuenum, OFF); 
       Gflush(1); 
       // increment counter 
       numtimes++; 
   } 
} 
Basically, external variables are used to store values that you want to persist between trials. There is the ability to have 30 external integers, 30 external character variables, etc. (the list is in the timing file reference manual). To use the first integer external variable, you can just use it by name (which is int0) in your timing file. To use the second integer external variable, you can use it as _int1, etc. If you use a variable name like _int0 in your timing file, your timing file will be very hard to read. Therefore, you can use #define to give it a more reasonable name. Refer to the example code above, which has the lines:

#define numtimes _int0
#define cuenum _int1

With those lines, I could then use the names "numtimes" and "cuenum" in the timing file, instead of the names _int0 and _int1.

You could just run your timing file like that forever. However, what if you want to reset the values of "numtimes" or "cuenum" to something else? In the DOS Cortex menus, you need to go to the Run:ExternVars:setExterns, to explicitly change the values for _int0 and _int1 in the list that appears. For the VCortex version, you would set them with the Edit:External Variables menu option.

You could just run like this, and be perfectly happy! However, again, wouldn't it make the timing file easier to run if you didn't have to remember that _int0 is numtimes and _int1 is cuenum when you were changing the values in the menu?

This is where #SET comes into the picture. #SET lets you create a set of names for the external variables that you are using. The syntax of the #SET line is:




That is why, for your timing file, I wrote:

/*
#SET _int0 numtimes 1 0
#SET _int1 cuenum 1 0
*/

These #SET commands must be within /* ... */ type comments as I have shown, so they can be included within your timing files.

To load in these #SET lines, use Run:ExternVars:create_Subset to load the timing file which contains the #SET lines. Then, use Run:ExternVars:Use_subset to view or change the values. (For the VCortex version, the File: Load: External Variables File, and Edit: External Variables menu options would be used.)
Back to top

# 1-847Rebuilding VCortex Code
QuestionHow do I rebuild the Cortex 2.0 code?
AnswerRefer to Chapter 8 “Source Code”, in the VCortex User’s Manual for detailed instructions on how to build the code. For licensing reasons, we did not ship the debug libraries for MS VC++ or for the GCL communications library (gclfwd.lib). Therefore, you may need to build the Release version of the executable, rather than the Debug version. You can change which version you are building in Build: Set Active Configuration.
Back to top

# 1-898Data Type Size
QuestionWhat are the exact sizes of all the data types in the timing files?
AnswerFor the old versions of Cortex (\num9gxi, \sgtpeppr, and \remcort), it uses a 16-bit compiler, so the integers are 16-bit. With the DOS \remote32 version, the Watcom compiler was used, which allowed for 32-bit integers. The VCortex versions all use the Microsoft Visual C++ compiler, which supports 32-bit integers. The main data types and sizes for VCortex and \remote32 DOS Cortex are as follows:

Char: 1 byte
Short: 2 bytes
Int: 4 bytes
Long: 4 bytes
Float: 4 bytes
Back to top

# 1-973Basic Cortex Questions, Lab Setup, Cortex Capabilities, RS-232
QuestionI wonder if it is possible to record movements via a device on a RS-232 serial port. I will additionally record spikes (1-2 channels), one eye-coil and one other analog input device. I also have two other devices that need to be controlled through Cortex.
AnswerI believe that Cortex will work with your system. Let me describe the capabilities of Cortex, and then you can decide.

First, yes, Cortex will accept serial input from a device. Cortex needs one serial port for communication with the graphics display computer. However, if your computer has another serial port, it can be used to read or write to a serial device. Refer to the online Function Reference Manual for the functions that can be used to talk to serial devices. The functions all begin with the prefix "Serial_".

The recording of 2 spike channels is no problem at all.

Cortex can collect 4 analog input channels. Therefore, most users collect 2 eye-coil channels (x and y positions). The other 2 analog input channels are generally not used by most users, but can be used for any other analog input you would like. Therefore, you could use them for the other analog input device.

The other two devices would need to be controlled via the digital or analog output lines on the data acquisition card. Sending out digital data is no problem at all. You would use the DEVoutp() function call for this purpose. If you need to send out analog output, the DAS16 board, which is used by Cortex, only has 2 analog output lines. If you know the port address and register in which to write for analog output, you can just use an outp() function to write to the port.

Back to top

Configuration, cortex.cfg
# 2-140More Than 8 Bit Color Depth
QuestionIs it possible to use more than 8-bit color depth in cortex? We would like at least 10 bit.
AnswerIt is not possible to use more than an 8-bit color depth in Cortex. One Cortex user requested this a couple of years ago. At the time, there were very few boards for PC's that would even support 10-bit color. I looked into using the Cambridge VSG boards which supported 10 and 12-bit color. Their boards are programmed with a proprietary graphics library, and were not able to be used with DirectX or Scitech MGL. Therefore, it would have been necessary to write a new "receive" (graphics) program for Cortex. For other vendors (such as ATI, I believe?), they had support for 10-bit, but no way to access it!! Besides the new graphics program, there would have been other changes to handle 10-bit color on the "send" side. Therefore, we decided that it was more trouble than it was worth for 1 user. I haven't looked into it since then, so there may be other graphics card vendors or other ways to do this easily. If you know of any 10-bit color cards for the PC, please let us know and we will look into it again, if there is a big enough demand for this feature.
Back to top

# 2-460Cortex.cfg, Graphics Information, EOG Screen
QuestionI am trying to setup the cortex.cfg file to have the correct graphics information. What does and mean? How can I use them to change the sizes and center of the EOG screen?
AnswerThe user screen is based on a non-conventional coordinate system, which was programmed by the original authors of Cortex. Basically, the screen is mapped as a large square, with (0,0) at the lower left corner, and (10000, 10000) at the upper right corner. Since computer monitors are not usually square, the 0->10000 coordinates get mapped into the pixel resolution of your screen that you provide in the GRAPHICS_SPECS line (with the Xdim and Ydim values). The value that you provide for pixels_per_dva is also entered into the calculation.

In the EOG_MAPPING parameter in the cortex.cfg file, you can use the and parameters to specify where you want this EOG "window" to appear on your screen. The default settings are:

EOG_MAPPING        -2048 2048 1 10 10 3250 0 10000 8000 10 
That is, the lower left x value is 3250, and the lower left y value is 0. The upper right x value is 10000, and the upper right y value is 8000. Now that you know that the screen goes from 0 to 10000, starting at the lower left, you can see how this default window would start about 1/3 of the way along the horizontal direction, and end at the right side of the screen. Likewise, in the vertical, it starts on the bottom of the screen and extends up to about 4/5 of the screen. You can change this location to whatever you want.

Another thing to keep in mind is that the size of the EOG window on the user screen has no bearing on the experiment. It just is used for your viewing of the data.
Back to top

# 2-481Cortex.cfg, Pixels, Graphics Resolution
QuestionThe Cortex Manual says: A third critical piece of information includes the graphics resolution and the pixels/degree that are to be used for the subjects display. Cortex assumes that your monitor has the correct aspect ratio, so that pixels are square.

On our setup the pixels are not squares, so how can I change that?
AnswerA pixel is just the point of light of the electron beam on the screen. The beam is not a square, because of the nature of light waves. For all practical purposes, it can be assumed to be a square. The pixel is the unit of resolution. For example, at a resolution of 1024 x 768, you will have 1024 rows each containing 768 pixels (i.e., 786432 pixels total). Unless you were using a resolution lower than the monitor is capable, the subject would not be able to tell a square pixel from a circular pixel.
Back to top

Data Acquisition Boards
# 3-194Dell, PCI, ISA, PCI-DAS1602
QuestionI have checked with Dell suppliers and it seems that Dell cannot provide any more ISA slots over the PCI motherboard (for example you need this slot for the ISA version of the CompuBoard card). Therefore, if you buy a new Dell PC, do you need to use the VCortex 2.0 for Win2000/XP with the PCI-DAS1602/12?
AnswerYou can also use the 5.9.5 release of the DOS version of Cortex. It supports the PCI-DAS1602/12 also.
Back to top

# 3-271USB Data Acquisition Card
QuestionIs it possible to use a USB-Interface-Card with Cortex? We have an external I/O-Card: Measurement PMD 1208FS for USB.
AnswerNo, Cortex will not work with a USB data acquisition card. Unfortunately, the code that interfaces with the boards is very low level and at the driver level, so special code needs to be written to support each board. Therefore, Cortex only supports the boards that are listed in the documentation.
Back to top

# 3-294Data Acquisition Boards, PCI-DAS1602/12, CompuBoard
QuestionIs the PCI-DAS1602/12 DAQ card the equivalent PCI version of the CompuBoard that runs on the ISA platforms? If not, when do you expect that cortex for Windows 2000 will support a CompuBoard card?
AnswerYes, the PCI-DAS1602/12 is the card from CompuBoard, Inc. Their company is now called Measurement Computing Corp, but it sells the same cards that CompuBoard, Inc always sold.
Back to top

# 3-297# Spike Lines, PCI-DAS1602/12, CIO-DAS16/F
QuestionIn the past I used the CIO-DAS16/F, and was able to record up to 6 spikes with cortex programming. With the new PCI-DAS1602/12 supported by Cortex for Windows2000/XP or Cortex 595 - can I use a similar configuration?
AnswerYes, you will be able to collect 6 spikes with the PCI-DAS1602/12. There are 24 digital lines on the board. I reserve Port C for the reward pulse, the latch reset pulse, the bar press, and 2 spike lines. Port A is configured by default to be 8 lines of input. Therefore, you can use these for spike inputs.
Back to top

# 3-359Sending Number To Two Ports On Device, Converting Integer to Bits
QuestionI have to send a number greater than 256 (i.e. 359) to two ports of a given device at the same time. I have to divide the number into 8 bits plus the rest. How should I do this?
AnswerYou will have to write code to split out the number into two bytes. One byte will be less than 256 and the other will be the part that is greater than 256. In C, the division and modulus operators can do this. That is, suppose your number is 359, then:
lower_byte = 359 % 256; 
upper_byte = 359 / 256; 
Since you are operating with integers, the division should truncate the result of the division, leaving you with 1 for the upper-byte. The modulus operator (%) will give you the integer remainder from the division. In this case, it will give you 103, which easily fits in a byte.

I haven't tried this in Cortex, but am instead doing this off the top of my head. If integer division and modulus don't work properly, you can also do this using subtraction, of course. (That is, 359 - 256 = 103. If the numbers are greater than 2 * 256, you have to keep subtracting and keeping track of how many times you've subtracted before you hit zero or negative.)
Back to top

# 3-646PCI-DIO24 Board, Config
QuestionI have the PCI-DIO24 board. When I set it up in the cortex.cfg file, Cortex does not recognize it. It does work if I call it PIO24.
AnswerYes, this could be the problem. If you are using the DOS Cortex 5.9.5 version, it does not support the PCI version of DIO24 card. Support for the PCIDIO24 will be in the next version of Cortex (5.9.6), which has not been officially released yet.
Back to top

Digital Input/Output, Serial Input/Output
# 4-207Digital Output, fMRI, Data Acquisition, reward(), serial_functions
QuestionI have a question regarding the digital output. I am using Cortex to run fMRI experiments and I need to trigger the data acquisition. For this I need a digital output I can set high for a specific period, and ideally this would not interfere with the processes of the timing file. Therefore, we tried to use the reward function for triggering the scanner, allowing us to determine the length of the trigger with the set_ms_reward_duration() function. But it seems that the trigger is interrupted. Do resets of the reward output occur or does the reward() function set its output high in a constant way? Is there a way to set a digital output high for a specific time without interfering with the main program (the way the reward() function should do it)?
AnswerThe reward() function should have worked to do what you were trying to do. The line should be kept high during the reward duration, and then be set back to low when the duration has expired. However, it sounds like you are getting some interference from the reset latch line, which is reset every 1 ms.

My only advice is to use a digital line that is not one of the bits on the port that has the reset latch. For example, use one of the pins of Port B to send out the digital pulse using DEVoutp(). I think this is what most fMRI users do. I have heard of others using the serial communications port to talk to an fMRI device too. Refer to the Serial_ functions in the online Cortex Function Reference Manual for some information on how to use the serial functions if you want to try that.

If you set a digital line high, it should remain high until you set it back to zero. I don\'t think that you will have the problem of it being reset, like you did when you were using the reward line. Of course, you should test it on your setup, with a simple timing file like I have pasted below. If that works, it is just a matter of fitting it into your own timing file. You will have to supply the DEVNUMBER and port number for your setup.

encode(start_num);
DEVoutp(DEVNUMBER, 0x1, 0xff);
MS_TIMERset(1, 500);
while (MS_TIMERcheck(1));
encode(end_num);
Back to top

# 4-462MS_TIMERset, timer_expired(), set_timer()
QuestionI came across a puzzling fact regarding the timer. I was trying two implementations, one using the MS_TIMERset function, while with the other I used set_timer(). The first one was working, the second not. All I changed was the functions to set and check the timer.

              MS_TIMERset(REWARD_TIMER, 2); 

              while( MS_TIMERcheck(REWARD_TIMER) > 0 ) 

              {DEVoutp(0,0x2,128);} 

        /**************************************/ 

              set_timer (2); 

              while(timer_expired() > 0 ) 

              {DEVoutp(0,0x2,128);} 
AnswerRegarding the timers, the logic of the two timers is the opposite of each other. I am not sure why the original programmers for Cortex did this, but it sure confused me for a long time! For MS_TIMERset()/MS_TIMERcheck(), it is a countdown timer. The MS_TIMERcheck() will return the amount of time left on the timer as it ticks down to zero. Therefore, your code is correct, that you just need to loop while it has not counted down to zero. The set_timer()/timer_expired() functions just have two states: expired is 1 and not expired is 0. Therefore, if you check timer_expired() and it is 0, that means that it still has time on it. In other words, in your code, it will not even get into your while loop, because 0 is not greater than 0. I usually have my while loop as follows: while(!timer_expired()) { DEVoutp(...) } That is, while it has not expired, do the loop.
Back to top

# 4-520Digital Input, DEVinp()
QuestionHow does Cortex read the digital entries? Is there any function for reading digital input? If I connect a button to the digital lines what shall we do after?
AnswerYou will need to call the DEVinp() function in your timing file to tell Cortex to read the line. If you are waiting for a button to be pressed, you will need to call this function inside a loop, so that you don't miss when it is pressed. DEVinp() will return the byte from the port. You will have to check if the bit (or bits) that you have wired is a 0 (not set) or 1 (set). This can be a little complicated because you have to use the C language bitwise operator "&".
Back to top

# 4-731Configure Port for DEVoutp
QuestionHow do I re-configure the ports of a DIO24 device?
AnswerTo configure Ports A and B as output ports, you should write a special code byte to the config port (that is, port 0x3). You should not try to write the special byte to the Port A or B itself. By default, Cortex writes a 0x91 to the config port, which makes Port A an input port, Port B an output port, and Port C is split input/output.

If you want to make Port A and Port B output ports, but keep Port C split input/output, you would write a 0x81 to the config port. In other words, your timing file would look like this:

DEVoutp(devnumber, 0x3, 0x81);

You have to do this once at the top of your timing file. In fact, it is sufficient to only do it on the first trial that you run, but you can do it every trial if you want. After that, you can use DEVoutp() to write to Ports A and B. For example,

// write all 1's to Port A
DEVoutp(devnumber, 0x0, 0xFF);

// write all 1's to Port B
DEVoutp(devnumber, 0x1, 0xFF);
Back to top

Graphics Timing, Refresh Rate, Timer Resolution
# 5-100Items, Transparency, Order Of Items, Layers of Items
QuestionWe want to present an image in the center of the screen with an arrow overlaid on top of it. Then, a few milliseconds later we want to present two figures on either side of the first image, and we would like the first image and arrow to remain on the screen.

This is what I have tried to do.
  1. I made the first image’s item number the background in the condition file and made the arrow and the second image files different test numbers in the condition file. However, when I tried that, the background turned a very light color and the arrow and images appears with different backgrounds. The first image did not appear at all.
  2. Then I made the arrow and the first image’s item numbers, Test0 in the condition file. When I did that, only the face appeared. No arrow appeared. Can I make the images transparent, or layers?
AnswerOK, there are a couple of things going on here. First, there is the ordering that the items need to be presented. Then, there is the idea of transparency.

The background item is only used for the colors in the RGB columns of the items file. The actual item will not display. This is why, when you made the first image item the background item, it did not show up.

The order of the test screens and the order of the items within the test screens are important, if the timing file contains commands to display multiple test screens simultaneously. TEST0 will always be on top, followed by TEST1, then TEST2, etc. (That is, TEST0 will cover up everything below it.) Within the tests, the items are drawn in the order they are listed. That is, if TEST0 lists items 1,2,3,4 (in that order), they will be drawn in the same order (1,2,3,4). Item 1 will be on the bottom, and item 4 will be on the top. In other words, in your attempt #2, you need to check that the items in TEST0 are listed in the order: face item number, then arrow item number.

Next, there is the issue of transparency. For the DirectX receive program, transparency works with both .BMP and CTX image files. The background color as specified in the items file is used as the "source key" color. All pixels in the image that are this color (i.e., LUT entry #0), will be transparent when displayed in Cortex. The files \cortex\demos\dx\dxtransp.* show this effect nicely.

In other words, check the color of your background item. Any pixels that you want to be transparent in your bitmap, must be that color. For example, I can imagine that you would want all of the pixels surrounding your arrow to be transparent so that the image will show through at those places. Fiddling around with LUT values is easier with a CTX file, but transparency will work with BMP files too.
Back to top

# 5-136Changing Refresh Rate, Config, Graphics Card
QuestionWe need to be able to change the refresh rate of the monitor from trial to trial in Cortex. Can you help us with this?

My understanding is that cortex can currently adjust refresh rate based on the entry in the cortex config file, but that there is (currently) no way to do this from within the timing file. So, can such a timing file command be implemented?

Also, does the config file setting of refresh work with all graphics cards?
AnswerIn the current implementation of DirectX receive, there is no way to change the refresh rate of the monitor from trial to trial. The resolution and frame rate are initialized when Dxrecv.exe starts up. It is not done on-the-fly, and I am not sure that it even can be.

Since it is done upon initialization of DXrecv.exe, there can't be a timing file function to change it. This is because both the send and receive sides are up and running before you load and run your timing file.

The refresh that you specify in the cortex.cfg file does not work with for all graphics cards.
Back to top

# 5-152Refresh, Missing Frames, encode(), Gflush()
QuestionWe are doing an experiment at 160 Hz, and find that occasionally the monitor seems to drop a frame. As a result, we can briefly see two gratings that are counter-balanced so they (should) add up to be flat gray. We put time stamps in after each refresh, and we see the skipped frames.

If we could be 100% sure that we're catching all skipped frames, we could flag these trials and throw them out, but we're not convinced that we can tag them all.
AnswerIf there are encode() calls after all of the Gflush() calls, you will not miss any of the skipped frames. Gflush() won't return until the screen has been refreshed. All the lines in a timing file are executed. Therefore, if you have an encode() after a Gflush(), you should be able to just look at the timestamps on the encodes to see if there was a skip.
Back to top

# 5-161Encode(), Timing, Refresh
QuestionCould Cortex sometimes send an encode when the screen hasn't been refresh? Can we completely trust the encodes?
AnswerYes, encode() will correctly write a timestamp when it gets executed in the timing file. It really is a question about whether we can trust Gflush() to wait to come back to the timing file until it has completely finished the refresh. We are also relying on it to come back immediately after it finishes the refresh, and not lose any time. Cortex does not have any control over this other than calling the DirectX function that queries the "finished the refresh" state. If there is a problem with the DirectX function, there is really nothing that Cortex can do about it. It may be a graphics card/driver issue, since it really boils down to how the card's driver implements the function that I call to check the refresh. You might want to run the experiment on another setup that has a different card and see what happens. Also, does this happen at other refresh rates, or are you really pushing the limits of the card/monitor by trying to run at 160 Hz? What happens if you back down to 120 Hz or 100 Hz?

To determine if the problem is the card, the monitor, DirectX, etc., make the test program as simple as possible. In other words, loop a bunch of times with:
{ 
Gon_off(TEST0, ON); 
Gflush(1); 
encode(number1); 

Gon_off(TEST0, OFF); 
Gflush(1); 
encode(number2); 
} 
Of course, run with the photodiode attached if that is what you are using in the test. If that doesn't work, anything more complicated won’t work either.

Check that the refresh rate is set properly in both the cortex.cfg file, and in the Windows:DisplayProperties:Settings. Also, some graphics cards have their own driver program that sits in the task bar. Sometimes this can be used to set the refresh rate. It would be a problem if the driver program overrides the Windows setting, so make sure those settings are not being set somewhere else.
Back to top

# 5-164Changing Colors Rapidly, Switching LUTs, Changing Color
QuestionI have a question. I'd like to change colors of the items very rapidly within a trial and I was wondering which way would be the best. I'm going to randomly flash gratings with different orientations and would like to change the colors of them. I was thinking that I could either load 5 LUTs (one for each color) and then change the LUT active on each flash or load a single LUT (with the five colors) and change the index within the LUT in each flush. I don't know what if could be faster (I suppose the latter one) and how it could be done (I'm looking through the Function Reference on the website, but I don't really see how to change the index within a LUT). Any ideas?
AnswerI am not sure which way would be faster -- switching between LUTs or changing the colors. You would have to test it. There is no way to change the LUT indices that the item is using. (When you create the item, you assign the appropriate LUT index to each pixel.) The only thing that you can do is to change the color at the LUT index with GcolorABS(). GcolorABS() usually takes 1 refresh for each color change, so if you have a bunch of colors to change, it will take some time. Switching the entire LUT may be faster.
Back to top

# 5-166Precise Timing, Display Timing, Graphics, Moving Stimulus, Gmove()
QuestionI've recently been collecting some neuronal data using stimuli that require precise timing. What I'm doing is showing a given CTX bitmap file for 300ms, and then switching to a different CTX bitmap and showing it for another 300ms. I use histogram_Ctik to make a mark on the raster where the transition took place. I've been noticing that those marks don't seem to reliably occur at the same place. Also, I was trying a moving stimulus, basically a square that I moved with Gmove, and I placed histogram ticks where it started and stopped moving. These seemed to vary a lot in position as well.

This got me to wondering how precise the timing is within cortex. For instance, is there any way to tell that cortex missed a frame? Alternatively, do you have any estimate of how often cortex misses frame swaps.

The DXrecv.exe machine is a very fast P4 with a good graphics card, so the system speed shouldn't be an issue.

One option I'm considering is rigging up a photocell with an oscilloscope to measure the precise timing of various stimuli, but I'm hoping there might be something short of that I could do to learn how reliable and precise the timing is.
AnswerThe user interface portion of Cortex has the lowest priority, so it is not real-time. This is why the histogram tiks do not appear to coincide with the event. They just give you a general idea of when things happen.

The timing in Cortex is 1 ms. Reading the data acquisition board for spikes and eye data is the highest priority, and occurs at 1 ms timing. Execution of the timing file is lower priority, but should not be noticeably off from 1 ms. Displaying graphics to the subject can take a variable amount of time, depending on whether the command to draw the graphics to screen occurred at the beginning, middle or end of a refresh. This is because new graphics cannot be drawn until the beginning of a refresh. To get the timing, I usually just put an encode() before the Gon_off(ON)/Gflush() pair, and then an encode() after the Gon_off(OFF)/Gflush() pair. This will give you an idea of the timing, since the encode() will not be executed until the refresh has finished after the Gflush(). Your data file will contain the encode numbers with the associated time that it was written to file.

Frames should not be missed unless you have big images and/or your computer and graphics card are slow. You are correct. If you want to precisely detect the timing, the best way to do it is with a photocell and oscilloscope.
Back to top

# 5-167Separate Windows For Each Condition
QuestionIn VCortex 1.1 with Win98, is it possible to open one window for one condition, so that we can see the Spike data separated by condition? I want to have 10 windows for the 10 conditions.
AnswerNo, you cannot have plots of the spikes by condition. Cortex just plots the histograms for each trial, separated by the spike channel. That is, each spike channel will have a separate histogram, and the spikes for that will be accumulated in that histogram. Any other data analysis would have to be done offline, after the experiment is completed.
Back to top

# 5-177Time Between Trials
QuestionIs there a way to get accurate times between trials, such that I could relate events of the previous trial to the current trial. The main reason why I am asking is that I need to know what time is passing between trials.
AnswerThere is not a built-in way to get the time between trials. The time between trials is variable, since it when Cortex writes data to disk, and sets up for the next trial. However, there are a few things that you could try.

The first way would only work if the result could be in "seconds". You could put the function time() at the beginning and end of the trial. You could write the results of this function to an external text file. Then, you could compare the time of the previous end with the time of the next beginning. The problem is that the time() function returns the time as the number of seconds since Jan 1, 1970. Therefore, you would have to do some external processing to convert this time to a useful time/date. The C code to do this is:
        time_t seconds; 
        struct tm *current_time; 

        time(&seconds);  // get time in seconds from Jan 1, 1970 
        // convert to tm struct 
        current_time = localtime(&seconds); 

        // convert it to a string, and copy it into the return 
        // string 
        strcpy(timeStr, asctime(current_time)); 
If you need millisecond resolution of the time, then you will need to use an external clock system. You could use the DEVoutp() function in your timing file to send a digital output pulse to the external system. The external clock system would have to be able to interpret the pulse and record the time.
Back to top

# 5-187Graphics Card, VSG Graphics Card
QuestionHas anyone programmed up cortex to use the Cambridge Research VSG Graphics card?
AnswerI have not tried to use a VSG system with Cortex, but at one point, I was trying to support the VSG 2/3 card with Cortex. I ran into a bunch of problems with the board, so I never ended up using it. Granted, this was about 5 years ago, and a lot may have changed! I will attach my notes below, in case they may be useful to you or others.

I don’t know how communication with the VSG system usually occurs. If it will take serial input or digital pulses, you may be able to control it completely with your timing file (using DEVoutp() calls and/or Serial_*() calls). If anyone has done this, it would be a great contribution to the Cortex community. Please write back and let us know!

Here are my notes from when I was trying to use the VSG 2/3 card in the receive computer…..

Since the VSG board can only be programmed by its own proprietary library (and not by DirectX calls), it is necessary to write a new Windows receive program which supports the VSG 2/3 card using VSG Software Library version 6.07.

The program would be based on the DirectX receive program, but I would need to figure out how to do:
  • Writing to off-screen surfaces and flipping them
  • Using palettes
  • Controlling refresh rate and resolution
  • Using video memory vs. system memory
  • Filling vs. outlining objects
  • Transparency
  • BMP/CTX images, movies, sound)
On our VSG 2/3 board, we can have a total of 6 memory pages in which to draw: 4 video pages and 2 scratch pages. For Cortex, I need to draw to at least 11 pages for Cortex.

Here is some background info:
The way that Cortex works is that, before the trial starts, the desired test screens of images are drawn into ten off-screen memory surfaces (either video memory or system memory). Eleven surfaces are necessary... one to be the main drawing surface, and the ten others to be blitting onto the main drawing surface. Additionally, each test screen can have 16 items, which can be located anywhere on the screen, and can be any size, shape, and can even be bitmaps. The surfaces must be able to be presented in any order, and multiple times during the trial. I can not take the time during the trial to compose and redraw to a surface, since that would cause a delay in the presentation of the surface.

I wrote to the Cambridge Research Systems technical support, and found out that there are undocumented functions that write to PC memory (called "hostpages"), instead of just relying on the VSG on-board video memory. I wrote a simple application that creates 15 of these hostpages of size 1024x1024. I drew a small red square to each hostpage, and then flipped them into the video display page, one after another. The problem is that when I run this program for 30 seconds, I only see about 37 page flips with the host pages. The fact that it is going so slow that I can count them is a problem!! I would like these flips to occur at (or close to) the refresh rate of the monitor. When I run this same program just using the video and scratch pages, the flip is so fast it is practically a blur. However, there are not enough of the video and scratch pages on our board to just use those pages. On a related topic, I noticed in the documentation that the VSG 2/3 can have up to 68 MB of vsgVIDEOPAGE memory (i.e., the fast on-board memory pages). Obviously, our board only has 4 MB. It sounds like there are daughter boards that work with the VSG 2/3 to expand the memory. I wrote to Cambridge to ask about the slow hostpage problem and to ask if they still manufacture/sell these boards.

Here is what they wrote back:
First of all I am sorry to say that the reason your program is so slow is due to the communication bus speed between the VSGs ISA interface and your computer. At best this speed is 1.5 Mb per sec for a VSG2/3. Bearing this in mind, if you multiply the size of the vsgHOSTPAGE that you are blitting (in your case 1Mb) by 30 sec at best you can only expect approx. 45 frames. You then need to subtract the time taken to call all the other VSG function you may be calling (e.g. vsgSetDrawPage, vsgSetDisplayPage), Windows timing, and perhaps the time taken to call one or two other functions inside your program and the speed will drop down even lower i.e. too the 37 frames you are measuring.

Regarding upgrading the memory of the VSG2/3 to 68 Mb. We no longer have any stock of the 32Mb expansion cards needed for this. However, as we now accept trade-ins of older VSGs from people purchasing new VSG2/5 occasional these memory expansion cards do become available. There is however no real certainty as to when another one will become available.
Back to top

# 5-224Reading Rate
QuestionIn VCortex 2.0, can the reading rate be changed to a higher value than 1khz to 10khz , or this change is not working in this version?
AnswerChanging the reading rate from 1 kHz to 10 kHz does not work in VCortex.
Back to top

# 5-278Gsweep(), Move Fixation Spot, PLAYupdate_sweep_specs(), Gsweep(), Gpan(), Gscroll()
QuestionI am trying to set up a program, where I would like to move the fixation spot across the screen. Ideally I am searching for a function, where I can define the two points limiting the movement, starting point (i.e. left, center, right), speed and maybe velocity profile (i.e. linear or sinusoidal). I was trying to use Gsweep, but somehow this doesn't make me happy, because as far as I understand this function it does just present one trajectory, afterwards it needs to be called again with the opposite direction. Furthermore I can't define the two edges of the trajectory directly, but have to transform it into moving distance and duration. I noticed that there is a sweep option in Play Mode that could do exactly what I need. How could I use this within the timing file?
AnswerYou are correct. The timing file function Gsweep() does not give you the same options as the Play mode. Instead, the Play mode manually calculates the necessary parameters to give the bounce or wrap-around movement of the object. You will have to do the same sort of calculations in your timing file to simulate this movement. If you want to look at the Play code that does this, it is in \source\play\psweep.c, in the PLAYupdate_sweep_specs() function.

There are a few demos that have an object bounce around the screen. For example, look at the file \demos\dx\dxtransp.tim. Also, there are a series of graphics test timing files, gtest.1, gtest.2, gtest.3, and gtest.4, that do some strange things with Gsweep, Gpan, and Gscroll. But, of course, these demos manually change the direction angle inside a while loop, so that it appears to be bouncing around the screen.
Back to top

# 5-330Graphics Timing, Photodiode
QuestionHow do I ensure the correct timing of graphics?
AnswerThere are two ways to determine the timing of the graphics. The most accurate way would be to use a photodiode, and measure exactly when the graphics have changed. The second way is to put an encode() function into your timing file before and after the GFlush(1) call. The encode number will be placed into your output data file with a timestamp of when it was placed in the file. By subtracting the timestamps, you can determine how long each step is taking. A more detailed discussion follows.

When you are talking about vertical refresh and display synchronization, this is always an uncertainty...even with a DOS system. When a command is given to draw something to the screen, if the command arrives when the monitor is in mid-refresh, it will need to wait until the start of the next refresh to be drawn. This will cause some variations in the times of the display.

It turns out that it is common problem with all visual stimulus display systems, not just Cortex. I asked one Cortex user how he deals with it. He said that if you ask for an item to be displayed for exactly 500 ms, it may not be exactly 500 ms because of the monitor is refreshing at a rate of 17 ms. Therefore, in Cortex, he sees how long a 500 ms item is actually displayed using the photodiode and oscilloscope, and puts that number in the timing file. So, if it really only takes 486 ms, this is the number that he puts in for the display time instead of 500 ms. He implied that once he did this for the timing file, he did not have to do it again. That is, he did not re-synchronize everything every time he ran the timing file. I am not sure if the number is an exact multiple of the refresh rate. This makes sense because, for example, at 60 Hz refresh, there are 16.6666 milliseconds between refreshes. Therefore, if you use a whole number (16 or 17) for the multiplication, you are bound to get some rounding errors. Your safest bet is to use a photodiode and oscilloscope for calculating the timing for your specific timing file and items.

In Cortex, you will write a timing file to control when things are displayed during the experiment. The function Gon_off() is used to tell Cortex to display the image. However, the image will not appear until Gflush() is called. Gflush() flushes out the queue of graphics commands. If Gflush() is passed the argument "1", then the graphics are synched to the vertical refresh of the monitor, and Gflush() will not return until the image has been drawn. This is the closest you will get to controlling the vertical refresh.

If multiple graphics commands are issued, they are all placed in a queue. As soon as you issue a Gflush() command, Cortex tries to execute all of the graphics commands in the queue as quickly as possible, and synchronize with the refresh of the monitor. Therefore, if the graphics card, monitor, and DirectX can perform multiple Gon_off() commands within one refresh, then it will. I have found that certain graphics commands (such as, GcolorABS()) take one refresh each in DirectX. If you put a Gflush() after every graphics command, then each one will take one refresh, since it will do the operation and then sync with the next refresh. It is system dependent (i.e., dependent on your graphics card, monitor, and speed of your computer) how much can be done in one refresh. Therefore, you really will need to test it on your system to see how many commands you can group/execute together before issuing a Gflush().

Note that in the DirectX version of the receive program, Gflush(0) and Gflush(1) have the same behavior (i.e., they behave as if you have called Gflush(1)). When I was writing that version, I found that in a DirectX application, the vertical refreshing behavior cannot be changed dynamically. It must be set up during initialization. Since I figured that most people would want to synch with the vertical refresh, I made that the default behavior.

Another issue involved in graphics timing relates to playing movies. When playing a movie, it is essential that the refresh rate in the cortex.cfg file is the same as the refresh rate at which the monitor/graphics card is running. If the refresh rate is not the same in both places, you will get strange timing. This is because Cortex uses the value in the cortex.cfg file to figure out how many frames to show in the time specified in the movie commands. Therefore, if the times are not the same, you may get extra or less frames than predicted. By the way, using a movie is the best way to ensure that the timing between frames is accurate.

One thing that might cause you to lose a refresh is the characteristics of the image to be displayed. If the image is large, and you are trying to display it at a high resolution and a high color depth, the hardware may not be able to process the image within one refresh. In my testing, I have seen problems with such images when using a slow computer with a slow, low video memory graphics card. The problems usually go away when the computer is upgraded, or the image is reduced in some way.

Back to top

# 5-344Dual Monitors
QuestionDoes Windows Cortex provide the opportunity to generate output for two monitors. I am using a Matrox card with dual screen support and would like to generate stimuli separated for each eye. Is this possible with Cortex?
AnswerI have never tried to use a dual head graphics card, so I am not sure how it will work with Cortex. I did not write any special code to handle two screens, so I am assuming that you will get the same image on both screens.
Back to top

# 5-664Inter-trial Time, Speed
QuestionI have a question related to the inter-trial time...after a given trial how much time does cortex need to be ready for the next trial? Do I have to set a minimum inter-trial time?
AnswerThe inter-trial time depends on the capabilities of your computer. Between trials, Cortex stores the collected data to file and sets up the graphics for the next condition to be displayed. Therefore, if you have collected a lot of data, and you have a slow computer, it will take more time than if you don't have much data and have a fast computer. Similarly, if you are going to be displaying big complicated graphics (like a movie), it takes time to load it all into memory before the trial starts. Again, if you have a fast computer and simple graphics, it will be faster than if you had a slow computer.

There are no parameters that you can set to change the inter-trial interval. If you want to make it longer, you can put a wait at the top of your timing file before you display any graphics (i.e., set_timer() and timer_expired() loop), which will make it appear to extend the inter-trial interval.
Back to top

# 5-665Timing Resolution, set_timer(), timer_expired(), MS_TIMERset(), MS_TIMERcheck()
QuestionIs it possible to get sub millisecond timing resolution in the timing file (e.g. with MS_TIMERcheck)?
AnswerThe timers in Cortex (set_timer/timer_expired and the MS_TIMERset/check) only work on the millisecond level. There is a setting in the Run:Parameters:General called "TIMERrun_Hz" which supposedly can be used to program the system clock to different speeds. I have never successfully used any setting other than 1 Hz. But, you might want to play with that parameter and the "kHz resolution of data" parameter in the same menu. Let me know if you are successful, since others may have the same question.
Back to top

# 5-772Resolution, Graphics Card
QuestionIs it possible to use a resolution higher than 640x480?
AnswerYes, it is currently possible to use resolutions higher than 640x480. In fact, you should be able to use any resolution that is supported for your graphics card and monitor. Check the Windows Control Panel: Display Settings for the possible resolutions for your setup.
Back to top

# 5-900Multiple Fixation Windows, ITEM_POSeye_ishere(), get_fixation_state()
QuestionIs it possible to have two fixation windows? Is it possible to associate the fixation state with something other than the fixation spot?
AnswerYes, you can check multiple windows for fixation. However, you cannot use the built-in function get_fixation_state(). Instead, you will have to check the eye location with the function ITEM_POSeye_iswithin() or ITEM_POSeye_ishere(). If you are just interested in seeing if the eye is within a certain item, you can give the TEST screen number as the first parameter of this function. Otherwise, it is possible to set up eye windows of certain sizes and positions, which do not necessarily correspond to any item on the screen (i.e., it could be a blank area). You will need to use EYE_WINset() for this purpose, which I will describe below.

The usual method of checking the fixation state is with the get_fixation_state() function. It compares the current x and y analog eye position values (EOG_x and EOG_y) to the bounds of the fixation window. By default, the fixation window is a 1x1 dva square located around the center of the fixation spot. Its size can be changed through the Run:Parameters:General menu, or using the function set_fixwin_params().

Besides the fixation spot, the fixation window can be associated with other items. It can also be associated with "eye_wins" which are not linked to any items, and can be any location or size on the screen. The number of eye_wins is set in the EOG_MAPPING line of the cortex.cfg file. To set the size and location of an eye_win, you can use the Run:Parameters:Eye_Wins menu or use the function EYE_WINset(). To associate the fixation window with an item or an eye_win, you must use the function ITEM_POSbind_fixspot(). Then, you can use get_fixation_state() as usual to check if the subject has fixated.

In your timing file, you can use the EYE_WINset() function to assign a number to the eye window along with a location and size. For example, in your timing file, you would have the call:
EYE_WINset(1,0,0,1,1); 
This will create eye window #1, with a center at (0,0) and a size of 1x1. To check if the eye is within this window, you will need to call ITEM_POSeye_ishere(). You will also need to specify that you are checking an eye window, and give the eye window number. For example, the code will look like this:
If (ITEM_POSeye_ishere(EYE_WIN, 1)) 
{ 
   Mprintf(1, "eye is in the eye window"); 
} 
else 
{ 
    Mprintf(1, "eye is not in the eye window"); 
}
Back to top

# 5-995Refresh Rate, LUT, Grating, Latency, LUT, load_CLT()
QuestionI am trying to show very short stimulus at 120hz refresh rate. I want to show a moving grating, but the minimum time that I can get is approximately 40msec and I want 10 or 20. I am loading the stimuli and changing the LUT so it will be quicker but I cannot go below 40 msec. Is this possible? Another issue is that in longer latencies, it is not so accurate.
AnswerIt can be very slow to change the LUT to create moving gratings. Unfortunately, I don't have any code samples involving LUT animation and moving gratings. In any case, I can give you some general guidelines about what to do.

There are a few different ways to make moving gratings in Cortex. Underlying all the methods, though, is the creation of the grating image. Since you will have the most control over the colors and the LUT using a Cortex image format file, I would recommend using that format instead of a .bmp file. When you are creating your image file, make sure that you only use the top 128 entries of the color lookup table. This is because Cortex uses the lower 128 entries for the background, the fixspot, and generic item types (circles, squares, etc.) Also, when you are creating the image, try to minimize the number of colors that you are using. That is, if your grating is black-darkgray-lightgray-white-lightgray-darkgray-black, etc., do not use different LUT entries for the colors that repeat (i.e., black, darkgray, lightgray, etc.) For most cards while using DirectX, the more LUT entries that you change, the longer it will take to execute the changes.

Once you have created your image file, you have two basic ways of generating the moving grating illusion. The first way is to create a bunch of LUTs that can be cycled in sequence to generate the colors. The LUTs will need to be loading into Cortex using the LUT menu. Each LUT is assigned a number in sequence, as it is loaded into Cortex. Then, inside your timing file, you can make calls to load_CLT() to load the different LUTs. The load_CLT() function takes the LUT number as a parameter, so you will need to make sure that you have kept track of the LUT numbers as they were loading in with the menu.

The second method is to only have one LUT. Then, inside your timing file, change the colors contained in the LUT entry for lines of that color in the grating. The function that you would need for this is the GcolorABS() function. It takes the LUT entry number, and then the RGB values that the color should be changed into. GcolorREL() is a similar function, but instead of changing the color to an absolute color value, it adds the values that you provide to the current color. If you only have a few colors that you need to change, this can work well. However, as I mentioned above, the more colors that you need to change, the more delay you may have. In DirectX, for all the cards that I have tried, each GcolorABS() can take up to 1 refresh to execute. Therefore, you can see that it would significantly slow down the speed of the grating, if you were trying to change too many colors at once. The GcolorABS() and GcolorREL() function calls must be followed by a call to Gflush(1). If you want to try this method, I would suggest putting all the GcolorABS() calls in, and then following it by a single Gflush(1). This is because Gflush() makes sure the graphics are drawn and does not return until the refresh has occurred. If your card is capable of performing more than one color change per refresh, it will have the best chance this way. I have not tested this effect in a while, so maybe cards have improved for this.

The final method that I have seen for generating moving gratings is to just generate the entire moving grating sequence as a movie. Then, show the movie inside Cortex.

The DirectX receive program is running at a real-time priority (as high as Windows will allow) while a trial is running. The latencies that you are seeing are due to the capabilities of the graphics card and the driver that the manufacturer wrote to support DirectX.
Back to top

Keyboard, Mouse, Touchscreen, Joystick
# 6-015LED, Mouse Buttons, TTL output
QuestionWe want to use LED with some buttons (mouse-like or with TTL output). Can Cortex command the lights of LED and the button input? How many LEDs + buttons can Cortex command? Are nine buttons + 9 LEDs is fine for us and for Cortex?
AnswerYes, Cortex can command the lights of an LED and take button presses as input. Of course, you will need to program your timing file with DEVinp() and DEVoutp() function calls in order to collect the button presses and send out the LED commands. Cortex can control 9 inputs and 9 outputs as required by your experiment, but it would be easier to program if there were only 8 of each. This is because the input and output ports of the board are 8 bit ports. Therefore, it is pretty easy to send out (or read in) 8 bits at a time. If you were trying to control 9 bits, you would need to send out 8 bits on Port B, for example, and then one bit on a free line of the Port C. I guess you can see that this would be more confusing to write in a timing file!

There is one more thing that I should warn you about if you decide to use the LED lights for the stimulus. That is, it will be difficult to determine if the subject is fixating on a fixspot. This is because Cortex expects the graphics to be generated by the receive program on a normal display system. You can get around this by mapping the eye position and LED lights manually, however, it is not as easy as just calling get_fixation_state(). If you are not worried about fixation, you can ignore this issue.
Back to top

# 6-084Item Location, MousePressed(), MouseMoved(), GmoveABS(), GmoveREL(), DrawBox()
QuestionI learned how to use MousePressed() and MouseMoved() functions, however I would like to know if it is possible to graphically show the movement of the cursor on the screen. I imagine there should be a trick to show a stimulus at the coordinates corresponding to the position of the mouse, right?
AnswerYes, you are correct. The best way to track the mouse would be to create an item that you will use as the cursor. MouseMoved() will give you the deltax and deltay values of how the mouse has moved in the x and y directions. You would then use these values with GmoveABS() or GmoveREL() to move your cursor item to that location. I have never done this, so you might have to play around with it a little bit to get it to work. For example, I think the mouse parameters are in pixels, while the positions in the Gmove() functions are in degrees of visual angle. Also, the mouse parameters are "delta's", so they are given in how the mouse has changed since the last time the function was called, so they are not an absolute position. But, otherwise, this would be the best way to track the mouse on the subject's screen.

If you just want to just show where the mouse is on the send computer screen, you can just use DrawBox() with the mouse position. Refer to the demo files in \demos\touch3 of the Cortex release package.
Back to top

# 6-365Joystick, Visual Stimuli
QuestionI’m wondering if it is possible to use a joystick under the control of Cortex? Is it possible to display the moving cursor superimposed on visual stimuli so that the subject can see the track of the moving joystick? The setup I have in mind would consist of two computers, one to display the stimuli and the joystick cursor and one to control the experiment. The control monitor should consist of the targets, the eye-position, joystick-track and the fixation-windows. The joystick itself can be anything that is moveable in two dimensions.
AnswerYes, it is possible to use a joystick under the control of Cortex. However, the difficulty level of implementing such an experiment depends upon the input that the joystick is able to provide to Cortex.

By default, Cortex has functions to read the keyboard and mouse. It can also read serial devices, touchscreens, digital inputs, and analog inputs. If the signal output from your joystick device can be mapped to one of these types of inputs, then it is possible to use it with Cortex. However, since there are no built-in functions in Cortex for explicitly supported a joystick device, there will be an amount of programming that you will need to do in your timing file to implement it.

After you have read the input from the joystick device, it is pretty straightforward to implement the moving cursor. For each condition, you would have an item defined for the ‘cursor’ image. As the joystick device is sampled, you would use the joystick’s position data as a parameter into the GmoveABS() function, to move the item to that location. Again, however, the difficulty here would be in converting data from the joystick device into degrees of visual angle. You may find that the joystick returns values on a different coordinate system than is used by Cortex, so some calculations will probably need to be made.

Back to top

# 6-454Keyboard
QuestionIf I use a keyboard for the subject’s response, can I somehow make two keyboards work with the send computer?
AnswerNo, the computer can only handle one keyboard at a time, so that is all Cortex can handle too. Usually, you would only expect a trusted human subject to use the keyboard. Therefore, you would start the trials running, and then you hand the keyboard to the subject. If you can't trust the subject, then this won't work, and you will need to build a button device for inputs from the subject.
Back to top

# 6-480KeyPressed(), GetAKey()
QuestionIs it possible to detect a release of a Key Press?
AnswerThe KeyPressed() function checks if a key is waiting in the keyboard buffer, which means that at some point a key was pressed. Once the key is removed from the queue with GetAKey(), KeyPressed() will not be true until another key is pressed. Therefore, you could do something like call KeyPressed() and GetAKey() until these functions do not return a key. Then you would know that the key had been released. I will warn you that the keyboard processing in DOS is very slow (55 ms), so if you need a very accurate time for key release, this will not be a good way. A better way for time critical stuff is using the digital lines with a button device.
Back to top

# 6-657Windows Cortex, Touch Screen, Read and Write Ascii
QuestionI am about to start a new program for training a subject with Cortex. I will need to read/write ascii to disk, use a touch screen, but not much else. Can the new Windows Cortex handle it?
AnswerYes, the touchscreen works in version 1.1 and 2.0 of VCortex. Reading and writing to ascii files with fopen/fclose/fprintf/etc. works, too.
Back to top

# 6-854Keyboard Problems With VCortex
QuestionI recently noticed a minor problem with the windows cortex version. Sometimes it occurs, that the keyboard is not read correctly when entering values into the menus. This problem could be related to the fact that I am using the keyboard within my timing file.
AnswerWe have found several keyboard problems in VCortex 1.0, 1.1 and 2.0. We have made a bunch of fixes to the keyboard processing, which are available in VCortex 2.1 and soon in 1.2.
Back to top

# 6-932Touchscreen, Microtouch, Elo
QuestionCan we use a touch screen other than the Microtouch touchscreen?
AnswerI have only tested Cortex with a Microtouch touchscreen. This is why the Cortex User's Manual recommends that you use a Microtouch. A few years ago, I helped someone who had an Elo touchscreen. It had its own Elo driver, which converted the touches to serial mouse inputs like the Microtouch driver does. It took a little bit of experimentation to get it to work with Cortex, but we did get it to work. The Elo driver for the Elo touchscreen had some utilities to test the touchscreen. The utilities allowed us to print out the touch locations to the screen, so that we could tell what it was returning. As I recall, there was also a configuration tool that allowed us to specify the range of the output values. To see what Cortex thinks it is getting for values, run one of the touch demos. Use the cortview.exe program to see the values that are stored in the TOUCH array and the EPP array. If they are all 0's (or all the same values no matter where you touch on the screen), something is definitely wrong.
Back to top

# 6-989Joystick, get_bar_state(), PCI-DAS1602
QuestionI am trying to get a joystick device to work in cortex. My joystick is a simple digital 4-way switch for the up, down, left, right directions. I have wired it so that the up and down directions are hooked up together and the left and right directions are hooked up together. This gives me a voltage reading of 5V in the center and 0 when I move in any direction. I was planning on putting the output of the left/right into the bar left/right pin of my PCI-DAS1602/12 board and the down/right output into the bar up/down pin. However, I’m not sure how to set up cortex so that it recognizes left from right and up from down.
AnswerYour wiring scheme sounds correct. That is, you could use the PCI-DAS1602 pins (#69, 70, and a ground of 89) to wire up the joystick. The get_bar_state() function queries these pins and returns different values. If the Options:General_Parameters: More_Misc: Detect_bar set to bar up/bar down, then bar state returns 0 for bar up, 1 for bar down. If the option is set to bar left/right, it returns 1 for bar_centered (neither left nor right) 2 for bar_left, 3 for bar_right, and 4 for bar extra. Having said that, I hate to say this, but in the last few weeks, we found a bug in the get_bar_state() for VCortex 2.0. Therefore, if you have tried get_bar_state() in VCortex 2.0, then that is the reason that it is not working. This bug has been fixed in VCortex 2.1. Otherwise, since you have somewhat of a custom device, you might want to call DEVinp() to query these pins directly in your timing file.
Back to top

Movies, Bitmaps, Color
# 7-035Bitmap, BPP, LUT, Config, Displaying Items, Photoshop
QuestionI am trying to display bitmap images in Cortex 5.9.5. My images are 24 bits per pixel, because Photoshop won’t save them as anything else, but I can’t configure Cortex to do 24 bpp. In my cortex.cfg file, it says bpp can be 1, 2, 4, 8, 16, 24, or 32. However, when I change it to 16 or 24, it won’t compile, and shows a message saying that bpp can only be 1, 2, 4, 8, or 32. When I use 8 or 32 bpp in the .cfg file, the images are really poor quality. Is there a way for cortex to do 24 bpp? Is this what I need to do in order for the images to look right?
AnswerThe GRAPHICS_SPECS line should allow you to set the bits per pixel to 24. There was a bug in the error message, where it says that bpp can only be 1, 2, 4, 8 or 32. This bug has been fixed since the DOS Cortex 5.7.9 version. I just looked at the code, and the 16 and 24 cases are available to use, so that should not be the problem.

I think the problem is that your graphics card and monitor cannot support this setting. To check which modes are supported, right-click on the Windows desktop of the receive computer, and choose Properties: Settings. If your graphics card is like mine, it can only support 8, 16, and 32 bits.

Assuming that your computer setup cannot support 24 bpp, you will need to choose from the other possibilities.

If you want to use 8 bpp, in the graphics program that is used to create the images, the images should be saved in RGB Color and 8 bits per channel. (In Adobe PhotoShop, these settings can be made in the Image: Mode menu.) Also, Cortex requires a color look-up table to correspond to the colors used in the image. (I assume that you are trying to use Windows .BMP files?) If a LUT is not specified in the conditions file or loading through the LUT menus, the image will be displayed in black-and-white, or maybe even in a default LUT from the graphics card. It is therefore recommended to create a default LUT that contains the Windows system palette, for example, for use in 8 bpp. At greater than 8 bpp, the images will look fine, and will not need/use the Cortex LUT. There is a utility program, bmp2lut.exe, which extracts the LUT from a .bmp file. It is available "as-is" from the Cortex web site (at www.cortex.salk.edu).

The 32 bpp should be the closest to the original image, since it is using the internal color lookup table in the image file. I am not sure why the colors would look bad at 32 bpp, unless you are trying to display more than one image at a time, which uses a different lookup table.
Back to top

# 7-326Bitmaps, Error files
QuestionWe are having a problem where we randomly get the error message "CAN’T CALCULATE ITEM SIZE" or "CAN’T DRAW OBJECT" followed by "CAN’T CREATE TESTX" and nothing is displayed on the screen. This does not happen immediately, but usually after running the program (with the same bitmaps) a few times each with a different subject.
AnswerOne thing that you can check is the .err file in the directory from which you are running the receive program. That is, for the Rvesactx.exe program, there will be a file called rvesactx.err in the \remote32 directory of the receive computer. For the Dxrecv.exe program, there will be a file called dxrecv.err in the \wcortex directory of the receive computer. There may be an error written to this file stating why the bitmap could not be displayed. The file is overwritten each time Cortex is started, so you will have to make sure that you re-run the error-generating scenario to see if an error message is generated.

Another thing that you may want to do is create a very “bare bones” timing file that simply displays the bitmaps one after another. In other words, take out complications like fixation, error cases, etc. Since the problem occurs after so few trials, it should be possible to reproduce it without too much trouble. If the problem does not occur when simply displaying the image, then it suggests that there may be some other problem with the timing file.
Back to top

# 7-496Movie, Frames, Gmovie()
QuestionWhy don’t the frames advance when I play my movie file?
AnswerThere are a few things that you can check. In your timing file, make sure that the “next_frame” parameter for the Gmovie_step() function is not set to 0. If it were set to 0, the movie would stick with the first frame, because you are telling it that the next frame is 0 (i.e., always the current frame) and it will not advance. If you change that parameter to 1, it plays the movie. This is true for Gmovie and Gmovie_step.

Run the following little timing file on your computer. If it doesn't work on your computer, there may be a problem with the copy of the movie file. For example, I've seen problems where it sticks on the first frame if the number of frames listed in the header doesn't agree with the number of frames in the movie.

Here is the timing file for testing. It should put the first frame up on the screen for 1 second, and then play the movie for 5 seconds.
#include "css_inc.h" 

main() 
{ 
  long    start, stop; 
  long    total; 
  long   count; 

  count = 0; 

  Gmovie_step(TEST0, 0, 1); 
  Gflush(1); 

  set_timer(1000); 
  while(!timer_expired()); 

  set_timer(5000); 
  while (timer_expired() == 0) 
  { 
     Gmovie_step(TEST0, 1, MOVIE_STEP_WRAP); 
     Gflush(1); 
     count++; 
  } 

  Mprintf(2,\"count: %ld\", count); 

  Gon_off(TEST0, OFF); 
  Gflush(1); 
}
Back to top

# 7-787Movies, Frames, Config, Gmovie()
QuestionIs it possible to show a movie at 1 frame per second? I am trying AVI movies and they are running too fast and cortex is not responding to changes in the config file.
AnswerThe frames-per-second setting in the cortex.cfg file is used to tell Cortex the refresh rate that you are using on your monitor/graphics card. If you check the refresh rates possible for your system (right click on the Windows desktop, choose Properties; Settings; Advanced), you will see that 60 Hz is probably the lowest refresh rate possible.

Luckily, the Gmovie() function in Cortex has a parameter called “pause_each_frame”, which can be used to keep a certain frame on the screen for a given number of refreshes. Knowing your refresh rate, you will need to calculate how many frames to pause to set this parameter, so that you will get 1 Hz (i.e., the parameter would be 60 if you are running at 60 Hz, etc.).
Back to top

# 7-958Movie Size, Memory
QuestionWhen Cortex loads a movie does it load the entire movie to the memory or just chunks of it to the buffer. It looks like it is having a problem loading big movies (i.e. 300-600 frames) and I don’t know if it will help if I will use a 256mb graphics card or that you have a better solution.
AnswerYes, you are correct. When you display a movie in Cortex, it reads all of the frames of the movie into memory. Then, if you want to loop through the movie for a specific period of time, it just uses the memory copy to play over and over again.

Cortex uses the video memory on the graphics card first. If this memory fills up, then it will use the system memory. As you might expect, it will be slower if it has to swap the graphics in and out of system memory, instead of the memory on the graphics card itself. Therefore, it would help to have a graphics card with a lot of onboard memory.

Refer also to the Troubleshooting section of the Cortex User’s Manual in the section entitled “Display of movies is slower than the refresh rate of the monitor/graphics card”, for more information.
Back to top

Timing Files, Trial Setup, Blocking
# 8-048random(), timer(), srand(), plong timer, time_t
QuestionI need to generate a seed for the random() function by using srand(). If I use the time() function as the argument for srand(), can the “time_t” structure be recognized? What is 'plong timer'?
AnswerSince the Cortex compiler does not recognize C "struct" types, the time_t structure could not be used in the time() function. Therefore, I had to rewrite it to use a "plong". The "p" tells Cortex that it is a pointer. So, in this case, it is a pointer to a long integer. The following is a sample timing file.
#include "css_inc.h" 

main() 
{ 
     int testnum; 
     long current; 
     int i; 

     // seed the random number generator once 
     srand2(time(¤t)); 

     for (i=0; i<10; i++) 
     { 
            testnum = random(0, 3); 
            Gon_off(testnum, ON); 
            Gflush(1); 

            set_timer(1000); 
            while(!timer_expired()); 

           Gon_off(testnum, OFF); 
            Gflush(1); 
      } 
} 
When I tested the random number generator functions, I just used a timing file like the one above. That is, I seeded it every trial, and the numbers are different each time, as expected. Since you may only want to seed it for the first trial, You could rewrite the timing file as follows:
if (get_trial_num() == 0) 
{ 
      srand2(time(¤t)); 
      Mprintf(1, "called srand2"); 
} 
...the rest of the timing file is the same.....
Back to top

# 8-078random(), rand2(), rand()
QuestionIs there a problem with the random function?
AnswerThe random functions have always been a huge source of confusion, since there are a bunch of them available. I sat down one day and finally figured out how they work. It turns out that they are paired as follows:

The random() function must be seeded with srand2().
The rand2() function also must be seeded with srand2().
The rand() function is internally seeded inside Cortex, but may be seeded in a timing file with srand().

Instead of using the random() function, try using the rand() function. The rand() function is seeded automatically when Cortex starts up, using the time and the srand() function. The rand() function does not take any parameters, and returns a number between 0 and 32767. Therefore, to get a number in a certain range, you will have to use the modulus operator. For example, to get a number between 0 and 9, put the following line in your timing file: x = rand() % 10;

Another option, if you want to control the seed yourself, is to use the paired functions srand2() and rand2() (or srand2() and random()). For some reason, the original authors of Cortex thought that these functions generated better random numbers. I enabled users to put these functions into their timing files in the 5.9.1 release of Cortex.

The random() and rand2() functions are not "seeded" internally. Therefore, every time that you started running Cortex, it would generate the same pseudo-random set of numbers each time. There is a function called srand2(), which takes an input value to use as a seed. srand2() only needs to be called once at the top of your timing file. The tricky part is that if you give it the same seed value (i.e., if you hardcode it to srand2(50);, for example), then random() will still generate the same set of numbers each time. One way to get around this is to call the time() function, which returns the elapsed seconds since midnight of Jan 1, 1970. Since this will be different each time the function is called, you can use it as a seed. Just put in the statement: srand2(time()); once inside main() in your timing file."
Back to top

# 8-111EYE_WINset(), Screen Coordinates, ITEM_POSbind_fixspot, ITEM_POSeye_ishere()
QuestionWhen I define a window like EYE_WINset(1,-14.6,0,1,1); I would like it to be centered on an item as specified in the item file which is centered at (-14.6, 0) This doesn't happen. The window, that I draw using SCREENdraw_fixwin (int color) appears to the right of the center. Do the two functions use different coordinates? Is it something related to the parameter of the EOG_MAPPING < minV > < maxV > < ManualDVA? > in the cortex.cfg?

In order to check the eye position (even though I would like to use a static window) I have to use the function ITEM_POSbind_fixspot() to link my window to the checking function ITEM_POSeye_ishere. Is this normal or did I make a mistake? Do I have to say ITEM_POSeye_ishere(BOUND_FIXWIN,1) instead of ITEM_POSeye_ishere (EYE_WIN,1)?
AnswerIf you want to have multiple eye windows during the trial, you should just be able to set them with EYE_WINset(), and then use ITEM_POSeye_ishere() to see whether the eye is in the window or not. If you use ITEM_POSeye_ishere(BOUND_FIXWIN,1), you will need to use ITEM_POSbind_fixspot(EYE_WIN, 1) to first make it the bound fixwin. From the Cortex code, it does not look like you need to make it a bound fixwin. You should just use ITEM_POSeye_ishere(EYEWIN, 1).

If you want to make it a bound fixation window, you need to use ITEM_POSbind_fixspot() for the EYE_WIN. Since SCREENdraw_fixwin() only draws the fixation window, and you have not called ITEM_POSbind_fixspot(), it is probably just drawing some default location of the fixation window. For example, it may be a 1x1 dva box centered at the origin. Or, if you are using Run: Parameters: General: Dynamic fixwin size = YES, then the fixation window will be the size/location of the item which is specified as your FIX_ID in your conditions file.

To see what is going on, you may want to put in some calls to ITEM_POSget() to see where Cortex thinks the eye window is located. For example, try something like this:

float xcenter, ycenter, xsize, ysize;
ITEM_POSget (EYE_WIN, 1, &xcenter, &ycenter, &xsize, &ysize);
Mprintf(1, "xcenter = %f, ycenter = %f, xsize = %f, ysize = %f", xcenter, ycenter, xsize, ysize);

If the results that are printed on the user area of the screen are not what you expect, then there is something happening in your timing file or settings.
Back to top

# 8-133Gsweep(), Moving Item, Gmove()
QuestionI would like to sweep an item in a constant motion across the center of the screen, and I am trying to use Gsweep(). However, my circle is not sweeping. It is just moved in one step to the direction I specified by a fraction of a degree of visual angle. Then it stands still.

As far as I can see, there are no problems with the configuration of cortex or conflicts of any hardware, since other graphics routines, like playing a movie or Gmove(), are working fine. Do you have any ideas?
AnswerYes, Gsweep() is the function that you should use. The problem is that you need to call Gflush() to display each frame along the sweep path. It works just like Gmovie(), if you have ever used that. There is a little bit of inf