home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-11-08 | 10.6 KB | 329 lines | [TEXT/KAHL] |
- /********************************************************************************
-
- PROJECT: clut_fade.π
-
- FILE: fade.c
-
- PURPOSE: 'clut' fading functions
-
- ??/??/93 1.0 written by N. Jonas Englund
- 07/26/94 1.1 Changes by Mark Womack to allow fading all monitors, only the
- main monitor, or all monitors except the main monitor. Cleaned
- up the fade.h to hide more structures, and removed almost all global
- space used (My changes grew the global space by 10 times so I figured
- it needed to be fixed). Current code is limited to 10 monitors max,
- but is easily cofigurable for more if you think you need it.
- 10/21/94 Changes by Mark Womack to make pascal friendly, fix < 256 color
- crasher, cleaned up to make more readable.
- 10/24/94 Integrated fade_to_clut function written by Macneil Shonle.
- Added copy_gdevice_clut function to make it easier to save
- and restore device clut's.
- Added fade_to_color function which uses both the fade_to_clut
- and copy_gdevice_clut functions to fade to a given rgb value.
-
- =-=-= PLEASE SEE THE README THAT ACCOMPANIED THIS PROJECT FOR DETAILS =-=-=
-
- This software is considered Public Domain. You are free to use it in any
- manner you wish. You are free to upload it to your favorite service, but
- you must post it with the accompanying readme and description files.
- If you use or appreciate it, please let us know!! We all love to get email.
- See the addresses below.
-
- This software is offered 'as is'. The authors are not responsible for any
- damages caused by bugs or defects that might be lurking. But if it blows up
- your monitor, please let us know. If you find any bugs, problems, enhancements,
- please contact us.
-
- Email Addresses: MarkWomack@aol.com, MacneilS@aol.com, KenLong@aol.com.
-
- ********************************************************************************/
-
- //================================= INCLUDES ====================================
-
- #include "fade.h"
-
- //================================= DEFINES =====================================
-
- #define MAXCOLORS 256 // supports 256 colors max
- #define gMaxDevices 10 // supports only 10 monitors max
-
- //================================= TYPEDEFS ====================================
-
- typedef struct FadeValues
- {
- short reds[MAXCOLORS];
- short greens[MAXCOLORS];
- short blues[MAXCOLORS];
- }
- FadeValues;
-
- //================================= FUNCTIONS ===================================
-
- static void copy_cluts (GDHandle, CTabHandle*, CTabHandle*, short);
- static void calc_fade (long, CTabHandle, FadeValues*);
- static void fade_out (long, CTabHandle, FadeValues);
- static void fade_in (long, CTabHandle, CTabHandle, FadeValues);
- static void black_out (CTabHandle);
- static void restore_clut(CTabHandle, CTabHandle);
-
- //===== PUBLIC FUNCTIONS =====//
-
- /********************************** fade_to_black ******************************/
- pascal void fade_to_black(long numSteps, short fadeFlags, Boolean fadeOut)
- {
- GDHandle oldDev, hGD;
- GDHandle gdHdls[gMaxDevices]; // list of valid graphic devices
- FadeValues rgbs[gMaxDevices]; // fade values
- CTabHandle gFade[gMaxDevices], // 'clut' to alter with fading functions
- gOrig[gMaxDevices]; // 'clut' to hold a copy of original
- short x,numDevices,stepCount;
-
- // initialize
- oldDev = GetGDevice();
- hGD = (!!(fadeFlags & fadeMainOnly != 0)) ? GetMainDevice() : GetDeviceList();
- numDevices = 0;
-
- // make a list of the affected gdevices
- while (hGD && numDevices < gMaxDevices)
- {
- // skip main device if fadeAllButMain flag
- if (TestDeviceAttribute(hGD,mainScreen) && (!!(fadeFlags & fadeAllButMain)))
- {
- hGD = (GDHandle)(*hGD)->gdNextGD;
- continue;
- }
-
- if (TestDeviceAttribute(hGD,screenDevice))
- {
- gdHdls[numDevices] = hGD;
- numDevices++;
- }
-
- // stop now if only fading main device
- if (!!(fadeFlags & fadeMainOnly != 0))
- break;
-
- hGD = (GDHandle)(*hGD)->gdNextGD;
- }
-
- // calculate the fade cluts for each device
- for (x = 0; x < numDevices; x++)
- {
- SetGDevice(gdHdls[x]);
- copy_cluts(gdHdls[x], &gFade[x], &gOrig[x], x);
- calc_fade(numSteps, gFade[x], &rgbs[x]);
- }
-
- // fade each device
- // I know this is unreadable (dontcha love C?), the idea is to count down on
- // fadeout and count up on fade in.
- for (stepCount = fadeOut ? numSteps : 0; fadeOut ? stepCount >= 0 : stepCount < numSteps; fadeOut ? stepCount-- : stepCount++)
- {
- for (x = 0; x < numDevices; x++)
- {
- SetGDevice(gdHdls[x]);
- if (fadeOut)
- fade_out(stepCount, gFade[x], rgbs[x]);
- else
- fade_in(stepCount, gFade[x], gOrig[x], rgbs[x]);
- }
- }
-
- // restore each devices clut, and dispose of temp memory
- for (x = 0; x < numDevices; x++)
- {
- SetGDevice(gdHdls[x]);
- restore_clut(gFade[x], gOrig[x]);
- DisposeHandle((Handle)gOrig[x]);
- }
-
- // set original device
- SetGDevice(oldDev);
- }
-
- /*********************************** fade_to_clut *******************************/
- pascal void fade_to_clut(long numSteps, CTabHandle destTab, GDHandle aGDevice )
- {
- CTabHandle srcTab = (**(**aGDevice).gdPMap).pmTable; // get the monitor’s current clut
- long redDelta[MAXCOLORS]; // We want the range for each color to be of an
- long greenDelta[MAXCOLORS]; // unsigned short, but we need negative numbers.
- long blueDelta[MAXCOLORS]; // So these longs are the solution.
- long difference; // used to clear up clutter in the code
- long i; // to cycle trough for loops
- long colorIndex; // to cycle through arrays
- GDHandle oldGDevice;
-
- oldGDevice = GetGDevice(); // save the old
-
- SetGDevice( aGDevice ); // set it to the monitor to be faded
-
- /**** Set up the deltas ****/
- for( i=0; i <= (**destTab).ctSize; i++ )
- { /* This is what I am thinking: take the difference between the two colors and divide
- it by the number of steps (numSteps). So we will have a number that can be added
- to the source numSteps times and have it end up equaling the destination.
- */
-
- difference = ( (long)(**srcTab).ctTable[i].rgb.red - (long)(**destTab).ctTable[i].rgb.red );
- redDelta[i] = difference / (long)numSteps;
-
- difference = ( (long)(**srcTab).ctTable[i].rgb.green - (long)(**destTab).ctTable[i].rgb.green );
- greenDelta[i] = difference / (long)numSteps;
-
- difference = ( (long)(**srcTab).ctTable[i].rgb.blue - (long)(**destTab).ctTable[i].rgb.blue );
- blueDelta[i] = difference / (long)numSteps;
- }
-
- /**** Do the fade ****/
- for( i = 0; i < numSteps; i++ )
- {
- for( colorIndex = 0; colorIndex <= (**destTab).ctSize; colorIndex++ )
- { // make the source more and more like the dest
- (**srcTab).ctTable[colorIndex].rgb.red -= redDelta[colorIndex];
- (**srcTab).ctTable[colorIndex].rgb.green -= greenDelta[colorIndex];
- (**srcTab).ctTable[colorIndex].rgb.blue -= blueDelta[colorIndex];
- }
-
- SetEntries( 0, (**srcTab).ctSize, (ColorSpec *)&(**srcTab).ctTable );
- }
-
- SetEntries( 0, (**destTab).ctSize, (ColorSpec *)&(**destTab).ctTable ); // set it to the dest, just in case
- MakeITable( nil, nil, 0 );
-
- SetGDevice( oldGDevice ); // return it back to it’s old state
- }
-
- pascal void fade_to_color(long numSteps, RGBColor* destColor, GDHandle aGDevice )
- {
- CTabHandle newColors;
- short x;
-
- // get copy of the current color table
- copy_gdevice_clut(aGDevice,&newColors);
-
- // make the color table all one color
- for( x = 0; x <= (**newColors).ctSize; x++ )
- (**newColors).ctTable[x].rgb = *destColor;
-
- // fade to the custom color table
- fade_to_clut(numSteps,newColors,aGDevice);
-
- // dispose color table
- DisposeHandle((Handle)newColors);
- }
-
- pascal void copy_gdevice_clut(GDHandle aGDevice, CTabHandle* copyOfClut)
- {
- CTabHandle srcTab = (**(**aGDevice).gdPMap).pmTable; // get the monitor’s current clut
-
- HandToHand((Handle*)&srcTab);
- *copyOfClut = srcTab;
- }
-
- //===== PRIVATE FUNCTIONS =====//
-
- /********************************** copy_cluts **********************************/
- static
- void copy_cluts(GDHandle hGD, CTabHandle* gFade, CTabHandle* gOrig, short arrayPos)
- {
- Handle gTempH; // temporary handle to copy 'clut'
-
- *gFade = (*(*hGD)->gdPMap)->pmTable;
- gTempH = (Handle) (*(*hGD)->gdPMap)->pmTable;
- HandToHand(&gTempH);
- *gOrig = (CTabHandle) gTempH;
-
- HLock((Handle) *gFade);
- HLock((Handle) *gOrig);
- }
-
- /*********************************** calc_fade **********************************/
- static
- void calc_fade(long numSteps, CTabHandle gFade, FadeValues *rgbs)
- {
- short i;
-
- for (i = 0; i <= (*gFade)->ctSize; i++)
- {
- rgbs->reds[i] = (*gFade)->ctTable[i].rgb.red / numSteps;
- rgbs->greens[i] = (*gFade)->ctTable[i].rgb.green / numSteps;
- rgbs->blues[i] = (*gFade)->ctTable[i].rgb.blue / numSteps;
- }
- }
-
- /*********************************** fade_out ***********************************/
- static
- void fade_out(long fadeLevel, CTabHandle gFade, FadeValues rgbs)
- {
- short i;
-
- for (i = 0; i <= (*gFade)->ctSize; i++)
- {
- if ((*gFade)->ctTable[i].rgb.red > rgbs.reds[i])
- (*gFade)->ctTable[i].rgb.red -= rgbs.reds[i];
- if ((*gFade)->ctTable[i].rgb.green > rgbs.greens[i])
- (*gFade)->ctTable[i].rgb.green -= rgbs.greens[i];
- if ((*gFade)->ctTable[i].rgb.blue > rgbs.blues[i])
- (*gFade)->ctTable[i].rgb.blue -= rgbs.blues[i];
- }
- SetEntries(0, (*gFade)->ctSize, (*gFade)->ctTable);
-
- if (fadeLevel == 0)
- black_out(gFade);
- }
-
- /************************************ fade_in ***********************************/
- static
- void fade_in(long fadeLevel, CTabHandle gFade, CTabHandle gOrig, FadeValues rgbs)
- {
- short i;
-
- if (fadeLevel == 0)
- black_out(gFade);
-
- for (i = 0; i <= (*gFade)->ctSize; i++)
- {
- if ((*gFade)->ctTable[i].rgb.red < (*gOrig)->ctTable[i].rgb.red)
- (*gFade)->ctTable[i].rgb.red += rgbs.reds[i];
- if ((*gFade)->ctTable[i].rgb.green < (*gOrig)->ctTable[i].rgb.green)
- (*gFade)->ctTable[i].rgb.green += rgbs.greens[i];
- if ((*gFade)->ctTable[i].rgb.blue < (*gOrig)->ctTable[i].rgb.blue)
- (*gFade)->ctTable[i].rgb.blue += rgbs.blues[i];
- }
- SetEntries(0, (*gFade)->ctSize, (*gFade)->ctTable);
- }
-
- /*********************************** black_out **********************************/
- static
- void black_out(CTabHandle gFade)
- {
- short i;
-
- for (i = 0; i <= (*gFade)->ctSize; i++)
- {
- (*gFade)->ctTable[i].rgb.red = 0;
- (*gFade)->ctTable[i].rgb.green = 0;
- (*gFade)->ctTable[i].rgb.blue = 0;
- }
- SetEntries(0, (*gFade)->ctSize, (*gFade)->ctTable);
- }
-
- /********************************** restore_clut ********************************/
- static
- void restore_clut(CTabHandle gFade, CTabHandle gOrig)
- {
- short i;
-
- for (i = 0; i <= (*gFade)->ctSize; i++)
- {
- (*gFade)->ctTable[i].rgb.red = (*gOrig)->ctTable[i].rgb.red;
- (*gFade)->ctTable[i].rgb.green = (*gOrig)->ctTable[i].rgb.green;
- (*gFade)->ctTable[i].rgb.blue = (*gOrig)->ctTable[i].rgb.blue;
- }
- (*gFade)->ctSeed = GetCTSeed();
- MakeITable(nil, nil, 0);
-
- HUnlock((Handle) gFade);
- HUnlock((Handle) gOrig);
- }
-