File:       SillyBalls.c
    Contains:   This is a very simple sample program that demonstrates how to use Color 
                QuickDraw.  It is about two pages of code, and does nothing more than open
                a color window and draw randomly colored ovals in the window.
                The purpose is to show how to get some initial results with Color QuickDraw.
                It is a complete program and is very short to be as clear as possible.
                It does not have an Event Loop.  It is not fully functional in the sense that
                it does not do all the things you would expect a well behaved Macintosh 
                program to do, like size the window naturally, have an event loop, use menus, 
                See Sample and TESample for the general structure and MultiFinder techniques that
                we recommend that you use when building a new application.
                purpose:    To demonstrate a simple color App using Color QuickDraw.
                            It draws colored balls in a color window, then uses colored
                            text inverted in the ball.  The ball location and color is Random.
                            The inverted Bob text was a Skippy Blair special concept,
                            kept for obvious aesthetic reasons.
    Written by: Bo3b Johnson    
    Copyright:  Copyright © 1988-1999 by Apple Computer, Inc., All Rights Reserved.
                You may incorporate this Apple sample source code into your program(s) without
                restriction. This Apple sample source code has been provided "AS IS" and the
                responsibility for its operation is yours. You are not permitted to redistribute
                this Apple sample source code as "Apple sample source code" after having made
                changes. If you're going to re-distribute the source, we require that you make
                it clear in the source that the code was descended from Apple sample source
                code, but that you've made changes.
    Change History (most recent first):
                8/13/1999   Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
                7/20/88     DJB             Converted to C
                            MW              -cut out some other program descriptions
                8/31/93 JA                  MW ** Metrowerks note **
                                            All changed code by Metrowerks is commented by "//MW".
                                            There is one type of modification to the original source:
                                            ¥ Added argument type and return type to function definitions.
                                            In order to pass with extended error checking on.
#include <Quickdraw.h>
#include <Fonts.h>
#include <Sound.h>
/* Constants */
#define BallWidth       20
#define BallHeight      20
#define BobSize         8       /* Size of text in each ball */
/* Globals */
Rect    windRect;
/* Prototypes */
void Initialize(void);
void NewBall(void);
//  Main body of program SillyBalls
//MW specified argument and return type.
void main(void)
    do {
    } while (!Button());
//  Initialize everything for the program, make sure we can run
//MW specified argument and return type.
void Initialize(void)
    WindowPtr   mainPtr;
    OSErr       error;
    SysEnvRec   theWorld;
    //  Test the computer to be sure we can do color.  
    //  If not we would crash, which would be bad.  
    //  If we canÕt run, just beep and exit.
    error = SysEnvirons(1, &theWorld);
    if (theWorld.hasColorQD == false) {
        ExitToShell();                  /* If no color QD, we must leave. */
    /* Initialize all the needed managers. */
    //  To make the Random sequences truly random, we need to make the seed start
    //  at a different number.  An easy way to do this is to put the current time
    //  and date into the seed.  Since it is always incrementing the starting seed
    //  will always be different.  DonÕt for each call of Random, or the sequence
    //  will no longer be random.  Only needed once, here in the init.
    GetDateTime((unsigned long*) &qd.randSeed);
    //  Make a new window for drawing in, and it must be a color window.  
    //  The window is full screen size, made smaller to make it more visible.
    windRect = qd.screenBits.bounds;
    InsetRect(&windRect, 50, 50);
    mainPtr = NewCWindow(nil, &windRect, "\pBob Land", true, documentProc, 
                        (WindowPtr) -1, false, 0);
    SetPort(mainPtr);                       /* set window to current graf port */
    TextSize(BobSize);                      /* smaller font for drawing. */
//  NewBall: make another ball in the window at a random location and color.
//MW -specified argument and return type.-
void NewBall(void)
    RGBColor    ballColor;
    Rect        ballRect;
    long int    newLeft,
    //  Make a random new color for the ball.
    //   = Random(); = Random();  = Random();
    //  Set that color as the new color to use in drawing.
    RGBForeColor (&ballColor);
    //  Make a Random new location for the ball, that is normalized to the window size.  
    //  This makes the Integer from Random into a number that is 0..windRect.bottom
    //  and 0..windRect.right.  They are normalized so that we don't spend most of our
    //  time drawing in places outside of the window.
    newTop = Random();  newLeft = Random();
    newTop = ((newTop+32767) * windRect.bottom)/65536;
    newLeft = ((newLeft+32767) * windRect.right)/65536;
    SetRect(&ballRect, newLeft, newTop, newLeft+BallWidth, newTop+BallHeight);
    //  Move pen to the new location, and paint the colored ball.
    MoveTo(newLeft, newTop);
    PaintOval (&ballRect);
    //  Move the pen to the middle of the new ball position, for the text
    MoveTo(ballRect.left + BallWidth/2 - BobSize, + BallHeight/2 + BobSize/2 -1);
    //  Invert the color and draw the text there.  This wonÕt look quite right in 1 bit
    //  mode, since the foreground and background colors will be the same.
    //  Color QuickDraw special cases this to not invert the color, to avoid
    //  invisible drawing.