C for Yourself - part 39

Steve Mumford takes a look at plotting sprites within windows

Now that we've covered the mechanics behind plotting a sprite on the screen using the various system calls available to us, it's just a small jump to extend the principles one step more and include their use within a multi-tasking application.

Being able to paint directly onto the screen in this way adds much more flexibility to any program you might care to write as you can dispense with the limitation of having to create your entire user interface using buttons and icons.

When the user creates a window, either through a template editor or directly using Wimp_CreateWindow, a bit within the definition is set to indicate whether the WIMP is capable of redrawing the window by itself that's possible as long as it doesn't contain anything other than the standard buttons and icons.

In order to be able to include user graphics within our windows, we have to unset this bit - the WIMP will then prompt us whenever the window in question needs redrawing. Consequentially, another chunk of housekeeping code is required, and this is described below.

Whether the target window has just been opened or uncovered, or the user has made some change that necessitates the screen to be redrawn, the application is informed of this in the same manner.

A Wimp_Poll event with a reason code of 1 is generated (Redraw_Window_Request), and this is passed to your application along with a pre-prepared data block.

It's formatted to be compatible with the Wimp_RedrawWindow SWI call, so as soon as you receive the redraw request you should call Wimp_RedrawWindow and immediately update the window before the program continues. Place the pointer to the data block returned by the polling loop in register 1 and call the SWI as follows:

_kernel_swi_regs in, out;
int redraw_flag;
in.r[1] = (int) pollblock;
_kernel_swi(Wimp_RedrawWindow, &in, &out);
redraw_flag = out.r[0];

At this stage, the WIMP will have calculated the area of the window that needs updating, and broken it down into a series of rectangles. The program can then interrogate the WIMP and discover these in sequence by entering a short while loop.

while (redraw_flag)
{
  /* Redraw window using given coordinates /
  in.r[1] = (int) pollblock;
  /* Get next rectangle to redraw */
  _kernel_swi(Wimp_GetRectangle, &in, &out);
  redraw_flag = out.r[0];
}

Every time Wimp_GetRectangle is called, a new set of coordinates are supplied in the data block, allowing the invalid area of the window to be determined and redrawn.

The graphics clipping window is automatically set to bound the appropriate area, so you can ignore all the numbers and simply redraw the whole window every time, not worrying whether you're plotting sprites that overlap the visible edges of the window. However, this is obviously not very economical and for graphics-intensive systems, it's better to undertake the task in a more intelligent fashion and only redraw the sections of the screen that you have to. Once the task has been completed, Wimp_GetRectangle will return a zero flag and the main body of the program will be able to continue.

At this point it's appropriate to say something about the coordinate system to describe the position of windows as well as the relative positions of their contents. In the past, x and y coordinates have been sufficient at describing graphics on screen; when specifying window position, several more are needed.

Firstly, the corners of the window are specified by measuring x and y distances from the bottom left corner of the screen, giving minimum and maximum values for both x and y.

Conceptually, windows are holes that look onto much larger documents beneath, only showing one small area at a time; to describe this, we need to specify the top left hand corner of the larger document as it would appear on the screen, and the size of the offset between the top left hand corners of the virtual document and the actual window through which we view it.

In order to plot a sprite to the window so it arrives in the right location, we need to convert between coordinates relative to the top left corner of the window's work area (the virtual document described above) and actual on-screen coordinates.

I'll cover this in greater detail next time, the demonstration application on next month's disc shows you how to go about it.


Source: Acorn User - 183 - July 1997
Publication: Acorn User
Contributor: Steve Mumford