/*============================================================*/
/*============================================================*/
/*==														==*/
/*==			QuickDraw Rendering Routines				==*/
/*==														==*/
/*============================================================*/
/*============================================================*/


/*========================================================  Includes  */

#include "Globals.h"
#include "UnivUtilities.h"
#include "RenderQD.h"
#include "Render.h"
#include "PlayUtils.h"


/*========================================================  Functions  */
/*========================================================  RenderSceneQD1  */

void RenderSceneQD1 (void)

{
	Rect			wholeBall, wholePlayer, wholeOpponent, wholeCursor;

/* find union of old & new position rects */
	UnionRect(&thePlayer.isRect, &thePlayer.wasRect, &wholePlayer);
	UnionRect(&theOpponent.isRect, &theOpponent.wasRect, &wholeOpponent);
	UnionRect(&theBall.isRect, &theBall.wasRect, &wholeBall);
	UnionRect(&boardCursor.isRect, &boardCursor.wasRect, &wholeCursor);
	
/* dick with the door */
	if (theDoor.stateChanged)
	{
		CopyBits(&offPartsBits, &offWorkBits, 
				&theDoor.srcRects[theDoor.doorOpen][theDoor.doorState], 
				&theDoor.destRects[theDoor.doorOpen], srcCopy, kNilPointer);
		CopyBits(&offWorkBits, &offBackBits, 
				&theDoor.destRects[theDoor.doorOpen], 
				&theDoor.destRects[theDoor.doorOpen], srcCopy, kNilPointer);
	}
	
	if ((showBoardCursor) && (!disableBoardCursor) && (drawThisFrame))
	{
		CopyMask(&offPartsBits, &offMaskMap, &offWorkBits, &boardCursor.srcRect, 
				&boardCursor.srcRect, &boardCursor.isRect);
	}
	
	if ((theBall.mode == kBallRolling) && (!theBall.dontDraw) && (drawThisFrame))
		CopyMask(&offPartsBits, &offMaskMap, &offWorkBits, &theBall.srcRect, 
				&theBall.srcRect, &theBall.isRect);

/* mask the bastards to the work map - back to front! */
	if (playerInBack)
	{
		if ((thePlayer.mode != kInStasis) && (drawThisFrame))
			CopyMask(&offPartsBits, &offMaskMap, &offWorkBits, &thePlayer.srcRect, 
					&thePlayer.maskRect, &thePlayer.isRect);
		if ((theOpponent.mode != kInStasis) && (drawThisFrame))
			CopyMask(&offPartsBits, &offMaskMap, &offWorkBits, &theOpponent.srcRect, 
					&theOpponent.maskRect, &theOpponent.isRect);
	}
	else
	{
		if ((theOpponent.mode != kInStasis) && (drawThisFrame))
			CopyMask(&offPartsBits, &offMaskMap, 
					&offWorkBits, &theOpponent.srcRect, 
					&theOpponent.maskRect, &theOpponent.isRect);
		if ((thePlayer.mode != kInStasis) && (drawThisFrame))
			CopyMask(&offPartsBits, &offMaskMap, 
					&offWorkBits, &thePlayer.srcRect, 
					&thePlayer.maskRect, &thePlayer.isRect);
	}

/* blast them to the screen */
	if ((thePlayer.mode != kInStasis) && (drawThisFrame))
	{
		CopyBits(&offWorkBits, &(mainWndo->portBits), &wholePlayer, 
				&wholePlayer, srcCopy, kNilPointer);
	}
	if ((theOpponent.mode != kInStasis) && (drawThisFrame))
	{
		CopyBits(&offWorkBits, &(mainWndo->portBits), 
				&wholeOpponent, &wholeOpponent, srcCopy, kNilPointer);
	}
	if ((theBall.mode == kBallRolling) && (drawThisFrame))
	{
		CopyBits(&offWorkBits, &(mainWndo->portBits), &wholeBall, 
				&wholeBall, srcCopy, kNilPointer);
	}
	else if (theBall.eraseTheBall)
	{
		CopyBits(&offWorkBits, &(mainWndo->portBits), &theBall.eraser, 
				&theBall.eraser, srcCopy, kNilPointer);
		
		theBall.eraseTheBall = FALSE;
	}
	
	if ((showBoardCursor) && (!disableBoardCursor) && (drawThisFrame))
	{
		CopyBits(&offWorkBits, &(mainWndo->portBits), &wholeCursor, &wholeCursor, 
				srcCopy, kNilPointer);
	}
	
/* and re-dick with the door */
	if (theDoor.stateChanged)
	{
		CopyBits(&offWorkBits, &(mainWndo->portBits), 
				&theDoor.destRects[theDoor.doorOpen], 
				&theDoor.destRects[theDoor.doorOpen], srcCopy, kNilPointer);
		CopyBits(&offPartsBits, &offBackBits, 
				&theDoor.srcRects[theDoor.doorOpen][theDoor.doorState], 
				&theDoor.destRects[theDoor.doorOpen], srcCopy, kNilPointer);
		CopyBits(&offWorkBits, &offBackBits, 
				&theDoor.destRects[theDoor.doorOpen], 
				&theDoor.destRects[theDoor.doorOpen], srcCopy, kNilPointer);
	}

/* plug up the holes on the work map */
	if ((thePlayer.mode != kInStasis) && (drawThisFrame))
		CopyBits(&offBackBits, &offWorkBits, &thePlayer.isRect, 
				&thePlayer.isRect, srcCopy, kNilPointer);
	if ((theOpponent.mode != kInStasis) && (drawThisFrame))
		CopyBits(&offBackBits, &offWorkBits, 
			&theOpponent.isRect, &theOpponent.isRect, srcCopy, kNilPointer);
	if ((theBall.mode == kBallRolling) && (drawThisFrame))
		CopyBits(&offBackBits, &offWorkBits, &theBall.isRect, 
			&theBall.isRect, srcCopy, kNilPointer);
	if ((showBoardCursor) && (!disableBoardCursor) && (drawThisFrame))
		CopyBits(&offBackBits, &offWorkBits, &boardCursor.isRect, &boardCursor.isRect, 
				srcCopy, kNilPointer);
}


/*========================================================  RenderSceneQDC  */

void RenderSceneQDC (void)

{
	Rect			wholeBall, wholePlayer, wholeOpponent, wholeCursor;
	
/* find union of old & new position rects */
	UnionRect(&thePlayer.isRect, &thePlayer.wasRect, &wholePlayer);
	UnionRect(&theOpponent.isRect, &theOpponent.wasRect, &wholeOpponent);
	UnionRect(&theBall.isRect, &theBall.wasRect, &wholeBall);
	UnionRect(&boardCursor.isRect, &boardCursor.wasRect, &wholeCursor);
	
/* dick with the door */
	if (theDoor.stateChanged)
	{
		CopyBits(&((GrafPtr)offCPartsPtr)->portBits, &((GrafPtr)offCWorkPtr)->portBits, 
				&theDoor.srcRects[theDoor.doorOpen][theDoor.doorState], 
				&theDoor.destRects[theDoor.doorOpen], srcCopy, kNilPointer);
		CopyBits(&((GrafPtr)offCWorkPtr)->portBits, &((GrafPtr)offCBackPtr)->portBits, 
				&theDoor.destRects[theDoor.doorOpen], 
				&theDoor.destRects[theDoor.doorOpen], srcCopy, kNilPointer);
	}
	
	if ((showBoardCursor) && (!disableBoardCursor) && (drawThisFrame))
	{
		CopyMask(&((GrafPtr)offCPartsPtr)->portBits, &offMaskMap, 
				&((GrafPtr)offCWorkPtr)->portBits, &boardCursor.srcRect, 
				&boardCursor.srcRect, &boardCursor.isRect);
	}
	
	if ((theBall.mode == kBallRolling) && (!theBall.dontDraw) && (drawThisFrame))
		CopyMask(&((GrafPtr)offCPartsPtr)->portBits, &offMaskMap, 
				&((GrafPtr)offCWorkPtr)->portBits, &theBall.srcRect, 
				&theBall.srcRect, &theBall.isRect);

/* mask the bastards to the work map - back to front! */
	
	if (playerInBack)
	{
		if ((thePlayer.mode != kInStasis) && (drawThisFrame))
			CopyMask(&((GrafPtr)offCPartsPtr)->portBits, &offMaskMap, 
					&((GrafPtr)offCWorkPtr)->portBits, &thePlayer.srcRect, 
					&thePlayer.maskRect, &thePlayer.isRect);
		if ((theOpponent.mode != kInStasis) && (drawThisFrame))
			CopyMask(&((GrafPtr)offCPartsPtr)->portBits, &offMaskMap, 
					&((GrafPtr)offCWorkPtr)->portBits, &theOpponent.srcRect, 
					&theOpponent.maskRect, &theOpponent.isRect);
	}
	else
	{
		if ((theOpponent.mode != kInStasis) && (drawThisFrame))
			CopyMask(&((GrafPtr)offCPartsPtr)->portBits, &offMaskMap, 
					&((GrafPtr)offCWorkPtr)->portBits, &theOpponent.srcRect, 
					&theOpponent.maskRect, &theOpponent.isRect);
		if ((thePlayer.mode != kInStasis) && (drawThisFrame))
			CopyMask(&((GrafPtr)offCPartsPtr)->portBits, &offMaskMap, 
					&((GrafPtr)offCWorkPtr)->portBits, &thePlayer.srcRect, 
					&thePlayer.maskRect, &thePlayer.isRect);
	}

/* blast them to the screen */
	if ((thePlayer.mode != kInStasis) && (drawThisFrame))
	{
		CopyBits(&((GrafPtr)offCWorkPtr)->portBits, &(((GrafPtr)mainWndo)->portBits), 
				&wholePlayer, &wholePlayer, srcCopy, kNilPointer);
	}
	if ((theOpponent.mode != kInStasis) && (drawThisFrame))
	{
		CopyBits(&((GrafPtr)offCWorkPtr)->portBits, &(((GrafPtr)mainWndo)->portBits), 
				&wholeOpponent, &wholeOpponent, srcCopy, kNilPointer);
	}
	if ((theBall.mode == kBallRolling) && (drawThisFrame))
	{
		CopyBits(&((GrafPtr)offCWorkPtr)->portBits, &(((GrafPtr)mainWndo)->portBits), 
				&wholeBall, &wholeBall, srcCopy, kNilPointer);
	}
	else if (theBall.eraseTheBall)
	{
		CopyBits(&((GrafPtr)offCWorkPtr)->portBits, &(((GrafPtr)mainWndo)->portBits), 
				&theBall.eraser, &theBall.eraser, srcCopy, kNilPointer);
		
		theBall.eraseTheBall = FALSE;
	}
	
	if ((showBoardCursor) && (!disableBoardCursor) && (drawThisFrame))
	{
		CopyBits(&((GrafPtr)offCWorkPtr)->portBits, &(((GrafPtr)mainWndo)->portBits), 
				&wholeCursor, &wholeCursor, srcCopy, kNilPointer);
	}
	
/* and re-dick with the door */
	if (theDoor.stateChanged)
	{
		CopyBits(&((GrafPtr)offCWorkPtr)->portBits, &(((GrafPtr)mainWndo)->portBits), 
				&theDoor.destRects[theDoor.doorOpen], 
				&theDoor.destRects[theDoor.doorOpen], srcCopy, kNilPointer);
		CopyBits(&((GrafPtr)offCPartsPtr)->portBits, &((GrafPtr)offCBackPtr)->portBits, 
				&theDoor.srcRects[theDoor.doorOpen][theDoor.doorState], 
				&theDoor.destRects[theDoor.doorOpen], srcCopy, kNilPointer);
		CopyBits(&((GrafPtr)offCWorkPtr)->portBits, &((GrafPtr)offCBackPtr)->portBits, 
				&theDoor.destRects[theDoor.doorOpen], 
				&theDoor.destRects[theDoor.doorOpen], srcCopy, kNilPointer);
	}

/* plug up the holes on the work map */
	if ((thePlayer.mode != kInStasis) && (drawThisFrame))
		CopyBits(&((GrafPtr)offCBackPtr)->portBits, &((GrafPtr)offCWorkPtr)->portBits, 
				&thePlayer.isRect, &thePlayer.isRect, srcCopy, kNilPointer);
	if ((theOpponent.mode != kInStasis) && (drawThisFrame))
		CopyBits(&((GrafPtr)offCBackPtr)->portBits, &((GrafPtr)offCWorkPtr)->portBits, 
				&theOpponent.isRect, &theOpponent.isRect, srcCopy, kNilPointer);
	if ((theBall.mode == kBallRolling) && (drawThisFrame))
		CopyBits(&((GrafPtr)offCBackPtr)->portBits, &((GrafPtr)offCWorkPtr)->portBits, 
				&theBall.isRect, &theBall.isRect, srcCopy, kNilPointer);
	if ((showBoardCursor) && (!disableBoardCursor) && (drawThisFrame))
		CopyBits(&((GrafPtr)offCBackPtr)->portBits, &((GrafPtr)offCWorkPtr)->portBits, 
				&boardCursor.isRect, &boardCursor.isRect, srcCopy, kNilPointer);
}


/*========================================================  DisplayScoreDigitQD1  */

void DisplayScoreDigitQD1 (short place, short digit, short who)

{
	CopyBits(&offPartsBits, &(mainWndo->portBits), &scoreDisplays[who].srcRects[digit], 
			&scoreDisplays[who].destRects[place], srcCopy, kNilPointer);
}


/*========================================================  DisplayScoreDigitQDC  */

void DisplayScoreDigitQDC (short place, short digit, short who)

{
	CopyBits(&((GrafPtr)offCPartsPtr)->portBits, &(((GrafPtr)mainWndo)->portBits), 
			&scoreDisplays[who].srcRects[digit], 
			&scoreDisplays[who].destRects[place], srcCopy, kNilPointer);
}


/*========================================================  DisplayPlayerFoulsQD1  */

void DisplayPlayerFoulsQD1 (short fouls)

{
	Rect			srcOnRect, srcOffRect;
	short			i, selector;
	
	SetRect(&srcOnRect, 0, 56, 16, 62);
	SetRect(&srcOffRect, 0, 50, 16, 56);
	
	if (leftGoalIsPlayers)
		selector = kLeftScoreSelector;
	else
		selector = kRightScoreSelector;
	
	for (i = 0; i < 2; i++)
	{
		if (i < fouls)
			CopyBits(&offPartsBits, &(mainWndo->portBits), &srcOnRect, 
					&scoreDisplays[selector].lightDest[i], srcCopy, kNilPointer);
		else
			CopyBits(&offPartsBits, &(mainWndo->portBits), &srcOffRect, 
					&scoreDisplays[selector].lightDest[i], srcCopy, kNilPointer);
	}
}


/*========================================================  DisplayPlayerFoulsQDC  */

void DisplayPlayerFoulsQDC (short fouls)

{
	Rect			srcOnRect, srcOffRect;
	short			i, selector;
	
	SetRect(&srcOffRect, 0, 50, 16, 56);
	
	if (leftGoalIsPlayers)
	{
		SetRect(&srcOnRect, 0, 56, 16, 62);
		selector = kLeftScoreSelector;
	}
	else
	{
		SetRect(&srcOnRect, 16, 56, 32, 62);
		selector = kRightScoreSelector;
	}
	
	for (i = 0; i < 2; i++)
	{
		if (i < fouls)
			CopyBits(&((GrafPtr)offCPartsPtr)->portBits, &(((GrafPtr)mainWndo)->portBits), 
					&srcOnRect, &scoreDisplays[selector].lightDest[i], 
					srcCopy, kNilPointer);
		else
			CopyBits(&((GrafPtr)offCPartsPtr)->portBits, &(((GrafPtr)mainWndo)->portBits), 
					&srcOffRect, &scoreDisplays[selector].lightDest[i], 
					srcCopy, kNilPointer);
	}
}


/*========================================================  DisplayOpponentFoulsQD1  */

void DisplayOpponentFoulsQD1 (short fouls)

{
	Rect			srcOnRect, srcOffRect;
	short			i, selector;
	
	SetRect(&srcOnRect, 16, 56, 32, 62);
	SetRect(&srcOffRect, 0, 50, 16, 56);
	
	if (leftGoalIsPlayers)
		selector = kRightScoreSelector;
	else
		selector = kLeftScoreSelector;
	
	for (i = 0; i < 2; i++)
	{
		if (i < fouls)
			CopyBits(&offPartsBits, &(mainWndo->portBits), &srcOnRect, 
					&scoreDisplays[selector].lightDest[i], srcCopy, kNilPointer);
		else
			CopyBits(&offPartsBits, &(mainWndo->portBits), &srcOffRect, 
					&scoreDisplays[selector].lightDest[i], srcCopy, kNilPointer);
	}
}


/*========================================================  DisplayOpponentFoulsQDC  */

void DisplayOpponentFoulsQDC (short fouls)

{
	Rect			srcOnRect, srcOffRect;
	short			i, selector;
	
	SetRect(&srcOffRect, 0, 50, 16, 56);
	
	if (leftGoalIsPlayers)
	{
		selector = kRightScoreSelector;
		SetRect(&srcOnRect, 16, 56, 32, 62);
	}
	else
	{
		selector = kLeftScoreSelector;
		SetRect(&srcOnRect, 0, 56, 16, 62);
	}
	
	for (i = 0; i < 2; i++)
	{
		if (i < fouls)
			CopyBits(&((GrafPtr)offCPartsPtr)->portBits, &(((GrafPtr)mainWndo)->portBits), 
					&srcOnRect, &scoreDisplays[selector].lightDest[i], 
					srcCopy, kNilPointer);
		else
			CopyBits(&((GrafPtr)offCPartsPtr)->portBits, &(((GrafPtr)mainWndo)->portBits), 
					&srcOffRect, &scoreDisplays[selector].lightDest[i], 
					srcCopy, kNilPointer);
	}
}


/*========================================================  TwinkleAStarQD1  */

void TwinkleAStarQD1 (short whichStar)

{
	GrafPtr			wasPort;
	
	GetPort(&wasPort);
	SetPort((GrafPtr)mainWndo);
	PenMode(patXor);
	MoveTo(starList[whichStar].h, starList[whichStar].v);
	Line(0, 0);
	PenNormal();
	SetPort((GrafPtr)wasPort);
}


/*========================================================  TwinkleAStarQDC  */

void TwinkleAStarQDC (short whichStar, short color)

{
	GrafPtr			wasPort;
	
	GetPort(&wasPort);
	SetPort((GrafPtr)mainWndo);
	RGBForeColor(&starColors[color]);
	MoveTo(starList[whichStar].h, starList[whichStar].v);
	Line(0, 0);
	RGBForeColor(&RGBBlackColor);
	SetPort((GrafPtr)wasPort);
}


/*========================================================  DrawOffscreenAStarQD1  */

void DrawOffscreenAStarQD1 (short whichStar)

{
	GrafPtr			wasPort;
	
	GetPort(&wasPort);
	SetPort(offBackPtr);
	PenMode(patXor);
	MoveTo(starList[whichStar].h, starList[whichStar].v);
	Line(0, 0);
	PenNormal();
	SetPort(offWorkPtr);
	PenMode(patXor);
	MoveTo(starList[whichStar].h, starList[whichStar].v);
	Line(0, 0);
	PenNormal();
	SetPort((GrafPtr)wasPort);
}


/*========================================================  DrawOffscreenAStarQDC  */

void DrawOffscreenAStarQDC (short whichStar, short color)

{
	GrafPtr			wasPort;
	
	GetPort(&wasPort);
	
	SetPort((GrafPtr)offCBackPtr);
	RGBForeColor(&starColors[color]);
	MoveTo(starList[whichStar].h, starList[whichStar].v);
	Line(0, 0);
	RGBForeColor(&RGBBlackColor);
	
	SetPort((GrafPtr)offCWorkPtr);
	RGBForeColor(&starColors[color]);
	MoveTo(starList[whichStar].h, starList[whichStar].v);
	Line(0, 0);
	RGBForeColor(&RGBBlackColor);
	
	SetPort((GrafPtr)wasPort);
}


/*========================================================  UpdateArrowsQD1  */

void UpdateArrowsQD1 (void)

{
	switch (whosGotBall)
	{
		case kBallIsNotHere:
		case kBallRollsFreely:
			CopyBits(&offPartsBits, &(mainWndo->portBits), &leftArrowStorage, 
					&leftArrowDest, srcCopy, mainWndo->visRgn);
			CopyBits(&offPartsBits, &offBackBits, &leftArrowStorage, &leftArrowDest, 
					srcCopy, kNilPointer);
			CopyBits(&offPartsBits, &offWorkBits, &leftArrowStorage, &leftArrowDest, 
					srcCopy, kNilPointer);
			
			CopyBits(&offPartsBits, &(mainWndo->portBits), &rightArrowStorage, 
					&rightArrowDest, srcCopy, mainWndo->visRgn);
			CopyBits(&offPartsBits, &offBackBits, &rightArrowStorage, &rightArrowDest, 
					srcCopy, kNilPointer);
			CopyBits(&offPartsBits, &offWorkBits, &rightArrowStorage, &rightArrowDest, 
					srcCopy, kNilPointer);
			break;
		case kPlayerHasBall:
			if (thePlayer.whichGoal == kLeftGoal)
			{
				CopyMask(&offPartsBits, &offMaskMap, &offBackBits, &leftArrowSrc, 
						&leftArrowSrc, &leftArrowDest);
				CopyBits(&offBackBits, &offWorkBits, &leftArrowDest, &leftArrowDest, 
						srcCopy, kNilPointer);
				CopyBits(&offBackBits, &(mainWndo->portBits), &leftArrowDest, 
						&leftArrowDest, srcCopy, mainWndo->visRgn);
				
				CopyBits(&offPartsBits, &(mainWndo->portBits), &rightArrowStorage, 
						&rightArrowDest, srcCopy, mainWndo->visRgn);
				CopyBits(&offPartsBits, &offBackBits, &rightArrowStorage, 
						&rightArrowDest, srcCopy, kNilPointer);
				CopyBits(&offPartsBits, &offWorkBits, &rightArrowStorage, 
						&rightArrowDest, srcCopy, kNilPointer);
			}
			else
			{
				CopyMask(&offPartsBits, &offMaskMap, &offBackBits, &rightArrowSrc, 
						&rightArrowSrc, &rightArrowDest);
				CopyBits(&offBackBits, &(mainWndo->portBits), &rightArrowDest, 
						&rightArrowDest, srcCopy, mainWndo->visRgn);
				CopyBits(&offBackBits, &offWorkBits, &rightArrowDest, &rightArrowDest, 
						srcCopy, kNilPointer);
				
				CopyBits(&offPartsBits, &(mainWndo->portBits), &leftArrowStorage, 
						&leftArrowDest, srcCopy, mainWndo->visRgn);
				CopyBits(&offPartsBits, &offBackBits, &leftArrowStorage, 
						&leftArrowDest, srcCopy, kNilPointer);
				CopyBits(&offPartsBits, &offWorkBits, &leftArrowStorage, 
						&leftArrowDest, srcCopy, kNilPointer);
			}
			break;
		case kOpponentHasBall:
			if (theOpponent.whichGoal == kLeftGoal)
			{
				CopyMask(&offPartsBits, &offMaskMap, &offBackBits, &leftArrowSrc, 
						&leftArrowSrc, &leftArrowDest);
				CopyBits(&offBackBits, &offWorkBits, &leftArrowDest, &leftArrowDest, 
						srcCopy, kNilPointer);
				CopyBits(&offBackBits, &(mainWndo->portBits), &leftArrowDest, 
						&leftArrowDest, srcCopy, mainWndo->visRgn);
				
				CopyBits(&offPartsBits, &(mainWndo->portBits), &rightArrowStorage, 
						&rightArrowDest, srcCopy, mainWndo->visRgn);
				CopyBits(&offPartsBits, &offBackBits, &rightArrowStorage, 
						&rightArrowDest, srcCopy, kNilPointer);
				CopyBits(&offPartsBits, &offWorkBits, &rightArrowStorage, 
						&rightArrowDest, srcCopy, kNilPointer);
			}
			else
			{
				CopyMask(&offPartsBits, &offMaskMap, &offBackBits, &rightArrowSrc, 
						&rightArrowSrc, &rightArrowDest);
				CopyBits(&offBackBits, &(mainWndo->portBits), &rightArrowDest, 
						&rightArrowDest, srcCopy, mainWndo->visRgn);
				CopyBits(&offBackBits, &offWorkBits, &rightArrowDest, &rightArrowDest, 
						srcCopy, kNilPointer);
				
				CopyBits(&offPartsBits, &(mainWndo->portBits), &leftArrowStorage, 
						&leftArrowDest, srcCopy, mainWndo->visRgn);
				CopyBits(&offPartsBits, &offBackBits, &leftArrowStorage, 
						&leftArrowDest, srcCopy, kNilPointer);
				CopyBits(&offPartsBits, &offWorkBits, &leftArrowStorage, 
						&leftArrowDest, srcCopy, kNilPointer);
			}
			break;
	}
}


/*========================================================  UpdateArrowsQDC  */

void UpdateArrowsQDC (void)

{
	switch (whosGotBall)
	{
		case kBallIsNotHere:
		case kBallRollsFreely:
			CopyBits(&((GrafPtr)offCPartsPtr)->portBits, 
					&(((GrafPtr)mainWndo)->portBits), &leftArrowStorage, 
					&leftArrowDest, srcCopy, mainWndo->visRgn);
			CopyBits(&((GrafPtr)offCPartsPtr)->portBits, 
					&((GrafPtr)offCBackPtr)->portBits, &leftArrowStorage, 
					&leftArrowDest, srcCopy, kNilPointer);
			CopyBits(&((GrafPtr)offCPartsPtr)->portBits, 
					&((GrafPtr)offCWorkPtr)->portBits, &leftArrowStorage, 
					&leftArrowDest, srcCopy, kNilPointer);
			
			CopyBits(&((GrafPtr)offCPartsPtr)->portBits, 
					&(((GrafPtr)mainWndo)->portBits), &rightArrowStorage, 
					&rightArrowDest, srcCopy, mainWndo->visRgn);
			CopyBits(&((GrafPtr)offCPartsPtr)->portBits, 
					&((GrafPtr)offCBackPtr)->portBits, &rightArrowStorage, 
					&rightArrowDest, srcCopy, kNilPointer);
			CopyBits(&((GrafPtr)offCPartsPtr)->portBits, 
					&((GrafPtr)offCWorkPtr)->portBits, &rightArrowStorage, 
					&rightArrowDest, srcCopy, kNilPointer);
			break;
		case kPlayerHasBall:
			if (thePlayer.whichGoal == kLeftGoal)
			{
				CopyMask(&((GrafPtr)offCPartsPtr)->portBits, &offMaskMap, 
						&(((GrafPtr)mainWndo)->portBits), &leftArrowSrc, 
						&leftArrowSrc, &leftArrowDest);
				CopyBits(&(((GrafPtr)mainWndo)->portBits), 
						&((GrafPtr)offCBackPtr)->portBits, 
						&leftArrowDest, &leftArrowDest, srcCopy, mainWndo->visRgn);
				CopyBits(&(((GrafPtr)mainWndo)->portBits), 
						&((GrafPtr)offCWorkPtr)->portBits, 
						&leftArrowDest, &leftArrowDest, srcCopy, mainWndo->visRgn);
				
				CopyBits(&((GrafPtr)offCPartsPtr)->portBits, 
						&(((GrafPtr)mainWndo)->portBits), &rightArrowStorage, 
						&rightArrowDest, srcCopy, mainWndo->visRgn);
				CopyBits(&((GrafPtr)offCPartsPtr)->portBits, 
						&((GrafPtr)offCBackPtr)->portBits, &rightArrowStorage, 
						&rightArrowDest, srcCopy, kNilPointer);
				CopyBits(&((GrafPtr)offCPartsPtr)->portBits, 
						&((GrafPtr)offCWorkPtr)->portBits, &rightArrowStorage, 
						&rightArrowDest, srcCopy, kNilPointer);
			}
			else
			{
				CopyMask(&((GrafPtr)offCPartsPtr)->portBits, &offMaskMap, 
						&(((GrafPtr)mainWndo)->portBits), &rightArrowSrc, 
						&rightArrowSrc, &rightArrowDest);
				CopyBits(&(((GrafPtr)mainWndo)->portBits), 
						&((GrafPtr)offCBackPtr)->portBits, &rightArrowDest, 
						&rightArrowDest, srcCopy, mainWndo->visRgn);
				CopyBits(&(((GrafPtr)mainWndo)->portBits), 
						&((GrafPtr)offCWorkPtr)->portBits, &rightArrowDest, 
						&rightArrowDest, srcCopy, mainWndo->visRgn);
				
				CopyBits(&((GrafPtr)offCPartsPtr)->portBits, 
						&(((GrafPtr)mainWndo)->portBits), &leftArrowStorage, 
						&leftArrowDest, srcCopy, mainWndo->visRgn);
				CopyBits(&((GrafPtr)offCPartsPtr)->portBits, 
						&((GrafPtr)offCBackPtr)->portBits, &leftArrowStorage, 
						&leftArrowDest, srcCopy, kNilPointer);
				CopyBits(&((GrafPtr)offCPartsPtr)->portBits, 
						&((GrafPtr)offCWorkPtr)->portBits, &leftArrowStorage, 
						&leftArrowDest, srcCopy, kNilPointer);
			}
			break;
		case kOpponentHasBall:
			if (theOpponent.whichGoal == kLeftGoal)
			{
				CopyMask(&((GrafPtr)offCPartsPtr)->portBits, &offMaskMap, 
						&(((GrafPtr)mainWndo)->portBits), &leftArrowSrc, 
						&leftArrowSrc, &leftArrowDest);
				CopyBits(&(((GrafPtr)mainWndo)->portBits), 
						&((GrafPtr)offCBackPtr)->portBits, 
						&leftArrowDest, &leftArrowDest, srcCopy, mainWndo->visRgn);
				CopyBits(&(((GrafPtr)mainWndo)->portBits), 
						&((GrafPtr)offCWorkPtr)->portBits, 
						&leftArrowDest, &leftArrowDest, srcCopy, mainWndo->visRgn);
				
				CopyBits(&((GrafPtr)offCPartsPtr)->portBits, 
						&(((GrafPtr)mainWndo)->portBits), &rightArrowStorage, 
						&rightArrowDest, srcCopy, mainWndo->visRgn);
				CopyBits(&((GrafPtr)offCPartsPtr)->portBits, 
						&((GrafPtr)offCBackPtr)->portBits, &rightArrowStorage, 
						&rightArrowDest, srcCopy, kNilPointer);
				CopyBits(&((GrafPtr)offCPartsPtr)->portBits, 
						&((GrafPtr)offCWorkPtr)->portBits, &rightArrowStorage, 
						&rightArrowDest, srcCopy, kNilPointer);
			}
			else
			{
				CopyMask(&((GrafPtr)offCPartsPtr)->portBits, &offMaskMap, 
						&(((GrafPtr)mainWndo)->portBits), &rightArrowSrc, 
						&rightArrowSrc, &rightArrowDest);
				CopyBits(&(((GrafPtr)mainWndo)->portBits), 
						&((GrafPtr)offCBackPtr)->portBits, &rightArrowDest, 
						&rightArrowDest, srcCopy, mainWndo->visRgn);
				CopyBits(&(((GrafPtr)mainWndo)->portBits), 
						&((GrafPtr)offCWorkPtr)->portBits, &rightArrowDest, 
						&rightArrowDest, srcCopy, mainWndo->visRgn);
				
				CopyBits(&((GrafPtr)offCPartsPtr)->portBits, 
						&(((GrafPtr)mainWndo)->portBits), &leftArrowStorage, 
						&leftArrowDest, srcCopy, mainWndo->visRgn);
				CopyBits(&((GrafPtr)offCPartsPtr)->portBits, 
						&((GrafPtr)offCBackPtr)->portBits, &leftArrowStorage, 
						&leftArrowDest, srcCopy, kNilPointer);
				CopyBits(&((GrafPtr)offCPartsPtr)->portBits, 
						&((GrafPtr)offCWorkPtr)->portBits, &leftArrowStorage, 
						&leftArrowDest, srcCopy, kNilPointer);
			}
			break;
	}
}


/*========================================================  RedrawWholeScreen  */

void RedrawWholeScreen (void)

{
	Rect	tempRect;
	short			i;
	
	if (isColor)
		CopyBits(&((GrafPtr)offCBackPtr)->portBits, &((GrafPtr)offCWorkPtr)->portBits, 
				&offWorkRect, &offWorkRect, srcCopy, kNilPointer);
	else
		CopyBits(&offBackBits, &offWorkBits, &offWorkRect, &offWorkRect, srcCopy, 
				kNilPointer);
	
	RenderScene();
	
	if (isColor)
		CopyBits(&((GrafPtr)offCWorkPtr)->portBits, &(((GrafPtr)mainWndo)->portBits), 
				&offWorkRect, &offWorkRect, srcCopy, ((GrafPtr)mainWndo)->visRgn);
	else
		CopyBits(&offWorkBits, &(mainWndo->portBits), &offWorkRect, &offWorkRect, 
				srcCopy, mainWndo->visRgn);
	
	UpdatePlayerScore();
	DisplayPlayerFouls(playerFouls);
	UpdateOpponentScore();
	DisplayOpponentFouls(opponentFouls);
	UpdateArrows();
	
	tempRect = leftTimingDest;
	tempRect.bottom = tempRect.top;
	if (isColor)
		UpdateBallTimersQDC(&tempRect);
	else
		UpdateBallTimersQD1(&tempRect);
	
	tempRect = rightTimingDest;
	tempRect.bottom = tempRect.top;
	if (isColor)
		UpdateBallTimersQDC(&tempRect);
	else
		UpdateBallTimersQD1(&tempRect);
	
	UpdateBallTimers(&thePlayer);
	UpdateBallTimers(&theOpponent);
}


/*========================================================  ReplayBackToWorkQD1  */

void ReplayBackToWorkQD1 (void)

{
	CopyBits(&offBackBits, &offWorkBits, &cameraRect, &replayRect, srcCopy, kNilPointer);
}


/*========================================================  ReplayBackToWorkQDC  */

void ReplayBackToWorkQDC (void)

{
	CopyBits(&((GrafPtr)offCBackPtr)->portBits, &((GrafPtr)offCWorkPtr)->portBits, 
			&cameraRect, &replayRect, srcCopy, kNilPointer);
}


/*========================================================  ReplayWorkToMainQD1  */

void ReplayWorkToMainQD1 (void)

{
	CopyBits(&offWorkBits, &(mainWndo->portBits), &replayRect, &replayRect, srcCopy, 
			kNilPointer);
}


/*========================================================  ReplayWorkToMainQDC  */

void ReplayWorkToMainQDC (void)

{
	CopyBits(&((GrafPtr)offCWorkPtr)->portBits, &(((GrafPtr)mainWndo)->portBits), 
			&replayRect, &replayRect, srcCopy, kNilPointer);
}


//========================================================  DumpPict

Boolean DumpPict (short frameNumber)

{
	Str255		nameStr, digitStr;
	Rect		offReplayRect;
	PicHandle	thePict;
	CTabHandle	thisCMHandle;
	CGrafPtr	offCReplayPtr;
	CGrafPort	offCReplayPort;
	GDHandle	thisGDevice;
	GrafPtr		wasPort;
	Ptr			offReplayPix;
	long		longCount, longZero, bytesAvail, sizeOfOff;
	OSErr		err;
	short		i, vrefnum, globalRef, replayRowBytes, digit;
	
	globalRef = 0;
	if (GetVInfo(0, (StringPtr)nameStr, &vrefnum, &bytesAvail) != noErr)
		return (FALSE);
	
	PasStringCopy("\pReplay.000", nameStr);
	
	digit = frameNumber % 10;
	nameStr[10] = digit + 48;
	
	frameNumber /= 10;
	digit = frameNumber % 10;
	nameStr[9] = digit + 48;
	
	frameNumber /= 10;
	digit = frameNumber % 10;
	nameStr[8] = digit + 48;
	
	do
	{
		err = Create(nameStr, vrefnum, 'ttxt', 'PICT');
		if (err != noErr)
		{
			if (err == dupFNErr)
				nameStr[10]++;
			else
				return (FALSE);
		}
	} while (err != noErr);
	
	if (FSOpen(nameStr, vrefnum, &globalRef) != 0)
		return (FALSE);
	
	longZero = 0L;
	longCount = 4L;
	for (i = 0; i < (512 / 4); i++)
	{
		err = FSWrite(globalRef, &longCount, &longZero);
		if (err != noErr)
			return (FALSE);
	}
	
	GetPort(&wasPort);
	SetPort((GrafPtr)mainWndo);
	
	thisGDevice = GetMainDevice();
	offCReplayPtr = &offCReplayPort;
	OpenCPort(offCReplayPtr);
	SetRect(&offReplayRect, 0, 0, replayRect.right - replayRect.left, 
			replayRect.bottom - replayRect.top);
	replayRowBytes = (((4 * offReplayRect.right) + 15) >> 4) << 1;
	sizeOfOff = (long)offReplayRect.bottom * (long)replayRowBytes;
	offReplayPix = NewPtr(sizeOfOff);
	if (offReplayPix == kNilPointer)
		DeathError(kErrNoMemory);
	(**(*offCReplayPtr).portPixMap).baseAddr = offReplayPix;
	(**(*offCReplayPtr).portPixMap).rowBytes = (short)replayRowBytes + 0x8000;
	(**(*offCReplayPtr).portPixMap).bounds = offReplayRect;
	SetPort((GrafPtr)offCReplayPtr);
	ClipRect(&offReplayRect);
	thisCMHandle = (**(**thisGDevice).gdPMap).pmTable;
	err = HandToHand((Handle *)&thisCMHandle);
	if (err != noErr)
		return (FALSE);
	(**(*offCReplayPtr).portPixMap).pmTable = thisCMHandle;
	PmForeColor(kBlackColor4Bit);
	PmBackColor(kWhiteColor4Bit);
	CopyBits(&(((GrafPtr)mainWndo)->portBits), &((GrafPtr)offCReplayPtr)->portBits, 
			&replayRect, &offReplayRect, srcCopy, kNilPointer);
	
	SetPort((GrafPtr)offCReplayPtr);
	thePict = OpenPicture(&offReplayRect);
	if (thePict == kNilPointer)
		return (FALSE);
	CopyBits(&((GrafPtr)offCReplayPtr)->portBits, &((GrafPtr)offCReplayPtr)->portBits, 
			&offReplayRect, &offReplayRect, srcCopy, kNilPointer);
	ClosePicture();
	
	HLock((Handle)thePict);
	longCount = GetHandleSize((Handle)thePict);
	
	if (FSWrite(globalRef, &longCount, *thePict) != noErr)
		return (FALSE);
	HUnlock((Handle)thePict);
	
	if (FSClose(globalRef) != noErr)
		return (FALSE);
	
	KillPicture(thePict);
	
	if (offCReplayPtr != kNilPointer)
		CloseCPort(offCReplayPtr);
	if (offReplayPix != kNilPointer)
		DisposPtr(offReplayPix);
	
	SetPort(wasPort);
	return (TRUE);
}

/*========================================================  UpdateBallTimersQD1  */

void UpdateBallTimersQD1 (Rect *dest)

{
	GrafPtr			wasPort;
	
	if (dest->top == dest->bottom)
	{
		dest->bottom = dest->top + 26;
		CopyBits(&offPartsBits, &(mainWndo->portBits), &timingSource, dest, srcCopy, 
				kNilPointer);
	}
	else
	{
		GetPort((GrafPtr *)&wasPort);
		SetPort((GrafPtr)mainWndo);
		PaintRect(dest);
		SetPort((GrafPtr)wasPort);
	}
}


/*========================================================  UpdateBallTimersQDC  */

void UpdateBallTimersQDC (Rect *dest)

{
	GrafPtr			wasPort;
	
	if (dest->top == dest->bottom)
	{
		dest->bottom = dest->top + 26;
		CopyBits(&((GrafPtr)offCPartsPtr)->portBits, &(((GrafPtr)mainWndo)->portBits), 
				&timingSource, dest, srcCopy, kNilPointer);
	}
	else
	{
		GetPort((GrafPtr *)&wasPort);
		SetPort((GrafPtr)mainWndo);
		PaintRect(dest);
		SetPort((GrafPtr)wasPort);
	}
}

