3.3 Two Kinds of Display Lists

In the display list we used as an example in the previous section, the display list was provided as a Gfx type data array. You may have wondered at that time whether display lists are always that inflexible.

Actually, this is a valid point. If the array is to be defined, the elements must be decided at the time of compilation. In other words, the contents of the display list must all be provided as constants before interpretation by the compiler. Imagine you are using the display list to draw a rectangle on the screen. If you must provide all information about the rectangle's position, size and fill color as constants, then you cannot change the color or move the position at the time of execution. Naturally, there will be times when you want a "dynamic" display list rather than this "static" kind of the display list.

In fact, both kinds of display lists are available: static and dynamic. As you may have surmised, rspinit_dl and rdpinit_dl are classified as static display lists. A static display list is suitable for initialization purposes since it is almost always okay to decide on the contents at compile time.

To see an example of a dynamic display list, look at the array glist defined in graphic.c.

List 3-2 See basic3 "graphic.c"

/* Display list */                          
Gfx    glist[GLIST_LENGTH];
Gfx *  glistp;

The glist array also stores a display list, but unlike rspinit_dl and rdpinit_dl, none of the array content is specified at compile time. In other words, at the time when the array is defined, the memory area for storing the commands is reserved, but the content remains empty.

The functions that actually create the contents of glist are ClearBackground and DrawBlueRectangle. When gSP... or gDP... commands are called, the commands are stored one by one in glist.

List 3-3 See basic3 "graphic.c"

void  DrawBlueRectangle(void)
{
  /* The blue rectangle's upper-left coordinates  */
  static int      x = 0, y = 0;

  /* Specify the fill color (moving rectangle, blue)*/
  gDPSetFillColor(glistp++,
                 (GPACK_RGBA5551(0, 0, 255, 1) << 16 |
                  GPACK_RGBA5551(0, 0, 255, 1)));

  /* This process when the blue rectangle protrudes from the screen */
  if(x >= SCREEN_WD)
    x = 0;
  if(y >= SCREEN_HT)
    y = 0;

  /*
   * If the blue rectangle protrudes from the bottom of the screen, divide it into top and bottom parts for display.
   *  The top and bottom look like they are connected.
   * Since the code is complicated, do not process in the horizontal direction.
   */
  if(y + 100 >= SCREEN_HT)
  {
    /* If it protrudes, draw two rectangles. */
    gDPFillRectangle(glistp++, x, y, x + 100, SCREEN_HT - 1);
    gDPPipeSync(glistp++);
    gDPFillRectangle(glistp++, x++, 0,
      x + 100, (y++) + 100 - SCREEN_HT);
  }
  else
  {
    /* If it does not protrude, one rectangle is sufficient. */
    gDPFillRectangle(glistp++, x++, y++, x + 100, y + 100);
  }
  gDPPipeSync(glistp++);
}

There is a line in the DrawBlueRectangle function that reads like this:

Here, x and y are variables, so they take various values during execution. A dynamic display list can handle these with no problem, making it possible to create the animation of a moving rectangle.



Figure 3-2 The gDPFillRectangle command in operation


Once a command has been stored in a certain element in the glist array, you cannot overwrite that space with the next command. Thus, you follow a procedure of inserting commands in order into the command list while incrementing the Gfx pointer variable glistp.

Characteristics of the two types of display lists
Static display list Dynamic display list
Advantages Fast to build (decided at compile time) and easy to handle. You can decide the contents at execution time.
Disadvantages Command contents are fixed and inflexible. Slow to build at execution time (rendering speed is the same).