Pararena2/Sources/Replay.c

1 line
17 KiB
C
Executable File

/*============================================================*/
/*============================================================*/
/*== ==*/
/*== 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();
}