N64® Functions Menu

al - Audio Library Functions
gDP - DP GBI Macros
gdSP - General GBI Macros
gSP - SP GBI Macros
gt - Turbo Microcode RDP
gu - Graphics Utilities
Math - Math Functions
nuSys - NuSystem
os - N64 Operating System
sp - Sprite Library Functions
uh - Host to Target IO
64DD - N64 Disk Drive

Nintendo® Confidential

## gSPBgRect1Cyc

Syntax

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

Arguments

- gdl is the display list pointer.

- bg is the pointer to the BG drawing data structure.

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

- Images can be enlarged and reduced.
- Scrolling is possible in a closed area, looping up/down or left/right.
- Textures can be inverted horizontally (vertical flipping is not possible).
- Drawing is performed in 1-cycle mode.
- Texture interpolation display is possible
- Subpixel movement is possible only in the horizontal direction.
- Anti-aliasing is not possible.
- Texture data is sequentially loaded from DRAM into texture memory (TMEM) and drawn by the macro.

This macro cannot be used in 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 there is no need to scale a drawing (enlarge/reduce), or if you want to use copy mode, then BG image rendering can be processed faster using g*SPBgRectCopy.

Note
This macro supports bilinear interpolation display of images. When bilinear interpolation display is used, texels appear less jagged and the image looks smoother when it is enlarged, compared to normal point sampling display. This effect is less apparent when the image is reduced.

The RDP's drawing performance declines when bilinear interpolation is used. The fewer the number of image lines that can be loaded into TMEM at one time, the greater the extent of this decline in performance. For example, when a 640x480 image is reduced by half for drawing in a 320x240 frame, the amount of overhead from bilinear interpolation is far greater than when a 320x240 image is drawn with no scaling. In addition, the RDP's drawing performance drops significantly compared to when point sampling is used. Considering the diminished effect obtained with bilinear interpolation when the image is reduced, you may want to switch to point sampling display.

This macro automatically divides an image into a number of subplanes for drawing. However, if this division process is done carelessly, unnatural wrinkles may emerge in the drawing result. Such wrinkles will be particularly apparent during scrolling. To prevent wrinkles, use the "imageYorig" of uObjScaleBg_t and perform operations like those shown below (this value is the y-coordinate of the origin for scaling, but it is also the division origin of the subplane). The Comment section below shows the uObjScaleBg_t structure.

* At the time of initialization:
  Assign the value of imageY to imageYorig

* When the value of scaleH has changed:
  Assign the value of imageY to imageYorig

* When imageX, imageY have been wrapped:
  Perform the same kind of process on imageYorig as on imageY

* When only imageY is changed (change without wrapping)
  Do not change imageYorig

Based on the above operations, the process for dx,dy scrolling of an image would be as follows:

    /*Add scroll values */
    bg->s.imageX += dx;
    bg->s.imageY += dy;
    /* Screen edge wrapping */
    if (bg->s.imageX < 0) {
      bg->s.imageX     += bg->s.imageW;
      bg->s.imageY     -= 32;
      bg->s.imageYorig -= 32;
    }
    if (bg->s.imageX >= bg->s.imageW) {
      bg->s.imageX     -= bg->s.imageW;
      bg->s.imageY     += 32;
      bg->s.imageYorig += 32;
    }
    if (bg->s.imageY < 0) {
      bg->s.imageY     += bg->s.imageH;
      bg->s.imageYorig += bg->s.imageH;
    }
    if (bg->s.imageY >= bg->s.imageH) {
      bg->s.imageY     -= bg->s.imageH;
      bg->s.imageYorig -= bg->s.imageH;

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

Comment
The uObjScaleBg 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) */

      u16 scaleW;      /* x-direction scale value (u5.10) */
      u16 scaleH;      /* y-direction scale value (u5.10) */
      s32 imageYorig;  /* image drawing origin (s20.5)*/

      u8  padding[4];  /* Padding */

    } uObjScaleBg_t;   /* 40 bytes */

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

Concerning the scaleW, scaleH, and imageYorig elements:
BG image scaling is controlled by the scaleW, and scaleH members of the uObjScaleBg_t structure. The scaling process centers around (imageX, imageY) of the BG image. The image is drawn to the (frameX, frameY) position in the frame buffer, just as when no scaling is performed. However, during a horizontal flip, the BG image is drawn to the (frameX+frameW-1, frameY) position in the frame buffer.

When the image is enlarged, the image is clamped by the frame size. Conversely, when the image is reduced, the frame is sometimes clamped by the image size. This frame clamp can be a little big or a little small, due to errors in calculation. If you want to strictly specify the size, you will need to calculate frameW, frameH with the CPU. For details, see the S2DEX sample program.

Concerning the imagePtr element:

You cannot specify any position in the first 4096 bytes of RDRAM for imagePtr. These are the physical addresses from

0x00000000 to 0x00000fff.

A segment-converted imagePtr cannot reside within this range.

To learn more about the other elements, please refer to the gSPBgRectCopy macro.

This macro is built into S2DEX Release 1.00 and later versions. However, the same processes can be emulated using guS2DEmuGBgRect1Cyc, which was added from S2DEX Release 0.75 and which works by assembling gSPTextureRectangle together with a number of other macros. This can be used to draw BG images that can be scaled. For details, see Section 25.5 "Emulation Functions" of the N64 Online Programming Manual. For information about the uObjScaleBg_t structure, see Section 25.5.4.1, "BG Drawing GBIs" in the same manual.

See Also
gSPBgRectCopy

Revision History
2/1/1999 Completely rewritten.

Nintendo® Confidential Warning: all information in this document is confidential and covered by a non-disclosure agreement. You are responsible for keeping this information confidential and protected. Nintendo will vigorously enforce this responsibility.
Copyright © 1998
Nintendo of America Inc. All rights reserved
Nintendo and N64 are registered trademarks of Nintendo
Last updated March 1999