Technical Note : SLE0002
Author : Scott Evans
Created/Modified : 7/9/97
Description : The display and drawing environments
 
This document describes the Yaroze display and drawing environments. Both the display and drawing environments can be manipulated using the structures DISPENV and DRAWENV and the functions PutDispEnv() and PutDrawEnv(). 

The Display Environment 

The display environment is used to define the area of VRAM that is to be displayed on your TV screen. The disp member of the DISPENV structure defines the rectangular area that is used as the display. The disp member is a RECT structure and its members define the actual display area of the VRAM. The display area can be located anywhere in VRAM but it usually has its top left corner at (0,0). What ever is in this rectangular area will be used as the image that appears on your TV screen. 

The screen member (another RECT) is used to position the image in the display area on your TV screen. So if your screen area starts from (0,0) and is the same width and height of the display area then the image displayed on your TV will start from the top left corner of your TV and display the whole of the display area. If you move the screen origin to say 16,16 (screen.x=16, screen.y=16) then the image on your TV will be appear to be shifted down and right by 16 pixels. The width and height of the screen area controls which area to fit the final image into. For instance with PAL you get a screen height of 256, so if you set screen.h to 256 you get a full screen image. 

The isinter member is used to set or clear the interlace mode flag. If isinter is 1 then interlace mode will be used. If it is 0 interlace mode is not used. If your display height (disp.h) is 480 (512 in PAL) then interlace mode is used regardless of the value of isinter. 

In interlace mode you can use higher resolution displays (for example the NTSC screen mode 320,240 can be doubled if using interlace mode (640,480). When using interlace mode you must take note of the following. 

You only need one screen buffer. The display and drawing areas are defined using the same rectangular area in VRAM. This is because when in interlace mode the even lines are displayed in the even field and the odd lines are displayed in the odd field. So when drawing the even lines the odd lines are displayed and likewise when the even lines are displayed the odd lines are drawn. This has the effect of producing its own screen switching so there is no need for two buffers or for you to switch screens in the program. 

You also need to set the dfe flag (dfe=0) in the DRAWENV structure to allow drawing in the display area (see the drawing environment section for more details). 

The contents of VRAM is made up of 16 bit pixels. With each pixel split into 5 bit RGB values and 1 bit for setting transparency. There is also a 24 bit mode where 24 bits are interpreted as a single pixel and each colour component (RGB) has 8 bits. The isrgb24 flag is used to set these different modes. When in 16 bit mode isrgb24 should be 0 and when in 24 bit mode isrgb24 should be 1. 

The pad0 and pad1 members are reserved by the system. Whether they will be used in the future who knows but what they do now is ensure the structure is aligned on a 4 byte boundary. You must make sure that all structures are on 4 byte boundaries since a word on the R3000 is equal to 32 bits not 16. 

The Drawing Environment 

The drawing environment defines the area of VRAM, which is used for drawing (building the next frame). The clip member of the DRAWENV structure defines this drawing area. No drawing can be done outside of the clip area. Again this area can be located anywhere in VRAM but it is usually placed physically below the display area. For example if the display area is defined by (0,0,320,240) then the drawing area is usually defined as (0,240,320,240). 

The ofs array gives the x and y offsets to the drawing area. So for one frame the offsets will be (0,240) and the next frame they will be (0,0). These values are added to drawing primitives before they are drawn so they are drawn in the correct area of VRAM. 

The tw member defines a texture window on the texture page specified by the tpage member. The texture within this window is used repeatedly during texture mapping. 

The tpage member sets the default texture page to be used. A texture page contains textures, which can be mapped onto sprites or polygons. A texture page is a rectangular area in VRAM which is 256x256 pixels in size. The x co-ordinate must be a multiple of 64 and the y co-ordinate must be a multiple of 256. This is used for primitives that do not have a tpage member (Note, this feature is not included with the Yaroze but to be complete I thought I would mention it). 

The dtd flag is used to select dithering while drawing. If it is set to 1 then dithering will be performed while drawing. If it is 0 then no dithering is performed. 

The dfe flag as mentioned earlier can be used to allow drawing in the display area. Normally you do not want to allow drawing in the display area, as this would cause problems with the display. In interlace mode on the other hand you have to allow drawing in the display area since both the drawing and display areas use the same rectangular area in VRAM. In the manual it states a value of 0 blocks drawing and 1 allows drawing. This is no correct a value of 0 allows drawing and 1 blocks drawing. 

The isbg flag when set will clear the drawing area with the colour given by the r0, g0 and b0 members when the drawing environment is set. If  it is not set then the drawing area will not be cleared when the drawing environment is set. If using the PutDrawEnv() functions to swap buffers then you can use this flag instead of using the GsSortClear() function to clear the screen. 

The dr_env member is a DR_ENV structure that is a low level primitive, which can be used to set the drawing environment while drawing an ordering table. A DR_ENV primitive can be linked to an ordering table so while drawing is taking place the environment can be changed. Again this is not part of the Yaroze libraries so ignore this bit. 

Setting up a display and drawing environment 

There are two ways you can set up and manipulate the display and drawing environments. You can use the high level functions GsDefDispBuff() and GsSwapDispBuff() or use the lower level functions PutDrawEnv() and PutDispEnv(). 

The Gs functions are the easiest to use. 

To define the display and drawing environments you use the function GsDefDispBuff() as follows. 

GsInitGraph(screenw,screenh,.); 
GsDefDispBuff(dispx,dispy,drawx,drawy); 
 
This creates two screens one at (0,0) to (screenw,screenh) and the other at (0,screenh) to (screenw,screenh*2). The GsInitGraph() function is called to set the screen width and height. 

You can the swap between these screens using the GsSwapDispBuff() function. 

To use the PutDrawEnv() and PutDispEnv() functions you first need to define a drawing and display environment like this. 

DRAWENV drawenv[2]; 
DISPENV dispenv[2]; 

All you need to do now is set up these environments by setting the members to the values required by your program. Notice there are two display and drawing areas this is because you use a double buffer. 

Once you have defined the display and drawing areas for each buffer you can use the PutDispEnv() and PutDrawEnv() functions to swap buffers 
 

Example programs 

See the double buffer example program listings for examples of both above techniques of manipulating the drawing and display environments. 
 
Double buffering example 1 (uses high level graphics functions) 
Double buffering example 2 (uses mostly low level graphics functions) 

Interlace mode example 

This document in word format. 
This document in text format.