unit PlaySetUp;

interface
	uses
		SMS, Balloons, Palettes, Globals, GlobalUtils, FileInNOut, PlayUtils;

	procedure HorizonMouse;
	procedure WrapItUp;
	procedure OffAMortal;
	procedure AdvanceARoom;
	procedure RetreatARoom;
	procedure UpAFlight (whatRoom: Integer);
	procedure DownAFlight (whatRoom: Integer);
	procedure Transport (whatRoom: Integer);

implementation

{=================================}

	procedure HorizonMouse;
		const
			MBState = $172;
			MTemp = $828;
			RawMouse = $82C;
			Mouse = $830;
			CrsrNew = $8CE;
			CrsrCouple = $8CF;
			Couple = $FF;
			Uncouple = $00;
		var
			horizon: Point;
			lowGlob: Integer;
			lowMem: Ptr;
			pointPtr: ^Point;

	begin
		GetMouse(horizon);
		horizon.v := 160;
		lowMem := Pointer(rawMouse);
		pointPtr := @lowMem^;
		pointPtr^ := horizon;
		lowMem := Pointer(MTemp);
		pointPtr := @lowMem^;
		pointPtr^ := horizon;
		lowMem := Pointer(CrsrNew);
		lowMem^ := $FFFF;
	end;

{=================================}

	procedure ClosingAnimation;
		const
			waitTicks = 4;
		var
			i, refNumber, whichTwist: Integer;
			twisterDst, tinyGliderDst, tinyGliderSrc, wasRect, wasGlider, boltRect: Rect;
			twisterSrc: array[0..3] of Rect;
			timeWas: LongInt;
			tempByte: SignedByte;
			thePict: PicHandle;
			boltWasCast, hasLetUpOnButton: Boolean;

{--------------}

		procedure CastBolt;
			const
				cloudBottom = 140;
				boltLength = 8;
			var
				i, start, finish: Integer;
		begin
			SetRect(boltRect, 512, cloudBottom, 0, (boltLength + 1) * 8 + cloudBottom + 2);

			if (inColor) then
				RGBForeColor(rgbWhite)
			else
				PenPat(white);

			start := Randomize(100) + 200;

			for i := 0 to boltLength do
			begin
				finish := Randomize(7) - 3 + start;
				MoveTo(start, i * 8 + cloudBottom + 1);
				LineTo(finish, (i + 1) * 8 + cloudBottom);

				if (start <= boltRect.left) then
					boltRect.left := start;
				if (finish <= boltRect.left) then
					boltRect.left := finish;
				if (start >= boltRect.right) then
					boltRect.right := start;
				if (finish >= boltRect.right) then
					boltRect.right := finish;

				start := finish;
			end;

			if (inColor) then
				RGBForeColor(rgbBlack)
			else
				PenPat(black);
			boltWasCast := TRUE;
			InsetRect(boltRect, -2, 0);
		end;

{--------------}

	begin
		RedrawWindowFrame;

		SetRect(twisterSrc[0], 208, 126, 256, 188);
		SetRect(twisterSrc[1], 208, 189, 256, 251);
		SetRect(twisterSrc[2], 208, 252, 256, 314);
		SetRect(twisterSrc[3], 256, 268, 304, 330);
		SetRect(tinyGliderSrc, 235, 315, 256, 325);

		twisterDst := twisterSrc[0];
		OffsetRect(twisterDst, -twisterDst.left, -twisterDst.top);
		OffsetRect(twisterDst, 230, 138);

		tinyGliderDst := tinyGliderSrc;
		OffsetRect(tinyGliderDst, -tinyGliderDst.left, -tinyGliderDst.top);
		OffsetRect(tinyGliderDst, 420, 90);
		wasGlider := tinyGliderDst;

		boltWasCast := FALSE;

		if (inColor) then
			SetPort(GrafPtr(virginCPtr))
		else
			SetPort(offVirginPort);

		refNumber := OpenResFile(resourceName);
		if (refNumber = -1) then
		begin
			UseResFile(gliderResNum);
			GenericAlert(kErrGraphicsNotFound);
			ShowMenuBar;
			if (not DoOpen(kArtType)) then
				Exit(ClosingAnimation);
			refNumber := OpenResFile(resourceName);
			if (refNumber = -1) then
			begin
				GenericAlert(kErrGraphicsNotFound);
				ShowMenuBar;
				Exit(ClosingAnimation);
			end;
		end;

		thePict := GetPicture(rFarmPict);
		if (thePict <> nil) then
		begin
			tempByte := HGetState(Handle(thePict));
			MoveHHi(Handle(thePict));
			HLock(Handle(thePict));
			DrawPicture(thePict, wholeArea);
			HSetState(Handle(thePict), tempByte);
			ReleaseResource(Handle(thePict));
		end
		else
			GenericAlert(kErrGraphicLoad);

		CloseResFile(refNumber);
		UseResFile(gliderResNum);

		DissBlocks;
		whichTwist := 0;

		PenNormal;
		if (inColor) then
			SetPort(GrafPtr(mainWndo))
		else
			SetPort(mainWndo);

		hasLetUpOnButton := FALSE;

		for i := 1 to 200 do
		begin
			timeWas := TickCount + waitTicks;
			wasRect := twisterDst;

			whichTwist := i mod 4;
			if ((i mod 4) = 0) then
			begin
				whichTwist := whichTwist + 1;
				if (whichTwist > 3) then
					whichTwist := 0;
				OffsetRect(twisterDst, -1, 0);
				wasRect.right := wasRect.right + 1;
			end;

			OffsetRect(tinyGliderDst, -2, -(i mod 2));
			wasGlider := tinyGliderDst;
			wasGlider.right := wasGlider.right + 2;
			wasGlider.bottom := wasGlider.bottom + 1;

			if (Randomize(20) = 0) then
				CastBolt;

			if (inColor) then
			begin
				CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, BitMapPtr(loadCPtr^.portPixMap^)^, wasRect, wasRect, srcCopy, nil);
				CopyMask(BitMapPtr(objectCPtr^.portPixMap^)^, offMaskMap, BitMapPtr(loadCPtr^.portPixMap^)^, twisterSrc[whichTwist], twisterSrc[whichTwist], twisterDst);
				CopyBits(BitMapPtr(loadCPtr^.portPixMap^)^, GrafPtr(mainWndo)^.portBits, wasRect, wasRect, srcCopy, nil);
			end
			else
			begin
				CopyBits(offVirginMap, offLoadMap, wasRect, wasRect, srcCopy, nil);
				CopyMask(offPlayerMap, offMaskMap, offLoadMap, twisterSrc[whichTwist], twisterSrc[whichTwist], twisterDst);
				CopyBits(offLoadMap, mainWndo^.portBits, wasRect, wasRect, srcCopy, nil);
			end;

			if (inColor) then
			begin
				CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, BitMapPtr(loadCPtr^.portPixMap^)^, wasGlider, wasGlider, srcCopy, nil);
				CopyMask(BitMapPtr(objectCPtr^.portPixMap^)^, offMaskMap, BitMapPtr(loadCPtr^.portPixMap^)^, tinyGliderSrc, tinyGliderSrc, tinyGliderDst);
				CopyBits(BitMapPtr(loadCPtr^.portPixMap^)^, GrafPtr(mainWndo)^.portBits, wasGlider, wasGlider, srcCopy, wholeRgn);
			end
			else
			begin
				CopyBits(offVirginMap, offLoadMap, wasGlider, wasGlider, srcCopy, nil);
				CopyMask(offPlayerMap, offMaskMap, offLoadMap, tinyGliderSrc, tinyGliderSrc, tinyGliderDst);
				CopyBits(offLoadMap, mainWndo^.portBits, wasGlider, wasGlider, srcCopy, wholeRgn);
			end;

			repeat
				if (Button) then
				begin
					if (hasLetUpOnButton) then
						Leave;
				end
				else
					hasLetUpOnButton := TRUE;
				GetKeys(theKeys);
				if (theKeys[kReturnKeyMap]) then
					Leave;
			until (TickCount > timeWas);

			timeWas := TickCount + waitTicks;

			if (Button) then
			begin
				if (hasLetUpOnButton) then
					Leave;
			end
			else
				hasLetUpOnButton := TRUE;
			GetKeys(theKeys);
			if (theKeys[kReturnKeyMap]) then
				Leave;

			if (boltWasCast) then
			begin
				DoTheSound(17);
				if (inColor) then
					CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, GrafPtr(mainWndo)^.portBits, boltRect, boltRect, srcCopy, wholeRgn)
				else
					CopyBits(offVirginMap, mainWndo^.portBits, boltRect, boltRect, srcCopy, wholeRgn);
				boltWasCast := FALSE;
			end;
		end;

	end;

{=================================}

	procedure GameOver;
		const
			timeBetween = 6;
		var
			i, i2, leftOff, topOff, whichLetter: Integer;
			dummyLong: LongInt;
			letters: array[0..6] of Rect;
			dest: Rect;
			tempStr: Str255;
			hasLetUpOnButton: Boolean;

	begin
		SetRect(letters[0], 375, 33, 409, 78);	{G}
		SetRect(letters[1], 375, 77, 409, 122);	{a}
		SetRect(letters[2], 375, 121, 409, 166);	{m}
		SetRect(letters[3], 375, 165, 409, 210);	{e}
		SetRect(letters[4], 375, 209, 409, 254);	{O}
		SetRect(letters[5], 375, 253, 409, 298);	{v}
		SetRect(letters[6], 375, 297, 409, 342);	{r}

		hasLetUpOnButton := FALSE;

		if (inColor) then
			SetPort(GrafPtr(virginCPtr))
		else
			SetPort(offVirginPort);
		FillRect(wholeArea, black);
		NumToString(roomScore + suppScore, tempStr);
		if (inColor) then
		begin
			PenNormal;
			TextFont(204);
			TextSize(32);
			MoveTo(120, 80);
			RGBForeColor(rgbYellow);
			PenMode(srcOr);
			DrawString(tempStr);
			PenNormal;
			RGBForeColor(rgbBlack);
			TextFont(SystemFont);
			TextSize(12);
		end
		else
		begin
			TextFont(204);
			TextSize(32);
			TextMode(patXOr);
			MoveTo(120, 80);
			DrawString(tempStr);
			TextFont(SystemFont);
			TextSize(12);
		end;

		DissBlocks;

		SetRect(dest, 0, 0, 34, 45);
		OffsetRect(dest, 113, 100);

		DoTheSound(21);
		if (inColor) then
			CopyBits(BitMapPtr(objectCPtr^.portPixMap^)^, GrafPtr(mainWndo)^.portBits, letters[0], dest, srcCopy, nil)
		else
			CopyBits(offPlayerMap, mainWndo^.portBits, letters[0], dest, srcCopy, nil);
		OffsetRect(dest, 36, 0);
		Delay(timeBetween, dummyLong);
		DoTheSound(21);
		if (inColor) then
			CopyBits(BitMapPtr(objectCPtr^.portPixMap^)^, GrafPtr(mainWndo)^.portBits, letters[1], dest, srcCopy, nil)
		else
			CopyBits(offPlayerMap, mainWndo^.portBits, letters[1], dest, srcCopy, nil);
		OffsetRect(dest, 36, 0);
		Delay(timeBetween, dummyLong);
		DoTheSound(21);
		if (inColor) then
			CopyBits(BitMapPtr(objectCPtr^.portPixMap^)^, GrafPtr(mainWndo)^.portBits, letters[2], dest, srcCopy, nil)
		else
			CopyBits(offPlayerMap, mainWndo^.portBits, letters[2], dest, srcCopy, nil);
		OffsetRect(dest, 36, 0);
		Delay(timeBetween, dummyLong);
		DoTheSound(21);
		if (inColor) then
			CopyBits(BitMapPtr(objectCPtr^.portPixMap^)^, GrafPtr(mainWndo)^.portBits, letters[3], dest, srcCopy, nil)
		else
			CopyBits(offPlayerMap, mainWndo^.portBits, letters[3], dest, srcCopy, nil);
		OffsetRect(dest, 36, 0);
		Delay(timeBetween, dummyLong);
		DoTheSound(21);
		if (inColor) then
			CopyBits(BitMapPtr(objectCPtr^.portPixMap^)^, GrafPtr(mainWndo)^.portBits, letters[4], dest, srcCopy, nil)
		else
			CopyBits(offPlayerMap, mainWndo^.portBits, letters[4], dest, srcCopy, nil);
		OffsetRect(dest, 36, 0);
		Delay(timeBetween, dummyLong);
		DoTheSound(21);
		if (inColor) then
			CopyBits(BitMapPtr(objectCPtr^.portPixMap^)^, GrafPtr(mainWndo)^.portBits, letters[5], dest, srcCopy, nil)
		else
			CopyBits(offPlayerMap, mainWndo^.portBits, letters[5], dest, srcCopy, nil);
		OffsetRect(dest, 36, 0);
		Delay(timeBetween, dummyLong);
		DoTheSound(21);
		if (inColor) then
			CopyBits(BitMapPtr(objectCPtr^.portPixMap^)^, GrafPtr(mainWndo)^.portBits, letters[3], dest, srcCopy, nil)
		else
			CopyBits(offPlayerMap, mainWndo^.portBits, letters[3], dest, srcCopy, nil);
		OffsetRect(dest, 36, 0);
		Delay(timeBetween, dummyLong);
		DoTheSound(21);
		if (inColor) then
			CopyBits(BitMapPtr(objectCPtr^.portPixMap^)^, GrafPtr(mainWndo)^.portBits, letters[6], dest, srcCopy, nil)
		else
			CopyBits(offPlayerMap, mainWndo^.portBits, letters[6], dest, srcCopy, nil);

		for i := 1 to 20 do
		begin

			if (Button) then
			begin
				if (hasLetUpOnButton) then
					Leave;
			end
			else
				hasLetUpOnButton := TRUE;
			GetKeys(theKeys);
			if (theKeys[kReturnKeyMap]) then
				Leave;

			SetRect(dest, 0, 0, 34, 45);
			OffsetRect(dest, 113, 100 + i * 8);
			for i2 := 0 to 7 do
			begin
				SetRect(letters[0], 375, 33, 409, 78);	{G}
				SetRect(letters[1], 375, 77, 409, 122);	{a}
				SetRect(letters[2], 375, 121, 409, 166);	{m}
				SetRect(letters[3], 375, 165, 409, 210);	{e}
				SetRect(letters[4], 375, 209, 409, 254);	{O}
				SetRect(letters[5], 375, 253, 409, 298);	{v}
				SetRect(letters[6], 375, 297, 409, 342);	{r}
				if (i2 = 6) then
					whichLetter := 3
				else if (i2 = 7) then
					whichLetter := 6
				else
					whichLetter := i2;
				OffsetRect(dest, Randomize(i * 2 + 1) - i, 0);

				Delay(1, dummyLong);

				if (inColor) then
					CopyBits(BitMapPtr(objectCPtr^.portPixMap^)^, GrafPtr(mainWndo)^.portBits, letters[whichLetter], dest, srcCopy, nil)
				else
					CopyBits(offPlayerMap, mainWndo^.portBits, letters[whichLetter], dest, srcCopy, nil);
				OffsetRect(dest, 36, 0);
			end;
		end;

		for i := 1 to 200 do
		begin
			Delay(1, dummyLong);
			if (Button) then
			begin
				if (hasLetUpOnButton) then
					Leave;
			end
			else
				hasLetUpOnButton := TRUE;
			GetKeys(theKeys);
			if (theKeys[kReturnKeyMap]) then
				Leave;
		end;

	end;

{=================================}

	procedure WrapItUp;
		var
			tempByte: SignedByte;
			tempRect: Rect;
			thePict: PicHandle;

	begin
		playing := FALSE;
		pausing := FALSE;

		if (hasMirror) then
		begin
			hasMirror := FALSE;
			HUnlock(Handle(mirrorRgn));
			DisposeRgn(mirrorRgn);
		end;
		if (hasWindow) then
		begin
			hasWindow := FALSE;
			HUnlock(Handle(windowRgn));
			DisposeRgn(windowRgn);
		end;
		if (hasToast) then
		begin
			hasToast := FALSE;
			HUnlock(Handle(toastRgn));
			DisposeRgn(toastRgn);
		end;

		ForceMainToVisible;

		FlushEvents(everyEvent, 0);
		theErr := PostEvent(KeyDown, 65);
		RedrawWindowFrame;
		GameOver;
		ShowMenuBar;

		if (inColor) then
			SetPort(GrafPtr(virginCPtr))
		else
			SetPort(offVirginPort);

		if (inColor) then
			thePict := GetPicture(rColorIdleID)
		else
			thePict := GetPicture(rIdleID);

		if (thePict <> nil) then
		begin
			tempByte := HGetState(Handle(thePict));
			MoveHHi(Handle(thePict));
			HLock(Handle(thePict));
			DrawPicture(thePict, wholeArea);
			HSetState(Handle(thePict), tempByte);
			ReleaseResource(Handle(thePict));
		end
		else
			GenericAlert(kErrGraphicLoad);

{$IFC DemoVersion}
		MoveTo(13, 113);
		TextFont(SystemFont);
		if (inColor) then
		begin
			ForeColor(redColor);
			TextMode(patOr);
			DrawString('DEMO VERSION');
			ForeColor(blackColor);
		end
		else
		begin
			TextMode(patXOr);
			DrawString('DEMO VERSION');
		end;
{$ENDC}

		DissBlocks;

{$IFC not DemoVersion}
		EnableItem(GetMenu(mGame), iLoadHouse);
{$ENDC}
		DisableItem(GetMenu(mGame), iEndGame);
{$IFC not DemoVersion}
		EnableItem(GetMenu(mGame), iLoadGame);
{$ENDC}
		DisableItem(GetMenu(mGame), iSaveGame);
		DisableItem(GetMenu(mGame), iSaveGameAs);
		EnableItem(GetMenu(mOption), iHiScores);

		InitCursor;
		SortHiScores;

		if (smsIsActive) then
			SMSExit;
		smsIsActive := FALSE;
	end;

{=================================}

	procedure AdvanceAFile;
		var
			i: Integer;
			wasHouse, newHouse: string[32];

{----------}

		procedure ExitGracefully;
		begin
			roomAt := 0;
			roomsPassed := roomsPassed - 1;
			ClosingAnimation;
			WrapItUp;
			Exit(AdvanceAFile);
		end;

{----------}

	begin
		wasHouse := housesName;
		housesName := thisHouse.nextFile;
		fileWasLost := FALSE;

		if (not GetHouse) then
			ExitGracefully;

		if (fileWasLost) then
		begin
			newHouse := housesName;
			housesName := wasHouse;

			if (not GetHouse) then
				ExitGracefully;

			thisHouse.nextFile := newHouse;

			if (not WriteHouse) then
				ExitGracefully;

			housesName := thisHouse.nextFile;

			if (not GetHouse) then
				ExitGracefully;
		end;

		CalcRoomScore;
		suppScore := suppScore + roomScore;
		for i := 1 to 40 do
			roomVisits[i] := FALSE;
		roomScore := 0;
	end;

{=================================}

	procedure OffAMortal;
		var
			tempRect: Rect;
			tempStr: Str255;

	begin
		with theGlider do
		begin
			if (inColor) then
			begin
				CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, BitMapPtr(loadCPtr^.portPixMap^)^, wholeRect, wholeRect, srcCopy, wholeRgn);
				CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, BitMapPtr(loadCPtr^.portPixMap^)^, wholeShado, wholeShado, srcCopy, wholeRgn);
				CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, GrafPtr(mainWndo)^.portBits, wholeRect, wholeRect, srcCopy, wholeRgn);
				CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, GrafPtr(mainWndo)^.portBits, wholeShado, wholeShado, srcCopy, wholeRgn);
			end
			else
			begin
				UnionRect(destRect, oldRect, wholeRect);
				UnionRect(shadoDest, oldShado, wholeShado);
				CopyBits(offVirginMap, offLoadMap, wholeRect, wholeRect, srcCopy, wholeRgn);
				CopyBits(offVirginMap, offLoadMap, wholeShado, wholeShado, srcCopy, wholeRgn);
				CopyBits(offVirginMap, mainWndo^.portBits, wholeRect, wholeRect, srcCopy, wholeRgn);
				CopyBits(offVirginMap, mainWndo^.portBits, wholeShado, wholeShado, srcCopy, wholeRgn);
			end;
		end;
		if (hasMirror) then
		begin
			SetPort(GrafPtr(mainWndo));
			EraseRgn(mirrorRgn);

			if (inColor) then
				SetPort(GrafPtr(loadCPtr))
			else
				SetPort(offLoadPort);
			EraseRgn(mirrorRgn);

			if (inColor) then
				SetPort(GrafPtr(virginCPtr))
			else
				SetPort(offVirginPort);
		end;
		if (hasWindow) then
		begin
			SetPort(GrafPtr(mainWndo));
			FillRgn(windowRgn, black);

			if (inColor) then
				SetPort(GrafPtr(loadCPtr))
			else
				SetPort(offLoadPort);
			FillRgn(windowRgn, black);

			if (inColor) then
				SetPort(GrafPtr(virginCPtr))
			else
				SetPort(offVirginPort);
		end;

		mortals := mortals - 1;
		if (mortals < 1) then
		begin
			WrapItUp;
			Exit(OffAMortal);
		end;

		if (mortals < 4) then	{hide a token glider}
		begin
			SetRect(tempRect, 470, 5, 505, 20);
			OffsetRect(tempRect, -37 * (mortals - 1), 0);
			if (inColor) then
				SetPort(GrafPtr(virginCPtr))
			else
				SetPort(offVirginPort);
			PenNormal;
			PaintRect(tempRect);
			if (inColor) then
			begin
				CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, BitMapPtr(loadCPtr^.portPixMap^)^, tempRect, tempRect, srcCopy, wholeRgn);
				CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, GrafPtr(mainWndo)^.portBits, tempRect, tempRect, srcCopy, wholeRgn);
			end
			else
			begin
				CopyBits(offVirginMap, offLoadMap, tempRect, tempRect, srcCopy, wholeRgn);
				CopyBits(offVirginMap, mainWndo^.portBits, tempRect, tempRect, srcCopy, wholeRgn);
			end;
			SetRect(tempRect, 384, 5, 397, 20);
			PaintRect(tempRect);
			if (inColor) then
			begin
				CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, BitMapPtr(loadCPtr^.portPixMap^)^, tempRect, tempRect, srcCopy, nil);
				CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, GrafPtr(mainWndo)^.portBits, tempRect, tempRect, srcCopy, wholeRgn);
			end
			else
			begin
				CopyBits(offVirginMap, offLoadMap, tempRect, tempRect, srcCopy, nil);
				CopyBits(offVirginMap, mainWndo^.portBits, tempRect, tempRect, srcCopy, wholeRgn);
			end;
		end
		else
		begin
			if (inColor) then
				SetPort(GrafPtr(virginCPtr))
			else
				SetPort(offVirginPort);
			PenNormal;
			SetRect(tempRect, 384, 5, 396, 20);
			PaintRect(tempRect);
			MoveTo(tempRect.left, tempRect.bottom - 2);
			TextFont(16);
			TextSize(12);
			NumToString(mortals - 1, tempStr);
			if (inColor) then
			begin
				RGBForeColor(rgbRed);
				PenMode(srcOr);
				DrawString(tempStr);
				PenNormal;
				RGBForeColor(rgbBlack);
				CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, BitMapPtr(loadCPtr^.portPixMap^)^, tempRect, tempRect, srcCopy, nil);
				CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, GrafPtr(mainWndo)^.portBits, tempRect, tempRect, srcCopy, wholeRgn);
			end
			else
			begin
				TextMode(patXOr);
				DrawString(tempStr);
				PenNormal;
				CopyBits(offVirginMap, offLoadMap, tempRect, tempRect, srcCopy, nil);
				CopyBits(offVirginMap, mainWndo^.portBits, tempRect, tempRect, srcCopy, wholeRgn);
			end;
		end;

		ResetGlider;
	end;

{=================================}

	procedure CheckForTimeBonus;
		var
			tempStr: Str255;
			tempRect: Rect;
			timeBonus, dummyLong: LongInt;
			i: Integer;

	begin
		timeBonus := 0;
		if (loopsThruRoom < kBonusTimeToBeat) then
			timeBonus := (kBonusTimeToBeat - loopsThruRoom) * ((roomAt div 5) + 1);
		suppScore := suppScore + timeBonus;

		loopsThruRoom := 0;

		NumToString(timeBonus, tempStr);
		tempStr := CONCAT('Time Bonus = ', tempStr);
		SetRect(tempRect, 190, 100, 312, 117);

		SetPort(GrafPtr(mainWndo));
		if (inColor) then
		begin
			PenNormal;
			PaintRect(tempRect);
			PenMode(patXOr);
			InsetRect(tempRect, 1, 1);
			FrameRect(tempRect);
			PenNormal;
			InsetRect(tempRect, -1, -1);
			RGBForeColor(rgbYellow);
			TextFont(16);
			TextSize(12);
			PenMode(srcOr);
			MoveTo(tempRect.left + 3, tempRect.bottom - 4);
			DrawString(tempStr);
			RGBForeColor(rgbBlack);

			SetPort(GrafPtr(virginCPtr));
			PenNormal;
			PaintRect(tempRect);
			PenMode(patXOr);
			InsetRect(tempRect, 1, 1);
			FrameRect(tempRect);
			PenNormal;
			InsetRect(tempRect, -1, -1);
			RGBForeColor(rgbYellow);
			PenNormal;
			TextFont(16);
			TextSize(12);
			PenMode(srcOr);
			MoveTo(tempRect.left + 3, tempRect.bottom - 4);
			DrawString(tempStr);
			RGBForeColor(rgbBlack);
		end
		else
		begin
			PenNormal;
			PaintRect(tempRect);
			PenMode(patXOr);
			InsetRect(tempRect, 1, 1);
			FrameRect(tempRect);
			PenNormal;
			InsetRect(tempRect, -1, -1);
			TextFont(16);
			TextSize(12);
			TextMode(patXOr);
			MoveTo(tempRect.left + 3, tempRect.bottom - 4);
			DrawString(tempStr);
			PenNormal;

			SetPort(offVirginPort);
			PenNormal;
			PaintRect(tempRect);
			PenMode(patXOr);
			InsetRect(tempRect, 1, 1);
			FrameRect(tempRect);
			PenNormal;
			InsetRect(tempRect, -1, -1);
			TextFont(16);
			TextSize(12);
			TextMode(patXOr);
			MoveTo(tempRect.left + 3, tempRect.bottom - 4);
			DrawString(tempStr);
			PenNormal;

			SetPort(offLoadPort);
			PenNormal;
			PaintRect(tempRect);
			PenMode(patXOr);
			InsetRect(tempRect, 1, 1);
			FrameRect(tempRect);
			PenNormal;
			InsetRect(tempRect, -1, -1);
			TextFont(16);
			TextSize(12);
			TextMode(patXOr);
			MoveTo(tempRect.left + 3, tempRect.bottom - 4);
			DrawString(tempStr);
			PenNormal;
		end;

		for i := 1 to 30 do
		begin
			HorizonMouse;
			Delay(1, dummyLong);
		end;
	end;

{=================================}

	procedure SetRoomState;
		var
			oldRoomScore: LongInt;
			i: Integer;

	begin
		if (didntExitEntrance) then
			roomVisits[roomAt] := TRUE;
		bassLoop := 0;
		playBassTime := kBonusTimeToBeat div kBassFract + kMinBassLoop;

		StartScoreRolling;

		oldRoomScore := roomScore;
		CalcRoomScore;
		if ((oldRoomScore < roomScore) and (didntExitEntrance)) then
			CheckForTimeBonus;
		loopsThruRoom := 0;

		for i := 1 to nObjects do
			case (eventKind[i, 0]) of
				awardIt, extraIt, energizeIt, bandIt, trickIt: 
				begin
					thisHouse.theRooms[roomAt].theObjects[i].amount := eventKind[i, 1];
				end;
				lightIt, airOnIt: 
				begin
					if ((not lightsOut) and (not airOut)) then
						thisHouse.theRooms[roomAt].conditionCode := 0;
				end;
				otherwise
			end;

		if (hasMirror) then
		begin
			SetPort(GrafPtr(mainWndo));
			EraseRgn(mirrorRgn);

			if (inColor) then
				SetPort(GrafPtr(loadCPtr))
			else
				SetPort(offLoadPort);
			EraseRgn(mirrorRgn);

			if (inColor) then
				SetPort(GrafPtr(virginCPtr))
			else
				SetPort(offVirginPort);
		end;

		with theGlider do
		begin
			if (inColor) then
			begin
				CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, BitMapPtr(loadCPtr^.portPixMap^)^, destRect, destRect, srcCopy, wholeRgn);
				CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, BitMapPtr(loadCPtr^.portPixMap^)^, shadoDest, shadoDest, srcCopy, wholeRgn);
				CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, GrafPtr(mainWndo)^.portBits, destRect, destRect, srcCopy, wholeRgn);
				CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, GrafPtr(mainWndo)^.portBits, shadoDest, shadoDest, srcCopy, wholeRgn);
			end
			else
			begin
				CopyBits(offVirginMap, offLoadMap, destRect, destRect, srcCopy, wholeRgn);
				CopyBits(offVirginMap, offLoadMap, shadoDest, shadoDest, srcCopy, wholeRgn);
				CopyBits(offVirginMap, mainWndo^.portBits, destRect, destRect, srcCopy, wholeRgn);
				CopyBits(offVirginMap, mainWndo^.portBits, shadoDest, shadoDest, srcCopy, wholeRgn);
			end;
		end;
	end;

{=================================}

	procedure ScrollForward;
		var
			srcRect: Rect;
			waitTicks: LongInt;
			index: Integer;

	begin
		with theGlider do
		begin
			destRect.left := 0;
			destRect.right := 48;
			oldRect := destRect;
			wholeRect := destRect;
			shadoDest.left := 0;
			shadoDest.right := 48;
			oldShado := shadoDest;
			wholeShado := shadoDest;
			touchRect := destRect;
			InsetRect(touchRect, 10, 5);
		end;

		SetRect(srcRect, 496, 0, 512, 342);

		for index := 0 to 31 do
		begin
			HorizonMouse;

			waitTicks := TickCount;
			repeat
			until (TickCount > waitTicks);

			if (inColor) then
			begin
				CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, GrafPtr(mainWndo)^.portBits, srcRect, srcRect, srcCopy, nil);
				SetPort(GrafPtr(mainWndo));
				PenNormal;
				MoveTo(srcRect.left - 1, srcRect.top);
				Line(0, 322);
				SetPort(GrafPtr(virginCPtr));
			end
			else
			begin
				CopyBits(offVirginMap, mainWndo^.portBits, srcRect, srcRect, srcCopy, nil);
				SetPort(mainWndo);
				PenNormal;
				MoveTo(srcRect.left - 1, srcRect.top);
				Line(0, 322);
				SetPort(offVirginPort);
			end;

			srcRect.right := srcRect.right - 16;
			srcRect.left := srcRect.left - 16;
		end;
	end;

{=================================}

	procedure ScrollBackward;
		var
			srcRect: Rect;
			waitTicks: LongInt;
			index: Integer;

	begin
		with theGlider do
		begin
			destRect.left := 464;
			destRect.right := 512;
			oldRect := destRect;
			wholeRect := destRect;
			shadoDest.left := 464;
			shadoDest.right := 512;
			oldShado := shadoDest;
			wholeShado := shadoDest;
			touchRect := destRect;
			InsetRect(touchRect, 10, 5);
		end;

		SetRect(srcRect, 0, 0, 16, 342);

		if (inColor) then
			CopyBits(GrafPtr(mainWndo)^.portBits, BitMapPtr(loadCPtr^.portPixMap^)^, wholeArea, wholeArea, srcCopy, nil)
		else
			CopyBits(mainWndo^.portBits, offLoadMap, wholeArea, wholeArea, srcCopy, nil);

		for index := 0 to 31 do
		begin
			HorizonMouse;

			waitTicks := TickCount;
			repeat
			until (TickCount > waitTicks);

			if (inColor) then
			begin
				CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, GrafPtr(mainWndo)^.portBits, srcRect, srcRect, srcCopy, nil);
				SetPort(GrafPtr(mainWndo));
				PenNormal;
				MoveTo(srcRect.right, srcRect.top);
				Line(0, 322);
				SetPort(GrafPtr(virginCPtr));
			end
			else
			begin
				CopyBits(offVirginMap, mainWndo^.portBits, srcRect, srcRect, srcCopy, nil);
				SetPort(mainWndo);
				PenNormal;
				MoveTo(srcRect.right, srcRect.top);
				Line(0, 322);
				SetPort(offVirginPort);
			end;

			srcRect.right := srcRect.right + 16;
			srcRect.left := srcRect.left + 16;
		end;
	end;

{=================================}

	procedure ScrollUp;
		var
			srcRect: Rect;
			waitTicks: LongInt;
			index, leftCorner: Integer;

	begin
		leftCorner := 232;
		for index := 1 to 16 do
			with thisHouse.theRooms[roomAt].theObjects[index] do
				if (objectIs = dnStar) then
					leftCorner := boundRect.left + 64;

		with theGlider do
		begin
			destRect.left := leftCorner;
			destRect.right := leftCorner + 48;
			destRect.top := kFloorVert - 20;
			destRect.bottom := kFloorVert;
			oldRect := destRect;
			wholeRect := destRect;
			shadoDest.left := destRect.left;
			shadoDest.right := destRect.right;
			oldShado := shadoDest;
			wholeShado := shadoDest;
			touchRect := destRect;
			InsetRect(touchRect, 10, 5);
		end;

		SetRect(srcRect, 0, 0, 512, 18);

		for index := 0 to 18 do
		begin
			HorizonMouse;

			waitTicks := TickCount;
			repeat
			until (TickCount > waitTicks);

			if (inColor) then
			begin
				CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, GrafPtr(mainWndo)^.portBits, srcRect, srcRect, srcCopy, nil);
				SetPort(GrafPtr(mainWndo));
				PenNormal;
				MoveTo(srcRect.left, srcRect.bottom);
				Line(512, 0);
				SetPort(GrafPtr(virginCPtr));
			end
			else
			begin
				CopyBits(offVirginMap, mainWndo^.portBits, srcRect, srcRect, srcCopy, nil);
				SetPort(mainWndo);
				PenNormal;
				MoveTo(srcRect.left, srcRect.bottom);
				Line(512, 0);
				SetPort(offVirginPort);
			end;

			srcRect.bottom := srcRect.bottom + 18;
			srcRect.top := srcRect.top + 18;
		end;
	end;

{=================================}

	procedure ScrollDown;
		var
			srcRect: Rect;
			waitTicks: LongInt;
			index, leftCorner: Integer;

	begin
		leftCorner := 232;
		for index := 1 to 16 do
			with thisHouse.theRooms[roomAt].theObjects[index] do
				if (objectIs = upStar) then
					leftCorner := boundRect.left + 64;

		with theGlider do
		begin
			destRect.left := leftCorner;
			destRect.right := leftCorner + 48;
			destRect.top := kCeilingVert + 20;
			destRect.bottom := kCeilingVert + 40;
			oldRect := destRect;
			wholeRect := destRect;
			shadoDest.left := destRect.left;
			shadoDest.right := destRect.right;
			oldShado := shadoDest;
			wholeShado := shadoDest;
			touchRect := destRect;
			InsetRect(touchRect, 10, 5);
		end;

		SetRect(srcRect, 0, 324, 512, 342);

		for index := 0 to 18 do
		begin
			waitTicks := TickCount;
			repeat
			until (TickCount > waitTicks);

			if (inColor) then
			begin
				CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, GrafPtr(mainWndo)^.portBits, srcRect, srcRect, srcCopy, nil);
				SetPort(GrafPtr(mainWndo));
				PenNormal;
				MoveTo(srcRect.left, srcRect.top - 1);
				Line(512, 0);
				SetPort(GrafPtr(virginCPtr));
			end
			else
			begin
				CopyBits(offVirginMap, mainWndo^.portBits, srcRect, srcRect, srcCopy, nil);
				SetPort(mainWndo);
				PenNormal;
				MoveTo(srcRect.left, srcRect.top - 1);
				Line(512, 0);
				SetPort(offVirginPort);
			end;

			srcRect.bottom := srcRect.bottom - 18;
			srcRect.top := srcRect.top - 18;
		end;
	end;

{=================================}

	procedure AdvanceARoom;
	begin
		didntExitEntrance := (sideYouCantExit <> rightOfRoom);

		SetRoomState;
		enteredLeft := TRUE;
		sideYouCantExit := leftOfRoom;

		roomAt := roomAt + 1;
		roomsPassed := roomsPassed + 1;

{$IFC DemoVersion}
		if (roomAt > 5) then
		begin
			roomAt := 0;
			roomsPassed := roomsPassed - 1;
			ClosingAnimation;
			WrapItUp;
			Exit(AdvanceARoom);
		end;
{$ENDC}

		if (roomAt > thisHouse.numberORooms) then
		begin
			if ((thisHouse.nextFile = 'nil') or (thisHouse.nextFile = '')) then
			begin
				roomAt := 0;
				roomsPassed := roomsPassed - 1;
				ClosingAnimation;
				WrapItUp;
				Exit(AdvanceARoom);
			end
			else
			begin
				AdvanceAFile;
				roomAt := 1;
			end;
		end;

		if (roomAt <> 0) then
		begin
			ReadyRoom;
			ScrollForward;
			if (inColor) then
				CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, BitMapPtr(loadCPtr^.portPixMap^)^, wholeArea, wholeArea, srcCopy, wholeRgn)
			else
				CopyBits(offVirginMap, offLoadMap, wholeArea, wholeArea, srcCopy, wholeRgn);
		end;
	end;

{=================================}

	procedure RetreatARoom;
	begin
		didntExitEntrance := (sideYouCantExit <> leftOfRoom);
		SetRoomState;
		enteredLeft := FALSE;
		sideYouCantExit := rightOfRoom;

		roomAt := roomAt - 1;
		roomsPassed := roomsPassed - 1;
		if (roomAt < 1) then
		begin
			roomAt := 0;
			roomsPassed := roomsPassed - 1;
			ClosingAnimation;
			WrapItUp;
			Exit(RetreatARoom);
		end;

		ReadyRoom;
		ScrollBackward;
		if (inColor) then
			CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, BitMapPtr(loadCPtr^.portPixMap^)^, wholeArea, wholeArea, srcCopy, wholeRgn)
		else
			CopyBits(offVirginMap, offLoadMap, wholeArea, wholeArea, srcCopy, wholeRgn);
	end;

{=================================}

	procedure UpAFlight;
		var
			addToIt: Integer;

	begin
		didntExitEntrance := (sideYouCantExit <> topOfRoom);
		SetRoomState;
		sideYouCantExit := bottomOfRoom;

		addToIt := whatRoom - roomAt;
		roomAt := whatRoom;
		roomsPassed := roomsPassed + addToIt;
		if ((roomAt > thisHouse.numberORooms) or (roomAt < 0)) then
		begin
			if ((thisHouse.nextFile = 'nil') or (thisHouse.nextFile = '') or (roomAt < 0)) then
			begin
				roomAt := 0;
				roomsPassed := roomsPassed - 1;
				ClosingAnimation;
				WrapItUp;
				Exit(UpAFlight);
			end
			else
			begin
				AdvanceAFile;
				roomAt := roomAt - 40;
			end;
		end
		else if (roomAt = 0) then
		begin
			roomAt := 0;
			roomsPassed := roomsPassed - 1;
			ClosingAnimation;
			WrapItUp;
			Exit(UpAFlight);
		end;

		if (roomAt <> 0) then
		begin
			ReadyRoom;
			ScrollUp;
			if (inColor) then
				CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, BitMapPtr(loadCPtr^.portPixMap^)^, wholeArea, wholeArea, srcCopy, wholeRgn)
			else
				CopyBits(offVirginMap, offLoadMap, wholeArea, wholeArea, srcCopy, wholeRgn);
		end;
	end;

{=================================}

	procedure DownAFlight;
		var
			addToIt: Integer;

	begin
		didntExitEntrance := (sideYouCantExit <> bottomOfRoom);
		SetRoomState;
		sideYouCantExit := topOfRoom;

		addToIt := whatRoom - roomAt;
		roomAt := whatRoom;
		roomsPassed := roomsPassed + addToIt;
		if ((roomAt < 0) or (roomAt > thisHouse.numberORooms)) then
		begin
			if ((thisHouse.nextFile = 'nil') or (thisHouse.nextFile = '') or (roomAt < 0)) then
			begin
				roomAt := 0;
				roomsPassed := roomsPassed - 1;
				ClosingAnimation;
				WrapItUp;
				Exit(DownAFlight);
			end
			else
			begin
				AdvanceAFile;
				roomAt := roomAt - 40;
			end;
		end
		else if (roomAt = 0) then
		begin
			ClosingAnimation;
			WrapItUp;
			Exit(DownAFlight);
		end;

		if (roomAt <> 0) then
		begin
			ReadyRoom;
			ScrollDown;
			if (inColor) then
				CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, BitMapPtr(loadCPtr^.portPixMap^)^, wholeArea, wholeArea, srcCopy, wholeRgn)
			else
				CopyBits(offVirginMap, offLoadMap, wholeArea, wholeArea, srcCopy, wholeRgn);
		end;
	end;

{=================================}

	procedure Transport;
		var
			addToIt, leftCorner, index, localRoomNumber: Integer;
			newRoom: Boolean;

	begin
		newRoom := (whatRoom <> roomAt);
		if (newRoom) then
		begin
			didntExitEntrance := TRUE;
			SetRoomState;
			sideYouCantExit := whoCares;
			addToIt := whatRoom - roomAt;
			roomAt := whatRoom;
			roomsPassed := roomsPassed + addToIt;

			if ((roomAt < 0) or (roomAt > thisHouse.numberORooms)) then
			begin
				if ((thisHouse.nextFile = 'nil') or (thisHouse.nextFile = '') or (roomAt < 0)) then
				begin
					ClosingAnimation;
					roomAt := 0;
					WrapItUp;
					Exit(Transport);
				end
				else
				begin
					localRoomNumber := roomAt - thisHouse.numberORooms;
					AdvanceAFile;
					roomAt := localRoomNumber;
					if (roomAt > thisHouse.numberORooms) then
					begin
						ClosingAnimation;
						roomAt := 0;
						WrapItUp;
						Exit(Transport);
					end
				end;
			end
			else if (roomAt = 0) then
			begin
				ClosingAnimation;
				WrapItUp;
				Exit(Transport);
			end;

			if (roomAt <> 0) then
				ReadyRoom;
		end
		else					{we're transporting to the room we're in}
			with theGlider do
				if (inColor) then
				begin
					CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, BitMapPtr(loadCPtr^.portPixMap^)^, destRect, destRect, srcCopy, wholeRgn);
					CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, BitMapPtr(loadCPtr^.portPixMap^)^, shadoDest, shadoDest, srcCopy, wholeRgn);
					CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, GrafPtr(mainWndo)^.portBits, destRect, destRect, srcCopy, wholeRgn);
					CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, GrafPtr(mainWndo)^.portBits, shadoDest, shadoDest, srcCopy, wholeRgn);
				end
				else
				begin
					CopyBits(offVirginMap, offLoadMap, destRect, destRect, srcCopy, wholeRgn);
					CopyBits(offVirginMap, offLoadMap, shadoDest, shadoDest, srcCopy, wholeRgn);
					CopyBits(offVirginMap, mainWndo^.portBits, destRect, destRect, srcCopy, wholeRgn);
					CopyBits(offVirginMap, mainWndo^.portBits, shadoDest, shadoDest, srcCopy, wholeRgn);
				end;

		if (roomAt <> 0) then
		begin
			leftCorner := 232;
			for index := 1 to 16 do
				with thisHouse.theRooms[roomAt].theObjects[index] do
					if ((objectIs = celDct) and (isOn)) then
						leftCorner := boundRect.left;

			with theGlider do
			begin
				destRect.left := leftCorner;
				destRect.right := leftCorner + 48;
				destRect.top := kCeilingVert;
				destRect.bottom := kCeilingVert + 20;
				oldRect := destRect;
				wholeRect := destRect;
				shadoDest.left := destRect.left;
				shadoDest.right := destRect.right;
				oldShado := shadoDest;
				wholeShado := shadoDest;
				touchRect := destRect;
				InsetRect(touchRect, 10, 5);
			end;

			if (newRoom) then
			begin
				HorizonMouse;
				DissBlocks;
				if (inColor) then
					CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, BitMapPtr(loadCPtr^.portPixMap^)^, wholeArea, wholeArea, srcCopy, nil)
				else
					CopyBits(offVirginMap, offLoadMap, wholeArea, wholeArea, srcCopy, nil);
			end;
		end;
	end;

{=================================}

end.