The sample code below comes from jsshowcel.c. The main()
function calls three functions to create the display:
DrawImage()
renders the background image into the display buffer
DrawCels()
renders the foreground cel into the display buffer
DisplayScreen()
shows the display buffer on the TV screen
main()
function in the example below, then discusses the function calls in some detail. Example 1: Displaying an image and a cel
The Lib3DO function
int main(int argc, char** argv)
{
printf("jsshowcel\n");
/* Initialize global resources */
if ( Initialize() < 0 )
goto DONE;
/* Draw the background image to the current screen. */
DrawImage(gScreenContext->sc_Screens[gScreenContext->sc_curScreen],
gBackgroundImage, gScreenContext);
/*
Draw (project) the cel to the current bitmap. If this cel
were linked to other cels, all of them would be drawn.
*/
DrawCels(gScreenContext->sc_BitmapItems[gScreenContext->sc_curScreen], gUFO_CCB);
/*
DisplayScreen automatically waits for the next vertical blank,
then tells the hardware to use the specified screen as the
display buffer. The hardware will continue to show this buffer
on the TV each frame, until another call to DisplayScreen, specifying
a different block of memory, is made.
*/
DisplayScreen(gScreenContext->sc_Screens[gScreenContext->sc_curScreen], 0);
/* Give the user a little time to look at the screen. */
{
int nCountdown;
for (nCountdown = (10 * 30); nCountdown; nCountdown--)
WaitVBL( gVBLIOReq, 1 );
}
DONE:
if ( gScreenContext )
FadeToBlack(gScreenContext, 60);
/* Always clean up after ourselves */
Cleanup();
printf("end of jsshowcel ( wasn't that special? )\n");
return 0;
}
DrawImage()
has three arguments:
The image is block-copied into the frame buffer using direct memory access (DMA), which is very fast and happens in the background while the CPU continues execution. Drawing an image, even if only a blank one, is by far the most common method of clearing the buffer between frames, since DMA copy operations are several times faster than cel engine rendering. While images can be displayed very quickly, they lack flexibility and are therefore only useful for large, static backgrounds.
The graphics folio function DrawCels()
sets up the cel engine according to parameters in the bitmapItem, and then submits the list of cels specified by the ccb argument. When the call returns, the cels have been rendered. The function has two arguments:
OpenGraphics()
. All information about the cel, including XY location, rotation, and scaling, is stored in the CCB. To change any aspect of a cel, you only have to alter one of the fields of the CCB and then rerender the cel list to the screen. Those CCB fields are discussed in a later chapter; for now, the default values (including the default XY position of 0,0) are sufficient.
The graphics folio function DisplayScreen()
displays the bitmap(s) of the specified screen (or screens). The hardware draws the active display to the TV screen 30 times a second for NTSC screens. The software is only responsible for telling the hardware what memory to use. There is no way to disable the hardware or shut off the display, so as long as the hardware is on, some piece of memory is being displayed on the TV.
Only one call to DisplayScreen()
is necessary until you want to change to a different buffer. The jsshowcel program uses only one buffer, even though it allocates two. The animation example discussed in the following chapter uses two buffers, displaying one while drawing into the other.