home *** CD-ROM | disk | FTP | other *** search
- #include <Multiprocessing.h>
-
- #include "MenubarEffects.h"
-
- typedef struct
- {
- Byte x, r, g, b;
- }xrgb;
-
-
- xrgb *gSavedMenuBar = nil;
- xrgb *gRenderedPulse = nil;
- xrgb *gRenderedDeadPulse = nil;
- xrgb *gScreenMemoryBase = nil;
- short gWidth;
- short gHeight;
- long gScreenRowBytes = 0;
- long gScreenWidth = 0;
- MPQueueID gQueue = 0;
- MPTaskID gTask = 0;
-
- xrgb gSavedBGColor;
-
- Rect gPulseRect;
-
- #define compare_xrgb(x1, x2) ((x1->r == x2->r) && (x1->g == x2->g) && (x1->b == x2->b))
-
- ////////////////////////////////////////////////////////////////////////
-
- void RenderPulse();
- void SavePosition(int hOffset);
- void StartMenuBarEffect();
- void MergePulseIntoMenuBar(int hOffset, xrgb* thePulse);
- void RestoreWreckedMenuBar(int hOffset, xrgb* thePulse);
- OSStatus EffectThreadProc(void *);
- void EndMenuBarEffect();
-
- extern long MPSetTaskWeight(MPTaskID, long);
-
- ////////////////////////////////////////////////////////////////////////
-
-
- ////////////////////////////////////////////////////////////////////////
-
- OSStatus EffectThreadProc(void *)
- {
- Duration wait = 100;
- int maxStep = gWidth / 2;
- while(1)
- {
- int position = 0;
- int step = jGNECount();
- if (step > maxStep) step = maxStep;
- for (position = 0; position < gScreenWidth - gWidth; position += step + 1)
- {
- OSStatus stat;
- xrgb *thePulse = (step == 0) ? gRenderedDeadPulse : gRenderedPulse;
- SavePosition(position);
- MergePulseIntoMenuBar(position, thePulse);
- stat = MPWaitOnQueue(gQueue, nil, nil, nil, wait);
- RestoreWreckedMenuBar(position, thePulse);
- step = jGNECount();
- if (step > maxStep) step = maxStep;
- }
- }
-
- return noErr;
- }
-
- ////////////////////////////////////////////////////////////////////////
-
- void EndMenuBarEffect()
- {
- MPTerminateTask(gTask, 0);
- MPDeleteQueue(gQueue);
- DisposePtr((Ptr)gSavedMenuBar);
- DisposePtr((Ptr)gRenderedPulse);
- DisposePtr((Ptr)gRenderedDeadPulse);
- RemovejGNE();
- }
-
- ////////////////////////////////////////////////////////////////////////
-
- void StartMenuBarEffect()
- {
- PixMapHandle offscreenPixMap = nil;
- CGrafPtr grafPtr = nil;
-
- // Get a hold of the screen memory
- // Get the row bytes
- GetCWMgrPort(&grafPtr);
- offscreenPixMap = GetGWorldPixMap(grafPtr);
- gScreenRowBytes = GetPixRowBytes(offscreenPixMap);
- gScreenMemoryBase = (xrgb*) (GetPixBaseAddr(offscreenPixMap) + gPulseRect.top * gScreenRowBytes);
-
- gPulseRect.top = 0;
- gPulseRect.left = 0;
- gPulseRect.bottom = gPulseRect.top + 18;
- gPulseRect.right = 32;
-
- gWidth = gPulseRect.right - gPulseRect.left;
- gHeight = gPulseRect.bottom - gPulseRect.top;
-
- gScreenWidth = (grafPtr->portRect.right - grafPtr->portRect.left);
-
- // Determine the background color
- // very cheesey, assume the fourth pixel has the bg color.
- gSavedBGColor = * (((xrgb*) (gScreenMemoryBase + 3 *gScreenRowBytes) ) + 4);
-
- // allocate a buffer to save the rendered pulse to.
- gRenderedPulse = (xrgb*) NewPtrClear(gWidth * gHeight * sizeof(xrgb));
-
- // allocate a buffer to save the rendered pulse to.
- gRenderedDeadPulse = (xrgb*) NewPtrClear(gWidth * gHeight * sizeof(xrgb));
-
- // Render a pulse, since they are all the same.
-
- RenderPulse();
-
- // allocate a buffer to save the affected menubar area to.
- gSavedMenuBar = (xrgb*) NewPtrClear(gWidth * gHeight * sizeof(xrgb));
-
- InstalljGNE();
-
- // Create a queue
- {
- OSStatus stat1 = MPCreateQueue(&gQueue);
- OSStatus stat2 = MPCreateTask(EffectThreadProc, nil,0,0,nil,nil,0, &gTask);
- stat1 = MPSetTaskWeight(gTask, 250);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- // Save a portion of the menu bar
-
- void SavePosition(int hOffset)
- {
- Ptr srcPtr = (Ptr) (gScreenMemoryBase + hOffset);
- Ptr destPtr = (Ptr) gSavedMenuBar;
- int i;
-
- for (i = 0; i < gHeight; i++, srcPtr += gScreenRowBytes, destPtr += gWidth * sizeof(xrgb))
- {
- BlockMoveData(srcPtr, destPtr, gWidth * sizeof(xrgb));
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- // Render the pulse once and reuse it.
-
- void RenderPulse()
- {
- xrgb* line1 = gRenderedDeadPulse;
- xrgb* p = gRenderedDeadPulse;
- int i = 0;
- xrgb* p2;
- int detent = (1000 * (255 - gSavedBGColor.r)) / gWidth;
- // Render the first line
- for (i = 0; i < gWidth; i++, p++)
- {
- p->x = 0;
- p->r = gSavedBGColor.r + (detent * i)/ 1000;
- p->g = gSavedBGColor.g - i*8;
- p->b = gSavedBGColor.b - i*8;
- }
-
- // Copy the first line to the rest
- for (i = 1, p2 = gRenderedDeadPulse + gWidth; i < gHeight; i++, p2 += gWidth)
- {
- BlockMoveData(line1, (Ptr)p2, gWidth * sizeof(xrgb));
- }
-
- p = line1 = gRenderedPulse;
- detent = (1000 * (255 - gSavedBGColor.g)) / gWidth;
- // Render the first line
- for (i = 0; i < gWidth; i++, p++)
- {
- p->x = gSavedBGColor.x;
- p->g = gSavedBGColor.g + (detent * i)/ 1000;
-
- p->r = gSavedBGColor.r - i*8;
- p->b = gSavedBGColor.b - i*8;
- }
-
- // Copy the first line to the rest
- for (i = 1, p2 = gRenderedPulse + gWidth; i < gHeight; i++, p2 += gWidth)
- {
- BlockMoveData(line1, (Ptr)p2, gWidth * sizeof(xrgb));
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
-
- void MergePulseIntoMenuBar(int hOffset, xrgb* thePulse)
- {
- Ptr destPtr = (Ptr) (gScreenMemoryBase + hOffset);
- Ptr srcPtr = (Ptr) thePulse;
- int stride = gWidth * sizeof(xrgb);
- int row, col;
-
- for (row = 0; row < gHeight; row++, destPtr += gScreenRowBytes, srcPtr += stride)
- {
- xrgb *s = (xrgb*) srcPtr;
- xrgb *p = (xrgb*) destPtr;
-
- for (col = 0; col < gWidth; col++)
- {
- if (compare_xrgb((&gSavedBGColor), p))
- {
- *p = *s;
- }
- p++;
- s++;
- }
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
-
- void RestoreWreckedMenuBar(int hOffset, xrgb* thePulse)
- {
- Ptr destPtr = (Ptr) (gScreenMemoryBase + hOffset);
- Ptr srcPtr = (Ptr) gSavedMenuBar;
- Ptr cmpPtr = (Ptr) thePulse;
- int row, col;
- int stride = gWidth * sizeof(xrgb);
-
- for (row = 0;
- row < gHeight;
- row++, destPtr += gScreenRowBytes, srcPtr += stride, cmpPtr += stride)
- {
- xrgb *s = (xrgb*) srcPtr;
- xrgb *p = (xrgb*) destPtr;
- xrgb *c = (xrgb*) cmpPtr;
-
- for (col = 0; col < gWidth; col++, c++, p++, s++)
- {
- // if the color is from the rendered data, copy the saved color back
- if (compare_xrgb(c, p))
- {
- *p = *s;
- }
- // if the color is not what we saved, then the menubar needs to be
- // refreshed.
- else if (!compare_xrgb(s, p))
- {
- doRefreshMenuBar();
- }
- }
- }
-
- }
-
-