gSPBgRectCopy [Macro]


Renders background image (BG)


#include <ultra64.h>        /* gs2dex.h */
gSPBgRectCopy(Gfx *gdl, uObjBg *bg)
gsSPBgRectCopy(         uObjBg *bg)


the display list pointer.
the pointer to the BG drawing data structure.


This macro is the dedicated BG image drawing macro for use in copy mode. It has the following special features and limitations:

The greatest advantage of this macro is that it offers the fastest drawing speed, since it assumes that drawing is being performed in copy mode. Accordingly, in order to use this macro the cycle type must be copy mode. For information about modes, see Section 2.2.7, "Drawing Cycle Modes" in the N64 Kantan Manual. For information about setting the cycle type, see gDPSetCycleType. If you want to enlarge or reduce an image, use gSPBgRect1Cyc. For additional details, please see the latest readme for S2DEX microcode Section 4.1, "BG Drawing GBIs".


It is allowable for the BG image to be larger than the transfer frame. However, operation cannot be guaranteed if the transfer frame is larger than the BG image. Make sure that the transfer frame is not larger than the BG image.

The right and left ends of the BG image are connected in the y-direction with a one-step shift. That is, the pixel to the right of the right-edge pixel (imageW-1, n) of the BG image becomes (0, n+1). This is necessary to boost RDRAM access efficiency when loading a texture. For information about the uObjBg structure, see the Comment section below.

Also note that operation is not currently guaranteed for G_IM_FMT_YUV (YUV format).


The uObjBg structure is shown below:

typedef struct {
  u16 imageX;     /* x-coordinate of upper-left position of texture (u10.5) */ 
  u16 imageW;     /* Texture width (8-byte alignment, u10.2) */
  s16 frameX;     /* x-coordinate of upper-left position of transfer destination frame (s10.2) */
  u16 frameW;     /* Transfer destination frame width (u10.2) */

  u16 imageY;     /* y-coordinate of upper-left position of texture (u10.5)  */ 
  u16 imageH;     /* Texture height (u10.2) */
  s16 frameY;     /* y-coordinate of upper-left position of transfer destination frame (s10.2) */
  u16 frameH;     /* Transfer destination frame height (u10.2)  */

  u64 *imagePtr;  /* Address of texture source in DRAM */
  u16 imageLoad;  /* Method for loading the BG image texture
                     G_BGLT_LOADBLOCK (use LoadBlock)
                     G_BGLT_LOADTILE (use LoadTile) */
  u8  imageFmt;   /* Texel format
                     G_IM_FMT_RGBA (RGBA format)
                     G_IM_FMT_YUV (YUV format)
                     G_IM_FMT_CI (CI format)
                     G_IM_FMT_IA (IA format)
                     G_IM_FMT_I (I format) */
  u8  imageSiz;   /* Texel size
                     G_IM_SIZ_4b (4 bits/texel)
                     G_IM_SIZ_8b (8 bits/texel)
                     G_IM_SIZ_16b (16 bits/texel)
                     G_IM_SIZ_32b (32 bits/texel) */
  u16 imagePal;   /* Position of palette for 4-bit color 
                     index texture (4-bit precision, 0~15) */
  u16 imageFlip;  /* Image inversion on/off (horizontal direction only)
                     0 (normal display (no inversion))
                     G_BG_FLAG_FLIPS (horizontal inversion of texture image) */

  /* The following is set in the initialization routine guS2DInitBg */
  u16 tmemW;      /* TMEM width for one frame line (word size)
  u16 tmemH;      /* TMEM height for a single load (quadruple value, s13.2)
  u16 tmemLoadSH; /* SH value
  u16 tmemLoadTH; /* TH value or Stride value
  u16 tmemSizeW;  /* imagePtr skip value for one image line
  u16 tmemSize;   /* imagePtr skip value for a single load */
} uObjBg_t;       /* 40 bytes */

typedef union {
  uObjBg_t      b;
  uObjScaleBg_t s;
  long long int force_structure_alignment;
} uObjBg;

The BG function in the S2DEX microcode transfers data from the BG image buffer to the actual rectangular area in the frame buffer (see the figure below). You can scroll by using imageX, imageY to specify which position in the BG image buffer corresponds to the upper-left corner of the rectangular area in the frame buffer at the time (the transfer frame). imageX, imageY can be specified in u10.5 format, but note that the values are rounded to integer values due to copy mode restrictions.

The size of the BG image is set by imageW, imageH. The starting address (address of the upper-left corner) is specified by imagePtr. In other words, the BG image can be regarded as texture data that starts at address imagePtr and is imageW wide and imageH tall.

The size of the transfer frame is specified by frameW, frameH and the position on the screen of the upper-left corner of the transfer frame is specified by frameX, frameY. These latter two values (frameX, frameY) can take negative numbers. If the transfer frame protrudes from the scissor box specified by g*DPSetScissor, the microcode will clip the protruding portion.

Concerning the imageW element:
The value of imageW must be aligned to 8 bytes. Because the actual imageW value used is in u10.2 format, the value that is actually assigned is quadruple this value (see the table below).

imageSizvalue imageWrestriction
G_IM_SIZ_4b Multiple of 64
G_IM_SIZ_8b Multiple of 32
G_IM_SIZ_16b Multiple of 16
G_IM_SIZ_32b Multiple of 8

In order to scroll horizontally, the imageW value must be greater than frameW. The values in the table below take the u10.2 format into account. When G_IM_SIZ_16b is used, the imageW value must be 4 pixels larger.

imageSizvalue imageWvalue
G_IM_SIZ_4b frameW+64 <= imageW
G_IM_SIZ_8b frameW+32 <= imageW
G_IM_SIZ_16b frameW+16 <= imageW
G_IM_SIZ_32b frameW+ 8 <= imageW

Concerning the imageFmt element:
Each texel comprises four elements of information: RGB (red, green, blue) and alpha (opacity).
Each texel comprises a Y (intensity) component and a UV (color difference) component.
Each texel is comprised of index information specifying palette data.
Each texel is comprised of I (intensity) information and alpha information.
Each texel is a texture with only I information. Since this is extremely compact, it is useful when only a few colors are being used.
The texture format and size of a BG image are specified by assigning G_IM_FMT_* and G_IM_SIZ_* to imageFmt and imageSiz, respectively. The texture image format can be selected from among eight types. Please refer to the following table for valid combinations of format and size, and select the most suitable format for the texture compression method and type. To use a 4-bit color index texture, specify a texture lookup table (TLUT) number in imagePal.

G_IM_SIZ_ (size)
4b 8b 16b 32b
RGBA     X
YUV     X  
CI X X    
I X X  

Concerning the imageLoadelement:
There are two ways to load texture for a BG image. One involves the use of LoadBlock (G_BGLT_LOADBLOCK) and the other uses LoadTile (G_BGLT_LOADTILE). With the gSPBgRectCopy macro, either of these two methods can be selected for the application at hand using imageLoad.
Although LoadBlock achieves the maximum performance under certain conditions, it may not be usable, or the processing overhead may become excessively large when those conditions are not satisfied. On the other hand, LoadTile always performs suitably. Therefore, you should switch between these two options, using LoadBlock under conditions in which it operates effectively, and using LoadTile at all other times.
There are restrictions on the BG image widths usable with LoadBlock. The imageW values that can be processed when imageSiz is 16 bits are shown below:
4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 48, 64, 72, 76, 100, 108, 128, 144, 152, 164, 200, 216, 228, 256, 304, 328, 432, 456, 512, 684, 820, 912
The imageW values usable when imageSiz is 8 bits is similar to the above sequence, with every term doubled. Similarly, when imageSiz is 4 bits, the imageW values will be the sequence obtained by quadrupling each term, and when imageSiz is 32 bits, they will be the sequence obtained by halving each term. (See Section 13, Appendix A "LoadBlock Line Limits" in the N64 Programming Manual.) When the BG image width cannot be processed by LoadBlock, only LoadTile can be used.
To draw one line of the transfer frame, LoadBlock reads the entire line of the corresponding BG image. For a normal scrolling BG surface, a slightly larger BG image must be prepared for the BG update area. Therefore, imageW must be larger than frameW. For this reason, extra data is loaded. In contrast, LoadTile only loads the required amount of data.
Since LoadBlock is processed faster than LoadTile, when the difference is several pixels, it is better to use LoadBlock. However, when imageW is significantly larger than frameW, the processing for loading the extra data becomes a major overhead, and it is better to use LoadTile.
For example, assume that a BG surface that covers the entire screen (320x240) is defined. Since the transfer frame is the entire screen, frameW = 320 pixels. If 8 pixels are prepared as the BG update area, then imageW = 328 pixels. In this case, since there is only a slight difference between frameW and imageW, you would use LoadBlock with 328 pixels.

See Also


Revision History

02/01/99 Entirely revised.