home *** CD-ROM | disk | FTP | other *** search
- #define DRAW_3D_C
- #include "Draw3D.h"
- #undef DRAW_3D_C
-
-
- #if defined(__MWERKS__)
- #pragma segment __%Main
- #else
- #pragma segment Main
- #endif
-
-
- #define WORLDSIZE 54
-
- static GWorldPtr myRoundWorld[kPlayers+1] = { 0L, 0L, 0L, 0L };
- static Rect offRect = { 0, 0, WORLDSIZE, WORLDSIZE };
- static Rect resRect = { 0, 0, 0, 0};
- static PaletteHandle pH = 0L;
- static Boolean invalidated = false;
-
-
-
- void
- DrawBallColor3D (Field field, char color)
- {
- RgnHandle ballRgn;
- Rect ballRect;
- RGBColor edgeColor;
-
- // Assert (gSet.Balls3D, INTERNAL_ERROR);
- // Assert (ColorQDAvailable(), INTERNAL_ERROR);
-
- if (! myRoundWorld[color])
- Init3D();
-
- // Draw the ball using CopyBits to get it from an offscreen world.
-
- ballRect = FieldToBallRect (field);
- ballRgn = NewRgn();
- OpenRgn();
- ForeColor (blackColor);
- BackColor (whiteColor);
- FrameOval (& ballRect);
- CloseRgn (ballRgn);
-
- ForeColor (blackColor);
- BackColor (whiteColor);
- CopyBits ( (BitMapPtr) *myRoundWorld[color]->portPixMap,
- &(*gAbaloneWindow).portBits,
- &offRect,
- & ballRect,
- ditherCopy,
- ballRgn
- );
-
- edgeColor.red = gSet.Color[color].red / 2;
- edgeColor.green = gSet.Color[color].green / 2;
- edgeColor.blue = gSet.Color[color].blue / 2;
- RGBForeColor (& edgeColor);
- FrameOval (& ballRect);
- ForeColor (blackColor);
- RGBBackColor (& gSet.Color[0]);
-
- DisposeRgn (ballRgn);
- }
-
-
- static short savedWidth = 0;
- static short savedHeight = 0;
-
- #define PushSizes { savedWidth = gSet.FieldWidth; savedHeight = gSet.FieldHeight; }
- #define PopSizes { gSet.FieldWidth = savedWidth; gSet.FieldHeight = savedHeight; }
-
- void
- DrawFieldColor3D (Field field)
- {
- Rect fieldRect;
- Rect pictRect;
-
- if (! myRoundWorld[0])
- Init3D();
-
- if (EmptyRect (& resRect))
- return;
-
- fieldRect = FieldToRect (field);
- pictRect = fieldRect;
-
- MapRect (& pictRect, & gAbaloneWindow->portRect, & resRect /* & myRoundWorld[0]->portRect */);
- ForeColor (blackColor);
- BackColor (whiteColor);
- CopyBits ( *( (BitMap **) GetGWorldPixMap (myRoundWorld[0])),
- &(*gAbaloneWindow).portBits,
- &pictRect,
- &fieldRect,
- ditherCopy,
- 0L
- );
- ForeColor (blackColor);
- RGBBackColor (& gSet.Color[0]);
- }
-
-
-
- void
- Init3D (void)
- {
- if (! pH && ColorQDAvailable() && gSet.Balls3D)
- SetUpPalette();
-
- if (ColorQDAvailable() && gSet.Balls3D)
- SetUpGWorlds();
- }
-
-
-
- void
- Inval3D (void)
- {
- invalidated = true;
- }
-
-
-
- void
- Update3D (void)
- {
- if (! invalidated)
- return;
-
- UpdatePalette();
- UpdateGWorlds();
- invalidated = false;
- }
-
-
-
- void
- UpdatePalette (void)
- {
- if (pH)
- {
- DisposePalette (pH);
- pH = 0L;
- }
- if (gSet.Balls3D && ColorQDAvailable())
- SetUpPalette();
- }
-
-
-
- void
- UpdateGWorlds (void)
- {
- short world;
-
- for (world = 0; world <= kPlayers; world++)
- {
- if (myRoundWorld[world])
- {
- DisposeGWorld (myRoundWorld[world]);
- myRoundWorld[world] = 0L;
- }
- }
- if (gSet.Balls3D && ColorQDAvailable())
- SetUpGWorlds();
- }
-
-
-
- void
- SetUpPalette (void)
- {
- #define pmDefaultOptions pmTolerant + (pixSize == 8 ? 0 : pmExplicit), 0
- unsigned short dR, dG, dB;
- RGBColor ovalColor;
- short world;
- short i;
- short pixSize = PixelSize();
- short colorsPerPlayer;
- short paletteSize;
- CTabHandle tmpTable;
-
- if (! gSet.Balls3D) // No need for a palette (no 3D effects).
- return;
-
- if (pixSize > 8) // No need for a palette (direct pixels).
- return;
-
- if (pH)
- {
- DisposePalette (pH);
- pH = 0L;
- }
-
- switch (pixSize)
- {
- case 1:
- case 2:
- colorsPerPlayer = 0;
- break;
- case 8:
- colorsPerPlayer = WORLDSIZE >> 1;
- break;
- default:
- colorsPerPlayer = ((1 << pixSize) - 4) / gSet.Players;
- break;
- }
- paletteSize = 2 + gSet.Players * colorsPerPlayer;
-
- if ((pH = NewPalette (paletteSize, 0L, pmCourteous, 0)) == NULL)
- {
- Warning (SHORT_ON_MEMORY);
- gSet.Balls3D = false;
- return;
- }
-
- if ((tmpTable = GetCTable (pixSize)) == 0) // try to get default color table
- {
- // Could not get the default color table; probably a direct device.
- // Can't do anything useful without a color table.
-
- return;
- }
-
- // Initialise the palette with the default color table
-
- // CTab2Palette (tmpTable, pH, pmTolerant, 0);
- DisposCTable (tmpTable), tmpTable = 0;
-
- // Put white in first entry. (explicit).
-
- ovalColor.red = ovalColor.green = ovalColor.blue = 0xFFFF;
- SetEntryColor (pH, 0, & ovalColor);
- SetEntryUsage (pH, 0, pmDefaultOptions);
-
- // add gray & chosen background color & black (for 2-bit setting).
-
- ovalColor.red = ovalColor.green = ovalColor.blue = 0x7FFF;
- SetEntryColor (pH, 1, & ovalColor);
- SetEntryUsage (pH, 1, pmDefaultOptions);
-
- ovalColor.red = gSet.Color[0].red;
- ovalColor.green = gSet.Color[0].green;
- ovalColor.blue = gSet.Color[0].blue;
-
- SetEntryColor (pH, 2, & ovalColor);
- SetEntryUsage (pH, 2, pmDefaultOptions);
-
- ovalColor.red = ovalColor.green = ovalColor.blue = 0x0;
- SetEntryColor (pH, 3, & ovalColor);
- SetEntryUsage (pH, 3, pmDefaultOptions);
-
-
- // Consider the first four entries filled.
- // Twelve colors remain for a sixteen-color palette, 252 for a 256-color palette
- // (black is moved to the last position, entry 3 is reused)
-
- if (pixSize == 4 || pixSize == 8) for (world = 1; world <= gSet.Players; world++)
- {
-
- ovalColor.red = gSet.Color[world].red / 2;
- ovalColor.green = gSet.Color[world].green / 2;
- ovalColor.blue = gSet.Color[world].blue / 2;
-
- // Add as much relevant colors for each ball as is possible or useful.
-
- for ( dR = dG = dB = (pixSize == 8 ? 2475 : (0x8000 / colorsPerPlayer)), i = 0;
- i < colorsPerPlayer - 1;
- i++)
- {
- short index = colorsPerPlayer * (world - 1) + i + 3;
-
- Assert (index <paletteSize, INTERNAL_ERROR);
-
- SetEntryColor (pH, index, & ovalColor);
- SetEntryUsage (pH, index, pmDefaultOptions);
-
- ovalColor.red += dR;
- ovalColor.green += dG;
- ovalColor.blue += dB;
-
- // Decrease the increase exponentially
- if (pixSize == 8)
- {
- // Decrease the increase exponentially
-
- dR -= dR >> 4;
- dG -= dG >> 4;
- dB -= dB >> 4;
-
- }
- }
-
- // Put black at last position
-
- ovalColor.red = ovalColor.green = ovalColor.blue = 0x0;
- SetEntryColor (pH, paletteSize - 1, & ovalColor);
- SetEntryUsage (pH, paletteSize - 1, pmDefaultOptions);
- }
- SetPalette (gAbaloneWindow, pH, true);
- ActivatePalette (gAbaloneWindow);
- }
-
-
-
- void
- SetUpGWorlds (void)
- {
- unsigned short dR, dG, dB;
- GDHandle oldDevice;
- CGrafPtr oldPort;
- Rect ballRect;
- RGBColor ovalColor;
- short world;
-
- Assert (! myRoundWorld[0] || ! myRoundWorld[1], INTERNAL_ERROR);
-
- GetGWorld (&oldPort, &oldDevice);
-
- if (! myRoundWorld[0]) // Background
- {
- PicHandle pict = (PicHandle) GetResource ('PICT', gSet.BackgroundPictID);
- if (pict != 0)
- {
- // save picture boundsrect in global variable.
-
- resRect = (*pict)->picFrame;
-
- MoveHHi ((Handle) pict);
- HLock ((Handle) pict);
-
- // Create offscreen GWorld for the background.
- if ( NewGWorld ( &myRoundWorld[0],
- 16, //8,
- & (*pict)->picFrame,
- nil,
- nil,
- 0)
- != noErr)
- {
- gSet.Balls3D = false;
- Warning (GRAPHIC_3D_TURNED_OFF);
- return;
- }
- SetGWorld (myRoundWorld[0], nil);
- EraseRect (& (*pict)->picFrame);
- DrawPicture (pict, & (*pict)->picFrame);
- HUnlock ((Handle) pict);
- ReleaseResource ((Handle) pict);
- }
- }
-
- if (gSet.Balls3D && ! myRoundWorld[1]) for (world = 1; world <= kPlayers; world++)
- {
- // Create offscreen GWorld for this players ball.
-
- Assert (! NewGWorld ( &myRoundWorld[world],
- 16,
- &offRect,
- nil,
- nil,
- 0),
- INSUFFICIENT_MEMORY);
-
- SetGWorld (myRoundWorld[world], nil);
-
-
- // Draw the ball to the offscreen pixmap.
-
- ForeColor (blackColor);
- PaintRect (& offRect);
-
-
- // dR = dG = dB = 2443; // WORLDSIZE = 55, >> 4
- dR = dG = dB = 2475; // WORLDSIZE = 54, >> 4
-
- // dR = dG = dB = 2594; // value determined empirically for WORLDSIZE = 50, dX -= dX >> 4
- // dR = dG = dB = 4238; // value determined empirically for WORLDSIZE = 50, dX -= dX >> 3
-
- // Start a bit darker at the edges, end a bit lighter in the center.
-
- ovalColor.red = gSet.Color[world].red / 2;
- ovalColor.green = gSet.Color[world].green / 2;
- ovalColor.blue = gSet.Color[world].blue / 2;
-
- RGBForeColor (& ovalColor);
- PaintRect (& ballRect);
-
- for (ballRect = offRect; ! EmptyRect (& ballRect); InsetRect (& ballRect, 1, 1))
- {
- if ((ballRect.bottom - ballRect.top) % 8 < 2)
- OffsetRect (& ballRect, 0, 1);
-
- RGBForeColor (& ovalColor);
- PaintOval (& ballRect);
-
- // Gradually increase going inwards
-
- ovalColor.red += dR;
- ovalColor.green += dG;
- ovalColor.blue += dB;
-
- // Decrease the increase exponentially
-
- dR -= dR >> 4;
- dG -= dG >> 4;
- dB -= dB >> 4;
-
- // Total increase should be about 32767
- }
-
- PenMode (addMax);
-
- dR = dG = dB = 2475; // WORLDSIZE = 54, >> 4
-
- ovalColor.red = gSet.Color[world].red / 2;
- ovalColor.green = gSet.Color[world].green / 2;
- ovalColor.blue = gSet.Color[world].blue / 2;
-
- RGBForeColor (& ovalColor);
- PaintRect (& ballRect);
- for (ballRect = offRect; ! EmptyRect (& ballRect); InsetRect (& ballRect, 1, 1))
- {
- if ((ballRect.bottom - ballRect.top) % 4 < 2)
- OffsetRect (& ballRect, -1, 0);
-
- if ((ballRect.bottom - ballRect.top) % 6 < 2)
- OffsetRect (& ballRect, 0, 1);
-
- RGBForeColor (& ovalColor);
- PaintOval (& ballRect);
-
- // Gradually increase going inwards
-
- ovalColor.red += dR;
- ovalColor.green += dG;
- ovalColor.blue += dB;
-
- // Decrease the increase exponentially
-
- dR -= dR >> 4;
- dG -= dG >> 4;
- dB -= dB >> 4;
-
- // Total increase should be about 32767
- }
-
- PenMode (srcCopy);
-
- ForeColor (blackColor);
- }
- SetGWorld (oldPort, oldDevice);
- }
-
-
-
- void
- DrawBackground (WindowPtr abaloneWindow)
- {
- if (! myRoundWorld[0])
- Init3D();
-
- if (! gSet.Balls3D) // Failure to initialise offscreen world resets flag
- return;
-
- ForeColor (blackColor);
- BackColor (whiteColor);
-
- CopyBits ( (BitMapPtr) *myRoundWorld[0]->portPixMap,//*( (BitMap **) GetGWorldPixMap (myRoundWorld[0])),
- &(*abaloneWindow).portBits,
- & resRect,
- & abaloneWindow->portRect,
- ditherCopy,
- abaloneWindow->visRgn
- );
-
- RGBBackColor (& gSet.Color[0]);
- }
-