currier@romeo.cs.duke.edu (Bob Currier - DCAC Network Comm. Specialist) (08/14/89)
Greetings, This weekend, while noodling around with animation, I came across a most puzzling phenomena. My graphics displayed fine while on the lower part of the screen (I am using a monochrome 1040), but when my little critters got about 30 or 40 pixels from the top they started to get a bad case of the flickers. I was using Vsync() to control flicker, and it seemed to work well, except for this twilight zone. I pulled my hair out for a couple of hours on this one, dug thru all my books, and finally, at about 1 a.m., in the premier issue of START, found a comment in an article about al graphics that went like this: "...vsync, but you will still see flicker near the top of the screen. This is a problem that can only be dealt with by very complex multiple screen flipping techniques..." So, does anyone know of this problem? What causes it? And, Virginia, how can I eliminate it? Bob Currier currier@romeo.cs.duke.edu rdc@northlab.ac.duke.edu
leo@philmds.UUCP (Leo de Wit) (08/15/89)
In article <15286@duke.cs.duke.edu> currier@romeo.cs.duke.edu (Bob Currier - DCAC Network Comm. Specialist) writes: |Greetings, | |This weekend, while noodling around with animation, I came across a |most puzzling phenomena. My graphics displayed fine while on the |lower part of the screen (I am using a monochrome 1040), but when |my little critters got about 30 or 40 pixels from the top they |started to get a bad case of the flickers. I was using Vsync() to |control flicker, and it seemed to work well, except for this |twilight zone. | |I pulled my hair out for a couple of hours on this one, dug thru all |my books, and finally, at about 1 a.m., in the premier issue of START, |found a comment in an article about al graphics that went like this: | |"...vsync, but you will still see flicker near the top of the screen. This |is a problem that can only be dealt with by very complex multiple screen |flipping techniques..." | |So, does anyone know of this problem? What causes it? And, Virginia, how |can I eliminate it? My name is not Virginia, Bob, but I still think I can make some sensible remarks about this one. Flicker is caused by updating the physical screen, that is: writing to the physical screen in some way. Most often one erases part of the screen, then draws on the erased part; at the same time this part of the screen is being read by the video stuff. Most animations use a separate screen to draw in, then as the picture is complete, swap the screens. All GEMDOS, (X)BIOS and GEM functions that deal with graphics (including characters) are being drawn on the logical screen (a chunk of 30000 bytes of memory pointed to by a system vector, 0x44e if my memory is OK 8-). The physical screen location is determined in two I/O addresses (it always starts on a 256 byte boundary). For reading the screen 3 I/O addresses are being used; they correspond to registers in the shifter (an ST custom chip for the video stuff). After each VBL these addresses are reinitialized from the two 'physical screen start' I/O addresses (this is also the reason that, though you could alter the physical screen start between VBL's (the XBIOS function Setscreen() does this), it can only take effect at the moment of the next VBL (the 3 I/O addresses for reading the screen are read-only). The Vsync() is not totally unuseful: it synchronizes your software with the VBL, that is, you know that after a Vsync() statement the shifter reads at the top of the screen (so at that moment avoid updates there). You could do updates to the lower part of the screen, or use a timing loop so you know the shifter already has had the upper part. Alternatively you could read the 3 I/O addresses (in supervisor mode, of course) to determine where the shifter is currently reading; in this case you don't need the Vsync(), which really can speed things up (I know, I did this myself). The most commonly used technique is to use two separate screens, one as the physical screen, one as the logical (as mentioned above), draw your stuff on the logical one, then use Setscreen to swap the screens. Now you must do a Vsync() before any new updates of the (new) logical screen, because remember until VBL it is still the old physical screen, which is being read by the shifter. This technique is guaranteed to be flicker-free, and, as opposed to what was possibly mentioned in START, is not difficult at all. A third technique is a somewhat more complicated variant of the second one. Its main idea is to use several screens (more than two) to avoid using Vsync(), thus gaining in speed. You use the screens alternatively: screen1 physical, screen2 logical screen2 physical, screen3 logical etc. screenn physical, screen1 logical screen1 physical, screen2 logical etc. The number of screens to use depends on the speed with which you can draw a new image on the logical screen. Since a physical screen remains fixed for at least one VBL period, doing the cycle of n screens must take at least one VBL. Since it doesn't make sense to swap screens a lot during a VBL period (only the last one takes effect) and it DOES take some time in general to redraw your screen, a useful number of screens is 3. Hope this helps - if you need the exact location of the I/O addresses I can look it up for you. Leo.