/*============================================================*/
/*============================================================*/
/*==														==*/
/*==			Instant Replay Handling Routines			==*/
/*==														==*/
/*============================================================*/
/*============================================================*/


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

#include "Globals.h"
#include "UnivUtilities.h"
#include "Replay.h"
#include "Render.h"
#include "RenderQD.h"
#include "NetOpponent.h"
#include "RenderAsm1.h"
#include "RenderAsm4.h"


/*========================================================  Functions  */
/*========================================================  AmassReplayData  */

void AmassReplayData (void)

{
	short			theFrame;
	
	if (canReplay)
	{
		replayData->frame++;
		
		if (replayData->frame >= kMaxReplayFrames)
			replayData->frame = 0;
		
		theFrame = replayData->frame;
		
		replayData->data[theFrame].playerIs = thePlayer.isRect;
		replayData->data[theFrame].opponentIs = theOpponent.isRect;
		replayData->data[theFrame].ballIs = theBall.isRect;
		if (leftGoalIsPlayers)
			replayData->data[theFrame].playerArraySrc = kPlayerSrc;
		else
			replayData->data[theFrame].playerArraySrc = kOpponentSrc;
		replayData->data[theFrame].playerDirSrc = thePlayer.dirFlagSrc;
		replayData->data[theFrame].playerPostSrc = thePlayer.postFlagSrc;
		replayData->data[theFrame].playerArrayMask = thePlayer.arrayFlagMask;
		replayData->data[theFrame].playerDirMask = thePlayer.dirFlagMask;
		replayData->data[theFrame].playerPostMask = thePlayer.postFlagMask;
		replayData->data[theFrame].playerMode = thePlayer.mode;
		if (leftGoalIsPlayers)
			replayData->data[theFrame].opponentArraySrc = kOpponentSrc;
		else
			replayData->data[theFrame].opponentArraySrc = kPlayerSrc;
		replayData->data[theFrame].opponentDirSrc = theOpponent.dirFlagSrc;
		replayData->data[theFrame].opponentPostSrc = theOpponent.postFlagSrc;
		replayData->data[theFrame].opponentArrayMask = theOpponent.arrayFlagMask;
		replayData->data[theFrame].opponentDirMask = theOpponent.dirFlagMask;
		replayData->data[theFrame].opponentPostMask = theOpponent.postFlagMask;
		replayData->data[theFrame].opponentMode = theOpponent.mode;
		replayData->data[theFrame].ballMode = theBall.mode;
		replayData->data[theFrame].wheresBall = whosGotBall;
		replayData->data[theFrame].ballDontDraw = theBall.dontDraw;
	}
}


/*========================================================  DoInstantReplay  */

void DoInstantReplay (void)

{
	Rect			playerIsRect, opponentIsRect, ballIsRect, zoomFrame;
	RgnHandle		wasClip, newClip;
	GrafPtr			wasPort;
	long			nowTime, waitFor, dummyLong;
	short			theFrame, i, replayTickDelay, zoomWide, zoomHigh, wasFrame;
	char			ballsMode;
	Boolean			confirmed, doQuicktime;
	
	if (!canReplay)
		return;
	
	doQuicktime = (isColor && OptionKeyIsDown() && CommandKeyIsDown());
	
	nowTime = Ticks;
	
	HandlePreGraphics();
	RenderScene();
	
	zoomFrame = replayRect;
	
	GetPort(&wasPort);
	SetPort((GrafPtr)mainWndo);
	
	wasClip = NewRgn();
	if (wasClip != kNilPointer)
		CopyRgn((RgnHandle)((GrafPtr)mainWndo->visRgn), wasClip);
	
	newClip = NewRgn();
	if (newClip != kNilPointer)
	{
		RectRgn(newClip, &screenBits.bounds);
		CopyRgn(newClip, (RgnHandle)((GrafPtr)mainWndo->visRgn));
	}
	
	if (replayZooms)
	{
		InsetRect(&zoomFrame, 63, 63);
		
		for (i = 1; i < 65; i++)
		{
			PenPat(black);
			FrameRect(&zoomFrame);
			InsetRect(&zoomFrame, -1, -1);
			PenPat(white);
			FrameRect(&zoomFrame);
		}
	}
	else
	{
		FillRect(&zoomFrame, black);
		InsetRect(&zoomFrame, -1, -1);
		PenPat(white);
		FrameRect(&zoomFrame);
	}
	
	PenNormal();
	SetPort((GrafPtr)wasPort);
	
	replayData->hVel = 0;
	replayData->vVel = 0;
	wasFrame = replayData->frame;
	
	replayData->frame++;
	if (replayData->frame >= kMaxReplayFrames)
		replayData->frame = 0;
	
	theFrame = replayData->frame;
	
	playerIsRect = replayData->data[theFrame].playerIs;
	opponentIsRect = replayData->data[theFrame].opponentIs;
	ballIsRect = replayData->data[theFrame].ballIs;
	ballsMode = replayData->data[theFrame].ballMode;
	
	if (ballsMode == kBallRolling)
	{
		cameraRect.left = ballIsRect.left - 96;
		cameraRect.top = ballIsRect.top - 64;
		cameraRect.right = cameraRect.left + 192;
		cameraRect.bottom = cameraRect.top + 128;
	}
	else if (playerJustScored)
	{
		cameraRect.left = playerIsRect.left - 96;
		cameraRect.top = playerIsRect.top - 64;
		cameraRect.right = cameraRect.left + 192;
		cameraRect.bottom = cameraRect.top + 128;
	}
	else
	{
		cameraRect.left = opponentIsRect.left - 96;
		cameraRect.top = opponentIsRect.top - 64;
		cameraRect.right = cameraRect.left + 192;
		cameraRect.bottom = cameraRect.top + 128;
	}
	
	if (cameraRect.left < 0)
	{
		cameraRect.left = 0;
		cameraRect.right = cameraRect.left + 192;
	}
	else if (cameraRect.right > screenWide)
	{
		cameraRect.left = screenWide - 192;
		cameraRect.right = cameraRect.left + 192;
	}
	
	if (cameraRect.top < 0)
	{
		cameraRect.top = 0;
		cameraRect.bottom = cameraRect.top + 128;
	}
	else if (cameraRect.bottom > screenHigh)
	{
		cameraRect.top = screenHigh - 128;
		cameraRect.bottom = cameraRect.top + 128;
	}
	
	while (Button());
	
	replayTickDelay = 1;
	waitFor = Ticks + (long)replayTickDelay;
	
	for (i = 0; i < (kMaxReplayFrames); i++)
	{
		RenderInstantReplay();
		
		if (doQuicktime && ((i % 2) == 0))
			doQuicktime = DumpPict(i / 2);
		
		while (Ticks < waitFor);
		
		if (i < 200)
			replayTickDelay = 2;
		else if (i < 275)
			replayTickDelay = 4;
		else
			replayTickDelay = 8;
		
		if (Button())
			break;
		
		waitFor = Ticks + replayTickDelay;
		
		replayData->frame++;
		if (replayData->frame >= kMaxReplayFrames)
			replayData->frame = 0;
	}
	
	replayData->frame = wasFrame;
	
	while (Button());
	
	RedrawWholeScreen();
	
	if (wasClip != kNilPointer)
	{
		CopyRgn(wasClip, (RgnHandle)((GrafPtr)mainWndo->visRgn));
		DisposeRgn(wasClip);
	}
	if (newClip != kNilPointer)
		DisposeRgn(newClip);
	
	if (netGameInSession)
	{
		confirmed = WaitForSynch(1200);
	}
	
	nowTime = Ticks - nowTime;
	baseTime += (nowTime / 60L);
}


/*========================================================  RenderInstantReplayQD1  */

void RenderInstantReplayQD1 (void)

{
	Rect			playerIsRect, opponentIsRect, ballIsRect;
	Rect			playerSrcRect, opponentSrcRect;
	Rect			playerMaskRect, opponentMaskRect;
	Point			cameraPt;
	short			theFrame;
	char			playersMode, opponentsMode, ballsMode, whereBall;
	Boolean			ballDontDraw;
	
	theFrame = replayData->frame;
	
	playerIsRect = replayData->data[theFrame].playerIs;
	opponentIsRect = replayData->data[theFrame].opponentIs;
	ballIsRect = replayData->data[theFrame].ballIs;
	playersMode = replayData->data[theFrame].playerMode;
	opponentsMode = replayData->data[theFrame].opponentMode;
	ballsMode = replayData->data[theFrame].ballMode;
	whereBall = replayData->data[theFrame].wheresBall;
	ballDontDraw = replayData->data[theFrame].ballDontDraw;
	
	if (replayData->data[theFrame].playerArraySrc == kPlayerSrc)
		playerSrcRect = playerSrcRects[replayData->data[theFrame].playerDirSrc]
				[replayData->data[theFrame].playerPostSrc];
	else
		playerSrcRect = opponentSrcRects[replayData->data[theFrame].playerDirSrc]
				[replayData->data[theFrame].playerPostSrc];
	if (replayData->data[theFrame].playerArrayMask == kMask)
		playerMaskRect = playerSrcRects[replayData->data[theFrame].playerDirMask]
				[replayData->data[theFrame].playerPostMask];
	else
		playerMaskRect = fadeMaskRects[replayData->data[theFrame].playerDirMask]
				[replayData->data[theFrame].playerPostMask];
	
	if (replayData->data[theFrame].opponentArraySrc == kPlayerSrc)
		opponentSrcRect = playerSrcRects[replayData->data[theFrame].opponentDirSrc]
				[replayData->data[theFrame].opponentPostSrc];
	else
		opponentSrcRect = opponentSrcRects[replayData->data[theFrame].opponentDirSrc]
				[replayData->data[theFrame].opponentPostSrc];
	if (replayData->data[theFrame].opponentArrayMask == kMask)
		opponentMaskRect = playerSrcRects[replayData->data[theFrame].opponentDirMask]
				[replayData->data[theFrame].opponentPostMask];
	else
		opponentMaskRect = fadeMaskRects[replayData->data[theFrame].opponentDirMask]
				[replayData->data[theFrame].opponentPostMask];
	
	if (whereBall == kBallRollsFreely)
	{
		cameraPt.h = ballIsRect.left - 96;
		cameraPt.v = ballIsRect.top - 64;
	}
	else if (whereBall == kPlayerHasBall)
	{
		cameraPt.h = playerIsRect.left - 96;
		cameraPt.v = playerIsRect.top - 64;
	}
	else if (whereBall == kOpponentHasBall)
	{
		cameraPt.h = opponentIsRect.left - 96;
		cameraPt.v = opponentIsRect.top - 64;
	}
	else
	{
		cameraPt.h = cameraRect.left;
		cameraPt.v = cameraRect.top;
	}
	
	replayData->hVel = (replayData->hVel / 2) + (cameraPt.h - cameraRect.left) / 
			kCameraInertia;
	replayData->vVel = (replayData->vVel / 2) + (cameraPt.v - cameraRect.top) / 
			kCameraInertia;
	
	cameraRect.left += replayData->hVel;
	cameraRect.top += replayData->vVel;
	cameraRect.right = cameraRect.left + 192;
	cameraRect.bottom = cameraRect.top + 128;
	
	if (cameraRect.left < 0)
	{
		cameraRect.left = 0;
		cameraRect.right = cameraRect.left + 192;
	}
	else if (cameraRect.right > screenWide)
	{
		cameraRect.left = screenWide - 192;
		cameraRect.right = cameraRect.left + 192;
	}
	
	if (cameraRect.top < 0)
	{
		cameraRect.top = 0;
		cameraRect.bottom = cameraRect.top + 128;
	}
	else if (cameraRect.bottom > screenHigh)
	{
		cameraRect.top = screenHigh - 128;
		cameraRect.bottom = cameraRect.top + 128;
	}
	
	playerIsRect.left = replayRect.left + playerIsRect.left - cameraRect.left;
	playerIsRect.right = playerIsRect.left + 32;
	playerIsRect.top = replayRect.top + playerIsRect.top - cameraRect.top;
	playerIsRect.bottom = playerIsRect.top + 44;
	
	opponentIsRect.left = replayRect.left + opponentIsRect.left - cameraRect.left;
	opponentIsRect.right = opponentIsRect.left + 32;
	opponentIsRect.top = replayRect.top + opponentIsRect.top - cameraRect.top;
	opponentIsRect.bottom = opponentIsRect.top + 44;
	
	ballIsRect.left = replayRect.left + ballIsRect.left - cameraRect.left;
	ballIsRect.right = ballIsRect.left + 16;
	ballIsRect.top = replayRect.top + ballIsRect.top - cameraRect.top;
	ballIsRect.bottom = ballIsRect.top + 12;
	
	ReplayBackToWorkQD1();
	
	if ((ballsMode == kBallRolling) && (!ballDontDraw))
		CopyMask(&offPartsBits, &offMaskMap, &offWorkBits, &theBall.srcRect, 
				&theBall.srcRect, &ballIsRect);
	
	if (playerIsRect.bottom < opponentIsRect.bottom)
	{
		if (playersMode != kInStasis)
			CopyMask(&offPartsBits, &offMaskMap, &offWorkBits, &playerSrcRect, 
					&playerMaskRect, &playerIsRect);
		if (opponentsMode != kInStasis)
			CopyMask(&offPartsBits, &offMaskMap, &offWorkBits, &opponentSrcRect, 
					&opponentMaskRect, &opponentIsRect);
	}
	else
	{
		if (opponentsMode != kInStasis)
			CopyMask(&offPartsBits, &offMaskMap, &offWorkBits, &opponentSrcRect, 
					&opponentMaskRect, &opponentIsRect);
		if (playersMode != kInStasis)
			CopyMask(&offPartsBits, &offMaskMap, &offWorkBits, &playerSrcRect, 
					&playerMaskRect, &playerIsRect);
	}
	
	if ((Ticks % 20) <= 15)
	{
		SetPort(offWorkPtr);
		MoveTo(replayRect.left + 4, replayRect.bottom - 4);
		TextMode(srcBic);
		TextFont(geneva);
		TextSize(9);
		DrawString("\pINSTANT REPLAY");
		PenPat(black);
	}
	
	if (useQD)
		ReplayWorkToMainQD1();
	else
		ReplayWorkToMainAsm1();
}


/*========================================================  RenderInstantReplayQDC  */

void RenderInstantReplayQDC (void)

{
	Rect			playerIsRect, opponentIsRect, ballIsRect;
	Rect			playerSrcRect, opponentSrcRect;
	Rect			playerMaskRect, opponentMaskRect;
	Point			cameraPt;
	short			theFrame;
	char			playersMode, opponentsMode, ballsMode, whereBall;
	Boolean			ballDontDraw;
	
	theFrame = replayData->frame;
	
	playerIsRect = replayData->data[theFrame].playerIs;
	opponentIsRect = replayData->data[theFrame].opponentIs;
	ballIsRect = replayData->data[theFrame].ballIs;
	playersMode = replayData->data[theFrame].playerMode;
	opponentsMode = replayData->data[theFrame].opponentMode;
	ballsMode = replayData->data[theFrame].ballMode;
	whereBall = replayData->data[theFrame].wheresBall;
	ballDontDraw = replayData->data[theFrame].ballDontDraw;
	
	if (replayData->data[theFrame].playerArraySrc == kPlayerSrc)
		playerSrcRect = playerSrcRects[replayData->data[theFrame].playerDirSrc]
				[replayData->data[theFrame].playerPostSrc];
	else
		playerSrcRect = opponentSrcRects[replayData->data[theFrame].playerDirSrc]
				[replayData->data[theFrame].playerPostSrc];
	if (replayData->data[theFrame].playerArrayMask == kMask)
		playerMaskRect = playerSrcRects[replayData->data[theFrame].playerDirMask]
				[replayData->data[theFrame].playerPostMask];
	else
		playerMaskRect = fadeMaskRects[replayData->data[theFrame].playerDirMask]
				[replayData->data[theFrame].playerPostMask];
	
	if (replayData->data[theFrame].opponentArraySrc == kPlayerSrc)
		opponentSrcRect = playerSrcRects[replayData->data[theFrame].opponentDirSrc]
				[replayData->data[theFrame].opponentPostSrc];
	else
		opponentSrcRect = opponentSrcRects[replayData->data[theFrame].opponentDirSrc]
				[replayData->data[theFrame].opponentPostSrc];
	if (replayData->data[theFrame].opponentArrayMask == kMask)
		opponentMaskRect = playerSrcRects[replayData->data[theFrame].opponentDirMask]
				[replayData->data[theFrame].opponentPostMask];
	else
		opponentMaskRect = fadeMaskRects[replayData->data[theFrame].opponentDirMask]
				[replayData->data[theFrame].opponentPostMask];
	
	if (whereBall == kBallRollsFreely)
	{
		cameraPt.h = ballIsRect.left - 96;
		cameraPt.v = ballIsRect.top - 64;
	}
	else if (whereBall == kPlayerHasBall)
	{
		cameraPt.h = playerIsRect.left - 96;
		cameraPt.v = playerIsRect.top - 64;
	}
	else if (whereBall == kOpponentHasBall)
	{
		cameraPt.h = opponentIsRect.left - 96;
		cameraPt.v = opponentIsRect.top - 64;
	}
	else
	{
		cameraPt.h = cameraRect.left;
		cameraPt.v = cameraRect.top;
	}
	
	replayData->hVel = (cameraPt.h - cameraRect.left) / kCameraInertia;
	replayData->vVel = (cameraPt.v - cameraRect.top) / kCameraInertia;
	
	cameraRect.left += replayData->hVel;
	cameraRect.top += replayData->vVel;
	cameraRect.right = cameraRect.left + 192;
	cameraRect.bottom = cameraRect.top + 128;
	
	if (cameraRect.left < 0)
	{
		cameraRect.left = 0;
		cameraRect.right = cameraRect.left + 192;
	}
	else if (cameraRect.right > screenWide)
	{
		cameraRect.left = screenWide - 192;
		cameraRect.right = cameraRect.left + 192;
	}
	
	if (cameraRect.top < 0)
	{
		cameraRect.top = 0;
		cameraRect.bottom = cameraRect.top + 128;
	}
	else if (cameraRect.bottom > screenHigh)
	{
		cameraRect.top = screenHigh - 128;
		cameraRect.bottom = cameraRect.top + 128;
	}
	
	playerIsRect.left = replayRect.left + playerIsRect.left - cameraRect.left;
	playerIsRect.right = playerIsRect.left + 32;
	playerIsRect.top = replayRect.top + playerIsRect.top - cameraRect.top;
	playerIsRect.bottom = playerIsRect.top + 44;
	
	opponentIsRect.left = replayRect.left + opponentIsRect.left - cameraRect.left;
	opponentIsRect.right = opponentIsRect.left + 32;
	opponentIsRect.top = replayRect.top + opponentIsRect.top - cameraRect.top;
	opponentIsRect.bottom = opponentIsRect.top + 44;
	
	ballIsRect.left = replayRect.left + ballIsRect.left - cameraRect.left;
	ballIsRect.right = ballIsRect.left + 16;
	ballIsRect.top = replayRect.top + ballIsRect.top - cameraRect.top;
	ballIsRect.bottom = ballIsRect.top + 12;
	
	ReplayBackToWorkQDC();
	
	if ((ballsMode == kBallRolling) && (!ballDontDraw))
		CopyMask(&((GrafPtr)offCPartsPtr)->portBits, &offMaskMap, 
				&((GrafPtr)offCWorkPtr)->portBits, &theBall.srcRect, 
				&theBall.srcRect, &ballIsRect);
	
	if (playerIsRect.bottom < opponentIsRect.bottom)
	{
		if (playersMode != kInStasis)
			CopyMask(&((GrafPtr)offCPartsPtr)->portBits, &offMaskMap, 
					&((GrafPtr)offCWorkPtr)->portBits, &playerSrcRect, 
					&playerMaskRect, &playerIsRect);
		if (opponentsMode != kInStasis)
			CopyMask(&((GrafPtr)offCPartsPtr)->portBits, &offMaskMap, 
					&((GrafPtr)offCWorkPtr)->portBits, &opponentSrcRect, 
					&opponentMaskRect, &opponentIsRect);
	}
	else
	{
		if (opponentsMode != kInStasis)
			CopyMask(&((GrafPtr)offCPartsPtr)->portBits, &offMaskMap, 
					&((GrafPtr)offCWorkPtr)->portBits, &opponentSrcRect, 
					&opponentMaskRect, &opponentIsRect);
		if (playersMode != kInStasis)
			CopyMask(&((GrafPtr)offCPartsPtr)->portBits, &offMaskMap, 
					&((GrafPtr)offCWorkPtr)->portBits, &playerSrcRect, 
					&playerMaskRect, &playerIsRect);
	}
	
	if ((Ticks % 20) <= 15)
	{
		SetPort((GrafPtr)offCWorkPtr);
		MoveTo(replayRect.left + 4, replayRect.bottom - 4);
		TextFont(geneva);
		TextSize(9);
		ForeColor(whiteColor);
		DrawString("\pINSTANT REPLAY");
		ForeColor(blackColor);
	}
	
	if (useQD)
		ReplayWorkToMainQDC();
	else
		ReplayWorkToMainAsm4();
}


/*========================================================  RenderInstantReplay  */

void RenderInstantReplay (void)

{
	if (isColor)
	{
		RenderInstantReplayQDC();
	}
	else
		RenderInstantReplayQD1();
}


