FadeScreen.c

/*
    File:       FadeScreen.c
 
    Contains:   code snippet for fading a screen of any depth in or out.
 
    Written by: John Wang   
 
    Copyright:  Copyright © 1994-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/18/1999   Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
                03/14/94    JW      Re-Created for Universal Headers.
 
*/
 
#ifdef THINK_C
#define     applec
#endif
 
#include    <Memory.h>
#include    <QuickDraw.h>
#include    <Devices.h>
#include    <Video.h>
#include    <LowMem.h>
 
#include    "FadeScreen.h"
 
/* ------------------------------------------------------------------------- */
 
/*
    Description:    Call this routine to fade any screen in or out.
 
    Format Params:  
        Name            Usage   Description/Assumptions
        ----            ----    -----------------------
        myDevice        PI      Pass in the device handle to the screen.
        inOut           PI      Pass in whether to fade in or out.  TRUE to fade out (black).
                                FALSE to fade back in.
        smoothness      PI      Number of steps to fade in or out.  A good number is 60.
        
    Usage: P=Parameter,R=ReturnValue,E=External,G=FileGlobal,L=Local,I=Input,O=Output
    
    Error Handling: If it can't allocate the color table necessary, then it returns without
                    doing anything.
 
    Special Notes:  xxx put other comments here xxx
 
*/
 
void FadeInOut(GDHandle myDevice, Boolean inOut, short smoothness)
{
    GDHandle        saveDevice;
    
    saveDevice = GetGDevice();
    SetGDevice(myDevice);
 
    if ( (**myDevice).gdType == directType ) {
        DirectFadeInOut(myDevice, inOut, smoothness);
    } else {
        IndexedFadeInOut(myDevice, inOut, smoothness);
    }
 
    SetGDevice(saveDevice);
}
 
/* ------------------------------------------------------------------------- */
 
/*  Internal routines used by fadeInOut.    */
 
void DirectFadeInOut(GDHandle myDevice, Boolean inOut, short smoothness)
{
    VDSetEntryRecord    setEntriesRec;  /* DirectSetEntries information */
    Ptr                 csPtr;          /* Passes setEntriesRect to the video card */
    short               index;          /* Index into the color table */
    short               iter;
    CTabHandle          animClut;       /* Color table weÕre using for animation. */
    short               pixelSize;
    long                colorComp;
    RGBColor            *thisRGB;
    long                now;
    
    animClut = (CTabHandle) NewHandle(sizeof(ColorTable) + 255 * sizeof(ColorSpec));
    if (animClut == nil)
        goto bail;
        
    (**animClut).ctSeed = GetCTSeed ();
    (**animClut).ctFlags = 0;
    pixelSize = (**((**myDevice).gdPMap)).pixelSize;
    if ( pixelSize == 32 )
        (**animClut).ctSize = 255;
    else if ( pixelSize == 16 )
        (**animClut).ctSize = 31;
    else
        goto bail;
 
    for ( iter = 0; iter < smoothness; iter++ ) {
        now = TickCount();
        for ( index = 0; index <= (**animClut).ctSize; index++ ) {
            if (pixelSize == 32)
                colorComp = (index << 8) + index;
            else if (pixelSize == 16)
                colorComp = (index << 11) + (index << 6) + (index << 1) + (index >> 4);
            if (inOut)
                colorComp = (colorComp * (smoothness - iter)) / smoothness;
            else
                colorComp = (colorComp * iter) / smoothness;
            thisRGB = &((**animClut).ctTable[index].rgb);
            thisRGB->red = (short) colorComp;
            thisRGB->green = (short) colorComp;
            thisRGB->blue = (short) colorComp;
        }
        
        //  Set the video cardÕs DACs
        setEntriesRec.csTable = (**animClut).ctTable;
        setEntriesRec.csStart = 0;
        setEntriesRec.csCount = (**animClut).ctSize;
        csPtr = (Ptr) &setEntriesRec;
        Control ((**myDevice).gdRefNum, cscDirectSetEntries, (Ptr) &csPtr);
        
        //  Wait
        while ( now == TickCount() );
    }
    
bail:
    if (animClut != nil)
        DisposeHandle((Handle) animClut);
}
 
void IndexedFadeInOut(GDHandle myDevice, Boolean inOut, short smoothness)
{
    VDSetEntryRecord    setEntriesRec; /* DirectSetEntries information */
    Ptr                 csPtr;         /* Passes setEntriesRect to the video card */
    short               index;         /* Index into the color table */
    short               iter;
    CTabHandle          animClut, sourceColorTB;
    RGBColor            *thisRGB, *sourceRGB;
    long                now;
    
    animClut = (CTabHandle) NewHandle (sizeof (ColorTable) + 255 * sizeof (ColorSpec));
    if ( animClut == nil )
        goto bail;
        
    sourceColorTB = (**((**myDevice).gdPMap)).pmTable;
 
    (**animClut).ctSeed = GetCTSeed();
    (**animClut).ctFlags = 0;
    (**animClut).ctSize = (**sourceColorTB).ctSize;
 
    //  Set the video cardÕs DACs       
    for ( iter = 0; iter < smoothness; iter++ ) {
        now = TickCount();
        for ( index = 0; index <= (**animClut).ctSize; index++ ) {
            thisRGB = &((**animClut).ctTable[index].rgb);
            sourceRGB = &((**sourceColorTB).ctTable[index].rgb);
            if (inOut) {
                thisRGB->red = (sourceRGB->red * (smoothness - iter)) / smoothness;
                thisRGB->green = (sourceRGB->green * (smoothness - iter)) / smoothness;
                thisRGB->blue = (sourceRGB->blue * (smoothness - iter)) / smoothness;
            } else {
                thisRGB->red = (sourceRGB->red * iter) / smoothness;
                thisRGB->green = (sourceRGB->green * iter) / smoothness;
                thisRGB->blue = (sourceRGB->blue * iter) / smoothness;
            }
        }
        
        //  Set the video cardÕs DACs
        setEntriesRec.csTable = (**animClut).ctTable;
        setEntriesRec.csStart = 0;
        setEntriesRec.csCount = (**animClut).ctSize;
        csPtr = (Ptr) &setEntriesRec;
        Control ((**myDevice).gdRefNum, cscSetEntries, (Ptr) &csPtr);
        
        //  Wait
        while ( now == TickCount() );
    }
    
bail:
    if (animClut != nil)
        DisposeHandle((Handle) animClut);
}